]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'usb/usb-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Wed, 24 Aug 2011 04:35:19 +0000 (14:35 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 24 Aug 2011 04:35:24 +0000 (14:35 +1000)
3118 files changed:
Documentation/ABI/removed/o2cb
Documentation/ABI/testing/evm [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-bcma
Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870
Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff [new file with mode: 0644]
Documentation/DocBook/mtdnand.tmpl
Documentation/RCU/NMI-RCU.txt
Documentation/RCU/lockdep-splat.txt [new file with mode: 0644]
Documentation/RCU/lockdep.txt
Documentation/RCU/torture.txt
Documentation/RCU/trace.txt
Documentation/blockdev/cciss.txt
Documentation/cgroups/cgroups.txt
Documentation/cpu-freq/governors.txt
Documentation/cris/README
Documentation/device-mapper/persistent-data.txt [new file with mode: 0644]
Documentation/device-mapper/thin-provisioning.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/l2cc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/crypto/picochip-spacc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/atmel-dataflash.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
Documentation/devicetree/bindings/net/smsc911x.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power_supply/olpc_battery.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8510.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8523.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8580.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8711.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8728.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8731.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8737.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8741.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8750.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8753.txt [new file with mode: 0644]
Documentation/fault-injection/fault-injection.txt
Documentation/filesystems/ext4.txt
Documentation/filesystems/sysfs.txt
Documentation/kernel-parameters.txt
Documentation/networking/00-INDEX
Documentation/networking/ip-sysctl.txt
Documentation/networking/netdevices.txt
Documentation/networking/scaling.txt
Documentation/power/basic-pm-debugging.txt
Documentation/power/freezing-of-tasks.txt
Documentation/power/runtime_pm.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/sound/alsa/HD-Audio.txt
Documentation/usb/power-management.txt
Documentation/x86/entry_64.txt
MAINTAINERS
arch/alpha/include/asm/thread_info.h
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/mmcif-sh7372.c
arch/arm/boot/compressed/sdhi-sh7372.c
arch/arm/common/scoop.c
arch/arm/configs/exynos4_defconfig
arch/arm/include/asm/Kbuild
arch/arm/include/asm/assembler.h
arch/arm/include/asm/auxvec.h [deleted file]
arch/arm/include/asm/bitsperlong.h [deleted file]
arch/arm/include/asm/cputime.h [deleted file]
arch/arm/include/asm/cputype.h
arch/arm/include/asm/dma-mapping.h
arch/arm/include/asm/ecard.h
arch/arm/include/asm/emergency-restart.h [deleted file]
arch/arm/include/asm/errno.h [deleted file]
arch/arm/include/asm/gpio.h
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/hardware/iop3xx-gpio.h
arch/arm/include/asm/io.h
arch/arm/include/asm/ioctl.h [deleted file]
arch/arm/include/asm/irq_regs.h [deleted file]
arch/arm/include/asm/kdebug.h [deleted file]
arch/arm/include/asm/local.h [deleted file]
arch/arm/include/asm/local64.h [deleted file]
arch/arm/include/asm/memory.h
arch/arm/include/asm/module.h
arch/arm/include/asm/page.h
arch/arm/include/asm/percpu.h [deleted file]
arch/arm/include/asm/pgalloc.h
arch/arm/include/asm/pgtable-2level-hwdef.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-2level-types.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-2level.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-3level-hwdef.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-3level-types.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-3level.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-hwdef.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/pmu.h
arch/arm/include/asm/poll.h [deleted file]
arch/arm/include/asm/proc-fns.h
arch/arm/include/asm/resource.h [deleted file]
arch/arm/include/asm/sections.h [deleted file]
arch/arm/include/asm/setup.h
arch/arm/include/asm/siginfo.h [deleted file]
arch/arm/include/asm/sizes.h [deleted file]
arch/arm/include/asm/system.h
arch/arm/include/asm/thread_info.h
arch/arm/include/asm/tlb.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/asm/topology.h
arch/arm/kernel/Makefile
arch/arm/kernel/ecard.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/head.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/module.c
arch/arm/kernel/pmu.c
arch/arm/kernel/setup.c
arch/arm/kernel/sleep.S
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/topology.c [new file with mode: 0644]
arch/arm/mach-at91/Makefile.boot
arch/arm/mach-at91/at91cap9_devices.c
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/board-1arm.c
arch/arm/mach-at91/board-afeb-9260v1.c
arch/arm/mach-at91/board-cam60.c
arch/arm/mach-at91/board-cap9adk.c
arch/arm/mach-at91/board-carmeva.c
arch/arm/mach-at91/board-cpu9krea.c
arch/arm/mach-at91/board-cpuat91.c
arch/arm/mach-at91/board-csb337.c
arch/arm/mach-at91/board-csb637.c
arch/arm/mach-at91/board-eb9200.c
arch/arm/mach-at91/board-ecbat91.c
arch/arm/mach-at91/board-kafa.c
arch/arm/mach-at91/board-kb9202.c
arch/arm/mach-at91/board-neocore926.c
arch/arm/mach-at91/board-picotux200.c
arch/arm/mach-at91/board-qil-a9260.c
arch/arm/mach-at91/board-rm9200dk.c
arch/arm/mach-at91/board-rm9200ek.c
arch/arm/mach-at91/board-sam9-l9260.c
arch/arm/mach-at91/board-sam9260ek.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/board-sam9rlek.c
arch/arm/mach-at91/board-snapper9260.c
arch/arm/mach-at91/board-usb-a9260.c
arch/arm/mach-at91/board-usb-a9263.c
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/gpio.c
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/include/mach/gpio.h
arch/arm/mach-at91/leds.c
arch/arm/mach-at91/pm.c
arch/arm/mach-bcmring/Makefile.boot
arch/arm/mach-clps711x/Makefile.boot
arch/arm/mach-cns3xxx/Makefile.boot
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/Makefile.boot
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-mityomapl138.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-tnetv107x-evm.c
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/include/mach/gpio-davinci.h [new file with mode: 0644]
arch/arm/mach-davinci/include/mach/gpio.h
arch/arm/mach-davinci/include/mach/nand.h
arch/arm/mach-davinci/tnetv107x.c
arch/arm/mach-dove/Makefile.boot
arch/arm/mach-ebsa110/Makefile.boot
arch/arm/mach-ebsa110/include/mach/io.h
arch/arm/mach-ep93xx/Makefile.boot
arch/arm/mach-ep93xx/include/mach/gpio.h
arch/arm/mach-ep93xx/include/mach/ts72xx.h
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-exynos4/Kconfig
arch/arm/mach-exynos4/Makefile
arch/arm/mach-exynos4/Makefile.boot
arch/arm/mach-exynos4/clock.c
arch/arm/mach-exynos4/cpu.c
arch/arm/mach-exynos4/include/mach/gpio.h
arch/arm/mach-exynos4/include/mach/irqs.h
arch/arm/mach-exynos4/include/mach/regs-pmu.h
arch/arm/mach-exynos4/irq-eint.c
arch/arm/mach-exynos4/mach-nuri.c
arch/arm/mach-exynos4/mach-origen.c [new file with mode: 0644]
arch/arm/mach-exynos4/mach-smdkv310.c
arch/arm/mach-exynos4/mach-universal_c210.c
arch/arm/mach-exynos4/setup-usb-phy.c
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-footbridge/Makefile.boot
arch/arm/mach-footbridge/include/mach/io.h
arch/arm/mach-gemini/Makefile.boot
arch/arm/mach-gemini/include/mach/gpio.h
arch/arm/mach-h720x/Makefile.boot
arch/arm/mach-imx/Makefile.boot
arch/arm/mach-imx/iomux-imx31.c
arch/arm/mach-imx/mach-mx27ads.c
arch/arm/mach-integrator/Makefile.boot
arch/arm/mach-integrator/include/mach/io.h
arch/arm/mach-iop13xx/Makefile.boot
arch/arm/mach-iop32x/Makefile.boot
arch/arm/mach-iop33x/Makefile.boot
arch/arm/mach-ixp2000/Makefile.boot
arch/arm/mach-ixp2000/core.c
arch/arm/mach-ixp2000/include/mach/gpio-ixp2000.h [moved from arch/arm/mach-ixp2000/include/mach/gpio.h with 95% similarity]
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp23xx/Makefile.boot
arch/arm/mach-ixp4xx/Makefile.boot
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-ixp4xx/dsmg600-setup.c
arch/arm/mach-ixp4xx/fsg-setup.c
arch/arm/mach-ixp4xx/include/mach/gpio.h
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-ixp4xx/nas100d-setup.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/arm/mach-kirkwood/Makefile.boot
arch/arm/mach-kirkwood/irq.c
arch/arm/mach-kirkwood/mpp.c
arch/arm/mach-ks8695/Makefile
arch/arm/mach-ks8695/Makefile.boot
arch/arm/mach-ks8695/board-acs5k.c
arch/arm/mach-ks8695/board-dsm320.c
arch/arm/mach-ks8695/board-micrel.c
arch/arm/mach-ks8695/devices.c
arch/arm/mach-ks8695/include/mach/gpio-ks8695.h [new file with mode: 0644]
arch/arm/mach-ks8695/include/mach/gpio.h
arch/arm/mach-ks8695/leds.c
arch/arm/mach-lpc32xx/Makefile
arch/arm/mach-lpc32xx/Makefile.boot
arch/arm/mach-lpc32xx/include/mach/gpio-lpc32xx.h [new file with mode: 0644]
arch/arm/mach-lpc32xx/include/mach/gpio.h
arch/arm/mach-lpc32xx/phy3250.c
arch/arm/mach-mmp/Makefile.boot
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-mmp/tavorevb.c
arch/arm/mach-mmp/ttc_dkb.c
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/Makefile.boot
arch/arm/mach-msm/acpuclock-arm11.c
arch/arm/mach-msm/board-halibut.c
arch/arm/mach-msm/board-mahimahi.c
arch/arm/mach-msm/board-msm7x27.c
arch/arm/mach-msm/board-msm7x30.c
arch/arm/mach-msm/board-msm8960.c
arch/arm/mach-msm/board-msm8x60.c
arch/arm/mach-msm/board-qsd8x50.c
arch/arm/mach-msm/board-sapphire.c
arch/arm/mach-msm/board-trout-mmc.c
arch/arm/mach-msm/board-trout-panel.c
arch/arm/mach-msm/board-trout.c
arch/arm/mach-msm/clock-dummy.c [new file with mode: 0644]
arch/arm/mach-msm/clock.c
arch/arm/mach-msm/clock.h
arch/arm/mach-msm/devices-msm7x00.c
arch/arm/mach-msm/devices-msm7x30.c
arch/arm/mach-msm/devices-msm8960.c
arch/arm/mach-msm/devices-msm8x60.c [new file with mode: 0644]
arch/arm/mach-msm/devices-qsd8x50.c
arch/arm/mach-msm/devices.h
arch/arm/mach-msm/dma.c
arch/arm/mach-msm/include/mach/dma.h
arch/arm/mach-msm/include/mach/gpio.h
arch/arm/mach-msm/include/mach/memory.h
arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
arch/arm/mach-msm/include/mach/msm_iomap-8960.h
arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
arch/arm/mach-msm/io.c
arch/arm/mach-mv78xx0/Makefile.boot
arch/arm/mach-mv78xx0/irq.c
arch/arm/mach-mv78xx0/mpp.c
arch/arm/mach-mx5/Makefile.boot
arch/arm/mach-mxs/Makefile.boot
arch/arm/mach-mxs/include/mach/gpio.h
arch/arm/mach-netx/Makefile.boot
arch/arm/mach-nomadik/Makefile.boot
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/cpu-8815.c
arch/arm/mach-nomadik/i2c-8815nhk.c
arch/arm/mach-nuc93x/Makefile.boot
arch/arm/mach-omap1/Makefile.boot
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-generic.c
arch/arm/mach-omap1/board-h2-mmc.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3-mmc.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-sx1-mmc.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap1/fpga.c
arch/arm/mach-omap1/irq.c
arch/arm/mach-omap1/leds-h2p2-debug.c
arch/arm/mach-omap1/leds-osk.c
arch/arm/mach-omap1/leds.c
arch/arm/mach-omap1/pm_bus.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap2/Makefile.boot
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-orion5x/Makefile.boot
arch/arm/mach-orion5x/db88f5281-setup.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/irq.c
arch/arm/mach-orion5x/kurobox_pro-setup.c
arch/arm/mach-orion5x/mv2120-setup.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
arch/arm/mach-orion5x/terastation_pro2-setup.c
arch/arm/mach-orion5x/ts209-setup.c
arch/arm/mach-orion5x/ts409-setup.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-orion5x/wnr854t-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-pnx4008/Makefile.boot
arch/arm/mach-pnx4008/gpio.c
arch/arm/mach-pnx4008/serial.c
arch/arm/mach-prima2/Makefile.boot
arch/arm/mach-pxa/Makefile.boot
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa3xx.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/include/mach/littleton.h
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/mxm8x10.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa95x.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/saar.c
arch/arm/mach-pxa/saarb.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-realview/Makefile.boot
arch/arm/mach-realview/include/mach/gpio.h
arch/arm/mach-realview/include/mach/system.h
arch/arm/mach-rpc/Makefile.boot
arch/arm/mach-rpc/include/mach/hardware.h
arch/arm/mach-rpc/include/mach/io.h
arch/arm/mach-rpc/riscpc.c
arch/arm/mach-s3c2410/Makefile.boot
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/include/mach/gpio.h
arch/arm/mach-s3c2410/include/mach/h1940-latch.h
arch/arm/mach-s3c2410/include/mach/io.h
arch/arm/mach-s3c2412/dma.c
arch/arm/mach-s3c2440/dma.c
arch/arm/mach-s3c2443/dma.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/Makefile.boot
arch/arm/mach-s3c64xx/include/mach/crag6410.h [new file with mode: 0644]
arch/arm/mach-s3c64xx/include/mach/gpio.h
arch/arm/mach-s3c64xx/mach-crag6410-module.c [new file with mode: 0644]
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/pm.c
arch/arm/mach-s5p64x0/Makefile.boot
arch/arm/mach-s5p64x0/include/mach/gpio.h
arch/arm/mach-s5p64x0/irq-eint.c
arch/arm/mach-s5p64x0/mach-smdk6440.c
arch/arm/mach-s5p64x0/mach-smdk6450.c
arch/arm/mach-s5pc100/Makefile.boot
arch/arm/mach-s5pc100/include/mach/gpio.h
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/Makefile.boot
arch/arm/mach-s5pv210/include/mach/gpio.h
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/pm.c
arch/arm/mach-sa1100/Makefile
arch/arm/mach-sa1100/Makefile.boot
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/include/mach/gpio.h
arch/arm/mach-sa1100/include/mach/io.h
arch/arm/mach-shark/Makefile.boot
arch/arm/mach-shmobile/Makefile.boot
arch/arm/mach-shmobile/board-ag5evm.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/include/mach/gpio.h
arch/arm/mach-shmobile/include/mach/sh7372.h
arch/arm/mach-shmobile/pm-sh7372.c
arch/arm/mach-shmobile/pm_runtime.c
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-spear3xx/Makefile.boot
arch/arm/mach-spear6xx/Makefile.boot
arch/arm/mach-tcc8k/Makefile.boot
arch/arm/mach-tegra/Makefile.boot
arch/arm/mach-tegra/board-trimslice-pinmux.c
arch/arm/mach-tegra/include/mach/gpio.h
arch/arm/mach-u300/Makefile.boot
arch/arm/mach-u300/include/mach/gpio-u300.h [new file with mode: 0644]
arch/arm/mach-u300/include/mach/gpio.h
arch/arm/mach-u300/mmc.c
arch/arm/mach-ux500/Makefile.boot
arch/arm/mach-ux500/board-mop500-pins.c
arch/arm/mach-ux500/board-mop500-u8500uib.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-u5500-sdi.c
arch/arm/mach-ux500/board-u5500.c
arch/arm/mach-ux500/cpu-db5500.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/devices-common.c
arch/arm/mach-versatile/Makefile.boot
arch/arm/mach-versatile/include/mach/gpio.h
arch/arm/mach-vexpress/Makefile.boot
arch/arm/mach-vexpress/include/mach/io.h
arch/arm/mach-vt8500/Makefile.boot
arch/arm/mach-vt8500/include/mach/gpio.h
arch/arm/mach-vt8500/include/mach/io.h
arch/arm/mach-w90x900/Makefile.boot
arch/arm/mach-w90x900/include/mach/gpio.h
arch/arm/mach-zynq/Makefile.boot
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/alignment.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/context.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault.c
arch/arm/mm/idmap.c
arch/arm/mm/ioremap.c
arch/arm/mm/mm.h
arch/arm/mm/mmu.c
arch/arm/mm/pgd.c
arch/arm/mm/proc-macros.S
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v7lpae.S [new file with mode: 0644]
arch/arm/plat-mxc/include/mach/gpio.h
arch/arm/plat-nomadik/include/plat/gpio-nomadik.h [new file with mode: 0644]
arch/arm/plat-nomadik/include/plat/gpio.h
arch/arm/plat-omap/debug-devices.c
arch/arm/plat-omap/debug-leds.c
arch/arm/plat-omap/devices.c
arch/arm/plat-omap/include/plat/gpio.h
arch/arm/plat-orion/include/plat/gpio.h
arch/arm/plat-pxa/gpio.c
arch/arm/plat-pxa/include/plat/gpio.h
arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
arch/arm/plat-s5p/clock.c
arch/arm/plat-s5p/irq-gpioint.c
arch/arm/plat-samsung/dev-hsmmc.c
arch/arm/plat-samsung/dev-hsmmc1.c
arch/arm/plat-samsung/dev-hsmmc2.c
arch/arm/plat-samsung/dev-hsmmc3.c
arch/arm/plat-samsung/dev-ts.c
arch/arm/plat-samsung/include/plat/backlight.h
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
arch/arm/plat-samsung/include/plat/sdhci.h
arch/arm/plat-samsung/irq-vic-timer.c
arch/arm/plat-samsung/platformdata.c
arch/arm/plat-spear/include/plat/gpio.h
arch/arm/tools/mach-types
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/include/asm/thread_info.h
arch/avr32/mach-at32ap/include/mach/board.h
arch/blackfin/include/asm/Kbuild
arch/blackfin/include/asm/mutex.h [deleted file]
arch/blackfin/include/asm/thread_info.h
arch/blackfin/include/asm/uaccess.h
arch/blackfin/mach-bf533/boards/H8606.c
arch/cris/arch-v32/drivers/cryptocop.c
arch/cris/arch-v32/drivers/mach-a3/nandflash.c
arch/cris/arch-v32/drivers/mach-fs/nandflash.c
arch/cris/arch-v32/kernel/ptrace.c
arch/cris/include/arch-v32/arch/cache.h
arch/cris/include/asm/thread_info.h
arch/frv/include/asm/thread_info.h
arch/h8300/include/asm/thread_info.h
arch/ia64/hp/sim/simeth.c
arch/ia64/include/asm/thread_info.h
arch/ia64/sn/kernel/sn2/sn_hwperf.c
arch/m32r/include/asm/thread_info.h
arch/m68k/Kconfig
arch/m68k/Kconfig.bus [new file with mode: 0644]
arch/m68k/Kconfig.cpu [new file with mode: 0644]
arch/m68k/Kconfig.devices [new file with mode: 0644]
arch/m68k/Kconfig.machine [moved from arch/m68k/Kconfig.nommu with 62% similarity]
arch/m68k/Kconfig.mmu [deleted file]
arch/m68k/Makefile
arch/m68k/Makefile_mm [deleted file]
arch/m68k/Makefile_no [deleted file]
arch/m68k/include/asm/entry.h
arch/m68k/include/asm/entry_mm.h [deleted file]
arch/m68k/include/asm/entry_no.h [deleted file]
arch/m68k/include/asm/m520xsim.h
arch/m68k/include/asm/mcfqspi.h
arch/m68k/include/asm/page_mm.h
arch/m68k/include/asm/page_no.h
arch/m68k/include/asm/processor.h
arch/m68k/include/asm/sections.h
arch/m68k/include/asm/thread_info.h
arch/m68k/kernel/Makefile
arch/m68k/kernel/Makefile_mm [deleted file]
arch/m68k/kernel/Makefile_no [deleted file]
arch/m68k/kernel/entry_no.S
arch/m68k/kernel/setup_no.c
arch/m68k/kernel/traps.c
arch/m68k/kernel/traps_mm.c [deleted file]
arch/m68k/kernel/traps_no.c [deleted file]
arch/m68k/kernel/vectors.c [new file with mode: 0644]
arch/m68k/lib/memcpy.c
arch/m68k/mac/macints.c
arch/m68k/mac/misc.c
arch/m68k/mm/init_no.c
arch/m68k/platform/520x/config.c
arch/m68k/platform/520x/gpio.c
arch/m68k/platform/68328/Makefile
arch/m68k/platform/68328/entry.S
arch/m68k/platform/68360/Makefile
arch/m68k/platform/68360/entry.S
arch/m68k/platform/coldfire/entry.S
arch/microblaze/include/asm/thread_info.h
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/alchemy/common/platform.c
arch/mips/alchemy/common/power.c
arch/mips/alchemy/devboards/db1200/platform.c
arch/mips/alchemy/devboards/db1x00/platform.c
arch/mips/ar7/irq.c
arch/mips/bcm47xx/Kconfig [new file with mode: 0644]
arch/mips/bcm47xx/Makefile
arch/mips/bcm47xx/gpio.c
arch/mips/bcm47xx/irq.c
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/serial.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/time.c
arch/mips/bcm47xx/wgt634u.c
arch/mips/bcm63xx/irq.c
arch/mips/cobalt/irq.c
arch/mips/dec/setup.c
arch/mips/emma/markeins/irq.c
arch/mips/include/asm/cacheflush.h
arch/mips/include/asm/io.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/gpio.h
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
arch/mips/include/asm/mipsprom.h
arch/mips/include/asm/prom.h
arch/mips/include/asm/thread_info.h
arch/mips/kernel/ftrace.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/signal.c
arch/mips/kernel/traps.c
arch/mips/lantiq/irq.c
arch/mips/lasat/interrupt.c
arch/mips/loongson/fuloong-2e/irq.c
arch/mips/loongson/lemote-2f/irq.c
arch/mips/mm/c-octeon.c
arch/mips/mm/c-r3k.c
arch/mips/mm/c-r4k.c
arch/mips/mm/c-tx39.c
arch/mips/mm/cache.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/malta-int.c
arch/mips/netlogic/Platform
arch/mips/netlogic/xlr/setup.c
arch/mips/netlogic/xlr/smp.c
arch/mips/netlogic/xlr/smpboot.S
arch/mips/nxp/pnx8550/common/pci.c [deleted file]
arch/mips/nxp/pnx8550/common/setup.c [deleted file]
arch/mips/pci/pci-bcm47xx.c
arch/mips/pci/pci-lantiq.c
arch/mips/pci/pci-rc32434.c
arch/mips/pmc-sierra/msp71xx/msp_irq.c
arch/mips/pmc-sierra/msp71xx/msp_setup.c
arch/mips/pmc-sierra/yosemite/py-console.c
arch/mips/pnx8550/common/int.c
arch/mips/pnx8550/common/prom.c
arch/mips/sgi-ip22/ip22-int.c
arch/mips/sgi-ip27/ip27-irq.c
arch/mips/sni/rm200.c
arch/mips/vr41xx/common/irq.c
arch/mn10300/include/asm/thread_info.h
arch/openrisc/include/asm/sigcontext.h
arch/openrisc/kernel/signal.c
arch/parisc/include/asm/thread_info.h
arch/powerpc/Kconfig
arch/powerpc/boot/dts/charon.dts [new file with mode: 0644]
arch/powerpc/boot/dts/hcu4.dts [deleted file]
arch/powerpc/boot/dts/p1010rdb.dts
arch/powerpc/boot/dts/p1010si.dtsi
arch/powerpc/boot/dts/yosemite.dts
arch/powerpc/configs/40x/acadia_defconfig
arch/powerpc/configs/40x/ep405_defconfig
arch/powerpc/configs/40x/hcu4_defconfig [deleted file]
arch/powerpc/configs/40x/kilauea_defconfig
arch/powerpc/configs/40x/makalu_defconfig
arch/powerpc/configs/40x/walnut_defconfig
arch/powerpc/configs/44x/arches_defconfig
arch/powerpc/configs/44x/bamboo_defconfig
arch/powerpc/configs/44x/bluestone_defconfig
arch/powerpc/configs/44x/canyonlands_defconfig
arch/powerpc/configs/44x/ebony_defconfig
arch/powerpc/configs/44x/eiger_defconfig
arch/powerpc/configs/44x/icon_defconfig
arch/powerpc/configs/44x/katmai_defconfig
arch/powerpc/configs/44x/redwood_defconfig
arch/powerpc/configs/44x/sam440ep_defconfig
arch/powerpc/configs/44x/sequoia_defconfig
arch/powerpc/configs/44x/taishan_defconfig
arch/powerpc/configs/44x/warp_defconfig
arch/powerpc/configs/52xx/tqm5200_defconfig
arch/powerpc/configs/ppc40x_defconfig
arch/powerpc/configs/ppc44x_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/include/asm/kexec.h
arch/powerpc/include/asm/thread_info.h
arch/powerpc/kernel/misc_32.S
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/40x/Makefile
arch/powerpc/platforms/40x/hcu4.c [deleted file]
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/512x/mpc512x_shared.c
arch/powerpc/platforms/52xx/mpc5200_simple.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/cell/Kconfig
arch/powerpc/sysdev/fsl_soc.h
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/ppc4xx_pci.h
arch/s390/Kconfig
arch/s390/include/asm/ipl.h
arch/s390/include/asm/kexec.h
arch/s390/include/asm/qdio.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/system.h
arch/s390/include/asm/thread_info.h
arch/s390/kernel/Makefile
arch/s390/kernel/crash_dump.c [new file with mode: 0644]
arch/s390/kernel/early.c
arch/s390/kernel/head.S
arch/s390/kernel/head_kdump.S [new file with mode: 0644]
arch/s390/kernel/ipl.c
arch/s390/kernel/machine_kexec.c
arch/s390/kernel/mem_detect.c
arch/s390/kernel/setup.c
arch/s390/kernel/suspend.c
arch/s390/kernel/swsusp_asm64.S
arch/s390/mm/maccess.c
arch/s390/mm/vmem.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/include/asm/ptrace.h
arch/sh/include/asm/thread_info.h
arch/sh/kernel/idle.c
arch/sparc/configs/sparc32_defconfig
arch/sparc/configs/sparc64_defconfig
arch/sparc/include/asm/sigcontext.h
arch/sparc/include/asm/thread_info_32.h
arch/sparc/include/asm/thread_info_64.h
arch/sparc/kernel/Makefile
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/sigutil.h [new file with mode: 0644]
arch/sparc/kernel/sigutil_32.c [new file with mode: 0644]
arch/sparc/kernel/sigutil_64.c [new file with mode: 0644]
arch/tile/kernel/intvec_32.S
arch/tile/lib/atomic_asm_32.S
arch/um/drivers/net_kern.c
arch/um/include/asm/thread_info.h
arch/unicore32/boot/compressed/Makefile
arch/unicore32/configs/unicore32_defconfig
arch/unicore32/include/asm/bitops.h
arch/unicore32/include/asm/io.h
arch/unicore32/include/asm/thread_info.h
arch/unicore32/kernel/ksyms.c
arch/unicore32/lib/findbit.S
arch/x86/Kconfig
arch/x86/crypto/Makefile
arch/x86/crypto/sha1_ssse3_asm.S [new file with mode: 0644]
arch/x86/crypto/sha1_ssse3_glue.c [new file with mode: 0644]
arch/x86/include/asm/archrandom.h [new file with mode: 0644]
arch/x86/include/asm/cmpxchg_32.h
arch/x86/include/asm/cmpxchg_64.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/elf.h
arch/x86/include/asm/pgtable_types.h
arch/x86/include/asm/spinlock.h
arch/x86/include/asm/spinlock_types.h
arch/x86/include/asm/thread_info.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpu.h
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/rdrand.c [new file with mode: 0644]
arch/x86/kernel/sys_x86_64.c
arch/x86/kernel/x86_init.c
arch/x86/lguest/boot.c
arch/x86/mm/fault.c
arch/x86/mm/init.c
arch/x86/mm/mmap.c
arch/x86/platform/olpc/olpc.c
arch/x86/vdso/vma.c
arch/x86/xen/Kconfig
arch/x86/xen/mmu.c
arch/xtensa/include/asm/thread_info.h
arch/xtensa/platforms/iss/network.c
crypto/Kconfig
crypto/cryptd.c
crypto/sha1_generic.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/apei/Kconfig
drivers/acpi/apei/apei-base.c
drivers/acpi/apei/erst.c
drivers/acpi/processor_idle.c
drivers/acpi/reboot.c
drivers/acpi/scan.c
drivers/ata/libata-eh.c
drivers/ata/pata_at91.c
drivers/ata/sata_sil24.c
drivers/base/core.c
drivers/base/devres.c
drivers/base/devtmpfs.c
drivers/base/platform.c
drivers/base/power/Makefile
drivers/base/power/clock_ops.c
drivers/base/power/common.c [new file with mode: 0644]
drivers/base/power/domain.c
drivers/base/power/main.c
drivers/base/power/qos.c [new file with mode: 0644]
drivers/base/power/runtime.c
drivers/base/regmap/Makefile
drivers/base/regmap/internal.h [new file with mode: 0644]
drivers/base/regmap/regmap-debugfs.c [new file with mode: 0644]
drivers/base/regmap/regmap-i2c.c
drivers/base/regmap/regmap-spi.c
drivers/base/regmap/regmap.c
drivers/bcma/Kconfig
drivers/bcma/Makefile
drivers/bcma/bcma_private.h
drivers/bcma/core.c
drivers/bcma/driver_chipcommon.c
drivers/bcma/driver_chipcommon_pmu.c
drivers/bcma/driver_mips.c [new file with mode: 0644]
drivers/bcma/driver_pci.c
drivers/bcma/host_soc.c [new file with mode: 0644]
drivers/bcma/main.c
drivers/bcma/scan.c
drivers/bcma/sprom.c
drivers/block/cciss.c
drivers/block/cciss.h
drivers/block/rbd.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btusb.c
drivers/char/agp/hp-agp.c
drivers/char/apm-emulation.c
drivers/char/random.c
drivers/char/tpm/tpm.c
drivers/char/virtio_console.c
drivers/clocksource/sh_cmt.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/e_powersaver.c
drivers/cpufreq/exynos4210-cpufreq.c
drivers/cpuidle/cpuidle.c
drivers/cpuidle/governors/ladder.c
drivers/cpuidle/governors/menu.c
drivers/crypto/n2_core.c
drivers/crypto/padlock-aes.c
drivers/crypto/picoxcell_crypto.c
drivers/dma/at_hdmac.c
drivers/dma/at_hdmac_regs.h
drivers/dma/dmatest.c
drivers/dma/mxs-dma.c
drivers/edac/Kconfig
drivers/edac/Makefile
drivers/edac/edac_core.h
drivers/edac/edac_mce.c [deleted file]
drivers/edac/i7core_edac.c
drivers/edac/mce_amd.c
drivers/edac/ppc4xx_edac.c
drivers/firewire/sbp2.c
drivers/firmware/efivars.c
drivers/firmware/google/gsmi.c
drivers/gpio/Makefile
drivers/gpio/gpio-davinci.c [moved from arch/arm/mach-davinci/gpio.c with 99% similarity]
drivers/gpio/gpio-ep93xx.c
drivers/gpio/gpio-ks8695.c [moved from arch/arm/mach-ks8695/gpio.c with 99% similarity]
drivers/gpio/gpio-lpc32xx.c [moved from arch/arm/mach-lpc32xx/gpiolib.c with 99% similarity]
drivers/gpio/gpio-nomadik.c
drivers/gpio/gpio-omap.c
drivers/gpio/gpio-sa1100.c [moved from arch/arm/mach-sa1100/gpio.c with 96% similarity]
drivers/gpio/gpio-tnetv107x.c [moved from arch/arm/mach-davinci/gpio-tnetv107x.c with 100% similarity]
drivers/gpio/gpio-u300.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_test.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/hid/Kconfig
drivers/hid/Makefile
drivers/hid/hid-apple.c
drivers/hid/hid-axff.c
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-ids.h
drivers/hid/hid-lg.c
drivers/hid/hid-lg.h
drivers/hid/hid-lg4ff.c
drivers/hid/hid-lgff.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-picolcd.c
drivers/hid/hid-prodikeys.c
drivers/hid/hid-sjoy.c
drivers/hid/hid-zydacron.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-quirks.c
drivers/hwmon/Kconfig
drivers/hwmon/ibmaem.c
drivers/hwmon/ntc_thermistor.c
drivers/hwmon/w83627ehf.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-ixp2000.c
drivers/ide/at91_ide.c
drivers/infiniband/hw/cxgb3/Makefile
drivers/infiniband/hw/cxgb4/Makefile
drivers/infiniband/hw/mlx4/Kconfig
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/input/input-polldev.c
drivers/input/joystick/analog.c
drivers/input/keyboard/ep93xx_keypad.c
drivers/input/keyboard/omap-keypad.c
drivers/input/keyboard/tegra-kbc.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ad714x-i2c.c
drivers/input/misc/ad714x-spi.c
drivers/input/misc/ad714x.c
drivers/input/misc/ad714x.h
drivers/input/misc/bma150.c [new file with mode: 0644]
drivers/input/misc/mma8450.c
drivers/input/misc/mpu3050.c
drivers/input/misc/pm8xxx-vibrator.c [new file with mode: 0644]
drivers/input/mouse/bcm5974.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/max11801_ts.c
drivers/input/touchscreen/tnetv107x-ts.c
drivers/leds/leds-asic3.c
drivers/lguest/core.c
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/dm-crypt.c
drivers/md/dm-flakey.c
drivers/md/dm-kcopyd.c
drivers/md/dm-raid.c
drivers/md/dm-table.c
drivers/md/dm-thin-metadata.c [new file with mode: 0644]
drivers/md/dm-thin-metadata.h [new file with mode: 0644]
drivers/md/dm-thin.c [new file with mode: 0644]
drivers/md/dm.c
drivers/md/md.c
drivers/md/persistent-data/Kconfig [new file with mode: 0644]
drivers/md/persistent-data/Makefile [new file with mode: 0644]
drivers/md/persistent-data/dm-block-manager.c [new file with mode: 0644]
drivers/md/persistent-data/dm-block-manager.h [new file with mode: 0644]
drivers/md/persistent-data/dm-btree-internal.h [new file with mode: 0644]
drivers/md/persistent-data/dm-btree-remove.c [new file with mode: 0644]
drivers/md/persistent-data/dm-btree-spine.c [new file with mode: 0644]
drivers/md/persistent-data/dm-btree.c [new file with mode: 0644]
drivers/md/persistent-data/dm-btree.h [new file with mode: 0644]
drivers/md/persistent-data/dm-persistent-data-internal.h [new file with mode: 0644]
drivers/md/persistent-data/dm-space-map-common.h [new file with mode: 0644]
drivers/md/persistent-data/dm-space-map-disk.c [new file with mode: 0644]
drivers/md/persistent-data/dm-space-map-disk.h [new file with mode: 0644]
drivers/md/persistent-data/dm-space-map-metadata.c [new file with mode: 0644]
drivers/md/persistent-data/dm-space-map-metadata.h [new file with mode: 0644]
drivers/md/persistent-data/dm-space-map.h [new file with mode: 0644]
drivers/md/persistent-data/dm-transaction-manager.c [new file with mode: 0644]
drivers/md/persistent-data/dm-transaction-manager.h [new file with mode: 0644]
drivers/md/raid5.c
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/video/via-camera.c
drivers/mfd/Kconfig
drivers/mfd/ab3550-core.c
drivers/mfd/ab8500-gpadc.c
drivers/mfd/asic3.c
drivers/mfd/max8997.c
drivers/mfd/menelaus.c
drivers/mfd/omap-usb-host.c
drivers/mfd/pcf50633-core.c
drivers/mfd/tc3589x.c
drivers/mfd/timberdale.c
drivers/mfd/tps65910-irq.c
drivers/mfd/twl4030-irq.c
drivers/mfd/twl4030-madc.c
drivers/mfd/twl6030-irq.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm831x-i2c.c
drivers/mfd/wm831x-irq.c
drivers/mfd/wm831x-spi.c
drivers/mfd/wm8350-gpio.c
drivers/mfd/wm8400-core.c
drivers/mfd/wm8994-core.c
drivers/misc/Kconfig
drivers/misc/pch_phub.c
drivers/misc/ti-st/st_core.c
drivers/misc/ti-st/st_kim.c
drivers/misc/ti-st/st_ll.c
drivers/mmc/core/core.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/host.c
drivers/mmc/core/host.h
drivers/mmc/core/sd.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/atmel-mci-regs.h
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/omap.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sh_mobile_sdhi.c
drivers/mtd/Kconfig
drivers/mtd/Makefile
drivers/mtd/afs.c
drivers/mtd/ar7part.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/fwh_lock.h
drivers/mtd/chips/jedec_probe.c
drivers/mtd/cmdlinepart.c
drivers/mtd/devices/doc2000.c
drivers/mtd/devices/doc2001.c
drivers/mtd/devices/doc2001plus.c
drivers/mtd/devices/docecc.c
drivers/mtd/devices/lart.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/devices/sst25l.c
drivers/mtd/ftl.c
drivers/mtd/inftlcore.c
drivers/mtd/inftlmount.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/ceiva.c [deleted file]
drivers/mtd/maps/dc21285.c
drivers/mtd/maps/edb7312.c [deleted file]
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/h720x-flash.c
drivers/mtd/maps/impa7.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/lantiq-flash.c
drivers/mtd/maps/latch-addr-flash.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/physmap.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/rbtx4939-flash.c
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/maps/solutionengine.c
drivers/mtd/maps/wr_sbc82xx_flash.c
drivers/mtd/mtdblock.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdcore.h
drivers/mtd/mtdpart.c
drivers/mtd/mtdsuper.c
drivers/mtd/mtdswap.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/ams-delta.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/autcpu12.c
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/cmx270_nand.c
drivers/mtd/nand/cs553x_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/edb7312.c [deleted file]
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/fsmc_nand.c
drivers/mtd/nand/h1910.c
drivers/mtd/nand/jz4740_nand.c
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_bch.c
drivers/mtd/nand/nand_ecc.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/nomadik_nand.c
drivers/mtd/nand/nuc900_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/pasemi_nand.c
drivers/mtd/nand/plat_nand.c
drivers/mtd/nand/ppchameleonevb.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/sharpsl.c
drivers/mtd/nand/socrates_nand.c
drivers/mtd/nand/tmio_nand.c
drivers/mtd/nand/txx9ndfmc.c
drivers/mtd/nftlcore.c
drivers/mtd/nftlmount.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/generic.c
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_bbt.c
drivers/mtd/onenand/samsung.c
drivers/mtd/redboot.c
drivers/mtd/sm_ftl.c
drivers/mtd/ssfdc.c
drivers/mtd/tests/mtd_readtest.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/appletalk/cops.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/com20020.c
drivers/net/arm/Kconfig [deleted file]
drivers/net/arm/Makefile [deleted file]
drivers/net/benet/Kconfig [deleted file]
drivers/net/bna/bfi_ctreg.h [deleted file]
drivers/net/bna/bfi_ll.h [deleted file]
drivers/net/bna/bna_ctrl.c [deleted file]
drivers/net/bna/bna_hw.h [deleted file]
drivers/net/bna/bna_txrx.c [deleted file]
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/can/flexcan.c
drivers/net/can/mscan/mscan.c
drivers/net/can/sja1000/plx_pci.c
drivers/net/cris/eth_v10.c
drivers/net/defxx.c
drivers/net/dummy.c
drivers/net/ethernet/3com/3c501.c [moved from drivers/net/3c501.c with 99% similarity]
drivers/net/ethernet/3com/3c501.h [moved from drivers/net/3c501.h with 100% similarity]
drivers/net/ethernet/3com/3c509.c [moved from drivers/net/3c509.c with 99% similarity]
drivers/net/ethernet/3com/3c515.c [moved from drivers/net/3c515.c with 99% similarity]
drivers/net/ethernet/3com/3c574_cs.c [moved from drivers/net/pcmcia/3c574_cs.c with 99% similarity]
drivers/net/ethernet/3com/3c589_cs.c [moved from drivers/net/pcmcia/3c589_cs.c with 99% similarity]
drivers/net/ethernet/3com/3c59x.c [moved from drivers/net/3c59x.c with 99% similarity]
drivers/net/ethernet/3com/Kconfig [new file with mode: 0644]
drivers/net/ethernet/3com/Makefile [new file with mode: 0644]
drivers/net/ethernet/3com/typhoon.c [moved from drivers/net/typhoon.c with 99% similarity]
drivers/net/ethernet/3com/typhoon.h [moved from drivers/net/typhoon.h with 100% similarity]
drivers/net/ethernet/8390/3c503.c [moved from drivers/net/3c503.c with 99% similarity]
drivers/net/ethernet/8390/3c503.h [moved from drivers/net/3c503.h with 100% similarity]
drivers/net/ethernet/8390/8390.c [moved from drivers/net/8390.c with 97% similarity]
drivers/net/ethernet/8390/8390.h [moved from drivers/net/8390.h with 100% similarity]
drivers/net/ethernet/8390/8390p.c [moved from drivers/net/8390p.c with 97% similarity]
drivers/net/ethernet/8390/Kconfig [new file with mode: 0644]
drivers/net/ethernet/8390/Makefile [new file with mode: 0644]
drivers/net/ethernet/8390/ac3200.c [moved from drivers/net/ac3200.c with 99% similarity]
drivers/net/ethernet/8390/apne.c [moved from drivers/net/apne.c with 100% similarity]
drivers/net/ethernet/8390/ax88796.c [moved from drivers/net/ax88796.c with 99% similarity]
drivers/net/ethernet/8390/axnet_cs.c [moved from drivers/net/pcmcia/axnet_cs.c with 99% similarity]
drivers/net/ethernet/8390/e2100.c [moved from drivers/net/e2100.c with 99% similarity]
drivers/net/ethernet/8390/es3210.c [moved from drivers/net/es3210.c with 100% similarity]
drivers/net/ethernet/8390/etherh.c [moved from drivers/net/arm/etherh.c with 99% similarity]
drivers/net/ethernet/8390/hp-plus.c [moved from drivers/net/hp-plus.c with 99% similarity]
drivers/net/ethernet/8390/hp.c [moved from drivers/net/hp.c with 100% similarity]
drivers/net/ethernet/8390/hydra.c [moved from drivers/net/hydra.c with 99% similarity]
drivers/net/ethernet/8390/lib8390.c [moved from drivers/net/lib8390.c with 100% similarity]
drivers/net/ethernet/8390/lne390.c [moved from drivers/net/lne390.c with 100% similarity]
drivers/net/ethernet/8390/mac8390.c [moved from drivers/net/mac8390.c with 99% similarity]
drivers/net/ethernet/8390/ne-h8300.c [moved from drivers/net/ne-h8300.c with 99% similarity]
drivers/net/ethernet/8390/ne.c [moved from drivers/net/ne.c with 100% similarity]
drivers/net/ethernet/8390/ne2.c [moved from drivers/net/ne2.c with 100% similarity]
drivers/net/ethernet/8390/ne2k-pci.c [moved from drivers/net/ne2k-pci.c with 99% similarity]
drivers/net/ethernet/8390/ne3210.c [moved from drivers/net/ne3210.c with 100% similarity]
drivers/net/ethernet/8390/pcnet_cs.c [moved from drivers/net/pcmcia/pcnet_cs.c with 99% similarity]
drivers/net/ethernet/8390/smc-mca.c [moved from drivers/net/smc-mca.c with 99% similarity]
drivers/net/ethernet/8390/smc-ultra.c [moved from drivers/net/smc-ultra.c with 99% similarity]
drivers/net/ethernet/8390/smc-ultra32.c [moved from drivers/net/smc-ultra32.c with 99% similarity]
drivers/net/ethernet/8390/stnic.c [moved from drivers/net/stnic.c with 100% similarity]
drivers/net/ethernet/8390/wd.c [moved from drivers/net/wd.c with 99% similarity]
drivers/net/ethernet/8390/zorro8390.c [moved from drivers/net/zorro8390.c with 99% similarity]
drivers/net/ethernet/Kconfig [new file with mode: 0644]
drivers/net/ethernet/Makefile [new file with mode: 0644]
drivers/net/ethernet/adaptec/Kconfig [new file with mode: 0644]
drivers/net/ethernet/adaptec/Makefile [new file with mode: 0644]
drivers/net/ethernet/adaptec/starfire.c [moved from drivers/net/starfire.c with 99% similarity]
drivers/net/ethernet/adi/Kconfig [new file with mode: 0644]
drivers/net/ethernet/adi/Makefile [new file with mode: 0644]
drivers/net/ethernet/adi/bfin_mac.c [moved from drivers/net/bfin_mac.c with 99% similarity]
drivers/net/ethernet/adi/bfin_mac.h [moved from drivers/net/bfin_mac.h with 100% similarity]
drivers/net/ethernet/aeroflex/Kconfig [new file with mode: 0644]
drivers/net/ethernet/aeroflex/Makefile [new file with mode: 0644]
drivers/net/ethernet/aeroflex/greth.c [moved from drivers/net/greth.c with 99% similarity]
drivers/net/ethernet/aeroflex/greth.h [moved from drivers/net/greth.h with 100% similarity]
drivers/net/ethernet/alteon/Kconfig [new file with mode: 0644]
drivers/net/ethernet/alteon/Makefile [new file with mode: 0644]
drivers/net/ethernet/alteon/acenic.c [moved from drivers/net/acenic.c with 99% similarity]
drivers/net/ethernet/alteon/acenic.h [moved from drivers/net/acenic.h with 100% similarity]
drivers/net/ethernet/amd/7990.c [moved from drivers/net/7990.c with 100% similarity]
drivers/net/ethernet/amd/7990.h [moved from drivers/net/7990.h with 100% similarity]
drivers/net/ethernet/amd/Kconfig [new file with mode: 0644]
drivers/net/ethernet/amd/Makefile [new file with mode: 0644]
drivers/net/ethernet/amd/a2065.c [moved from drivers/net/a2065.c with 99% similarity]
drivers/net/ethernet/amd/a2065.h [moved from drivers/net/a2065.h with 100% similarity]
drivers/net/ethernet/amd/am79c961a.c [moved from drivers/net/arm/am79c961a.c with 99% similarity]
drivers/net/ethernet/amd/am79c961a.h [moved from drivers/net/arm/am79c961a.h with 100% similarity]
drivers/net/ethernet/amd/amd8111e.c [moved from drivers/net/amd8111e.c with 99% similarity]
drivers/net/ethernet/amd/amd8111e.h [moved from drivers/net/amd8111e.h with 100% similarity]
drivers/net/ethernet/amd/ariadne.c [moved from drivers/net/ariadne.c with 99% similarity]
drivers/net/ethernet/amd/ariadne.h [moved from drivers/net/ariadne.h with 100% similarity]
drivers/net/ethernet/amd/atarilance.c [moved from drivers/net/atarilance.c with 99% similarity]
drivers/net/ethernet/amd/au1000_eth.c [moved from drivers/net/au1000_eth.c with 99% similarity]
drivers/net/ethernet/amd/au1000_eth.h [moved from drivers/net/au1000_eth.h with 100% similarity]
drivers/net/ethernet/amd/declance.c [moved from drivers/net/declance.c with 99% similarity]
drivers/net/ethernet/amd/depca.c [moved from drivers/net/depca.c with 99% similarity]
drivers/net/ethernet/amd/depca.h [moved from drivers/net/depca.h with 100% similarity]
drivers/net/ethernet/amd/hplance.c [moved from drivers/net/hplance.c with 99% similarity]
drivers/net/ethernet/amd/hplance.h [moved from drivers/net/hplance.h with 100% similarity]
drivers/net/ethernet/amd/lance.c [moved from drivers/net/lance.c with 99% similarity]
drivers/net/ethernet/amd/mvme147.c [moved from drivers/net/mvme147.c with 99% similarity]
drivers/net/ethernet/amd/ni65.c [moved from drivers/net/ni65.c with 99% similarity]
drivers/net/ethernet/amd/ni65.h [moved from drivers/net/ni65.h with 100% similarity]
drivers/net/ethernet/amd/nmclan_cs.c [moved from drivers/net/pcmcia/nmclan_cs.c with 99% similarity]
drivers/net/ethernet/amd/pcnet32.c [moved from drivers/net/pcnet32.c with 99% similarity]
drivers/net/ethernet/amd/sun3lance.c [moved from drivers/net/sun3lance.c with 99% similarity]
drivers/net/ethernet/amd/sunlance.c [moved from drivers/net/sunlance.c with 99% similarity]
drivers/net/ethernet/apple/Kconfig [new file with mode: 0644]
drivers/net/ethernet/apple/Makefile [new file with mode: 0644]
drivers/net/ethernet/apple/bmac.c [moved from drivers/net/bmac.c with 99% similarity]
drivers/net/ethernet/apple/bmac.h [moved from drivers/net/bmac.h with 100% similarity]
drivers/net/ethernet/apple/cs89x0.c [moved from drivers/net/cs89x0.c with 99% similarity]
drivers/net/ethernet/apple/cs89x0.h [moved from drivers/net/cs89x0.h with 100% similarity]
drivers/net/ethernet/apple/mac89x0.c [moved from drivers/net/mac89x0.c with 99% similarity]
drivers/net/ethernet/apple/mace.c [moved from drivers/net/mace.c with 99% similarity]
drivers/net/ethernet/apple/mace.h [moved from drivers/net/mace.h with 100% similarity]
drivers/net/ethernet/apple/macmace.c [moved from drivers/net/macmace.c with 99% similarity]
drivers/net/ethernet/atheros/Kconfig [new file with mode: 0644]
drivers/net/ethernet/atheros/Makefile [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/Makefile [moved from drivers/net/atl1c/Makefile with 100% similarity]
drivers/net/ethernet/atheros/atl1c/atl1c.h [moved from drivers/net/atl1c/atl1c.h with 100% similarity]
drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c [moved from drivers/net/atl1c/atl1c_ethtool.c with 100% similarity]
drivers/net/ethernet/atheros/atl1c/atl1c_hw.c [moved from drivers/net/atl1c/atl1c_hw.c with 100% similarity]
drivers/net/ethernet/atheros/atl1c/atl1c_hw.h [moved from drivers/net/atl1c/atl1c_hw.h with 100% similarity]
drivers/net/ethernet/atheros/atl1c/atl1c_main.c [moved from drivers/net/atl1c/atl1c_main.c with 99% similarity]
drivers/net/ethernet/atheros/atl1e/Makefile [moved from drivers/net/atl1e/Makefile with 100% similarity]
drivers/net/ethernet/atheros/atl1e/atl1e.h [moved from drivers/net/atl1e/atl1e.h with 100% similarity]
drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c [moved from drivers/net/atl1e/atl1e_ethtool.c with 100% similarity]
drivers/net/ethernet/atheros/atl1e/atl1e_hw.c [moved from drivers/net/atl1e/atl1e_hw.c with 100% similarity]
drivers/net/ethernet/atheros/atl1e/atl1e_hw.h [moved from drivers/net/atl1e/atl1e_hw.h with 100% similarity]
drivers/net/ethernet/atheros/atl1e/atl1e_main.c [moved from drivers/net/atl1e/atl1e_main.c with 99% similarity]
drivers/net/ethernet/atheros/atl1e/atl1e_param.c [moved from drivers/net/atl1e/atl1e_param.c with 100% similarity]
drivers/net/ethernet/atheros/atlx/Makefile [moved from drivers/net/atlx/Makefile with 100% similarity]
drivers/net/ethernet/atheros/atlx/atl1.c [moved from drivers/net/atlx/atl1.c with 99% similarity]
drivers/net/ethernet/atheros/atlx/atl1.h [moved from drivers/net/atlx/atl1.h with 100% similarity]
drivers/net/ethernet/atheros/atlx/atl2.c [moved from drivers/net/atlx/atl2.c with 99% similarity]
drivers/net/ethernet/atheros/atlx/atl2.h [moved from drivers/net/atlx/atl2.h with 100% similarity]
drivers/net/ethernet/atheros/atlx/atlx.c [moved from drivers/net/atlx/atlx.c with 100% similarity]
drivers/net/ethernet/atheros/atlx/atlx.h [moved from drivers/net/atlx/atlx.h with 100% similarity]
drivers/net/ethernet/broadcom/Kconfig [new file with mode: 0644]
drivers/net/ethernet/broadcom/Makefile [new file with mode: 0644]
drivers/net/ethernet/broadcom/b44.c [moved from drivers/net/b44.c with 99% similarity]
drivers/net/ethernet/broadcom/b44.h [moved from drivers/net/b44.h with 100% similarity]
drivers/net/ethernet/broadcom/bcm63xx_enet.c [moved from drivers/net/bcm63xx_enet.c with 99% similarity]
drivers/net/ethernet/broadcom/bcm63xx_enet.h [moved from drivers/net/bcm63xx_enet.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2.c [moved from drivers/net/bnx2.c with 99% similarity]
drivers/net/ethernet/broadcom/bnx2.h [moved from drivers/net/bnx2.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2_fw.h [moved from drivers/net/bnx2_fw.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/Makefile [moved from drivers/net/bnx2x/Makefile with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h [moved from drivers/net/bnx2x/bnx2x.h with 98% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c [moved from drivers/net/bnx2x/bnx2x_cmn.c with 98% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h [moved from drivers/net/bnx2x/bnx2x_cmn.h with 99% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c [moved from drivers/net/bnx2x/bnx2x_dcb.c with 99% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h [moved from drivers/net/bnx2x/bnx2x_dcb.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h [moved from drivers/net/bnx2x/bnx2x_dump.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c [moved from drivers/net/bnx2x/bnx2x_ethtool.c with 99% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h [moved from drivers/net/bnx2x/bnx2x_fw_defs.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h [moved from drivers/net/bnx2x/bnx2x_fw_file_hdr.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h [moved from drivers/net/bnx2x/bnx2x_hsi.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h [moved from drivers/net/bnx2x/bnx2x_init.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h [moved from drivers/net/bnx2x/bnx2x_init_ops.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c [moved from drivers/net/bnx2x/bnx2x_link.c with 99% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h [moved from drivers/net/bnx2x/bnx2x_link.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c [moved from drivers/net/bnx2x/bnx2x_main.c with 99% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h [moved from drivers/net/bnx2x/bnx2x_reg.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c [moved from drivers/net/bnx2x/bnx2x_sp.c with 98% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h [moved from drivers/net/bnx2x/bnx2x_sp.h with 100% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c [moved from drivers/net/bnx2x/bnx2x_stats.c with 98% similarity]
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h [moved from drivers/net/bnx2x/bnx2x_stats.h with 100% similarity]
drivers/net/ethernet/broadcom/cnic.c [moved from drivers/net/cnic.c with 99% similarity]
drivers/net/ethernet/broadcom/cnic.h [moved from drivers/net/cnic.h with 100% similarity]
drivers/net/ethernet/broadcom/cnic_defs.h [moved from drivers/net/cnic_defs.h with 100% similarity]
drivers/net/ethernet/broadcom/cnic_if.h [moved from drivers/net/cnic_if.h with 100% similarity]
drivers/net/ethernet/broadcom/sb1250-mac.c [moved from drivers/net/sb1250-mac.c with 99% similarity]
drivers/net/ethernet/broadcom/tg3.c [moved from drivers/net/tg3.c with 98% similarity]
drivers/net/ethernet/broadcom/tg3.h [moved from drivers/net/tg3.h with 99% similarity]
drivers/net/ethernet/brocade/Kconfig [new file with mode: 0644]
drivers/net/ethernet/brocade/Makefile [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/Kconfig [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/Makefile [moved from drivers/net/bna/Makefile with 52% similarity]
drivers/net/ethernet/brocade/bna/bfa_cee.c [moved from drivers/net/bna/bfa_cee.c with 98% similarity]
drivers/net/ethernet/brocade/bna/bfa_cee.h [moved from drivers/net/bna/bfa_cee.h with 100% similarity]
drivers/net/ethernet/brocade/bna/bfa_cs.h [moved from drivers/net/bna/bfa_cs.h with 100% similarity]
drivers/net/ethernet/brocade/bna/bfa_defs.h [moved from drivers/net/bna/bfa_defs.h with 92% similarity]
drivers/net/ethernet/brocade/bna/bfa_defs_cna.h [moved from drivers/net/bna/bfa_defs_cna.h with 100% similarity]
drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h [moved from drivers/net/bna/bfa_defs_mfg_comm.h with 89% similarity]
drivers/net/ethernet/brocade/bna/bfa_defs_status.h [moved from drivers/net/bna/bfa_defs_status.h with 100% similarity]
drivers/net/ethernet/brocade/bna/bfa_ioc.c [moved from drivers/net/bna/bfa_ioc.c with 87% similarity]
drivers/net/ethernet/brocade/bna/bfa_ioc.h [moved from drivers/net/bna/bfa_ioc.h with 88% similarity]
drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c [moved from drivers/net/bna/bfa_ioc_ct.c with 76% similarity]
drivers/net/ethernet/brocade/bna/bfa_msgq.c [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bfa_msgq.h [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bfi.h [moved from drivers/net/bna/bfi.h with 70% similarity]
drivers/net/ethernet/brocade/bna/bfi_cna.h [moved from drivers/net/bna/bfi_cna.h with 100% similarity]
drivers/net/ethernet/brocade/bna/bfi_enet.h [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bfi_reg.h [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bna.h [moved from drivers/net/bna/bna.h with 67% similarity]
drivers/net/ethernet/brocade/bna/bna_enet.c [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bna_hw_defs.h [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bna_tx_rx.c [new file with mode: 0644]
drivers/net/ethernet/brocade/bna/bna_types.h [moved from drivers/net/bna/bna_types.h with 58% similarity]
drivers/net/ethernet/brocade/bna/bnad.c [moved from drivers/net/bna/bnad.c with 85% similarity]
drivers/net/ethernet/brocade/bna/bnad.h [moved from drivers/net/bna/bnad.h with 89% similarity]
drivers/net/ethernet/brocade/bna/bnad_ethtool.c [moved from drivers/net/bna/bnad_ethtool.c with 67% similarity]
drivers/net/ethernet/brocade/bna/cna.h [moved from drivers/net/bna/cna.h with 68% similarity]
drivers/net/ethernet/brocade/bna/cna_fwimg.c [moved from drivers/net/bna/cna_fwimg.c with 100% similarity]
drivers/net/ethernet/cadence/Kconfig [new file with mode: 0644]
drivers/net/ethernet/cadence/Makefile [new file with mode: 0644]
drivers/net/ethernet/cadence/at91_ether.c [moved from drivers/net/arm/at91_ether.c with 99% similarity]
drivers/net/ethernet/cadence/at91_ether.h [moved from drivers/net/arm/at91_ether.h with 100% similarity]
drivers/net/ethernet/cadence/macb.c [moved from drivers/net/macb.c with 99% similarity]
drivers/net/ethernet/cadence/macb.h [moved from drivers/net/macb.h with 100% similarity]
drivers/net/ethernet/chelsio/Kconfig [new file with mode: 0644]
drivers/net/ethernet/chelsio/Makefile [new file with mode: 0644]
drivers/net/ethernet/chelsio/cxgb/Makefile [moved from drivers/net/chelsio/Makefile with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/common.h [moved from drivers/net/chelsio/common.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/cphy.h [moved from drivers/net/chelsio/cphy.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/cpl5_cmd.h [moved from drivers/net/chelsio/cpl5_cmd.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/cxgb2.c [moved from drivers/net/chelsio/cxgb2.c with 99% similarity]
drivers/net/ethernet/chelsio/cxgb/elmer0.h [moved from drivers/net/chelsio/elmer0.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/espi.c [moved from drivers/net/chelsio/espi.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/espi.h [moved from drivers/net/chelsio/espi.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/fpga_defs.h [moved from drivers/net/chelsio/fpga_defs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/gmac.h [moved from drivers/net/chelsio/gmac.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c [moved from drivers/net/chelsio/mv88e1xxx.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.h [moved from drivers/net/chelsio/mv88e1xxx.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/mv88x201x.c [moved from drivers/net/chelsio/mv88x201x.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/my3126.c [moved from drivers/net/chelsio/my3126.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/pm3393.c [moved from drivers/net/chelsio/pm3393.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/regs.h [moved from drivers/net/chelsio/regs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/sge.c [moved from drivers/net/chelsio/sge.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/sge.h [moved from drivers/net/chelsio/sge.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/subr.c [moved from drivers/net/chelsio/subr.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/suni1x10gexp_regs.h [moved from drivers/net/chelsio/suni1x10gexp_regs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/tp.c [moved from drivers/net/chelsio/tp.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/tp.h [moved from drivers/net/chelsio/tp.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/vsc7326.c [moved from drivers/net/chelsio/vsc7326.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb/vsc7326_reg.h [moved from drivers/net/chelsio/vsc7326_reg.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/Makefile [moved from drivers/net/cxgb3/Makefile with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/adapter.h [moved from drivers/net/cxgb3/adapter.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/ael1002.c [moved from drivers/net/cxgb3/ael1002.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/aq100x.c [moved from drivers/net/cxgb3/aq100x.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/common.h [moved from drivers/net/cxgb3/common.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/cxgb3_ctl_defs.h [moved from drivers/net/cxgb3/cxgb3_ctl_defs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h [moved from drivers/net/cxgb3/cxgb3_defs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/cxgb3_ioctl.h [moved from drivers/net/cxgb3/cxgb3_ioctl.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c [moved from drivers/net/cxgb3/cxgb3_main.c with 99% similarity]
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c [moved from drivers/net/cxgb3/cxgb3_offload.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.h [moved from drivers/net/cxgb3/cxgb3_offload.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/firmware_exports.h [moved from drivers/net/cxgb3/firmware_exports.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/l2t.c [moved from drivers/net/cxgb3/l2t.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/l2t.h [moved from drivers/net/cxgb3/l2t.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/mc5.c [moved from drivers/net/cxgb3/mc5.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/regs.h [moved from drivers/net/cxgb3/regs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/sge.c [moved from drivers/net/cxgb3/sge.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/sge_defs.h [moved from drivers/net/cxgb3/sge_defs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/t3_cpl.h [moved from drivers/net/cxgb3/t3_cpl.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/t3_hw.c [moved from drivers/net/cxgb3/t3_hw.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/t3cdev.h [moved from drivers/net/cxgb3/t3cdev.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/version.h [moved from drivers/net/cxgb3/version.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/vsc8211.c [moved from drivers/net/cxgb3/vsc8211.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb3/xgmac.c [moved from drivers/net/cxgb3/xgmac.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/Makefile [moved from drivers/net/cxgb4/Makefile with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h [moved from drivers/net/cxgb4/cxgb4.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c [moved from drivers/net/cxgb4/cxgb4_main.c with 99% similarity]
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h [moved from drivers/net/cxgb4/cxgb4_uld.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/l2t.c [moved from drivers/net/cxgb4/l2t.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/l2t.h [moved from drivers/net/cxgb4/l2t.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/sge.c [moved from drivers/net/cxgb4/sge.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c [moved from drivers/net/cxgb4/t4_hw.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h [moved from drivers/net/cxgb4/t4_hw.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h [moved from drivers/net/cxgb4/t4_msg.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h [moved from drivers/net/cxgb4/t4_regs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h [moved from drivers/net/cxgb4/t4fw_api.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/Makefile [moved from drivers/net/cxgb4vf/Makefile with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h [moved from drivers/net/cxgb4vf/adapter.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c [moved from drivers/net/cxgb4vf/cxgb4vf_main.c with 99% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/sge.c [moved from drivers/net/cxgb4vf/sge.c with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h [moved from drivers/net/cxgb4vf/t4vf_common.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h [moved from drivers/net/cxgb4vf/t4vf_defs.h with 100% similarity]
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c [moved from drivers/net/cxgb4vf/t4vf_hw.c with 100% similarity]
drivers/net/ethernet/cirrus/Kconfig [new file with mode: 0644]
drivers/net/ethernet/cirrus/Makefile [new file with mode: 0644]
drivers/net/ethernet/cirrus/ep93xx_eth.c [moved from drivers/net/arm/ep93xx_eth.c with 100% similarity]
drivers/net/ethernet/cisco/Kconfig [new file with mode: 0644]
drivers/net/ethernet/cisco/Makefile [new file with mode: 0644]
drivers/net/ethernet/cisco/enic/Kconfig [new file with mode: 0644]
drivers/net/ethernet/cisco/enic/Makefile [moved from drivers/net/enic/Makefile with 100% similarity]
drivers/net/ethernet/cisco/enic/cq_desc.h [moved from drivers/net/enic/cq_desc.h with 100% similarity]
drivers/net/ethernet/cisco/enic/cq_enet_desc.h [moved from drivers/net/enic/cq_enet_desc.h with 100% similarity]
drivers/net/ethernet/cisco/enic/enic.h [moved from drivers/net/enic/enic.h with 100% similarity]
drivers/net/ethernet/cisco/enic/enic_dev.c [moved from drivers/net/enic/enic_dev.c with 100% similarity]
drivers/net/ethernet/cisco/enic/enic_dev.h [moved from drivers/net/enic/enic_dev.h with 100% similarity]
drivers/net/ethernet/cisco/enic/enic_main.c [moved from drivers/net/enic/enic_main.c with 99% similarity]
drivers/net/ethernet/cisco/enic/enic_pp.c [moved from drivers/net/enic/enic_pp.c with 100% similarity]
drivers/net/ethernet/cisco/enic/enic_pp.h [moved from drivers/net/enic/enic_pp.h with 100% similarity]
drivers/net/ethernet/cisco/enic/enic_res.c [moved from drivers/net/enic/enic_res.c with 100% similarity]
drivers/net/ethernet/cisco/enic/enic_res.h [moved from drivers/net/enic/enic_res.h with 100% similarity]
drivers/net/ethernet/cisco/enic/rq_enet_desc.h [moved from drivers/net/enic/rq_enet_desc.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_cq.c [moved from drivers/net/enic/vnic_cq.c with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_cq.h [moved from drivers/net/enic/vnic_cq.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_dev.c [moved from drivers/net/enic/vnic_dev.c with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_dev.h [moved from drivers/net/enic/vnic_dev.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_devcmd.h [moved from drivers/net/enic/vnic_devcmd.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_enet.h [moved from drivers/net/enic/vnic_enet.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_intr.c [moved from drivers/net/enic/vnic_intr.c with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_intr.h [moved from drivers/net/enic/vnic_intr.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_nic.h [moved from drivers/net/enic/vnic_nic.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_resource.h [moved from drivers/net/enic/vnic_resource.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_rq.c [moved from drivers/net/enic/vnic_rq.c with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_rq.h [moved from drivers/net/enic/vnic_rq.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_rss.h [moved from drivers/net/enic/vnic_rss.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_stats.h [moved from drivers/net/enic/vnic_stats.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_vic.c [moved from drivers/net/enic/vnic_vic.c with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_vic.h [moved from drivers/net/enic/vnic_vic.h with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_wq.c [moved from drivers/net/enic/vnic_wq.c with 100% similarity]
drivers/net/ethernet/cisco/enic/vnic_wq.h [moved from drivers/net/enic/vnic_wq.h with 100% similarity]
drivers/net/ethernet/cisco/enic/wq_enet_desc.h [moved from drivers/net/enic/wq_enet_desc.h with 100% similarity]
drivers/net/ethernet/davicom/Kconfig [new file with mode: 0644]
drivers/net/ethernet/davicom/Makefile [new file with mode: 0644]
drivers/net/ethernet/davicom/dm9000.c [moved from drivers/net/dm9000.c with 99% similarity]
drivers/net/ethernet/davicom/dm9000.h [moved from drivers/net/dm9000.h with 100% similarity]
drivers/net/ethernet/dec/Kconfig [new file with mode: 0644]
drivers/net/ethernet/dec/Makefile [new file with mode: 0644]
drivers/net/ethernet/dec/ewrk3.c [moved from drivers/net/ewrk3.c with 99% similarity]
drivers/net/ethernet/dec/ewrk3.h [moved from drivers/net/ewrk3.h with 100% similarity]
drivers/net/ethernet/dec/tulip/21142.c [moved from drivers/net/tulip/21142.c with 100% similarity]
drivers/net/ethernet/dec/tulip/Kconfig [moved from drivers/net/tulip/Kconfig with 96% similarity]
drivers/net/ethernet/dec/tulip/Makefile [moved from drivers/net/tulip/Makefile with 100% similarity]
drivers/net/ethernet/dec/tulip/de2104x.c [moved from drivers/net/tulip/de2104x.c with 99% similarity]
drivers/net/ethernet/dec/tulip/de4x5.c [moved from drivers/net/tulip/de4x5.c with 99% similarity]
drivers/net/ethernet/dec/tulip/de4x5.h [moved from drivers/net/tulip/de4x5.h with 100% similarity]
drivers/net/ethernet/dec/tulip/dmfe.c [moved from drivers/net/tulip/dmfe.c with 99% similarity]
drivers/net/ethernet/dec/tulip/eeprom.c [moved from drivers/net/tulip/eeprom.c with 100% similarity]
drivers/net/ethernet/dec/tulip/interrupt.c [moved from drivers/net/tulip/interrupt.c with 100% similarity]
drivers/net/ethernet/dec/tulip/media.c [moved from drivers/net/tulip/media.c with 100% similarity]
drivers/net/ethernet/dec/tulip/pnic.c [moved from drivers/net/tulip/pnic.c with 100% similarity]
drivers/net/ethernet/dec/tulip/pnic2.c [moved from drivers/net/tulip/pnic2.c with 100% similarity]
drivers/net/ethernet/dec/tulip/timer.c [moved from drivers/net/tulip/timer.c with 100% similarity]
drivers/net/ethernet/dec/tulip/tulip.h [moved from drivers/net/tulip/tulip.h with 100% similarity]
drivers/net/ethernet/dec/tulip/tulip_core.c [moved from drivers/net/tulip/tulip_core.c with 99% similarity]
drivers/net/ethernet/dec/tulip/uli526x.c [moved from drivers/net/tulip/uli526x.c with 99% similarity]
drivers/net/ethernet/dec/tulip/winbond-840.c [moved from drivers/net/tulip/winbond-840.c with 99% similarity]
drivers/net/ethernet/dec/tulip/xircom_cb.c [moved from drivers/net/tulip/xircom_cb.c with 100% similarity]
drivers/net/ethernet/dlink/Kconfig [new file with mode: 0644]
drivers/net/ethernet/dlink/Makefile [new file with mode: 0644]
drivers/net/ethernet/dlink/de600.c [moved from drivers/net/de600.c with 100% similarity]
drivers/net/ethernet/dlink/de600.h [moved from drivers/net/de600.h with 100% similarity]
drivers/net/ethernet/dlink/de620.c [moved from drivers/net/de620.c with 99% similarity]
drivers/net/ethernet/dlink/de620.h [moved from drivers/net/de620.h with 100% similarity]
drivers/net/ethernet/dlink/dl2k.c [moved from drivers/net/dl2k.c with 99% similarity]
drivers/net/ethernet/dlink/dl2k.h [moved from drivers/net/dl2k.h with 100% similarity]
drivers/net/ethernet/dlink/sundance.c [moved from drivers/net/sundance.c with 99% similarity]
drivers/net/ethernet/dnet.c [moved from drivers/net/dnet.c with 100% similarity]
drivers/net/ethernet/dnet.h [moved from drivers/net/dnet.h with 100% similarity]
drivers/net/ethernet/emulex/Kconfig [new file with mode: 0644]
drivers/net/ethernet/emulex/Makefile [new file with mode: 0644]
drivers/net/ethernet/emulex/benet/Kconfig [new file with mode: 0644]
drivers/net/ethernet/emulex/benet/Makefile [moved from drivers/net/benet/Makefile with 100% similarity]
drivers/net/ethernet/emulex/benet/be.h [moved from drivers/net/benet/be.h with 85% similarity]
drivers/net/ethernet/emulex/benet/be_cmds.c [moved from drivers/net/benet/be_cmds.c with 94% similarity]
drivers/net/ethernet/emulex/benet/be_cmds.h [moved from drivers/net/benet/be_cmds.h with 95% similarity]
drivers/net/ethernet/emulex/benet/be_ethtool.c [moved from drivers/net/benet/be_ethtool.c with 85% similarity]
drivers/net/ethernet/emulex/benet/be_hw.h [moved from drivers/net/benet/be_hw.h with 94% similarity]
drivers/net/ethernet/emulex/benet/be_main.c [moved from drivers/net/benet/be_main.c with 91% similarity]
drivers/net/ethernet/ethoc.c [moved from drivers/net/ethoc.c with 99% similarity]
drivers/net/ethernet/faraday/Kconfig [new file with mode: 0644]
drivers/net/ethernet/faraday/Makefile [new file with mode: 0644]
drivers/net/ethernet/faraday/ftgmac100.c [moved from drivers/net/ftgmac100.c with 100% similarity]
drivers/net/ethernet/faraday/ftgmac100.h [moved from drivers/net/ftgmac100.h with 100% similarity]
drivers/net/ethernet/faraday/ftmac100.c [moved from drivers/net/ftmac100.c with 100% similarity]
drivers/net/ethernet/faraday/ftmac100.h [moved from drivers/net/ftmac100.h with 100% similarity]
drivers/net/ethernet/fealnx.c [moved from drivers/net/fealnx.c with 99% similarity]
drivers/net/ethernet/freescale/Kconfig [new file with mode: 0644]
drivers/net/ethernet/freescale/Makefile [new file with mode: 0644]
drivers/net/ethernet/freescale/fec.c [moved from drivers/net/fec.c with 99% similarity]
drivers/net/ethernet/freescale/fec.h [moved from drivers/net/fec.h with 100% similarity]
drivers/net/ethernet/freescale/fec_mpc52xx.c [moved from drivers/net/fec_mpc52xx.c with 99% similarity]
drivers/net/ethernet/freescale/fec_mpc52xx.h [moved from drivers/net/fec_mpc52xx.h with 100% similarity]
drivers/net/ethernet/freescale/fec_mpc52xx_phy.c [moved from drivers/net/fec_mpc52xx_phy.c with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/Kconfig [moved from drivers/net/fs_enet/Kconfig with 91% similarity]
drivers/net/ethernet/freescale/fs_enet/Makefile [moved from drivers/net/fs_enet/Makefile with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/fec.h [moved from drivers/net/fs_enet/fec.h with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c [moved from drivers/net/fs_enet/fs_enet-main.c with 99% similarity]
drivers/net/ethernet/freescale/fs_enet/fs_enet.h [moved from drivers/net/fs_enet/fs_enet.h with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/mac-fcc.c [moved from drivers/net/fs_enet/mac-fcc.c with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/mac-fec.c [moved from drivers/net/fs_enet/mac-fec.c with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/mac-scc.c [moved from drivers/net/fs_enet/mac-scc.c with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c [moved from drivers/net/fs_enet/mii-bitbang.c with 100% similarity]
drivers/net/ethernet/freescale/fs_enet/mii-fec.c [moved from drivers/net/fs_enet/mii-fec.c with 100% similarity]
drivers/net/ethernet/freescale/fsl_pq_mdio.c [moved from drivers/net/fsl_pq_mdio.c with 100% similarity]
drivers/net/ethernet/freescale/fsl_pq_mdio.h [moved from drivers/net/fsl_pq_mdio.h with 100% similarity]
drivers/net/ethernet/freescale/gianfar.c [moved from drivers/net/gianfar.c with 99% similarity]
drivers/net/ethernet/freescale/gianfar.h [moved from drivers/net/gianfar.h with 100% similarity]
drivers/net/ethernet/freescale/gianfar_ethtool.c [moved from drivers/net/gianfar_ethtool.c with 99% similarity]
drivers/net/ethernet/freescale/gianfar_ptp.c [moved from drivers/net/gianfar_ptp.c with 100% similarity]
drivers/net/ethernet/freescale/gianfar_sysfs.c [moved from drivers/net/gianfar_sysfs.c with 100% similarity]
drivers/net/ethernet/freescale/ucc_geth.c [moved from drivers/net/ucc_geth.c with 99% similarity]
drivers/net/ethernet/freescale/ucc_geth.h [moved from drivers/net/ucc_geth.h with 100% similarity]
drivers/net/ethernet/freescale/ucc_geth_ethtool.c [moved from drivers/net/ucc_geth_ethtool.c with 100% similarity]
drivers/net/ethernet/fujitsu/Kconfig [new file with mode: 0644]
drivers/net/ethernet/fujitsu/Makefile [new file with mode: 0644]
drivers/net/ethernet/fujitsu/at1700.c [moved from drivers/net/at1700.c with 99% similarity]
drivers/net/ethernet/fujitsu/eth16i.c [moved from drivers/net/eth16i.c with 99% similarity]
drivers/net/ethernet/fujitsu/fmvj18x_cs.c [moved from drivers/net/pcmcia/fmvj18x_cs.c with 99% similarity]
drivers/net/ethernet/hp/Kconfig [new file with mode: 0644]
drivers/net/ethernet/hp/Makefile [new file with mode: 0644]
drivers/net/ethernet/hp/hp100.c [moved from drivers/net/hp100.c with 99% similarity]
drivers/net/ethernet/hp/hp100.h [moved from drivers/net/hp100.h with 100% similarity]
drivers/net/ethernet/i825xx/3c505.c [moved from drivers/net/3c505.c with 99% similarity]
drivers/net/ethernet/i825xx/3c505.h [moved from drivers/net/3c505.h with 100% similarity]
drivers/net/ethernet/i825xx/3c507.c [moved from drivers/net/3c507.c with 100% similarity]
drivers/net/ethernet/i825xx/3c523.c [moved from drivers/net/3c523.c with 99% similarity]
drivers/net/ethernet/i825xx/3c523.h [moved from drivers/net/3c523.h with 100% similarity]
drivers/net/ethernet/i825xx/3c527.c [moved from drivers/net/3c527.c with 99% similarity]
drivers/net/ethernet/i825xx/3c527.h [moved from drivers/net/3c527.h with 100% similarity]
drivers/net/ethernet/i825xx/82596.c [moved from drivers/net/82596.c with 99% similarity]
drivers/net/ethernet/i825xx/Kconfig [new file with mode: 0644]
drivers/net/ethernet/i825xx/Makefile [new file with mode: 0644]
drivers/net/ethernet/i825xx/eepro.c [moved from drivers/net/eepro.c with 99% similarity]
drivers/net/ethernet/i825xx/eexpress.c [moved from drivers/net/eexpress.c with 99% similarity]
drivers/net/ethernet/i825xx/eexpress.h [moved from drivers/net/eexpress.h with 100% similarity]
drivers/net/ethernet/i825xx/ether1.c [moved from drivers/net/arm/ether1.c with 99% similarity]
drivers/net/ethernet/i825xx/ether1.h [moved from drivers/net/arm/ether1.h with 100% similarity]
drivers/net/ethernet/i825xx/lasi_82596.c [moved from drivers/net/lasi_82596.c with 100% similarity]
drivers/net/ethernet/i825xx/lib82596.c [moved from drivers/net/lib82596.c with 99% similarity]
drivers/net/ethernet/i825xx/lp486e.c [moved from drivers/net/lp486e.c with 99% similarity]
drivers/net/ethernet/i825xx/ni52.c [moved from drivers/net/ni52.c with 99% similarity]
drivers/net/ethernet/i825xx/ni52.h [moved from drivers/net/ni52.h with 100% similarity]
drivers/net/ethernet/i825xx/sni_82596.c [moved from drivers/net/sni_82596.c with 100% similarity]
drivers/net/ethernet/i825xx/sun3_82586.c [moved from drivers/net/sun3_82586.c with 99% similarity]
drivers/net/ethernet/i825xx/sun3_82586.h [moved from drivers/net/sun3_82586.h with 100% similarity]
drivers/net/ethernet/i825xx/znet.c [moved from drivers/net/znet.c with 99% similarity]
drivers/net/ethernet/ibm/Kconfig [new file with mode: 0644]
drivers/net/ethernet/ibm/Makefile [new file with mode: 0644]
drivers/net/ethernet/ibm/ehea/Makefile [moved from drivers/net/ehea/Makefile with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea.h [moved from drivers/net/ehea/ehea.h with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea_ethtool.c [moved from drivers/net/ehea/ehea_ethtool.c with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea_hw.h [moved from drivers/net/ehea/ehea_hw.h with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea_main.c [moved from drivers/net/ehea/ehea_main.c with 99% similarity]
drivers/net/ethernet/ibm/ehea/ehea_phyp.c [moved from drivers/net/ehea/ehea_phyp.c with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea_phyp.h [moved from drivers/net/ehea/ehea_phyp.h with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea_qmr.c [moved from drivers/net/ehea/ehea_qmr.c with 100% similarity]
drivers/net/ethernet/ibm/ehea/ehea_qmr.h [moved from drivers/net/ehea/ehea_qmr.h with 100% similarity]
drivers/net/ethernet/ibm/emac/Kconfig [moved from drivers/net/ibm_newemac/Kconfig with 63% similarity]
drivers/net/ethernet/ibm/emac/Makefile [new file with mode: 0644]
drivers/net/ethernet/ibm/emac/core.c [moved from drivers/net/ibm_newemac/core.c with 99% similarity]
drivers/net/ethernet/ibm/emac/core.h [moved from drivers/net/ibm_newemac/core.h with 97% similarity]
drivers/net/ethernet/ibm/emac/debug.c [moved from drivers/net/ibm_newemac/debug.c with 100% similarity]
drivers/net/ethernet/ibm/emac/debug.h [moved from drivers/net/ibm_newemac/debug.h with 98% similarity]
drivers/net/ethernet/ibm/emac/emac.h [moved from drivers/net/ibm_newemac/emac.h with 100% similarity]
drivers/net/ethernet/ibm/emac/mal.c [moved from drivers/net/ibm_newemac/mal.c with 99% similarity]
drivers/net/ethernet/ibm/emac/mal.h [moved from drivers/net/ibm_newemac/mal.h with 99% similarity]
drivers/net/ethernet/ibm/emac/phy.c [moved from drivers/net/ibm_newemac/phy.c with 100% similarity]
drivers/net/ethernet/ibm/emac/phy.h [moved from drivers/net/ibm_newemac/phy.h with 100% similarity]
drivers/net/ethernet/ibm/emac/rgmii.c [moved from drivers/net/ibm_newemac/rgmii.c with 100% similarity]
drivers/net/ethernet/ibm/emac/rgmii.h [moved from drivers/net/ibm_newemac/rgmii.h with 96% similarity]
drivers/net/ethernet/ibm/emac/tah.c [moved from drivers/net/ibm_newemac/tah.c with 100% similarity]
drivers/net/ethernet/ibm/emac/tah.h [moved from drivers/net/ibm_newemac/tah.h with 97% similarity]
drivers/net/ethernet/ibm/emac/zmii.c [moved from drivers/net/ibm_newemac/zmii.c with 100% similarity]
drivers/net/ethernet/ibm/emac/zmii.h [moved from drivers/net/ibm_newemac/zmii.h with 96% similarity]
drivers/net/ethernet/ibm/ibmveth.c [moved from drivers/net/ibmveth.c with 99% similarity]
drivers/net/ethernet/ibm/ibmveth.h [moved from drivers/net/ibmveth.h with 100% similarity]
drivers/net/ethernet/ibm/iseries_veth.c [moved from drivers/net/iseries_veth.c with 99% similarity]
drivers/net/ethernet/icplus/Kconfig [new file with mode: 0644]
drivers/net/ethernet/icplus/Makefile [new file with mode: 0644]
drivers/net/ethernet/icplus/ipg.c [moved from drivers/net/ipg.c with 92% similarity]
drivers/net/ethernet/icplus/ipg.h [moved from drivers/net/ipg.h with 100% similarity]
drivers/net/ethernet/intel/Kconfig [new file with mode: 0644]
drivers/net/ethernet/intel/Makefile [new file with mode: 0644]
drivers/net/ethernet/intel/e100.c [moved from drivers/net/e100.c with 99% similarity]
drivers/net/ethernet/intel/e1000/Makefile [moved from drivers/net/e1000/Makefile with 100% similarity]
drivers/net/ethernet/intel/e1000/e1000.h [moved from drivers/net/e1000/e1000.h with 100% similarity]
drivers/net/ethernet/intel/e1000/e1000_ethtool.c [moved from drivers/net/e1000/e1000_ethtool.c with 100% similarity]
drivers/net/ethernet/intel/e1000/e1000_hw.c [moved from drivers/net/e1000/e1000_hw.c with 100% similarity]
drivers/net/ethernet/intel/e1000/e1000_hw.h [moved from drivers/net/e1000/e1000_hw.h with 100% similarity]
drivers/net/ethernet/intel/e1000/e1000_main.c [moved from drivers/net/e1000/e1000_main.c with 99% similarity]
drivers/net/ethernet/intel/e1000/e1000_osdep.h [moved from drivers/net/e1000/e1000_osdep.h with 100% similarity]
drivers/net/ethernet/intel/e1000/e1000_param.c [moved from drivers/net/e1000/e1000_param.c with 100% similarity]
drivers/net/ethernet/intel/e1000e/80003es2lan.c [moved from drivers/net/e1000e/es2lan.c with 100% similarity]
drivers/net/ethernet/intel/e1000e/82571.c [moved from drivers/net/e1000e/82571.c with 100% similarity]
drivers/net/ethernet/intel/e1000e/Makefile [moved from drivers/net/e1000e/Makefile with 96% similarity]
drivers/net/ethernet/intel/e1000e/defines.h [moved from drivers/net/e1000e/defines.h with 100% similarity]
drivers/net/ethernet/intel/e1000e/e1000.h [moved from drivers/net/e1000e/e1000.h with 99% similarity]
drivers/net/ethernet/intel/e1000e/ethtool.c [moved from drivers/net/e1000e/ethtool.c with 99% similarity]
drivers/net/ethernet/intel/e1000e/hw.h [moved from drivers/net/e1000e/hw.h with 100% similarity]
drivers/net/ethernet/intel/e1000e/ich8lan.c [moved from drivers/net/e1000e/ich8lan.c with 98% similarity]
drivers/net/ethernet/intel/e1000e/lib.c [moved from drivers/net/e1000e/lib.c with 100% similarity]
drivers/net/ethernet/intel/e1000e/netdev.c [moved from drivers/net/e1000e/netdev.c with 96% similarity]
drivers/net/ethernet/intel/e1000e/param.c [moved from drivers/net/e1000e/param.c with 100% similarity]
drivers/net/ethernet/intel/e1000e/phy.c [moved from drivers/net/e1000e/phy.c with 100% similarity]
drivers/net/ethernet/intel/igb/Makefile [moved from drivers/net/igb/Makefile with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_82575.c [moved from drivers/net/igb/e1000_82575.c with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_82575.h [moved from drivers/net/igb/e1000_82575.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_defines.h [moved from drivers/net/igb/e1000_defines.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_hw.h [moved from drivers/net/igb/e1000_hw.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_mac.c [moved from drivers/net/igb/e1000_mac.c with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_mac.h [moved from drivers/net/igb/e1000_mac.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_mbx.c [moved from drivers/net/igb/e1000_mbx.c with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_mbx.h [moved from drivers/net/igb/e1000_mbx.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_nvm.c [moved from drivers/net/igb/e1000_nvm.c with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_nvm.h [moved from drivers/net/igb/e1000_nvm.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_phy.c [moved from drivers/net/igb/e1000_phy.c with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_phy.h [moved from drivers/net/igb/e1000_phy.h with 100% similarity]
drivers/net/ethernet/intel/igb/e1000_regs.h [moved from drivers/net/igb/e1000_regs.h with 100% similarity]
drivers/net/ethernet/intel/igb/igb.h [moved from drivers/net/igb/igb.h with 100% similarity]
drivers/net/ethernet/intel/igb/igb_ethtool.c [moved from drivers/net/igb/igb_ethtool.c with 100% similarity]
drivers/net/ethernet/intel/igb/igb_main.c [moved from drivers/net/igb/igb_main.c with 99% similarity]
drivers/net/ethernet/intel/igbvf/Makefile [moved from drivers/net/igbvf/Makefile with 100% similarity]
drivers/net/ethernet/intel/igbvf/defines.h [moved from drivers/net/igbvf/defines.h with 100% similarity]
drivers/net/ethernet/intel/igbvf/ethtool.c [moved from drivers/net/igbvf/ethtool.c with 100% similarity]
drivers/net/ethernet/intel/igbvf/igbvf.h [moved from drivers/net/igbvf/igbvf.h with 100% similarity]
drivers/net/ethernet/intel/igbvf/mbx.c [moved from drivers/net/igbvf/mbx.c with 100% similarity]
drivers/net/ethernet/intel/igbvf/mbx.h [moved from drivers/net/igbvf/mbx.h with 100% similarity]
drivers/net/ethernet/intel/igbvf/netdev.c [moved from drivers/net/igbvf/netdev.c with 99% similarity]
drivers/net/ethernet/intel/igbvf/regs.h [moved from drivers/net/igbvf/regs.h with 100% similarity]
drivers/net/ethernet/intel/igbvf/vf.c [moved from drivers/net/igbvf/vf.c with 100% similarity]
drivers/net/ethernet/intel/igbvf/vf.h [moved from drivers/net/igbvf/vf.h with 100% similarity]
drivers/net/ethernet/intel/ixgb/Makefile [moved from drivers/net/ixgb/Makefile with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb.h [moved from drivers/net/ixgb/ixgb.h with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_ee.c [moved from drivers/net/ixgb/ixgb_ee.c with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_ee.h [moved from drivers/net/ixgb/ixgb_ee.h with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c [moved from drivers/net/ixgb/ixgb_ethtool.c with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_hw.c [moved from drivers/net/ixgb/ixgb_hw.c with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_hw.h [moved from drivers/net/ixgb/ixgb_hw.h with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_ids.h [moved from drivers/net/ixgb/ixgb_ids.h with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_main.c [moved from drivers/net/ixgb/ixgb_main.c with 99% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_osdep.h [moved from drivers/net/ixgb/ixgb_osdep.h with 100% similarity]
drivers/net/ethernet/intel/ixgb/ixgb_param.c [moved from drivers/net/ixgb/ixgb_param.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/Makefile [moved from drivers/net/ixgbe/Makefile with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe.h [moved from drivers/net/ixgbe/ixgbe.h with 97% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c [moved from drivers/net/ixgbe/ixgbe_82598.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c [moved from drivers/net/ixgbe/ixgbe_82599.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c [moved from drivers/net/ixgbe/ixgbe_common.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h [moved from drivers/net/ixgbe/ixgbe_common.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c [moved from drivers/net/ixgbe/ixgbe_dcb.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h [moved from drivers/net/ixgbe/ixgbe_dcb.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c [moved from drivers/net/ixgbe/ixgbe_dcb_82598.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h [moved from drivers/net/ixgbe/ixgbe_dcb_82598.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c [moved from drivers/net/ixgbe/ixgbe_dcb_82599.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h [moved from drivers/net/ixgbe/ixgbe_dcb_82599.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c [moved from drivers/net/ixgbe/ixgbe_dcb_nl.c with 99% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c [moved from drivers/net/ixgbe/ixgbe_ethtool.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c [moved from drivers/net/ixgbe/ixgbe_fcoe.c with 99% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h [moved from drivers/net/ixgbe/ixgbe_fcoe.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c [moved from drivers/net/ixgbe/ixgbe_main.c with 96% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c [moved from drivers/net/ixgbe/ixgbe_mbx.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h [moved from drivers/net/ixgbe/ixgbe_mbx.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c [moved from drivers/net/ixgbe/ixgbe_phy.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h [moved from drivers/net/ixgbe/ixgbe_phy.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c [moved from drivers/net/ixgbe/ixgbe_sriov.c with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h [moved from drivers/net/ixgbe/ixgbe_sriov.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h [moved from drivers/net/ixgbe/ixgbe_type.h with 100% similarity]
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c [moved from drivers/net/ixgbe/ixgbe_x540.c with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/Makefile [moved from drivers/net/ixgbevf/Makefile with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/defines.h [moved from drivers/net/ixgbevf/defines.h with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/ethtool.c [moved from drivers/net/ixgbevf/ethtool.c with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h [moved from drivers/net/ixgbevf/ixgbevf.h with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c [moved from drivers/net/ixgbevf/ixgbevf_main.c with 99% similarity]
drivers/net/ethernet/intel/ixgbevf/mbx.c [moved from drivers/net/ixgbevf/mbx.c with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/mbx.h [moved from drivers/net/ixgbevf/mbx.h with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/regs.h [moved from drivers/net/ixgbevf/regs.h with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/vf.c [moved from drivers/net/ixgbevf/vf.c with 100% similarity]
drivers/net/ethernet/intel/ixgbevf/vf.h [moved from drivers/net/ixgbevf/vf.h with 100% similarity]
drivers/net/ethernet/jme.c [moved from drivers/net/jme.c with 99% similarity]
drivers/net/ethernet/jme.h [moved from drivers/net/jme.h with 100% similarity]
drivers/net/ethernet/korina.c [moved from drivers/net/korina.c with 99% similarity]
drivers/net/ethernet/lantiq_etop.c [moved from drivers/net/lantiq_etop.c with 99% similarity]
drivers/net/ethernet/marvell/Kconfig [new file with mode: 0644]
drivers/net/ethernet/marvell/Makefile [new file with mode: 0644]
drivers/net/ethernet/marvell/mv643xx_eth.c [moved from drivers/net/mv643xx_eth.c with 99% similarity]
drivers/net/ethernet/marvell/pxa168_eth.c [moved from drivers/net/pxa168_eth.c with 100% similarity]
drivers/net/ethernet/marvell/skge.c [moved from drivers/net/skge.c with 99% similarity]
drivers/net/ethernet/marvell/skge.h [moved from drivers/net/skge.h with 100% similarity]
drivers/net/ethernet/marvell/sky2.c [moved from drivers/net/sky2.c with 99% similarity]
drivers/net/ethernet/marvell/sky2.h [moved from drivers/net/sky2.h with 100% similarity]
drivers/net/ethernet/mellanox/Kconfig [new file with mode: 0644]
drivers/net/ethernet/mellanox/Makefile [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlx4/Kconfig [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlx4/Makefile [moved from drivers/net/mlx4/Makefile with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/alloc.c [moved from drivers/net/mlx4/alloc.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/catas.c [moved from drivers/net/mlx4/catas.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/cmd.c [moved from drivers/net/mlx4/cmd.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/cq.c [moved from drivers/net/mlx4/cq.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_cq.c [moved from drivers/net/mlx4/en_cq.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c [moved from drivers/net/mlx4/en_ethtool.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_main.c [moved from drivers/net/mlx4/en_main.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_netdev.c [moved from drivers/net/mlx4/en_netdev.c with 99% similarity]
drivers/net/ethernet/mellanox/mlx4/en_port.c [moved from drivers/net/mlx4/en_port.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_port.h [moved from drivers/net/mlx4/en_port.h with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_resources.c [moved from drivers/net/mlx4/en_resources.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_rx.c [moved from drivers/net/mlx4/en_rx.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_selftest.c [moved from drivers/net/mlx4/en_selftest.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/en_tx.c [moved from drivers/net/mlx4/en_tx.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/eq.c [moved from drivers/net/mlx4/eq.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/fw.c [moved from drivers/net/mlx4/fw.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/fw.h [moved from drivers/net/mlx4/fw.h with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/icm.c [moved from drivers/net/mlx4/icm.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/icm.h [moved from drivers/net/mlx4/icm.h with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/intf.c [moved from drivers/net/mlx4/intf.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/main.c [moved from drivers/net/mlx4/main.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/mcg.c [moved from drivers/net/mlx4/mcg.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/mlx4.h [moved from drivers/net/mlx4/mlx4.h with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h [moved from drivers/net/mlx4/mlx4_en.h with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/mr.c [moved from drivers/net/mlx4/mr.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/pd.c [moved from drivers/net/mlx4/pd.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/port.c [moved from drivers/net/mlx4/port.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/profile.c [moved from drivers/net/mlx4/profile.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/qp.c [moved from drivers/net/mlx4/qp.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/reset.c [moved from drivers/net/mlx4/reset.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/sense.c [moved from drivers/net/mlx4/sense.c with 100% similarity]
drivers/net/ethernet/mellanox/mlx4/srq.c [moved from drivers/net/mlx4/srq.c with 100% similarity]
drivers/net/ethernet/micrel/Kconfig [new file with mode: 0644]
drivers/net/ethernet/micrel/Makefile [new file with mode: 0644]
drivers/net/ethernet/micrel/ks8695net.c [moved from drivers/net/arm/ks8695net.c with 99% similarity]
drivers/net/ethernet/micrel/ks8695net.h [moved from drivers/net/arm/ks8695net.h with 100% similarity]
drivers/net/ethernet/micrel/ks8842.c [moved from drivers/net/ks8842.c with 100% similarity]
drivers/net/ethernet/micrel/ks8851.c [moved from drivers/net/ks8851.c with 100% similarity]
drivers/net/ethernet/micrel/ks8851.h [moved from drivers/net/ks8851.h with 100% similarity]
drivers/net/ethernet/micrel/ks8851_mll.c [moved from drivers/net/ks8851_mll.c with 100% similarity]
drivers/net/ethernet/micrel/ksz884x.c [moved from drivers/net/ksz884x.c with 100% similarity]
drivers/net/ethernet/microchip/Kconfig [new file with mode: 0644]
drivers/net/ethernet/microchip/Makefile [new file with mode: 0644]
drivers/net/ethernet/microchip/enc28j60.c [moved from drivers/net/enc28j60.c with 99% similarity]
drivers/net/ethernet/microchip/enc28j60_hw.h [moved from drivers/net/enc28j60_hw.h with 100% similarity]
drivers/net/ethernet/mipsnet.c [moved from drivers/net/mipsnet.c with 99% similarity]
drivers/net/ethernet/myricom/Kconfig [new file with mode: 0644]
drivers/net/ethernet/myricom/Makefile [new file with mode: 0644]
drivers/net/ethernet/myricom/myri10ge/Makefile [moved from drivers/net/myri10ge/Makefile with 100% similarity]
drivers/net/ethernet/myricom/myri10ge/myri10ge.c [moved from drivers/net/myri10ge/myri10ge.c with 99% similarity]
drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp.h [moved from drivers/net/myri10ge/myri10ge_mcp.h with 100% similarity]
drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp_gen_header.h [moved from drivers/net/myri10ge/myri10ge_mcp_gen_header.h with 100% similarity]
drivers/net/ethernet/natsemi/Kconfig [new file with mode: 0644]
drivers/net/ethernet/natsemi/Makefile [new file with mode: 0644]
drivers/net/ethernet/natsemi/ibmlana.c [moved from drivers/net/ibmlana.c with 99% similarity]
drivers/net/ethernet/natsemi/ibmlana.h [moved from drivers/net/ibmlana.h with 100% similarity]
drivers/net/ethernet/natsemi/jazzsonic.c [moved from drivers/net/jazzsonic.c with 99% similarity]
drivers/net/ethernet/natsemi/macsonic.c [moved from drivers/net/macsonic.c with 99% similarity]
drivers/net/ethernet/natsemi/natsemi.c [moved from drivers/net/natsemi.c with 99% similarity]
drivers/net/ethernet/natsemi/ns83820.c [moved from drivers/net/ns83820.c with 99% similarity]
drivers/net/ethernet/natsemi/sonic.c [moved from drivers/net/sonic.c with 100% similarity]
drivers/net/ethernet/natsemi/sonic.h [moved from drivers/net/sonic.h with 100% similarity]
drivers/net/ethernet/natsemi/xtsonic.c [moved from drivers/net/xtsonic.c with 99% similarity]
drivers/net/ethernet/neterion/Kconfig [new file with mode: 0644]
drivers/net/ethernet/neterion/Makefile [new file with mode: 0644]
drivers/net/ethernet/neterion/s2io-regs.h [moved from drivers/net/s2io-regs.h with 100% similarity]
drivers/net/ethernet/neterion/s2io.c [moved from drivers/net/s2io.c with 99% similarity]
drivers/net/ethernet/neterion/s2io.h [moved from drivers/net/s2io.h with 100% similarity]
drivers/net/ethernet/neterion/vxge/Makefile [moved from drivers/net/vxge/Makefile with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-config.c [moved from drivers/net/vxge/vxge-config.c with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-config.h [moved from drivers/net/vxge/vxge-config.h with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-ethtool.c [moved from drivers/net/vxge/vxge-ethtool.c with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-ethtool.h [moved from drivers/net/vxge/vxge-ethtool.h with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-main.c [moved from drivers/net/vxge/vxge-main.c with 99% similarity]
drivers/net/ethernet/neterion/vxge/vxge-main.h [moved from drivers/net/vxge/vxge-main.h with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-reg.h [moved from drivers/net/vxge/vxge-reg.h with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-traffic.c [moved from drivers/net/vxge/vxge-traffic.c with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-traffic.h [moved from drivers/net/vxge/vxge-traffic.h with 100% similarity]
drivers/net/ethernet/neterion/vxge/vxge-version.h [moved from drivers/net/vxge/vxge-version.h with 100% similarity]
drivers/net/ethernet/netx-eth.c [moved from drivers/net/netx-eth.c with 99% similarity]
drivers/net/ethernet/nuvoton/Kconfig [new file with mode: 0644]
drivers/net/ethernet/nuvoton/Makefile [new file with mode: 0644]
drivers/net/ethernet/nuvoton/w90p910_ether.c [moved from drivers/net/arm/w90p910_ether.c with 99% similarity]
drivers/net/ethernet/nvidia/Kconfig [new file with mode: 0644]
drivers/net/ethernet/nvidia/Makefile [new file with mode: 0644]
drivers/net/ethernet/nvidia/forcedeth.c [moved from drivers/net/forcedeth.c with 99% similarity]
drivers/net/ethernet/octeon/Kconfig [moved from drivers/net/octeon/Kconfig with 85% similarity]
drivers/net/ethernet/octeon/Makefile [new file with mode: 0644]
drivers/net/ethernet/octeon/octeon_mgmt.c [moved from drivers/net/octeon/octeon_mgmt.c with 99% similarity]
drivers/net/ethernet/oki-semi/Kconfig [new file with mode: 0644]
drivers/net/ethernet/oki-semi/Makefile [new file with mode: 0644]
drivers/net/ethernet/oki-semi/pch_gbe/Kconfig [new file with mode: 0644]
drivers/net/ethernet/oki-semi/pch_gbe/Makefile [moved from drivers/net/pch_gbe/Makefile with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h [moved from drivers/net/pch_gbe/pch_gbe.h with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c [moved from drivers/net/pch_gbe/pch_gbe_api.c with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.h [moved from drivers/net/pch_gbe/pch_gbe_api.h with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c [moved from drivers/net/pch_gbe/pch_gbe_ethtool.c with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c [moved from drivers/net/pch_gbe/pch_gbe_main.c with 99% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c [moved from drivers/net/pch_gbe/pch_gbe_param.c with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c [moved from drivers/net/pch_gbe/pch_gbe_phy.c with 100% similarity]
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h [moved from drivers/net/pch_gbe/pch_gbe_phy.h with 100% similarity]
drivers/net/ethernet/packetengines/Kconfig [new file with mode: 0644]
drivers/net/ethernet/packetengines/Makefile [new file with mode: 0644]
drivers/net/ethernet/packetengines/hamachi.c [moved from drivers/net/hamachi.c with 99% similarity]
drivers/net/ethernet/packetengines/yellowfin.c [moved from drivers/net/yellowfin.c with 99% similarity]
drivers/net/ethernet/pasemi/Kconfig [new file with mode: 0644]
drivers/net/ethernet/pasemi/Makefile [new file with mode: 0644]
drivers/net/ethernet/pasemi/pasemi_mac.c [moved from drivers/net/pasemi_mac.c with 99% similarity]
drivers/net/ethernet/pasemi/pasemi_mac.h [moved from drivers/net/pasemi_mac.h with 100% similarity]
drivers/net/ethernet/pasemi/pasemi_mac_ethtool.c [moved from drivers/net/pasemi_mac_ethtool.c with 100% similarity]
drivers/net/ethernet/qlogic/Kconfig [new file with mode: 0644]
drivers/net/ethernet/qlogic/Makefile [new file with mode: 0644]
drivers/net/ethernet/qlogic/netxen/Makefile [moved from drivers/net/netxen/Makefile with 100% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic.h [moved from drivers/net/netxen/netxen_nic.h with 99% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c [moved from drivers/net/netxen/netxen_nic_ctx.c with 100% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c [moved from drivers/net/netxen/netxen_nic_ethtool.c with 100% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h [moved from drivers/net/netxen/netxen_nic_hdr.h with 100% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c [moved from drivers/net/netxen/netxen_nic_hw.c with 100% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.h [moved from drivers/net/netxen/netxen_nic_hw.h with 100% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c [moved from drivers/net/netxen/netxen_nic_init.c with 99% similarity]
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c [moved from drivers/net/netxen/netxen_nic_main.c with 96% similarity]
drivers/net/ethernet/qlogic/qla3xxx.c [moved from drivers/net/qla3xxx.c with 99% similarity]
drivers/net/ethernet/qlogic/qla3xxx.h [moved from drivers/net/qla3xxx.h with 100% similarity]
drivers/net/ethernet/qlogic/qlcnic/Makefile [moved from drivers/net/qlcnic/Makefile with 100% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h [moved from drivers/net/qlcnic/qlcnic.h with 99% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c [moved from drivers/net/qlcnic/qlcnic_ctx.c with 100% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c [moved from drivers/net/qlcnic/qlcnic_ethtool.c with 98% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h [moved from drivers/net/qlcnic/qlcnic_hdr.h with 100% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c [moved from drivers/net/qlcnic/qlcnic_hw.c with 99% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c [moved from drivers/net/qlcnic/qlcnic_init.c with 99% similarity]
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c [moved from drivers/net/qlcnic/qlcnic_main.c with 98% similarity]
drivers/net/ethernet/qlogic/qlge/Makefile [moved from drivers/net/qlge/Makefile with 100% similarity]
drivers/net/ethernet/qlogic/qlge/qlge.h [moved from drivers/net/qlge/qlge.h with 100% similarity]
drivers/net/ethernet/qlogic/qlge/qlge_dbg.c [moved from drivers/net/qlge/qlge_dbg.c with 100% similarity]
drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c [moved from drivers/net/qlge/qlge_ethtool.c with 100% similarity]
drivers/net/ethernet/qlogic/qlge/qlge_main.c [moved from drivers/net/qlge/qlge_main.c with 99% similarity]
drivers/net/ethernet/qlogic/qlge/qlge_mpi.c [moved from drivers/net/qlge/qlge_mpi.c with 100% similarity]
drivers/net/ethernet/racal/Kconfig [new file with mode: 0644]
drivers/net/ethernet/racal/Makefile [new file with mode: 0644]
drivers/net/ethernet/racal/ni5010.c [moved from drivers/net/ni5010.c with 99% similarity]
drivers/net/ethernet/racal/ni5010.h [moved from drivers/net/ni5010.h with 100% similarity]
drivers/net/ethernet/rdc/Kconfig [new file with mode: 0644]
drivers/net/ethernet/rdc/Makefile [new file with mode: 0644]
drivers/net/ethernet/rdc/r6040.c [moved from drivers/net/r6040.c with 99% similarity]
drivers/net/ethernet/realtek/8139cp.c [moved from drivers/net/8139cp.c with 99% similarity]
drivers/net/ethernet/realtek/8139too.c [moved from drivers/net/8139too.c with 99% similarity]
drivers/net/ethernet/realtek/Kconfig [new file with mode: 0644]
drivers/net/ethernet/realtek/Makefile [new file with mode: 0644]
drivers/net/ethernet/realtek/atp.c [moved from drivers/net/atp.c with 99% similarity]
drivers/net/ethernet/realtek/atp.h [moved from drivers/net/atp.h with 100% similarity]
drivers/net/ethernet/realtek/r8169.c [moved from drivers/net/r8169.c with 99% similarity]
drivers/net/ethernet/realtek/sc92031.c [moved from drivers/net/sc92031.c with 99% similarity]
drivers/net/ethernet/renesas/Kconfig [new file with mode: 0644]
drivers/net/ethernet/renesas/Makefile [new file with mode: 0644]
drivers/net/ethernet/renesas/sh_eth.c [moved from drivers/net/sh_eth.c with 99% similarity]
drivers/net/ethernet/renesas/sh_eth.h [moved from drivers/net/sh_eth.h with 100% similarity]
drivers/net/ethernet/s6gmac.c [moved from drivers/net/s6gmac.c with 100% similarity]
drivers/net/ethernet/seeq/Kconfig [new file with mode: 0644]
drivers/net/ethernet/seeq/Makefile [new file with mode: 0644]
drivers/net/ethernet/seeq/ether3.c [moved from drivers/net/arm/ether3.c with 99% similarity]
drivers/net/ethernet/seeq/ether3.h [moved from drivers/net/arm/ether3.h with 100% similarity]
drivers/net/ethernet/seeq/seeq8005.c [moved from drivers/net/seeq8005.c with 99% similarity]
drivers/net/ethernet/seeq/seeq8005.h [moved from drivers/net/seeq8005.h with 100% similarity]
drivers/net/ethernet/seeq/sgiseeq.c [moved from drivers/net/sgiseeq.c with 99% similarity]
drivers/net/ethernet/seeq/sgiseeq.h [moved from drivers/net/sgiseeq.h with 100% similarity]
drivers/net/ethernet/sfc/Kconfig [moved from drivers/net/sfc/Kconfig with 96% similarity]
drivers/net/ethernet/sfc/Makefile [moved from drivers/net/sfc/Makefile with 100% similarity]
drivers/net/ethernet/sfc/bitfield.h [moved from drivers/net/sfc/bitfield.h with 100% similarity]
drivers/net/ethernet/sfc/efx.c [moved from drivers/net/sfc/efx.c with 99% similarity]
drivers/net/ethernet/sfc/efx.h [moved from drivers/net/sfc/efx.h with 100% similarity]
drivers/net/ethernet/sfc/enum.h [moved from drivers/net/sfc/enum.h with 100% similarity]
drivers/net/ethernet/sfc/ethtool.c [moved from drivers/net/sfc/ethtool.c with 100% similarity]
drivers/net/ethernet/sfc/falcon.c [moved from drivers/net/sfc/falcon.c with 100% similarity]
drivers/net/ethernet/sfc/falcon_boards.c [moved from drivers/net/sfc/falcon_boards.c with 100% similarity]
drivers/net/ethernet/sfc/falcon_xmac.c [moved from drivers/net/sfc/falcon_xmac.c with 100% similarity]
drivers/net/ethernet/sfc/filter.c [moved from drivers/net/sfc/filter.c with 100% similarity]
drivers/net/ethernet/sfc/filter.h [moved from drivers/net/sfc/filter.h with 100% similarity]
drivers/net/ethernet/sfc/io.h [moved from drivers/net/sfc/io.h with 100% similarity]
drivers/net/ethernet/sfc/mac.h [moved from drivers/net/sfc/mac.h with 100% similarity]
drivers/net/ethernet/sfc/mcdi.c [moved from drivers/net/sfc/mcdi.c with 100% similarity]
drivers/net/ethernet/sfc/mcdi.h [moved from drivers/net/sfc/mcdi.h with 100% similarity]
drivers/net/ethernet/sfc/mcdi_mac.c [moved from drivers/net/sfc/mcdi_mac.c with 100% similarity]
drivers/net/ethernet/sfc/mcdi_pcol.h [moved from drivers/net/sfc/mcdi_pcol.h with 100% similarity]
drivers/net/ethernet/sfc/mcdi_phy.c [moved from drivers/net/sfc/mcdi_phy.c with 100% similarity]
drivers/net/ethernet/sfc/mdio_10g.c [moved from drivers/net/sfc/mdio_10g.c with 100% similarity]
drivers/net/ethernet/sfc/mdio_10g.h [moved from drivers/net/sfc/mdio_10g.h with 100% similarity]
drivers/net/ethernet/sfc/mtd.c [moved from drivers/net/sfc/mtd.c with 100% similarity]
drivers/net/ethernet/sfc/net_driver.h [moved from drivers/net/sfc/net_driver.h with 100% similarity]
drivers/net/ethernet/sfc/nic.c [moved from drivers/net/sfc/nic.c with 100% similarity]
drivers/net/ethernet/sfc/nic.h [moved from drivers/net/sfc/nic.h with 100% similarity]
drivers/net/ethernet/sfc/phy.h [moved from drivers/net/sfc/phy.h with 100% similarity]
drivers/net/ethernet/sfc/qt202x_phy.c [moved from drivers/net/sfc/qt202x_phy.c with 100% similarity]
drivers/net/ethernet/sfc/regs.h [moved from drivers/net/sfc/regs.h with 100% similarity]
drivers/net/ethernet/sfc/rx.c [moved from drivers/net/sfc/rx.c with 100% similarity]
drivers/net/ethernet/sfc/selftest.c [moved from drivers/net/sfc/selftest.c with 100% similarity]
drivers/net/ethernet/sfc/selftest.h [moved from drivers/net/sfc/selftest.h with 100% similarity]
drivers/net/ethernet/sfc/siena.c [moved from drivers/net/sfc/siena.c with 100% similarity]
drivers/net/ethernet/sfc/spi.h [moved from drivers/net/sfc/spi.h with 100% similarity]
drivers/net/ethernet/sfc/tenxpress.c [moved from drivers/net/sfc/tenxpress.c with 100% similarity]
drivers/net/ethernet/sfc/tx.c [moved from drivers/net/sfc/tx.c with 100% similarity]
drivers/net/ethernet/sfc/txc43128_phy.c [moved from drivers/net/sfc/txc43128_phy.c with 100% similarity]
drivers/net/ethernet/sfc/workarounds.h [moved from drivers/net/sfc/workarounds.h with 100% similarity]
drivers/net/ethernet/sgi/Kconfig [new file with mode: 0644]
drivers/net/ethernet/sgi/Makefile [new file with mode: 0644]
drivers/net/ethernet/sgi/ioc3-eth.c [moved from drivers/net/ioc3-eth.c with 99% similarity]
drivers/net/ethernet/sgi/meth.c [moved from drivers/net/meth.c with 100% similarity]
drivers/net/ethernet/sgi/meth.h [moved from drivers/net/meth.h with 100% similarity]
drivers/net/ethernet/sis/Kconfig [new file with mode: 0644]
drivers/net/ethernet/sis/Makefile [new file with mode: 0644]
drivers/net/ethernet/sis/sis190.c [moved from drivers/net/sis190.c with 99% similarity]
drivers/net/ethernet/sis/sis900.c [moved from drivers/net/sis900.c with 99% similarity]
drivers/net/ethernet/sis/sis900.h [moved from drivers/net/sis900.h with 100% similarity]
drivers/net/ethernet/smsc/Kconfig [new file with mode: 0644]
drivers/net/ethernet/smsc/Makefile [new file with mode: 0644]
drivers/net/ethernet/smsc/epic100.c [moved from drivers/net/epic100.c with 99% similarity]
drivers/net/ethernet/smsc/smc911x.c [moved from drivers/net/smc911x.c with 99% similarity]
drivers/net/ethernet/smsc/smc911x.h [moved from drivers/net/smc911x.h with 100% similarity]
drivers/net/ethernet/smsc/smc9194.c [moved from drivers/net/smc9194.c with 99% similarity]
drivers/net/ethernet/smsc/smc9194.h [moved from drivers/net/smc9194.h with 100% similarity]
drivers/net/ethernet/smsc/smc91c92_cs.c [moved from drivers/net/pcmcia/smc91c92_cs.c with 99% similarity]
drivers/net/ethernet/smsc/smc91x.c [moved from drivers/net/smc91x.c with 99% similarity]
drivers/net/ethernet/smsc/smc91x.h [moved from drivers/net/smc91x.h with 100% similarity]
drivers/net/ethernet/smsc/smsc911x.c [moved from drivers/net/smsc911x.c with 97% similarity]
drivers/net/ethernet/smsc/smsc911x.h [moved from drivers/net/smsc911x.h with 100% similarity]
drivers/net/ethernet/smsc/smsc9420.c [moved from drivers/net/smsc9420.c with 99% similarity]
drivers/net/ethernet/smsc/smsc9420.h [moved from drivers/net/smsc9420.h with 100% similarity]
drivers/net/ethernet/stmicro/Kconfig [new file with mode: 0644]
drivers/net/ethernet/stmicro/Makefile [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/Kconfig [moved from drivers/net/stmmac/Kconfig with 93% similarity]
drivers/net/ethernet/stmicro/stmmac/Makefile [moved from drivers/net/stmmac/Makefile with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/common.h [moved from drivers/net/stmmac/common.h with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/descs.h [moved from drivers/net/stmmac/descs.h with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac100.h [moved from drivers/net/stmmac/dwmac100.h with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h [moved from drivers/net/stmmac/dwmac1000.h with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c [moved from drivers/net/stmmac/dwmac1000_core.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c [moved from drivers/net/stmmac/dwmac1000_dma.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c [moved from drivers/net/stmmac/dwmac100_core.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c [moved from drivers/net/stmmac/dwmac100_dma.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h [moved from drivers/net/stmmac/dwmac_dma.h with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c [moved from drivers/net/stmmac/dwmac_lib.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/enh_desc.c [moved from drivers/net/stmmac/enh_desc.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/norm_desc.c [moved from drivers/net/stmmac/norm_desc.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/stmmac.h [moved from drivers/net/stmmac/stmmac.h with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c [moved from drivers/net/stmmac/stmmac_ethtool.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c [moved from drivers/net/stmmac/stmmac_main.c with 99% similarity]
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c [moved from drivers/net/stmmac/stmmac_mdio.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c [moved from drivers/net/stmmac/stmmac_timer.c with 100% similarity]
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h [moved from drivers/net/stmmac/stmmac_timer.h with 100% similarity]
drivers/net/ethernet/sun/Kconfig [new file with mode: 0644]
drivers/net/ethernet/sun/Makefile [new file with mode: 0644]
drivers/net/ethernet/sun/cassini.c [moved from drivers/net/cassini.c with 99% similarity]
drivers/net/ethernet/sun/cassini.h [moved from drivers/net/cassini.h with 100% similarity]
drivers/net/ethernet/sun/niu.c [moved from drivers/net/niu.c with 99% similarity]
drivers/net/ethernet/sun/niu.h [moved from drivers/net/niu.h with 100% similarity]
drivers/net/ethernet/sun/sunbmac.c [moved from drivers/net/sunbmac.c with 99% similarity]
drivers/net/ethernet/sun/sunbmac.h [moved from drivers/net/sunbmac.h with 100% similarity]
drivers/net/ethernet/sun/sungem.c [moved from drivers/net/sungem.c with 99% similarity]
drivers/net/ethernet/sun/sungem.h [moved from drivers/net/sungem.h with 100% similarity]
drivers/net/ethernet/sun/sunhme.c [moved from drivers/net/sunhme.c with 99% similarity]
drivers/net/ethernet/sun/sunhme.h [moved from drivers/net/sunhme.h with 100% similarity]
drivers/net/ethernet/sun/sunqe.c [moved from drivers/net/sunqe.c with 99% similarity]
drivers/net/ethernet/sun/sunqe.h [moved from drivers/net/sunqe.h with 100% similarity]
drivers/net/ethernet/sun/sunvnet.c [moved from drivers/net/sunvnet.c with 99% similarity]
drivers/net/ethernet/sun/sunvnet.h [moved from drivers/net/sunvnet.h with 100% similarity]
drivers/net/ethernet/tehuti/Kconfig [new file with mode: 0644]
drivers/net/ethernet/tehuti/Makefile [new file with mode: 0644]
drivers/net/ethernet/tehuti/tehuti.c [moved from drivers/net/tehuti.c with 99% similarity]
drivers/net/ethernet/tehuti/tehuti.h [moved from drivers/net/tehuti.h with 100% similarity]
drivers/net/ethernet/ti/Kconfig [new file with mode: 0644]
drivers/net/ethernet/ti/Makefile [new file with mode: 0644]
drivers/net/ethernet/ti/cpmac.c [moved from drivers/net/cpmac.c with 99% similarity]
drivers/net/ethernet/ti/davinci_cpdma.c [moved from drivers/net/davinci_cpdma.c with 100% similarity]
drivers/net/ethernet/ti/davinci_cpdma.h [moved from drivers/net/davinci_cpdma.h with 100% similarity]
drivers/net/ethernet/ti/davinci_emac.c [moved from drivers/net/davinci_emac.c with 99% similarity]
drivers/net/ethernet/ti/davinci_mdio.c [moved from drivers/net/davinci_mdio.c with 100% similarity]
drivers/net/ethernet/ti/tlan.c [moved from drivers/net/tlan.c with 99% similarity]
drivers/net/ethernet/ti/tlan.h [moved from drivers/net/tlan.h with 100% similarity]
drivers/net/ethernet/tile/Kconfig [new file with mode: 0644]
drivers/net/ethernet/tile/Makefile [moved from drivers/net/tile/Makefile with 100% similarity]
drivers/net/ethernet/tile/tilepro.c [moved from drivers/net/tile/tilepro.c with 100% similarity]
drivers/net/ethernet/toshiba/Kconfig [new file with mode: 0644]
drivers/net/ethernet/toshiba/Makefile [new file with mode: 0644]
drivers/net/ethernet/toshiba/ps3_gelic_net.c [moved from drivers/net/ps3_gelic_net.c with 99% similarity]
drivers/net/ethernet/toshiba/ps3_gelic_net.h [moved from drivers/net/ps3_gelic_net.h with 100% similarity]
drivers/net/ethernet/toshiba/ps3_gelic_wireless.c [moved from drivers/net/ps3_gelic_wireless.c with 99% similarity]
drivers/net/ethernet/toshiba/ps3_gelic_wireless.h [moved from drivers/net/ps3_gelic_wireless.h with 100% similarity]
drivers/net/ethernet/toshiba/spider_net.c [moved from drivers/net/spider_net.c with 99% similarity]
drivers/net/ethernet/toshiba/spider_net.h [moved from drivers/net/spider_net.h with 99% similarity]
drivers/net/ethernet/toshiba/spider_net_ethtool.c [moved from drivers/net/spider_net_ethtool.c with 100% similarity]
drivers/net/ethernet/toshiba/tc35815.c [moved from drivers/net/tc35815.c with 99% similarity]
drivers/net/ethernet/tundra/Kconfig [new file with mode: 0644]
drivers/net/ethernet/tundra/Makefile [new file with mode: 0644]
drivers/net/ethernet/tundra/tsi108_eth.c [moved from drivers/net/tsi108_eth.c with 99% similarity]
drivers/net/ethernet/tundra/tsi108_eth.h [moved from drivers/net/tsi108_eth.h with 100% similarity]
drivers/net/ethernet/via/Kconfig [new file with mode: 0644]
drivers/net/ethernet/via/Makefile [new file with mode: 0644]
drivers/net/ethernet/via/via-rhine.c [moved from drivers/net/via-rhine.c with 99% similarity]
drivers/net/ethernet/via/via-velocity.c [moved from drivers/net/via-velocity.c with 97% similarity]
drivers/net/ethernet/via/via-velocity.h [moved from drivers/net/via-velocity.h with 100% similarity]
drivers/net/ethernet/xilinx/Kconfig [new file with mode: 0644]
drivers/net/ethernet/xilinx/Makefile [new file with mode: 0644]
drivers/net/ethernet/xilinx/ll_temac.h [moved from drivers/net/ll_temac.h with 100% similarity]
drivers/net/ethernet/xilinx/ll_temac_main.c [moved from drivers/net/ll_temac_main.c with 99% similarity]
drivers/net/ethernet/xilinx/ll_temac_mdio.c [moved from drivers/net/ll_temac_mdio.c with 100% similarity]
drivers/net/ethernet/xilinx/xilinx_emaclite.c [moved from drivers/net/xilinx_emaclite.c with 100% similarity]
drivers/net/ethernet/xircom/Kconfig [new file with mode: 0644]
drivers/net/ethernet/xircom/Makefile [new file with mode: 0644]
drivers/net/ethernet/xircom/xirc2ps_cs.c [moved from drivers/net/pcmcia/xirc2ps_cs.c with 99% similarity]
drivers/net/ethernet/xscale/Kconfig [new file with mode: 0644]
drivers/net/ethernet/xscale/Makefile [new file with mode: 0644]
drivers/net/ethernet/xscale/ixp2000/Kconfig [moved from drivers/net/ixp2000/Kconfig with 94% similarity]
drivers/net/ethernet/xscale/ixp2000/Makefile [moved from drivers/net/ixp2000/Makefile with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/caleb.c [moved from drivers/net/ixp2000/caleb.c with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/caleb.h [moved from drivers/net/ixp2000/caleb.h with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/enp2611.c [moved from drivers/net/ixp2000/enp2611.c with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.c [moved from drivers/net/ixp2000/ixp2400-msf.c with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.h [moved from drivers/net/ixp2000/ixp2400-msf.h with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.uc [moved from drivers/net/ixp2000/ixp2400_rx.uc with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.ucode [moved from drivers/net/ixp2000/ixp2400_rx.ucode with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.uc [moved from drivers/net/ixp2000/ixp2400_tx.uc with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.ucode [moved from drivers/net/ixp2000/ixp2400_tx.ucode with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixpdev.c [moved from drivers/net/ixp2000/ixpdev.c with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixpdev.h [moved from drivers/net/ixp2000/ixpdev.h with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/ixpdev_priv.h [moved from drivers/net/ixp2000/ixpdev_priv.h with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/pm3386.c [moved from drivers/net/ixp2000/pm3386.c with 100% similarity]
drivers/net/ethernet/xscale/ixp2000/pm3386.h [moved from drivers/net/ixp2000/pm3386.h with 100% similarity]
drivers/net/ethernet/xscale/ixp4xx_eth.c [moved from drivers/net/arm/ixp4xx_eth.c with 99% similarity]
drivers/net/ibm_newemac/Makefile [deleted file]
drivers/net/irda/stir4200.c
drivers/net/mac-puv3.c [new file with mode: 0644]
drivers/net/macvlan.c
drivers/net/octeon/Makefile [deleted file]
drivers/net/pci-skeleton.c [deleted file]
drivers/net/pcmcia/Kconfig
drivers/net/pcmcia/Makefile
drivers/net/skfp/skfddi.c
drivers/net/slip.c
drivers/net/slip.h
drivers/net/sungem_phy.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/ibmtr.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/olympic.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tun.c
drivers/net/usb/asix.c
drivers/net/usb/catc.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/dm9601.c
drivers/net/usb/int51x1.c
drivers/net/usb/kaweth.c
drivers/net/usb/lg-vl600.c
drivers/net/usb/mcs7830.c
drivers/net/usb/pegasus.c
drivers/net/usb/rtl8150.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wan/sbni.c
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/airo.c
drivers/net/wireless/ath/Kconfig
drivers/net/wireless/ath/Makefile
drivers/net/wireless/ath/ath5k/ahb.c
drivers/net/wireless/ath/ath5k/ani.c
drivers/net/wireless/ath/ath5k/ani.h
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/base.h
drivers/net/wireless/ath/ath5k/caps.c
drivers/net/wireless/ath/ath5k/debug.c
drivers/net/wireless/ath/ath5k/desc.c
drivers/net/wireless/ath/ath5k/dma.c
drivers/net/wireless/ath/ath5k/eeprom.c
drivers/net/wireless/ath/ath5k/gpio.c
drivers/net/wireless/ath/ath5k/initvals.c
drivers/net/wireless/ath/ath5k/led.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/pci.c
drivers/net/wireless/ath/ath5k/pcu.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath5k/qcu.c
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath5k/rfkill.c
drivers/net/wireless/ath/ath5k/sysfs.c
drivers/net/wireless/ath/ath5k/trace.h
drivers/net/wireless/ath/ath6kl/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/bmi.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/bmi.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/cfg80211.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/cfg80211.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/common.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/core.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/debug.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/debug.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/hif-ops.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/hif.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/htc.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/htc.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/htc_hif.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/htc_hif.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/init.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/main.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/node.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/sdio.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/target.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/txrx.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/wmi.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/wmi.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ahb.c
drivers/net/wireless/ath/ath9k/ar9002_hw.c
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/calib.c
drivers/net/wireless/ath/ath9k/calib.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/eeprom.h
drivers/net/wireless/ath/ath9k/eeprom_4k.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/hw-ops.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/regd.h
drivers/net/wireless/ath/regd_common.h
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/phy_common.c
drivers/net/wireless/b43/phy_common.h
drivers/net/wireless/b43/phy_ht.c
drivers/net/wireless/b43/phy_ht.h
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/tables_phy_ht.c
drivers/net/wireless/b43/tables_phy_ht.h
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/dma.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/iwlegacy/iwl-3945-led.c
drivers/net/wireless/iwlegacy/iwl-3945-rs.c
drivers/net/wireless/iwlegacy/iwl-3945.c
drivers/net/wireless/iwlegacy/iwl-4965-led.c
drivers/net/wireless/iwlegacy/iwl-4965-rs.c
drivers/net/wireless/iwlegacy/iwl-4965.c
drivers/net/wireless/iwlegacy/iwl-led.c
drivers/net/wireless/iwlegacy/iwl3945-base.c
drivers/net/wireless/iwlegacy/iwl4965-base.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
drivers/net/wireless/iwlwifi/iwl-agn-hw.h
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-trans.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/cfg.h
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/decl.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/ethtool.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/mesh.c
drivers/net/wireless/libertas/mesh.h
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/ioctl.h
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/orinoco_usb.c
drivers/net/wireless/orinoco/wext.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rtlwifi/debug.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/wl1251/cmd.h
drivers/net/wireless/wl1251/wl12xx_80211.h
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/scan.h
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/testmode.c
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/zd1201.c
drivers/pci/xen-pcifront.c
drivers/pcmcia/pxa2xx_vpac270.c
drivers/platform/x86/thinkpad_acpi.c
drivers/power/ds2780_battery.c
drivers/power/max17042_battery.c
drivers/power/max8903_charger.c
drivers/power/max8997_charger.c
drivers/power/max8998_charger.c
drivers/power/olpc_battery.c
drivers/power/pda_power.c
drivers/power/power_supply_sysfs.c
drivers/power/s3c_adc_battery.c
drivers/power/wm831x_power.c
drivers/power/z2_battery.c
drivers/regulator/88pm8607.c
drivers/regulator/aat2870-regulator.c
drivers/regulator/max8649.c
drivers/regulator/max8952.c
drivers/regulator/tps65023-regulator.c
drivers/regulator/tps6507x-regulator.c
drivers/regulator/tps65912-regulator.c
drivers/rtc/rtc-twl.c
drivers/s390/block/dasd_ioctl.c
drivers/s390/char/zcore.c
drivers/s390/cio/ccwreq.c
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_setup.c
drivers/s390/cio/qdio_thinint.c
drivers/s390/net/lcs.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3.h
drivers/s390/net/qeth_l3_main.c
drivers/s390/net/qeth_l3_sys.c
drivers/scsi/bnx2fc/Kconfig
drivers/scsi/bnx2fc/bnx2fc.h
drivers/scsi/bnx2i/Kconfig
drivers/scsi/bnx2i/bnx2i.h
drivers/scsi/cxgbi/cxgb3i/Kbuild
drivers/scsi/cxgbi/cxgb3i/Kconfig
drivers/scsi/cxgbi/cxgb4i/Kbuild
drivers/scsi/cxgbi/cxgb4i/Kconfig
drivers/sh/intc/chip.c
drivers/spi/spi-atmel.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/ath6kl/Kconfig [deleted file]
drivers/staging/ath6kl/Makefile [deleted file]
drivers/staging/ath6kl/TODO [deleted file]
drivers/staging/ath6kl/bmi/include/bmi_internal.h [deleted file]
drivers/staging/ath6kl/bmi/src/bmi.c [deleted file]
drivers/staging/ath6kl/hif/common/hif_sdio_common.h [deleted file]
drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h [deleted file]
drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c [deleted file]
drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c [deleted file]
drivers/staging/ath6kl/htc2/AR6000/ar6k.c [deleted file]
drivers/staging/ath6kl/htc2/AR6000/ar6k.h [deleted file]
drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c [deleted file]
drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c [deleted file]
drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c [deleted file]
drivers/staging/ath6kl/htc2/htc.c [deleted file]
drivers/staging/ath6kl/htc2/htc_debug.h [deleted file]
drivers/staging/ath6kl/htc2/htc_internal.h [deleted file]
drivers/staging/ath6kl/htc2/htc_recv.c [deleted file]
drivers/staging/ath6kl/htc2/htc_send.c [deleted file]
drivers/staging/ath6kl/htc2/htc_services.c [deleted file]
drivers/staging/ath6kl/include/a_config.h [deleted file]
drivers/staging/ath6kl/include/a_debug.h [deleted file]
drivers/staging/ath6kl/include/a_drv.h [deleted file]
drivers/staging/ath6kl/include/a_drv_api.h [deleted file]
drivers/staging/ath6kl/include/a_osapi.h [deleted file]
drivers/staging/ath6kl/include/aggr_recv_api.h [deleted file]
drivers/staging/ath6kl/include/ar3kconfig.h [deleted file]
drivers/staging/ath6kl/include/ar6000_api.h [deleted file]
drivers/staging/ath6kl/include/ar6000_diag.h [deleted file]
drivers/staging/ath6kl/include/ar6kap_common.h [deleted file]
drivers/staging/ath6kl/include/athbtfilter.h [deleted file]
drivers/staging/ath6kl/include/bmi.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/addrs.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h [deleted file]
drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h [deleted file]
drivers/staging/ath6kl/include/common/athdefs.h [deleted file]
drivers/staging/ath6kl/include/common/bmi_msg.h [deleted file]
drivers/staging/ath6kl/include/common/cnxmgmt.h [deleted file]
drivers/staging/ath6kl/include/common/dbglog.h [deleted file]
drivers/staging/ath6kl/include/common/dbglog_id.h [deleted file]
drivers/staging/ath6kl/include/common/discovery.h [deleted file]
drivers/staging/ath6kl/include/common/epping_test.h [deleted file]
drivers/staging/ath6kl/include/common/gmboxif.h [deleted file]
drivers/staging/ath6kl/include/common/gpio_reg.h [deleted file]
drivers/staging/ath6kl/include/common/htc.h [deleted file]
drivers/staging/ath6kl/include/common/htc_services.h [deleted file]
drivers/staging/ath6kl/include/common/pkt_log.h [deleted file]
drivers/staging/ath6kl/include/common/roaming.h [deleted file]
drivers/staging/ath6kl/include/common/targaddrs.h [deleted file]
drivers/staging/ath6kl/include/common/testcmd.h [deleted file]
drivers/staging/ath6kl/include/common/tlpm.h [deleted file]
drivers/staging/ath6kl/include/common/wlan_defs.h [deleted file]
drivers/staging/ath6kl/include/common/wmi.h [deleted file]
drivers/staging/ath6kl/include/common/wmix.h [deleted file]
drivers/staging/ath6kl/include/common_drv.h [deleted file]
drivers/staging/ath6kl/include/dbglog_api.h [deleted file]
drivers/staging/ath6kl/include/dl_list.h [deleted file]
drivers/staging/ath6kl/include/dset_api.h [deleted file]
drivers/staging/ath6kl/include/hci_transport_api.h [deleted file]
drivers/staging/ath6kl/include/hif.h [deleted file]
drivers/staging/ath6kl/include/host_version.h [deleted file]
drivers/staging/ath6kl/include/htc_api.h [deleted file]
drivers/staging/ath6kl/include/htc_packet.h [deleted file]
drivers/staging/ath6kl/include/wlan_api.h [deleted file]
drivers/staging/ath6kl/include/wmi_api.h [deleted file]
drivers/staging/ath6kl/miscdrv/ar3kconfig.c [deleted file]
drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c [deleted file]
drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h [deleted file]
drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c [deleted file]
drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h [deleted file]
drivers/staging/ath6kl/miscdrv/common_drv.c [deleted file]
drivers/staging/ath6kl/miscdrv/credit_dist.c [deleted file]
drivers/staging/ath6kl/miscdrv/miscdrv.h [deleted file]
drivers/staging/ath6kl/os/linux/ar6000_drv.c [deleted file]
drivers/staging/ath6kl/os/linux/ar6000_pm.c [deleted file]
drivers/staging/ath6kl/os/linux/ar6000_raw_if.c [deleted file]
drivers/staging/ath6kl/os/linux/cfg80211.c [deleted file]
drivers/staging/ath6kl/os/linux/export_hci_transport.c [deleted file]
drivers/staging/ath6kl/os/linux/hci_bridge.c [deleted file]
drivers/staging/ath6kl/os/linux/include/ar6000_drv.h [deleted file]
drivers/staging/ath6kl/os/linux/include/ar6k_pal.h [deleted file]
drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/include/athdrv_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/include/cfg80211.h [deleted file]
drivers/staging/ath6kl/os/linux/include/config_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/include/debug_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/include/export_hci_transport.h [deleted file]
drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h [deleted file]
drivers/staging/ath6kl/os/linux/include/osapi_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/include/wlan_config.h [deleted file]
drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/netbuf.c [deleted file]
drivers/staging/ath6kl/reorder/aggr_rx_internal.h [deleted file]
drivers/staging/ath6kl/reorder/rcv_aggr.c [deleted file]
drivers/staging/ath6kl/wlan/include/ieee80211.h [deleted file]
drivers/staging/ath6kl/wlan/include/ieee80211_node.h [deleted file]
drivers/staging/ath6kl/wlan/src/wlan_node.c [deleted file]
drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c [deleted file]
drivers/staging/ath6kl/wlan/src/wlan_utils.c [deleted file]
drivers/staging/ath6kl/wmi/wmi.c [deleted file]
drivers/staging/ath6kl/wmi/wmi_host.h [deleted file]
drivers/staging/brcm80211/brcmfmac/dhd_linux.c
drivers/staging/brcm80211/brcmsmac/otp.c
drivers/staging/brcm80211/brcmsmac/types.h
drivers/staging/et131x/et131x_netdev.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/octeon/ethernet-rgmii.c
drivers/staging/octeon/ethernet-spi.c
drivers/staging/octeon/ethernet.c
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8192e/r8192E_core.c
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rts_pstor/rtsx.c
drivers/staging/slicoss/slicoss.c
drivers/staging/vt6655/device_main.c
drivers/staging/vt6656/main_usb.c
drivers/staging/wlags49_h2/wl_netdev.c
drivers/staging/wlan-ng/p80211netdev.c
drivers/staging/xgifb/XGI_main_26.c
drivers/staging/zcache/tmem.c
drivers/staging/zcache/zcache-main.c
drivers/tty/pty.c
drivers/tty/serial/8250.c
drivers/tty/serial/8250_pci.c
drivers/tty/serial/8250_pnp.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/max3107-aava.c
drivers/tty/serial/max3107.c
drivers/tty/serial/mrst_max3110.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/samsung.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/ucc_uart.c
drivers/tty/tty_io.c
drivers/uio/uio.c
drivers/uio/uio_pci_generic.c
drivers/uio/uio_pdrv_genirq.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/gadget/f_phonet.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-s5p.c
drivers/usb/host/ohci-pnx4008.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_regs.h
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010_omap.c
drivers/usb/musb/ux500_dma.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/sierra.c
drivers/usb/serial/usb_wwan.c
drivers/video/68328fb.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/acornfb.c
drivers/video/arkfb.c
drivers/video/atmel_lcdfb.c
drivers/video/aty/radeon_base.c
drivers/video/au1200fb.c
drivers/video/backlight/adp8860_bl.c
drivers/video/backlight/adp8870_bl.c
drivers/video/carminefb.c
drivers/video/controlfb.c
drivers/video/da8xx-fb.c
drivers/video/fb-puv3.c
drivers/video/fb_defio.c
drivers/video/fsl-diu-fb.c
drivers/video/g364fb.c
drivers/video/grvga.c [new file with mode: 0644]
drivers/video/gxt4500.c
drivers/video/hgafb.c
drivers/video/imsttfb.c
drivers/video/intelfb/intelfbhw.c
drivers/video/mb862xx/mb862xxfbdrv.c
drivers/video/msm/mdp.c
drivers/video/mx3fb.c
drivers/video/neofb.c
drivers/video/omap/lcd_apollon.c
drivers/video/omap/lcd_h3.c
drivers/video/omap/lcd_inn1610.c
drivers/video/omap/lcd_ldp.c
drivers/video/omap/lcd_osk.c
drivers/video/omap/lcd_overo.c
drivers/video/omap/lcd_palmtt.c
drivers/video/platinumfb.c
drivers/video/pm2fb.c
drivers/video/pm3fb.c
drivers/video/pnx4008/sdum.c
drivers/video/pxa3xx-gcu.c
drivers/video/s3c-fb.c
drivers/video/s3c2410fb.c
drivers/video/s3fb.c
drivers/video/savage/savagefb_driver.c
drivers/video/sis/sis_main.c
drivers/video/skeletonfb.c
drivers/video/sm501fb.c
drivers/video/tridentfb.c
drivers/video/udlfb.c
drivers/video/valkyriefb.c
drivers/video/vfb.c
drivers/video/vga16fb.c
drivers/video/via/dvi.c
drivers/video/via/dvi.h
drivers/video/via/global.c
drivers/video/via/global.h
drivers/video/via/hw.c
drivers/video/via/hw.h
drivers/video/via/lcd.c
drivers/video/via/lcd.h
drivers/video/via/share.h
drivers/video/via/via-core.c
drivers/video/via/via_modesetting.c
drivers/video/via/via_modesetting.h
drivers/video/via/viafbdev.c
drivers/video/via/viamode.c
drivers/video/via/viamode.h
drivers/video/vt8500lcdfb.c
drivers/video/vt8623fb.c
drivers/video/xilinxfb.c
drivers/watchdog/bcm47xx_wdt.c
drivers/watchdog/hpwdt.c
drivers/watchdog/watchdog_dev.c
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/pci.c
drivers/xen/swiotlb-xen.c
drivers/xen/xen-balloon.c
drivers/xen/xen-pciback/conf_space_header.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe.h
drivers/zorro/zorro-driver.c
fs/9p/v9fs_vfs.h
fs/9p/vfs_dir.c
fs/9p/vfs_file.c
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/9p/vfs_super.c
fs/attr.c
fs/btrfs/async-thread.c
fs/btrfs/disk-io.c
fs/btrfs/xattr.c
fs/cachefiles/namei.c
fs/cachefiles/xattr.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/ioctl.h
fs/ceph/mds_client.c
fs/ceph/super.c
fs/ceph/super.h
fs/cifs/cifssmb.c
fs/cifs/xattr.c
fs/debugfs/inode.c
fs/eventpoll.c
fs/exec.c
fs/exofs/exofs.h
fs/exofs/super.c
fs/ext2/xattr_security.c
fs/ext3/xattr_security.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/super.c
fs/ext4/xattr_security.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/gfs2/acl.c
fs/gfs2/aops.c
fs/gfs2/dir.c
fs/gfs2/file.c
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/inode.h
fs/gfs2/log.c
fs/gfs2/quota.c
fs/gfs2/super.c
fs/gfs2/xattr.c
fs/jbd/journal.c
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/jffs2/scan.c
fs/jffs2/security.c
fs/jffs2/wbuf.c
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_txnmgr.c
fs/jfs/xattr.c
fs/logfs/dev_mtd.c
fs/logfs/logfs.h
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/logfs/super.c
fs/nfs/nfs4filelayout.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/nilfs2/segment.c
fs/notify/dnotify/dnotify.c
fs/notify/fanotify/fanotify.c
fs/notify/fanotify/fanotify_user.c
fs/notify/group.c
fs/notify/mark.c
fs/ocfs2/aops.c
fs/ocfs2/aops.h
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/cluster/tcp.h
fs/ocfs2/dir.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmlock.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/dlm/dlmthread.c
fs/ocfs2/dlmglue.c
fs/ocfs2/extent_map.c
fs/ocfs2/extent_map.h
fs/ocfs2/file.c
fs/ocfs2/inode.h
fs/ocfs2/ioctl.c
fs/ocfs2/journal.c
fs/ocfs2/mmap.c
fs/ocfs2/move_extents.c
fs/ocfs2/ocfs2.h
fs/ocfs2/quota_local.c
fs/ocfs2/slot_map.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/super.c
fs/ocfs2/xattr.c
fs/proc/inode.c
fs/proc/namespaces.c
fs/proc/proc_sysctl.c
fs/pstore/inode.c
fs/pstore/internal.h
fs/pstore/platform.c
fs/reiserfs/xattr_security.c
fs/sysfs/dir.c
fs/sysfs/inode.c
fs/sysfs/sysfs.h
fs/ubifs/debug.h
fs/xattr.c
fs/xfs/Makefile
fs/xfs/kmem.c [moved from fs/xfs/linux-2.6/kmem.c with 100% similarity]
fs/xfs/kmem.h [moved from fs/xfs/linux-2.6/kmem.h with 100% similarity]
fs/xfs/mrlock.h [moved from fs/xfs/linux-2.6/mrlock.h with 100% similarity]
fs/xfs/time.h [moved from fs/xfs/linux-2.6/time.h with 100% similarity]
fs/xfs/uuid.c [moved from fs/xfs/support/uuid.c with 100% similarity]
fs/xfs/uuid.h [moved from fs/xfs/support/uuid.h with 100% similarity]
fs/xfs/xfs.h
fs/xfs/xfs_acl.c [moved from fs/xfs/linux-2.6/xfs_acl.c with 100% similarity]
fs/xfs/xfs_aops.c [moved from fs/xfs/linux-2.6/xfs_aops.c with 100% similarity]
fs/xfs/xfs_aops.h [moved from fs/xfs/linux-2.6/xfs_aops.h with 100% similarity]
fs/xfs/xfs_buf.c [moved from fs/xfs/linux-2.6/xfs_buf.c with 99% similarity]
fs/xfs/xfs_buf.h [moved from fs/xfs/linux-2.6/xfs_buf.h with 100% similarity]
fs/xfs/xfs_discard.c [moved from fs/xfs/linux-2.6/xfs_discard.c with 100% similarity]
fs/xfs/xfs_discard.h [moved from fs/xfs/linux-2.6/xfs_discard.h with 100% similarity]
fs/xfs/xfs_dquot.c [moved from fs/xfs/quota/xfs_dquot.c with 100% similarity]
fs/xfs/xfs_dquot.h [moved from fs/xfs/quota/xfs_dquot.h with 100% similarity]
fs/xfs/xfs_dquot_item.c [moved from fs/xfs/quota/xfs_dquot_item.c with 100% similarity]
fs/xfs/xfs_dquot_item.h [moved from fs/xfs/quota/xfs_dquot_item.h with 100% similarity]
fs/xfs/xfs_export.c [moved from fs/xfs/linux-2.6/xfs_export.c with 100% similarity]
fs/xfs/xfs_export.h [moved from fs/xfs/linux-2.6/xfs_export.h with 100% similarity]
fs/xfs/xfs_file.c [moved from fs/xfs/linux-2.6/xfs_file.c with 100% similarity]
fs/xfs/xfs_fs_subr.c [moved from fs/xfs/linux-2.6/xfs_fs_subr.c with 100% similarity]
fs/xfs/xfs_globals.c [moved from fs/xfs/linux-2.6/xfs_globals.c with 100% similarity]
fs/xfs/xfs_ioctl.c [moved from fs/xfs/linux-2.6/xfs_ioctl.c with 100% similarity]
fs/xfs/xfs_ioctl.h [moved from fs/xfs/linux-2.6/xfs_ioctl.h with 100% similarity]
fs/xfs/xfs_ioctl32.c [moved from fs/xfs/linux-2.6/xfs_ioctl32.c with 100% similarity]
fs/xfs/xfs_ioctl32.h [moved from fs/xfs/linux-2.6/xfs_ioctl32.h with 100% similarity]
fs/xfs/xfs_iops.c [moved from fs/xfs/linux-2.6/xfs_iops.c with 98% similarity]
fs/xfs/xfs_iops.h [moved from fs/xfs/linux-2.6/xfs_iops.h with 100% similarity]
fs/xfs/xfs_linux.h [moved from fs/xfs/linux-2.6/xfs_linux.h with 96% similarity]
fs/xfs/xfs_message.c [moved from fs/xfs/linux-2.6/xfs_message.c with 100% similarity]
fs/xfs/xfs_message.h [moved from fs/xfs/linux-2.6/xfs_message.h with 100% similarity]
fs/xfs/xfs_qm.c [moved from fs/xfs/quota/xfs_qm.c with 100% similarity]
fs/xfs/xfs_qm.h [moved from fs/xfs/quota/xfs_qm.h with 100% similarity]
fs/xfs/xfs_qm_bhv.c [moved from fs/xfs/quota/xfs_qm_bhv.c with 100% similarity]
fs/xfs/xfs_qm_stats.c [moved from fs/xfs/quota/xfs_qm_stats.c with 100% similarity]
fs/xfs/xfs_qm_stats.h [moved from fs/xfs/quota/xfs_qm_stats.h with 100% similarity]
fs/xfs/xfs_qm_syscalls.c [moved from fs/xfs/quota/xfs_qm_syscalls.c with 100% similarity]
fs/xfs/xfs_quota_priv.h [moved from fs/xfs/quota/xfs_quota_priv.h with 100% similarity]
fs/xfs/xfs_quotaops.c [moved from fs/xfs/linux-2.6/xfs_quotaops.c with 99% similarity]
fs/xfs/xfs_stats.c [moved from fs/xfs/linux-2.6/xfs_stats.c with 100% similarity]
fs/xfs/xfs_stats.h [moved from fs/xfs/linux-2.6/xfs_stats.h with 100% similarity]
fs/xfs/xfs_super.c [moved from fs/xfs/linux-2.6/xfs_super.c with 100% similarity]
fs/xfs/xfs_super.h [moved from fs/xfs/linux-2.6/xfs_super.h with 100% similarity]
fs/xfs/xfs_sync.c [moved from fs/xfs/linux-2.6/xfs_sync.c with 100% similarity]
fs/xfs/xfs_sync.h [moved from fs/xfs/linux-2.6/xfs_sync.h with 100% similarity]
fs/xfs/xfs_sysctl.c [moved from fs/xfs/linux-2.6/xfs_sysctl.c with 100% similarity]
fs/xfs/xfs_sysctl.h [moved from fs/xfs/linux-2.6/xfs_sysctl.h with 100% similarity]
fs/xfs/xfs_trace.c [moved from fs/xfs/linux-2.6/xfs_trace.c with 96% similarity]
fs/xfs/xfs_trace.h [moved from fs/xfs/linux-2.6/xfs_trace.h with 100% similarity]
fs/xfs/xfs_trans_dquot.c [moved from fs/xfs/quota/xfs_trans_dquot.c with 100% similarity]
fs/xfs/xfs_vnode.h [moved from fs/xfs/linux-2.6/xfs_vnode.h with 100% similarity]
fs/xfs/xfs_xattr.c [moved from fs/xfs/linux-2.6/xfs_xattr.c with 100% similarity]
include/crypto/sha.h
include/linux/atmel-mci.h
include/linux/atmel_pdc.h
include/linux/bcma/bcma.h
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/bcma/bcma_driver_mips.h [new file with mode: 0644]
include/linux/bcma/bcma_soc.h [new file with mode: 0644]
include/linux/bma150.h [new file with mode: 0644]
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
include/linux/crash_dump.h
include/linux/device-mapper.h
include/linux/device.h
include/linux/dm-kcopyd.h
include/linux/dmaengine.h
include/linux/dynamic_debug.h
include/linux/edac.h
include/linux/edac_mce.h [deleted file]
include/linux/ethtool.h
include/linux/evm.h [new file with mode: 0644]
include/linux/ext2_fs.h
include/linux/ext3_fs.h
include/linux/fanotify.h
include/linux/freezer.h
include/linux/fsnotify_backend.h
include/linux/fuse.h
include/linux/hid.h
include/linux/i2c/twl4030-madc.h
include/linux/ieee80211.h
include/linux/if.h
include/linux/if_ether.h
include/linux/ima.h
include/linux/integrity.h [new file with mode: 0644]
include/linux/kexec.h
include/linux/kthread.h
include/linux/lockdep.h
include/linux/mfd/ab8500/gpadc.h
include/linux/mfd/max8997-private.h
include/linux/mfd/pcf50633/core.h
include/linux/mfd/wm831x/core.h
include/linux/mfd/wm8400-private.h
include/linux/mfd/wm8994/core.h
include/linux/mfd/wm8994/pdata.h
include/linux/mfd/wm8994/registers.h
include/linux/mmc/host.h
include/linux/mtd/bbm.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/onenand.h
include/linux/mtd/partitions.h
include/linux/mtd/physmap.h
include/linux/netdevice.h
include/linux/nl80211.h
include/linux/pda_power.h
include/linux/pm.h
include/linux/pm_clock.h [new file with mode: 0644]
include/linux/pm_domain.h
include/linux/pm_qos.h [new file with mode: 0644]
include/linux/pm_qos_params.h [deleted file]
include/linux/pm_runtime.h
include/linux/pstore.h
include/linux/random.h
include/linux/rcupdate.h
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/regmap.h
include/linux/regulator/consumer.h
include/linux/sched.h
include/linux/security.h
include/linux/skbuff.h
include/linux/ssb/ssb_regs.h
include/linux/sungem_phy.h [moved from drivers/net/sungem_phy.h with 98% similarity]
include/linux/suspend.h
include/linux/ti_wilink_st.h
include/linux/tty.h
include/linux/tty_driver.h
include/linux/types.h
include/linux/virtio_config.h
include/linux/xattr.h
include/net/9p/9p.h
include/net/9p/transport.h
include/net/addrconf.h
include/net/bluetooth/l2cap.h
include/net/cfg80211-wext.h [new file with mode: 0644]
include/net/cfg80211.h
include/net/dst.h
include/net/if_inet6.h
include/net/iucv/af_iucv.h
include/net/iucv/iucv.h
include/net/lib80211.h
include/net/mac80211.h
include/net/sock.h
include/scsi/osd_ore.h
include/sound/adau1373.h [new file with mode: 0644]
include/sound/pcm.h
include/sound/soc-dapm.h
include/sound/soc.h
include/trace/events/rcu.h [new file with mode: 0644]
include/trace/events/regmap.h [new file with mode: 0644]
init/Kconfig
kernel/Makefile
kernel/cgroup_freezer.c
kernel/crash_dump.c
kernel/cred.c
kernel/exit.c
kernel/fork.c
kernel/freezer.c
kernel/irq/manage.c
kernel/kexec.c
kernel/kthread.c
kernel/lockdep.c
kernel/pid.c
kernel/power/Kconfig
kernel/power/Makefile
kernel/power/hibernate.c
kernel/power/main.c
kernel/power/process.c
kernel/power/qos.c [moved from kernel/pm_qos_params.c with 71% similarity]
kernel/power/snapshot.c
kernel/power/suspend.c
kernel/power/user.c
kernel/rcu.h [new file with mode: 0644]
kernel/rcupdate.c
kernel/rcutiny.c
kernel/rcutiny_plugin.h
kernel/rcutorture.c
kernel/rcutree.c
kernel/rcutree.h
kernel/rcutree_plugin.h
kernel/rcutree_trace.c
kernel/rtmutex.c
kernel/sched.c
kernel/sysctl_binary.c
kernel/sysctl_check.c
kernel/time/tick-sched.c
lib/Kconfig.debug
lib/dynamic_debug.c
lib/fault-inject.c
lib/idr.c
lib/kobject_uevent.c
mm/backing-dev.c
mm/percpu-vm.c
mm/percpu.c
mm/shmem.c
net/802/garp.c
net/802/stp.c
net/8021q/vlan.c
net/8021q/vlan_core.c
net/8021q/vlan_dev.c
net/9p/client.c
net/9p/protocol.c
net/9p/protocol.h
net/9p/trans_common.c
net/9p/trans_common.h
net/9p/trans_virtio.c
net/atm/br2684.c
net/atm/lec.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/bnep.h
net/bluetooth/bnep/core.c
net/bluetooth/bnep/netdev.c
net/bluetooth/cmtp/capi.c
net/bluetooth/cmtp/cmtp.h
net/bluetooth/cmtp/core.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bridge/br_device.c
net/bridge/netfilter/ebtable_broute.c
net/caif/cfmuxl.c
net/can/af_can.c
net/ceph/ceph_common.c
net/ceph/messenger.c
net/ceph/mon_client.c
net/ceph/msgpool.c
net/ceph/osd_client.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/dst.c
net/core/fib_rules.c
net/core/filter.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/netpoll.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.h
net/dccp/dccp.h
net/dccp/feat.c
net/dccp/feat.h
net/dccp/proto.c
net/decnet/dn_dev.c
net/dsa/slave.c
net/ipv4/devinet.c
net/ipv4/fib_trie.c
net/ipv4/gre.c
net/ipv4/igmp.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/netfilter/nf_nat_amanda.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_ftp.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_irc.c
net/ipv4/netfilter/nf_nat_pptp.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/netfilter/nf_nat_tftp.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/raw.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/irda/irlan/irlan_eth.c
net/iucv/Kconfig
net/iucv/af_iucv.c
net/iucv/iucv.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/status.c
net/mac80211/tx.c
net/mac80211/util.c
net/netfilter/core.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_extend.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_log.c
net/netfilter/nf_queue.c
net/netfilter/nfnetlink.c
net/netlabel/netlabel_domainhash.c
net/netlabel/netlabel_unlabeled.c
net/netlink/af_netlink.c
net/phonet/af_phonet.c
net/phonet/pn_dev.c
net/phonet/socket.c
net/sched/act_mirred.c
net/socket.c
net/sunrpc/auth_gss/auth_gss.c
net/wireless/core.c
net/wireless/lib80211.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/scan.c
net/wireless/sysfs.c
net/wireless/util.c
net/wireless/wext-compat.c
net/wireless/wext-compat.h
net/wireless/wext-sme.c
net/xfrm/xfrm_user.c
scripts/kconfig/Makefile
scripts/kconfig/menu.c
scripts/kconfig/nconf.c
scripts/kconfig/streamline_config.pl
security/Kconfig
security/Makefile
security/commoncap.c
security/integrity/Kconfig [new file with mode: 0644]
security/integrity/Makefile [new file with mode: 0644]
security/integrity/evm/Kconfig [new file with mode: 0644]
security/integrity/evm/Makefile [new file with mode: 0644]
security/integrity/evm/evm.h [new file with mode: 0644]
security/integrity/evm/evm_crypto.c [new file with mode: 0644]
security/integrity/evm/evm_main.c [new file with mode: 0644]
security/integrity/evm/evm_secfs.c [new file with mode: 0644]
security/integrity/iint.c [new file with mode: 0644]
security/integrity/ima/Kconfig
security/integrity/ima/Makefile
security/integrity/ima/ima.h
security/integrity/ima/ima_api.c
security/integrity/ima/ima_iint.c [deleted file]
security/integrity/ima/ima_main.c
security/integrity/integrity.h [new file with mode: 0644]
security/keys/gc.c
security/keys/internal.h
security/keys/key.c
security/keys/keyring.c
security/keys/process_keys.c
security/security.c
security/tomoyo/gc.c
sound/core/pcm_native.c
sound/firewire/isight.c
sound/mips/Kconfig
sound/pci/hda/Makefile
sound/pci/hda/alc260_quirks.c
sound/pci/hda/alc262_quirks.c
sound/pci/hda/alc268_quirks.c [deleted file]
sound/pci/hda/alc269_quirks.c [deleted file]
sound/pci/hda/alc662_quirks.c
sound/pci/hda/alc680_quirks.c [deleted file]
sound/pci/hda/alc861_quirks.c [deleted file]
sound/pci/hda/alc861vd_quirks.c [deleted file]
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_local.h
sound/pci/hda/hda_trace.h [new file with mode: 0644]
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/oxygen/xonar_pcm179x.c
sound/pci/rme9652/hdspm.c
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/au1x/Kconfig
sound/soc/au1x/Makefile
sound/soc/au1x/ac97c.c [new file with mode: 0644]
sound/soc/au1x/db1000.c [new file with mode: 0644]
sound/soc/au1x/db1200.c
sound/soc/au1x/dbdma2.c
sound/soc/au1x/dma.c [new file with mode: 0644]
sound/soc/au1x/i2sc.c [new file with mode: 0644]
sound/soc/au1x/psc-ac97.c
sound/soc/au1x/psc-i2s.c
sound/soc/au1x/psc.h
sound/soc/blackfin/Kconfig
sound/soc/blackfin/Makefile
sound/soc/blackfin/bf5xx-ad193x.c
sound/soc/blackfin/bfin-eval-adau1373.c [new file with mode: 0644]
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ad193x.c
sound/soc/codecs/ad193x.h
sound/soc/codecs/adau1373.c [new file with mode: 0644]
sound/soc/codecs/adau1373.h [new file with mode: 0644]
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/wm1250-ev1.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8737.c
sound/soc/codecs/wm8741.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm8994-tables.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8994.h
sound/soc/codecs/wm8996.c
sound/soc/codecs/wm_hubs.c
sound/soc/codecs/wm_hubs.h
sound/soc/ep93xx/ep93xx-i2s.c
sound/soc/fsl/fsl_dma.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/p1022_ds.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/mxs/Kconfig [new file with mode: 0644]
sound/soc/mxs/Makefile [new file with mode: 0644]
sound/soc/mxs/mxs-pcm.c [new file with mode: 0644]
sound/soc/mxs/mxs-pcm.h [new file with mode: 0644]
sound/soc/mxs/mxs-saif.c [new file with mode: 0644]
sound/soc/mxs/mxs-saif.h [new file with mode: 0644]
sound/soc/mxs/mxs-sgtl5000.c [new file with mode: 0644]
sound/soc/nuc900/nuc900-pcm.c
sound/soc/omap/ams-delta.c
sound/soc/pxa/spitz.c
sound/soc/pxa/z2.c
sound/soc/s6000/s6000-pcm.c
sound/soc/samsung/h1940_uda1380.c
sound/soc/samsung/jive_wm8750.c
sound/soc/samsung/rx1950_uda1380.c
sound/soc/samsung/smartq_wm8987.c
sound/soc/samsung/smdk_wm8580.c
sound/soc/samsung/smdk_wm8580pcm.c
sound/soc/samsung/speyside.c
sound/soc/samsung/speyside_wm8962.c
sound/soc/soc-cache.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-io.c
sound/soc/soc-jack.c
sound/soc/soc-pcm.c
sound/usb/card.c
sound/usb/mixer.c
tools/perf/arch/arm/util/dwarf-regs.c
tools/power/cpupower/Makefile
tools/power/cpupower/debug/x86_64/Makefile
tools/power/cpupower/debug/x86_64/centrino-decode.c [deleted symlink]
tools/power/cpupower/debug/x86_64/powernow-k8-decode.c [deleted symlink]
tools/power/cpupower/man/cpupower-frequency-info.1
tools/power/cpupower/man/cpupower-frequency-set.1
tools/power/cpupower/man/cpupower.1
tools/power/cpupower/utils/builtin.h
tools/power/cpupower/utils/cpufreq-info.c
tools/power/cpupower/utils/cpufreq-set.c
tools/power/cpupower/utils/cpuidle-info.c
tools/power/cpupower/utils/cpupower-info.c
tools/power/cpupower/utils/cpupower-set.c
tools/power/cpupower/utils/cpupower.c
tools/power/cpupower/utils/helpers/helpers.h
tools/power/cpupower/utils/helpers/sysfs.c
tools/power/cpupower/utils/helpers/sysfs.h
tools/power/cpupower/utils/helpers/topology.c
tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
tools/power/cpupower/utils/idle_monitor/mperf_monitor.c

index 7f5daa465093b898f123b67fb4bc8ab453ce9bc0..20c91adca6d412102dabf73d6b6f387a60d888ec 100644 (file)
@@ -1,6 +1,6 @@
 What:          /sys/o2cb symlink
 Date:          May 2011
-KernelVersion: 2.6.40
+KernelVersion: 3.0
 Contact:       ocfs2-devel@oss.oracle.com
 Description:   This is a symlink: /sys/o2cb to /sys/fs/o2cb. The symlink is
                removed when new versions of ocfs2-tools which know to look
diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm
new file mode 100644 (file)
index 0000000..8374d45
--- /dev/null
@@ -0,0 +1,23 @@
+What:          security/evm
+Date:          March 2011
+Contact:       Mimi Zohar <zohar@us.ibm.com>
+Description:
+               EVM protects a file's security extended attributes(xattrs)
+               against integrity attacks. The initial method maintains an
+               HMAC-sha1 value across the extended attributes, storing the
+               value as the extended attribute 'security.evm'.
+
+               EVM depends on the Kernel Key Retention System to provide it
+               with a trusted/encrypted key for the HMAC-sha1 operation.
+               The key is loaded onto the root's keyring using keyctl.  Until
+               EVM receives notification that the key has been successfully
+               loaded onto the keyring (echo 1 > <securityfs>/evm), EVM
+               can not create or validate the 'security.evm' xattr, but
+               returns INTEGRITY_UNKNOWN.  Loading the key and signaling EVM
+               should be done as early as possible.  Normally this is done
+               in the initramfs, which has already been measured as part
+               of the trusted boot.  For more information on creating and
+               loading existing trusted/encrypted keys, refer to:
+               Documentation/keys-trusted-encrypted.txt.  (A sample dracut
+               patch, which loads the trusted/encrypted key and enables
+               EVM, is available from http://linux-ima.sourceforge.net/#EVM.)
index 06b62badddd18a4b5fdc61ae9012ad73621fcb7e..721b4aea3020a43f4722e61c6cff9cede284e664 100644 (file)
@@ -1,6 +1,6 @@
 What:          /sys/bus/bcma/devices/.../manuf
 Date:          May 2011
-KernelVersion: 2.6.40
+KernelVersion: 3.0
 Contact:       RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
 Description:
                Each BCMA core has it's manufacturer id. See
@@ -8,7 +8,7 @@ Description:
 
 What:          /sys/bus/bcma/devices/.../id
 Date:          May 2011
-KernelVersion: 2.6.40
+KernelVersion: 3.0
 Contact:       RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
 Description:
                There are a few types of BCMA cores, they can be identified by
@@ -16,7 +16,7 @@ Description:
 
 What:          /sys/bus/bcma/devices/.../rev
 Date:          May 2011
-KernelVersion: 2.6.40
+KernelVersion: 3.0
 Contact:       RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
 Description:
                BCMA cores of the same type can still slightly differ depending
@@ -24,7 +24,7 @@ Description:
 
 What:          /sys/bus/bcma/devices/.../class
 Date:          May 2011
-KernelVersion: 2.6.40
+KernelVersion: 3.0
 Contact:       RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
 Description:
                Each BCMA core is identified by few fields, including class it
index f5bb0a3bb8c0d5d18bdcfdd2bf8ce70765ed4dc5..53d99edd1d75acf45fc63152b111d5fbcc6ea202 100644 (file)
@@ -71,3 +71,10 @@ Description: Value of 1 indicates the controller can honor the reset_devices
                a dump device, as kdump requires resetting the device in order
                to work reliably.
 
+Where:         /sys/bus/pci/devices/<dev>/ccissX/transport_mode
+Date:          July 2011
+Kernel Version:        3.0
+Contact:       iss_storagedev@hp.com
+Description:   Value of "simple" indicates that the controller has been placed
+               in "simple mode". Value of "performant" indicates that the
+               controller has been placed in "performant mode".
index aa11dbdd794b2e1725bc254651198fa1af938f35..4a9c545bda4ba2d4d75637290007d2b510134c9f 100644 (file)
@@ -4,8 +4,8 @@ What:           /sys/class/backlight/<backlight>/l2_bright_max
 What:          /sys/class/backlight/<backlight>/l3_office_max
 What:          /sys/class/backlight/<backlight>/l4_indoor_max
 What:          /sys/class/backlight/<backlight>/l5_dark_max
-Date:          Mai 2011
-KernelVersion: 2.6.40
+Date:          May 2011
+KernelVersion: 3.0
 Contact:       device-drivers-devel@blackfin.uclinux.org
 Description:
                Control the maximum brightness for <ambient light zone>
@@ -18,8 +18,8 @@ What:         /sys/class/backlight/<backlight>/l2_bright_dim
 What:          /sys/class/backlight/<backlight>/l3_office_dim
 What:          /sys/class/backlight/<backlight>/l4_indoor_dim
 What:          /sys/class/backlight/<backlight>/l5_dark_dim
-Date:          Mai 2011
-KernelVersion: 2.6.40
+Date:          May 2011
+KernelVersion: 3.0
 Contact:       device-drivers-devel@blackfin.uclinux.org
 Description:
                Control the dim brightness for <ambient light zone>
@@ -29,8 +29,8 @@ Description:
                this <ambient light zone>.
 
 What:          /sys/class/backlight/<backlight>/ambient_light_level
-Date:          Mai 2011
-KernelVersion: 2.6.40
+Date:          May 2011
+KernelVersion: 3.0
 Contact:       device-drivers-devel@blackfin.uclinux.org
 Description:
                Get conversion value of the light sensor.
@@ -39,8 +39,8 @@ Description:
                8000 (max ambient brightness)
 
 What:          /sys/class/backlight/<backlight>/ambient_light_zone
-Date:          Mai 2011
-KernelVersion: 2.6.40
+Date:          May 2011
+KernelVersion: 3.0
 Contact:       device-drivers-devel@blackfin.uclinux.org
 Description:
                Get/Set current ambient light zone. Reading returns
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff b/Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff
new file mode 100644 (file)
index 0000000..9aec8ef
--- /dev/null
@@ -0,0 +1,7 @@
+What:          /sys/module/hid_logitech/drivers/hid:logitech/<dev>/range.
+Date:          July 2011
+KernelVersion: 3.2
+Contact:       Michal Malý <madcatxster@gmail.com>
+Description:   Display minimum, maximum and current range of the steering
+               wheel. Writing a value within min and max boundaries sets the
+               range of the wheel.
index 17910e2052addefcc2a581fa810991fde2545820..8c07540c181cd86c6ebc90728cadcc968c27a95e 100644 (file)
@@ -572,7 +572,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
                        </para>
                        <para>
                                The simplest way to activate the FLASH based bad block table support 
-                               is to set the option NAND_USE_FLASH_BBT in the option field of
+                               is to set the option NAND_BBT_USE_FLASH in the bbt_option field of
                                the nand chip structure before calling nand_scan(). For AG-AND
                                chips is this done by default.
                                This activates the default FLASH based bad block table functionality 
@@ -1158,9 +1158,6 @@ in this page</entry>
                These constants are defined in nand.h. They are ored together to describe
                the functionality.
                <programlisting>
-/* Use a flash based bad block table. This option is parsed by the
- * default bad block table function (nand_default_bbt). */
-#define NAND_USE_FLASH_BBT     0x00010000
 /* The hw ecc generator provides a syndrome instead a ecc value on read 
  * This can only work if we have the ecc bytes directly behind the 
  * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
index bf82851a0e576e501137090a6550cee82f8cc3bb..687777f83b2371d4bd24e5d7abff88d7cf90a5d8 100644 (file)
@@ -95,7 +95,7 @@ not to return until all ongoing NMI handlers exit.  It is therefore safe
 to free up the handler's data as soon as synchronize_sched() returns.
 
 Important note: for this to work, the architecture in question must
-invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
+invoke nmi_enter() and nmi_exit() on NMI entry and exit, respectively.
 
 
 Answer to Quick Quiz
diff --git a/Documentation/RCU/lockdep-splat.txt b/Documentation/RCU/lockdep-splat.txt
new file mode 100644 (file)
index 0000000..bf90611
--- /dev/null
@@ -0,0 +1,110 @@
+Lockdep-RCU was added to the Linux kernel in early 2010
+(http://lwn.net/Articles/371986/).  This facility checks for some common
+misuses of the RCU API, most notably using one of the rcu_dereference()
+family to access an RCU-protected pointer without the proper protection.
+When such misuse is detected, an lockdep-RCU splat is emitted.
+
+The usual cause of a lockdep-RCU slat is someone accessing an
+RCU-protected data structure without either (1) being in the right kind of
+RCU read-side critical section or (2) holding the right update-side lock.
+This problem can therefore be serious: it might result in random memory
+overwriting or worse.  There can of course be false positives, this
+being the real world and all that.
+
+So let's look at an example RCU lockdep splat from 3.0-rc5, one that
+has long since been fixed:
+
+===============================
+[ INFO: suspicious RCU usage. ]
+-------------------------------
+block/cfq-iosched.c:2776 suspicious rcu_dereference_protected() usage!
+
+other info that might help us debug this:
+
+
+rcu_scheduler_active = 1, debug_locks = 0
+3 locks held by scsi_scan_6/1552:
+ #0:  (&shost->scan_mutex){+.+.+.}, at: [<ffffffff8145efca>]
+scsi_scan_host_selected+0x5a/0x150
+ #1:  (&eq->sysfs_lock){+.+...}, at: [<ffffffff812a5032>]
+elevator_exit+0x22/0x60
+ #2:  (&(&q->__queue_lock)->rlock){-.-...}, at: [<ffffffff812b6233>]
+cfq_exit_queue+0x43/0x190
+
+stack backtrace:
+Pid: 1552, comm: scsi_scan_6 Not tainted 3.0.0-rc5 #17
+Call Trace:
+ [<ffffffff810abb9b>] lockdep_rcu_dereference+0xbb/0xc0
+ [<ffffffff812b6139>] __cfq_exit_single_io_context+0xe9/0x120
+ [<ffffffff812b626c>] cfq_exit_queue+0x7c/0x190
+ [<ffffffff812a5046>] elevator_exit+0x36/0x60
+ [<ffffffff812a802a>] blk_cleanup_queue+0x4a/0x60
+ [<ffffffff8145cc09>] scsi_free_queue+0x9/0x10
+ [<ffffffff81460944>] __scsi_remove_device+0x84/0xd0
+ [<ffffffff8145dca3>] scsi_probe_and_add_lun+0x353/0xb10
+ [<ffffffff817da069>] ? error_exit+0x29/0xb0
+ [<ffffffff817d98ed>] ? _raw_spin_unlock_irqrestore+0x3d/0x80
+ [<ffffffff8145e722>] __scsi_scan_target+0x112/0x680
+ [<ffffffff812c690d>] ? trace_hardirqs_off_thunk+0x3a/0x3c
+ [<ffffffff817da069>] ? error_exit+0x29/0xb0
+ [<ffffffff812bcc60>] ? kobject_del+0x40/0x40
+ [<ffffffff8145ed16>] scsi_scan_channel+0x86/0xb0
+ [<ffffffff8145f0b0>] scsi_scan_host_selected+0x140/0x150
+ [<ffffffff8145f149>] do_scsi_scan_host+0x89/0x90
+ [<ffffffff8145f170>] do_scan_async+0x20/0x160
+ [<ffffffff8145f150>] ? do_scsi_scan_host+0x90/0x90
+ [<ffffffff810975b6>] kthread+0xa6/0xb0
+ [<ffffffff817db154>] kernel_thread_helper+0x4/0x10
+ [<ffffffff81066430>] ? finish_task_switch+0x80/0x110
+ [<ffffffff817d9c04>] ? retint_restore_args+0xe/0xe
+ [<ffffffff81097510>] ? __init_kthread_worker+0x70/0x70
+ [<ffffffff817db150>] ? gs_change+0xb/0xb
+
+Line 2776 of block/cfq-iosched.c in v3.0-rc5 is as follows:
+
+       if (rcu_dereference(ioc->ioc_data) == cic) {
+
+This form says that it must be in a plain vanilla RCU read-side critical
+section, but the "other info" list above shows that this is not the
+case.  Instead, we hold three locks, one of which might be RCU related.
+And maybe that lock really does protect this reference.  If so, the fix
+is to inform RCU, perhaps by changing __cfq_exit_single_io_context() to
+take the struct request_queue "q" from cfq_exit_queue() as an argument,
+which would permit us to invoke rcu_dereference_protected as follows:
+
+       if (rcu_dereference_protected(ioc->ioc_data,
+                                     lockdep_is_held(&q->queue_lock)) == cic) {
+
+With this change, there would be no lockdep-RCU splat emitted if this
+code was invoked either from within an RCU read-side critical section
+or with the ->queue_lock held.  In particular, this would have suppressed
+the above lockdep-RCU splat because ->queue_lock is held (see #2 in the
+list above).
+
+On the other hand, perhaps we really do need an RCU read-side critical
+section.  In this case, the critical section must span the use of the
+return value from rcu_dereference(), or at least until there is some
+reference count incremented or some such.  One way to handle this is to
+add rcu_read_lock() and rcu_read_unlock() as follows:
+
+       rcu_read_lock();
+       if (rcu_dereference(ioc->ioc_data) == cic) {
+               spin_lock(&ioc->lock);
+               rcu_assign_pointer(ioc->ioc_data, NULL);
+               spin_unlock(&ioc->lock);
+       }
+       rcu_read_unlock();
+
+With this change, the rcu_dereference() is always within an RCU
+read-side critical section, which again would have suppressed the
+above lockdep-RCU splat.
+
+But in this particular case, we don't actually deference the pointer
+returned from rcu_dereference().  Instead, that pointer is just compared
+to the cic pointer, which means that the rcu_dereference() can be replaced
+by rcu_access_pointer() as follows:
+
+       if (rcu_access_pointer(ioc->ioc_data) == cic) {
+
+Because it is legal to invoke rcu_access_pointer() without protection,
+this change would also suppress the above lockdep-RCU splat.
index d7a49b2f6994c68ced38075000ccbc07803ba413..a102d4b3724bad454250d5d9e4ae883818725d91 100644 (file)
@@ -32,9 +32,27 @@ checking of rcu_dereference() primitives:
        srcu_dereference(p, sp):
                Check for SRCU read-side critical section.
        rcu_dereference_check(p, c):
-               Use explicit check expression "c".  This is useful in
-               code that is invoked by both readers and updaters.
-       rcu_dereference_raw(p)
+               Use explicit check expression "c" along with
+               rcu_read_lock_held().  This is useful in code that is
+               invoked by both RCU readers and updaters.
+       rcu_dereference_bh_check(p, c):
+               Use explicit check expression "c" along with
+               rcu_read_lock_bh_held().  This is useful in code that
+               is invoked by both RCU-bh readers and updaters.
+       rcu_dereference_sched_check(p, c):
+               Use explicit check expression "c" along with
+               rcu_read_lock_sched_held().  This is useful in code that
+               is invoked by both RCU-sched readers and updaters.
+       srcu_dereference_check(p, c):
+               Use explicit check expression "c" along with
+               srcu_read_lock_held()().  This is useful in code that
+               is invoked by both SRCU readers and updaters.
+       rcu_dereference_index_check(p, c):
+               Use explicit check expression "c", but the caller
+               must supply one of the rcu_read_lock_held() functions.
+               This is useful in code that uses RCU-protected arrays
+               that is invoked by both RCU readers and updaters.
+       rcu_dereference_raw(p):
                Don't check.  (Use sparingly, if at all.)
        rcu_dereference_protected(p, c):
                Use explicit check expression "c", and omit all barriers
@@ -48,13 +66,11 @@ checking of rcu_dereference() primitives:
                value of the pointer itself, for example, against NULL.
 
 The rcu_dereference_check() check expression can be any boolean
-expression, but would normally include one of the rcu_read_lock_held()
-family of functions and a lockdep expression.  However, any boolean
-expression can be used.  For a moderately ornate example, consider
-the following:
+expression, but would normally include a lockdep expression.  However,
+any boolean expression can be used.  For a moderately ornate example,
+consider the following:
 
        file = rcu_dereference_check(fdt->fd[fd],
-                                    rcu_read_lock_held() ||
                                     lockdep_is_held(&files->file_lock) ||
                                     atomic_read(&files->count) == 1);
 
@@ -62,7 +78,7 @@ This expression picks up the pointer "fdt->fd[fd]" in an RCU-safe manner,
 and, if CONFIG_PROVE_RCU is configured, verifies that this expression
 is used in:
 
-1.     An RCU read-side critical section, or
+1.     An RCU read-side critical section (implicit), or
 2.     with files->file_lock held, or
 3.     on an unshared files_struct.
 
index 5d9016795fd825a43f2a4093e4edd870cb92e42c..783d6c134d3f007c220ca6a24203b1a16ea136c2 100644 (file)
@@ -42,7 +42,7 @@ fqs_holdoff   Holdoff time (in microseconds) between consecutive calls
 fqs_stutter    Wait time (in seconds) between consecutive bursts
                of calls to force_quiescent_state().
 
-irqreaders     Says to invoke RCU readers from irq level.  This is currently
+irqreader      Says to invoke RCU readers from irq level.  This is currently
                done via timers.  Defaults to "1" for variants of RCU that
                permit this.  (Or, more accurately, variants of RCU that do
                -not- permit this know to ignore this variable.)
@@ -79,19 +79,68 @@ stutter             The length of time to run the test before pausing for this
                Specifying "stutter=0" causes the test to run continuously
                without pausing, which is the old default behavior.
 
+test_boost     Whether or not to test the ability of RCU to do priority
+               boosting.  Defaults to "test_boost=1", which performs
+               RCU priority-inversion testing only if the selected
+               RCU implementation supports priority boosting.  Specifying
+               "test_boost=0" never performs RCU priority-inversion
+               testing.  Specifying "test_boost=2" performs RCU
+               priority-inversion testing even if the selected RCU
+               implementation does not support RCU priority boosting,
+               which can be used to test rcutorture's ability to
+               carry out RCU priority-inversion testing.
+
+test_boost_interval
+               The number of seconds in an RCU priority-inversion test
+               cycle.  Defaults to "test_boost_interval=7".  It is
+               usually wise for this value to be relatively prime to
+               the value selected for "stutter".
+
+test_boost_duration
+               The number of seconds to do RCU priority-inversion testing
+               within any given "test_boost_interval".  Defaults to
+               "test_boost_duration=4".
+
 test_no_idle_hz        Whether or not to test the ability of RCU to operate in
                a kernel that disables the scheduling-clock interrupt to
                idle CPUs.  Boolean parameter, "1" to test, "0" otherwise.
                Defaults to omitting this test.
 
-torture_type   The type of RCU to test: "rcu" for the rcu_read_lock() API,
-               "rcu_sync" for rcu_read_lock() with synchronous reclamation,
-               "rcu_bh" for the rcu_read_lock_bh() API, "rcu_bh_sync" for
-               rcu_read_lock_bh() with synchronous reclamation, "srcu" for
-               the "srcu_read_lock()" API, "sched" for the use of
-               preempt_disable() together with synchronize_sched(),
-               and "sched_expedited" for the use of preempt_disable()
-               with synchronize_sched_expedited().
+torture_type   The type of RCU to test, with string values as follows:
+
+               "rcu":  rcu_read_lock(), rcu_read_unlock() and call_rcu().
+
+               "rcu_sync":  rcu_read_lock(), rcu_read_unlock(), and
+                       synchronize_rcu().
+
+               "rcu_expedited": rcu_read_lock(), rcu_read_unlock(), and
+                       synchronize_rcu_expedited().
+
+               "rcu_bh": rcu_read_lock_bh(), rcu_read_unlock_bh(), and
+                       call_rcu_bh().
+
+               "rcu_bh_sync": rcu_read_lock_bh(), rcu_read_unlock_bh(),
+                       and synchronize_rcu_bh().
+
+               "rcu_bh_expedited": rcu_read_lock_bh(), rcu_read_unlock_bh(),
+                       and synchronize_rcu_bh_expedited().
+
+               "srcu": srcu_read_lock(), srcu_read_unlock() and
+                       synchronize_srcu().
+
+               "srcu_expedited": srcu_read_lock(), srcu_read_unlock() and
+                       synchronize_srcu_expedited().
+
+               "sched": preempt_disable(), preempt_enable(), and
+                       call_rcu_sched().
+
+               "sched_sync": preempt_disable(), preempt_enable(), and
+                       synchronize_sched().
+
+               "sched_expedited": preempt_disable(), preempt_enable(), and
+                       synchronize_sched_expedited().
+
+               Defaults to "rcu".
 
 verbose                Enable debug printk()s.  Default is disabled.
 
@@ -100,12 +149,12 @@ OUTPUT
 
 The statistics output is as follows:
 
-       rcu-torture: --- Start of test: nreaders=16 stat_interval=0 verbose=0
-       rcu-torture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915
-       rcu-torture: Reader Pipe:  1466408 9747 0 0 0 0 0 0 0 0 0
-       rcu-torture: Reader Batch:  1464477 11678 0 0 0 0 0 0 0 0
-       rcu-torture: Free-Block Circulation:  1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0
-       rcu-torture: --- End of test
+       rcu-torture:--- Start of test: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4
+       rcu-torture: rtc:           (null) ver: 155441 tfle: 0 rta: 155441 rtaf: 8884 rtf: 155440 rtmbe: 0 rtbke: 0 rtbre: 0 rtbf: 0 rtb: 0 nt: 3055767
+       rcu-torture: Reader Pipe:  727860534 34213 0 0 0 0 0 0 0 0 0
+       rcu-torture: Reader Batch:  727877838 17003 0 0 0 0 0 0 0 0 0
+       rcu-torture: Free-Block Circulation:  155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0
+       rcu-torture:--- End of test: SUCCESS: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4
 
 The command "dmesg | grep torture:" will extract this information on
 most systems.  On more esoteric configurations, it may be necessary to
@@ -113,26 +162,55 @@ use other commands to access the output of the printk()s used by
 the RCU torture test.  The printk()s use KERN_ALERT, so they should
 be evident.  ;-)
 
+The first and last lines show the rcutorture module parameters, and the
+last line shows either "SUCCESS" or "FAILURE", based on rcutorture's
+automatic determination as to whether RCU operated correctly.
+
 The entries are as follows:
 
 o      "rtc": The hexadecimal address of the structure currently visible
        to readers.
 
-o      "ver": The number of times since boot that the rcutw writer task
+o      "ver": The number of times since boot that the RCU writer task
        has changed the structure visible to readers.
 
 o      "tfle": If non-zero, indicates that the "torture freelist"
-       containing structure to be placed into the "rtc" area is empty.
+       containing structures to be placed into the "rtc" area is empty.
        This condition is important, since it can fool you into thinking
        that RCU is working when it is not.  :-/
 
 o      "rta": Number of structures allocated from the torture freelist.
 
 o      "rtaf": Number of allocations from the torture freelist that have
-       failed due to the list being empty.
+       failed due to the list being empty.  It is not unusual for this
+       to be non-zero, but it is bad for it to be a large fraction of
+       the value indicated by "rta".
 
 o      "rtf": Number of frees into the torture freelist.
 
+o      "rtmbe": A non-zero value indicates that rcutorture believes that
+       rcu_assign_pointer() and rcu_dereference() are not working
+       correctly.  This value should be zero.
+
+o      "rtbke": rcutorture was unable to create the real-time kthreads
+       used to force RCU priority inversion.  This value should be zero.
+
+o      "rtbre": Although rcutorture successfully created the kthreads
+       used to force RCU priority inversion, it was unable to set them
+       to the real-time priority level of 1.  This value should be zero.
+
+o      "rtbf": The number of times that RCU priority boosting failed
+       to resolve RCU priority inversion.
+
+o      "rtb": The number of times that rcutorture attempted to force
+       an RCU priority inversion condition.  If you are testing RCU
+       priority boosting via the "test_boost" module parameter, this
+       value should be non-zero.
+
+o      "nt": The number of times rcutorture ran RCU read-side code from
+       within a timer handler.  This value should be non-zero only
+       if you specified the "irqreader" module parameter.
+
 o      "Reader Pipe": Histogram of "ages" of structures seen by readers.
        If any entries past the first two are non-zero, RCU is broken.
        And rcutorture prints the error flag string "!!!" to make sure
@@ -162,26 +240,15 @@ o "Free-Block Circulation": Shows the number of torture structures
        somehow gets incremented farther than it should.
 
 Different implementations of RCU can provide implementation-specific
-additional information.  For example, SRCU provides the following:
+additional information.  For example, SRCU provides the following
+additional line:
 
-       srcu-torture: rtc: f8cf46a8 ver: 355 tfle: 0 rta: 356 rtaf: 0 rtf: 346 rtmbe: 0
-       srcu-torture: Reader Pipe:  559738 939 0 0 0 0 0 0 0 0 0
-       srcu-torture: Reader Batch:  560434 243 0 0 0 0 0 0 0 0
-       srcu-torture: Free-Block Circulation:  355 354 353 352 351 350 349 348 347 346 0
        srcu-torture: per-CPU(idx=1): 0(0,1) 1(0,1) 2(0,0) 3(0,1)
 
-The first four lines are similar to those for RCU.  The last line shows
-the per-CPU counter state.  The numbers in parentheses are the values
-of the "old" and "current" counters for the corresponding CPU.  The
-"idx" value maps the "old" and "current" values to the underlying array,
-and is useful for debugging.
-
-Similarly, sched_expedited RCU provides the following:
-
-       sched_expedited-torture: rtc: d0000000016c1880 ver: 1090796 tfle: 0 rta: 1090796 rtaf: 0 rtf: 1090787 rtmbe: 0 nt: 27713319
-       sched_expedited-torture: Reader Pipe:  12660320201 95875 0 0 0 0 0 0 0 0 0
-       sched_expedited-torture: Reader Batch:  12660424885 0 0 0 0 0 0 0 0 0 0
-       sched_expedited-torture: Free-Block Circulation:  1090795 1090795 1090794 1090793 1090792 1090791 1090790 1090789 1090788 1090787 0
+This line shows the per-CPU counter state.  The numbers in parentheses are
+the values of the "old" and "current" counters for the corresponding CPU.
+The "idx" value maps the "old" and "current" values to the underlying
+array, and is useful for debugging.
 
 
 USAGE
index 8173cec473aa0099a185d694bad1b1b6ee48743d..aaf65f6c6cd7845e7cf671366671b713bcd8fe16 100644 (file)
@@ -33,23 +33,23 @@ rcu/rcuboost:
 The output of "cat rcu/rcudata" looks as follows:
 
 rcu_sched:
-  0 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=545/1/0 df=50 of=0 ri=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0
-  1 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=967/1/0 df=58 of=0 ri=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0
-  2 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=1081/1/0 df=175 of=0 ri=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0
-  3 c=20942 g=20943 pq=1 pqc=20942 qp=1 dt=1846/0/0 df=404 of=0 ri=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0
-  4 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=369/1/0 df=83 of=0 ri=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0
-  5 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=381/1/0 df=64 of=0 ri=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0
-  6 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=1037/1/0 df=183 of=0 ri=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0
-  7 c=20897 g=20897 pq=1 pqc=20896 qp=0 dt=1572/0/0 df=382 of=0 ri=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0
+  0 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=545/1/0 df=50 of=0 ri=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0
+  1 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=967/1/0 df=58 of=0 ri=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0
+  2 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1081/1/0 df=175 of=0 ri=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0
+  3 c=20942 g=20943 pq=1 pgp=20942 qp=1 dt=1846/0/0 df=404 of=0 ri=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0
+  4 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=369/1/0 df=83 of=0 ri=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0
+  5 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=381/1/0 df=64 of=0 ri=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0
+  6 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1037/1/0 df=183 of=0 ri=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0
+  7 c=20897 g=20897 pq=1 pgp=20896 qp=0 dt=1572/0/0 df=382 of=0 ri=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0
 rcu_bh:
-  0 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=545/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0
-  1 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=967/1/0 df=3 of=0 ri=1 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0
-  2 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1081/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0
-  3 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1846/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0
-  4 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=369/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0
-  5 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=381/1/0 df=4 of=0 ri=1 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0
-  6 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1037/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0
-  7 c=1474 g=1474 pq=1 pqc=1473 qp=0 dt=1572/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0
+  0 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=545/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0
+  1 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=967/1/0 df=3 of=0 ri=1 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0
+  2 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1081/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0
+  3 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1846/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0
+  4 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=369/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0
+  5 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=381/1/0 df=4 of=0 ri=1 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0
+  6 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1037/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0
+  7 c=1474 g=1474 pq=1 pgp=1473 qp=0 dt=1572/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0
 
 The first section lists the rcu_data structures for rcu_sched, the second
 for rcu_bh.  Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
@@ -84,7 +84,7 @@ o     "pq" indicates that this CPU has passed through a quiescent state
        CPU has not yet reported that fact, (2) some other CPU has not
        yet reported for this grace period, or (3) both.
 
-o      "pqc" indicates which grace period the last-observed quiescent
+o      "pgp" indicates which grace period the last-observed quiescent
        state for this CPU corresponds to.  This is important for handling
        the race between CPU 0 reporting an extended dynticks-idle
        quiescent state for CPU 1 and CPU 1 suddenly waking up and
@@ -184,10 +184,14 @@ o "kt" is the per-CPU kernel-thread state.  The digit preceding
        The number after the final slash is the CPU that the kthread
        is actually running on.
 
+       This field is displayed only for CONFIG_RCU_BOOST kernels.
+
 o      "ktl" is the low-order 16 bits (in hexadecimal) of the count of
        the number of times that this CPU's per-CPU kthread has gone
        through its loop servicing invoke_rcu_cpu_kthread() requests.
 
+       This field is displayed only for CONFIG_RCU_BOOST kernels.
+
 o      "b" is the batch limit for this CPU.  If more than this number
        of RCU callbacks is ready to invoke, then the remainder will
        be deferred.
index c00c6a5ab21f6b0d253bf465eb6e1274d5994d18..71464e09ec1841a39f031d972b281488e5d703af 100644 (file)
@@ -78,6 +78,16 @@ The device naming scheme is:
 /dev/cciss/c1d1p2              Controller 1, disk 1, partition 2
 /dev/cciss/c1d1p3              Controller 1, disk 1, partition 3
 
+CCISS simple mode support
+-------------------------
+
+The "cciss_simple_mode=1" boot parameter may be used to prevent the driver
+from putting the controller into "performant" mode. The difference is that
+with simple mode, each command completion requires an interrupt, while with
+"performant mode" (the default, and ordinarily better performing) it is
+possible to have multiple command completions indicated by a single
+interrupt.
+
 SCSI tape drive and medium changer support
 ------------------------------------------
 
index cd67e90003c0e547952de41086f01d59ecb9a493..9c452ef2328c73b606b40e01820624a3aa4c13a6 100644 (file)
@@ -454,8 +454,8 @@ mounted hierarchy, to remove a task from its current cgroup you must
 move it into a new cgroup (possibly the root cgroup) by writing to the
 new cgroup's tasks file.
 
-Note: If the ns cgroup is active, moving a process to another cgroup can
-fail.
+Note: Due to some restrictions enforced by some cgroup subsystems, moving
+a process to another cgroup can fail.
 
 2.3 Mounting hierarchies by name
 --------------------------------
index e74d0a2eb1cf4d9921b0720039c6696e42fc3062..d221781dabaa84f49977d985fe617f74dfdb090a 100644 (file)
@@ -132,7 +132,7 @@ The sampling rate is limited by the HW transition latency:
 transition_latency * 100
 Or by kernel restrictions:
 If CONFIG_NO_HZ is set, the limit is 10ms fixed.
-If CONFIG_NO_HZ is not set or no_hz=off boot parameter is used, the
+If CONFIG_NO_HZ is not set or nohz=off boot parameter is used, the
 limits depend on the CONFIG_HZ option:
 HZ=1000: min=20000us  (20ms)
 HZ=250:  min=80000us  (80ms)
index d9b086869a6054d9687ec51070cfceb51fab6a50..8dbdb1a44429aedc90e770dfba266f8f57e97ce9 100644 (file)
@@ -1,38 +1,34 @@
-Linux 2.4 on the CRIS architecture
-==================================
-$Id: README,v 1.7 2001/04/19 12:38:32 bjornw Exp $
+Linux on the CRIS architecture
+==============================
 
-This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded 
-network CPU. For more information about CRIS and ETRAX please see further
-below.
+This is a port of Linux to Axis Communications ETRAX 100LX,
+ETRAX FS and ARTPEC-3 embedded network CPUs.
+
+For more information about CRIS and ETRAX please see further below.
 
 In order to compile this you need a version of gcc with support for the
-ETRAX chip family. Please see this link for more information on how to 
+ETRAX chip family. Please see this link for more information on how to
 download the compiler and other tools useful when building and booting
 software for the ETRAX platform:
 
-http://developer.axis.com/doc/software/devboard_lx/install-howto.html
-
-<more specific information should come in this document later>
+http://developer.axis.com/wiki/doku.php?id=axis:install-howto-2_20
 
 What is CRIS ?
 --------------
 
 CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU
 architecture in Axis Communication AB's range of embedded network CPU's,
-called ETRAX. The latest CPU is called ETRAX 100LX, where LX stands for
-'Linux' because the chip was designed to be a good host for the Linux
-operating system.
+called ETRAX.
 
 The ETRAX 100LX chip
 --------------------
 
-For reference, please see the press-release:
+For reference, please see the following link:
 
-http://www.axis.com/news/us/001101_etrax.htm
+http://www.axis.com/products/dev_etrax_100lx/index.htm
 
-The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad 
-range of  built-in interfaces, all with modern scatter/gather DMA.
+The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad
+range of built-in interfaces, all with modern scatter/gather DMA.
 
 Memory interfaces:
 
@@ -51,20 +47,28 @@ I/O interfaces:
        * SCSI
        * two parallel-ports
        * two generic 8-bit ports
-       
-       (not all interfaces are available at the same time due to chip pin 
+
+       (not all interfaces are available at the same time due to chip pin
          multiplexing)
 
-The previous version of the ETRAX, the ETRAX 100, sits in almost all of
-Axis shipping thin-servers like the Axis 2100 web camera or the ETRAX 100
-developer-board. It lacks an MMU so the Linux we run on that is a version
-of uClinux (Linux 2.0 without MM-support) ported to the CRIS architecture.
-The new Linux 2.4 port has full MM and needs a CPU with an MMU, so it will
-not run on the ETRAX 100.
+ETRAX 100LX is CRISv10 architecture.
+
+
+The ETRAX FS and ARTPEC-3 chips
+-------------------------------
 
-A version of the Axis developer-board with ETRAX 100LX (running Linux
-2.4) is now available. For more information please see developer.axis.com.
+The ETRAX FS is a 200MHz 32-bit RISC processor with on-chip 16kB
+I-cache and 16kB D-cache and with a wide range of device interfaces
+including multiple high speed serial ports and an integrated USB 1.1 PHY.
 
+The ARTPEC-3 is a variant of the ETRAX FS with additional IO-units
+used by the Axis Communications network cameras.
+
+See below link for more information:
+
+http://www.axis.com/products/dev_etrax_fs/index.htm
+
+ETRAX FS and ARTPEC-3 are both CRISv32 architectures.
 
 Bootlog
 -------
@@ -182,10 +186,6 @@ SwapFree:            0 kB
 -rwxr-xr-x  1 342      100         16252  Jan 01 00:00 telnetd
 
 
-(All programs are statically linked to the libc at this point - we have not ported the
- shared libraries yet)
-
-
 
 
 
diff --git a/Documentation/device-mapper/persistent-data.txt b/Documentation/device-mapper/persistent-data.txt
new file mode 100644 (file)
index 0000000..0e5df9b
--- /dev/null
@@ -0,0 +1,84 @@
+Introduction
+============
+
+The more-sophisticated device-mapper targets require complex metadata
+that is managed in kernel.  In late 2010 we were seeing that various
+different targets were rolling their own data strutures, for example:
+
+- Mikulas Patocka's multisnap implementation
+- Heinz Mauelshagen's thin provisioning target
+- Another btree-based caching target posted to dm-devel
+- Another multi-snapshot target based on a design of Daniel Phillips
+
+Maintaining these data structures takes a lot of work, so if possible
+we'd like to reduce the number.
+
+The persistent-data library is an attempt to provide a re-usable
+framework for people who want to store metadata in device-mapper
+targets.  It's currently used by the thin-provisioning target and an
+upcoming hierarchical storage target.
+
+Overview
+========
+
+The main documentation is in the header files which can all be found
+under drivers/md/persistent-data.
+
+The block manager
+-----------------
+
+dm-block-manager.[hc]
+
+This provides access to the data on disk in fixed sized-blocks.  There
+is a read/write locking interface to prevent concurrent accesses, and
+keep data that is being used in the cache.
+
+Clients of persistent-data are unlikely to use this directly.
+
+The transaction manager
+-----------------------
+
+dm-transaction-manager.[hc]
+
+This restricts access to blocks and enforces copy-on-write semantics.
+The only way you can get hold of a writable block through the
+transaction manager is by shadowing an existing block (ie. doing
+copy-on-write) or allocating a fresh one.  Shadowing is elided within
+the same transaction so performance is reasonable.  The commit method
+ensures that all data is flushed before it writes the superblock.
+On power failure your metadata will be as it was when last committed.
+
+The Space Maps
+--------------
+
+dm-space-map.h
+dm-space-map-metadata.[hc]
+dm-space-map-disk.[hc]
+
+On-disk data structures that keep track of reference counts of blocks.
+Also acts as the allocator of new blocks.  Currently two
+implementations: a simpler one for managing blocks on a different
+device (eg. thinly-provisioned data blocks); and one for managing
+the metadata space.  The latter is complicated by the need to store
+its own data within the space it's managing.
+
+The data structures
+-------------------
+
+dm-btree.[hc]
+dm-btree-remove.c
+dm-btree-spine.c
+dm-btree-internal.h
+
+Currently there is only one data structure, a hierarchical btree.
+There are plans to add more.  For example, something with an
+array-like interface would see a lot of use.
+
+The btree is 'hierarchical' in that you can define it to be composed
+of nested btrees, and take multiple keys.  For example, the
+thin-provisioning target uses a btree with two levels of nesting.
+The first maps a device id to a mapping tree, and that in turn maps a
+virtual block to a physical block.
+
+Values stored in the btrees can have arbitrary size.  Keys are always
+64bits, although nesting allows you to use multiple keys.
diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt
new file mode 100644 (file)
index 0000000..5ced8fe
--- /dev/null
@@ -0,0 +1,275 @@
+Introduction
+============
+
+This document descibes a collection of device-mapper targets that
+between them implement thin-provisioning and snapshots.
+
+The main highlight of this implementation, compared to the previous
+implementation of snapshots, is that it allows many virtual devices to
+be stored on the same data volume.  This simplifies administration and
+allows the sharing of data between volumes, thus reducing disk usage.
+
+Another significant feature is support for an arbitrary depth of
+recursive snapshots (snapshots of snapshots of snapshots ...).  The
+previous implementation of snapshots did this by chaining together
+lookup tables, and so performance was O(depth).  This new
+implementation uses a single data structure to avoid this degradation
+with depth.  Fragmentation may still be an issue, however, in some
+scenarios.
+
+Metadata is stored on a separate device from data, giving the
+administrator some freedom, for example to:
+
+- Improve metadata resilience by storing metadata on a mirrored volume
+  but data on a non-mirrored one.
+
+- Improve performance by storing the metadata on SSD.
+
+Status
+======
+
+These targets are very much still in the EXPERIMENTAL state.  Please
+do not yet rely on them in production.  But do experiment and offer us
+feedback.  Different use cases will have different performance
+characteristics, for example due to fragmentation of the data volume.
+
+If you find this software is not performing as expected please mail
+dm-devel@redhat.com with details and we'll try our best to improve
+things for you.
+
+Userspace tools for checking and repairing the metadata are under
+development.
+
+Cookbook
+========
+
+This section describes some quick recipes for using thin provisioning.
+They use the dmsetup program to control the device-mapper driver
+directly.  End users will be advised to use a higher-level volume
+manager such as LVM2 once support has been added.
+
+Pool device
+-----------
+
+The pool device ties together the metadata volume and the data volume.
+It maps I/O linearly to the data volume and updates the metadata via
+two mechanisms:
+
+- Function calls from the thin targets
+
+- Device-mapper 'messages' from userspace which control the creation of new
+  virtual devices amongst other things.
+
+Setting up a fresh pool device
+------------------------------
+
+Setting up a pool device requires a valid metadata device, and a
+data device.  If you do not have an existing metadata device you can
+make one by zeroing the first 4k to indicate empty metadata.
+
+    dd if=/dev/zero of=$metadata_dev bs=4096 count=1
+
+FIXME How big must $metadata_dev be?
+
+Reloading a pool table
+----------------------
+
+You may reload a pool's table, indeed this is how the pool is resized
+if it runs out of space.  (N.B. While specifying a different metadata
+device when reloading is not forbidden at the moment, things will go
+wrong if it does not route I/O to exactly the same on-disk location as
+previously.)
+
+Using an existing pool device
+-----------------------------
+
+    dmsetup create pool \
+       --table "0 20971520 thin-pool $metadata_dev $data_dev \
+                $data_block_size $low_water_mark"
+
+$data_block_size gives the smallest unit of disk space that can be
+allocated at a time.  As with all sizes passed to device-mapper, this
+is expressed in units of 512-byte sectors.  People primarily
+interested in thin provisioning may want to use a value such as 1024.
+People doing lots of snapshotting may want a smaller value such as
+128.  $data_block_size must be the same for the lifetime of the
+metadata device.
+
+$low_water_mark is expressed in 512-byte sectors.  If free space on
+the data device drops below this level then a dm event will be
+triggered which a userspace daemon should catch allowing it to
+extend the pool device.  Only one such event will be sent.
+
+FIXME - Do we get a second event after a table reload when you're
+already over the threshold?
+
+Thin provisioning
+-----------------
+
+i) Creating a new thinly-provisioned volume.
+
+  To create a new thinly- provisioned volume you must send a message to an
+  active pool device, /dev/mapper/pool in this example.
+
+    dmsetup message /dev/mapper/pool 0 "create_thin 0"
+
+  Here '0' is an identifier for the volume, a 24-bit number.  It's up
+  to the caller to allocate and manage these identifiers.  If the
+  identifier is already in use, the message will fail.
+FIXME With what error?
+
+ii) Using a thinly-provisioned volume.
+
+  Thinly-provisioned volumes are activated using the 'thin' target:
+
+    dmsetup create thin --table "0 2097152 thin /dev/mapper/pool 0"
+
+  The last parameter is the identifier for the thinp device.
+
+Internal snapshots
+------------------
+
+i) Creating an internal snapshot.
+
+  Snapshots are created with another message to the pool.
+
+  If the origin device that you wish to snapshot is active, you must
+  suspend it before creating the snapshot.
+FIXME What happens if you don't?
+
+    dmsetup suspend /dev/mapper/thin
+    dmsetup message /dev/mapper/pool 0 "create_snap 1 0"
+    dmsetup resume /dev/mapper/thin
+
+  Here '1' is the identifier for the volume, a 24-bit number.  '0' is the
+  identifier for the origin device.
+
+ii) Using an internal snapshot.
+
+  Once created, the user doesn't have to worry about any connection
+  between the origin and the snapshot.  Indeed the snapshot is no
+  different from any other thinly-provisioned device and can be
+  snapshotted itself via the same method.  It's perfectly legal to
+  have only one of them active, and there's no ordering requirement on
+  activating or removing them both.  (This differs from conventional
+  device-mapper snapshots.)
+
+  Activate it exactly the same way as any other thinly-provisioned volume:
+
+    dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 1"
+
+Deactivation
+------------
+
+All devices using a pool must be deactivated before the pool itself
+can be.
+
+    dmsetup remove thin
+    dmsetup remove snap
+    dmsetup remove pool
+
+Reference
+=========
+
+'thin-pool' target
+------------------
+
+i) Constructor
+
+    thin-pool <metadata dev> <data dev> <data block size (sectors)> \
+             <low water mark (sectors)> [<number of feature args> [<arg>]*]
+
+    Optional feature arguments:
+    - 'skip_block_zeroing': skips the zeroing of newly-provisioned blocks.
+
+    Data block size must be between 64KB (128 sectors) and 1GB
+    (2097152 sectors) inclusive.
+
+ii) Status
+
+    <transaction id> <used metadata sectors>/<total metadata sectors>
+    <used data sectors>/<total data sectors> <held metadata root>
+
+
+    transaction id:
+       A 64-bit number used by userspace to help synchronise with metadata
+       from volume managers.
+
+    used data sectors / total data sectors
+       If the number of free sectors drops below the pool's low water mark a
+       dm event will be sent to userspace.  This event is edge-triggered and
+       it will occur only once after each resume so volume manager writers
+       should register for the event and then check the target's status.
+
+    held metadata root:
+       The location, in sectors, of the metadata root that has been
+       'held' for userspace read access.  '-' indicates there is no
+       held root.  This feature is not yet implemented so '-' is
+       always returned.
+
+iii) Messages
+
+    create_thin <dev id>
+
+       Create a new thinly-provisioned device.
+       <dev id> is an arbitrary unique 24-bit identifier chosen by
+       the caller.
+
+    create_snap <dev id> <origin id>
+
+       Create a new snapshot of another thinly-provisioned device.
+       <dev id> is an arbitrary unique 24-bit identifier chosen by
+       the caller.
+       <origin id> is the identifier of the thinly-provisioned device
+       of which the new device will be a snapshot.
+
+    delete <dev id>
+
+       Deletes a thin device.  Irreversible.
+
+    trim <dev id> <new size in sectors>
+
+       Delete mappings from the end of a thin device.  Irreversible.
+       You might want to use this if you're reducing the size of
+       your thinly-provisioned device.  In many cases, due to the
+       sharing of blocks between devices, it is not possible to
+       determine in advance how much space 'trim' will release.  (In
+       future a userspace tool might be able to perform this
+       calculation.)
+
+    set_transaction_id <current id> <new id>
+
+       Userland volume managers, such as LVM, need a way to
+       synchronise their external metadata with the internal metadata of the
+       pool target.  The thin-pool target offers to store an
+       arbitrary 64-bit transaction id and return it on the target's
+       status line.  To avoid races you must provide what you think
+       the current transaction id is when you change it with this
+       compare-and-swap message.
+
+'thin' target
+-------------
+
+i) Constructor
+
+    thin <pool dev> <dev id>
+
+    pool dev:
+       the thin-pool device, e.g. /dev/mapper/my_pool or 253:0
+
+    dev id:
+       the internal device identifier of the device to be
+       activated.
+
+The pool doesn't store any size against the thin devices.  If you
+load a thin target that is smaller than you've been using previously,
+then you'll have no access to blocks mapped beyond the end.  If you
+load a target that is bigger than before, then extra blocks will be
+provisioned as and when needed.
+
+If you wish to reduce the size of your thin device and potentially
+regain some space then send the 'trim' message to the pool.
+
+ii) Status
+
+     <nr mapped sectors> <highest mapped sector>
diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt
new file mode 100644 (file)
index 0000000..f50e021
--- /dev/null
@@ -0,0 +1,42 @@
+* ARM L2 Cache Controller
+
+ARM cores often have a separate level 2 cache controller. There are various
+implementations of the L2 cache controller with compatible programming models.
+The ARM L2 cache representation in the device tree should be done as follows:
+
+Required properties:
+
+- compatible : should be one of:
+       "arm,pl310-cache"
+       "arm,l220-cache"
+       "arm,l210-cache"
+- cache-unified : Specifies the cache is a unified cache.
+- cache-level : Should be set to 2 for a level 2 cache.
+- reg : Physical base address and size of cache controller's memory mapped
+  registers.
+
+Optional properties:
+
+- arm,data-latency : Cycles of latency for Data RAM accesses. Specifies 3 cells of
+  read, write and setup latencies. Minimum valid values are 1. Controllers
+  without setup latency control should use a value of 0.
+- arm,tag-latency : Cycles of latency for Tag RAM accesses. Specifies 3 cells of
+  read, write and setup latencies. Controllers without setup latency control
+  should use 0. Controllers without separate read and write Tag RAM latency
+  values should only use the first cell.
+- arm,dirty-latency : Cycles of latency for Dirty RAMs. This is a single cell.
+- arm,filter-ranges : <start length> Starting address and length of window to
+  filter. Addresses in the filter window are directed to the M1 port. Other
+  addresses will go to the M0 port.
+
+Example:
+
+L2: cache-controller {
+        compatible = "arm,pl310-cache";
+        reg = <0xfff12000 0x1000>;
+        arm,data-latency = <1 1 1>;
+        arm,tag-latency = <2 2 2>;
+        arm,filter-latency = <0x80000000 0x8000000>;
+        cache-unified;
+        cache-level = <2>;
+};
diff --git a/Documentation/devicetree/bindings/crypto/picochip-spacc.txt b/Documentation/devicetree/bindings/crypto/picochip-spacc.txt
new file mode 100644 (file)
index 0000000..d8609ec
--- /dev/null
@@ -0,0 +1,23 @@
+Picochip picoXcell SPAcc (Security Protocol Accelerator) bindings
+
+Picochip picoXcell devices contain crypto offload engines that may be used for
+IPSEC and femtocell layer 2 ciphering.
+
+Required properties:
+  - compatible : "picochip,spacc-ipsec" for the IPSEC offload engine
+    "picochip,spacc-l2" for the femtocell layer 2 ciphering engine.
+  - reg : Offset and length of the register set for this device
+  - interrupt-parent : The interrupt controller that controls the SPAcc
+    interrupt.
+  - interrupts : The interrupt line from the SPAcc.
+  - ref-clock : The input clock that drives the SPAcc.
+
+Example SPAcc node:
+
+spacc@10000 {
+       compatible = "picochip,spacc-ipsec";
+       reg = <0x100000 0x10000>;
+       interrupt-parent = <&vic0>;
+       interrupts = <24>;
+       ref-clock = <&ipsec_clk>, "ref";
+};
diff --git a/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt
new file mode 100644 (file)
index 0000000..c87f667
--- /dev/null
@@ -0,0 +1,25 @@
+* NVIDIA Tegra Secure Digital Host Controller
+
+This controller on Tegra family SoCs provides an interface for MMC, SD,
+and SDIO types of memory cards.
+
+Required properties:
+- compatible : Should be "nvidia,<chip>-sdhci"
+- reg : Should contain eSDHC registers location and length
+- interrupts : Should contain eSDHC interrupt
+
+Optional properties:
+- cd-gpios : Specify GPIOs for card detection
+- wp-gpios : Specify GPIOs for write protection
+- power-gpios : Specify GPIOs for power control
+
+Example:
+
+sdhci@c8000200 {
+       compatible = "nvidia,tegra20-sdhci";
+       reg = <0xc8000200 0x200>;
+       interrupts = <47>;
+       cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+       wp-gpios = <&gpio 57 0>; /* gpio PH1 */
+       power-gpios = <&gpio 155 0>; /* gpio PT3 */
+};
diff --git a/Documentation/devicetree/bindings/mtd/atmel-dataflash.txt b/Documentation/devicetree/bindings/mtd/atmel-dataflash.txt
new file mode 100644 (file)
index 0000000..ef66ddd
--- /dev/null
@@ -0,0 +1,14 @@
+* Atmel Data Flash
+
+Required properties:
+- compatible : "atmel,<model>", "atmel,<series>", "atmel,dataflash".
+
+Example:
+
+flash@1 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
+       spi-max-frequency = <25000000>;
+       reg = <1>;
+};
index 1a729f089866259ef82d0db5893ff7a8c54d5ccf..1ad80d5865a9848c10869814b0cc32118d093fc9 100644 (file)
@@ -1,61 +1,24 @@
-CAN Device Tree Bindings
-------------------------
-2011 Freescale Semiconductor, Inc.
+Flexcan CAN contoller on Freescale's ARM and PowerPC system-on-a-chip (SOC).
 
-fsl,flexcan-v1.0 nodes
------------------------
-In addition to the required compatible-, reg- and interrupt-properties, you can
-also specify which clock source shall be used for the controller.
+Required properties:
 
-CPI Clock- Can Protocol Interface Clock
-       This CLK_SRC bit of CTRL(control register) selects the clock source to
-       the CAN Protocol Interface(CPI) to be either the peripheral clock
-       (driven by the PLL) or the crystal oscillator clock. The selected clock
-       is the one fed to the prescaler to generate the Serial Clock (Sclock).
-       The PRESDIV field of CTRL(control register) controls a prescaler that
-       generates the Serial Clock (Sclock), whose period defines the
-       time quantum used to compose the CAN waveform.
+- compatible : Should be "fsl,<processor>-flexcan"
 
-Can Engine Clock Source
-       There are two sources for CAN clock
-       - Platform Clock  It represents the bus clock
-       - Oscillator Clock
+  An implementation should also claim any of the following compatibles
+  that it is fully backwards compatible with:
 
-       Peripheral Clock (PLL)
-       --------------
-                    |
-                   ---------                 -------------
-                   |       |CPI Clock        | Prescaler |       Sclock
-                   |       |---------------->| (1.. 256) |------------>
-                   ---------                 -------------
-                     |  |
-       --------------  ---------------------CLK_SRC
-       Oscillator Clock
+  - fsl,p1010-flexcan
 
-- fsl,flexcan-clock-source : CAN Engine Clock Source.This property selects
-                            the peripheral clock. PLL clock is fed to the
-                            prescaler to generate the Serial Clock (Sclock).
-                            Valid values are "oscillator" and "platform"
-                            "oscillator": CAN engine clock source is oscillator clock.
-                            "platform" The CAN engine clock source is the bus clock
-                            (platform clock).
+- reg : Offset and length of the register set for this device
+- interrupts : Interrupt tuple for this device
+- clock-frequency : The oscillator frequency driving the flexcan device
 
-- fsl,flexcan-clock-divider : for the reference and system clock, an additional
-                             clock divider can be specified.
-- clock-frequency: frequency required to calculate the bitrate for FlexCAN.
+Example:
 
-Note:
-       - v1.0 of flexcan-v1.0 represent the IP block version for P1010 SOC.
-       - P1010 does not have oscillator as the Clock Source.So the default
-         Clock Source is platform clock.
-Examples:
-
-       can0@1c000 {
-               compatible = "fsl,flexcan-v1.0";
+       can@1c000 {
+               compatible = "fsl,p1010-flexcan";
                reg = <0x1c000 0x1000>;
                interrupts = <48 0x2>;
                interrupt-parent = <&mpic>;
-               fsl,flexcan-clock-source = "platform";
-               fsl,flexcan-clock-divider = <2>;
-               clock-frequency = <fixed by u-boot>;
+               clock-frequency = <200000000>; // filled in by bootloader
        };
diff --git a/Documentation/devicetree/bindings/net/smsc911x.txt b/Documentation/devicetree/bindings/net/smsc911x.txt
new file mode 100644 (file)
index 0000000..adb5b57
--- /dev/null
@@ -0,0 +1,38 @@
+* Smart Mixed-Signal Connectivity (SMSC) LAN911x/912x Controller
+
+Required properties:
+- compatible : Should be "smsc,lan<model>", "smsc,lan9115"
+- reg : Address and length of the io space for SMSC LAN
+- interrupts : Should contain SMSC LAN interrupt line
+- interrupt-parent : Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- phy-mode : String, operation mode of the PHY interface.
+  Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii",
+  "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii".
+
+Optional properties:
+- reg-shift : Specify the quantity to shift the register offsets by
+- reg-io-width : Specify the size (in bytes) of the IO accesses that
+  should be performed on the device.  Valid value for SMSC LAN is
+  2 or 4.  If it's omitted or invalid, the size would be 2.
+- smsc,irq-active-high : Indicates the IRQ polarity is active-high
+- smsc,irq-push-pull : Indicates the IRQ type is push-pull
+- smsc,force-internal-phy : Forces SMSC LAN controller to use
+  internal PHY
+- smsc,force-external-phy : Forces SMSC LAN controller to use
+  external PHY
+- smsc,save-mac-address : Indicates that mac address needs to be saved
+  before resetting the controller
+- local-mac-address : 6 bytes, mac address
+
+Examples:
+
+lan9220@f4000000 {
+       compatible = "smsc,lan9220", "smsc,lan9115";
+       reg = <0xf4000000 0x2000000>;
+       phy-mode = "mii";
+       interrupt-parent = <&gpio1>;
+       interrupts = <31>;
+       reg-io-width = <4>;
+       smsc,irq-push-pull;
+};
diff --git a/Documentation/devicetree/bindings/power_supply/olpc_battery.txt b/Documentation/devicetree/bindings/power_supply/olpc_battery.txt
new file mode 100644 (file)
index 0000000..c8901b3
--- /dev/null
@@ -0,0 +1,5 @@
+OLPC battery
+~~~~~~~~~~~~
+
+Required properties:
+  - compatible : "olpc,xo1-battery"
diff --git a/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt b/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt
new file mode 100644 (file)
index 0000000..2c3cd41
--- /dev/null
@@ -0,0 +1,11 @@
+* Freescale SGTL5000 Stereo Codec
+
+Required properties:
+- compatible : "fsl,sgtl5000".
+
+Example:
+
+codec: sgtl5000@0a {
+       compatible = "fsl,sgtl5000";
+       reg = <0x0a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8510.txt b/Documentation/devicetree/bindings/sound/wm8510.txt
new file mode 100644 (file)
index 0000000..fa1a32b
--- /dev/null
@@ -0,0 +1,18 @@
+WM8510 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8510"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8510@1a {
+       compatible = "wlf,wm8510";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8523.txt b/Documentation/devicetree/bindings/sound/wm8523.txt
new file mode 100644 (file)
index 0000000..0474618
--- /dev/null
@@ -0,0 +1,16 @@
+WM8523 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+  - compatible : "wlf,wm8523"
+
+  - reg : the I2C address of the device.
+
+Example:
+
+codec: wm8523@1a {
+       compatible = "wlf,wm8523";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8580.txt b/Documentation/devicetree/bindings/sound/wm8580.txt
new file mode 100644 (file)
index 0000000..7d9821f
--- /dev/null
@@ -0,0 +1,16 @@
+WM8580 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+  - compatible : "wlf,wm8580"
+
+  - reg : the I2C address of the device.
+
+Example:
+
+codec: wm8580@1a {
+       compatible = "wlf,wm8580";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8711.txt b/Documentation/devicetree/bindings/sound/wm8711.txt
new file mode 100644 (file)
index 0000000..8ed9998
--- /dev/null
@@ -0,0 +1,18 @@
+WM8711 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8711"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8711@1a {
+       compatible = "wlf,wm8711";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8728.txt b/Documentation/devicetree/bindings/sound/wm8728.txt
new file mode 100644 (file)
index 0000000..a8b5c36
--- /dev/null
@@ -0,0 +1,18 @@
+WM8728 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8728"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8728@1a {
+       compatible = "wlf,wm8728";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8731.txt b/Documentation/devicetree/bindings/sound/wm8731.txt
new file mode 100644 (file)
index 0000000..15f7004
--- /dev/null
@@ -0,0 +1,18 @@
+WM8731 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8731"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8731@1a {
+       compatible = "wlf,wm8731";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8737.txt b/Documentation/devicetree/bindings/sound/wm8737.txt
new file mode 100644 (file)
index 0000000..4bc2cea
--- /dev/null
@@ -0,0 +1,18 @@
+WM8737 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8737"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8737@1a {
+       compatible = "wlf,wm8737";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8741.txt b/Documentation/devicetree/bindings/sound/wm8741.txt
new file mode 100644 (file)
index 0000000..74bda58
--- /dev/null
@@ -0,0 +1,18 @@
+WM8741 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8741"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8741@1a {
+       compatible = "wlf,wm8741";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8750.txt b/Documentation/devicetree/bindings/sound/wm8750.txt
new file mode 100644 (file)
index 0000000..8db239f
--- /dev/null
@@ -0,0 +1,18 @@
+WM8750 and WM8987 audio CODECs
+
+These devices support both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8750" or "wlf,wm8987"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8750@1a {
+       compatible = "wlf,wm8750";
+       reg = <0x1a>;
+};
diff --git a/Documentation/devicetree/bindings/sound/wm8753.txt b/Documentation/devicetree/bindings/sound/wm8753.txt
new file mode 100644 (file)
index 0000000..e65277a
--- /dev/null
@@ -0,0 +1,18 @@
+WM8753 audio CODEC
+
+This device supports both I2C and SPI (configured with pin strapping
+on the board).
+
+Required properties:
+
+  - compatible : "wlf,wm8753"
+
+  - reg : the I2C address of the device for I2C, the chip select
+          number for SPI.
+
+Example:
+
+codec: wm8737@1a {
+       compatible = "wlf,wm8753";
+       reg = <0x1a>;
+};
index 82a5d250d75e705f92b8c32ff634ca1b945ef008..70f924ec1e587b2e8c1767699c73f7d8ba6b9e72 100644 (file)
@@ -21,6 +21,11 @@ o fail_make_request
   /sys/block/<device>/make-it-fail or
   /sys/block/<device>/<partition>/make-it-fail. (generic_make_request())
 
+o fail_mmc_request
+
+  injects MMC data errors on devices permitted by setting
+  debugfs entries under /sys/kernel/debug/mmc0/fail_mmc_request
+
 Configure fault-injection capabilities behavior
 -----------------------------------------------
 
@@ -115,7 +120,8 @@ use the boot option:
 
        failslab=
        fail_page_alloc=
-       fail_make_request=<interval>,<probability>,<space>,<times>
+       fail_make_request=
+       fail_mmc_request=<interval>,<probability>,<space>,<times>
 
 How to add new fault injection capability
 -----------------------------------------
index 232a575a0c4857249edc5aa76a235ce4e258082f..168242b5c045ff6542907dedd11146af6f4e234f 100644 (file)
@@ -160,7 +160,9 @@ noload                      if the filesystem was not unmounted cleanly,
                        lead to any number of problems.
 
 data=journal           All data are committed into the journal prior to being
-                       written into the main file system.
+                       written into the main file system.  Enabling
+                       this mode will disable delayed allocation and
+                       O_DIRECT support.
 
 data=ordered   (*)     All data are forced directly out to the main file
                        system prior to its metadata being committed to the
@@ -419,8 +421,8 @@ written to the journal first, and then to its final location.
 In the event of a crash, the journal can be replayed, bringing both data and
 metadata into a consistent state.  This mode is the slowest except when data
 needs to be read from and written to disk at the same time where it
-outperforms all others modes.  Currently ext4 does not have delayed
-allocation support if this data journalling mode is selected.
+outperforms all others modes.  Enabling this mode will disable delayed
+allocation and O_DIRECT support.
 
 /proc entries
 =============
index 597f728e7b4e9d4c2e9ec231c166be3f1d277642..07235caec22c6ef811af210aff63857c25f9dd56 100644 (file)
@@ -4,7 +4,7 @@ sysfs - _The_ filesystem for exporting kernel objects.
 Patrick Mochel <mochel@osdl.org>
 Mike Murphy <mamurph@cs.clemson.edu>
 
-Revised:    15 July 2010
+Revised:    16 August 2011
 Original:   10 January 2003
 
 
@@ -370,3 +370,11 @@ int driver_create_file(struct device_driver *, const struct driver_attribute *);
 void driver_remove_file(struct device_driver *, const struct driver_attribute *);
 
 
+Documentation
+~~~~~~~~~~~~~
+
+The sysfs directory structure and the attributes in each directory define an
+ABI between the kernel and user space. As for any ABI, it is important that
+this ABI is stable and properly documented. All new sysfs attributes must be
+documented in Documentation/ABI. See also Documentation/ABI/README for more
+information.
index 614d0382e2cbe5b4fd37ce5ce67db76ddd89a6c4..916feab334b578b1630e9ad8da3f47784609ff7f 100644 (file)
@@ -49,6 +49,7 @@ parameter is applicable:
        EDD     BIOS Enhanced Disk Drive Services (EDD) is enabled
        EFI     EFI Partitioning (GPT) is enabled
        EIDE    EIDE/ATAPI support is enabled.
+       EVM     Extended Verification Module
        FB      The frame buffer device is enabled.
        FTRACE  Function tracing enabled.
        GCOV    GCOV profiling is enabled.
@@ -306,6 +307,19 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        behaviour to be specified.  Bit 0 enables warnings,
                        bit 1 enables fixups, and bit 2 sends a segfault.
 
+       align_va_addr=  [X86-64]
+                       Align virtual addresses by clearing slice [14:12] when
+                       allocating a VMA at process creation time. This option
+                       gives you up to 3% performance improvement on AMD F15h
+                       machines (where it is enabled by default) for a
+                       CPU-intensive style benchmark, and it can vary highly in
+                       a microbenchmark depending on workload and compiler.
+
+                       1: only for 32-bit processes
+                       2: only for 64-bit processes
+                       on: enable for both 32- and 64-bit processes
+                       off: disable for both 32- and 64-bit processes
+
        amd_iommu=      [HW,X86-84]
                        Pass parameters to the AMD IOMMU driver in the system.
                        Possible values are:
@@ -727,10 +741,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        See Documentation/block/as-iosched.txt and
                        Documentation/block/deadline-iosched.txt for details.
 
-       elfcorehdr=     [IA-64,PPC,SH,X86]
+       elfcorehdr=[size[KMG]@]offset[KMG] [IA64,PPC,SH,X86,S390]
                        Specifies physical address of start of kernel core
-                       image elf header. Generally kexec loader will
-                       pass this option to capture kernel.
+                       image elf header and optionally the size. Generally
+                       kexec loader will pass this option to capture kernel.
                        See Documentation/kdump/kdump.txt for details.
 
        enable_mtrr_cleanup [X86]
@@ -760,6 +774,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        This option is obsoleted by the "netdev=" option, which
                        has equivalent usage. See its documentation for details.
 
+       evm=            [EVM]
+                       Format: { "fix" }
+                       Permit 'security.evm' to be updated regardless of
+                       current integrity status.
+
        failslab=
        fail_page_alloc=
        fail_make_request=[KNL]
@@ -1777,6 +1796,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
        noresidual      [PPC] Don't use residual data on PReP machines.
 
+       nordrand        [X86] Disable the direct use of the RDRAND
+                       instruction even if it is supported by the
+                       processor.  RDRAND is still available to user
+                       space applications.
+
        noresume        [SWSUSP] Disables resume and restores original swap
                        space.
 
@@ -2086,9 +2110,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        Override pmtimer IOPort with a hex value.
                        e.g. pmtmr=0x508
 
-       pnp.debug       [PNP]
-                       Enable PNP debug messages.  This depends on the
-                       CONFIG_PNP_DEBUG_MESSAGES option.
+       pnp.debug=1     [PNP]
+                       Enable PNP debug messages (depends on the
+                       CONFIG_PNP_DEBUG_MESSAGES option).  Change at run-time
+                       via /sys/module/pnp/parameters/debug.  We always show
+                       current resource usage; turning this on also shows
+                       possible settings and some assignment information.
 
        pnpacpi=        [ACPI]
                        { off }
index 4edd78dfb3622f195a4b05d5948a8e39ceb43070..bbce1215434a9e70797ce679bb6a15c5c2aa29ab 100644 (file)
@@ -1,13 +1,21 @@
 00-INDEX
        - this file
+3c359.txt
+       - information on the 3Com TokenLink Velocity XL (3c5359) driver.
 3c505.txt
        - information on the 3Com EtherLink Plus (3c505) driver.
+3c509.txt
+       - information on the 3Com Etherlink III Series Ethernet cards.
 6pack.txt
        - info on the 6pack protocol, an alternative to KISS for AX.25
 DLINK.txt
        - info on the D-Link DE-600/DE-620 parallel port pocket adapters
 PLIP.txt
        - PLIP: The Parallel Line Internet Protocol device driver
+README.ipw2100
+       - README for the Intel PRO/Wireless 2100 driver.
+README.ipw2200
+       - README for the Intel PRO/Wireless 2915ABG and 2200BG driver.
 README.sb1000
        - info on General Instrument/NextLevel SURFboard1000 cable modem.
 alias.txt
@@ -20,8 +28,12 @@ atm.txt
        - info on where to get ATM programs and support for Linux.
 ax25.txt
        - info on using AX.25 and NET/ROM code for Linux
+batman-adv.txt
+       - B.A.T.M.A.N routing protocol on top of layer 2 Ethernet Frames.
 baycom.txt
        - info on the driver for Baycom style amateur radio modems
+bonding.txt
+       - Linux Ethernet Bonding Driver HOWTO: link aggregation in Linux.
 bridge.txt
        - where to get user space programs for ethernet bridging with Linux.
 can.txt
@@ -34,32 +46,60 @@ cxacru.txt
        - Conexant AccessRunner USB ADSL Modem
 cxacru-cf.py
        - Conexant AccessRunner USB ADSL Modem configuration file parser
+cxgb.txt
+       - Release Notes for the Chelsio N210 Linux device driver.
+dccp.txt
+       - the Datagram Congestion Control Protocol (DCCP) (RFC 4340..42).
 de4x5.txt
        - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver
 decnet.txt
        - info on using the DECnet networking layer in Linux.
 depca.txt
        - the Digital DEPCA/EtherWORKS DE1?? and DE2?? LANCE Ethernet driver
+dl2k.txt
+       - README for D-Link DL2000-based Gigabit Ethernet Adapters (dl2k.ko).
+dm9000.txt
+       - README for the Simtec DM9000 Network driver.
 dmfe.txt
        - info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
+dns_resolver.txt
+       - The DNS resolver module allows kernel servies to make DNS queries.
+driver.txt
+       - Softnet driver issues.
 e100.txt
        - info on Intel's EtherExpress PRO/100 line of 10/100 boards
 e1000.txt
        - info on Intel's E1000 line of gigabit ethernet boards
+e1000e.txt
+       - README for the Intel Gigabit Ethernet Driver (e1000e).
 eql.txt
        - serial IP load balancing
 ewrk3.txt
        - the Digital EtherWORKS 3 DE203/4/5 Ethernet driver
+fib_trie.txt
+       - Level Compressed Trie (LC-trie) notes: a structure for routing.
 filter.txt
        - Linux Socket Filtering
 fore200e.txt
        - FORE Systems PCA-200E/SBA-200E ATM NIC driver info.
 framerelay.txt
        - info on using Frame Relay/Data Link Connection Identifier (DLCI).
+gen_stats.txt
+       - Generic networking statistics for netlink users.
+generic_hdlc.txt
+       - The generic High Level Data Link Control (HDLC) layer.
 generic_netlink.txt
        - info on Generic Netlink
+gianfar.txt
+       - Gianfar Ethernet Driver.
 ieee802154.txt
        - Linux IEEE 802.15.4 implementation, API and drivers
+ifenslave.c
+       - Configure network interfaces for parallel routing (bonding).
+igb.txt
+       - README for the Intel Gigabit Ethernet Driver (igb).
+igbvf.txt
+       - README for the Intel Gigabit Ethernet Driver (igbvf).
 ip-sysctl.txt
        - /proc/sys/net/ipv4/* variables
 ip_dynaddr.txt
@@ -68,41 +108,117 @@ ipddp.txt
        - AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
 iphase.txt
        - Interphase PCI ATM (i)Chip IA Linux driver info.
+ipv6.txt
+       - Options to the ipv6 kernel module.
+ipvs-sysctl.txt
+       - Per-inode explanation of the /proc/sys/net/ipv4/vs interface.
 irda.txt
        - where to get IrDA (infrared) utilities and info for Linux.
+ixgb.txt
+       - README for the Intel 10 Gigabit Ethernet Driver (ixgb).
+ixgbe.txt
+       - README for the Intel 10 Gigabit Ethernet Driver (ixgbe).
+ixgbevf.txt
+       - README for the Intel Virtual Function (VF) Driver (ixgbevf).
+l2tp.txt
+       - User guide to the L2TP tunnel protocol.
 lapb-module.txt
        - programming information of the LAPB module.
 ltpc.txt
        - the Apple or Farallon LocalTalk PC card driver
+mac80211-injection.txt
+       - HOWTO use packet injection with mac80211
 multicast.txt
        - Behaviour of cards under Multicast
+multiqueue.txt
+       - HOWTO for multiqueue network device support.
+netconsole.txt
+       - The network console module netconsole.ko: configuration and notes.
+netdev-features.txt
+       - Network interface features API description.
 netdevices.txt
        - info on network device driver functions exported to the kernel.
+netif-msg.txt
+       - Design of the network interface message level setting (NETIF_MSG_*).
+nfc.txt
+       - The Linux Near Field Communication (NFS) subsystem.
 olympic.txt
        - IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info.
+operstates.txt
+       - Overview of network interface operational states.
+packet_mmap.txt
+       - User guide to memory mapped packet socket rings (PACKET_[RT]X_RING).
+phonet.txt
+       - The Phonet packet protocol used in Nokia cellular modems.
+phy.txt
+       - The PHY abstraction layer.
+pktgen.txt
+       - User guide to the kernel packet generator (pktgen.ko).
 policy-routing.txt
        - IP policy-based routing
+ppp_generic.txt
+       - Information about the generic PPP driver.
+proc_net_tcp.txt
+       - Per inode overview of the /proc/net/tcp and /proc/net/tcp6 interfaces.
+radiotap-headers.txt
+       - Background on radiotap headers.
 ray_cs.txt
        - Raylink Wireless LAN card driver info.
+rds.txt
+       - Background on the reliable, ordered datagram delivery method RDS.
+regulatory.txt
+       - Overview of the Linux wireless regulatory infrastructure.
+rxrpc.txt
+       - Guide to the RxRPC protocol.
+s2io.txt
+       - Release notes for Neterion Xframe I/II 10GbE driver.
+scaling.txt
+       - Explanation of network scaling techniques: RSS, RPS, RFS, aRFS, XPS.
+sctp.txt
+       - Notes on the Linux kernel implementation of the SCTP protocol.
+secid.txt
+       - Explanation of the secid member in flow structures.
 skfp.txt
        - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 smc9.txt
        - the driver for SMC's 9000 series of Ethernet cards
 smctr.txt
        - SMC TokenCard TokenRing Linux driver info.
+spider-net.txt
+       - README for the Spidernet Driver (as found in PS3 / Cell BE).
+stmmac.txt
+       - README for the STMicro Synopsys Ethernet driver.
+tc-actions-env-rules.txt
+       - rules for traffic control (tc) actions.
+timestamping.txt
+       - overview of network packet timestamping variants.
 tcp.txt
        - short blurb on how TCP output takes place.
+tcp-thin.txt
+       - kernel tuning options for low rate 'thin' TCP streams.
 tlan.txt
        - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info.
 tms380tr.txt
        - SysKonnect Token Ring ISA/PCI adapter driver info.
+tproxy.txt
+       - Transparent proxy support user guide.
 tuntap.txt
        - TUN/TAP device driver, allowing user space Rx/Tx of packets.
+udplite.txt
+       - UDP-Lite protocol (RFC 3828) introduction.
 vortex.txt
        - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards.
+vxge.txt
+       - README for the Neterion X3100 PCIe Server Adapter.
 x25.txt
        - general info on X.25 development.
 x25-iface.txt
        - description of the X.25 Packet Layer to LAPB device interface.
+xfrm_proc.txt
+       - description of the statistics package for XFRM.
+xfrm_sync.txt
+       - sync patches for XFRM enable migration of an SA between hosts.
+xfrm_sysctl.txt
+       - description of the XFRM configuration options.
 z8530drv.txt
        - info about Linux driver for Z8530 based HDLC cards for AX.25
index db2a4067013c2e25deabc419ee3e9cab14c2b282..81546990f41ca16b2c1c022dac487aea92fbc20b 100644 (file)
@@ -992,7 +992,7 @@ bindv6only - BOOLEAN
                TRUE: disable IPv4-mapped address feature
                FALSE: enable IPv4-mapped address feature
 
-       Default: FALSE (as specified in RFC2553bis)
+       Default: FALSE (as specified in RFC3493)
 
 IPv6 Fragmentation:
 
index 87b3d15f523ad49863d927801269efd1b5fb65de..89358341682a1290879d26b854c1527991b54768 100644 (file)
@@ -73,7 +73,7 @@ dev->hard_start_xmit:
        has to lock by itself when needed. It is recommended to use a try lock
        for this and return NETDEV_TX_LOCKED when the spin lock fails.
        The locking there should also properly protect against 
-       set_multicast_list. Note that the use of NETIF_F_LLTX is deprecated.
+       set_rx_mode. Note that the use of NETIF_F_LLTX is deprecated.
        Don't use it for new drivers.
 
        Context: Process with BHs disabled or BH (timer),
@@ -92,7 +92,7 @@ dev->tx_timeout:
        Context: BHs disabled
        Notes: netif_queue_stopped() is guaranteed true
 
-dev->set_multicast_list:
+dev->set_rx_mode:
        Synchronization: netif_tx_lock spinlock.
        Context: BHs disabled
 
index 7254b4b5910e45b422028e3e3215fac73f5e9f8e..58fd7414e6c08120c14bf13dd300f45af0438b0e 100644 (file)
@@ -52,7 +52,8 @@ module parameter for specifying the number of hardware queues to
 configure. In the bnx2x driver, for instance, this parameter is called
 num_queues. A typical RSS configuration would be to have one receive queue
 for each CPU if the device supports enough queues, or otherwise at least
-one for each cache domain at a particular cache level (L1, L2, etc.).
+one for each memory domain, where a memory domain is a set of CPUs that
+share a particular memory level (L1, L2, NUMA node, etc.).
 
 The indirection table of an RSS device, which resolves a queue by masked
 hash, is usually programmed by the driver at initialization. The
@@ -82,11 +83,17 @@ RSS should be enabled when latency is a concern or whenever receive
 interrupt processing forms a bottleneck. Spreading load between CPUs
 decreases queue length. For low latency networking, the optimal setting
 is to allocate as many queues as there are CPUs in the system (or the
-NIC maximum, if lower). Because the aggregate number of interrupts grows
-with each additional queue, the most efficient high-rate configuration
+NIC maximum, if lower). The most efficient high-rate configuration
 is likely the one with the smallest number of receive queues where no
-CPU that processes receive interrupts reaches 100% utilization. Per-cpu
-load can be observed using the mpstat utility.
+receive queue overflows due to a saturated CPU, because in default
+mode with interrupt coalescing enabled, the aggregate number of
+interrupts (and thus work) grows with each additional queue.
+
+Per-cpu load can be observed using the mpstat utility, but note that on
+processors with hyperthreading (HT), each hyperthread is represented as
+a separate CPU. For interrupt handling, HT has shown no benefit in
+initial tests, so limit the number of queues to the number of CPU cores
+in the system.
 
 
 RPS: Receive Packet Steering
@@ -145,7 +152,7 @@ the bitmap.
 == Suggested Configuration
 
 For a single queue device, a typical RPS configuration would be to set
-the rps_cpus to the CPUs in the same cache domain of the interrupting
+the rps_cpus to the CPUs in the same memory domain of the interrupting
 CPU. If NUMA locality is not an issue, this could also be all CPUs in
 the system. At high interrupt rate, it might be wise to exclude the
 interrupting CPU from the map since that already performs much work.
@@ -154,7 +161,7 @@ For a multi-queue system, if RSS is configured so that a hardware
 receive queue is mapped to each CPU, then RPS is probably redundant
 and unnecessary. If there are fewer hardware queues than CPUs, then
 RPS might be beneficial if the rps_cpus for each queue are the ones that
-share the same cache domain as the interrupting CPU for that queue.
+share the same memory domain as the interrupting CPU for that queue.
 
 
 RFS: Receive Flow Steering
@@ -326,7 +333,7 @@ The queue chosen for transmitting a particular flow is saved in the
 corresponding socket structure for the flow (e.g. a TCP connection).
 This transmit queue is used for subsequent packets sent on the flow to
 prevent out of order (ooo) packets. The choice also amortizes the cost
-of calling get_xps_queues() over all packets in the connection. To avoid
+of calling get_xps_queues() over all packets in the flow. To avoid
 ooo packets, the queue for a flow can subsequently only be changed if
 skb->ooo_okay is set for a packet in the flow. This flag indicates that
 there are no outstanding packets in the flow, so the transmit queue can
index ddd78172ef738d2c3f52dcea70f61cb0591670c2..62eca080a71b2313196b4588dfa817dae5ed573a 100644 (file)
@@ -201,3 +201,27 @@ case, you may be able to search for failing drivers by following the procedure
 analogous to the one described in section 1.  If you find some failing drivers,
 you will have to unload them every time before an STR transition (ie. before
 you run s2ram), and please report the problems with them.
+
+There is a debugfs entry which shows the suspend to RAM statistics. Here is an
+example of its output.
+       # mount -t debugfs none /sys/kernel/debug
+       # cat /sys/kernel/debug/suspend_stats
+       success: 20
+       fail: 5
+       failed_freeze: 0
+       failed_prepare: 0
+       failed_suspend: 5
+       failed_suspend_noirq: 0
+       failed_resume: 0
+       failed_resume_noirq: 0
+       failures:
+         last_failed_dev:      alarm
+                               adc
+         last_failed_errno:    -16
+                               -16
+         last_failed_step:     suspend
+                               suspend
+Field success means the success number of suspend to RAM, and field fail means
+the failure number. Others are the failure number of different steps of suspend
+to RAM. suspend_stats just lists the last 2 failed devices, error number and
+failed step of suspend.
index 38b57248fd61f5755528837145052c5c998c17b7..cbea897f2da0c6329f99284cbdab8aed8f84a0da 100644 (file)
@@ -21,7 +21,7 @@ freeze_processes() (defined in kernel/power/process.c) is called.  It executes
 try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
 either wakes them up, if they are kernel threads, or sends fake signals to them,
 if they are user space processes.  A task that has TIF_FREEZE set, should react
-to it by calling the function called refrigerator() (defined in
+to it by calling the function called __refrigerator() (defined in
 kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state
 to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
 Then, we say that the task is 'frozen' and therefore the set of functions
@@ -29,10 +29,10 @@ handling this mechanism is referred to as 'the freezer' (these functions are
 defined in kernel/power/process.c and include/linux/freezer.h).  User space
 processes are generally frozen before kernel threads.
 
-It is not recommended to call refrigerator() directly.  Instead, it is
-recommended to use the try_to_freeze() function (defined in
-include/linux/freezer.h), that checks the task's TIF_FREEZE flag and makes the
-task enter refrigerator() if the flag is set.
+__refrigerator() must not be called directly.  Instead, use the
+try_to_freeze() function (defined in include/linux/freezer.h), that checks
+the task's TIF_FREEZE flag and makes the task enter __refrigerator() if the
+flag is set.
 
 For user space processes try_to_freeze() is called automatically from the
 signal-handling code, but the freezable kernel threads need to call it
@@ -61,13 +61,13 @@ wait_event_freezable() and wait_event_freezable_timeout() macros.
 After the system memory state has been restored from a hibernation image and
 devices have been reinitialized, the function thaw_processes() is called in
 order to clear the PF_FROZEN flag for each frozen task.  Then, the tasks that
-have been frozen leave refrigerator() and continue running.
+have been frozen leave __refrigerator() and continue running.
 
 III. Which kernel threads are freezable?
 
 Kernel threads are not freezable by default.  However, a kernel thread may clear
 PF_NOFREEZE for itself by calling set_freezable() (the resetting of PF_NOFREEZE
-directly is strongly discouraged).  From this point it is regarded as freezable
+directly is not allowed).  From this point it is regarded as freezable
 and must call try_to_freeze() in a suitable place.
 
 IV. Why do we do that?
index 4ce5450ab6e833cef372ef2755993353cae50935..62f37bc3866fbec75fba42ce2141d2c123867338 100644 (file)
@@ -484,6 +484,7 @@ pm_runtime_resume()
 pm_runtime_get_sync()
 pm_runtime_put_sync()
 pm_runtime_put_sync_suspend()
+pm_runtime_put_sync_autosuspend()
 
 5. Runtime PM Initialization, Device Probing and Removal
 
index 89757012c7ffda2d1babfd1dd9bc9d7e4d1604eb..27126c469f7086bf7fe24897d1402165d8922a49 100644 (file)
@@ -886,6 +886,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                disable)
     power_save_controller - Reset HD-audio controller in power-saving mode
                (default = on)
+    align_buffer_size - Force rounding of buffer/period sizes to multiples
+                     of 128 bytes. This is more efficient in terms of memory
+                     access but isn't required by the HDA spec and prevents
+                     users from specifying exact period/buffer sizes.
+                     (default = on)
 
     This module supports multiple cards and autoprobe.
     
index d70c93bdcadf16a8be454581c1cb611686102cf0..fbec67f29a1a18fb3f0f81edf27280e040df9e5c 100644 (file)
@@ -29,9 +29,6 @@ ALC880
 
 ALC260
 ======
-  hp           HP machines
-  hp-3013      HP machines (3013-variant)
-  hp-dc7600    HP DC7600
   fujitsu      Fujitsu S7020
   acer         Acer TravelMate
   will         Will laptops (PB V7900)
@@ -46,15 +43,10 @@ ALC260
 ALC262
 ======
   fujitsu      Fujitsu Laptop
-  hp-bpc       HP xw4400/6400/8400/9400 laptops
-  hp-bpc-d7000 HP BPC D7000
-  hp-tc-t5735  HP Thin Client T5735
-  hp-rp5700    HP RP5700
   benq         Benq ED8
   benq-t31     Benq T31
   hippo                Hippo (ATI) with jack detection, Sony UX-90s
   hippo_1      Hippo (Benq) with jack detection
-  sony-assamd  Sony ASSAMD
   toshiba-s06  Toshiba S06
   toshiba-rx1  Toshiba RX1
   tyan         Tyan Thunder n6650W (S2915-E)
@@ -66,28 +58,12 @@ ALC262
 
 ALC267/268
 ==========
-  quanta-il1   Quanta IL1 mini-notebook
-  3stack       3-stack model
-  toshiba      Toshiba A205
-  acer         Acer laptops
-  acer-dmic    Acer laptops with digital-mic
-  acer-aspire  Acer Aspire One
-  dell         Dell OEM laptops (Vostro 1200)
-  zepto                Zepto laptops
-  test         for testing/debugging purpose, almost all controls can
-               adjusted.  Appearing only when compiled with
-               $CONFIG_SND_DEBUG=y
-  auto         auto-config reading BIOS (default)
+  N/A
 
 ALC269
 ======
-  basic                Basic preset
-  quanta       Quanta FL1
   laptop-amic  Laptops with analog-mic input
   laptop-dmic  Laptops with digital-mic input
-  fujitsu      FSC Amilo
-  lifebook     Fujitsu Lifebook S6420
-  auto         auto-config reading BIOS (default)
 
 ALC662/663/272
 ==============
@@ -95,10 +71,7 @@ ALC662/663/272
   3stack-6ch    3-stack (6-channel)
   3stack-6ch-dig 3-stack (6-channel) with SPDIF
   5stack-dig    5-stack with SPDIF
-  lenovo-101e   Lenovo laptop
-  eeepc-p701   ASUS Eeepc P701
   eeepc-ep20   ASUS Eeepc EP20
-  ecs          ECS/Foxconn mobo
   m51va                ASUS M51VA
   g71v         ASUS G71V
   h13          ASUS H13
@@ -111,15 +84,11 @@ ALC662/663/272
   asus-mode6   ASUS
   asus-mode7   ASUS
   asus-mode8   ASUS
-  dell         Dell with ALC272
-  dell-zm1     Dell ZM1 with ALC272
-  samsung-nc10 Samsung NC10 mini notebook
   auto         auto-config reading BIOS (default)
 
 ALC680
 ======
-  base         Base model (ASUS NX90)
-  auto         auto-config reading BIOS (default)
+  N/A
 
 ALC882/883/885/888/889
 ======================
@@ -175,28 +144,11 @@ ALC882/883/885/888/889
 
 ALC861/660
 ==========
-  3stack       3-jack
-  3stack-dig   3-jack with SPDIF I/O
-  6stack-dig   6-jack with SPDIF I/O
-  3stack-660   3-jack (for ALC660)
-  uniwill-m31  Uniwill M31 laptop
-  toshiba      Toshiba laptop support
-  asus         Asus laptop support
-  asus-laptop  ASUS F2/F3 laptops
-  auto         auto-config reading BIOS (default)
+  N/A
 
 ALC861VD/660VD
 ==============
-  3stack       3-jack
-  3stack-dig   3-jack with SPDIF OUT
-  6stack-dig   6-jack with SPDIF OUT
-  3stack-660   3-jack (for ALC660VD)
-  3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
-  lenovo       Lenovo 3000 C200
-  dallas       Dallas laptops
-  hp           HP TX1000
-  asus-v1s     ASUS V1Sn
-  auto         auto-config reading BIOS (default)
+  N/A
 
 CMI9880
 =======
index c82beb0076341856ca13b1e1dd125cc440ed439c..850b1b3956aeb8feaa6ecb55f8e4da583461e931 100644 (file)
@@ -524,6 +524,54 @@ power-saving.  See /sys/module/snd_hda_intel/parameters/power_save to
 check the current value.  If it's non-zero, the feature is turned on.
 
 
+Tracepoints
+~~~~~~~~~~~
+The hd-audio driver gives a few basic tracepoints.
+`hda:hda_send_cmd` traces each CORB write while `hda:hda_get_response`
+traces the response from RIRB (only when read from the codec driver).
+`hda:hda_bus_reset` traces the bus-reset due to fatal error, etc,
+`hda:hda_unsol_event` traces the unsolicited events, and
+`hda:hda_power_down` and `hda:hda_power_up` trace the power down/up
+via power-saving behavior.
+
+Enabling all tracepoints can be done like
+------------------------------------------------------------------------
+  # echo 1 > /sys/kernel/debug/tracing/events/hda/enable
+------------------------------------------------------------------------
+then after some commands, you can traces from
+/sys/kernel/debug/tracing/trace file.  For example, when you want to
+trace what codec command is sent, enable the tracepoint like:
+------------------------------------------------------------------------
+  # cat /sys/kernel/debug/tracing/trace
+  # tracer: nop
+  #
+  #       TASK-PID    CPU#    TIMESTAMP  FUNCTION
+  #          | |       |          |         |
+         <...>-7807  [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019
+         <...>-7807  [002] 105147.774893: hda_send_cmd: [0:0] val=e39019
+         <...>-7807  [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a
+         <...>-7807  [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a
+         <...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019
+         <...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019
+         <...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a
+         <...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a
+------------------------------------------------------------------------
+Here `[0:0]` indicates the card number and the codec address, and
+`val` shows the value sent to the codec, respectively.  The value is
+a packed value, and you can decode it via hda-decode-verb program
+included in hda-emu package below.  For example, the value e3a019 is
+to set the left output-amp value to 25.
+------------------------------------------------------------------------
+  % hda-decode-verb 0xe3a019
+  raw value = 0x00e3a019
+  cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19
+  raw value: verb = 0x3a0, parm = 0x19
+  verbname = set_amp_gain_mute
+  amp raw val = 0xa019
+  output, left, idx=0, mute=0, val=25
+------------------------------------------------------------------------
+
+
 Development Tree
 ~~~~~~~~~~~~~~~~
 The latest development codes for HD-audio are found on sound git tree:
index c9ffa9ced7eec964e47c2513584f9041a6fb9c7e..e8662a5fbc5d2be688248cd6db5256aa61e4a09e 100644 (file)
@@ -439,10 +439,10 @@ cause autosuspends to fail with -EBUSY if the driver needs to use the
 device.
 
 External suspend calls should never be allowed to fail in this way,
-only autosuspend calls.  The driver can tell them apart by checking
-the PM_EVENT_AUTO bit in the message.event argument to the suspend
-method; this bit will be set for internal PM events (autosuspend) and
-clear for external PM events.
+only autosuspend calls.  The driver can tell them apart by applying
+the PMSG_IS_AUTO() macro to the message argument to the suspend
+method; it will return True for internal PM events (autosuspend) and
+False for external PM events.
 
 
        Mutual exclusion
index 7869f14d055cc3899315defbef14320c6314b725..bc7226ef5055c4c3bec4b7a270f8260449fe705c 100644 (file)
@@ -27,9 +27,6 @@ Some of these entries are:
    magically-generated functions that make their way to do_IRQ with
    the interrupt number as a parameter.
 
- - emulate_vsyscall: int 0xcc, a special non-ABI entry used by
-   vsyscall emulation.
-
  - APIC interrupts: Various special-purpose interrupts for things
    like TLB shootdown.
 
index 18a36f036aa76aa375635dab0f1ea31d43d2301e..bdc0cf304608735257ade18c95bc3129a2629cb7 100644 (file)
@@ -117,20 +117,20 @@ Maintainers List (try to look for most precise areas first)
 M:     Philip Blundell <philb@gnu.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/3c505*
+F:     drivers/net/ethernet/i825xx/3c505*
 
 3C59X NETWORK DRIVER
 M:     Steffen Klassert <klassert@mathematik.tu-chemnitz.de>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/networking/vortex.txt
-F:     drivers/net/3c59x.c
+F:     drivers/net/ethernet/3com/3c59x.c
 
 3CR990 NETWORK DRIVER
 M:     David Dillow <dave@thedillows.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/typhoon*
+F:     drivers/net/ethernet/3com/typhoon*
 
 3WARE SAS/SATA-RAID SCSI DRIVERS (3W-XXXX, 3W-9XXX, 3W-SAS)
 M:     Adam Radford <linuxraid@lsi.com>
@@ -156,7 +156,7 @@ M:  Realtek linux nic maintainers <nic_swsd@realtek.com>
 M:     Francois Romieu <romieu@fr.zoreil.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/r8169.c
+F:     drivers/net/ethernet/realtek/r8169.c
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
 M:     Greg Kroah-Hartman <gregkh@suse.de>
@@ -170,8 +170,7 @@ F:  include/linux/serial_8250.h
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 L:     netdev@vger.kernel.org
 S:     Orphan / Obsolete
-F:     drivers/net/*8390*
-F:     drivers/net/ax88796.c
+F:     drivers/net/ethernet/8390/
 
 9P FILE SYSTEM
 M:     Eric Van Hensbergen <ericvh@gmail.com>
@@ -214,7 +213,7 @@ ACENIC DRIVER
 M:     Jes Sorensen <jes@trained-monkey.org>
 L:     linux-acenic@sunsite.dk
 S:     Maintained
-F:     drivers/net/acenic*
+F:     drivers/net/ethernet/alteon/acenic*
 
 ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
 M:     Peter Feuerer <peter@piie.net>
@@ -746,7 +745,7 @@ L:  linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.arm.linux.org.uk/
 S:     Maintained
 F:     arch/arm/mach-ebsa110/
-F:     drivers/net/arm/am79c961a.*
+F:     drivers/net/ethernet/amd/am79c961a.*
 
 ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
 M:     Daniel Ribeiro <drwyrm@gmail.com>
@@ -1015,7 +1014,8 @@ F:        arch/arm/include/asm/hardware/ioc.h
 F:     arch/arm/include/asm/hardware/iomd.h
 F:     arch/arm/include/asm/hardware/memc.h
 F:     arch/arm/mach-rpc/
-F:     drivers/net/arm/ether*
+F:     drivers/net/ethernet/i825xx/ether1*
+F:     drivers/net/ethernet/seeq/ether3*
 F:     drivers/scsi/arm/
 
 ARM/SHARK MACHINE SUPPORT
@@ -1127,7 +1127,7 @@ F:        arch/arm/mach-nuc93x/
 F:     drivers/input/keyboard/w90p910_keypad.c
 F:     drivers/input/touchscreen/w90p910_ts.c
 F:     drivers/watchdog/nuc900_wdt.c
-F:     drivers/net/arm/w90p910_ether.c
+F:     drivers/net/ethernet/nuvoton/w90p910_ether.c
 F:     drivers/mtd/nand/nuc900_nand.c
 F:     drivers/rtc/rtc-nuc900.c
 F:     drivers/spi/spi_nuc900.c
@@ -1283,7 +1283,7 @@ L:        netdev@vger.kernel.org
 W:     http://sourceforge.net/projects/atl1
 W:     http://atl1.sourceforge.net
 S:     Maintained
-F:     drivers/net/atlx/
+F:     drivers/net/ethernet/atheros/
 
 ATM
 M:     Chas Williams <chas@cmf.nrl.navy.mil>
@@ -1323,7 +1323,7 @@ F:        include/video/atmel_lcdc.h
 ATMEL MACB ETHERNET DRIVER
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
 S:     Supported
-F:     drivers/net/macb.*
+F:     drivers/net/ethernet/cadence/
 
 ATMEL SPI DRIVER
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
@@ -1446,7 +1446,7 @@ BLACKFIN EMAC DRIVER
 L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org
 S:     Supported
-F:     drivers/net/bfin_mac.*
+F:     drivers/net/ethernet/adi/
 
 BLACKFIN RTC DRIVER
 M:     Mike Frysinger <vapier.adi@gmail.com>
@@ -1527,27 +1527,27 @@ BROADCOM B44 10/100 ETHERNET DRIVER
 M:     Gary Zambrano <zambrano@broadcom.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/b44.*
+F:     drivers/net/ethernet/broadcom/b44.*
 
 BROADCOM BNX2 GIGABIT ETHERNET DRIVER
 M:     Michael Chan <mchan@broadcom.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/bnx2.*
-F:     drivers/net/bnx2_*
+F:     drivers/net/ethernet/broadcom/bnx2.*
+F:     drivers/net/ethernet/broadcom/bnx2_*
 
 BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
 M:     Eilon Greenstein <eilong@broadcom.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/bnx2x/
+F:     drivers/net/ethernet/broadcom/bnx2x/
 
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 M:     Matt Carlson <mcarlson@broadcom.com>
 M:     Michael Chan <mchan@broadcom.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/tg3.*
+F:     drivers/net/ethernet/broadcom/tg3.*
 
 BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
 M:     Brett Rudley <brudley@broadcom.com>
@@ -1577,7 +1577,7 @@ M:        Rasesh Mody <rmody@brocade.com>
 M:     Debashis Dutt <ddutt@brocade.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/bna/
+F:     drivers/net/ethernet/brocade/bna/
 
 BSG (block layer generic sg v4 driver)
 M:     FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
@@ -1762,13 +1762,13 @@ M:      Vasanthy Kolluri <vkolluri@cisco.com>
 M:     Roopa Prabhu <roprabhu@cisco.com>
 M:     David Wang <dwang2@cisco.com>
 S:     Supported
-F:     drivers/net/enic/
+F:     drivers/net/ethernet/cisco/enic/
 
 CIRRUS LOGIC EP93XX ETHERNET DRIVER
 M:     Hartley Sweeten <hsweeten@visionengravers.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/arm/ep93xx_eth.c
+F:     drivers/net/ethernet/cirrus/ep93xx_eth.c
 
 CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
 M:     Lennert Buytenhek <kernel@wantstofly.org>
@@ -1908,7 +1908,7 @@ CPMAC ETHERNET DRIVER
 M:     Florian Fainelli <florian@openwrt.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/cpmac.c
+F:     drivers/net/ethernet/ti/cpmac.c
 
 CPU FREQUENCY DRIVERS
 M:     Dave Jones <davej@redhat.com>
@@ -1995,7 +1995,7 @@ M:        Divy Le Ray <divy@chelsio.com>
 L:     netdev@vger.kernel.org
 W:     http://www.chelsio.com
 S:     Supported
-F:     drivers/net/cxgb3/
+F:     drivers/net/ethernet/chelsio/cxgb3/
 
 CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
 M:     Steve Wise <swise@chelsio.com>
@@ -2009,7 +2009,7 @@ M:        Dimitris Michailidis <dm@chelsio.com>
 L:     netdev@vger.kernel.org
 W:     http://www.chelsio.com
 S:     Supported
-F:     drivers/net/cxgb4/
+F:     drivers/net/ethernet/chelsio/cxgb4/
 
 CXGB4 IWARP RNIC DRIVER (IW_CXGB4)
 M:     Steve Wise <swise@chelsio.com>
@@ -2023,14 +2023,14 @@ M:      Casey Leedom <leedom@chelsio.com>
 L:     netdev@vger.kernel.org
 W:     http://www.chelsio.com
 S:     Supported
-F:     drivers/net/cxgb4vf/
+F:     drivers/net/ethernet/chelsio/cxgb4vf/
 
 STMMAC ETHERNET DRIVER
 M:     Giuseppe Cavallaro <peppe.cavallaro@st.com>
 L:     netdev@vger.kernel.org
 W:     http://www.stlinux.com
 S:     Supported
-F:     drivers/net/stmmac/
+F:     drivers/net/ethernet/stmicro/stmmac/
 
 CYBERPRO FB DRIVER
 M:     Russell King <linux@arm.linux.org.uk>
@@ -2074,7 +2074,7 @@ DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
 L:     netdev@vger.kernel.org
 S:     Orphan
 F:     Documentation/networking/dmfe.txt
-F:     drivers/net/tulip/dmfe.c
+F:     drivers/net/ethernet/tulip/dmfe.c
 
 DC390/AM53C974 SCSI driver
 M:     Kurt Garloff <garloff@suse.de>
@@ -2305,6 +2305,12 @@ L:       netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/wan/dscc4.c
 
+DYNAMIC DEBUG
+M:     Jason Baron <jbaron@redhat.com>
+S:     Maintained
+F:     lib/dynamic_debug.c
+F:     include/linux/dynamic_debug.h
+
 DZ DECSTATION DZ11 SERIAL DRIVER
 M:     "Maciej W. Rozycki" <macro@linux-mips.org>
 S:     Maintained
@@ -2474,7 +2480,7 @@ EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
 M:     Breno Leitao <leitao@linux.vnet.ibm.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/ehea/
+F:     drivers/net/ethernet/ibm/ehea/
 
 EMBEDDED LINUX
 M:     Paul Gortmaker <paul.gortmaker@windriver.com>
@@ -2519,7 +2525,7 @@ ETHEREXPRESS-16 NETWORK DRIVER
 M:     Philip Blundell <philb@gnu.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/eexpress.*
+F:     drivers/net/ethernet/i825xx/eexpress.*
 
 ETHERNET BRIDGE
 M:     Stephen Hemminger <shemminger@linux-foundation.org>
@@ -2533,7 +2539,7 @@ F:        net/bridge/
 ETHERTEAM 16I DRIVER
 M:     Mika Kuoppala <miku@iki.fi>
 S:     Maintained
-F:     drivers/net/eth16i.c
+F:     drivers/net/ethernet/fujitsu/eth16i.c
 
 EXT2 FILE SYSTEM
 M:     Jan Kara <jack@suse.cz>
@@ -2563,6 +2569,11 @@ S:       Maintained
 F:     Documentation/filesystems/ext4.txt
 F:     fs/ext4/
 
+Extended Verification Module (EVM)
+M:     Mimi Zohar <zohar@us.ibm.com>
+S:     Supported
+F:     security/integrity/evm/
+
 F71805F HARDWARE MONITORING DRIVER
 M:     Jean Delvare <khali@linux-fr.org>
 L:     lm-sensors@lm-sensors.org
@@ -2697,7 +2708,7 @@ M:        Vitaly Bordug <vbordug@ru.mvista.com>
 L:     linuxppc-dev@lists.ozlabs.org
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/fs_enet/
+F:     drivers/net/ethernet/freescale/fs_enet/
 F:     include/linux/fs_enet_pd.h
 
 FREESCALE QUICC ENGINE LIBRARY
@@ -2719,7 +2730,7 @@ M:        Li Yang <leoli@freescale.com>
 L:     netdev@vger.kernel.org
 L:     linuxppc-dev@lists.ozlabs.org
 S:     Maintained
-F:     drivers/net/ucc_geth*
+F:     drivers/net/ethernet/freescale/ucc_geth*
 
 FREESCALE QUICC ENGINE UCC UART DRIVER
 M:     Timur Tabi <timur@freescale.com>
@@ -3074,7 +3085,7 @@ F:        drivers/platform/x86/tc1100-wmi.c
 HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
 M:     Jaroslav Kysela <perex@perex.cz>
 S:     Maintained
-F:     drivers/net/hp100.*
+F:     drivers/net/ethernet/hp/hp100.*
 
 HPET:  High Precision Event Timers driver
 M:     Clemens Ladisch <clemens@ladisch.de>
@@ -3172,7 +3183,7 @@ IBM Power Virtual Ethernet Device Driver
 M:     Santiago Leon <santil@linux.vnet.ibm.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/ibmveth.*
+F:     drivers/net/ethernet/ibm/ibmveth.*
 
 IBM ServeRAID RAID DRIVER
 P:     Jack Hammer
@@ -3328,7 +3339,7 @@ F:        arch/arm/mach-ixp4xx/include/mach/qmgr.h
 F:     arch/arm/mach-ixp4xx/include/mach/npe.h
 F:     arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
 F:     arch/arm/mach-ixp4xx/ixp4xx_npe.c
-F:     drivers/net/arm/ixp4xx_eth.c
+F:     drivers/net/ethernet/xscale/ixp4xx_eth.c
 F:     drivers/net/wan/ixp4xx_hss.c
 
 INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
@@ -3340,7 +3351,7 @@ INTEL IXP2000 ETHERNET DRIVER
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/ixp2000/
+F:     drivers/net/ethernet/xscale/ixp2000/
 
 INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
 M:     Jeff Kirsher <jeffrey.t.kirsher@intel.com>
@@ -3349,13 +3360,13 @@ M:      Bruce Allan <bruce.w.allan@intel.com>
 M:     Carolyn Wyborny <carolyn.wyborny@intel.com>
 M:     Don Skidmore <donald.c.skidmore@intel.com>
 M:     Greg Rose <gregory.v.rose@intel.com>
-M:     PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
+M:     Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
 M:     Alex Duyck <alexander.h.duyck@intel.com>
 M:     John Ronciak <john.ronciak@intel.com>
 L:     e1000-devel@lists.sourceforge.net
 W:     http://e1000.sourceforge.net/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-2.6.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next.git
 S:     Supported
 F:     Documentation/networking/e100.txt
 F:     Documentation/networking/e1000.txt
@@ -3365,14 +3376,7 @@ F:       Documentation/networking/igbvf.txt
 F:     Documentation/networking/ixgb.txt
 F:     Documentation/networking/ixgbe.txt
 F:     Documentation/networking/ixgbevf.txt
-F:     drivers/net/e100.c
-F:     drivers/net/e1000/
-F:     drivers/net/e1000e/
-F:     drivers/net/igb/
-F:     drivers/net/igbvf/
-F:     drivers/net/ixgb/
-F:     drivers/net/ixgbe/
-F:     drivers/net/ixgbevf/
+F:     drivers/net/ethernet/intel/
 
 INTEL MRST PMU DRIVER
 M:     Len Brown <len.brown@intel.com>
@@ -3440,7 +3444,7 @@ IOC3 ETHERNET DRIVER
 M:     Ralf Baechle <ralf@linux-mips.org>
 L:     linux-mips@linux-mips.org
 S:     Maintained
-F:     drivers/net/ioc3-eth.c
+F:     drivers/net/ethernet/sgi/ioc3-eth.c
 
 IOC3 SERIAL DRIVER
 M:     Pat Gefre <pfg@sgi.com>
@@ -3458,7 +3462,7 @@ M:        Francois Romieu <romieu@fr.zoreil.com>
 M:     Sorbica Shieh <sorbica@icplus.com.tw>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/ipg.*
+F:     drivers/net/ethernet/icplus/ipg.*
 
 IPATH DRIVER
 M:     Mike Marciniszyn <infinipath@qlogic.com>
@@ -3606,7 +3610,7 @@ JME NETWORK DRIVER
 M:     Guo-Fu Tseng <cooldavid@cooldavid.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/jme.*
+F:     drivers/net/ethernet/jme.*
 
 JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
 M:     David Woodhouse <dwmw2@infradead.org>
@@ -4137,7 +4141,7 @@ MARVELL MV643XX ETHERNET DRIVER
 M:     Lennert Buytenhek <buytenh@wantstofly.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/mv643xx_eth.*
+F:     drivers/net/ethernet/marvell/mv643xx_eth.*
 F:     include/linux/mv643xx.h
 
 MARVELL MWIFIEX WIRELESS DRIVER
@@ -4351,12 +4355,12 @@ M:      Andrew Gallatin <gallatin@myri.com>
 L:     netdev@vger.kernel.org
 W:     http://www.myri.com/scs/download-Myri10GE.html
 S:     Supported
-F:     drivers/net/myri10ge/
+F:     drivers/net/ethernet/myricom/myri10ge/
 
 NATSEMI ETHERNET DRIVER (DP8381x)
 M:     Tim Hockin <thockin@hockin.org>
 S:     Maintained
-F:     drivers/net/natsemi.c
+F:     drivers/net/ethernet/natsemi/natsemi.c
 
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
 M:     Daniel Mack <zonque@gmail.com>
@@ -4396,9 +4400,8 @@ W:        http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
 W:     http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
 S:     Supported
 F:     Documentation/networking/s2io.txt
-F:     drivers/net/s2io*
 F:     Documentation/networking/vxge.txt
-F:     drivers/net/vxge/
+F:     drivers/net/ethernet/neterion/
 
 NETFILTER/IPTABLES/IPCHAINS
 P:     Rusty Russell
@@ -4511,11 +4514,12 @@ F:      include/linux/if_*
 F:     include/linux/*device.h
 
 NETXEN (1/10) GbE SUPPORT
-M:     Amit Kumar Salecha <amit.salecha@qlogic.com>
+M:     Sony Chacko <sony.chacko@qlogic.com>
+M:     Rajesh Borundia <rajesh.borundia@qlogic.com>
 L:     netdev@vger.kernel.org
 W:     http://www.qlogic.com
 S:     Supported
-F:     drivers/net/netxen/
+F:     drivers/net/ethernet/qlogic/netxen/
 
 NFS, SUNRPC, AND LOCKD CLIENTS
 M:     Trond Myklebust <Trond.Myklebust@netapp.com>
@@ -4536,7 +4540,7 @@ M:        Jan-Pascal van Best <janpascal@vanbest.org>
 M:     Andreas Mohr <andi@lisas.de>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/ni5010.*
+F:     drivers/net/ethernet/racal/ni5010.*
 
 NILFS2 FILESYSTEM
 M:     KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
@@ -4802,7 +4806,7 @@ PA SEMI ETHERNET DRIVER
 M:     Olof Johansson <olof@lixom.net>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/pasemi_mac.*
+F:     drivers/net/ethernet/pasemi/*
 
 PA SEMI SMBUS DRIVER
 M:     Olof Johansson <olof@lixom.net>
@@ -4949,7 +4953,7 @@ PCNET32 NETWORK DRIVER
 M:     Don Fry <pcnet32@frontier.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/pcnet32.c
+F:     drivers/net/ethernet/amd/pcnet32.c
 
 PCRYPT PARALLEL CRYPTO ENGINE
 M:     Steffen Klassert <steffen.klassert@secunet.com>
@@ -5024,6 +5028,7 @@ F:        drivers/input/serio/i8042-unicore32io.h
 F:     drivers/i2c/busses/i2c-puv3.c
 F:     drivers/video/fb-puv3.c
 F:     drivers/rtc/rtc-puv3.c
+F:     drivers/net/mac-puv3.c
 
 PMBUS HARDWARE MONITORING DRIVERS
 M:     Guenter Roeck <guenter.roeck@ericsson.com>
@@ -5143,7 +5148,7 @@ M:        Geoff Levand <geoff@infradead.org>
 L:     netdev@vger.kernel.org
 L:     cbe-oss-dev@lists.ozlabs.org
 S:     Maintained
-F:     drivers/net/ps3_gelic_net.*
+F:     drivers/net/ethernet/toshiba/ps3_gelic_net.*
 
 PS3 PLATFORM SUPPORT
 M:     Geoff Levand <geoff@infradead.org>
@@ -5261,23 +5266,24 @@ M:      linux-driver@qlogic.com
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     Documentation/networking/LICENSE.qla3xxx
-F:     drivers/net/qla3xxx.*
+F:     drivers/net/ethernet/qlogic/qla3xxx.*
 
 QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
-M:     Amit Kumar Salecha <amit.salecha@qlogic.com>
 M:     Anirban Chakraborty <anirban.chakraborty@qlogic.com>
+M:     Sony Chacko <sony.chacko@qlogic.com>
 M:     linux-driver@qlogic.com
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/qlcnic/
+F:     drivers/net/ethernet/qlogic/qlcnic/
 
 QLOGIC QLGE 10Gb ETHERNET DRIVER
+M:     Anirban Chakraborty <anirban.chakraborty@qlogic.com>
 M:     Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
 M:     Ron Mercer <ron.mercer@qlogic.com>
 M:     linux-driver@qlogic.com
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/qlge/
+F:     drivers/net/ethernet/qlogic/qlge/
 
 QNX4 FILESYSTEM
 M:     Anders Larsen <al@alarsen.net>
@@ -5359,7 +5365,7 @@ RDC R6040 FAST ETHERNET DRIVER
 M:     Florian Fainelli <florian@openwrt.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/r6040.c
+F:     drivers/net/ethernet/rdc/r6040.c
 
 RDS - RELIABLE DATAGRAM SOCKETS
 M:     Andy Grover <andy.grover@oracle.com>
@@ -5762,7 +5768,7 @@ M:        Ajit Khaparde <ajit.khaparde@emulex.com>
 L:     netdev@vger.kernel.org
 W:     http://www.emulex.com
 S:     Supported
-F:     drivers/net/benet/
+F:     drivers/net/ethernet/emulex/benet/
 
 SFC NETWORK DRIVER
 M:     Solarflare linux maintainers <linux-net-drivers@solarflare.com>
@@ -5770,7 +5776,7 @@ M:        Steve Hodgson <shodgson@solarflare.com>
 M:     Ben Hutchings <bhutchings@solarflare.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/sfc/
+F:     drivers/net/ethernet/sfc/
 
 SGI GRU DRIVER
 M:     Jack Steiner <steiner@sgi.com>
@@ -5836,14 +5842,14 @@ SIS 190 ETHERNET DRIVER
 M:     Francois Romieu <romieu@fr.zoreil.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/sis190.c
+F:     drivers/net/ethernet/sis/sis190.c
 
 SIS 900/7016 FAST ETHERNET DRIVER
 M:     Daniele Venzano <venza@brownhat.org>
 W:     http://www.brownhat.org/sis900.html
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/sis900.*
+F:     drivers/net/ethernet/sis/sis900.*
 
 SIS 96X I2C/SMBUS DRIVER
 M:     "Mark M. Hoffman" <mhoffman@lightlink.com>
@@ -5870,8 +5876,7 @@ SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
 M:     Stephen Hemminger <shemminger@linux-foundation.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/skge.*
-F:     drivers/net/sky2.*
+F:     drivers/net/ethernet/marvell/sk*
 
 SLAB ALLOCATOR
 M:     Christoph Lameter <cl@linux-foundation.org>
@@ -5885,7 +5890,7 @@ F:        mm/sl?b.c
 SMC91x ETHERNET DRIVER
 M:     Nicolas Pitre <nico@fluxnic.net>
 S:     Odd Fixes
-F:     drivers/net/smc91x.*
+F:     drivers/net/ethernet/smsc/smc91x.*
 
 SMM665 HARDWARE MONITOR DRIVER
 M:     Guenter Roeck <linux@roeck-us.net>
@@ -5920,13 +5925,13 @@ M:      Steve Glendinning <steve.glendinning@smsc.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     include/linux/smsc911x.h
-F:     drivers/net/smsc911x.*
+F:     drivers/net/ethernet/smsc/smsc911x.*
 
 SMSC9420 PCI ETHERNET DRIVER
 M:     Steve Glendinning <steve.glendinning@smsc.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/smsc9420.*
+F:     drivers/net/ethernet/smsc/smsc9420.*
 
 SN-IA64 (Itanium) SUB-PLATFORM
 M:     Jes Sorensen <jes@sgi.com>
@@ -5960,7 +5965,7 @@ SONIC NETWORK DRIVER
 M:     Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/sonic.*
+F:     drivers/net/ethernet/natsemi/sonic.*
 
 SONICS SILICON BACKPLANE DRIVER (SSB)
 M:     Michael Buesch <m@bues.ch>
@@ -6101,7 +6106,7 @@ M:        Jens Osterkamp <jens@de.ibm.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     Documentation/networking/spider_net.txt
-F:     drivers/net/spider_net*
+F:     drivers/net/ethernet/toshiba/spider_net*
 
 SPU FILE SYSTEM
 M:     Jeremy Kerr <jk@ozlabs.org>
@@ -6279,7 +6284,7 @@ F:        drivers/staging/xgifb/
 STARFIRE/DURALAN NETWORK DRIVER
 M:     Ion Badulescu <ionut@badula.org>
 S:     Odd Fixes
-F:     drivers/net/starfire*
+F:     drivers/net/ethernet/adaptec/starfire*
 
 SUN3/3X
 M:     Sam Creasey <sammy@sammy.net>
@@ -6288,6 +6293,7 @@ S:        Maintained
 F:     arch/m68k/kernel/*sun3*
 F:     arch/m68k/sun3*/
 F:     arch/m68k/include/asm/sun3*
+F:     drivers/net/ethernet/i825xx/sun3*
 
 SUPERH
 M:     Paul Mundt <lethal@linux-sh.org>
@@ -6376,7 +6382,7 @@ M:        Alexander Indenbaum <baum@tehutinetworks.net>
 M:     Andy Gospodarek <andy@greyhouse.net>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     drivers/net/tehuti*
+F:     drivers/net/ethernet/tehuti/*
 
 Telecom Clock Driver for MCPL0010
 M:     Mark Gross <mark.gross@intel.com>
@@ -6427,7 +6433,7 @@ W:        http://www.tilera.com/scm/
 S:     Supported
 F:     arch/tile/
 F:     drivers/tty/hvc/hvc_tile.c
-F:     drivers/net/tile/
+F:     drivers/net/ethernet/tile/
 F:     drivers/edac/tile_edac.c
 
 TLAN NETWORK DRIVER
@@ -6436,7 +6442,7 @@ L:        tlan-devel@lists.sourceforge.net (subscribers-only)
 W:     http://sourceforge.net/projects/tlan/
 S:     Maintained
 F:     Documentation/networking/tlan.txt
-F:     drivers/net/tlan.*
+F:     drivers/net/ethernet/ti/tlan.*
 
 TOMOYO SECURITY MODULE
 M:     Kentaro Takeda <takedakn@nttdata.co.jp>
@@ -6530,7 +6536,7 @@ TULIP NETWORK DRIVERS
 M:     Grant Grundler <grundler@parisc-linux.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/tulip/
+F:     drivers/net/ethernet/tulip/
 
 TUN/TAP driver
 M:     Maxim Krasnyansky <maxk@qualcomm.com>
@@ -6576,7 +6582,7 @@ W:        http://uclinux-h8.sourceforge.jp/
 S:     Supported
 F:     arch/h8300/
 F:     drivers/ide/ide-h8300.c
-F:     drivers/net/ne-h8300.c
+F:     drivers/net/ethernet/8390/ne-h8300.c
 
 UDF FILESYSTEM
 M:     Jan Kara <jack@suse.cz>
@@ -7004,7 +7010,7 @@ F:        include/linux/vhost.h
 VIA RHINE NETWORK DRIVER
 M:     Roger Luethi <rl@hellgate.ch>
 S:     Maintained
-F:     drivers/net/via-rhine.c
+F:     drivers/net/ethernet/via/via-rhine.c
 
 VIAPRO SMBUS DRIVER
 M:     Jean Delvare <khali@linux-fr.org>
@@ -7032,7 +7038,7 @@ VIA VELOCITY NETWORK DRIVER
 M:     Francois Romieu <romieu@fr.zoreil.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/via-velocity.*
+F:     drivers/net/ethernet/via/via-velocity.*
 
 VLAN (802.1Q)
 M:     Patrick McHardy <kaber@trash.net>
index 6f32f9c84a2ddde12a85826a4339f70c857ee2f0..7e5510202d3792a8822b40108becc50ba1d0fa0d 100644 (file)
@@ -79,7 +79,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
 #define TIF_UAC_SIGBUS         12
 #define TIF_MEMDIE             13      /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    14      /* restore signal mask in do_signal */
-#define TIF_FREEZE             16      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
@@ -87,7 +86,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 /* Work to do on interrupt/exception return.  */
 #define _TIF_WORK_MASK         (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
index 5ebc5d922ea14984e10ef8e10f47d414469efa7c..7a78e7e7783e051263fa184c63cc65220b80bf8b 100644 (file)
@@ -195,7 +195,8 @@ config VECTORS_BASE
          The base address of exception vectors.
 
 config ARM_PATCH_PHYS_VIRT
-       bool "Patch physical to virtual translations at runtime"
+       bool "Patch physical to virtual translations at runtime" if EMBEDDED
+       default y
        depends on !XIP_KERNEL && MMU
        depends on !ARCH_REALVIEW || !SPARSEMEM
        help
@@ -204,16 +205,12 @@ config ARM_PATCH_PHYS_VIRT
          kernel in system memory.
 
          This can only be used with non-XIP MMU kernels where the base
-         of physical memory is at a 16MB boundary, or theoretically 64K
-         for the MSM machine class.
+         of physical memory is at a 16MB boundary.
+
+         Only disable this option if you know that you do not require
+         this feature (eg, building a kernel for a single machine) and
+         you need to shrink the kernel to the minimal size.
 
-config ARM_PATCH_PHYS_VIRT_16BIT
-       def_bool y
-       depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
-       help
-         This option extends the physical to virtual translation patching
-         to allow physical memory down to a theoretical minimum of 64K
-         boundaries.
 
 source "init/Kconfig"
 
@@ -301,7 +298,6 @@ config ARCH_AT91
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
        select CLKDEV_LOOKUP
-       select ARM_PATCH_PHYS_VIRT if MMU
        help
          This enables support for systems based on the Atmel AT91RM9200,
          AT91SAM9 and AT91CAP9 processors.
@@ -1271,6 +1267,18 @@ config ARM_ERRATA_754327
          This workaround defines cpu_relax() as smp_mb(), preventing correctly
          written polling loops from denying visibility of updates to memory.
 
+config ARM_ERRATA_364296
+       bool "ARM errata: Possible cache data corruption with hit-under-miss enabled"
+       depends on CPU_V6 && !SMP
+       help
+         This options enables the workaround for the 364296 ARM1136
+         r0p2 erratum (possible cache data corruption with
+         hit-under-miss enabled). It sets the undocumented bit 31 in
+         the auxiliary control register and the FI bit in the control
+         register, thus disabling hit-under-miss without putting the
+         processor into full low interrupt latency mode. ARM11MPCore
+         is not affected.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1381,6 +1389,31 @@ config SMP_ON_UP
 
          If you don't know what to do here, say Y.
 
+config ARM_CPU_TOPOLOGY
+       bool "Support cpu topology definition"
+       depends on SMP && CPU_V7
+       default y
+       help
+         Support ARM cpu topology definition. The MPIDR register defines
+         affinity between processors which is then used to describe the cpu
+         topology of an ARM System.
+
+config SCHED_MC
+       bool "Multi-core scheduler support"
+       depends on ARM_CPU_TOPOLOGY
+       help
+         Multi-core scheduler support improves the CPU scheduler's decision
+         making when dealing with multi-core CPU chips at a cost of slightly
+         increased overhead in some places. If unsure say N here.
+
+config SCHED_SMT
+       bool "SMT scheduler support"
+       depends on ARM_CPU_TOPOLOGY
+       help
+         Improves the CPU scheduler's decision making when dealing with
+         MultiThreading at a cost of slightly increased overhead in some
+         places. If unsure say N here.
+
 config HAVE_ARM_SCU
        bool
        help
@@ -1819,7 +1852,7 @@ endchoice
 
 config XIP_KERNEL
        bool "Kernel Execute-In-Place from ROM"
-       depends on !ZBOOT_ROM
+       depends on !ZBOOT_ROM && !ARM_LPAE
        help
          Execute-In-Place allows the kernel to run from non-volatile storage
          directly addressable by the CPU, such as NOR flash. This saves RAM
index 70c424eaf7b0d84db6af6431279a835ba71094c2..5665c2a3b652cccb4e9c66125540fbe08259039f 100644 (file)
@@ -128,6 +128,9 @@ textofs-$(CONFIG_PM_H1940)      := 0x00108000
 ifeq ($(CONFIG_ARCH_SA1100),y)
 textofs-$(CONFIG_SA1111) := 0x00208000
 endif
+textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
+textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
+textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
index a1edfd5a129a653ba847b5fb310a88bacfecfc1d..176062ac7f07305014357372c42285ff07a09c68 100644 (file)
@@ -78,7 +78,16 @@ endif
 
 $(obj)/uImage: STARTADDR=$(LOADADDR)
 
+check_for_multiple_loadaddr = \
+if [ $(words $(LOADADDR)) -gt 1 ]; then \
+       echo 'multiple load addresses: $(LOADADDR)'; \
+       echo 'This is incompatible with uImages'; \
+       echo 'Specify LOADADDR on the commandline to build an uImage'; \
+       false; \
+fi
+
 $(obj)/uImage: $(obj)/zImage FORCE
+       @$(check_for_multiple_loadaddr)
        $(call if_changed,uimage)
        @echo '  Image $@ is ready'
 
index 0c74a6fab95278eee8cdbc077aa0800c40da428f..a53a333c255d650c9645ab3dcdd8096d5a7c1851 100644 (file)
@@ -139,8 +139,16 @@ bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
   ( echo "following symbols must have non local/private scope:" >&2; \
     echo "$$bad_syms" >&2; rm -f $@; false )
 
+check_for_multiple_zreladdr = \
+if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" == "" ]; then \
+       echo 'multiple zreladdrs: $(ZRELADDR)'; \
+       echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
+       false; \
+fi
+
 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
                $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
+       @$(check_for_multiple_zreladdr)
        $(call if_changed,ld)
        @$(check_for_bad_syms)
 
index e95a5989602ae3fcf54f56257ce35739593d5f86..716c7bac756a78a10258a657a0ed8c6bbf886bba 100644 (file)
@@ -551,6 +551,7 @@ __armv7_mmu_cache_on:
                mcrne   p15, 0, r3, c2, c0, 0   @ load page table pointer
                mcrne   p15, 0, r1, c3, c0, 0   @ load domain access control
 #endif
+               mcr     p15, 0, r0, c7, c5, 4   @ ISB
                mcr     p15, 0, r0, c1, c0, 0   @ load control register
                mrc     p15, 0, r0, c1, c0, 0   @ and read it back
                mov     r0, #0
index b6f61d9a5a1b5279bf8576267b5a788f9f1cfe40..672ae95db5c3177aedc1dfdb3825a490b31e9fc2 100644 (file)
@@ -82,7 +82,7 @@ asmlinkage void mmc_loader(unsigned char *buf, unsigned long len)
 
 
        /* Disable clock to MMC hardware block */
-       __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+       __raw_writel(__raw_readl(SMSTPCR3) | (1 << 12), SMSTPCR3);
 
        mmc_update_progress(MMC_PROGRESS_DONE);
 }
index d403a8b24d7f322ad8b53c58ce047a06dc2bc0f8..d279294f238116fa4fbd3c71931149528516b483 100644 (file)
@@ -85,7 +85,7 @@ asmlinkage void mmc_loader(unsigned short *buf, unsigned long len)
                goto err;
 
         /* Disable clock to SDHI1 hardware block */
-        __raw_writel(__raw_readl(SMSTPCR3) & (1 << 13), SMSTPCR3);
+        __raw_writel(__raw_readl(SMSTPCR3) | (1 << 13), SMSTPCR3);
 
        mmc_update_progress(MMC_PROGRESS_DONE);
 
index a07b0e763a805109c007161d46efd6df5f45d6b6..1cde34a080d7e688efbf019aae2e55f8e20895c2 100644 (file)
  */
 
 #include <linux/device.h>
+#include <linux/gpio.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <asm/gpio.h>
 #include <asm/hardware/scoop.h>
 
 /* PCMCIA to Scoop linkage
index da53ff3b4d708122668cf2a910ae0f72ce9f4746..cd40bb56e5686c58b5c2ad7beab4a2105842d897 100644 (file)
@@ -11,6 +11,7 @@ CONFIG_MACH_SMDKV310=y
 CONFIG_MACH_ARMLEX4210=y
 CONFIG_MACH_UNIVERSAL_C210=y
 CONFIG_MACH_NURI=y
+CONFIG_MACH_ORIGEN=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
index 6550db3aa5c7d41351e29e9f8a72a0a927a07cfa..960abceb8e14dd878fd7b5cf979a3c318021f0f4 100644 (file)
@@ -1,3 +1,20 @@
 include include/asm-generic/Kbuild.asm
 
 header-y += hwcap.h
+
+generic-y += auxvec.h
+generic-y += bitsperlong.h
+generic-y += cputime.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += ioctl.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += local.h
+generic-y += local64.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += resource.h
+generic-y += sections.h
+generic-y += siginfo.h
+generic-y += sizes.h
index 29035e86a59db0d4c46ab315a9350780dbfe2999..b6e65dedfd716db5e336451868af811e34a684dc 100644 (file)
 #define ALT_UP_B(label) b label
 #endif
 
+/*
+ * Instruction barrier
+ */
+       .macro  instr_sync
+#if __LINUX_ARM_ARCH__ >= 7
+       isb
+#elif __LINUX_ARM_ARCH__ == 6
+       mcr     p15, 0, r0, c7, c5, 4
+#endif
+       .endm
+
 /*
  * SMP data memory barrier
  */
diff --git a/arch/arm/include/asm/auxvec.h b/arch/arm/include/asm/auxvec.h
deleted file mode 100644 (file)
index c0536f6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __ASMARM_AUXVEC_H
-#define __ASMARM_AUXVEC_H
-
-#endif
diff --git a/arch/arm/include/asm/bitsperlong.h b/arch/arm/include/asm/bitsperlong.h
deleted file mode 100644 (file)
index 6dc0bb0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/bitsperlong.h>
diff --git a/arch/arm/include/asm/cputime.h b/arch/arm/include/asm/cputime.h
deleted file mode 100644 (file)
index 3a8002a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ARM_CPUTIME_H
-#define __ARM_CPUTIME_H
-
-#include <asm-generic/cputime.h>
-
-#endif /* __ARM_CPUTIME_H */
index cd4458f64171e5e40720b991e8df5ad72099b0c5..cb47d28cbe1f81c4cfb43de4d1f08dbcec9f0cf7 100644 (file)
@@ -8,6 +8,7 @@
 #define CPUID_CACHETYPE        1
 #define CPUID_TCM      2
 #define CPUID_TLBTYPE  3
+#define CPUID_MPIDR    5
 
 #define CPUID_EXT_PFR0 "c1, 0"
 #define CPUID_EXT_PFR1 "c1, 1"
@@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)
        return read_cpuid(CPUID_TCM);
 }
 
+static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
+{
+       return read_cpuid(CPUID_MPIDR);
+}
+
 /*
  * Intel's XScale3 core supports some v6 features (supersections, L2)
  * but advertises itself as v5 as it does not support the v6 ISA.  For
index 7a21d0bf7134d2ec16b8afeb87ea1c184ee2f717..28b7ee8d7398a29c0187d6d2de59d7168c8110e5 100644 (file)
@@ -32,7 +32,7 @@ static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
 
 static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
 {
-       return (void *)__bus_to_virt(addr);
+       return (void *)__bus_to_virt((unsigned long)addr);
 }
 
 static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
index 29f2610efc70775a7059f4b5f63e1cc175c78749..eaea14676d5732798433ad91cb25f05482b75147 100644 (file)
@@ -161,7 +161,6 @@ struct expansion_card {
 
        /* Private internal data */
        const char              *card_desc;     /* Card description             */
-       CONST unsigned int      podaddr;        /* Base Linux address for card  */
        CONST loader_t          loader;         /* loader program */
        u64                     dma_mask;
 };
diff --git a/arch/arm/include/asm/emergency-restart.h b/arch/arm/include/asm/emergency-restart.h
deleted file mode 100644 (file)
index 108d8c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-#include <asm-generic/emergency-restart.h>
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/arm/include/asm/errno.h b/arch/arm/include/asm/errno.h
deleted file mode 100644 (file)
index 6e60f06..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ARM_ERRNO_H
-#define _ARM_ERRNO_H
-
-#include <asm-generic/errno.h>
-
-#endif
index 166a7a3e28400db64062715a53bdb2f31d4e9df4..11ad0bfbb0ad67ca3c3865d25a216b22a13c10f5 100644 (file)
@@ -4,4 +4,23 @@
 /* not all ARM platforms necessarily support this API ... */
 #include <mach/gpio.h>
 
+#ifndef __ARM_GPIOLIB_COMPLEX
+/* Note: this may rely upon the value of ARCH_NR_GPIOS set in mach/gpio.h */
+#include <asm-generic/gpio.h>
+
+/* The trivial gpiolib dispatchers */
+#define gpio_get_value  __gpio_get_value
+#define gpio_set_value  __gpio_set_value
+#define gpio_cansleep   __gpio_cansleep
+#endif
+
+/*
+ * Provide a default gpio_to_irq() which should satisfy every case.
+ * However, some platforms want to do this differently, so allow them
+ * to override it.
+ */
+#ifndef gpio_to_irq
+#define gpio_to_irq    __gpio_to_irq
+#endif
+
 #endif /* _ARCH_ARM_GPIO_H */
index 16bd48031583da44b7c0f25c68027fd787dc3fe1..4a6004a86a12c6728c46c8da5120d329e8bb39c0 100644 (file)
@@ -47,6 +47,8 @@
 #define L2X0_CLEAN_INV_WAY             0x7FC
 #define L2X0_LOCKDOWN_WAY_D            0x900
 #define L2X0_LOCKDOWN_WAY_I            0x904
+#define L2X0_ADDR_FILTER_START         0xC00
+#define L2X0_ADDR_FILTER_END           0xC04
 #define L2X0_TEST_OPERATION            0xF00
 #define L2X0_LINE_DATA                 0xF10
 #define L2X0_LINE_TAG                  0xF30
 #define L2X0_CACHE_ID_PART_L310                (3 << 6)
 
 #define L2X0_AUX_CTRL_MASK                     0xc0000fff
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT    0
+#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK     0x7
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT    3
+#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK     (0x7 << 3)
+#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT                6
+#define L2X0_AUX_CTRL_TAG_LATENCY_MASK         (0x7 << 6)
+#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT      9
+#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK       (0x7 << 9)
 #define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT      16
 #define L2X0_AUX_CTRL_WAY_SIZE_SHIFT           17
-#define L2X0_AUX_CTRL_WAY_SIZE_MASK            (0x3 << 17)
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK            (0x7 << 17)
 #define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT     22
 #define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT                26
 #define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT                27
 #define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT     29
 #define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT                30
 
+#define L2X0_LATENCY_CTRL_SETUP_SHIFT  0
+#define L2X0_LATENCY_CTRL_RD_SHIFT     4
+#define L2X0_LATENCY_CTRL_WR_SHIFT     8
+
+#define L2X0_ADDR_FILTER_EN            1
+
 #ifndef __ASSEMBLY__
 extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask);
 #endif
 
 #endif
index b69d972b1f7d21987c2ca86c7119cb101767f75d..9eda7dc92ad8d79c2214ac1ba472fa9e29c2357f 100644 (file)
@@ -28,6 +28,8 @@
 #include <mach/hardware.h>
 #include <asm-generic/gpio.h>
 
+#define __ARM_GPIOLIB_COMPLEX
+
 #define IOP3XX_N_GPIOS 8
 
 static inline int gpio_get_value(unsigned gpio)
index d66605dea55a217fc10df9fda8a94f3e5b1eb9ea..ffb089d46a179a05089e84a71fa5d13036a3c749 100644 (file)
@@ -109,6 +109,27 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
  */
 #include <mach/io.h>
 
+/*
+ * This is the limit of PC card/PCI/ISA IO space, which is by default
+ * 64K if we have PC card, PCI or ISA support.  Otherwise, default to
+ * zero to prevent ISA/PCI drivers claiming IO space (and potentially
+ * oopsing.)
+ *
+ * Only set this larger if you really need inb() et.al. to operate over
+ * a larger address space.  Note that SOC_COMMON ioremaps each sockets
+ * IO space area, and so inb() et.al. must be defined to operate as per
+ * readb() et.al. on such platforms.
+ */
+#ifndef IO_SPACE_LIMIT
+#if defined(CONFIG_PCMCIA_SOC_COMMON) || defined(CONFIG_PCMCIA_SOC_COMMON_MODULE)
+#define IO_SPACE_LIMIT ((resource_size_t)0xffffffff)
+#elif defined(CONFIG_PCI) || defined(CONFIG_ISA) || defined(CONFIG_PCCARD)
+#define IO_SPACE_LIMIT ((resource_size_t)0xffff)
+#else
+#define IO_SPACE_LIMIT ((resource_size_t)0)
+#endif
+#endif
+
 /*
  *  IO port access primitives
  *  -------------------------
diff --git a/arch/arm/include/asm/ioctl.h b/arch/arm/include/asm/ioctl.h
deleted file mode 100644 (file)
index b279fe0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ioctl.h>
diff --git a/arch/arm/include/asm/irq_regs.h b/arch/arm/include/asm/irq_regs.h
deleted file mode 100644 (file)
index 3dd9c0b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/irq_regs.h>
diff --git a/arch/arm/include/asm/kdebug.h b/arch/arm/include/asm/kdebug.h
deleted file mode 100644 (file)
index 6ece1b0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kdebug.h>
diff --git a/arch/arm/include/asm/local.h b/arch/arm/include/asm/local.h
deleted file mode 100644 (file)
index c11c530..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/local.h>
diff --git a/arch/arm/include/asm/local64.h b/arch/arm/include/asm/local64.h
deleted file mode 100644 (file)
index 36c93b5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/local64.h>
index b8de516e600e855e4ece64e3a654a1d451626603..441fc4fe82630b0290d63a73528262bdb4c16c0c 100644 (file)
  * so that all we need to do is modify the 8-bit constant field.
  */
 #define __PV_BITS_31_24        0x81000000
-#define __PV_BITS_23_16        0x00810000
 
 extern unsigned long __pv_phys_offset;
 #define PHYS_OFFSET __pv_phys_offset
@@ -178,9 +177,6 @@ static inline unsigned long __virt_to_phys(unsigned long x)
 {
        unsigned long t;
        __pv_stub(x, t, "add", __PV_BITS_31_24);
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-       __pv_stub(t, t, "add", __PV_BITS_23_16);
-#endif
        return t;
 }
 
@@ -188,9 +184,6 @@ static inline unsigned long __phys_to_virt(unsigned long x)
 {
        unsigned long t;
        __pv_stub(x, t, "sub", __PV_BITS_31_24);
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-       __pv_stub(t, t, "sub", __PV_BITS_23_16);
-#endif
        return t;
 }
 #else
index 543b44916d2c59c76abe930c5ea23116d77f77a1..6c6809f982f12557a6fa23a711f095c9a122fdb0 100644 (file)
@@ -31,11 +31,7 @@ struct mod_arch_specific {
 
 /* Add __virt_to_phys patching state as well */
 #ifdef CONFIG_ARM_PATCH_PHYS_VIRT
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
-#else
 #define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
-#endif
 #else
 #define MODULE_ARCH_VERMAGIC_P2V ""
 #endif
index ac75d08488892f22dace530691de9a001d884f48..97b440c25c5855977481a40ba18977f1f988dd09 100644 (file)
@@ -151,47 +151,11 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
 #define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
 
-typedef unsigned long pteval_t;
-
-#undef STRICT_MM_TYPECHECKS
-
-#ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { pteval_t pte; } pte_t;
-typedef struct { unsigned long pmd; } pmd_t;
-typedef struct { unsigned long pgd[2]; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-
-#define pte_val(x)      ((x).pte)
-#define pmd_val(x)      ((x).pmd)
-#define pgd_val(x)     ((x).pgd[0])
-#define pgprot_val(x)   ((x).pgprot)
-
-#define __pte(x)        ((pte_t) { (x) } )
-#define __pmd(x)        ((pmd_t) { (x) } )
-#define __pgprot(x)     ((pgprot_t) { (x) } )
-
+#ifdef CONFIG_ARM_LPAE
+#include <asm/pgtable-3level-types.h>
 #else
-/*
- * .. while these make it easier on the compiler
- */
-typedef pteval_t pte_t;
-typedef unsigned long pmd_t;
-typedef unsigned long pgd_t[2];
-typedef unsigned long pgprot_t;
-
-#define pte_val(x)      (x)
-#define pmd_val(x)      (x)
-#define pgd_val(x)     ((x)[0])
-#define pgprot_val(x)   (x)
-
-#define __pte(x)        (x)
-#define __pmd(x)        (x)
-#define __pgprot(x)     (x)
-
-#endif /* STRICT_MM_TYPECHECKS */
+#include <asm/pgtable-2level-types.h>
+#endif
 
 #endif /* CONFIG_MMU */
 
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
deleted file mode 100644 (file)
index b4e32d8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ARM_PERCPU
-#define __ARM_PERCPU
-
-#include <asm-generic/percpu.h>
-
-#endif
index 22de005f159ce7599166d749fdf8cfdea0905512..943504f53f579e58c878165c595d5a110dae00ed 100644 (file)
 #define _PAGE_USER_TABLE       (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
 #define _PAGE_KERNEL_TABLE     (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
 
+#ifdef CONFIG_ARM_LPAE
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+       return (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
+}
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+       BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
+       free_page((unsigned long)pmd);
+}
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+       set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
+}
+
+#else  /* !CONFIG_ARM_LPAE */
+
 /*
  * Since we have only two-level page tables, these are trivial
  */
 #define pmd_alloc_one(mm,addr)         ({ BUG(); ((pmd_t *)2); })
 #define pmd_free(mm, pmd)              do { } while (0)
-#define pgd_populate(mm,pmd,pte)       BUG()
+#define pud_populate(mm,pmd,pte)       BUG()
+
+#endif /* CONFIG_ARM_LPAE */
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
 extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
@@ -105,11 +127,13 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 }
 
 static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
-       unsigned long prot)
+                                 pmdval_t prot)
 {
-       unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
+       pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot;
        pmdp[0] = __pmd(pmdval);
+#ifndef CONFIG_ARM_LPAE
        pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+#endif
        flush_pmd_entry(pmdp);
 }
 
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
new file mode 100644 (file)
index 0000000..5cfba15
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *  arch/arm/include/asm/pgtable-2level-hwdef.h
+ *
+ *  Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASM_PGTABLE_2LEVEL_HWDEF_H
+#define _ASM_PGTABLE_2LEVEL_HWDEF_H
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ *   - common
+ */
+#define PMD_TYPE_MASK          (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_FAULT         (_AT(pmdval_t, 0) << 0)
+#define PMD_TYPE_TABLE         (_AT(pmdval_t, 1) << 0)
+#define PMD_TYPE_SECT          (_AT(pmdval_t, 2) << 0)
+#define PMD_BIT4               (_AT(pmdval_t, 1) << 4)
+#define PMD_DOMAIN(x)          (_AT(pmdval_t, (x)) << 5)
+#define PMD_PROTECTION         (_AT(pmdval_t, 1) << 9)         /* v5 */
+/*
+ *   - section
+ */
+#define PMD_SECT_BUFFERABLE    (_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_CACHEABLE     (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_XN            (_AT(pmdval_t, 1) << 4)         /* v6 */
+#define PMD_SECT_AP_WRITE      (_AT(pmdval_t, 1) << 10)
+#define PMD_SECT_AP_READ       (_AT(pmdval_t, 1) << 11)
+#define PMD_SECT_TEX(x)                (_AT(pmdval_t, (x)) << 12)      /* v5 */
+#define PMD_SECT_APX           (_AT(pmdval_t, 1) << 15)        /* v6 */
+#define PMD_SECT_S             (_AT(pmdval_t, 1) << 16)        /* v6 */
+#define PMD_SECT_nG            (_AT(pmdval_t, 1) << 17)        /* v6 */
+#define PMD_SECT_SUPER         (_AT(pmdval_t, 1) << 18)        /* v6 */
+#define PMD_SECT_AF            (_AT(pmdval_t, 0))
+
+#define PMD_SECT_UNCACHED      (_AT(pmdval_t, 0))
+#define PMD_SECT_BUFFERED      (PMD_SECT_BUFFERABLE)
+#define PMD_SECT_WT            (PMD_SECT_CACHEABLE)
+#define PMD_SECT_WB            (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_MINICACHE     (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
+#define PMD_SECT_WBWA          (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
+
+/*
+ *   - coarse table (not used)
+ */
+
+/*
+ * + Level 2 descriptor (PTE)
+ *   - common
+ */
+#define PTE_TYPE_MASK          (_AT(pteval_t, 3) << 0)
+#define PTE_TYPE_FAULT         (_AT(pteval_t, 0) << 0)
+#define PTE_TYPE_LARGE         (_AT(pteval_t, 1) << 0)
+#define PTE_TYPE_SMALL         (_AT(pteval_t, 2) << 0)
+#define PTE_TYPE_EXT           (_AT(pteval_t, 3) << 0)         /* v5 */
+#define PTE_BUFFERABLE         (_AT(pteval_t, 1) << 2)
+#define PTE_CACHEABLE          (_AT(pteval_t, 1) << 3)
+
+/*
+ *   - extended small page/tiny page
+ */
+#define PTE_EXT_XN             (_AT(pteval_t, 1) << 0)         /* v6 */
+#define PTE_EXT_AP_MASK                (_AT(pteval_t, 3) << 4)
+#define PTE_EXT_AP0            (_AT(pteval_t, 1) << 4)
+#define PTE_EXT_AP1            (_AT(pteval_t, 2) << 4)
+#define PTE_EXT_AP_UNO_SRO     (_AT(pteval_t, 0) << 4)
+#define PTE_EXT_AP_UNO_SRW     (PTE_EXT_AP0)
+#define PTE_EXT_AP_URO_SRW     (PTE_EXT_AP1)
+#define PTE_EXT_AP_URW_SRW     (PTE_EXT_AP1|PTE_EXT_AP0)
+#define PTE_EXT_TEX(x)         (_AT(pteval_t, (x)) << 6)       /* v5 */
+#define PTE_EXT_APX            (_AT(pteval_t, 1) << 9)         /* v6 */
+#define PTE_EXT_COHERENT       (_AT(pteval_t, 1) << 9)         /* XScale3 */
+#define PTE_EXT_SHARED         (_AT(pteval_t, 1) << 10)        /* v6 */
+#define PTE_EXT_NG             (_AT(pteval_t, 1) << 11)        /* v6 */
+
+/*
+ *   - small page
+ */
+#define PTE_SMALL_AP_MASK      (_AT(pteval_t, 0xff) << 4)
+#define PTE_SMALL_AP_UNO_SRO   (_AT(pteval_t, 0x00) << 4)
+#define PTE_SMALL_AP_UNO_SRW   (_AT(pteval_t, 0x55) << 4)
+#define PTE_SMALL_AP_URO_SRW   (_AT(pteval_t, 0xaa) << 4)
+#define PTE_SMALL_AP_URW_SRW   (_AT(pteval_t, 0xff) << 4)
+
+#define PHYS_MASK              (~0UL)
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-2level-types.h b/arch/arm/include/asm/pgtable-2level-types.h
new file mode 100644 (file)
index 0000000..66cb5b0
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/include/asm/pgtable-2level-types.h
+ *
+ * Copyright (C) 1995-2003 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _ASM_PGTABLE_2LEVEL_TYPES_H
+#define _ASM_PGTABLE_2LEVEL_TYPES_H
+
+#include <asm/types.h>
+
+typedef u32 pteval_t;
+typedef u32 pmdval_t;
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { pteval_t pte; } pte_t;
+typedef struct { pmdval_t pmd; } pmd_t;
+typedef struct { pmdval_t pgd[2]; } pgd_t;
+typedef struct { pteval_t pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)     ((x).pgd[0])
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef pteval_t pte_t;
+typedef pmdval_t pmd_t;
+typedef pmdval_t pgd_t[2];
+typedef pteval_t pgprot_t;
+
+#define pte_val(x)      (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)     ((x)[0])
+#define pgprot_val(x)   (x)
+
+#define __pte(x)        (x)
+#define __pmd(x)        (x)
+#define __pgprot(x)     (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* _ASM_PGTABLE_2LEVEL_TYPES_H */
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
new file mode 100644 (file)
index 0000000..470457e
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ *  arch/arm/include/asm/pgtable-2level.h
+ *
+ *  Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASM_PGTABLE_2LEVEL_H
+#define _ASM_PGTABLE_2LEVEL_H
+
+/*
+ * Hardware-wise, we have a two level page table structure, where the first
+ * level has 4096 entries, and the second level has 256 entries.  Each entry
+ * is one 32-bit word.  Most of the bits in the second level entry are used
+ * by hardware, and there aren't any "accessed" and "dirty" bits.
+ *
+ * Linux on the other hand has a three level page table structure, which can
+ * be wrapped to fit a two level page table structure easily - using the PGD
+ * and PTE only.  However, Linux also expects one "PTE" table per page, and
+ * at least a "dirty" bit.
+ *
+ * Therefore, we tweak the implementation slightly - we tell Linux that we
+ * have 2048 entries in the first level, each of which is 8 bytes (iow, two
+ * hardware pointers to the second level.)  The second level contains two
+ * hardware PTE tables arranged contiguously, preceded by Linux versions
+ * which contain the state information Linux needs.  We, therefore, end up
+ * with 512 entries in the "PTE" level.
+ *
+ * This leads to the page tables having the following layout:
+ *
+ *    pgd             pte
+ * |        |
+ * +--------+
+ * |        |       +------------+ +0
+ * +- - - - +       | Linux pt 0 |
+ * |        |       +------------+ +1024
+ * +--------+ +0    | Linux pt 1 |
+ * |        |-----> +------------+ +2048
+ * +- - - - + +4    |  h/w pt 0  |
+ * |        |-----> +------------+ +3072
+ * +--------+ +8    |  h/w pt 1  |
+ * |        |       +------------+ +4096
+ *
+ * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
+ * PTE_xxx for definitions of bits appearing in the "h/w pt".
+ *
+ * PMD_xxx definitions refer to bits in the first level page table.
+ *
+ * The "dirty" bit is emulated by only granting hardware write permission
+ * iff the page is marked "writable" and "dirty" in the Linux PTE.  This
+ * means that a write to a clean page will cause a permission fault, and
+ * the Linux MM layer will mark the page dirty via handle_pte_fault().
+ * For the hardware to notice the permission change, the TLB entry must
+ * be flushed, and ptep_set_access_flags() does that for us.
+ *
+ * The "accessed" or "young" bit is emulated by a similar method; we only
+ * allow accesses to the page if the "young" bit is set.  Accesses to the
+ * page will cause a fault, and handle_pte_fault() will set the young bit
+ * for us as long as the page is marked present in the corresponding Linux
+ * PTE entry.  Again, ptep_set_access_flags() will ensure that the TLB is
+ * up to date.
+ *
+ * However, when the "young" bit is cleared, we deny access to the page
+ * by clearing the hardware PTE.  Currently Linux does not flush the TLB
+ * for us in this case, which means the TLB will retain the transation
+ * until either the TLB entry is evicted under pressure, or a context
+ * switch which changes the user space mapping occurs.
+ */
+#define PTRS_PER_PTE           512
+#define PTRS_PER_PMD           1
+#define PTRS_PER_PGD           2048
+
+#define PTE_HWTABLE_PTRS       (PTRS_PER_PTE)
+#define PTE_HWTABLE_OFF                (PTE_HWTABLE_PTRS * sizeof(pte_t))
+#define PTE_HWTABLE_SIZE       (PTRS_PER_PTE * sizeof(u32))
+
+/*
+ * PMD_SHIFT determines the size of the area a second-level page table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PMD_SHIFT              21
+#define PGDIR_SHIFT            21
+
+#define PMD_SIZE               (1UL << PMD_SHIFT)
+#define PMD_MASK               (~(PMD_SIZE-1))
+#define PGDIR_SIZE             (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK             (~(PGDIR_SIZE-1))
+
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT          20
+#define SECTION_SIZE           (1UL << SECTION_SHIFT)
+#define SECTION_MASK           (~(SECTION_SIZE-1))
+
+/*
+ * ARMv6 supersection address mask and size definitions.
+ */
+#define SUPERSECTION_SHIFT     24
+#define SUPERSECTION_SIZE      (1UL << SUPERSECTION_SHIFT)
+#define SUPERSECTION_MASK      (~(SUPERSECTION_SIZE-1))
+
+#define USER_PTRS_PER_PGD      (TASK_SIZE / PGDIR_SIZE)
+
+/*
+ * "Linux" PTE definitions.
+ *
+ * We keep two sets of PTEs - the hardware and the linux version.
+ * This allows greater flexibility in the way we map the Linux bits
+ * onto the hardware tables, and allows us to have YOUNG and DIRTY
+ * bits.
+ *
+ * The PTE table pointer refers to the hardware entries; the "Linux"
+ * entries are stored 1024 bytes below.
+ */
+#define L_PTE_PRESENT          (_AT(pteval_t, 1) << 0)
+#define L_PTE_YOUNG            (_AT(pteval_t, 1) << 1)
+#define L_PTE_FILE             (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
+#define L_PTE_DIRTY            (_AT(pteval_t, 1) << 6)
+#define L_PTE_RDONLY           (_AT(pteval_t, 1) << 7)
+#define L_PTE_USER             (_AT(pteval_t, 1) << 8)
+#define L_PTE_XN               (_AT(pteval_t, 1) << 9)
+#define L_PTE_SHARED           (_AT(pteval_t, 1) << 10)        /* shared(v6), coherent(xsc3) */
+
+/*
+ * These are the memory types, defined to be compatible with
+ * pre-ARMv6 CPUs cacheable and bufferable bits:   XXCB
+ */
+#define L_PTE_MT_UNCACHED      (_AT(pteval_t, 0x00) << 2)      /* 0000 */
+#define L_PTE_MT_BUFFERABLE    (_AT(pteval_t, 0x01) << 2)      /* 0001 */
+#define L_PTE_MT_WRITETHROUGH  (_AT(pteval_t, 0x02) << 2)      /* 0010 */
+#define L_PTE_MT_WRITEBACK     (_AT(pteval_t, 0x03) << 2)      /* 0011 */
+#define L_PTE_MT_MINICACHE     (_AT(pteval_t, 0x06) << 2)      /* 0110 (sa1100, xscale) */
+#define L_PTE_MT_WRITEALLOC    (_AT(pteval_t, 0x07) << 2)      /* 0111 */
+#define L_PTE_MT_DEV_SHARED    (_AT(pteval_t, 0x04) << 2)      /* 0100 */
+#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2)      /* 1100 */
+#define L_PTE_MT_DEV_WC                (_AT(pteval_t, 0x09) << 2)      /* 1001 */
+#define L_PTE_MT_DEV_CACHED    (_AT(pteval_t, 0x0b) << 2)      /* 1011 */
+#define L_PTE_MT_MASK          (_AT(pteval_t, 0x0f) << 2)
+
+#endif /* _ASM_PGTABLE_2LEVEL_H */
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
new file mode 100644 (file)
index 0000000..7c238a3
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/include/asm/pgtable-3level-hwdef.h
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _ASM_PGTABLE_3LEVEL_HWDEF_H
+#define _ASM_PGTABLE_3LEVEL_HWDEF_H
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1/2 descriptor
+ *   - common
+ */
+#define PMD_TYPE_MASK          (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_FAULT         (_AT(pmdval_t, 0) << 0)
+#define PMD_TYPE_TABLE         (_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_SECT          (_AT(pmdval_t, 1) << 0)
+#define PMD_BIT4               (_AT(pmdval_t, 0))
+#define PMD_DOMAIN(x)          (_AT(pmdval_t, 0))
+
+/*
+ *   - section
+ */
+#define PMD_SECT_BUFFERABLE    (_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_CACHEABLE     (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_S             (_AT(pmdval_t, 3) << 8)
+#define PMD_SECT_AF            (_AT(pmdval_t, 1) << 10)
+#define PMD_SECT_nG            (_AT(pmdval_t, 1) << 11)
+#ifdef __ASSEMBLY__
+/* avoid 'shift count out of range' warning */
+#define PMD_SECT_XN            (0)
+#else
+#define PMD_SECT_XN            ((pmdval_t)1 << 54)
+#endif
+#define PMD_SECT_AP_WRITE      (_AT(pmdval_t, 0))
+#define PMD_SECT_AP_READ       (_AT(pmdval_t, 0))
+#define PMD_SECT_TEX(x)                (_AT(pmdval_t, 0))
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define PMD_SECT_UNCACHED      (_AT(pmdval_t, 0) << 2) /* strongly ordered */
+#define PMD_SECT_BUFFERED      (_AT(pmdval_t, 1) << 2) /* normal non-cacheable */
+#define PMD_SECT_WT            (_AT(pmdval_t, 2) << 2) /* normal inner write-through */
+#define PMD_SECT_WB            (_AT(pmdval_t, 3) << 2) /* normal inner write-back */
+#define PMD_SECT_WBWA          (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */
+
+/*
+ * + Level 3 descriptor (PTE)
+ */
+#define PTE_TYPE_MASK          (_AT(pteval_t, 3) << 0)
+#define PTE_TYPE_FAULT         (_AT(pteval_t, 0) << 0)
+#define PTE_TYPE_PAGE          (_AT(pteval_t, 3) << 0)
+#define PTE_BUFFERABLE         (_AT(pteval_t, 1) << 2)         /* AttrIndx[0] */
+#define PTE_CACHEABLE          (_AT(pteval_t, 1) << 3)         /* AttrIndx[1] */
+#define PTE_EXT_SHARED         (_AT(pteval_t, 3) << 8)         /* SH[1:0], inner shareable */
+#define PTE_EXT_AF             (_AT(pteval_t, 1) << 10)        /* Access Flag */
+#define PTE_EXT_NG             (_AT(pteval_t, 1) << 11)        /* nG */
+#define PTE_EXT_XN             (_AT(pteval_t, 1) << 54)        /* XN */
+
+/*
+ * 40-bit physical address supported.
+ */
+#define PHYS_MASK_SHIFT                (40)
+#define PHYS_MASK              ((1ULL << PHYS_MASK_SHIFT) - 1)
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-3level-types.h b/arch/arm/include/asm/pgtable-3level-types.h
new file mode 100644 (file)
index 0000000..921aa30
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/include/asm/pgtable-3level-types.h
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _ASM_PGTABLE_3LEVEL_TYPES_H
+#define _ASM_PGTABLE_3LEVEL_TYPES_H
+
+#include <asm/types.h>
+
+typedef u64 pteval_t;
+typedef u64 pmdval_t;
+typedef u64 pgdval_t;
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { pteval_t pte; } pte_t;
+typedef struct { pmdval_t pmd; } pmd_t;
+typedef struct { pgdval_t pgd; } pgd_t;
+typedef struct { pteval_t pgprot; } pgprot_t;
+
+#define pte_val(x)      ((x).pte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)     ((x).pgd)
+#define pgprot_val(x)   ((x).pgprot)
+
+#define __pte(x)        ((pte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)       ((pgd_t) { (x) } )
+#define __pgprot(x)     ((pgprot_t) { (x) } )
+
+#else  /* !STRICT_MM_TYPECHECKS */
+
+typedef pteval_t pte_t;
+typedef pmdval_t pmd_t;
+typedef pgdval_t pgd_t;
+typedef pteval_t pgprot_t;
+
+#define pte_val(x)     (x)
+#define pmd_val(x)     (x)
+#define pgd_val(x)     (x)
+#define pgprot_val(x)  (x)
+
+#define __pte(x)       (x)
+#define __pmd(x)       (x)
+#define __pgd(x)       (x)
+#define __pgprot(x)    (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* _ASM_PGTABLE_3LEVEL_TYPES_H */
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
new file mode 100644 (file)
index 0000000..a6261f5
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * arch/arm/include/asm/pgtable-3level.h
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _ASM_PGTABLE_3LEVEL_H
+#define _ASM_PGTABLE_3LEVEL_H
+
+/*
+ * With LPAE, there are 3 levels of page tables. Each level has 512 entries of
+ * 8 bytes each, occupying a 4K page. The first level table covers a range of
+ * 512GB, each entry representing 1GB. Since we are limited to 4GB input
+ * address range, only 4 entries in the PGD are used.
+ *
+ * There are enough spare bits in a page table entry for the kernel specific
+ * state.
+ */
+#define PTRS_PER_PTE           512
+#define PTRS_PER_PMD           512
+#define PTRS_PER_PGD           4
+
+#define PTE_HWTABLE_PTRS       (PTRS_PER_PTE)
+#define PTE_HWTABLE_OFF                (0)
+#define PTE_HWTABLE_SIZE       (PTRS_PER_PTE * sizeof(u64))
+
+/*
+ * PGDIR_SHIFT determines the size a top-level page table entry can map.
+ */
+#define PGDIR_SHIFT            30
+
+/*
+ * PMD_SHIFT determines the size a middle-level page table entry can map.
+ */
+#define PMD_SHIFT              21
+
+#define PMD_SIZE               (1UL << PMD_SHIFT)
+#define PMD_MASK               (~(PMD_SIZE-1))
+#define PGDIR_SIZE             (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK             (~(PGDIR_SIZE-1))
+
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT          21
+#define SECTION_SIZE           (1UL << SECTION_SHIFT)
+#define SECTION_MASK           (~(SECTION_SIZE-1))
+
+#define USER_PTRS_PER_PGD      (PAGE_OFFSET / PGDIR_SIZE)
+
+/*
+ * "Linux" PTE definitions for LPAE.
+ *
+ * These bits overlap with the hardware bits but the naming is preserved for
+ * consistency with the classic page table format.
+ */
+#define L_PTE_PRESENT          (_AT(pteval_t, 3) << 0)         /* Valid */
+#define L_PTE_FILE             (_AT(pteval_t, 1) << 2)         /* only when !PRESENT */
+#define L_PTE_BUFFERABLE       (_AT(pteval_t, 1) << 2)         /* AttrIndx[0] */
+#define L_PTE_CACHEABLE                (_AT(pteval_t, 1) << 3)         /* AttrIndx[1] */
+#define L_PTE_USER             (_AT(pteval_t, 1) << 6)         /* AP[1] */
+#define L_PTE_RDONLY           (_AT(pteval_t, 1) << 7)         /* AP[2] */
+#define L_PTE_SHARED           (_AT(pteval_t, 3) << 8)         /* SH[1:0], inner shareable */
+#define L_PTE_YOUNG            (_AT(pteval_t, 1) << 10)        /* AF */
+#define L_PTE_XN               (_AT(pteval_t, 1) << 54)        /* XN */
+#define L_PTE_DIRTY            (_AT(pteval_t, 1) << 55)        /* unused */
+#define L_PTE_SPECIAL          (_AT(pteval_t, 1) << 56)        /* unused */
+
+/*
+ * To be used in assembly code with the upper page attributes.
+ */
+#define L_PTE_XN_HIGH          (1 << (54 - 32))
+#define L_PTE_DIRTY_HIGH       (1 << (55 - 32))
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define L_PTE_MT_UNCACHED      (_AT(pteval_t, 0) << 2) /* strongly ordered */
+#define L_PTE_MT_BUFFERABLE    (_AT(pteval_t, 1) << 2) /* normal non-cacheable */
+#define L_PTE_MT_WRITETHROUGH  (_AT(pteval_t, 2) << 2) /* normal inner write-through */
+#define L_PTE_MT_WRITEBACK     (_AT(pteval_t, 3) << 2) /* normal inner write-back */
+#define L_PTE_MT_WRITEALLOC    (_AT(pteval_t, 7) << 2) /* normal inner write-alloc */
+#define L_PTE_MT_DEV_SHARED    (_AT(pteval_t, 4) << 2) /* device */
+#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 4) << 2) /* device */
+#define L_PTE_MT_DEV_WC                (_AT(pteval_t, 1) << 2) /* normal non-cacheable */
+#define L_PTE_MT_DEV_CACHED    (_AT(pteval_t, 3) << 2) /* normal inner write-back */
+#define L_PTE_MT_MASK          (_AT(pteval_t, 7) << 2)
+
+/*
+ * Software PGD flags.
+ */
+#define L_PGD_SWAPPER          (_AT(pgdval_t, 1) << 55)        /* swapper_pg_dir entry */
+
+#endif /* _ASM_PGTABLE_3LEVEL_H */
index fd1521d5cb9dd97e07e8f5a54b7994295294a7d3..8426229ba29282582a20bf65a2c08253f914edf3 100644 (file)
 #ifndef _ASMARM_PGTABLE_HWDEF_H
 #define _ASMARM_PGTABLE_HWDEF_H
 
-/*
- * Hardware page table definitions.
- *
- * + Level 1 descriptor (PMD)
- *   - common
- */
-#define PMD_TYPE_MASK          (3 << 0)
-#define PMD_TYPE_FAULT         (0 << 0)
-#define PMD_TYPE_TABLE         (1 << 0)
-#define PMD_TYPE_SECT          (2 << 0)
-#define PMD_BIT4               (1 << 4)
-#define PMD_DOMAIN(x)          ((x) << 5)
-#define PMD_PROTECTION         (1 << 9)        /* v5 */
-/*
- *   - section
- */
-#define PMD_SECT_BUFFERABLE    (1 << 2)
-#define PMD_SECT_CACHEABLE     (1 << 3)
-#define PMD_SECT_XN            (1 << 4)        /* v6 */
-#define PMD_SECT_AP_WRITE      (1 << 10)
-#define PMD_SECT_AP_READ       (1 << 11)
-#define PMD_SECT_TEX(x)                ((x) << 12)     /* v5 */
-#define PMD_SECT_APX           (1 << 15)       /* v6 */
-#define PMD_SECT_S             (1 << 16)       /* v6 */
-#define PMD_SECT_nG            (1 << 17)       /* v6 */
-#define PMD_SECT_SUPER         (1 << 18)       /* v6 */
-
-#define PMD_SECT_UNCACHED      (0)
-#define PMD_SECT_BUFFERED      (PMD_SECT_BUFFERABLE)
-#define PMD_SECT_WT            (PMD_SECT_CACHEABLE)
-#define PMD_SECT_WB            (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
-#define PMD_SECT_MINICACHE     (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
-#define PMD_SECT_WBWA          (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
-#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
-
-/*
- *   - coarse table (not used)
- */
-
-/*
- * + Level 2 descriptor (PTE)
- *   - common
- */
-#define PTE_TYPE_MASK          (3 << 0)
-#define PTE_TYPE_FAULT         (0 << 0)
-#define PTE_TYPE_LARGE         (1 << 0)
-#define PTE_TYPE_SMALL         (2 << 0)
-#define PTE_TYPE_EXT           (3 << 0)        /* v5 */
-#define PTE_BUFFERABLE         (1 << 2)
-#define PTE_CACHEABLE          (1 << 3)
-
-/*
- *   - extended small page/tiny page
- */
-#define PTE_EXT_XN             (1 << 0)        /* v6 */
-#define PTE_EXT_AP_MASK                (3 << 4)
-#define PTE_EXT_AP0            (1 << 4)
-#define PTE_EXT_AP1            (2 << 4)
-#define PTE_EXT_AP_UNO_SRO     (0 << 4)
-#define PTE_EXT_AP_UNO_SRW     (PTE_EXT_AP0)
-#define PTE_EXT_AP_URO_SRW     (PTE_EXT_AP1)
-#define PTE_EXT_AP_URW_SRW     (PTE_EXT_AP1|PTE_EXT_AP0)
-#define PTE_EXT_TEX(x)         ((x) << 6)      /* v5 */
-#define PTE_EXT_APX            (1 << 9)        /* v6 */
-#define PTE_EXT_COHERENT       (1 << 9)        /* XScale3 */
-#define PTE_EXT_SHARED         (1 << 10)       /* v6 */
-#define PTE_EXT_NG             (1 << 11)       /* v6 */
-
-/*
- *   - small page
- */
-#define PTE_SMALL_AP_MASK      (0xff << 4)
-#define PTE_SMALL_AP_UNO_SRO   (0x00 << 4)
-#define PTE_SMALL_AP_UNO_SRW   (0x55 << 4)
-#define PTE_SMALL_AP_URO_SRW   (0xaa << 4)
-#define PTE_SMALL_AP_URW_SRW   (0xff << 4)
+#ifdef CONFIG_ARM_LPAE
+#include <asm/pgtable-3level-hwdef.h>
+#else
+#include <asm/pgtable-2level-hwdef.h>
+#endif
 
 #endif
index 5750704e02718b9247704021a0832f161bcbaf3b..9645e52f55853b29d46c2f472c05c552e6c2873b 100644 (file)
 #define _ASMARM_PGTABLE_H
 
 #include <linux/const.h>
-#include <asm-generic/4level-fixup.h>
 #include <asm/proc-fns.h>
 
 #ifndef CONFIG_MMU
 
+#include <asm-generic/4level-fixup.h>
 #include "pgtable-nommu.h"
 
 #else
 
+#include <asm-generic/pgtable-nopud.h>
 #include <asm/memory.h>
 #include <mach/vmalloc.h>
 #include <asm/pgtable-hwdef.h>
 
+#ifdef CONFIG_ARM_LPAE
+#include <asm/pgtable-3level.h>
+#else
+#include <asm/pgtable-2level.h>
+#endif
+
 /*
  * Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 8MB value just means that there will be a 8MB "hole" after the
 #define VMALLOC_START          (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 #endif
 
-/*
- * Hardware-wise, we have a two level page table structure, where the first
- * level has 4096 entries, and the second level has 256 entries.  Each entry
- * is one 32-bit word.  Most of the bits in the second level entry are used
- * by hardware, and there aren't any "accessed" and "dirty" bits.
- *
- * Linux on the other hand has a three level page table structure, which can
- * be wrapped to fit a two level page table structure easily - using the PGD
- * and PTE only.  However, Linux also expects one "PTE" table per page, and
- * at least a "dirty" bit.
- *
- * Therefore, we tweak the implementation slightly - we tell Linux that we
- * have 2048 entries in the first level, each of which is 8 bytes (iow, two
- * hardware pointers to the second level.)  The second level contains two
- * hardware PTE tables arranged contiguously, preceded by Linux versions
- * which contain the state information Linux needs.  We, therefore, end up
- * with 512 entries in the "PTE" level.
- *
- * This leads to the page tables having the following layout:
- *
- *    pgd             pte
- * |        |
- * +--------+
- * |        |       +------------+ +0
- * +- - - - +       | Linux pt 0 |
- * |        |       +------------+ +1024
- * +--------+ +0    | Linux pt 1 |
- * |        |-----> +------------+ +2048
- * +- - - - + +4    |  h/w pt 0  |
- * |        |-----> +------------+ +3072
- * +--------+ +8    |  h/w pt 1  |
- * |        |       +------------+ +4096
- *
- * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
- * PTE_xxx for definitions of bits appearing in the "h/w pt".
- *
- * PMD_xxx definitions refer to bits in the first level page table.
- *
- * The "dirty" bit is emulated by only granting hardware write permission
- * iff the page is marked "writable" and "dirty" in the Linux PTE.  This
- * means that a write to a clean page will cause a permission fault, and
- * the Linux MM layer will mark the page dirty via handle_pte_fault().
- * For the hardware to notice the permission change, the TLB entry must
- * be flushed, and ptep_set_access_flags() does that for us.
- *
- * The "accessed" or "young" bit is emulated by a similar method; we only
- * allow accesses to the page if the "young" bit is set.  Accesses to the
- * page will cause a fault, and handle_pte_fault() will set the young bit
- * for us as long as the page is marked present in the corresponding Linux
- * PTE entry.  Again, ptep_set_access_flags() will ensure that the TLB is
- * up to date.
- *
- * However, when the "young" bit is cleared, we deny access to the page
- * by clearing the hardware PTE.  Currently Linux does not flush the TLB
- * for us in this case, which means the TLB will retain the transation
- * until either the TLB entry is evicted under pressure, or a context
- * switch which changes the user space mapping occurs.
- */
-#define PTRS_PER_PTE           512
-#define PTRS_PER_PMD           1
-#define PTRS_PER_PGD           2048
-
-#define PTE_HWTABLE_PTRS       (PTRS_PER_PTE)
-#define PTE_HWTABLE_OFF                (PTE_HWTABLE_PTRS * sizeof(pte_t))
-#define PTE_HWTABLE_SIZE       (PTRS_PER_PTE * sizeof(u32))
-
-/*
- * PMD_SHIFT determines the size of the area a second-level page table can map
- * PGDIR_SHIFT determines what a third-level page table entry can map
- */
-#define PMD_SHIFT              21
-#define PGDIR_SHIFT            21
-
 #define LIBRARY_TEXT_START     0x0c000000
 
 #ifndef __ASSEMBLY__
@@ -124,12 +58,6 @@ extern void __pgd_error(const char *file, int line, pgd_t);
 #define pte_ERROR(pte)         __pte_error(__FILE__, __LINE__, pte)
 #define pmd_ERROR(pmd)         __pmd_error(__FILE__, __LINE__, pmd)
 #define pgd_ERROR(pgd)         __pgd_error(__FILE__, __LINE__, pgd)
-#endif /* !__ASSEMBLY__ */
-
-#define PMD_SIZE               (1UL << PMD_SHIFT)
-#define PMD_MASK               (~(PMD_SIZE-1))
-#define PGDIR_SIZE             (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK             (~(PGDIR_SIZE-1))
 
 /*
  * This is the lowest virtual address we can permit any user space
@@ -138,60 +66,6 @@ extern void __pgd_error(const char *file, int line, pgd_t);
  */
 #define FIRST_USER_ADDRESS     PAGE_SIZE
 
-#define USER_PTRS_PER_PGD      (TASK_SIZE / PGDIR_SIZE)
-
-/*
- * section address mask and size definitions.
- */
-#define SECTION_SHIFT          20
-#define SECTION_SIZE           (1UL << SECTION_SHIFT)
-#define SECTION_MASK           (~(SECTION_SIZE-1))
-
-/*
- * ARMv6 supersection address mask and size definitions.
- */
-#define SUPERSECTION_SHIFT     24
-#define SUPERSECTION_SIZE      (1UL << SUPERSECTION_SHIFT)
-#define SUPERSECTION_MASK      (~(SUPERSECTION_SIZE-1))
-
-/*
- * "Linux" PTE definitions.
- *
- * We keep two sets of PTEs - the hardware and the linux version.
- * This allows greater flexibility in the way we map the Linux bits
- * onto the hardware tables, and allows us to have YOUNG and DIRTY
- * bits.
- *
- * The PTE table pointer refers to the hardware entries; the "Linux"
- * entries are stored 1024 bytes below.
- */
-#define L_PTE_PRESENT          (_AT(pteval_t, 1) << 0)
-#define L_PTE_YOUNG            (_AT(pteval_t, 1) << 1)
-#define L_PTE_FILE             (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
-#define L_PTE_DIRTY            (_AT(pteval_t, 1) << 6)
-#define L_PTE_RDONLY           (_AT(pteval_t, 1) << 7)
-#define L_PTE_USER             (_AT(pteval_t, 1) << 8)
-#define L_PTE_XN               (_AT(pteval_t, 1) << 9)
-#define L_PTE_SHARED           (_AT(pteval_t, 1) << 10)        /* shared(v6), coherent(xsc3) */
-
-/*
- * These are the memory types, defined to be compatible with
- * pre-ARMv6 CPUs cacheable and bufferable bits:   XXCB
- */
-#define L_PTE_MT_UNCACHED      (_AT(pteval_t, 0x00) << 2)      /* 0000 */
-#define L_PTE_MT_BUFFERABLE    (_AT(pteval_t, 0x01) << 2)      /* 0001 */
-#define L_PTE_MT_WRITETHROUGH  (_AT(pteval_t, 0x02) << 2)      /* 0010 */
-#define L_PTE_MT_WRITEBACK     (_AT(pteval_t, 0x03) << 2)      /* 0011 */
-#define L_PTE_MT_MINICACHE     (_AT(pteval_t, 0x06) << 2)      /* 0110 (sa1100, xscale) */
-#define L_PTE_MT_WRITEALLOC    (_AT(pteval_t, 0x07) << 2)      /* 0111 */
-#define L_PTE_MT_DEV_SHARED    (_AT(pteval_t, 0x04) << 2)      /* 0100 */
-#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2)      /* 1100 */
-#define L_PTE_MT_DEV_WC                (_AT(pteval_t, 0x09) << 2)      /* 1001 */
-#define L_PTE_MT_DEV_CACHED    (_AT(pteval_t, 0x0b) << 2)      /* 1011 */
-#define L_PTE_MT_MASK          (_AT(pteval_t, 0x0f) << 2)
-
-#ifndef __ASSEMBLY__
-
 /*
  * The pgprot_* and protection_map entries will be fixed up in runtime
  * to include the cachable and bufferable bits based on memory policy,
@@ -291,24 +165,79 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(addr)     pgd_offset(&init_mm, addr)
 
+#ifdef CONFIG_ARM_LPAE
+
+#define pud_none(pud)          (!pud_val(pud))
+#define pud_bad(pud)           (!(pud_val(pud) & 2))
+#define pud_present(pud)       (pud_val(pud))
+
+#define pud_clear(pudp)                        \
+       do {                            \
+               *pudp = __pud(0);       \
+               clean_pmd_entry(pudp);  \
+       } while (0)
+
+#define set_pud(pudp, pud)             \
+       do {                            \
+               *pudp = pud;            \
+               flush_pmd_entry(pudp);  \
+       } while (0)
+
+static inline pmd_t *pud_page_vaddr(pud_t pud)
+{
+       return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
+}
+
+#else  /* !CONFIG_ARM_LPAE */
+
 /*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
+ * The "pud_xxx()" functions here are trivial when the pmd is folded into
+ * the pud: the pud entry is never bad, always exists, and can't be set or
+ * cleared.
  */
-#define pgd_none(pgd)          (0)
-#define pgd_bad(pgd)           (0)
-#define pgd_present(pgd)       (1)
-#define pgd_clear(pgdp)                do { } while (0)
-#define set_pgd(pgd,pgdp)      do { } while (0)
+#define pud_none(pud)          (0)
+#define pud_bad(pud)           (0)
+#define pud_present(pud)       (1)
+#define pud_clear(pudp)                do { } while (0)
 #define set_pud(pud,pudp)      do { } while (0)
 
+#endif /* CONFIG_ARM_LPAE */
 
 /* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, addr)  ((pmd_t *)(dir))
+#ifdef CONFIG_ARM_LPAE
+#define pmd_index(addr)                (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+{
+       return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
+}
+#else
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+{
+       return (pmd_t *)pud;
+}
+#endif
 
 #define pmd_none(pmd)          (!pmd_val(pmd))
 #define pmd_present(pmd)       (pmd_val(pmd))
+
+#ifdef CONFIG_ARM_LPAE
+
+#define pmd_bad(pmd)           (!(pmd_val(pmd) & 2))
+
+#define copy_pmd(pmdpd,pmdps)          \
+       do {                            \
+               *pmdpd = *pmdps;        \
+               flush_pmd_entry(pmdpd); \
+       } while (0)
+
+#define pmd_clear(pmdp)                        \
+       do {                            \
+               *pmdp = __pmd(0);       \
+               clean_pmd_entry(pmdp);  \
+       } while (0)
+
+#else  /* !CONFIG_ARM_LPAE */
+
 #define pmd_bad(pmd)           (pmd_val(pmd) & 2)
 
 #define copy_pmd(pmdpd,pmdps)          \
@@ -325,16 +254,14 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
                clean_pmd_entry(pmdp);  \
        } while (0)
 
+#endif /* CONFIG_ARM_LPAE */
+
 static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 {
-       return __va(pmd_val(pmd) & PAGE_MASK);
+       return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
 }
 
-#define pmd_page(pmd)          pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
-
-/* we don't need complex calculations here as the pmd is folded into the pgd */
-#define pmd_addr_end(addr,end) (end)
-
+#define pmd_page(pmd)          pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
 
 #ifndef CONFIG_HIGHPTE
 #define __pte_map(pmd)         pmd_page_vaddr(*(pmd))
@@ -351,15 +278,20 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 #define pte_offset_map(pmd,addr)       (__pte_map(pmd) + pte_index(addr))
 #define pte_unmap(pte)                 __pte_unmap(pte)
 
-#define pte_pfn(pte)           (pte_val(pte) >> PAGE_SHIFT)
+#define pte_pfn(pte)           ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
 #define pfn_pte(pfn,prot)      __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
 
 #define pte_page(pte)          pfn_to_page(pte_pfn(pte))
 #define mk_pte(page,prot)      pfn_pte(page_to_pfn(page), prot)
 
-#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
 #define pte_clear(mm,addr,ptep)        set_pte_ext(ptep, __pte(0), 0)
 
+#ifdef CONFIG_ARM_LPAE
+#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
+#else
+#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+#endif
+
 #if __LINUX_ARM_ARCH__ < 6
 static inline void __sync_icache_dcache(pte_t pteval)
 {
index 67c70a31a1be33c34ecdd271c343767342a83dfe..b7e82c4aced63ed7222df9a92c46810bc3094622 100644 (file)
@@ -41,7 +41,7 @@ struct arm_pmu_platdata {
  * encoded error on failure.
  */
 extern struct platform_device *
-reserve_pmu(enum arm_pmu_type device);
+reserve_pmu(enum arm_pmu_type type);
 
 /**
  * release_pmu() - Relinquish control of the performance counters
@@ -62,26 +62,26 @@ release_pmu(enum arm_pmu_type type);
  * the actual hardware initialisation.
  */
 extern int
-init_pmu(enum arm_pmu_type device);
+init_pmu(enum arm_pmu_type type);
 
 #else /* CONFIG_CPU_HAS_PMU */
 
 #include <linux/err.h>
 
 static inline struct platform_device *
-reserve_pmu(enum arm_pmu_type device)
+reserve_pmu(enum arm_pmu_type type)
 {
        return ERR_PTR(-ENODEV);
 }
 
 static inline int
-release_pmu(struct platform_device *pdev)
+release_pmu(enum arm_pmu_type type)
 {
        return -ENODEV;
 }
 
 static inline int
-init_pmu(enum arm_pmu_type device)
+init_pmu(enum arm_pmu_type type)
 {
        return -ENODEV;
 }
diff --git a/arch/arm/include/asm/poll.h b/arch/arm/include/asm/poll.h
deleted file mode 100644 (file)
index c98509d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/poll.h>
index 633d1cb84d87cbe356496b863e24f85a5f0402ea..34e852c636e0b97ef24ba32bcb8e70e6a9ab8a61 100644 (file)
@@ -65,7 +65,11 @@ extern struct processor {
         * Set a possibly extended PTE.  Non-extended PTEs should
         * ignore 'ext'.
         */
+#ifdef CONFIG_ARM_LPAE
+       void (*set_pte_ext)(pte_t *ptep, pte_t pte);
+#else
        void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+#endif
 
        /* Suspend/resume */
        unsigned int suspend_size;
@@ -79,7 +83,11 @@ extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
 extern void cpu_dcache_clean_area(void *, int);
 extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+#ifdef CONFIG_ARM_LPAE
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
+#else
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+#endif
 extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
 #else
 #define cpu_proc_init                  processor._proc_init
@@ -99,6 +107,18 @@ extern void cpu_resume(void);
 
 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
 
+#ifdef CONFIG_ARM_LPAE
+#define cpu_get_pgd()  \
+       ({                                              \
+               unsigned long pg, pg2;                  \
+               __asm__("mrrc   p15, 0, %0, %1, c2"     \
+                       : "=r" (pg), "=r" (pg2)         \
+                       :                               \
+                       : "cc");                        \
+               pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);  \
+               (pgd_t *)phys_to_virt(pg);              \
+       })
+#else
 #define cpu_get_pgd()  \
        ({                                              \
                unsigned long pg;                       \
@@ -107,6 +127,7 @@ extern void cpu_resume(void);
                pg &= ~0x3fff;                          \
                (pgd_t *)phys_to_virt(pg);              \
        })
+#endif
 
 #endif
 
diff --git a/arch/arm/include/asm/resource.h b/arch/arm/include/asm/resource.h
deleted file mode 100644 (file)
index 734b581..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ARM_RESOURCE_H
-#define _ARM_RESOURCE_H
-
-#include <asm-generic/resource.h>
-
-#endif
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
deleted file mode 100644 (file)
index 2b8c516..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/sections.h>
index 915696dd9c7c32d4d9702d54c933d50bbc4ca1e0..a3ca303a08011eae1d54788a5bbca888bb63974c 100644 (file)
@@ -43,6 +43,13 @@ struct tag_mem32 {
        __u32   start;  /* physical start address */
 };
 
+#define ATAG_MEM64     0x54420002
+
+struct tag_mem64 {
+       __u64   size;
+       __u64   start;  /* physical start address */
+};
+
 /* VGA text type displays */
 #define ATAG_VIDEOTEXT 0x54410003
 
@@ -148,6 +155,7 @@ struct tag {
        union {
                struct tag_core         core;
                struct tag_mem32        mem;
+               struct tag_mem64        mem64;
                struct tag_videotext    videotext;
                struct tag_ramdisk      ramdisk;
                struct tag_initrd       initrd;
diff --git a/arch/arm/include/asm/siginfo.h b/arch/arm/include/asm/siginfo.h
deleted file mode 100644 (file)
index 5e21852..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASMARM_SIGINFO_H
-#define _ASMARM_SIGINFO_H
-
-#include <asm-generic/siginfo.h>
-
-#endif
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
deleted file mode 100644 (file)
index 154b89b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-/*  Size definitions
- *  Copyright (C) ARM Limited 1998. All rights reserved.
- */
-#include <asm-generic/sizes.h>
-
-#define SZ_48M (SZ_32M + SZ_16M)
index 832888d0c20c263a761cc093bb96ae4977ed15bc..d4ced6df39f983595eafb2f3577d27a2c1387c8c 100644 (file)
@@ -57,6 +57,7 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <linux/irqflags.h>
 
@@ -86,6 +87,14 @@ struct siginfo;
 void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
                unsigned long err, unsigned long trap);
 
+#ifdef CONFIG_ARM_LPAE
+#define FAULT_CODE_ALIGNMENT   33
+#define FAULT_CODE_DEBUG       34
+#else
+#define FAULT_CODE_ALIGNMENT   1
+#define FAULT_CODE_DEBUG       2
+#endif
+
 void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
                                       struct pt_regs *),
                     int sig, int code, const char *name);
@@ -104,7 +113,7 @@ struct mm_struct;
 extern void show_pte(struct mm_struct *mm, unsigned long addr);
 extern void __show_regs(struct pt_regs *);
 
-extern int cpu_architecture(void);
+extern int __pure cpu_architecture(void);
 extern void cpu_init(void);
 
 void arm_machine_restart(char mode, const char *cmd);
index 7b5cc8dae06e6e99b1dfc18edf6cef748629f25f..0f30c3a78fc10815668b56c2ae5789ea38b4fdd9 100644 (file)
@@ -142,7 +142,6 @@ extern void vfp_flush_hwstate(struct thread_info *);
 #define TIF_POLLING_NRFLAG     16
 #define TIF_USING_IWMMXT       17
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
-#define TIF_FREEZE             19
 #define TIF_RESTORE_SIGMASK    20
 #define TIF_SECCOMP            21
 
@@ -152,7 +151,6 @@ extern void vfp_flush_hwstate(struct thread_info *);
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_USING_IWMMXT      (1 << TIF_USING_IWMMXT)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 
index 265f908c4a6e79b98e07d43b7614c5164e86da53..5d3ed7e38561dd43553d1d3bf1b2af07e0d2b747 100644 (file)
@@ -202,8 +202,18 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
        tlb_remove_page(tlb, pte);
 }
 
+static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
+                                 unsigned long addr)
+{
+#ifdef CONFIG_ARM_LPAE
+       tlb_add_flush(tlb, addr);
+       tlb_remove_page(tlb, virt_to_page(pmdp));
+#endif
+}
+
 #define pte_free_tlb(tlb, ptep, addr)  __pte_free_tlb(tlb, ptep, addr)
-#define pmd_free_tlb(tlb, pmdp, addr)  pmd_free((tlb)->mm, pmdp)
+#define pmd_free_tlb(tlb, pmdp, addr)  __pmd_free_tlb(tlb, pmdp, addr)
+#define pud_free_tlb(tlb, pudp, addr)  pud_free((tlb)->mm, pudp)
 
 #define tlb_migrate_finish(mm)         do { } while (0)
 
index 8077145698ffff09f802644021ae9980b8b226a2..02b2f82039828bb0d4b016e41882c3071b686b93 100644 (file)
@@ -471,7 +471,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
  *     these operations.  This is typically used when we are removing
  *     PMD entries.
  */
-static inline void flush_pmd_entry(pmd_t *pmd)
+static inline void flush_pmd_entry(void *pmd)
 {
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
@@ -487,7 +487,7 @@ static inline void flush_pmd_entry(pmd_t *pmd)
                dsb();
 }
 
-static inline void clean_pmd_entry(pmd_t *pmd)
+static inline void clean_pmd_entry(void *pmd)
 {
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
index accbd7cad9b519c4e76994454c19ff9332960be8..a7e457ed27c31e1185ebe3a0eaa745d88c35029d 100644 (file)
@@ -1,6 +1,39 @@
 #ifndef _ASM_ARM_TOPOLOGY_H
 #define _ASM_ARM_TOPOLOGY_H
 
+#ifdef CONFIG_ARM_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cputopo_arm {
+       int thread_id;
+       int core_id;
+       int socket_id;
+       cpumask_t thread_sibling;
+       cpumask_t core_sibling;
+};
+
+extern struct cputopo_arm cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu)      (cpu_topology[cpu].socket_id)
+#define topology_core_id(cpu)          (cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu)     (&cpu_topology[cpu].core_sibling)
+#define topology_thread_cpumask(cpu)   (&cpu_topology[cpu].thread_sibling)
+
+#define mc_capable()   (cpu_topology[0].socket_id != -1)
+#define smt_capable()  (cpu_topology[0].thread_id != -1)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_ARM_TOPOLOGY_H */
index f7887dc53c1f6ac8dbda79c63bfd331d51f67a4c..c687bceba7da2984e67fd06fe65cb62ab2217d47 100644 (file)
@@ -66,6 +66,7 @@ obj-$(CONFIG_IWMMXT)          += iwmmxt.o
 obj-$(CONFIG_CPU_HAS_PMU)      += pmu.o
 obj-$(CONFIG_HW_PERF_EVENTS)   += perf_event.o
 AFLAGS_iwmmxt.o                        := -Wa,-mcpu=iwmmxt
+obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
 
 ifneq ($(CONFIG_ARCH_EBSA110),y)
   obj-y                += io.o
index d16500110ee99526655dcf409455ea0b8e32587b..4dd0edab6a658880ed505145fff2c5ce001ae639 100644 (file)
@@ -237,7 +237,7 @@ static void ecard_init_pgtables(struct mm_struct *mm)
 
        memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
 
-       src_pgd = pgd_offset(mm, EASI_BASE);
+       src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE);
        dst_pgd = pgd_offset(mm, EASI_START);
 
        memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
@@ -674,44 +674,37 @@ static int __init ecard_probeirqhw(void)
 #define ecard_probeirqhw() (0)
 #endif
 
-#ifndef IO_EC_MEMC8_BASE
-#define IO_EC_MEMC8_BASE 0
-#endif
-
-static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
 {
-       unsigned long address = 0;
+       void __iomem *address = NULL;
        int slot = ec->slot_no;
 
        if (ec->slot_no == 8)
-               return IO_EC_MEMC8_BASE;
+               return ECARD_MEMC8_BASE;
 
        ectcr &= ~(1 << slot);
 
        switch (type) {
        case ECARD_MEMC:
                if (slot < 4)
-                       address = IO_EC_MEMC_BASE + (slot << 12);
+                       address = ECARD_MEMC_BASE + (slot << 14);
                break;
 
        case ECARD_IOC:
                if (slot < 4)
-                       address = IO_EC_IOC_BASE + (slot << 12);
-#ifdef IO_EC_IOC4_BASE
+                       address = ECARD_IOC_BASE + (slot << 14);
                else
-                       address = IO_EC_IOC4_BASE + ((slot - 4) << 12);
-#endif
+                       address = ECARD_IOC4_BASE + ((slot - 4) << 14);
                if (address)
-                       address +=  speed << 17;
+                       address += speed << 19;
                break;
 
-#ifdef IO_EC_EASI_BASE
        case ECARD_EASI:
-               address = IO_EC_EASI_BASE + (slot << 22);
+               address = ECARD_EASI_BASE + (slot << 24);
                if (speed == ECARD_FAST)
                        ectcr |= 1 << slot;
                break;
-#endif
+
        default:
                break;
        }
@@ -990,6 +983,7 @@ ecard_probe(int slot, card_type_t type)
        ecard_t **ecp;
        ecard_t *ec;
        struct ex_ecid cid;
+       void __iomem *addr;
        int i, rc;
 
        ec = ecard_alloc_card(type, slot);
@@ -999,7 +993,7 @@ ecard_probe(int slot, card_type_t type)
        }
 
        rc = -ENODEV;
-       if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0)
+       if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
                goto nodev;
 
        cid.r_zero = 1;
@@ -1019,7 +1013,7 @@ ecard_probe(int slot, card_type_t type)
        ec->cid.fiqmask = cid.r_fiqmask;
        ec->cid.fiqoff  = ecard_gets24(cid.r_fiqoff);
        ec->fiqaddr     =
-       ec->irqaddr     = (void __iomem *)ioaddr(ec->podaddr);
+       ec->irqaddr     = addr;
 
        if (ec->cid.is) {
                ec->irqmask = ec->cid.irqmask;
@@ -1048,10 +1042,8 @@ ecard_probe(int slot, card_type_t type)
                set_irq_flags(ec->irq, IRQF_VALID);
        }
 
-#ifdef IO_EC_MEMC8_BASE
        if (slot == 8)
                ec->irq = 11;
-#endif
 #ifdef CONFIG_ARCH_RPC
        /* On RiscPC, only first two slots have DMA capability */
        if (slot < 2)
@@ -1097,9 +1089,7 @@ static int __init ecard_init(void)
                        ecard_probe(slot, ECARD_IOC);
        }
 
-#ifdef IO_EC_MEMC8_BASE
        ecard_probe(8, ECARD_IOC);
-#endif
 
        irqhw = ecard_probeirqhw();
 
index a87cbf889ff479f635df3d42af731f80e32e8e64..9ad50c4208aebf5aaf7ee245444da5789935b269 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/unwind.h>
 #include <asm/unistd.h>
 #include <asm/tls.h>
+#include <asm/system.h>
 
 #include "entry-header.S"
 #include <asm/entry-macro-multi.S>
@@ -262,8 +263,7 @@ __und_svc:
        ldr     r0, [r4, #-4]
 #else
        ldrh    r0, [r4, #-2]                   @ Thumb instruction at LR - 2
-       and     r9, r0, #0xf800
-       cmp     r9, #0xe800                     @ 32-bit instruction if xx >= 0
+       cmp     r0, #0xe800                     @ 32-bit instruction if xx >= 0
        ldrhhs  r9, [r4]                        @ bottom 16 bits
        orrhs   r0, r9, r0, lsl #16
 #endif
@@ -440,18 +440,46 @@ __und_usr:
 #endif
        beq     call_fpe
        @ Thumb instruction
-#if __LINUX_ARM_ARCH__ >= 7
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
+/*
+ * Thumb-2 instruction handling.  Note that because pre-v6 and >= v6 platforms
+ * can never be supported in a single kernel, this code is not applicable at
+ * all when __LINUX_ARM_ARCH__ < 6.  This allows simplifying assumptions to be
+ * made about .arch directives.
+ */
+#if __LINUX_ARM_ARCH__ < 7
+/* If the target CPU may not be Thumb-2-capable, a run-time check is needed: */
+#define NEED_CPU_ARCHITECTURE
+       ldr     r5, .LCcpu_architecture
+       ldr     r5, [r5]
+       cmp     r5, #CPU_ARCH_ARMv7
+       blo     __und_usr_unknown
+/*
+ * The following code won't get run unless the running CPU really is v7, so
+ * coding round the lack of ldrht on older arches is pointless.  Temporarily
+ * override the assembler target arch with the minimum required instead:
+ */
+       .arch   armv6t2
+#endif
 2:
  ARM(  ldrht   r5, [r4], #2    )
  THUMB(        ldrht   r5, [r4]        )
  THUMB(        add     r4, r4, #2      )
-       and     r0, r5, #0xf800                 @ mask bits 111x x... .... ....
-       cmp     r0, #0xe800                     @ 32bit instruction if xx != 0
+       cmp     r5, #0xe800                     @ 32bit instruction if xx != 0
        blo     __und_usr_unknown
 3:     ldrht   r0, [r4]
        add     r2, r2, #2                      @ r2 is PC + 2, make it PC + 4
        orr     r0, r0, r5, lsl #16
+
+#if __LINUX_ARM_ARCH__ < 7
+/* If the target arch was overridden, change it back: */
+#ifdef CONFIG_CPU_32v6K
+       .arch   armv6k
 #else
+       .arch   armv6
+#endif
+#endif /* __LINUX_ARM_ARCH__ < 7 */
+#else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */
        b       __und_usr_unknown
 #endif
  UNWIND(.fnend         )
@@ -578,6 +606,12 @@ call_fpe:
        movw_pc lr                              @ CP#14 (Debug)
        movw_pc lr                              @ CP#15 (Control)
 
+#ifdef NEED_CPU_ARCHITECTURE
+       .align  2
+.LCcpu_architecture:
+       .word   __cpu_architecture
+#endif
+
 #ifdef CONFIG_NEON
        .align  6
 
index 742b6108a00168b8ed8c391c6d8e8b1b9c438fc6..aa65a72333dd5b2c9fa7512d4d7f66edd1e01676 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/system.h>
+#include <asm/pgtable.h>
 
 #ifdef CONFIG_DEBUG_LL
 #include <mach/debug-macro.S>
 #define KERNEL_RAM_VADDR       (PAGE_OFFSET + TEXT_OFFSET)
 #if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
 #error KERNEL_RAM_VADDR must start at 0xXXXX8000
+#endif
+
+#ifdef CONFIG_ARM_LPAE
+       /* LPAE requires an additional page for the PGD */
+#define PG_DIR_SIZE    0x5000
+#define PMD_ORDER      3
+#else
+#define PG_DIR_SIZE    0x4000
+#define PMD_ORDER      2
 #endif
 
        .globl  swapper_pg_dir
-       .equ    swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
+       .equ    swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
 
        .macro  pgtbl, rd, phys
-       add     \rd, \phys, #TEXT_OFFSET - 0x4000
+       add     \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
        .endm
 
 #ifdef CONFIG_XIP_KERNEL
@@ -148,11 +158,11 @@ __create_page_tables:
        pgtbl   r4, r8                          @ page table address
 
        /*
-        * Clear the 16K level 1 swapper page table
+        * Clear the swapper page table
         */
        mov     r0, r4
        mov     r3, #0
-       add     r6, r0, #0x4000
+       add     r6, r0, #PG_DIR_SIZE
 1:     str     r3, [r0], #4
        str     r3, [r0], #4
        str     r3, [r0], #4
@@ -160,6 +170,25 @@ __create_page_tables:
        teq     r0, r6
        bne     1b
 
+#ifdef CONFIG_ARM_LPAE
+       /*
+        * Build the PGD table (first level) to point to the PMD table. A PGD
+        * entry is 64-bit wide.
+        */
+       mov     r0, r4
+       add     r3, r4, #0x1000                 @ first PMD table address
+       orr     r3, r3, #3                      @ PGD block type
+       mov     r6, #4                          @ PTRS_PER_PGD
+       mov     r7, #1 << (55 - 32)             @ L_PGD_SWAPPER
+1:     str     r3, [r0], #4                    @ set bottom PGD entry bits
+       str     r7, [r0], #4                    @ set top PGD entry bits
+       add     r3, r3, #0x1000                 @ next PMD table
+       subs    r6, r6, #1
+       bne     1b
+
+       add     r4, r4, #0x1000                 @ point to the PMD tables
+#endif
+
        ldr     r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
 
        /*
@@ -171,30 +200,30 @@ __create_page_tables:
        sub     r0, r0, r3                      @ virt->phys offset
        add     r5, r5, r0                      @ phys __enable_mmu
        add     r6, r6, r0                      @ phys __enable_mmu_end
-       mov     r5, r5, lsr #20
-       mov     r6, r6, lsr #20
+       mov     r5, r5, lsr #SECTION_SHIFT
+       mov     r6, r6, lsr #SECTION_SHIFT
 
-1:     orr     r3, r7, r5, lsl #20             @ flags + kernel base
-       str     r3, [r4, r5, lsl #2]            @ identity mapping
-       teq     r5, r6
-       addne   r5, r5, #1                      @ next section
-       bne     1b
+1:     orr     r3, r7, r5, lsl #SECTION_SHIFT  @ flags + kernel base
+       str     r3, [r4, r5, lsl #PMD_ORDER]    @ identity mapping
+       cmp     r5, r6
+       addlo   r5, r5, #1                      @ next section
+       blo     1b
 
        /*
         * Now setup the pagetables for our kernel direct
         * mapped region.
         */
        mov     r3, pc
-       mov     r3, r3, lsr #20
-       orr     r3, r7, r3, lsl #20
-       add     r0, r4,  #(KERNEL_START & 0xff000000) >> 18
-       str     r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
+       mov     r3, r3, lsr #SECTION_SHIFT
+       orr     r3, r7, r3, lsl #SECTION_SHIFT
+       add     r0, r4,  #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
+       str     r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]!
        ldr     r6, =(KERNEL_END - 1)
-       add     r0, r0, #4
-       add     r6, r4, r6, lsr #18
+       add     r0, r0, #1 << PMD_ORDER
+       add     r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
 1:     cmp     r0, r6
-       add     r3, r3, #1 << 20
-       strls   r3, [r0], #4
+       add     r3, r3, #1 << SECTION_SHIFT
+       strls   r3, [r0], #1 << PMD_ORDER
        bls     1b
 
 #ifdef CONFIG_XIP_KERNEL
@@ -203,11 +232,11 @@ __create_page_tables:
         */
        add     r3, r8, #TEXT_OFFSET
        orr     r3, r3, r7
-       add     r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> 18
-       str     r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
+       add     r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER)
+       str     r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]!
        ldr     r6, =(_end - 1)
        add     r0, r0, #4
-       add     r6, r4, r6, lsr #18
+       add     r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
 1:     cmp     r0, r6
        add     r3, r3, #1 << 20
        strls   r3, [r0], #4
@@ -215,15 +244,15 @@ __create_page_tables:
 #endif
 
        /*
-        * Then map boot params address in r2 or
-        * the first 1MB of ram if boot params address is not specified.
+        * Then map boot params address in r2 or the first 1MB (2MB with LPAE)
+        * of ram if boot params address is not specified.
         */
-       mov     r0, r2, lsr #20
-       movs    r0, r0, lsl #20
+       mov     r0, r2, lsr #SECTION_SHIFT
+       movs    r0, r0, lsl #SECTION_SHIFT
        moveq   r0, r8
        sub     r3, r0, r8
        add     r3, r3, #PAGE_OFFSET
-       add     r3, r4, r3, lsr #18
+       add     r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
        orr     r6, r7, r0
        str     r6, [r3]
 
@@ -236,21 +265,27 @@ __create_page_tables:
         */
        addruart r7, r3
 
-       mov     r3, r3, lsr #20
-       mov     r3, r3, lsl #2
+       mov     r3, r3, lsr #SECTION_SHIFT
+       mov     r3, r3, lsl #PMD_ORDER
 
        add     r0, r4, r3
        rsb     r3, r3, #0x4000                 @ PTRS_PER_PGD*sizeof(long)
        cmp     r3, #0x0800                     @ limit to 512MB
        movhi   r3, #0x0800
        add     r6, r0, r3
-       mov     r3, r7, lsr #20
+       mov     r3, r7, lsr #SECTION_SHIFT
        ldr     r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
-       orr     r3, r7, r3, lsl #20
+       orr     r3, r7, r3, lsl #SECTION_SHIFT
+#ifdef CONFIG_ARM_LPAE
+       mov     r7, #1 << (54 - 32)             @ XN
+#endif
 1:     str     r3, [r0], #4
-       add     r3, r3, #1 << 20
-       teq     r0, r6
-       bne     1b
+#ifdef CONFIG_ARM_LPAE
+       str     r7, [r0], #4
+#endif
+       add     r3, r3, #1 << SECTION_SHIFT
+       cmp     r0, r6
+       blo     1b
 
 #else /* CONFIG_DEBUG_ICEDCC */
        /* we don't need any serial debugging mappings for ICEDCC */
@@ -262,7 +297,7 @@ __create_page_tables:
         * If we're using the NetWinder or CATS, we also need to map
         * in the 16550-type serial port for the debug messages
         */
-       add     r0, r4, #0xff000000 >> 18
+       add     r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER)
        orr     r3, r7, #0x7c000000
        str     r3, [r0]
 #endif
@@ -272,12 +307,15 @@ __create_page_tables:
         * Similar reasons here - for debug.  This is
         * only for Acorn RiscPC architectures.
         */
-       add     r0, r4, #0x02000000 >> 18
+       add     r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER)
        orr     r3, r7, #0x02000000
        str     r3, [r0]
-       add     r0, r4, #0xd8000000 >> 18
+       add     r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER)
        str     r3, [r0]
 #endif
+#endif
+#ifdef CONFIG_ARM_LPAE
+       sub     r4, r4, #0x1000         @ point to the PGD table
 #endif
        mov     pc, lr
 ENDPROC(__create_page_tables)
@@ -370,12 +408,17 @@ __enable_mmu:
 #ifdef CONFIG_CPU_ICACHE_DISABLE
        bic     r0, r0, #CR_I
 #endif
+#ifdef CONFIG_ARM_LPAE
+       mov     r5, #0
+       mcrr    p15, 0, r4, r5, c2              @ load TTBR0
+#else
        mov     r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
                      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
                      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
                      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
        mcr     p15, 0, r5, c3, c0, 0           @ load domain access register
        mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
+#endif
        b       __turn_mmu_on
 ENDPROC(__enable_mmu)
 
@@ -396,8 +439,10 @@ ENDPROC(__enable_mmu)
        .align  5
 __turn_mmu_on:
        mov     r0, r0
+       instr_sync
        mcr     p15, 0, r0, c1, c0, 0           @ write control reg
        mrc     p15, 0, r3, c0, c0, 0           @ read id reg
+       instr_sync
        mov     r3, r3
        mov     r3, r13
        mov     pc, r3
@@ -488,13 +533,8 @@ __fixup_pv_table:
        add     r5, r5, r3      @ adjust table end address
        add     r7, r7, r3      @ adjust __pv_phys_offset address
        str     r8, [r7]        @ save computed PHYS_OFFSET to __pv_phys_offset
-#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
        mov     r6, r3, lsr #24 @ constant for add/sub instructions
        teq     r3, r6, lsl #24 @ must be 16MiB aligned
-#else
-       mov     r6, r3, lsr #16 @ constant for add/sub instructions
-       teq     r3, r6, lsl #16 @ must be 64kiB aligned
-#endif
 THUMB( it      ne              @ cross section branch )
        bne     __error
        str     r6, [r7, #4]    @ save to __pv_offset
@@ -510,20 +550,8 @@ ENDPROC(__fixup_pv_table)
        .text
 __fixup_a_pv_table:
 #ifdef CONFIG_THUMB2_KERNEL
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-       lsls    r0, r6, #24
-       lsr     r6, #8
-       beq     1f
-       clz     r7, r0
-       lsr     r0, #24
-       lsl     r0, r7
-       bic     r0, 0x0080
-       lsrs    r7, #1
-       orrcs   r0, #0x0080
-       orr     r0, r0, r7, lsl #12
-#endif
-1:     lsls    r6, #24
-       beq     4f
+       lsls    r6, #24
+       beq     2f
        clz     r7, r6
        lsr     r6, #24
        lsl     r6, r7
@@ -532,43 +560,25 @@ __fixup_a_pv_table:
        orrcs   r6, #0x0080
        orr     r6, r6, r7, lsl #12
        orr     r6, #0x4000
-       b       4f
-2:     @ at this point the C flag is always clear
-       add     r7, r3
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-       ldrh    ip, [r7]
-       tst     ip, 0x0400      @ the i bit tells us LS or MS byte
-       beq     3f
-       cmp     r0, #0          @ set C flag, and ...
-       biceq   ip, 0x0400      @ immediate zero value has a special encoding
-       streqh  ip, [r7]        @ that requires the i bit cleared
-#endif
-3:     ldrh    ip, [r7, #2]
+       b       2f
+1:     add     r7, r3
+       ldrh    ip, [r7, #2]
        and     ip, 0x8f00
-       orrcc   ip, r6  @ mask in offset bits 31-24
-       orrcs   ip, r0  @ mask in offset bits 23-16
+       orr     ip, r6  @ mask in offset bits 31-24
        strh    ip, [r7, #2]
-4:     cmp     r4, r5
+2:     cmp     r4, r5
        ldrcc   r7, [r4], #4    @ use branch for delay slot
-       bcc     2b
+       bcc     1b
        bx      lr
 #else
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
-       and     r0, r6, #255    @ offset bits 23-16
-       mov     r6, r6, lsr #8  @ offset bits 31-24
-#else
-       mov     r0, #0          @ just in case...
-#endif
-       b       3f
-2:     ldr     ip, [r7, r3]
+       b       2f
+1:     ldr     ip, [r7, r3]
        bic     ip, ip, #0x000000ff
-       tst     ip, #0x400      @ rotate shift tells us LS or MS byte
-       orrne   ip, ip, r6      @ mask in offset bits 31-24
-       orreq   ip, ip, r0      @ mask in offset bits 23-16
+       orr     ip, ip, r6      @ mask in offset bits 31-24
        str     ip, [r7, r3]
-3:     cmp     r4, r5
+2:     cmp     r4, r5
        ldrcc   r7, [r4], #4    @ use branch for delay slot
-       bcc     2b
+       bcc     1b
        mov     pc, lr
 #endif
 ENDPROC(__fixup_a_pv_table)
index a927ca1f5566ce67055296f9a45f9e8714dcda51..541c237efdf08e607d95871d37df58b262e5d11c 100644 (file)
@@ -951,10 +951,10 @@ static int __init arch_hw_breakpoint_init(void)
        }
 
        /* Register debug fault handler. */
-       hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
-                       "watchpoint debug exception");
-       hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
-                       "breakpoint debug exception");
+       hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
+                       TRAP_HWBKPT, "watchpoint debug exception");
+       hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
+                       TRAP_HWBKPT, "breakpoint debug exception");
 
        /* Register hotplug notifier. */
        register_cpu_notifier(&dbg_reset_nb);
index cc2020c2c70977a4e95eaadad130c688514682e9..1e9be5d25e56adcddb8ea4cff5997fc1698e72ce 100644 (file)
@@ -33,7 +33,7 @@
  * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
  */
 #undef MODULES_VADDR
-#define MODULES_VADDR  (((unsigned long)_etext + ~PGDIR_MASK) & PGDIR_MASK)
+#define MODULES_VADDR  (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
 #endif
 
 #ifdef CONFIG_MMU
index 2b70709376c3271e1007b3e6bd7d829db997375e..c53474fe84dfe1851df72fd7428fccf02ea33c4f 100644 (file)
@@ -31,7 +31,7 @@ static int __devinit pmu_register(struct platform_device *pdev,
 {
        if (type < 0 || type >= ARM_NUM_PMU_DEVICES) {
                pr_warning("received registration request for unknown "
-                               "device %d\n", type);
+                               "PMU device type %d\n", type);
                return -EINVAL;
        }
 
@@ -112,17 +112,17 @@ static int __init register_pmu_driver(void)
 device_initcall(register_pmu_driver);
 
 struct platform_device *
-reserve_pmu(enum arm_pmu_type device)
+reserve_pmu(enum arm_pmu_type type)
 {
        struct platform_device *pdev;
 
-       if (test_and_set_bit_lock(device, &pmu_lock)) {
+       if (test_and_set_bit_lock(type, &pmu_lock)) {
                pdev = ERR_PTR(-EBUSY);
-       } else if (pmu_devices[device] == NULL) {
-               clear_bit_unlock(device, &pmu_lock);
+       } else if (pmu_devices[type] == NULL) {
+               clear_bit_unlock(type, &pmu_lock);
                pdev = ERR_PTR(-ENODEV);
        } else {
-               pdev = pmu_devices[device];
+               pdev = pmu_devices[type];
        }
 
        return pdev;
@@ -130,11 +130,11 @@ reserve_pmu(enum arm_pmu_type device)
 EXPORT_SYMBOL_GPL(reserve_pmu);
 
 int
-release_pmu(enum arm_pmu_type device)
+release_pmu(enum arm_pmu_type type)
 {
-       if (WARN_ON(!pmu_devices[device]))
+       if (WARN_ON(!pmu_devices[type]))
                return -EINVAL;
-       clear_bit_unlock(device, &pmu_lock);
+       clear_bit_unlock(type, &pmu_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(release_pmu);
@@ -182,17 +182,17 @@ init_cpu_pmu(void)
 }
 
 int
-init_pmu(enum arm_pmu_type device)
+init_pmu(enum arm_pmu_type type)
 {
        int err = 0;
 
-       switch (device) {
+       switch (type) {
        case ARM_PMU_DEVICE_CPU:
                err = init_cpu_pmu();
                break;
        default:
-               pr_warning("attempt to initialise unknown device %d\n",
-                               device);
+               pr_warning("attempt to initialise PMU of unknown "
+                          "type %d\n", type);
                err = -EINVAL;
        }
 
index 70bca649e9250d8a517348c7536e1fd7e782f942..6c5e1342fbf515ba3e3d0e2036c696e0fc27ed48 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/memblock.h>
+#include <linux/bug.h>
+#include <linux/compiler.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -42,6 +44,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/tlbflush.h>
+#include <asm/system.h>
 
 #include <asm/prom.h>
 #include <asm/mach/arch.h>
@@ -115,6 +118,13 @@ struct outer_cache_fns outer_cache __read_mostly;
 EXPORT_SYMBOL(outer_cache);
 #endif
 
+/*
+ * Cached cpu_architecture() result for use by assembler code.
+ * C code should use the cpu_architecture() function instead of accessing this
+ * variable directly.
+ */
+int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
+
 struct stack {
        u32 irq[3];
        u32 abt[3];
@@ -210,7 +220,7 @@ static const char *proc_arch[] = {
        "?(17)",
 };
 
-int cpu_architecture(void)
+static int __get_cpu_architecture(void)
 {
        int cpu_arch;
 
@@ -243,6 +253,13 @@ int cpu_architecture(void)
        return cpu_arch;
 }
 
+int __pure cpu_architecture(void)
+{
+       BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
+
+       return __cpu_architecture;
+}
+
 static int cpu_has_aliasing_icache(unsigned int arch)
 {
        int aliasing_icache;
@@ -280,18 +297,19 @@ static void __init cacheid_init(void)
        if (arch >= CPU_ARCH_ARMv6) {
                if ((cachetype & (7 << 29)) == 4 << 29) {
                        /* ARMv7 register format */
+                       arch = CPU_ARCH_ARMv7;
                        cacheid = CACHEID_VIPT_NONALIASING;
                        if ((cachetype & (3 << 14)) == 1 << 14)
                                cacheid |= CACHEID_ASID_TAGGED;
-                       else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
-                               cacheid |= CACHEID_VIPT_I_ALIASING;
-               } else if (cachetype & (1 << 23)) {
-                       cacheid = CACHEID_VIPT_ALIASING;
                } else {
-                       cacheid = CACHEID_VIPT_NONALIASING;
-                       if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
-                               cacheid |= CACHEID_VIPT_I_ALIASING;
+                       arch = CPU_ARCH_ARMv6;
+                       if (cachetype & (1 << 23))
+                               cacheid = CACHEID_VIPT_ALIASING;
+                       else
+                               cacheid = CACHEID_VIPT_NONALIASING;
                }
+               if (cpu_has_aliasing_icache(arch))
+                       cacheid |= CACHEID_VIPT_I_ALIASING;
        } else {
                cacheid = CACHEID_VIVT;
        }
@@ -413,6 +431,7 @@ static void __init setup_processor(void)
        }
 
        cpu_name = list->cpu_name;
+       __cpu_architecture = __get_cpu_architecture();
 
 #ifdef MULTI_CPU
        processor = *list->proc;
@@ -608,6 +627,16 @@ static int __init parse_tag_mem32(const struct tag *tag)
 
 __tagtable(ATAG_MEM, parse_tag_mem32);
 
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+static int __init parse_tag_mem64(const struct tag *tag)
+{
+       /* We only use 32-bits for the size. */
+       return arm_add_memory(tag->u.mem64.start, (unsigned long)tag->u.mem64.size);
+}
+
+__tagtable(ATAG_MEM64, parse_tag_mem64);
+#endif /* CONFIG_PHYS_ADDR_T_64BIT */
+
 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 struct screen_info screen_info = {
  .orig_video_lines     = 30,
index dc902f2c68457b0f3277b8112a7a1e867106cde8..ecece65251fadb3ea9e4adacbc8ac0d388c2d3d9 100644 (file)
@@ -85,8 +85,10 @@ ENDPROC(cpu_resume_mmu)
        .ltorg
        .align  5
 cpu_resume_turn_mmu_on:
+       instr_sync
        mcr     p15, 0, r1, c1, c0, 0   @ turn on MMU, I-cache, etc
        mrc     p15, 0, r1, c0, c0, 0   @ read id reg
+       instr_sync
        mov     r1, r1
        mov     r1, r1
        mov     pc, r3                  @ jump to virtual address
index d88ff0230e826f8ea15a60560668dcf81ef80373..62775c5c5ba069ca9c854d41b9639dc92fdda24a 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
+#include <asm/topology.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -268,6 +269,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
        struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
 
        cpu_info->loops_per_jiffy = loops_per_jiffy;
+
+       store_cpu_topology(cpuid);
 }
 
 /*
@@ -358,6 +361,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        unsigned int ncores = num_possible_cpus();
 
+       init_cpu_topology();
+
        smp_store_cpu_info(smp_processor_id());
 
        /*
index 2c277d40cee681ccc496239b3ab6724259a35756..01c186222f3b9d132c670bdba6721a7b3b8f50ce 100644 (file)
@@ -137,8 +137,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
        clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
        clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
 
+       clockevents_register_device(clk);
+
        /* Make sure our local interrupt controller has this enabled */
        gic_enable_ppi(clk->irq);
-
-       clockevents_register_device(clk);
 }
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
new file mode 100644 (file)
index 0000000..1040c00
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * arch/arm/kernel/topology.c
+ *
+ * Copyright (C) 2011 Linaro Limited.
+ * Written by: Vincent Guittot
+ *
+ * based on arch/sh/kernel/topology.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+
+#include <asm/cputype.h>
+#include <asm/topology.h>
+
+#define MPIDR_SMP_BITMASK (0x3 << 30)
+#define MPIDR_SMP_VALUE (0x2 << 30)
+
+#define MPIDR_MT_BITMASK (0x1 << 24)
+
+/*
+ * These masks reflect the current use of the affinity levels.
+ * The affinity level can be up to 16 bits according to ARM ARM
+ */
+
+#define MPIDR_LEVEL0_MASK 0x3
+#define MPIDR_LEVEL0_SHIFT 0
+
+#define MPIDR_LEVEL1_MASK 0xF
+#define MPIDR_LEVEL1_SHIFT 8
+
+#define MPIDR_LEVEL2_MASK 0xFF
+#define MPIDR_LEVEL2_SHIFT 16
+
+struct cputopo_arm cpu_topology[NR_CPUS];
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+{
+       return &cpu_topology[cpu].core_sibling;
+}
+
+/*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+ * which prevents simultaneous write access to cpu_topology array
+ */
+void store_cpu_topology(unsigned int cpuid)
+{
+       struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
+       unsigned int mpidr;
+       unsigned int cpu;
+
+       /* If the cpu topology has been already set, just return */
+       if (cpuid_topo->core_id != -1)
+               return;
+
+       mpidr = read_cpuid_mpidr();
+
+       /* create cpu topology mapping */
+       if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
+               /*
+                * This is a multiprocessor system
+                * multiprocessor format & multiprocessor mode field are set
+                */
+
+               if (mpidr & MPIDR_MT_BITMASK) {
+                       /* core performance interdependency */
+                       cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
+                               & MPIDR_LEVEL0_MASK;
+                       cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
+                               & MPIDR_LEVEL1_MASK;
+                       cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT)
+                               & MPIDR_LEVEL2_MASK;
+               } else {
+                       /* largely independent cores */
+                       cpuid_topo->thread_id = -1;
+                       cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
+                               & MPIDR_LEVEL0_MASK;
+                       cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
+                               & MPIDR_LEVEL1_MASK;
+               }
+       } else {
+               /*
+                * This is an uniprocessor system
+                * we are in multiprocessor format but uniprocessor system
+                * or in the old uniprocessor format
+                */
+               cpuid_topo->thread_id = -1;
+               cpuid_topo->core_id = 0;
+               cpuid_topo->socket_id = -1;
+       }
+
+       /* update core and thread sibling masks */
+       for_each_possible_cpu(cpu) {
+               struct cputopo_arm *cpu_topo = &cpu_topology[cpu];
+
+               if (cpuid_topo->socket_id == cpu_topo->socket_id) {
+                       cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+                       if (cpu != cpuid)
+                               cpumask_set_cpu(cpu,
+                                       &cpuid_topo->core_sibling);
+
+                       if (cpuid_topo->core_id == cpu_topo->core_id) {
+                               cpumask_set_cpu(cpuid,
+                                       &cpu_topo->thread_sibling);
+                               if (cpu != cpuid)
+                                       cpumask_set_cpu(cpu,
+                                               &cpuid_topo->thread_sibling);
+                       }
+               }
+       }
+       smp_wmb();
+
+       printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
+               cpuid, cpu_topology[cpuid].thread_id,
+               cpu_topology[cpuid].core_id,
+               cpu_topology[cpuid].socket_id, mpidr);
+}
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void init_cpu_topology(void)
+{
+       unsigned int cpu;
+
+       /* init core mask */
+       for_each_possible_cpu(cpu) {
+               struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
+
+               cpu_topo->thread_id = -1;
+               cpu_topo->core_id =  -1;
+               cpu_topo->socket_id = -1;
+               cpumask_clear(&cpu_topo->core_sibling);
+               cpumask_clear(&cpu_topo->thread_sibling);
+       }
+       smp_wmb();
+}
index 3462b815054ace1695cfe1f5f9bddc3358e4d513..9ab5a3e5f4f16679129fd8917a7d8882ce253614 100644 (file)
@@ -4,15 +4,15 @@
 #   INITRD_PHYS must be in RAM
 
 ifeq ($(CONFIG_ARCH_AT91CAP9),y)
-   zreladdr-y  := 0x70008000
+   zreladdr-y  += 0x70008000
 params_phys-y  := 0x70000100
 initrd_phys-y  := 0x70410000
 else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
-   zreladdr-y  := 0x70008000
+   zreladdr-y  += 0x70008000
 params_phys-y  := 0x70000100
 initrd_phys-y  := 0x70410000
 else
-   zreladdr-y  := 0x20008000
+   zreladdr-y  += 0x20008000
 params_phys-y  := 0x20000100
 initrd_phys-y  := 0x20410000
 endif
index dba0d8d8a4bd185dd96054cbc466b9a2a6c825d7..f87f5040e78ef18d7e2fca5b355684e9b121bc3e 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/mach/irq.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -23,7 +24,6 @@
 
 #include <mach/board.h>
 #include <mach/cpu.h>
-#include <mach/gpio.h>
 #include <mach/at91cap9.h>
 #include <mach/at91cap9_matrix.h>
 #include <mach/at91sam9_smc.h>
index 7227755ffec643fae52b92ebd71844581fb1ed92..978be950035acb0f9fd4b21c19a3f6e6f11521af 100644 (file)
 #include <asm/mach/map.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91rm9200.h>
 #include <mach/at91rm9200_mc.h>
 
index 39f81f47b4ba4d4fe12c02e852cae1afb97b661b..3c2b580b9d758a62279cfe9c76b532ae16647bd6 100644 (file)
 #include <asm/mach/map.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 #include <mach/at91sam9260.h>
 #include <mach/at91sam9260_matrix.h>
@@ -319,7 +319,7 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
        if (!data)
                return;
 
-       for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+       for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                if (data->slot[i].bus_width) {
                        /* input/irq */
                        if (data->slot[i].detect_pin) {
index 0f917928eeb7782510f7b590d8e627a8b319795a..4e647b653339d4dc64f31302078036ffe85310cb 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -21,7 +22,6 @@
 #include <video/atmel_lcdc.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9261.h>
 #include <mach/at91sam9261_matrix.h>
 #include <mach/at91sam9_smc.h>
index a050f41fc860d7698b2a8ba83b29221f14805d22..dd7662bc395f5b319be704007262ece04ab715b7 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -20,7 +21,6 @@
 #include <video/atmel_lcdc.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9263.h>
 #include <mach/at91sam9263_matrix.h>
 #include <mach/at91sam9_smc.h>
index 600bffb01edb9b056f0e45cdb0bbf5960f1cea6a..c3dfb1b3b1e3a6032e554c273f05bf81699579a8 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 #include <linux/atmel-mci.h>
@@ -21,7 +22,6 @@
 #include <video/atmel_lcdc.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9g45.h>
 #include <mach/at91sam9g45_matrix.h>
 #include <mach/at91sam9_smc.h>
index aacb19dc9225a7c90554ee6e03e7610d90df57cb..305a851b5bff950f60b374fc5ab709f51bbebdaf 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 
@@ -17,7 +18,6 @@
 #include <video/atmel_lcdc.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9rl.h>
 #include <mach/at91sam9rl_matrix.h>
 #include <mach/at91sam9_smc.h>
index 5aa58851eb394b43c1c0f972465e766d5bab4a38..367d5cd5e36288c1c5395aedc6eaec91e2138ccf 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -34,7 +35,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
index b0c796d42e495bf1158da2d19fda3c8cb0bf90dc..4282d96dffa808b1ebf059227d088ca3b92ec441 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -43,7 +44,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
@@ -130,19 +130,14 @@ static struct mtd_partition __initdata afeb9260_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(afeb9260_nand_partition);
-       return afeb9260_nand_partition;
-}
-
 static struct atmel_nand_data __initdata afeb9260_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
        .bus_width_16   = 0,
+       .parts          = afeb9260_nand_partition,
+       .num_parts      = ARRAY_SIZE(afeb9260_nand_partition),
 };
 
 
index d1abd5898e85bb53c8f48b9c703f393a9f86776c..f90cfb32bad2b89815c0ed292b15721dcaa393be 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -38,7 +39,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 
 #include "sam9_smc.h"
@@ -132,19 +132,14 @@ static struct mtd_partition __initdata cam60_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(cam60_nand_partition);
-       return cam60_nand_partition;
-}
-
 static struct atmel_nand_data __initdata cam60_nand_data = {
        .ale            = 21,
        .cle            = 22,
        // .det_pin     = ... not there
        .rdy_pin        = AT91_PIN_PA9,
        .enable_pin     = AT91_PIN_PA7,
-       .partition_info = nand_partitions,
+       .parts          = cam60_nand_partition,
+       .num_parts      = ARRAY_SIZE(cam60_nand_partition),
 };
 
 static struct sam9_smc_config __initdata cam60_nand_smc_config = {
index 679b0b743e9277d1e7994c314359f5db6a844603..5dffd3be62d25878b52cdbb46150a7d71ad965ac 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -41,7 +42,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91cap9_matrix.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/system_rev.h>
@@ -169,19 +169,14 @@ static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(cap9adk_nand_partitions);
-       return cap9adk_nand_partitions;
-}
-
 static struct atmel_nand_data __initdata cap9adk_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
 //     .rdy_pin        = ... not connected
        .enable_pin     = AT91_PIN_PD15,
-       .partition_info = nand_partitions,
+       .parts          = cap9adk_nand_partitions,
+       .num_parts      = ARRAY_SIZE(cap9adk_nand_partitions),
 };
 
 static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
index c578c5d9072887334e3a4e354de5d80b0fa18c8d..774c87fcbd5b8f0ee355bf7b9d7c84822eb95ac9 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -35,7 +36,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
index f4da8a16d5dc14fa0c558bb2b66e2392a2d150e7..fc885a4ce243fbedce8461435cf966c859f68886 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -40,7 +41,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91sam9260_matrix.h>
 
index 2d919f5a4f571cfcfcf884c13d8a4465cfd88e02..d35e65b08ccde481aeac88978fd83d7ca1a329c1 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -36,7 +37,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
 #include <mach/cpu.h>
 
index 17654d5e94e6fd3aefe8055227246e9222878c3c..c3936665e6457715dedaccb0a8b0be0e0fc5f936 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -38,7 +39,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
index 72b55674616c30d0ab08b0f465e5fc891744d94c..586100e2acbbb5b54c3820b0acd34dafc14f23df 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -35,7 +36,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
index 01170a2766a82e5169b0ef35ae8dacc94867a9ae..45db7a3dbef01b960caa77ff7495a3096a9308bd 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -35,7 +36,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
index 7c0313c51f2673f8491ebb97e681c1b21a2cef35..2f9c16d29212332f195c85ae7e6e7bc7b3e814c2 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -37,7 +38,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
index 4a170890b3b1c9976036d4e527c91c9370550ac9..3bae73e636332fc5ccfef18b6e02c09915728b2d 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -34,7 +35,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
index 9dc8d496ead1bfa6c796c8fc445c23c76f944a28..e61351ffad50c15399dba98cb7b8b7fa9116728e 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -35,7 +36,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 #include <mach/at91rm9200_mc.h>
 
@@ -97,19 +97,14 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(kb9202_nand_partition);
-       return kb9202_nand_partition;
-}
-
 static struct atmel_nand_data __initdata kb9202_nand_data = {
        .ale            = 22,
        .cle            = 21,
        // .det_pin     = ... not there
        .rdy_pin        = AT91_PIN_PC29,
        .enable_pin     = AT91_PIN_PC28,
-       .partition_info = nand_partitions,
+       .parts          = kb9202_nand_partition,
+       .num_parts      = ARRAY_SIZE(kb9202_nand_partition),
 };
 
 static void __init kb9202_board_init(void)
index 9bc6ab32e0acd2bb9b7d3f60ebd8c0a77d8980b3..ef816c17dc61ebd0a0b9fb0c04ab134912f5b4c7 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -44,7 +45,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 
 #include "sam9_smc.h"
@@ -182,19 +182,14 @@ static struct mtd_partition __initdata neocore926_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(neocore926_nand_partition);
-       return neocore926_nand_partition;
-}
-
 static struct atmel_nand_data __initdata neocore926_nand_data = {
        .ale                    = 21,
        .cle                    = 22,
        .rdy_pin                = AT91_PIN_PB19,
        .rdy_pin_active_low     = 1,
        .enable_pin             = AT91_PIN_PD15,
-       .partition_info         = nand_partitions,
+       .parts                  = neocore926_nand_partition,
+       .num_parts              = ARRAY_SIZE(neocore926_nand_partition),
 };
 
 static struct sam9_smc_config __initdata neocore926_nand_smc_config = {
index b7b8390e8a00b732f882fefd3b64673880de285d..0a8fe6a1b7c8a8a606241f46d8a0a2ff133a75e7 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -37,7 +38,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
 
 #include "generic.h"
index 81f911033681004be055a80a84ded42874644af5..07421bdb88eaf7f1b985a39c23bac74a7d61dd08 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -40,7 +41,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 
@@ -130,19 +130,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 6f08faadb4742b8faef2de1f84e90cb5ca137454..80a8c9c6e92221f53b2024f95d41a1be80e90afe 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -39,7 +40,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
 
 #include "generic.h"
@@ -138,19 +138,14 @@ static struct mtd_partition __initdata dk_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(dk_nand_partition);
-       return dk_nand_partition;
-}
-
 static struct atmel_nand_data __initdata dk_nand_data = {
        .ale            = 22,
        .cle            = 21,
        .det_pin        = AT91_PIN_PB1,
        .rdy_pin        = AT91_PIN_PC2,
        // .enable_pin  = ... not there
-       .partition_info = nand_partitions,
+       .parts          = dk_nand_partition,
+       .num_parts      = ARRAY_SIZE(dk_nand_partition),
 };
 
 #define DK_FLASH_BASE  AT91_CHIPSELECT_0
index 85bcccd7b9e40118b7c8a72eb12c64609d38c287..99fd7f8aee0e0f378583365575d3be4bd9127bfe 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -39,7 +40,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
 
 #include "generic.h"
index 4d3a02f1289e87fd9c025170240364d4ef2f7a44..072d53af98d9ebdd594dc9d17efd68c479341976 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -37,7 +38,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 
 #include "sam9_smc.h"
@@ -131,19 +131,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 8a50c3e67186f1e8b8d4b0a962ab245aac6d51d6..4f10181a07822b4a4a93b0634aa668f428951a19 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -41,7 +42,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 #include <mach/system_rev.h>
@@ -173,19 +173,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 5096a0ec50c13c8a64ab041b064e960c5f4aa0d4..b005b738e8ff7bc6dc4af3c8e173421bd9b234c7 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -45,7 +46,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 #include <mach/system_rev.h>
@@ -179,19 +179,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 22,
        .cle            = 21,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC15,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index ea8f185d3b9d342b7cdcf19e1c8bff5e54af0574..bccdcf23caa106e392dba97fa4df69f9775a5337 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -44,7 +45,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 #include <mach/system_rev.h>
@@ -180,19 +180,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PA22,
        .enable_pin     = AT91_PIN_PD15,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 817f59d7251bcc9dfc8ab9dbae37c18b85f840d2..64fc75c9d0ac118730cac024eeb94c4d3da17611 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -41,7 +42,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/system_rev.h>
 
@@ -157,19 +157,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 /* det_pin is not connected */
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index ad234ccbf57e5214d8e0ebb0eec63a00fa80ef68..92de9127923a6dd0ecf6b61780129a1e3e9d6cf2 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -38,7 +39,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 #include <mach/system_rev.h>
@@ -137,19 +137,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 /* det_pin is not connected */
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC8,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 4f14b54b93a88278bef0ad5ab854d3bd497cce92..b2b748239f365ab77627a6d96a7c442be91fd161 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -30,7 +31,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 
@@ -88,19 +88,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PD17,
        .enable_pin     = AT91_PIN_PB6,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index c73d25e5faea84c876b4b7e539aa0f68eb3e2271..0df01c6e2d0c1b458bc89ac41e46740302eda69b 100644 (file)
@@ -97,18 +97,12 @@ static struct mtd_partition __initdata snapper9260_nand_partitions[] = {
        },
 };
 
-static struct mtd_partition * __init
-snapper9260_nand_partition_info(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(snapper9260_nand_partitions);
-       return snapper9260_nand_partitions;
-}
-
 static struct atmel_nand_data __initdata snapper9260_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC13,
-       .partition_info = snapper9260_nand_partition_info,
+       .parts          = snapper9260_nand_partitions,
+       .num_parts      = ARRAY_SIZE(snapper9260_nand_partitions),
        .bus_width_16   = 0,
 };
 
index 8c4c1a02c4bebb45e8b11bb22905a744975f0f75..da2f659ff0b2bc9372208314ab999993a0e01f33 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -40,7 +41,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 
@@ -104,19 +104,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        }
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 25e793782a4e94c3ac49f9f9bc1c3a71a7c60d22..b37500b575f233d816081ef4c8672f67a2cf1536 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -39,7 +40,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
 
@@ -117,19 +117,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        }
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PA22,
        .enable_pin     = AT91_PIN_PD15,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 95edcbd2aec64c0107e8dab5ca233706af65ca76..649b052231f5aad9ea812547aed176bd3bd5ebcf 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -43,7 +44,6 @@
 
 #include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
 #include <mach/cpu.h>
 
@@ -172,19 +172,14 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = {
        }
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(yl9200_nand_partition);
-       return yl9200_nand_partition;
-}
-
 static struct atmel_nand_data __initdata yl9200_nand_data = {
        .ale            = 6,
        .cle            = 7,
        // .det_pin     = ... not connected
        .rdy_pin        = AT91_PIN_PC14,        /* R/!B (Sheet10) */
        .enable_pin     = AT91_PIN_PC15,        /* !CE  (Sheet10) */
-       .partition_info = nand_partitions,
+       .parts          = yl9200_nand_partition,
+       .num_parts      = ARRAY_SIZE(yl9200_nand_partition),
 };
 
 /*
index 4615528205c8329522b360b3b95e4fee4e89279c..224e9e2f867453bd85b08b371edf888f961d6e6e 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/errno.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/debugfs.h>
@@ -22,9 +23,6 @@
 
 #include <mach/hardware.h>
 #include <mach/at91_pio.h>
-#include <mach/gpio.h>
-
-#include <asm/gpio.h>
 
 #include "generic.h"
 
index ed544a0d5a1d8b5ce5bc4681ed7e83ef704ab41d..664353198bc0a7970ac5143dc39211217aef9938 100644 (file)
@@ -112,7 +112,8 @@ struct atmel_nand_data {
        u8              ale;            /* address line number connected to ALE */
        u8              cle;            /* address line number connected to CLE */
        u8              bus_width_16;   /* buswidth is 16 bit */
-       struct mtd_partition* (*partition_info)(int, int*);
+       struct mtd_partition *parts;
+       unsigned int    num_parts;
 };
 extern void __init at91_add_device_nand(struct atmel_nand_data *data);
 
index 056dc6674b6bf74c649cabe60204ebbf01ff9a03..2b9a1f51210f0cc048048410bd9e801883e04bc9 100644 (file)
@@ -214,11 +214,6 @@ extern void at91_gpio_resume(void);
  */
 
 #include <asm/errno.h>
-#include <asm-generic/gpio.h>          /* cansleep wrappers */
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
 
 #define gpio_to_irq(gpio) (gpio)
 #define irq_to_gpio(irq)  (irq)
index 0415a839e1ad9319944a662b409799015f9fde3d..8dfafe76ffe6298f822ad2b4d3ea64ebf0243337 100644 (file)
@@ -9,13 +9,13 @@
  * 2 of the License, or (at your option) any later version.
 */
 
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
 
 
 /* ------------------------------------------------------------------------- */
index 4159eca78945360b8b9a4fc5630ba5ddab7e07a8..7046158109d7cd581776466798becc3abbe83f47 100644 (file)
@@ -10,6 +10,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/gpio.h>
 #include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
@@ -25,7 +26,6 @@
 #include <asm/mach/irq.h>
 
 #include <mach/at91_pmc.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
index fb53b283bebb37b1d4714d93dc775c095fb17755..aef2467757fa9afbb0e08803d9a35f5bc3a2a61a 100644 (file)
@@ -1,6 +1,6 @@
 # Address where decompressor will be written and eventually executed.
 #
 # default to SDRAM
-zreladdr-y      := $(CONFIG_BCM_ZRELADDR)
+zreladdr-y      += $(CONFIG_BCM_ZRELADDR)
 params_phys-y   := 0x00000800
 
index a51fcef64fe0bb2324db6a1225c6d06dff9913d6..9398e859b5afd59a5dfad462a66001b6f71e40b4 100644 (file)
@@ -1,5 +1,5 @@
 # The standard locations for stuff on CLPS711x type processors
-   zreladdr-y                          := 0xc0028000
+   zreladdr-y                          += 0xc0028000
 params_phys-y                          := 0xc0000100
 # Should probably have some agreement on these...
 initrd_phys-$(CONFIG_ARCH_P720T)       := 0xc0400000
index 777012865220754fc511d58133847eac0406cc61..d079de0b6e3b54b5e9c3ad2581690bf5320c1e9c 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00C00000
index 0b87a1ca2bb3a187c78a6b20b68f7c8bb66c2288..495e31306fc00a213f3084daf20894bfa94c53bd 100644 (file)
@@ -5,7 +5,7 @@
 
 # Common objects
 obj-y                  := time.o clock.o serial.o io.o psc.o \
-                          gpio.o dma.o usb.o common.o sram.o aemif.o
+                          dma.o usb.o common.o sram.o aemif.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
 
@@ -17,7 +17,6 @@ obj-$(CONFIG_ARCH_DAVINCI_DM365)      += dm365.o devices.o
 obj-$(CONFIG_ARCH_DAVINCI_DA830)        += da830.o devices-da8xx.o
 obj-$(CONFIG_ARCH_DAVINCI_DA850)        += da850.o devices-da8xx.o
 obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)    += tnetv107x.o devices-tnetv107x.o
-obj-$(CONFIG_ARCH_DAVINCI_TNETV107X)    += gpio-tnetv107x.o
 
 obj-$(CONFIG_AINTC)                    += irq.o
 obj-$(CONFIG_CP_INTC)                  += cp_intc.o
index db97ef2c6477ca0841578018cf0c65d8aab4fa38..04a6c4e67b146dee4aeaab855b55a63f554e3674 100644 (file)
@@ -2,12 +2,12 @@ ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
 ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
 $(error Cannot enable DaVinci and DA8XX platforms concurrently)
 else
-   zreladdr-y  := 0xc0008000
+   zreladdr-y  += 0xc0008000
 params_phys-y  := 0xc0000100
 initrd_phys-y  := 0xc0800000
 endif
 else
-   zreladdr-y  := 0x80008000
+   zreladdr-y  += 0x80008000
 params_phys-y  := 0x80000100
 initrd_phys-y  := 0x80800000
 endif
index 84fd78684868f7112bd441df1577b18c734656d0..0b36fd54fc47491b93352bc531ddf8affa073f8b 100644 (file)
@@ -377,7 +377,7 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = {
        .nr_parts       = ARRAY_SIZE(da830_evm_nand_partitions),
        .ecc_mode       = NAND_ECC_HW,
        .ecc_bits       = 4,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .bbt_td         = &da830_evm_nand_bbt_main_descr,
        .bbt_md         = &da830_evm_nand_bbt_mirror_descr,
        .timing         = &da830_evm_nandflash_timing,
index bd5394537c88d8f305c9bda5a00cf57214263c12..8193d340de22b3d0f39fca1489f35e5bbe60d98e 100644 (file)
@@ -225,7 +225,7 @@ static struct davinci_nand_pdata da850_evm_nandflash_data = {
        .nr_parts       = ARRAY_SIZE(da850_evm_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
        .ecc_bits       = 4,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .timing         = &da850_evm_nandflash_timing,
 };
 
index 241a6bd67408fc4d5bc895c0c0c48cae48b1ac2c..fe617790fe2b84d93d538365d4ede22b7d9eb338 100644 (file)
@@ -77,7 +77,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .parts                  = davinci_nand_partitions,
        .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
        .ecc_mode               = NAND_ECC_HW,
-       .options                = NAND_USE_FLASH_BBT,
+       .bbt_options            = NAND_BBT_USE_FLASH,
        .ecc_bits               = 4,
 };
 
index bee284ca7fd6103a5622bd33b6c9f471c3c7fc73..249c355127481567263d94117bcad01a9ff4d64c 100644 (file)
@@ -74,7 +74,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .parts                  = davinci_nand_partitions,
        .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
        .ecc_mode               = NAND_ECC_HW_SYNDROME,
-       .options                = NAND_USE_FLASH_BBT,
+       .bbt_options            = NAND_BBT_USE_FLASH,
 };
 
 static struct resource davinci_nand_resources[] = {
index 9818f214d4f0c15b445c16e4eab0dbf6f4731893..e555267f249289777cbbea0016a0e1e080ddd14f 100644 (file)
@@ -139,7 +139,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .parts                  = davinci_nand_partitions,
        .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
        .ecc_mode               = NAND_ECC_HW,
-       .options                = NAND_USE_FLASH_BBT,
+       .bbt_options            = NAND_BBT_USE_FLASH,
        .ecc_bits               = 4,
 };
 
index 95607a191e03ea5d88ce88f6d51836bc54c390e7..8fd305264e83154cbb7c4d20c397b1b98cb5cc68 100644 (file)
@@ -150,7 +150,7 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = {
        .parts          = davinci_evm_nandflash_partition,
        .nr_parts       = ARRAY_SIZE(davinci_evm_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .timing         = &davinci_evm_nandflash_timing,
 };
 
index c278226627ad01368e232ed9ab4b53399ebe2812..dffab31670f7e0c45f99a00be82e22634044f6ec 100644 (file)
@@ -396,7 +396,8 @@ static struct davinci_nand_pdata mityomapl138_nandflash_data = {
        .parts          = mityomapl138_nandflash_partition,
        .nr_parts       = ARRAY_SIZE(mityomapl138_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16,
+       .bbt_options    = NAND_BBT_USE_FLASH,
+       .options        = NAND_BUSWIDTH_16,
        .ecc_bits       = 1, /* 4 bit mode is not supported with 16 bit NAND */
 };
 
index d60a80028ba3c23c6b7a6f78943c6dbc7b968d55..70dcf9f30213a2e249bf1a7882b25245508cc907 100644 (file)
@@ -87,7 +87,7 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
        .parts          = davinci_ntosd2_nandflash_partition,
        .nr_parts       = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
 };
 
 static struct resource davinci_ntosd2_nandflash_resource[] = {
index 78289206568217341aae532579ab84038602996b..75383df868ffe90bc15516e6d5968a7fcad0547d 100644 (file)
@@ -144,7 +144,7 @@ static struct davinci_nand_pdata nand_config = {
        .parts          = nand_partitions,
        .nr_parts       = ARRAY_SIZE(nand_partitions),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .ecc_bits       = 1,
 };
 
index 2ed2f822fc40ca1e79448038c279b3910fe14ab7..a6bf5dcaef1341863d614412fe3bc29275f44a47 100644 (file)
@@ -8,6 +8,7 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 
@@ -19,7 +20,7 @@
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
-#include <mach/gpio.h>
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
index 935dbed5c541ccea2e1d4bbe5e059dfd6295ac03..4aae01576aaba3bdfa667e2ee63db759933b3f64 100644 (file)
@@ -11,6 +11,7 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
@@ -27,7 +28,7 @@
 #include <mach/da8xx.h>
 #include <mach/cpufreq.h>
 #include <mach/pm.h>
-#include <mach/gpio.h>
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
index a3a94e9c93784b10a6d98c3b379a680def7641e2..c143f43addccc2590f5f7cc384ab487425312459 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/gpio.h>
 
 #include <linux/spi/spi.h>
 
@@ -30,6 +29,7 @@
 #include <mach/common.h>
 #include <mach/asp.h>
 #include <mach/spi.h>
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
index 4604e72d7d9947bce4263d7c52b72e66e7620018..679e168dce34e55f4c711d12c01eab4300174bac 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/gpio.h>
 #include <linux/spi/spi.h>
 
 #include <asm/mach/map.h>
@@ -34,7 +33,7 @@
 #include <mach/asp.h>
 #include <mach/keyscan.h>
 #include <mach/spi.h>
-
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
index 4c82c2716293a6e750f242c128fb14e66c2ce636..9a274665edc520527476fd6cb1425b7dbb8f485c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
 
 #include <asm/mach/map.h>
 
@@ -26,6 +25,7 @@
 #include <mach/serial.h>
 #include <mach/common.h>
 #include <mach/asp.h>
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
index 1802e711a2b8f7218131613365f19e4361ff04e2..03e5f4931b423d4612c4f479d1f2cfe2df5acc51 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
 
 #include <asm/mach/map.h>
 
@@ -27,6 +26,7 @@
 #include <mach/serial.h>
 #include <mach/common.h>
 #include <mach/asp.h>
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
diff --git a/arch/arm/mach-davinci/include/mach/gpio-davinci.h b/arch/arm/mach-davinci/include/mach/gpio-davinci.h
new file mode 100644 (file)
index 0000000..1fdd1fd
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef        __DAVINCI_DAVINCI_GPIO_H
+#define        __DAVINCI_DAVINCI_GPIO_H
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm-generic/gpio.h>
+
+#include <mach/irqs.h>
+#include <mach/common.h>
+
+#define DAVINCI_GPIO_BASE 0x01C67000
+
+enum davinci_gpio_type {
+       GPIO_TYPE_DAVINCI = 0,
+       GPIO_TYPE_TNETV107X,
+};
+
+/*
+ * basic gpio routines
+ *
+ * board-specific init should be done by arch/.../.../board-XXX.c (maybe
+ * initializing banks together) rather than boot loaders; kexec() won't
+ * go through boot loaders.
+ *
+ * the gpio clock will be turned on when gpios are used, and you may also
+ * need to pay attention to PINMUX registers to be sure those pins are
+ * used as gpios, not with other peripherals.
+ *
+ * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation,
+ * and maybe for later updates, code may write GPIO(N).  These may be
+ * all 1.8V signals, all 3.3V ones, or a mix of the two.  A given chip
+ * may not support all the GPIOs in that range.
+ *
+ * GPIOs can also be on external chips, numbered after the ones built-in
+ * to the DaVinci chip.  For now, they won't be usable as IRQ sources.
+ */
+#define        GPIO(X)         (X)             /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
+
+/* Convert GPIO signal to GPIO pin number */
+#define GPIO_TO_PIN(bank, gpio)        (16 * (bank) + (gpio))
+
+struct davinci_gpio_controller {
+       struct gpio_chip        chip;
+       int                     irq_base;
+       spinlock_t              lock;
+       void __iomem            *regs;
+       void __iomem            *set_data;
+       void __iomem            *clr_data;
+       void __iomem            *in_data;
+};
+
+/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
+ * with constant parameters; or in outlined code they execute at runtime.
+ *
+ * You'd access the controller directly when reading or writing more than
+ * one gpio value at a time, and to support wired logic where the value
+ * being driven by the cpu need not match the value read back.
+ *
+ * These are NOT part of the cross-platform GPIO interface
+ */
+static inline struct davinci_gpio_controller *
+__gpio_to_controller(unsigned gpio)
+{
+       struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
+       int index = gpio / 32;
+
+       if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
+               return NULL;
+
+       return ctlrs + index;
+}
+
+static inline u32 __gpio_mask(unsigned gpio)
+{
+       return 1 << (gpio % 32);
+}
+
+#endif /* __DAVINCI_DAVINCI_GPIO_H */
index fbece126c2bf2f451a5983207273525be2a9d12a..fbaae4772b91c6237b2a1499b28af7a79eb2de19 100644 (file)
 #ifndef        __DAVINCI_GPIO_H
 #define        __DAVINCI_GPIO_H
 
-#include <linux/io.h>
-#include <linux/spinlock.h>
-
 #include <asm-generic/gpio.h>
 
-#include <mach/irqs.h>
-#include <mach/common.h>
-
-#define DAVINCI_GPIO_BASE 0x01C67000
-
-enum davinci_gpio_type {
-       GPIO_TYPE_DAVINCI = 0,
-       GPIO_TYPE_TNETV107X,
-};
-
-/*
- * basic gpio routines
- *
- * board-specific init should be done by arch/.../.../board-XXX.c (maybe
- * initializing banks together) rather than boot loaders; kexec() won't
- * go through boot loaders.
- *
- * the gpio clock will be turned on when gpios are used, and you may also
- * need to pay attention to PINMUX registers to be sure those pins are
- * used as gpios, not with other peripherals.
- *
- * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation,
- * and maybe for later updates, code may write GPIO(N).  These may be
- * all 1.8V signals, all 3.3V ones, or a mix of the two.  A given chip
- * may not support all the GPIOs in that range.
- *
- * GPIOs can also be on external chips, numbered after the ones built-in
- * to the DaVinci chip.  For now, they won't be usable as IRQ sources.
- */
-#define        GPIO(X)         (X)             /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
-
-/* Convert GPIO signal to GPIO pin number */
-#define GPIO_TO_PIN(bank, gpio)        (16 * (bank) + (gpio))
-
-struct davinci_gpio_controller {
-       struct gpio_chip        chip;
-       int                     irq_base;
-       spinlock_t              lock;
-       void __iomem            *regs;
-       void __iomem            *set_data;
-       void __iomem            *clr_data;
-       void __iomem            *in_data;
-};
-
-/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
- * with constant parameters; or in outlined code they execute at runtime.
- *
- * You'd access the controller directly when reading or writing more than
- * one gpio value at a time, and to support wired logic where the value
- * being driven by the cpu need not match the value read back.
- *
- * These are NOT part of the cross-platform GPIO interface
- */
-static inline struct davinci_gpio_controller *
-__gpio_to_controller(unsigned gpio)
-{
-       struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
-       int index = gpio / 32;
-
-       if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
-               return NULL;
-
-       return ctlrs + index;
-}
-
-static inline u32 __gpio_mask(unsigned gpio)
-{
-       return 1 << (gpio % 32);
-}
+/* The inline versions use the static inlines in the driver header */
+#include "gpio-davinci.h"
 
 /*
  * The get/set/clear functions will inline when called with constant
@@ -147,11 +77,6 @@ static inline int gpio_cansleep(unsigned gpio)
                return __gpio_cansleep(gpio);
 }
 
-static inline int gpio_to_irq(unsigned gpio)
-{
-       return __gpio_to_irq(gpio);
-}
-
 static inline int irq_to_gpio(unsigned irq)
 {
        /* don't support the reverse mapping */
index 025151049f0517a103c4efb96ee86d465c3fff19..1cf555aef896c39342bd7306c09cfa1358451fe6 100644 (file)
@@ -74,8 +74,10 @@ struct davinci_nand_pdata {          /* platform_data */
        nand_ecc_modes_t        ecc_mode;
        u8                      ecc_bits;
 
-       /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+       /* e.g. NAND_BUSWIDTH_16 */
        unsigned                options;
+       /* e.g. NAND_BBT_USE_FLASH */
+       unsigned                bbt_options;
 
        /* Main and mirror bbt descriptor overrides */
        struct nand_bbt_descr   *bbt_td;
index 1b28fdd892a64aac8a1f7a430982d36104aa433f..409bb869c7c766c071bf9838375b2df1410b14f3 100644 (file)
@@ -12,6 +12,7 @@
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
@@ -27,9 +28,9 @@
 #include <mach/psc.h>
 #include <mach/cp_intc.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
 #include <mach/hardware.h>
 #include <mach/tnetv107x.h>
+#include <mach/gpio-davinci.h>
 
 #include "clock.h"
 #include "mux.h"
index 67039c3e0c48fa6b94f1147b3316f74afcecba9e..760a0efe7580b0dd194ff9bfe4295624336bb806 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 23212604493571068450c1c329def3de2f425a11..83cf07c38adab7fd51317400bd7c410732c388ac 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000400
 initrd_phys-y  := 0x00800000
 
index f68daa632af02e8a0bd2b6bbda06b58e100cbf6e..44679db672fbf54b1a55adc0304593e458545ef5 100644 (file)
@@ -13,8 +13,6 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffff
-
 u8 __inb8(unsigned int port);
 void __outb8(u8  val, unsigned int port);
 
index 0ad33f15c622644449eacc1bbf329c05f4741930..d3113a71cb4084f2050c09d772b02d844c9133ea 100644 (file)
@@ -1,14 +1,14 @@
-   zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET)    := 0x00008000
+   zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET)    += 0x00008000
 params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET)    := 0x00000100
 
-   zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)         := 0xc0008000
+   zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)         += 0xc0008000
 params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)         := 0xc0000100
 
-   zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)         := 0xd0008000
+   zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)         += 0xd0008000
 params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)         := 0xd0000100
 
-   zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)         := 0xe0008000
+   zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)         += 0xe0008000
 params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)         := 0xe0000100
 
-   zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)   := 0xf0008000
+   zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)   += 0xf0008000
 params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)   := 0xf0000100
index c57152c231f16a474442c0d65cefc2e9de8342cb..76c68faca943a9c60d0c0bd9ce524f9c451994c2 100644 (file)
 /* maximum value for irq capable line identifiers */
 #define EP93XX_GPIO_LINE_MAX_IRQ       EP93XX_GPIO_LINE_F(7)
 
-/* new generic GPIO API - see Documentation/gpio.txt */
-
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-
-/*
- * Map GPIO A0..A7  (0..7)  to irq 64..71,
- *          B0..B7  (7..15) to irq 72..79, and
- *          F0..F7 (16..24) to irq 80..87.
- */
-#define gpio_to_irq(gpio)      \
-       (((gpio) <= EP93XX_GPIO_LINE_MAX_IRQ) ? (64 + (gpio)) : -EINVAL)
-
+#define gpio_to_irq            __gpio_to_irq
 #define irq_to_gpio(irq)       ((irq) - gpio_to_irq(0))
 
 #endif
index 0eabec62cd9df5d97a747978003dde74990c8ed0..f1397a13e76b87b563b4343c848a023f57e71f09 100644 (file)
@@ -6,7 +6,7 @@
  * TS72xx memory map:
  *
  * virt                phys            size
- * febff000    22000000        4K      model number register
+ * febff000    22000000        4K      model number register (bits 0-2)
  * febfe000    22400000        4K      options register
  * febfd000    22800000        4K      options register #2
  * febf9000    10800000        4K      TS-5620 RTC index register
@@ -20,6 +20,9 @@
 #define TS72XX_MODEL_TS7200            0x00
 #define TS72XX_MODEL_TS7250            0x01
 #define TS72XX_MODEL_TS7260            0x02
+#define TS72XX_MODEL_TS7300            0x03
+#define TS72XX_MODEL_TS7400            0x04
+#define TS72XX_MODEL_MASK              0x07
 
 
 #define TS72XX_OPTIONS_PHYS_BASE       0x22400000
 
 #ifndef __ASSEMBLY__
 
+static inline int ts72xx_model(void)
+{
+       return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK;
+}
+
 static inline int board_is_ts7200(void)
 {
-       return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200;
+       return ts72xx_model() == TS72XX_MODEL_TS7200;
 }
 
 static inline int board_is_ts7250(void)
 {
-       return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250;
+       return ts72xx_model() == TS72XX_MODEL_TS7250;
 }
 
 static inline int board_is_ts7260(void)
 {
-       return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260;
+       return ts72xx_model() == TS72XX_MODEL_TS7260;
+}
+
+static inline int board_is_ts7300(void)
+{
+       return ts72xx_model()  == TS72XX_MODEL_TS7300;
+}
+
+static inline int board_is_ts7400(void)
+{
+       return ts72xx_model() == TS72XX_MODEL_TS7400;
 }
 
 static inline int is_max197_installed(void)
index c2d2cf40ead920f323a717185b9fc715d704d96d..dea42e262151a1502cc39e19c5b9c41c78fd4de1 100644 (file)
@@ -116,8 +116,9 @@ static struct mtd_partition ts72xx_nand_parts[] = {
                .mask_flags     = MTD_WRITEABLE,        /* force read-only */
        }, {
                .name           = "Linux",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 0,                    /* filled in later */
+               .offset         = MTDPART_OFS_RETAIN,
+               .size           = TS72XX_REDBOOT_PART_SIZE,
+                               /* leave so much for last partition */
        }, {
                .name           = "RedBoot",
                .offset         = MTDPART_OFS_APPEND,
@@ -126,28 +127,14 @@ static struct mtd_partition ts72xx_nand_parts[] = {
        },
 };
 
-static void ts72xx_nand_set_parts(uint64_t size,
-                                 struct platform_nand_chip *chip)
-{
-       /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */
-       if (size == SZ_32M || size == SZ_128M) {
-               /* Set the "Linux" partition size */
-               ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE;
-
-               chip->partitions = ts72xx_nand_parts;
-               chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts);
-       } else {
-               pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20);
-       }
-}
-
 static struct platform_nand_data ts72xx_nand_data = {
        .chip = {
                .nr_chips       = 1,
                .chip_offset    = 0,
                .chip_delay     = 15,
                .part_probe_types = ts72xx_nand_part_probes,
-               .set_parts      = ts72xx_nand_set_parts,
+               .partitions     = ts72xx_nand_parts,
+               .nr_partitions  = ARRAY_SIZE(ts72xx_nand_parts),
        },
        .ctrl = {
                .cmd_ctrl       = ts72xx_nand_hwcontrol,
index 0c77ab99fa16a754794ece0407b4dae95ee114da..e6925de41ce7b5be49dc0916a0d0d3231b93013e 100644 (file)
@@ -139,6 +139,7 @@ config MACH_SMDKV310
        select S3C_DEV_RTC
        select S3C_DEV_WDT
        select S3C_DEV_I2C1
+       select S5P_DEV_MFC
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_HSMMC2
@@ -178,6 +179,7 @@ config MACH_UNIVERSAL_C210
        select S5P_DEV_FIMC1
        select S5P_DEV_FIMC2
        select S5P_DEV_FIMC3
+       select S5P_DEV_FIMD0
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC2
        select S3C_DEV_HSMMC3
@@ -187,6 +189,7 @@ config MACH_UNIVERSAL_C210
        select S5P_DEV_MFC
        select S5P_DEV_ONENAND
        select EXYNOS4_DEV_PD
+       select EXYNOS4_SETUP_FIMD0
        select EXYNOS4_SETUP_I2C1
        select EXYNOS4_SETUP_I2C3
        select EXYNOS4_SETUP_I2C5
@@ -199,6 +202,8 @@ config MACH_NURI
        bool "Mobile NURI Board"
        select CPU_EXYNOS4210
        select S3C_DEV_WDT
+       select S3C_DEV_RTC
+       select S5P_DEV_FIMD0
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC2
        select S3C_DEV_HSMMC3
@@ -208,6 +213,7 @@ config MACH_NURI
        select S5P_DEV_MFC
        select S5P_DEV_USB_EHCI
        select EXYNOS4_DEV_PD
+       select EXYNOS4_SETUP_FIMD0
        select EXYNOS4_SETUP_I2C1
        select EXYNOS4_SETUP_I2C3
        select EXYNOS4_SETUP_I2C5
@@ -218,6 +224,16 @@ config MACH_NURI
        help
          Machine support for Samsung Mobile NURI Board.
 
+config MACH_ORIGEN
+       bool "ORIGEN"
+       select CPU_EXYNOS4210
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C_DEV_HSMMC2
+       select EXYNOS4_SETUP_SDHCI
+       help
+         Machine support for ORIGEN based on Samsung EXYNOS4210
+
 endmenu
 
 comment "Configuration for HSMMC bus width"
index b7fe1d7b0b1fb087f8813cbd8a4ba7cc0156686d..cbc9767014328d5dfff4cb0fa78dcc571d9c2d9b 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_SMDKV310)           += mach-smdkv310.o
 obj-$(CONFIG_MACH_ARMLEX4210)          += mach-armlex4210.o
 obj-$(CONFIG_MACH_UNIVERSAL_C210)      += mach-universal_c210.o
 obj-$(CONFIG_MACH_NURI)                        += mach-nuri.o
+obj-$(CONFIG_MACH_ORIGEN)              += mach-origen.o
 
 # device support
 
index d65956ffb43dddddb7d32a7b897544e7caf73f06..b9862e22bf10a3ecc4ccca0c6e7ece16f3f3a2bb 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x40008000
+   zreladdr-y  += 0x40008000
 params_phys-y  := 0x40000100
index 851dea018578db02d58ee39b0d39b0f09f652fb0..1561b036a9bf2fd3ac9c4221df04e5117df6d3f6 100644 (file)
@@ -520,7 +520,7 @@ static struct clk init_clocks_off[] = {
                .ctrlbit        = (1 << 21),
        }, {
                .name           = "ac97",
-               .id             = -1,
+               .devname        = "samsung-ac97",
                .enable         = exynos4_clk_ip_peril_ctrl,
                .ctrlbit        = (1 << 27),
        }, {
index 2d8a40c9e6e5a69c49cf48f642bd38aa7bff30f5..746d6fc6d397dc23dffd93ea3764c80fd0db3bb0 100644 (file)
 #include <plat/exynos4.h>
 #include <plat/adc-core.h>
 #include <plat/sdhci.h>
-#include <plat/devs.h>
 #include <plat/fb-core.h>
 #include <plat/fimc-core.h>
 #include <plat/iic-core.h>
+#include <plat/reset.h>
 
 #include <mach/regs-irq.h>
+#include <mach/regs-pmu.h>
 
 extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
                         unsigned int irq_start);
@@ -128,6 +129,11 @@ static void exynos4_idle(void)
        local_irq_enable();
 }
 
+static void exynos4_sw_reset(void)
+{
+       __raw_writel(0x1, S5P_SWRESET);
+}
+
 /*
  * exynos4_map_io
  *
@@ -241,5 +247,8 @@ int __init exynos4_init(void)
        /* set idle function */
        pm_idle = exynos4_idle;
 
+       /* set sw_reset function */
+       s5p_reset_hook = exynos4_sw_reset;
+
        return sysdev_register(&exynos4_sysdev);
 }
index be9266b10fdb66b2a5e0deb6896e8d1b50328fcc..80523ca9bb49b87030220b9725e3c58b4922ed53 100644 (file)
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H __FILE__
 
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
 /* Practically, GPIO banks up to GPZ are the configurable gpio banks */
 
 /* GPIO bank sizes */
@@ -151,6 +146,4 @@ enum s5p_gpio_number {
 #define ARCH_NR_GPIOS          (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) +       \
                                 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
 
-#include <asm-generic/gpio.h>
-
 #endif /* __ASM_ARCH_GPIO_H */
index 934d2a493982ca7a3951540b2ffbaf1bca25219f..f8952f8f3757760029e7d95d077ed99cd6e119f4 100644 (file)
@@ -80,9 +80,8 @@
 #define IRQ_HSMMC3             IRQ_SPI(76)
 #define IRQ_DWMCI              IRQ_SPI(77)
 
-#define IRQ_MIPICSI0           IRQ_SPI(78)
-
-#define IRQ_MIPICSI1           IRQ_SPI(80)
+#define IRQ_MIPI_CSIS0         IRQ_SPI(78)
+#define IRQ_MIPI_CSIS1         IRQ_SPI(80)
 
 #define IRQ_ONENAND_AUDI       IRQ_SPI(82)
 #define IRQ_ROTATOR            IRQ_SPI(83)
index fa49bbb8e7b01c2e1cf49497af543c205b432d75..cdf9b47c303cea185e668f7c52e1c28cb5dac4fd 100644 (file)
@@ -29,6 +29,8 @@
 #define S5P_USE_STANDBY_WFE1                   (1 << 25)
 #define S5P_USE_MASK                           ((0x3 << 16) | (0x3 << 24))
 
+#define S5P_SWRESET                            S5P_PMUREG(0x0400)
+
 #define S5P_WAKEUP_STAT                                S5P_PMUREG(0x0600)
 #define S5P_EINT_WAKEUP_MASK                   S5P_PMUREG(0x0604)
 #define S5P_WAKEUP_MASK                                S5P_PMUREG(0x0608)
index 9d87d2ac7f687303547a57aece1fd19f10d91384..badb8c66fc9bc907c6950806f2e9f63357dc06f8 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <mach/regs-gpio.h>
 
+#include <asm/mach/irq.h>
+
 static DEFINE_SPINLOCK(eint_lock);
 
 static unsigned int eint0_15_data[16];
@@ -184,8 +186,11 @@ static inline void exynos4_irq_demux_eint(unsigned int start)
 
 static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 {
+       struct irq_chip *chip = irq_get_chip(irq);
+       chained_irq_enter(chip, desc);
        exynos4_irq_demux_eint(IRQ_EINT(16));
        exynos4_irq_demux_eint(IRQ_EINT(24));
+       chained_irq_exit(chip, desc);
 }
 
 static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
@@ -193,6 +198,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
        u32 *irq_data = irq_get_handler_data(irq);
        struct irq_chip *chip = irq_get_chip(irq);
 
+       chained_irq_enter(chip, desc);
        chip->irq_mask(&desc->irq_data);
 
        if (chip->irq_ack)
@@ -201,6 +207,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
        generic_handle_irq(*irq_data);
 
        chip->irq_unmask(&desc->irq_data);
+       chained_irq_exit(chip, desc);
 }
 
 int __init exynos4_init_irq_eint(void)
index 43be71b799cbce337cc6174badd8c035c44b912b..bbd13f454151bcee0bbbd1a732df19693cafedf2 100644 (file)
 #include <asm/mach-types.h>
 
 #include <plat/adc.h>
+#include <plat/regs-fb-v4.h>
 #include <plat/regs-serial.h>
 #include <plat/exynos4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/ehci.h>
 #include <plat/clock.h>
@@ -199,6 +201,33 @@ static struct platform_device nuri_gpio_keys = {
        },
 };
 
+/* Frame Buffer */
+static struct s3c_fb_pd_win nuri_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 64,
+               .right_margin   = 16,
+               .upper_margin   = 64,
+               .lower_margin   = 1,
+               .hsync_len      = 48,
+               .vsync_len      = 3,
+               .xres           = 1280,
+               .yres           = 800,
+               .refresh        = 60,
+       },
+       .max_bpp        = 24,
+       .default_bpp    = 16,
+       .virtual_x      = 1280,
+       .virtual_y      = 800,
+};
+
+static struct s3c_fb_platdata nuri_fb_pdata __initdata = {
+       .win[0]         = &nuri_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+                         VIDCON0_CLKSEL_LCD,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
 {
        int gpio = EXYNOS4_GPE1(5);
@@ -1092,6 +1121,7 @@ static struct platform_device *nuri_devices[] __initdata = {
        /* Samsung Platform Devices */
        &s3c_device_i2c5, /* PMIC should initialize first */
        &emmc_fixed_voltage,
+       &s5p_device_fimd0,
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc2,
        &s3c_device_hsmmc3,
@@ -1106,6 +1136,7 @@ static struct platform_device *nuri_devices[] __initdata = {
        &s5p_device_mfc_l,
        &s5p_device_mfc_r,
        &exynos4_device_pd[PD_MFC],
+       &exynos4_device_pd[PD_LCD0],
 
        /* NURI Devices */
        &nuri_gpio_keys,
@@ -1142,12 +1173,15 @@ static void __init nuri_machine_init(void)
        i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
        i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
 
+       s5p_fimd0_set_platdata(&nuri_fb_pdata);
+
        nuri_ehci_init();
        clk_xusbxti.rate = 24000000;
 
        /* Last */
        platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
        s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+       s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
 }
 
 MACHINE_START(NURI, "NURI")
diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c
new file mode 100644 (file)
index 0000000..ed59f86
--- /dev/null
@@ -0,0 +1,108 @@
+/* linux/arch/arm/mach-exynos4/mach-origen.c
+ *
+ * Copyright (c) 2011 Insignal Co., Ltd.
+ *             http://www.insignal.co.kr/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/input.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/iic.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define ORIGEN_UCON_DEFAULT    (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define ORIGEN_ULCON_DEFAULT   S3C2410_LCON_CS8
+
+#define ORIGEN_UFCON_DEFAULT   (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+};
+
+static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = EXYNOS4_GPK2(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct platform_device *origen_devices[] __initdata = {
+       &s3c_device_hsmmc2,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+};
+
+static void __init origen_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
+}
+
+static void __init origen_machine_init(void)
+{
+       s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
+       platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
+}
+
+MACHINE_START(ORIGEN, "ORIGEN")
+       /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
+       .boot_params    = S5P_PA_SDRAM + 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = origen_map_io,
+       .init_machine   = origen_machine_init,
+       .timer          = &exynos4_timer,
+MACHINE_END
index ea4149556860f45c471cff55891cf7fc051a6980..5f62b2b3310d495fbafa53016624fa96404cb12b 100644 (file)
@@ -32,6 +32,7 @@
 #include <plat/pd.h>
 #include <plat/gpio-cfg.h>
 #include <plat/backlight.h>
+#include <plat/mfc.h>
 
 #include <mach/map.h>
 
@@ -177,6 +178,9 @@ static struct platform_device *smdkv310_devices[] __initdata = {
        &exynos4_device_ac97,
        &exynos4_device_i2s0,
        &samsung_device_keypad,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
        &exynos4_device_pd[PD_MFC],
        &exynos4_device_pd[PD_G3D],
        &exynos4_device_pd[PD_LCD0],
@@ -233,6 +237,11 @@ static void __init smdkv310_map_io(void)
        s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
 }
 
+static void __init smdkv310_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
 static void __init smdkv310_machine_init(void)
 {
        s3c_i2c1_set_platdata(NULL);
@@ -250,6 +259,7 @@ static void __init smdkv310_machine_init(void)
        samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data);
 
        platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
@@ -260,4 +270,5 @@ MACHINE_START(SMDKV310, "SMDKV310")
        .map_io         = smdkv310_map_io,
        .init_machine   = smdkv310_machine_init,
        .timer          = &exynos4_timer,
+       .reserve        = &smdkv310_reserve,
 MACHINE_END
index 0e280d12301ebe542bcb170661c7bc2097b67fca..3ca7f3a8c2c523c327427fe8e356f938ff9d47ce 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/gpio_keys.h>
 #include <linux/gpio.h>
+#include <linux/fb.h>
 #include <linux/mfd/max8998.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 #include <plat/devs.h>
 #include <plat/iic.h>
 #include <plat/gpio-cfg.h>
+#include <plat/fb.h>
 #include <plat/mfc.h>
 #include <plat/sdhci.h>
 #include <plat/pd.h>
+#include <plat/regs-fb-v4.h>
 
 #include <mach/map.h>
 
@@ -79,7 +82,7 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
 };
 
 static struct regulator_consumer_supply max8952_consumer =
-       REGULATOR_SUPPLY("vddarm", NULL);
+       REGULATOR_SUPPLY("vdd_arm", NULL);
 
 static struct max8952_platform_data universal_max8952_pdata __initdata = {
        .gpio_vid0      = EXYNOS4_GPX0(3),
@@ -105,7 +108,7 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = {
 };
 
 static struct regulator_consumer_supply lp3974_buck1_consumer =
-       REGULATOR_SUPPLY("vddint", NULL);
+       REGULATOR_SUPPLY("vdd_int", NULL);
 
 static struct regulator_consumer_supply lp3974_buck2_consumer =
        REGULATOR_SUPPLY("vddg3d", NULL);
@@ -702,6 +705,32 @@ static struct i2c_board_info i2c1_devs[] __initdata = {
        /* Gyro, To be updated */
 };
 
+/* Frame Buffer */
+static struct s3c_fb_pd_win universal_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 16,
+               .right_margin   = 16,
+               .upper_margin   = 2,
+               .lower_margin   = 28,
+               .hsync_len      = 2,
+               .vsync_len      = 1,
+               .xres           = 480,
+               .yres           = 800,
+               .refresh        = 55,
+       },
+       .max_bpp        = 32,
+       .default_bpp    = 16,
+};
+
+static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
+       .win[0]         = &universal_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+                         VIDCON0_CLKSEL_LCD,
+       .vidcon1        = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+                         | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
+};
+
 static struct platform_device *universal_devices[] __initdata = {
        /* Samsung Platform Devices */
        &s5p_device_fimc0,
@@ -719,10 +748,12 @@ static struct platform_device *universal_devices[] __initdata = {
        &i2c_gpio12,
        &universal_gpio_keys,
        &s5p_device_onenand,
+       &s5p_device_fimd0,
        &s5p_device_mfc,
        &s5p_device_mfc_l,
        &s5p_device_mfc_r,
        &exynos4_device_pd[PD_MFC],
+       &exynos4_device_pd[PD_LCD0],
 };
 
 static void __init universal_map_io(void)
@@ -751,6 +782,8 @@ static void __init universal_machine_init(void)
        s3c_i2c5_set_platdata(NULL);
        i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
 
+       s5p_fimd0_set_platdata(&universal_lcd_pdata);
+
        universal_touchkey_init();
        i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs,
                        ARRAY_SIZE(i2c_gpio12_devs));
@@ -758,6 +791,7 @@ static void __init universal_machine_init(void)
        /* Last */
        platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
        s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+       s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
 }
 
 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
index 0883c1b824b94df5cdca0f7cabf76812fb734df0..39aca045f6604ae1b7c4125ee85646ef34df95f0 100644 (file)
@@ -82,7 +82,7 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
 
        rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
        writel(rstcon, EXYNOS4_RSTCON);
-       udelay(50);
+       udelay(80);
 
        clk_disable(otg_clk);
        clk_put(otg_clk);
index dc26fff22cf062df3753eb4d0b46360334116dc1..c8e7afcf14ec142b38d7a1558f98661936006477 100644 (file)
@@ -62,6 +62,7 @@ config ARCH_EBSA285_HOST
 config ARCH_NETWINDER
        bool "NetWinder"
        select CLKSRC_I8253
+       select CLKEVT_I8253
        select FOOTBRIDGE_HOST
        select ISA
        select ISA_DMA
index c7e75acfe6c9b1911a5825c2b3136ad9b719d445..ff0a4b5b0a82b5873a119ec072b3db781651ab86 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 
index 32e4cc397c28c07f45bdd957a6236e6953ca4188..15a70396c27d41f123910fdd9cd7844d2d2cf033 100644 (file)
@@ -23,8 +23,6 @@
 #define PCIO_SIZE       0x00100000
 #define PCIO_BASE       MMU_IO(0xff000000, 0x7c000000)
 
-#define IO_SPACE_LIMIT 0xffff
-
 /*
  * Translation of various region addresses to virtual addresses
  */
index 22a52c228d93140e95d623f7a0cb5e5a95861998..683f52b20e3d2b683227cb524166a2d1c27aec00 100644 (file)
@@ -1,9 +1,9 @@
 ifeq ($(CONFIG_GEMINI_MEM_SWAP),y)
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 else
-   zreladdr-y  := 0x10008000
+   zreladdr-y  += 0x10008000
 params_phys-y  := 0x10000100
 initrd_phys-y  := 0x10800000
 endif
index 3bc2c70f298934a85bcb10b858e5e90e758ceb16..40a0527bada7a969d1bb366fe5bf7e150ace2256 100644 (file)
 #define __MACH_GPIO_H__
 
 #include <mach/irqs.h>
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
 
 #define gpio_to_irq(x) ((x) + GPIO_IRQ_BASE)
 #define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE)
index 52984017bd91c56404e0667103f1e5081f035c1a..d875a7094dfee5f8c2383ad9d0a746f177302429 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-$(CONFIG_ARCH_H720X)       := 0x40008000
+   zreladdr-$(CONFIG_ARCH_H720X)       += 0x40008000
 
index ebee18b3884c7dc756870f30c2b3531d9e95441b..dbe61201bcd80202007d604ca5bb8c98cba0aadc 100644 (file)
@@ -1,19 +1,19 @@
-zreladdr-$(CONFIG_ARCH_MX1)    := 0x08008000
+zreladdr-$(CONFIG_ARCH_MX1)    += 0x08008000
 params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
 initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
 
-zreladdr-$(CONFIG_MACH_MX21)   := 0xC0008000
+zreladdr-$(CONFIG_MACH_MX21)   += 0xC0008000
 params_phys-$(CONFIG_MACH_MX21)        := 0xC0000100
 initrd_phys-$(CONFIG_MACH_MX21)        := 0xC0800000
 
-zreladdr-$(CONFIG_ARCH_MX25)   := 0x80008000
+zreladdr-$(CONFIG_ARCH_MX25)   += 0x80008000
 params_phys-$(CONFIG_ARCH_MX25)        := 0x80000100
 initrd_phys-$(CONFIG_ARCH_MX25)        := 0x80800000
 
-zreladdr-$(CONFIG_MACH_MX27)   := 0xA0008000
+zreladdr-$(CONFIG_MACH_MX27)   += 0xA0008000
 params_phys-$(CONFIG_MACH_MX27)        := 0xA0000100
 initrd_phys-$(CONFIG_MACH_MX27)        := 0xA0800000
 
-zreladdr-$(CONFIG_ARCH_MX3)    := 0x80008000
+zreladdr-$(CONFIG_ARCH_MX3)    += 0x80008000
 params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
 initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
index cf8f8099ebd78abb3b92676b170fa0df81874005..82bd4403b450a915ac2a8b83a627ddf00642a6fa 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA 02110-1301, USA.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <mach/hardware.h>
-#include <mach/gpio.h>
 #include <mach/iomux-mx3.h>
 
 /*
index fc26ed71b9edf56cafa4426668b3a52d523b9fb1..e1addc1a5813428a9e11fbe1bd535bcb4cd54c34 100644 (file)
@@ -13,7 +13,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
@@ -27,7 +27,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <mach/gpio.h>
 #include <mach/iomux-mx27.h>
 
 #include "devices-imx27.h"
index c7e75acfe6c9b1911a5825c2b3136ad9b719d445..ff0a4b5b0a82b5873a119ec072b3db781651ab86 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 
index f21bb5493dd99ad293bddf5326fc4469dc930524..37beed3fa3ed38a811faea3e96886f046abef737 100644 (file)
@@ -20,8 +20,6 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffff
-
 /*
  * WARNING: this has to mirror definitions in platform.h
  */
index 0b0e19fdfe6c27ecfa4f8a5c0c4437ddd8b6e892..3a8c38c3189c0b76138e7bdc294d9d189176178a 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y   := 0x00008000
+   zreladdr-y   += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 47000dccd61ff2ce04cec012ab5b30508138e43e..0a833b11e38cc948a43fec477637bcac3b5aa711 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0xa0008000
+   zreladdr-y  += 0xa0008000
 params_phys-y  := 0xa0000100
 initrd_phys-y  := 0xa0800000
index 67039c3e0c48fa6b94f1147b3316f74afcecba9e..760a0efe7580b0dd194ff9bfe4295624336bb806 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index d84c5807a43d799e042be16f58b4271509b2a392..9c7af91d93da49e617c6e6c9b0429a6e15e69c64 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 
index 4068166c899384903206e2f4325049639712a480..59a512672bb9de9035b6e695c7e1e914bc7eb3c4 100644 (file)
@@ -13,7 +13,7 @@
  * License version 2. This program is licensed "as is" without any 
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -39,7 +39,7 @@
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 
-#include <mach/gpio.h>
+#include <mach/gpio-ixp2000.h>
 
 static DEFINE_SPINLOCK(ixp2000_slowport_lock);
 static unsigned long ixp2000_slowport_irq_flags;
similarity index 95%
rename from arch/arm/mach-ixp2000/include/mach/gpio.h
rename to arch/arm/mach-ixp2000/include/mach/gpio-ixp2000.h
index 4a88d2c33dacb6a4640b998c824465c9561d3e23..af836c76c3f1a2e142d38a1106e46fa75fa20693 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2002 Intel Corporation.
  *
- * This program is free software, you can redistribute it and/or modify 
+ * This program is free software, you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
@@ -11,7 +11,7 @@
 /*
  * IXP2000 GPIO in/out, edge/level detection for IRQs:
  * IRQs are generated on Falling-edge, Rising-Edge, Level-low, Level-High
- * or both Falling-edge and Rising-edge.  
+ * or both Falling-edge and Rising-edge.
  * This must be called *before* the corresponding IRQ is registerd.
  * Use this instead of directly setting the GPIO registers.
  * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
index 235638f800e55795629597f1de58d82ed1456715..634b6c852f68f58d0d8cf368e45cf0946b0987a7 100644 (file)
@@ -14,6 +14,7 @@
  *  Free Software Foundation;  either version 2 of the  License, or (at your
  *  option) any later version.
  */
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mm.h>
@@ -40,8 +41,7 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/arch.h>
 
-#include <mach/gpio.h>
-
+#include <mach/gpio-ixp2000.h>
 
 /*************************************************************************
  * IXDP2x00 IRQ Initialization
index d5561ad15badcef26897b1f938355c05b5c6a592..44fb4a717c3f9ad373a3ba01a2295716b071f6af 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
index d84c5807a43d799e042be16f58b4271509b2a392..9c7af91d93da49e617c6e6c9b0429a6e15e69c64 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 
index 2131832ee6baba03dd28f19d187f1987555a5038..85245e48099cd1369ce725f3d9c691c1cc7e9119 100644 (file)
@@ -397,7 +397,8 @@ void __init ixp4xx_pci_preinit(void)
                local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
                local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
                local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
-               local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + SZ_48M);
+               local_write_config(PCI_BASE_ADDRESS_3, 4,
+                                       PHYS_OFFSET + SZ_32M + SZ_16M);
 
                /*
                 * Enable CSR window at 64 MiB to allow PCI masters
index 03e54515e8b3c58b9c3cd02dd70176f6b6588830..96e378345801ba88a5f052b3bb54df6836dac420 100644 (file)
@@ -16,7 +16,7 @@
  * Author: Rod Whitby <rod@whitby.id.au>
  * Maintainers: http://www.nslu2-linux.org/
  */
-
+#include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
@@ -31,7 +31,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
-#include <asm/gpio.h>
 
 #define DSMG600_SDA_PIN                5
 #define DSMG600_SCL_PIN                4
index 23a8b3614568157f1aa9921fc8ce00c615107078..72333a0394312eff6ba5d1a5b6e041ba37320dbd 100644 (file)
@@ -14,7 +14,7 @@
  * Maintainers: http://www.nslu2-linux.org/
  *
  */
-
+#include <linux/gpio.h>
 #include <linux/if_ether.h>
 #include <linux/irq.h>
 #include <linux/serial.h>
@@ -27,7 +27,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <asm/gpio.h>
 
 #define FSG_SDA_PIN            12
 #define FSG_SCL_PIN            13
index a5f87ded2f28bd8e039d8c09ac04db6e8fc43d50..83d6b4ed60bbd42f3e912d68611205d720ad98a1 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/kernel.h>
 #include <mach/hardware.h>
 
+#define __ARM_GPIOLIB_COMPLEX
+
 static inline int gpio_request(unsigned gpio, const char *label)
 {
        return 0;
@@ -70,6 +72,7 @@ static inline void gpio_set_value(unsigned gpio, int value)
 #include <asm-generic/gpio.h>                  /* cansleep wrappers */
 
 extern int gpio_to_irq(int gpio);
+#define gpio_to_irq gpio_to_irq
 extern int irq_to_gpio(unsigned int irq);
 
 #endif
index 57b5410c31f40dc9db120b0b8f04b0e55c0912d6..ffb9d6afb89f4dfd789ec03a6ccaabf6b4dea61d 100644 (file)
@@ -17,8 +17,6 @@
 
 #include <mach/hardware.h>
 
-#define IO_SPACE_LIMIT 0x0000ffff
-
 extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
 extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
 
index afb51879d9a4d1dbac46472ce07543166fdc0120..b752fa4d692763690d8e969a4b4add897fbcd48c 100644 (file)
@@ -17,7 +17,7 @@
  * Maintainers: http://www.nslu2-linux.org/
  *
  */
-
+#include <linux/gpio.h>
 #include <linux/if_ether.h>
 #include <linux/irq.h>
 #include <linux/jiffies.h>
@@ -32,7 +32,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <asm/gpio.h>
 
 #define NAS100D_SDA_PIN                5
 #define NAS100D_SCL_PIN                6
index 69e40f2cf09217caab9f7d7c5c0d3569c3807134..0411a0a01071bd49f3b3e16ff940e20e2482b697 100644 (file)
@@ -16,7 +16,7 @@
  * Maintainers: http://www.nslu2-linux.org/
  *
  */
-
+#include <linux/gpio.h>
 #include <linux/if_ether.h>
 #include <linux/irq.h>
 #include <linux/serial.h>
@@ -30,7 +30,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
-#include <asm/gpio.h>
 
 #define NSLU2_SDA_PIN          7
 #define NSLU2_SCL_PIN          6
index 67039c3e0c48fa6b94f1147b3316f74afcecba9e..760a0efe7580b0dd194ff9bfe4295624336bb806 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 05d193a25b250d73c90830c52050e106e70eddca..c4c68e5b94f145cf1a3d36c4a7b4e281d40d92ba 100644 (file)
@@ -7,14 +7,13 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <mach/bridge-regs.h>
 #include <plat/irq.h>
-#include <asm/gpio.h>
 #include "common.h"
 
 static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
index b0a7d979a8ed98e9fa35abed1d49577e0ec66b63..cc431fa22ccb6538f85bb1c98d366ba0d57e5532 100644 (file)
@@ -7,12 +7,11 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
 #include <linux/io.h>
-#include <asm/gpio.h>
 #include <mach/hardware.h>
 #include <plat/mpp.h>
 #include "common.h"
index 7e3e8160ed30fe1874dc9540f9b2178f8f4b0eea..853efd9133c6a8f91ed7e1bef24158f562006942 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for KS8695 architecture support
 #
 
-obj-y                          := cpu.o irq.o time.o gpio.o devices.o
+obj-y                          := cpu.o irq.o time.o devices.o
 obj-m                          :=
 obj-n                          :=
 obj-                           :=
index 48eb2cb3ac77bd1e71d4e3dd0a5b6a6f8ae7d45c..c9b0bebcf23718d88270e7be0be60e634df276ea 100644 (file)
@@ -3,6 +3,6 @@
 #   PARAMS_PHYS must be within 4MB of ZRELADDR
 #   INITRD_PHYS must be in RAM
 
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 3ca4f8e6f54fd1cd1fb56f08723aa7b0668de44a..3d7d11436aa533e85762b1d08a1b5849156e25ff 100644 (file)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -34,7 +34,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/devices.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
 
 #include "generic.h"
 
index 1338cb3e98274641557667e5be5b808be22e009b..c3c867ac41559d70846041eb53fa5ccfd12ea629 100644 (file)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -29,7 +29,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/devices.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
 
 #include "generic.h"
 
index e2e3cba8dcdb437f04aa19e9b7091f09386b4989..9b9c47cc647190c01a00bd726fcaa63b03092cc4 100644 (file)
@@ -5,7 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -18,7 +18,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
 #include <mach/devices.h>
 
 #include "generic.h"
index b89fb6d46cccc9efc5ed9f112875ef039da17595..73bd63812878548fcd1e7526ff3c5c22592a2664 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 
 #include <mach/irqs.h>
diff --git a/arch/arm/mach-ks8695/include/mach/gpio-ks8695.h b/arch/arm/mach-ks8695/include/mach/gpio-ks8695.h
new file mode 100644 (file)
index 0000000..6eb034d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_KS8659_GPIO_H
+#define __MACH_KS8659_GPIO_H
+
+#include <linux/kernel.h>
+
+#define KS8695_GPIO_0          0
+#define KS8695_GPIO_1          1
+#define KS8695_GPIO_2          2
+#define KS8695_GPIO_3          3
+#define KS8695_GPIO_4          4
+#define KS8695_GPIO_5          5
+#define KS8695_GPIO_6          6
+#define KS8695_GPIO_7          7
+#define KS8695_GPIO_8          8
+#define KS8695_GPIO_9          9
+#define KS8695_GPIO_10         10
+#define KS8695_GPIO_11         11
+#define KS8695_GPIO_12         12
+#define KS8695_GPIO_13         13
+#define KS8695_GPIO_14         14
+#define KS8695_GPIO_15         15
+
+/*
+ * Configure GPIO pin as external interrupt source.
+ */
+extern int ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
+
+/* Register the GPIOs */
+extern void ks8695_register_gpios(void);
+
+#endif /* __MACH_KS8659_GPIO_H */
index 86312d476bc69525317641b63fe46ff53021342d..f5fda36e4512632e24d74ef05f8acdb119b6e801 100644 (file)
 #ifndef __ASM_ARCH_GPIO_H_
 #define __ASM_ARCH_GPIO_H_
 
-#include <linux/kernel.h>
-
-#define KS8695_GPIO_0          0
-#define KS8695_GPIO_1          1
-#define KS8695_GPIO_2          2
-#define KS8695_GPIO_3          3
-#define KS8695_GPIO_4          4
-#define KS8695_GPIO_5          5
-#define KS8695_GPIO_6          6
-#define KS8695_GPIO_7          7
-#define KS8695_GPIO_8          8
-#define KS8695_GPIO_9          9
-#define KS8695_GPIO_10         10
-#define KS8695_GPIO_11         11
-#define KS8695_GPIO_12         12
-#define KS8695_GPIO_13         13
-#define KS8695_GPIO_14         14
-#define KS8695_GPIO_15         15
-
-/*
- * Configure GPIO pin as external interrupt source.
- */
-extern int ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
-
 /*
  * Map IRQ number to GPIO line.
  */
 extern int irq_to_gpio(unsigned int irq);
 
-#include <asm-generic/gpio.h>
-
-/* If it turns out that we need to optimise GPIO access for the
- * Micrel's GPIOs, then these can be changed to check their argument
- * directly as static inlines. However for now it's probably not
- * worthwhile.
- */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_to_irq __gpio_to_irq
-
-/* Register the GPIOs */
-extern void ks8695_register_gpios(void);
-
 #endif
index 184ef74e4bee53151666d7d26396964d7c36bcb6..d6f6502ac9b59c1722a0ea09b6938933a15e62e9 100644 (file)
@@ -7,14 +7,14 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 
 #include <asm/leds.h>
 #include <mach/devices.h>
-#include <mach/gpio.h>
 
 
 static inline void ks8695_led_on(unsigned int led)
index a5fc5d0eeaeba093b6669833cffccf65d62034a0..f5db805ab95872bb38838a5129324ccbbedb1529 100644 (file)
@@ -3,6 +3,6 @@
 #
 
 obj-y  := timer.o irq.o common.o serial.o clock.o
-obj-y  += gpiolib.o pm.o suspend.o
+obj-y  += pm.o suspend.o
 obj-y  += phy3250.o
 
index b796b41ebf8fe973990f24507919e3d5f6a4d206..2cfe0ee635c55ba844e93aedb64a477d2572d25a 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x80008000
+   zreladdr-y  += 0x80008000
 params_phys-y  := 0x80000100
 initrd_phys-y  := 0x82000000
 
diff --git a/arch/arm/mach-lpc32xx/include/mach/gpio-lpc32xx.h b/arch/arm/mach-lpc32xx/include/mach/gpio-lpc32xx.h
new file mode 100644 (file)
index 0000000..1816e22
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_GPIO_LPC32XX_H
+#define __MACH_GPIO_LPC32XX_H
+
+/*
+ * Note!
+ * Muxed GP pins need to be setup to the GP state in the board level
+ * code prior to using this driver.
+ * GPI pins : 28xP3 group
+ * GPO pins : 24xP3 group
+ * GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group
+ */
+
+#define LPC32XX_GPIO_P0_MAX 8
+#define LPC32XX_GPIO_P1_MAX 24
+#define LPC32XX_GPIO_P2_MAX 13
+#define LPC32XX_GPIO_P3_MAX 6
+#define LPC32XX_GPI_P3_MAX 28
+#define LPC32XX_GPO_P3_MAX 24
+
+#define LPC32XX_GPIO_P0_GRP 0
+#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
+#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
+#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
+#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
+#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
+
+/*
+ * A specific GPIO can be selected with this macro
+ * ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
+ * See the LPC32x0 User's guide for GPIO group numbers
+ */
+#define LPC32XX_GPIO(x, y) ((x) + (y))
+
+#endif /* __MACH_GPIO_LPC32XX_H */
index 67d03da1eee94049a3fa459ff0ac57b1e6ee16e3..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,74 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/include/mach/gpio.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-/*
- * Note!
- * Muxed GP pins need to be setup to the GP state in the board level
- * code prior to using this driver.
- * GPI pins : 28xP3 group
- * GPO pins : 24xP3 group
- * GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group
- */
-
-#define LPC32XX_GPIO_P0_MAX 8
-#define LPC32XX_GPIO_P1_MAX 24
-#define LPC32XX_GPIO_P2_MAX 13
-#define LPC32XX_GPIO_P3_MAX 6
-#define LPC32XX_GPI_P3_MAX 28
-#define LPC32XX_GPO_P3_MAX 24
-
-#define LPC32XX_GPIO_P0_GRP 0
-#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
-#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
-#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
-#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
-#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
-
-/*
- * A specific GPIO can be selected with this macro
- * ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
- * See the LPC32x0 User's guide for GPIO group numbers
- */
-#define LPC32XX_GPIO(x, y) ((x) + (y))
-
-static inline int gpio_get_value(unsigned gpio)
-{
-       return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-       __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
-       return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
-       return __gpio_to_irq(gpio);
-}
-
-#endif
index 7993b096778e1f49c9d44d3e2762dd58b4233678..c3a22fd736aa401da040802690c029fb08101975 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
+#include <mach/gpio-lpc32xx.h>
 #include "common.h"
 
 /*
index 574a4aa8321a86d5f44e24ee18858829c5078685..5edf03e2beede327855eee878fc22b4f802a96a1 100644 (file)
@@ -1 +1 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
index 06b5fa853c9325b81548378a7978a29cbe898a88..2b3b0c6344b2c94c9c3a09cd046d227e78628bce 100644 (file)
@@ -8,7 +8,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  publishhed by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -23,7 +23,6 @@
 #include <mach/addr-map.h>
 #include <mach/mfp-pxa168.h>
 #include <mach/pxa168.h>
-#include <mach/gpio.h>
 #include <video/pxa168fb.h>
 #include <linux/input.h>
 #include <plat/pxa27x_keypad.h>
@@ -160,15 +159,16 @@ static struct mtd_partition aspenite_nand_partitions[] = {
        }, {
                .name           = "filesystem",
                .offset         = MTDPART_OFS_APPEND,
-               .size           = SZ_48M,
+               .size           = SZ_32M + SZ_16M,
                .mask_flags     = 0,
        }
 };
 
 static struct pxa3xx_nand_platform_data aspenite_nand_info = {
        .enable_arbiter = 1,
-       .parts          = aspenite_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(aspenite_nand_partitions),
+       .num_cs = 1,
+       .parts[0]       = aspenite_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(aspenite_nand_partitions),
 };
 
 static struct i2c_board_info aspenite_i2c_info[] __initdata = {
index 079c18861d5c885a9027be3fcce617d2caffdbda..19358344a4a4ef2f82f3b3742d4638ed38e705c0 100644 (file)
@@ -9,7 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -25,7 +25,6 @@
 #include <mach/irqs.h>
 #include <mach/dma.h>
 #include <mach/mfp.h>
-#include <mach/gpio.h>
 #include <mach/devices.h>
 #include <mach/mmp2.h>
 
index b2b280c517ddeba3ef47f929ebb218592d73ac88..e6f67893736c3afa7d46a4dca9b6171b18eb2644 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -21,7 +21,6 @@
 #include <mach/regs-apbc.h>
 #include <mach/regs-apmu.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
 #include <mach/dma.h>
 #include <mach/devices.h>
 #include <mach/mfp.h>
index 1464607aa60db76632ce72b0008cfa4333178b13..c70b4dd359f6b1b9592c563248d01efd621c044d 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -20,7 +20,6 @@
 #include <mach/regs-apmu.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
 #include <mach/dma.h>
 #include <mach/mfp.h>
 #include <mach/devices.h>
index c296b75c4453de76f0757329baffb677b56dda5c..143e52ede8ef14350dac15279ec53b654ae4a716 100644 (file)
@@ -7,7 +7,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  publishhed by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -18,7 +18,6 @@
 #include <mach/addr-map.h>
 #include <mach/mfp-pxa910.h>
 #include <mach/pxa910.h>
-#include <mach/gpio.h>
 
 #include "common.h"
 
index 6bd37a27e5fca67ccfd876582fed715441f409a4..176515a7698935ee136842563b1c025e39a22651 100644 (file)
@@ -93,7 +93,7 @@ static struct mtd_partition ttc_dkb_onenand_partitions[] = {
        }, {
                .name           = "filesystem",
                .offset         = MTDPART_OFS_APPEND,
-               .size           = SZ_48M,
+               .size           = SZ_32M + SZ_16M,
                .mask_flags     = 0,
        }
 };
index 4285dfd80b6ff30d36eaa378699dc709670e0e8f..dc7eab2e294906f213a33a818b66292568ad1db4 100644 (file)
@@ -1,5 +1,6 @@
 obj-y += io.o idle.o timer.o
 obj-y += clock.o
+obj-y += clock-dummy.o
 obj-$(CONFIG_DEBUG_FS) += clock-debug.o
 
 obj-$(CONFIG_MSM_VIC) += irq-vic.o
@@ -8,6 +9,8 @@ obj-$(CONFIG_MSM_IOMMU) += devices-iommu.o
 obj-$(CONFIG_ARCH_MSM7X00A) += dma.o irq.o acpuclock-arm11.o
 obj-$(CONFIG_ARCH_MSM7X30) += dma.o
 obj-$(CONFIG_ARCH_QSD8X50) += dma.o sirc.o
+obj-$(CONFIG_ARCH_MSM8X60) += dma.o
+obj-$(CONFIG_ARCH_MSM8960) += dma.o
 
 obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
 
@@ -23,7 +26,7 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o b
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
+obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o devices-msm8x60.o
 obj-$(CONFIG_ARCH_MSM8960) += board-msm8960.o devices-msm8960.o
 
 obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o
index 24dfbf8c07c47dc8d4e9bb5a01daf62b6a780fd5..9b803a578b4db92f25996aee1af5899e8f5f320d 100644 (file)
@@ -1,3 +1,3 @@
-  zreladdr-y           := 0x10008000
+  zreladdr-y           += 0x10008000
 params_phys-y          := 0x10000100
 initrd_phys-y          := 0x10800000
index 805d4ee53f7e1f7ef2a43f2d60f9a226175574b8..30f4ace13a4698b50143ef68dc50cbdd84c276d5 100644 (file)
@@ -376,7 +376,7 @@ int acpuclk_set_rate(unsigned long rate, int for_power_collapse)
                }
 #if PERF_SWITCH_STEP_DEBUG
                printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n",
-                       __FUNCTION__, cur_s->a11clk_khz, cur_s->pll);
+                       __func__, cur_s->a11clk_khz, cur_s->pll);
 #endif
                if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO
                    && !(plls_enabled & (1 << cur_s->pll))) {
index 18a3c97bc8632b6d781c940be2fedb6bd8e1eba3..4d264eb9a3b19d54cbd8dce2507a2b293484c2c7 100644 (file)
@@ -59,6 +59,7 @@ static struct platform_device smc91x_device = {
 
 static struct platform_device *devices[] __initdata = {
        &msm_device_uart3,
+       &msm_device_dmov,
        &msm_device_smd,
        &msm_device_nand,
        &msm_device_hsusb,
index 7a9a03eb189cb578db9f20c992ead2105650ef39..db3201ad8652acff21d8652faf42910e70b01755 100644 (file)
@@ -44,6 +44,7 @@ static struct platform_device *devices[] __initdata = {
 #if !defined(CONFIG_MSM_SERIAL_DEBUGGER)
        &msm_device_uart1,
 #endif
+       &msm_device_dmov,
        &msm_device_uart_dm1,
        &msm_device_nand,
 };
index c03f269e2e4bdaa29b29d9dc940ab4fab60a1c19..1a313e10c68aa6884dd310f391787c6ccb6e95c5 100644 (file)
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -34,7 +34,6 @@
 
 #include <mach/vreg.h>
 #include <mach/mpp.h>
-#include <mach/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 
index b7a84966b711bcc9658595ecfdcc789bd9e1fe70..f161127eb86375953323307a19f0ee4e4dd12bf8 100644 (file)
@@ -14,7 +14,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02110-1301, USA.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/smsc911x.h>
 #include <linux/usb/msm_hsusb.h>
 #include <linux/clkdev.h>
+#include <linux/memblock.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/memory.h>
 #include <asm/setup.h>
 
-#include <mach/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 #include <mach/dma.h>
 
 extern struct sys_timer msm_timer;
 
+static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag,
+                        char **cmdline, struct meminfo *mi)
+{
+       for (; tag->hdr.size; tag = tag_next(tag))
+               if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) {
+                       tag->u.mem.start = 0;
+                       tag->u.mem.size += SZ_2M;
+               }
+}
+
+static void __init msm7x30_reserve(void)
+{
+       memblock_remove(0x0, SZ_2M);
+}
+
 static int hsusb_phy_init_seq[] = {
        0x30, 0x32,     /* Enable and set Pre-Emphasis Depth to 20% */
        0x02, 0x36,     /* Disable CDR Auto Reset feature */
@@ -79,6 +94,7 @@ static struct platform_device *devices[] __initdata = {
 #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
         &msm_device_uart2,
 #endif
+       &msm_device_dmov,
        &msm_device_smd,
        &msm_device_otg,
        &msm_device_hsusb,
@@ -107,6 +123,8 @@ static void __init msm7x30_map_io(void)
 
 MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
        .boot_params = PLAT_PHYS_OFFSET + 0x100,
+       .fixup = msm7x30_fixup,
+       .reserve = msm7x30_reserve,
        .map_io = msm7x30_map_io,
        .init_irq = msm7x30_init_irq,
        .init_machine = msm7x30_init,
@@ -115,6 +133,8 @@ MACHINE_END
 
 MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
        .boot_params = PLAT_PHYS_OFFSET + 0x100,
+       .fixup = msm7x30_fixup,
+       .reserve = msm7x30_reserve,
        .map_io = msm7x30_map_io,
        .init_irq = msm7x30_init_irq,
        .init_machine = msm7x30_init,
@@ -123,6 +143,8 @@ MACHINE_END
 
 MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
        .boot_params = PLAT_PHYS_OFFSET + 0x100,
+       .fixup = msm7x30_fixup,
+       .reserve = msm7x30_reserve,
        .map_io = msm7x30_map_io,
        .init_irq = msm7x30_init_irq,
        .init_machine = msm7x30_init,
index 35c7ceeb3f29bfa1b7cb7aa606dfe7930a543712..dab58ef834d7a78b25e66f5c48b74c7dd0301fc0 100644 (file)
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/clkdev.h>
+#include <linux/memblock.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
+#include <asm/setup.h>
 
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 
 #include "devices.h"
 
+static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag,
+                        char **cmdline, struct meminfo *mi)
+{
+       for (; tag->hdr.size; tag = tag_next(tag))
+               if (tag->hdr.tag == ATAG_MEM &&
+                               tag->u.mem.start == 0x40200000) {
+                       tag->u.mem.start = 0x40000000;
+                       tag->u.mem.size += SZ_2M;
+               }
+}
+
+static void __init msm8960_reserve(void)
+{
+       memblock_remove(0x40000000, SZ_2M);
+}
+
 static void __init msm8960_map_io(void)
 {
        msm_map_msm8960_io();
 }
 
+static void __init msm8960_init_early(void)
+{
+       msm_clock_init(msm_clocks_8960, msm_num_clocks_8960);
+}
+
 static void __init msm8960_init_irq(void)
 {
        unsigned int i;
@@ -65,25 +88,42 @@ static struct platform_device *rumi3_devices[] __initdata = {
        &msm8960_device_uart_gsbi5,
 };
 
+static struct platform_device *devices[] __initdata = {
+       &msm8960_device_dmov,
+};
+
+static void __init msm8960_init(void)
+{
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
 static void __init msm8960_sim_init(void)
 {
+       msm8960_init();
        platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
 }
 
 static void __init msm8960_rumi3_init(void)
 {
+       msm8960_init();
        platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
 }
 
 MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
+       .fixup = msm8960_fixup,
+       .reserve = msm8960_reserve,
        .map_io = msm8960_map_io,
+       .init_early = msm8960_init_early,
        .init_irq = msm8960_init_irq,
        .timer = &msm_timer,
        .init_machine = msm8960_sim_init,
 MACHINE_END
 
 MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
+       .fixup = msm8960_fixup,
+       .reserve = msm8960_reserve,
        .map_io = msm8960_map_io,
+       .init_early = msm8960_init_early,
        .init_irq = msm8960_init_irq,
        .timer = &msm_timer,
        .init_machine = msm8960_rumi3_init,
index 1163b6fd05d2ceb71ae21b5b3bef550a65ba3ca6..5b47ec85aa541d8a0de651365099fd1df90ae3ea 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/memblock.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
+#include <asm/setup.h>
 
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
+#include "devices.h"
 
+static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag,
+                        char **cmdline, struct meminfo *mi)
+{
+       for (; tag->hdr.size; tag = tag_next(tag))
+               if (tag->hdr.tag == ATAG_MEM &&
+                               tag->u.mem.start == 0x40200000) {
+                       tag->u.mem.start = 0x40000000;
+                       tag->u.mem.size += SZ_2M;
+               }
+}
+
+static void __init msm8x60_reserve(void)
+{
+       memblock_remove(0x40000000, SZ_2M);
+}
 
 static void __init msm8x60_map_io(void)
 {
        msm_map_msm8x60_io();
 }
 
+static struct platform_device *devices[] __initdata = {
+       &msm_device_dmov_adm0,
+       &msm_device_dmov_adm1,
+};
+
 static void __init msm8x60_init_irq(void)
 {
        unsigned int i;
@@ -62,9 +85,12 @@ static void __init msm8x60_init_irq(void)
 
 static void __init msm8x60_init(void)
 {
+       platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
+       .fixup = msm8x60_fixup,
+       .reserve = msm8x60_reserve,
        .map_io = msm8x60_map_io,
        .init_irq = msm8x60_init_irq,
        .init_machine = msm8x60_init,
@@ -72,6 +98,8 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
 MACHINE_END
 
 MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
+       .fixup = msm8x60_fixup,
+       .reserve = msm8x60_reserve,
        .map_io = msm8x60_map_io,
        .init_irq = msm8x60_init_irq,
        .init_machine = msm8x60_init,
@@ -79,6 +107,8 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
 MACHINE_END
 
 MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
+       .fixup = msm8x60_fixup,
+       .reserve = msm8x60_reserve,
        .map_io = msm8x60_map_io,
        .init_irq = msm8x60_init_irq,
        .init_machine = msm8x60_init,
@@ -86,6 +116,8 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
 MACHINE_END
 
 MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
+       .fixup = msm8x60_fixup,
+       .reserve = msm8x60_reserve,
        .map_io = msm8x60_map_io,
        .init_irq = msm8x60_init_irq,
        .init_machine = msm8x60_init,
index 6a96911b0ad508cdde70e79359a8e3480ce10c16..fee4ab8d64bb90c8c13522565be67cc053c46089 100644 (file)
@@ -14,7 +14,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02110-1301, USA.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
@@ -32,7 +32,6 @@
 #include <mach/board.h>
 #include <mach/irqs.h>
 #include <mach/sirc.h>
-#include <mach/gpio.h>
 #include <mach/vreg.h>
 #include <mach/mmc.h>
 
@@ -93,6 +92,7 @@ static struct msm_otg_platform_data msm_otg_pdata = {
 
 static struct platform_device *devices[] __initdata = {
        &msm_device_uart3,
+       &msm_device_dmov,
        &msm_device_smd,
        &msm_device_otg,
        &msm_device_hsusb,
index 68f930f07d77c2bb86192e329036db861ccedafc..863394c59e862e5b8eba4d53925110efa64a1ba3 100644 (file)
@@ -11,7 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
 */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -22,7 +22,6 @@
 
 #include <linux/delay.h>
 
-#include <asm/gpio.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index f7a9724788b0f54fe7dc7e239d895d9ed6162ffa..8650342b7493e00e4828ffd1bf057c81979efee3 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/board-trout-mmc.c
 ** Author: Brian Swetland <swetland@google.com>
 */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -11,7 +11,6 @@
 #include <linux/err.h>
 #include <linux/debugfs.h>
 
-#include <asm/gpio.h>
 #include <asm/io.h>
 
 #include <mach/vreg.h>
index 729bb49a44caf6bbd2b38557304d155bea242cf3..25105c1027fe44c1862b94605ca8d6fd520ff3c1 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/mach-msm/board-trout-mddi.c
 ** Author: Brian Swetland <swetland@google.com>
 */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -11,7 +11,6 @@
 #include <linux/err.h>
 
 #include <asm/io.h>
-#include <asm/gpio.h>
 #include <asm/mach-types.h>
 
 #include <mach/msm_fb.h>
index 814386772c663d16ea9c314a23788e9dba706745..5831ce5737399149dcb2dc1b4a805d106b0af091 100644 (file)
@@ -35,6 +35,7 @@ extern int trout_init_mmc(unsigned int);
 
 static struct platform_device *devices[] __initdata = {
        &msm_device_uart3,
+       &msm_device_dmov,
        &msm_device_smd,
        &msm_device_nand,
        &msm_device_hsusb,
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
new file mode 100644 (file)
index 0000000..8ae3768
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "clock.h"
+
+static int dummy_clk_enable(unsigned id)
+{
+       return 0;
+}
+
+static void dummy_clk_disable(unsigned id)
+{
+}
+
+static int dummy_clk_reset(unsigned id, enum clk_reset_action action)
+{
+       return 0;
+}
+
+static int dummy_clk_set_rate(unsigned id, unsigned rate)
+{
+       return 0;
+}
+
+static int dummy_clk_set_min_rate(unsigned id, unsigned rate)
+{
+       return 0;
+}
+
+static int dummy_clk_set_max_rate(unsigned id, unsigned rate)
+{
+       return 0;
+}
+
+static int dummy_clk_set_flags(unsigned id, unsigned flags)
+{
+       return 0;
+}
+
+static unsigned dummy_clk_get_rate(unsigned id)
+{
+       return 0;
+}
+
+static unsigned dummy_clk_is_enabled(unsigned id)
+{
+       return 0;
+}
+
+static long dummy_clk_round_rate(unsigned id, unsigned rate)
+{
+       return rate;
+}
+
+static bool dummy_clk_is_local(unsigned id)
+{
+       return true;
+}
+
+struct clk_ops clk_ops_dummy = {
+       .enable = dummy_clk_enable,
+       .disable = dummy_clk_disable,
+       .reset = dummy_clk_reset,
+       .set_rate = dummy_clk_set_rate,
+       .set_min_rate = dummy_clk_set_min_rate,
+       .set_max_rate = dummy_clk_set_max_rate,
+       .set_flags = dummy_clk_set_flags,
+       .get_rate = dummy_clk_get_rate,
+       .is_enabled = dummy_clk_is_enabled,
+       .round_rate = dummy_clk_round_rate,
+       .is_local = dummy_clk_is_local,
+};
index 22a537669624285e938f31d0ba2cdc0e8d51783f..d9145dfc2a3b04c4096c1dd10f4ac97ef9ac815f 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/list.h>
 #include <linux/err.h>
 #include <linux/spinlock.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
 #include <linux/string.h>
index 2c007f606d2921e61d8692bd7a3e288cf08d588b..1e6207463e6d447f476726e7eab73002cec75d2c 100644 (file)
@@ -69,4 +69,15 @@ static inline int __init clock_debug_init(void) { return 0; }
 static inline int __init clock_debug_add(struct clk *clock) { return 0; }
 #endif
 
+extern struct clk_ops clk_ops_dummy;
+
+#define CLK_DUMMY(clk_name, clk_id, clk_dev) { \
+       .con_id = clk_name, \
+       .dev_id = clk_dev, \
+       .clk = &(struct clk){ \
+               .dbg_name = #clk_id, \
+               .ops = &clk_ops_dummy, \
+       }, \
+       }
+
 #endif
index c4f5e26feb4dc4d274a1b721b90fce08e6fffd96..3ef38a53c508d5b99429acaef679135175034409 100644 (file)
@@ -418,8 +418,27 @@ struct platform_device msm_device_mdp = {
        .resource = resources_mdp,
 };
 
+static struct resource resources_dmov[] = {
+       {
+               .start = MSM7X00_DMOV_PHYS,
+               .end = MSM7X00_DMOV_PHYS + MSM7X00_DMOV_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = INT_ADM_AARM,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_dmov = {
+       .name   = "msm_dmov",
+       .id     = -1,
+       .num_resources = ARRAY_SIZE(resources_dmov),
+       .resource = resources_dmov,
+};
+
 struct clk_lookup msm_clocks_7x01a[] = {
-       CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
+       CLK_PCOM("adm_clk",     ADM_CLK,        "msm_dmov", 0),
        CLK_PCOM("adsp_clk",    ADSP_CLK,       NULL, 0),
        CLK_PCOM("ebi1_clk",    EBI1_CLK,       NULL, 0),
        CLK_PCOM("ebi2_clk",    EBI2_CLK,       NULL, 0),
index 09b4f14038246f6004aa4e9ef5d2721baba285c8..f803fcd380d068c50fcd449ef3b6683d505741d2 100644 (file)
@@ -130,8 +130,27 @@ struct platform_device msm_device_hsusb_host = {
        },
 };
 
+static struct resource resources_dmov[] = {
+       {
+               .start = MSM7X30_DMOV_PHYS,
+               .end = MSM7X30_DMOV_PHYS + MSM7X30_DMOV_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = INT_ADM_AARM,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_dmov = {
+       .name   = "msm_dmov",
+       .id     = -1,
+       .num_resources = ARRAY_SIZE(resources_dmov),
+       .resource = resources_dmov,
+};
+
 struct clk_lookup msm_clocks_7x30[] = {
-       CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
+       CLK_PCOM("adm_clk",     ADM_CLK,        "msm_dmov", 0),
        CLK_PCOM("adsp_clk",    ADSP_CLK,       NULL, 0),
        CLK_PCOM("cam_m_clk",   CAM_M_CLK,      NULL, 0),
        CLK_PCOM("camif_pad_pclk",      CAMIF_PAD_P_CLK,        NULL, OFF),
index d9e1f26475deb2a229d112a307b1cf6e4838b60b..2e17ac6f1f04a3ae3bb4c968164c523e890ec11e 100644 (file)
 #include <linux/dma-mapping.h>
 #include <mach/irqs-8960.h>
 #include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/irqs.h>
 
 #include "devices.h"
+#include "clock.h"
 
 #define MSM_GSBI2_PHYS         0x16100000
 #define MSM_UART2DM_PHYS       (MSM_GSBI2_PHYS + 0x40000)
@@ -83,3 +86,181 @@ struct platform_device msm8960_device_uart_gsbi5 = {
        .num_resources  = ARRAY_SIZE(resources_uart_gsbi5),
        .resource       = resources_uart_gsbi5,
 };
+
+static struct resource resources_dmov[] = {
+       {
+               .start = MSM8960_DMOV_PHYS,
+               .end = MSM8960_DMOV_PHYS + MSM8960_DMOV_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = INT_ADM0_SCSS_0_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm8960_device_dmov = {
+       .name   = "msm_dmov",
+       .id     = -1,
+       .num_resources = ARRAY_SIZE(resources_dmov),
+       .resource = resources_dmov,
+};
+
+struct clk_lookup msm_clocks_8960[] = {
+       CLK_DUMMY("gsbi_uart_clk",      GSBI1_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI2_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI3_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI4_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI5_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI6_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI7_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI8_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI9_UART_CLK,         NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI10_UART_CLK,        NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI11_UART_CLK,        NULL),
+       CLK_DUMMY("gsbi_uart_clk",      GSBI12_UART_CLK,        NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI1_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI2_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI3_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI4_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI5_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI6_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI7_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI8_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI9_QUP_CLK,          NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI10_QUP_CLK,         NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI11_QUP_CLK,         NULL),
+       CLK_DUMMY("gsbi_qup_clk",       GSBI12_QUP_CLK,         NULL),
+       CLK_DUMMY("pdm_clk",            PDM_CLK,                NULL),
+       CLK_DUMMY("pmem_clk",           PMEM_CLK,               NULL),
+       CLK_DUMMY("prng_clk",           PRNG_CLK,               NULL),
+       CLK_DUMMY("sdc_clk",            SDC1_CLK,               NULL),
+       CLK_DUMMY("sdc_clk",            SDC2_CLK,               NULL),
+       CLK_DUMMY("sdc_clk",            SDC3_CLK,               NULL),
+       CLK_DUMMY("sdc_clk",            SDC4_CLK,               NULL),
+       CLK_DUMMY("sdc_clk",            SDC5_CLK,               NULL),
+       CLK_DUMMY("tsif_ref_clk",       TSIF_REF_CLK,           NULL),
+       CLK_DUMMY("tssc_clk",           TSSC_CLK,               NULL),
+       CLK_DUMMY("usb_hs_clk",         USB_HS1_XCVR_CLK,       NULL),
+       CLK_DUMMY("usb_phy_clk",        USB_PHY0_CLK,           NULL),
+       CLK_DUMMY("usb_fs_src_clk",     USB_FS1_SRC_CLK,        NULL),
+       CLK_DUMMY("usb_fs_clk",         USB_FS1_XCVR_CLK,       NULL),
+       CLK_DUMMY("usb_fs_sys_clk",     USB_FS1_SYS_CLK,        NULL),
+       CLK_DUMMY("usb_fs_src_clk",     USB_FS2_SRC_CLK,        NULL),
+       CLK_DUMMY("usb_fs_clk",         USB_FS2_XCVR_CLK,       NULL),
+       CLK_DUMMY("usb_fs_sys_clk",     USB_FS2_SYS_CLK,        NULL),
+       CLK_DUMMY("ce_clk",             CE2_CLK,                NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI1_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI2_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI3_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI4_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI5_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI6_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI7_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI8_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI9_P_CLK,            NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI10_P_CLK,           NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI11_P_CLK,           NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI12_P_CLK,           NULL),
+       CLK_DUMMY("gsbi_pclk",          GSBI12_P_CLK,           NULL),
+       CLK_DUMMY("ppss_pclk",          PPSS_P_CLK,             NULL),
+       CLK_DUMMY("tsif_pclk",          TSIF_P_CLK,             NULL),
+       CLK_DUMMY("usb_fs_pclk",        USB_FS1_P_CLK,          NULL),
+       CLK_DUMMY("usb_fs_pclk",        USB_FS2_P_CLK,          NULL),
+       CLK_DUMMY("usb_hs_pclk",        USB_HS1_P_CLK,          NULL),
+       CLK_DUMMY("sdc_pclk",           SDC1_P_CLK,             NULL),
+       CLK_DUMMY("sdc_pclk",           SDC2_P_CLK,             NULL),
+       CLK_DUMMY("sdc_pclk",           SDC3_P_CLK,             NULL),
+       CLK_DUMMY("sdc_pclk",           SDC4_P_CLK,             NULL),
+       CLK_DUMMY("sdc_pclk",           SDC5_P_CLK,             NULL),
+       CLK_DUMMY("adm_clk",            ADM0_CLK,               NULL),
+       CLK_DUMMY("adm_pclk",           ADM0_P_CLK,             NULL),
+       CLK_DUMMY("pmic_arb_pclk",      PMIC_ARB0_P_CLK,        NULL),
+       CLK_DUMMY("pmic_arb_pclk",      PMIC_ARB1_P_CLK,        NULL),
+       CLK_DUMMY("pmic_ssbi2",         PMIC_SSBI2_CLK,         NULL),
+       CLK_DUMMY("rpm_msg_ram_pclk",   RPM_MSG_RAM_P_CLK,      NULL),
+       CLK_DUMMY("amp_clk",            AMP_CLK,                NULL),
+       CLK_DUMMY("cam_clk",            CAM0_CLK,               NULL),
+       CLK_DUMMY("cam_clk",            CAM1_CLK,               NULL),
+       CLK_DUMMY("csi_src_clk",        CSI0_SRC_CLK,           NULL),
+       CLK_DUMMY("csi_src_clk",        CSI1_SRC_CLK,           NULL),
+       CLK_DUMMY("csi_clk",            CSI0_CLK,               NULL),
+       CLK_DUMMY("csi_clk",            CSI1_CLK,               NULL),
+       CLK_DUMMY("csi_pix_clk",        CSI_PIX_CLK,            NULL),
+       CLK_DUMMY("csi_rdi_clk",        CSI_RDI_CLK,            NULL),
+       CLK_DUMMY("csiphy_timer_src_clk", CSIPHY_TIMER_SRC_CLK, NULL),
+       CLK_DUMMY("csi0phy_timer_clk",  CSIPHY0_TIMER_CLK,      NULL),
+       CLK_DUMMY("csi1phy_timer_clk",  CSIPHY1_TIMER_CLK,      NULL),
+       CLK_DUMMY("dsi_byte_div_clk",   DSI1_BYTE_CLK,          NULL),
+       CLK_DUMMY("dsi_byte_div_clk",   DSI2_BYTE_CLK,          NULL),
+       CLK_DUMMY("dsi_esc_clk",        DSI1_ESC_CLK,           NULL),
+       CLK_DUMMY("dsi_esc_clk",        DSI2_ESC_CLK,           NULL),
+       CLK_DUMMY("gfx2d0_clk",         GFX2D0_CLK,             NULL),
+       CLK_DUMMY("gfx2d1_clk",         GFX2D1_CLK,             NULL),
+       CLK_DUMMY("gfx3d_clk",          GFX3D_CLK,              NULL),
+       CLK_DUMMY("ijpeg_axi_clk",      IJPEG_AXI_CLK,          NULL),
+       CLK_DUMMY("imem_axi_clk",       IMEM_AXI_CLK,           NULL),
+       CLK_DUMMY("jpegd_clk",          JPEGD_CLK,              NULL),
+       CLK_DUMMY("mdp_clk",            MDP_CLK,                NULL),
+       CLK_DUMMY("mdp_vsync_clk",      MDP_VSYNC_CLK,          NULL),
+       CLK_DUMMY("lut_mdp",            LUT_MDP_CLK,            NULL),
+       CLK_DUMMY("rot_clk",            ROT_CLK,                NULL),
+       CLK_DUMMY("tv_src_clk",         TV_SRC_CLK,             NULL),
+       CLK_DUMMY("tv_enc_clk",         TV_ENC_CLK,             NULL),
+       CLK_DUMMY("tv_dac_clk",         TV_DAC_CLK,             NULL),
+       CLK_DUMMY("vcodec_clk",         VCODEC_CLK,             NULL),
+       CLK_DUMMY("mdp_tv_clk",         MDP_TV_CLK,             NULL),
+       CLK_DUMMY("hdmi_clk",           HDMI_TV_CLK,            NULL),
+       CLK_DUMMY("hdmi_app_clk",       HDMI_APP_CLK,           NULL),
+       CLK_DUMMY("vpe_clk",            VPE_CLK,                NULL),
+       CLK_DUMMY("vfe_clk",            VFE_CLK,                NULL),
+       CLK_DUMMY("csi_vfe_clk",        CSI0_VFE_CLK,           NULL),
+       CLK_DUMMY("vfe_axi_clk",        VFE_AXI_CLK,            NULL),
+       CLK_DUMMY("ijpeg_axi_clk",      IJPEG_AXI_CLK,          NULL),
+       CLK_DUMMY("mdp_axi_clk",        MDP_AXI_CLK,            NULL),
+       CLK_DUMMY("rot_axi_clk",        ROT_AXI_CLK,            NULL),
+       CLK_DUMMY("vcodec_axi_clk",     VCODEC_AXI_CLK,         NULL),
+       CLK_DUMMY("vcodec_axi_a_clk",   VCODEC_AXI_A_CLK,       NULL),
+       CLK_DUMMY("vcodec_axi_b_clk",   VCODEC_AXI_B_CLK,       NULL),
+       CLK_DUMMY("vpe_axi_clk",        VPE_AXI_CLK,            NULL),
+       CLK_DUMMY("amp_pclk",           AMP_P_CLK,              NULL),
+       CLK_DUMMY("csi_pclk",           CSI0_P_CLK,             NULL),
+       CLK_DUMMY("dsi_m_pclk",         DSI1_M_P_CLK,           NULL),
+       CLK_DUMMY("dsi_s_pclk",         DSI1_S_P_CLK,           NULL),
+       CLK_DUMMY("dsi_m_pclk",         DSI2_M_P_CLK,           NULL),
+       CLK_DUMMY("dsi_s_pclk",         DSI2_S_P_CLK,           NULL),
+       CLK_DUMMY("gfx2d0_pclk",        GFX2D0_P_CLK,           NULL),
+       CLK_DUMMY("gfx2d1_pclk",        GFX2D1_P_CLK,           NULL),
+       CLK_DUMMY("gfx3d_pclk",         GFX3D_P_CLK,            NULL),
+       CLK_DUMMY("hdmi_m_pclk",        HDMI_M_P_CLK,           NULL),
+       CLK_DUMMY("hdmi_s_pclk",        HDMI_S_P_CLK,           NULL),
+       CLK_DUMMY("ijpeg_pclk",         IJPEG_P_CLK,            NULL),
+       CLK_DUMMY("jpegd_pclk",         JPEGD_P_CLK,            NULL),
+       CLK_DUMMY("imem_pclk",          IMEM_P_CLK,             NULL),
+       CLK_DUMMY("mdp_pclk",           MDP_P_CLK,              NULL),
+       CLK_DUMMY("smmu_pclk",          SMMU_P_CLK,             NULL),
+       CLK_DUMMY("rotator_pclk",       ROT_P_CLK,              NULL),
+       CLK_DUMMY("tv_enc_pclk",        TV_ENC_P_CLK,           NULL),
+       CLK_DUMMY("vcodec_pclk",        VCODEC_P_CLK,           NULL),
+       CLK_DUMMY("vfe_pclk",           VFE_P_CLK,              NULL),
+       CLK_DUMMY("vpe_pclk",           VPE_P_CLK,              NULL),
+       CLK_DUMMY("mi2s_osr_clk",       MI2S_OSR_CLK,           NULL),
+       CLK_DUMMY("mi2s_bit_clk",       MI2S_BIT_CLK,           NULL),
+       CLK_DUMMY("i2s_mic_osr_clk",    CODEC_I2S_MIC_OSR_CLK,  NULL),
+       CLK_DUMMY("i2s_mic_bit_clk",    CODEC_I2S_MIC_BIT_CLK,  NULL),
+       CLK_DUMMY("i2s_mic_osr_clk",    SPARE_I2S_MIC_OSR_CLK,  NULL),
+       CLK_DUMMY("i2s_mic_bit_clk",    SPARE_I2S_MIC_BIT_CLK,  NULL),
+       CLK_DUMMY("i2s_spkr_osr_clk",   CODEC_I2S_SPKR_OSR_CLK, NULL),
+       CLK_DUMMY("i2s_spkr_bit_clk",   CODEC_I2S_SPKR_BIT_CLK, NULL),
+       CLK_DUMMY("i2s_spkr_osr_clk",   SPARE_I2S_SPKR_OSR_CLK, NULL),
+       CLK_DUMMY("i2s_spkr_bit_clk",   SPARE_I2S_SPKR_BIT_CLK, NULL),
+       CLK_DUMMY("pcm_clk",            PCM_CLK,                NULL),
+       CLK_DUMMY("iommu_clk",          JPEGD_AXI_CLK,          NULL),
+       CLK_DUMMY("iommu_clk",          VFE_AXI_CLK,            NULL),
+       CLK_DUMMY("iommu_clk",          VCODEC_AXI_CLK, NULL),
+       CLK_DUMMY("iommu_clk",          GFX3D_CLK,      NULL),
+       CLK_DUMMY("iommu_clk",          GFX2D0_CLK,     NULL),
+       CLK_DUMMY("iommu_clk",          GFX2D1_CLK,     NULL),
+};
+
+unsigned msm_num_clocks_8960 = ARRAY_SIZE(msm_clocks_8960);
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
new file mode 100644 (file)
index 0000000..33c236c
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+
+static struct resource resources_dmov_adm0[] = {
+       {
+               .start = MSM8X60_DMOV_ADM0_PHYS,
+               .end = MSM8X60_DMOV_ADM0_PHYS + MSM8X60_DMOV_ADM0_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = INT_ADM0_AARM,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct resource resources_dmov_adm1[] = {
+       {
+               .start = MSM8X60_DMOV_ADM1_PHYS,
+               .end = MSM8X60_DMOV_ADM1_PHYS + MSM8X60_DMOV_ADM1_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = INT_ADM1_AARM,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_dmov_adm0 = {
+       .name   = "msm_dmov",
+       .id     = 0,
+       .num_resources = ARRAY_SIZE(resources_dmov_adm0),
+       .resource = resources_dmov_adm0,
+};
+
+struct platform_device msm_device_dmov_adm1 = {
+       .name   = "msm_dmov",
+       .id     = 1,
+       .num_resources = ARRAY_SIZE(resources_dmov_adm1),
+       .resource = resources_dmov_adm1,
+};
index 12d8deb78d9ca37b6a9bbe8fa6804301f3b1bae6..730982fe5902bd7df59eed913085cff3f459d127 100644 (file)
@@ -315,8 +315,27 @@ int __init msm_add_sdcc(unsigned int controller,
        return platform_device_register(pdev);
 }
 
+static struct resource resources_dmov[] = {
+       {
+               .start = QSD8X50_DMOV_PHYS,
+               .end = QSD8X50_DMOV_PHYS + QSD8X50_DMOV_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = INT_ADM_AARM,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_dmov = {
+       .name   = "msm_dmov",
+       .id     = -1,
+       .num_resources = ARRAY_SIZE(resources_dmov),
+       .resource = resources_dmov,
+};
+
 struct clk_lookup msm_clocks_8x50[] = {
-       CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
+       CLK_PCOM("adm_clk",     ADM_CLK,        "msm_dmov", 0),
        CLK_PCOM("ce_clk",      CE_CLK,         NULL, 0),
        CLK_PCOM("ebi1_clk",    EBI1_CLK,       NULL, CLK_MIN),
        CLK_PCOM("ebi2_clk",    EBI2_CLK,       NULL, 0),
index 9545c196c6e87832400bbb5fab059cbda93ba5ba..e38fc8610f39a5812c67adb2578cc10e91413f6d 100644 (file)
@@ -40,6 +40,11 @@ extern struct platform_device msm_device_i2c;
 
 extern struct platform_device msm_device_smd;
 
+extern struct platform_device msm_device_dmov;
+extern struct platform_device msm8960_device_dmov;
+extern struct platform_device msm_device_dmov_adm0;
+extern struct platform_device msm_device_dmov_adm1;
+
 extern struct platform_device msm_device_nand;
 
 extern struct platform_device msm_device_mddi0;
@@ -55,4 +60,7 @@ extern unsigned msm_num_clocks_7x30;
 extern struct clk_lookup msm_clocks_8x50[];
 extern unsigned msm_num_clocks_8x50;
 
+extern struct clk_lookup msm_clocks_8960[];
+extern unsigned msm_num_clocks_8960;
+
 #endif
index 02cae5e2951c2d8ebc6cade2c582d5bb37d25d54..16b40344d98c77e6d9406dcdab51c7164ad9857e 100644 (file)
@@ -1,6 +1,7 @@
 /* linux/arch/arm/mach-msm/dma.c
  *
  * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/completion.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <mach/dma.h>
 
 #define MSM_DMOV_CHANNEL_COUNT 16
+#define MSM_DMOV_MAX_ADMS 2
+
+#define MODULE_NAME "msm_dmov"
 
 enum {
        MSM_DMOV_PRINT_ERRORS = 1,
@@ -28,13 +35,55 @@ enum {
        MSM_DMOV_PRINT_FLOW = 4
 };
 
-static DEFINE_SPINLOCK(msm_dmov_lock);
-static struct clk *msm_dmov_clk;
-static unsigned int channel_active;
-static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
-static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
 unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
 
+struct msm_dmov_conf {
+       void __iomem *base;
+       int channel_active;
+       struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
+       struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
+       spinlock_t lock;
+       unsigned irq;
+       struct clk *clk;
+       struct clk *pclk;
+};
+
+static struct msm_dmov_conf dmov_conf[MSM_DMOV_MAX_ADMS];
+static int nr_adms;
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define DMOV_SD_AARM DMOV_SD2
+#define DMOV_SD_SIZE 0x400
+#elif defined(CONFIG_ARCH_MSM8X60)
+#define DMOV_SD_AARM DMOV_SD1
+#define DMOV_SD_SIZE 0x800
+#elif defined(CONFIG_ARCH_MSM8960)
+#define DMOV_SD_AARM DMOV_SD0
+#define DMOV_SD_SIZE 0x800
+#else
+#define DMOV_SD_AARM DMOV_SD3
+#define DMOV_SD_SIZE 0x400
+#endif
+
+#define DMOV_ADDR(sd, off, ch) (((sd) * DMOV_SD_SIZE) + (off) + ((ch) << 2))
+
+#define DMOV_SD0(off, ch) DMOV_ADDR(0, off, ch)
+#define DMOV_SD1(off, ch) DMOV_ADDR(1, off, ch)
+#define DMOV_SD2(off, ch) DMOV_ADDR(2, off, ch)
+#define DMOV_SD3(off, ch) DMOV_ADDR(3, off, ch)
+
+#define DMOV_CMD_PTR(ch)      DMOV_SD_AARM(0x000, ch)
+#define DMOV_RSLT(ch)         DMOV_SD_AARM(0x040, ch)
+#define DMOV_FLUSH0(ch)       DMOV_SD_AARM(0x080, ch)
+#define DMOV_FLUSH1(ch)       DMOV_SD_AARM(0x0C0, ch)
+#define DMOV_FLUSH2(ch)       DMOV_SD_AARM(0x100, ch)
+#define DMOV_FLUSH3(ch)       DMOV_SD_AARM(0x140, ch)
+#define DMOV_FLUSH4(ch)       DMOV_SD_AARM(0x180, ch)
+#define DMOV_FLUSH5(ch)       DMOV_SD_AARM(0x1C0, ch)
+#define DMOV_STATUS(ch)       DMOV_SD_AARM(0x200, ch)
+#define DMOV_CONFIG(ch)       DMOV_SD_AARM(0x300, ch)
+#define DMOV_ISR              DMOV_SD_AARM(0x380, 0)
+
 #define MSM_DMOV_DPRINTF(mask, format, args...) \
        do { \
                if ((mask) & msm_dmov_print_mask) \
@@ -47,48 +96,121 @@ unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
 #define PRINT_FLOW(format, args...) \
        MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
 
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+static inline unsigned dmov_readl(unsigned addr, int adm)
+{
+       return readl(dmov_conf[adm].base + addr);
+}
+
+static inline void dmov_writel(unsigned val, unsigned addr, int adm)
+{
+       writel(val, dmov_conf[adm].base + addr);
+}
+
+#define DMOV_ID_TO_ADM(id)   ((id) / MSM_DMOV_CHANNEL_COUNT)
+#define DMOV_ID_TO_CHAN(id)   ((id) % MSM_DMOV_CHANNEL_COUNT)
+#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)
+
+int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+{
+       int adm = DMOV_ID_TO_ADM(id);
+       int ch = DMOV_ID_TO_CHAN(id);
+
+       if (!dmov_conf[adm].base)
+               return -ENODEV;
+
+       dmov_writel((graceful << 31), DMOV_FLUSH0(ch), adm);
+
+       return 0;
+}
+EXPORT_SYMBOL(msm_dmov_stop_cmd);
+
+static int msm_dmov_clocks_on(int adm)
+{
+       int ret = 0;
+
+       if (!IS_ERR(dmov_conf[adm].clk)) {
+               ret = clk_enable(dmov_conf[adm].clk);
+               if (ret)
+                       return ret;
+               if (!IS_ERR(dmov_conf[adm].pclk)) {
+                       ret = clk_enable(dmov_conf[adm].pclk);
+                       if (ret)
+                               clk_disable(dmov_conf[adm].clk);
+               }
+       }
+       return ret;
+}
+
+static void msm_dmov_clocks_off(int adm)
 {
-       writel((graceful << 31), DMOV_FLUSH0(id));
+       if (!IS_ERR(dmov_conf[adm].clk))
+               clk_disable(dmov_conf[adm].clk);
+       if (!IS_ERR(dmov_conf[adm].pclk))
+               clk_disable(dmov_conf[adm].pclk);
 }
 
-void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
+int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 {
        unsigned long irq_flags;
        unsigned int status;
+       int adm = DMOV_ID_TO_ADM(id);
+       int ch = DMOV_ID_TO_CHAN(id);
+
+       if (!dmov_conf[adm].base)
+               return -ENODEV;
 
-       spin_lock_irqsave(&msm_dmov_lock, irq_flags);
-       if (!channel_active)
-               clk_enable(msm_dmov_clk);
+       spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+       if (!dmov_conf[adm].channel_active)
+               msm_dmov_clocks_on(adm);
        dsb();
-       status = readl(DMOV_STATUS(id));
-       if (list_empty(&ready_commands[id]) &&
+       status = dmov_readl(DMOV_STATUS(ch), adm);
+       if (list_empty(&dmov_conf[adm].ready_commands[ch]) &&
                (status & DMOV_STATUS_CMD_PTR_RDY)) {
-#if 0
-               if (list_empty(&active_commands[id])) {
-                       PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id);
-                       writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id));
-               }
-#endif
                if (cmd->execute_func)
                        cmd->execute_func(cmd);
-               PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
-               list_add_tail(&cmd->list, &active_commands[id]);
-               if (!channel_active)
-                       enable_irq(INT_ADM_AARM);
-               channel_active |= 1U << id;
-               writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+               PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
+                        id, status);
+               list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
+               if (!dmov_conf[adm].channel_active)
+                       enable_irq(dmov_conf[adm].irq);
+               dmov_conf[adm].channel_active |= 1U << ch;
+               dmov_writel(cmd->cmdptr, DMOV_CMD_PTR(ch), adm);
        } else {
-               if (!channel_active)
-                       clk_disable(msm_dmov_clk);
-               if (list_empty(&active_commands[id]))
-                       PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
+               if (!dmov_conf[adm].channel_active)
+                       msm_dmov_clocks_off(adm);
+               if (list_empty(&dmov_conf[adm].active_commands[ch]))
+                       PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover "
+                                   "stalled, status %x\n", id, status);
+               PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
+                        "%x\n", id, status);
+               list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
+       }
+       spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
 
-               PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status);
-               list_add_tail(&cmd->list, &ready_commands[id]);
+       return 0;
+}
+EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
+
+int msm_dmov_flush(unsigned int id)
+{
+       unsigned long flags;
+       int ch = DMOV_ID_TO_CHAN(id);
+       int adm = DMOV_ID_TO_ADM(id);
+
+       if (!dmov_conf[adm].base)
+               return -ENODEV;
+
+       spin_lock_irqsave(&dmov_conf[adm].lock, flags);
+       /* XXX not checking if flush cmd sent already */
+       if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
+               PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
+               dmov_writel(DMOV_FLUSH_GRACEFUL, DMOV_FLUSH0(ch), adm);
        }
-       spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+       spin_unlock_irqrestore(&dmov_conf[adm].lock, flags);
+
+       return 0;
 }
+EXPORT_SYMBOL(msm_dmov_flush);
 
 struct msm_dmov_exec_cmdptr_cmd {
        struct msm_dmov_cmd dmov_cmd;
@@ -114,6 +236,10 @@ dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
 int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
 {
        struct msm_dmov_exec_cmdptr_cmd cmd;
+       int adm = DMOV_ID_TO_ADM(id);
+
+       if (!dmov_conf[adm].base)
+               return -ENODEV;
 
        PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
 
@@ -135,41 +261,68 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
        PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
        return 0;
 }
+EXPORT_SYMBOL(msm_dmov_exec_cmd);
 
+static void msm_dmov_fill_errdata(struct msm_dmov_errdata *errdata, int ch,
+                                 int adm)
+{
+       errdata->flush[0] = dmov_readl(DMOV_FLUSH0(ch), adm);
+       errdata->flush[1] = dmov_readl(DMOV_FLUSH1(ch), adm);
+       errdata->flush[2] = dmov_readl(DMOV_FLUSH2(ch), adm);
+       errdata->flush[3] = dmov_readl(DMOV_FLUSH3(ch), adm);
+       errdata->flush[4] = dmov_readl(DMOV_FLUSH4(ch), adm);
+       errdata->flush[5] = dmov_readl(DMOV_FLUSH5(ch), adm);
+}
+
+static int msm_dmov_irq_to_adm(unsigned irq)
+{
+       int i;
+       for (i = 0; i < nr_adms; i++)
+               if (dmov_conf[i].irq == irq)
+                       return i;
+       PRINT_ERROR("msm_dmov_irq_to_adm: can't match ADM to IRQ %d\n", irq);
+       return -EINVAL;
+}
 
 static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 {
        unsigned int int_status, mask, id;
        unsigned long irq_flags;
+       unsigned int ch;
        unsigned int ch_status;
        unsigned int ch_result;
        struct msm_dmov_cmd *cmd;
+       int adm = msm_dmov_irq_to_adm(irq);
 
-       spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+       spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
 
-       int_status = readl(DMOV_ISR); /* read and clear interrupt */
+       int_status = dmov_readl(DMOV_ISR, adm); /* read and clear interrupt */
        PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
 
        while (int_status) {
                mask = int_status & -int_status;
-               id = fls(mask) - 1;
+               ch = fls(mask) - 1;
+               id = DMOV_CHAN_ADM_TO_ID(ch, adm);
                PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
                int_status &= ~mask;
-               ch_status = readl(DMOV_STATUS(id));
+               ch_status = dmov_readl(DMOV_STATUS(ch), adm);
                if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
                        PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status);
                        continue;
                }
                do {
-                       ch_result = readl(DMOV_RSLT(id));
-                       if (list_empty(&active_commands[id])) {
+                       ch_result = dmov_readl(DMOV_RSLT(ch), adm);
+                       if (list_empty(&dmov_conf[adm].active_commands[ch])) {
                                PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
                                        "with no active command, status %x, result %x\n",
                                        id, ch_status, ch_result);
                                cmd = NULL;
                        } else
-                               cmd = list_entry(active_commands[id].next, typeof(*cmd), list);
-                       PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
+                               cmd = list_entry(dmov_conf[adm].
+                                       active_commands[ch].next, typeof(*cmd),
+                                       list);
+                       PRINT_FLOW("msm_datamover_irq_handler id %d, status %x,"
+                                  " result %x\n", id, ch_status, ch_result);
                        if (ch_result & DMOV_RSLT_DONE) {
                                PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
                                        id, ch_status);
@@ -184,12 +337,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                        if (ch_result & DMOV_RSLT_FLUSH) {
                                struct msm_dmov_errdata errdata;
 
-                               errdata.flush[0] = readl(DMOV_FLUSH0(id));
-                               errdata.flush[1] = readl(DMOV_FLUSH1(id));
-                               errdata.flush[2] = readl(DMOV_FLUSH2(id));
-                               errdata.flush[3] = readl(DMOV_FLUSH3(id));
-                               errdata.flush[4] = readl(DMOV_FLUSH4(id));
-                               errdata.flush[5] = readl(DMOV_FLUSH5(id));
+                               msm_dmov_fill_errdata(&errdata, ch, adm);
                                PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
                                PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
                                if (cmd) {
@@ -201,13 +349,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                        if (ch_result & DMOV_RSLT_ERROR) {
                                struct msm_dmov_errdata errdata;
 
-                               errdata.flush[0] = readl(DMOV_FLUSH0(id));
-                               errdata.flush[1] = readl(DMOV_FLUSH1(id));
-                               errdata.flush[2] = readl(DMOV_FLUSH2(id));
-                               errdata.flush[3] = readl(DMOV_FLUSH3(id));
-                               errdata.flush[4] = readl(DMOV_FLUSH4(id));
-                               errdata.flush[5] = readl(DMOV_FLUSH5(id));
-
+                               msm_dmov_fill_errdata(&errdata, ch, adm);
                                PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
                                PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
                                if (cmd) {
@@ -217,55 +359,148 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                                }
                                /* this does not seem to work, once we get an error */
                                /* the datamover will no longer accept commands */
-                               writel(0, DMOV_FLUSH0(id));
+                               dmov_writel(0, DMOV_FLUSH0(ch), adm);
                        }
-                       ch_status = readl(DMOV_STATUS(id));
+                       ch_status = dmov_readl(DMOV_STATUS(ch), adm);
                        PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-                       if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) {
-                               cmd = list_entry(ready_commands[id].next, typeof(*cmd), list);
+                       if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) &&
+                           !list_empty(&dmov_conf[adm].ready_commands[ch])) {
+                               cmd = list_entry(dmov_conf[adm].
+                                       ready_commands[ch].next, typeof(*cmd),
+                                       list);
                                list_del(&cmd->list);
-                               list_add_tail(&cmd->list, &active_commands[id]);
+                               list_add_tail(&cmd->list, &dmov_conf[adm].
+                                             active_commands[ch]);
                                if (cmd->execute_func)
                                        cmd->execute_func(cmd);
                                PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
-                               writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+                               dmov_writel(cmd->cmdptr, DMOV_CMD_PTR(ch), adm);
                        }
                } while (ch_status & DMOV_STATUS_RSLT_VALID);
-               if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
-                       channel_active &= ~(1U << id);
+               if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
+                               list_empty(&dmov_conf[adm].ready_commands[ch]))
+                       dmov_conf[adm].channel_active &= ~(1U << ch);
                PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
        }
 
-       if (!channel_active) {
-               disable_irq_nosync(INT_ADM_AARM);
-               clk_disable(msm_dmov_clk);
+       if (!dmov_conf[adm].channel_active) {
+               disable_irq_nosync(dmov_conf[adm].irq);
+               msm_dmov_clocks_off(adm);
        }
 
-       spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+       spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
        return IRQ_HANDLED;
 }
 
-static int __init msm_init_datamover(void)
+static void __init msm_dmov_deinit_clocks(int adm)
+{
+       if (!IS_ERR(dmov_conf[adm].clk))
+               clk_put(dmov_conf[adm].clk);
+       if (!IS_ERR(dmov_conf[adm].pclk))
+               clk_put(dmov_conf[adm].pclk);
+}
+
+#define PDEV_TO_ADM(pdev) \
+({ \
+       typeof(pdev) _pdev = pdev; \
+       (_pdev->id == -1) ? 0 : _pdev->id; \
+})
+
+static int __devinit msm_dmov_init_clocks(struct platform_device *pdev)
+{
+       int ret = 0;
+       int adm = PDEV_TO_ADM(pdev);
+
+       dmov_conf[adm].clk = clk_get(&pdev->dev, "adm_clk");
+       if (IS_ERR(dmov_conf[adm].clk)) {
+               PRINT_ERROR("%s: Error getting adm_clk\n", __func__);
+               ret = PTR_ERR(dmov_conf[adm].clk);
+       }
+
+       dmov_conf[adm].pclk = clk_get(&pdev->dev, "adm_pclk");
+       /* pclk not present on all SoCs, don't return error on failure */
+
+       return ret;
+}
+
+static int __devinit msm_dmov_conf_init(struct platform_device *pdev)
 {
        int i;
-       int ret;
-       struct clk *clk;
+       int adm = PDEV_TO_ADM(pdev);
+       struct resource *irqres =
+               platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       struct resource *memres =
+               platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
+       if (!irqres || !memres || !irqres->start)
+               return -EINVAL;
+
+       dmov_conf[adm].irq = irqres->start;
+
+       dmov_conf[adm].base =
+               ioremap_nocache(memres->start, resource_size(memres));
+       if (!dmov_conf[adm].base)
+               return -ENOMEM;
+
+       dmov_conf[adm].lock = __SPIN_LOCK_UNLOCKED(dmov_lock);
        for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
-               INIT_LIST_HEAD(&ready_commands[i]);
-               INIT_LIST_HEAD(&active_commands[i]);
-               writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
+               INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
+               INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);
        }
-       clk = clk_get(NULL, "adm_clk");
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
-       msm_dmov_clk = clk;
-       ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+       return 0;
+}
+
+static inline void __devinit msm_dmov_conf_free(int adm)
+{
+       iounmap(dmov_conf[adm].base);
+       dmov_conf[adm].base = NULL;
+}
+
+static int __devinit msm_dmov_probe(struct platform_device *pdev)
+{
+       int i;
+       int ret;
+       int adm = PDEV_TO_ADM(pdev);
+
+       ret = msm_dmov_conf_init(pdev);
        if (ret)
                return ret;
-       disable_irq(INT_ADM_AARM);
+
+       for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++)
+               dmov_writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT
+                         | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i), adm);
+
+       ret = msm_dmov_init_clocks(pdev);
+       if (ret)
+               goto out_conf;
+
+       ret = request_irq(dmov_conf[adm].irq, msm_datamover_irq_handler, 0,
+                         "msmdatamover", NULL);
+       if (ret)
+               goto out_clock;
+       disable_irq(dmov_conf[adm].irq);
+       nr_adms++;
+
        return 0;
+
+out_clock:
+       msm_dmov_deinit_clocks(adm);
+out_conf:
+       msm_dmov_conf_free(adm);
+       return ret;
 }
 
-arch_initcall(msm_init_datamover);
+static struct platform_driver msm_dmov_driver = {
+       .probe = msm_dmov_probe,
+       .driver = {
+               .name = MODULE_NAME,
+               .owner = THIS_MODULE,
+       },
+};
 
+static int __init msm_init_datamover(void)
+{
+       return platform_driver_register(&msm_dmov_driver);
+}
+
+arch_initcall(msm_init_datamover);
index 05583f569524449ed2b61ea52ecd42544a959416..3d677731eda3345a89639825494ab40688621ea4 100644 (file)
@@ -1,6 +1,7 @@
 /* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -14,6 +15,7 @@
  */
 
 #ifndef __ASM_ARCH_MSM_DMA_H
+#define __ASM_ARCH_MSM_DMA_H
 
 #include <linux/list.h>
 #include <mach/msm_iomap.h>
@@ -32,67 +34,75 @@ struct msm_dmov_cmd {
        void *data;
 };
 
-#ifndef CONFIG_ARCH_MSM8X60
-void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
+int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
 int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-#else
-static inline
-void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
-static inline
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
-static inline
-int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
-#endif
-
-
-#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
-#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
-#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
-#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
-
-#if defined(CONFIG_ARCH_MSM7X30)
-#define DMOV_SD_AARM DMOV_SD2
-#else
-#define DMOV_SD_AARM DMOV_SD3
-#endif
+int msm_dmov_flush(unsigned int id);
 
-#define DMOV_CMD_PTR(ch)      DMOV_SD_AARM(0x000, ch)
 #define DMOV_CMD_LIST         (0 << 29) /* does not work */
 #define DMOV_CMD_PTR_LIST     (1 << 29) /* works */
 #define DMOV_CMD_INPUT_CFG    (2 << 29) /* untested */
 #define DMOV_CMD_OUTPUT_CFG   (3 << 29) /* untested */
 #define DMOV_CMD_ADDR(addr)   ((addr) >> 3)
 
-#define DMOV_RSLT(ch)         DMOV_SD_AARM(0x040, ch)
 #define DMOV_RSLT_VALID       (1 << 31) /* 0 == host has empties result fifo */
 #define DMOV_RSLT_ERROR       (1 << 3)
 #define DMOV_RSLT_FLUSH       (1 << 2)
 #define DMOV_RSLT_DONE        (1 << 1)  /* top pointer done */
 #define DMOV_RSLT_USER        (1 << 0)  /* command with FR force result */
 
-#define DMOV_FLUSH0(ch)       DMOV_SD_AARM(0x080, ch)
-#define DMOV_FLUSH1(ch)       DMOV_SD_AARM(0x0C0, ch)
-#define DMOV_FLUSH2(ch)       DMOV_SD_AARM(0x100, ch)
-#define DMOV_FLUSH3(ch)       DMOV_SD_AARM(0x140, ch)
-#define DMOV_FLUSH4(ch)       DMOV_SD_AARM(0x180, ch)
-#define DMOV_FLUSH5(ch)       DMOV_SD_AARM(0x1C0, ch)
+#define DMOV_FLUSH_GRACEFUL  (1 << 31)
 
-#define DMOV_STATUS(ch)       DMOV_SD_AARM(0x200, ch)
 #define DMOV_STATUS_RSLT_COUNT(n)    (((n) >> 29))
 #define DMOV_STATUS_CMD_COUNT(n)     (((n) >> 27) & 3)
 #define DMOV_STATUS_RSLT_VALID       (1 << 1)
 #define DMOV_STATUS_CMD_PTR_RDY      (1 << 0)
 
-#define DMOV_ISR              DMOV_SD_AARM(0x380, 0)
-  
-#define DMOV_CONFIG(ch)       DMOV_SD_AARM(0x300, ch)
 #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
 #define DMOV_CONFIG_FORCE_FLUSH_RSLT   (1 << 1)
 #define DMOV_CONFIG_IRQ_EN             (1 << 0)
 
-/* channel assignments */
+#define DMOV_8X60_GP_CHAN           16
+
+#define DMOV_8X60_CE_IN_CHAN        2
+#define DMOV_8X60_CE_IN_CRCI        4
+
+#define DMOV_8X60_CE_OUT_CHAN       3
+#define DMOV_8X60_CE_OUT_CRCI       5
+
+#define DMOV_8X60_CE_HASH_CRCI      15
+
+#define DMOV_8X60_SDC1_CHAN         18
+#define DMOV_8X60_SDC1_CRCI         1
+
+#define DMOV_8X60_SDC2_CHAN         19
+#define DMOV_8X60_SDC2_CRCI         4
+
+#define DMOV_8X60_SDC3_CHAN         20
+#define DMOV_8X60_SDC3_CRCI         2
+
+#define DMOV_8X60_SDC4_CHAN         21
+#define DMOV_8X60_SDC4_CRCI         5
+
+#define DMOV_8X60_SDC5_CHAN         21
+#define DMOV_8X60_SDC5_CRCI         14
+
+#define DMOV_8X60_TSIF_CHAN         4
+#define DMOV_8X60_TSIF_CRCI         6
+
+#define DMOV_8X60_HSUART1_TX_CHAN   22
+#define DMOV_8X60_HSUART1_TX_CRCI   8
+
+#define DMOV_8X60_HSUART1_RX_CHAN   23
+#define DMOV_8X60_HSUART1_RX_CRCI   9
+
+#define DMOV_8X60_HSUART2_TX_CHAN   8
+#define DMOV_8X60_HSUART2_TX_CRCI   13
+
+#define DMOV_8X60_HSUART2_RX_CHAN   8
+#define DMOV_8X60_HSUART2_RX_CRCI   14
 
+/* channel assignments before 8x60 */
 #define DMOV_NAND_CHAN        7
 #define DMOV_NAND_CRCI_CMD    5
 #define DMOV_NAND_CRCI_DATA   4
index 36ad50d3bfaa8e03e9f0333c05ed655d9ebf4adb..40a8c178f10d9e85a2873c83247c3f2fe553f408 100644 (file)
@@ -1,26 +1 @@
-/*
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
- * Author: Mike Lockwood <lockwood@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#ifndef __ASM_ARCH_MSM_GPIO_H
-#define __ASM_ARCH_MSM_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value  __gpio_get_value
-#define gpio_set_value  __gpio_set_value
-#define gpio_cansleep   __gpio_cansleep
-#define gpio_to_irq     __gpio_to_irq
-
-#endif /* __ASM_ARCH_MSM_GPIO_H */
+/* empty */
index f2f8d299ba9533a1d15ce080823e3a2f653a579b..58d5e7eec431de7e2c5b9ff89116cc3764be6476 100644 (file)
 #elif defined(CONFIG_ARCH_QSD8X50)
 #define PLAT_PHYS_OFFSET               UL(0x20000000)
 #elif defined(CONFIG_ARCH_MSM7X30)
-#define PLAT_PHYS_OFFSET               UL(0x00200000)
+#define PLAT_PHYS_OFFSET               UL(0x00000000)
 #elif defined(CONFIG_ARCH_MSM8X60)
-#define PLAT_PHYS_OFFSET               UL(0x40200000)
+#define PLAT_PHYS_OFFSET               UL(0x40000000)
 #elif defined(CONFIG_ARCH_MSM8960)
-#define PLAT_PHYS_OFFSET               UL(0x40200000)
+#define PLAT_PHYS_OFFSET               UL(0x40000000)
 #else
 #define PLAT_PHYS_OFFSET               UL(0x10000000)
 #endif
index 94fe9fe6feb35e207a48b88685f143985d6910d1..04bca831ecb06aa042a325e072cfdd6b6b7135a6 100644 (file)
@@ -51,9 +51,8 @@
 #define MSM7X00_CSR_PHYS      0xC0100000
 #define MSM7X00_CSR_SIZE      SZ_4K
 
-#define MSM_DMOV_BASE         IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS         0xA9700000
-#define MSM_DMOV_SIZE         SZ_4K
+#define MSM7X00_DMOV_PHYS     0xA9700000
+#define MSM7X00_DMOV_SIZE     SZ_4K
 
 #define MSM7X00_GPIO1_PHYS        0xA9200000
 #define MSM7X00_GPIO1_SIZE        SZ_4K
index 37694442d1bda079bb1475e71a511cf27ad825f3..7357ed6b116496029622cf74efc290c4d3b9a693 100644 (file)
@@ -42,9 +42,8 @@
 #define MSM7X30_CSR_PHYS      0xC0100000
 #define MSM7X30_CSR_SIZE      SZ_4K
 
-#define MSM_DMOV_BASE         IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS         0xAC400000
-#define MSM_DMOV_SIZE         SZ_4K
+#define MSM7X30_DMOV_PHYS     0xAC400000
+#define MSM7X30_DMOV_SIZE     SZ_4K
 
 #define MSM7X30_GPIO1_PHYS        0xAC001000
 #define MSM7X30_GPIO1_SIZE        SZ_4K
index 3c9d9602a318b935ebb5e5a940df12fba6fdbeb6..b251ba63b3e23123957f28715c4ec897164836ce 100644 (file)
@@ -45,4 +45,7 @@
 #define MSM8960_TMR0_PHYS      0x0208A000
 #define MSM8960_TMR0_SIZE      SZ_4K
 
+#define MSM8960_DMOV_PHYS      0x18300000
+#define MSM8960_DMOV_SIZE      SZ_1M
+
 #endif
index d67cd73316f456eaaf7258fc8ea3444ebd884b9d..38f37ed66c704ca3e1f6093f5a21e145b006f80c 100644 (file)
@@ -42,9 +42,8 @@
 #define QSD8X50_CSR_PHYS      0xAC100000
 #define QSD8X50_CSR_SIZE      SZ_4K
 
-#define MSM_DMOV_BASE         IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS         0xA9700000
-#define MSM_DMOV_SIZE         SZ_4K
+#define QSD8X50_DMOV_PHYS     0xA9700000
+#define QSD8X50_DMOV_SIZE     SZ_4K
 
 #define QSD8X50_GPIO1_PHYS        0xA9000000
 #define QSD8X50_GPIO1_SIZE        SZ_4K
index 3b19b8f244b8808d63489a1b92fc1851a38e0ffb..87a26c6ed98f55515009c5087fcc657f21b54a29 100644 (file)
 #define MSM_SHARED_RAM_BASE    IOMEM(0xF0100000)
 #define MSM_SHARED_RAM_SIZE    SZ_1M
 
+#define MSM8X60_DMOV_ADM0_PHYS 0x18320000
+#define MSM8X60_DMOV_ADM0_SIZE SZ_1M
+
+#define MSM8X60_DMOV_ADM1_PHYS 0x18420000
+#define MSM8X60_DMOV_ADM1_SIZE SZ_1M
+
 #define MSM8X60_TMR_PHYS       0x02000000
 #define MSM8X60_TMR_SIZE       SZ_4K
 
index 140ddbbc3a8a5509ddbabb6520bb1605ae038d70..067653a11fbb6f8d34092f4bda416a3781f02ee7 100644 (file)
@@ -42,7 +42,6 @@
 static struct map_desc msm_io_desc[] __initdata = {
        MSM_DEVICE(VIC),
        MSM_CHIP_DEVICE(CSR, MSM7X00),
-       MSM_DEVICE(DMOV),
        MSM_CHIP_DEVICE(GPIO1, MSM7X00),
        MSM_CHIP_DEVICE(GPIO2, MSM7X00),
        MSM_DEVICE(CLK_CTL),
@@ -75,7 +74,6 @@ void __init msm_map_common_io(void)
 static struct map_desc qsd8x50_io_desc[] __initdata = {
        MSM_DEVICE(VIC),
        MSM_CHIP_DEVICE(CSR, QSD8X50),
-       MSM_DEVICE(DMOV),
        MSM_CHIP_DEVICE(GPIO1, QSD8X50),
        MSM_CHIP_DEVICE(GPIO2, QSD8X50),
        MSM_DEVICE(CLK_CTL),
@@ -134,7 +132,6 @@ void __init msm_map_msm8960_io(void)
 static struct map_desc msm7x30_io_desc[] __initdata = {
        MSM_DEVICE(VIC),
        MSM_CHIP_DEVICE(CSR, MSM7X30),
-       MSM_DEVICE(DMOV),
        MSM_CHIP_DEVICE(GPIO1, MSM7X30),
        MSM_CHIP_DEVICE(GPIO2, MSM7X30),
        MSM_DEVICE(CLK_CTL),
index 67039c3e0c48fa6b94f1147b3316f74afcecba9e..760a0efe7580b0dd194ff9bfe4295624336bb806 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 3e24431bb5eaf929c28ed46cd77b62286711c512..e421b701663b8bfda904ca151727b7d2456452bc 100644 (file)
@@ -7,12 +7,11 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/irq.h>
-#include <asm/gpio.h>
 #include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include "common.h"
index 59b7686b92097f30f36175ccfeb8ead5f12d42c3..cf4e494d44bf98a62bfee8cbd67baee13d87a1e3 100644 (file)
@@ -7,13 +7,12 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
 #include <linux/io.h>
 #include <plat/mpp.h>
-#include <asm/gpio.h>
 #include <mach/hardware.h>
 #include "common.h"
 #include "mpp.h"
index e928be1b6757ed7b4ee9c17cd642a379c42e2ca1..ca207ca305ec2cb4bb191ad93287e9d729336753 100644 (file)
@@ -1,9 +1,9 @@
-   zreladdr-$(CONFIG_ARCH_MX50)        := 0x70008000
+   zreladdr-$(CONFIG_ARCH_MX50)        += 0x70008000
 params_phys-$(CONFIG_ARCH_MX50)        := 0x70000100
 initrd_phys-$(CONFIG_ARCH_MX50)        := 0x70800000
-   zreladdr-$(CONFIG_ARCH_MX51)        := 0x90008000
+   zreladdr-$(CONFIG_ARCH_MX51)        += 0x90008000
 params_phys-$(CONFIG_ARCH_MX51)        := 0x90000100
 initrd_phys-$(CONFIG_ARCH_MX51)        := 0x90800000
-   zreladdr-$(CONFIG_ARCH_MX53)        := 0x70008000
+   zreladdr-$(CONFIG_ARCH_MX53)        += 0x70008000
 params_phys-$(CONFIG_ARCH_MX53)        := 0x70000100
 initrd_phys-$(CONFIG_ARCH_MX53)        := 0x70800000
index eb541e0291daddd2cd685e16abfa228b425d2ed9..07b11fe6453f525bc43fc15cf32694388188f0c7 100644 (file)
@@ -1 +1 @@
-zreladdr-y := 0x40008000
+zreladdr-y += 0x40008000
index 828ccccb6aad68dcb7b0e407f898b6d8147b2f98..bb11e63261e491fb36c750787487c23bce2dc313 100644 (file)
 #ifndef __MACH_MXS_GPIO_H__
 #define __MACH_MXS_GPIO_H__
 
-#include <asm-generic/gpio.h>
-
 #define MXS_GPIO_NR(bank, nr)  ((bank) * 32 + (nr))
 
-/* use gpiolib dispatchers */
-#define gpio_get_value         __gpio_get_value
-#define gpio_set_value         __gpio_set_value
-#define gpio_cansleep          __gpio_cansleep
-#define gpio_to_irq            __gpio_to_irq
-
 #define irq_to_gpio(irq)       ((irq) - MXS_GPIO_IRQ_START)
 
 #endif /* __MACH_MXS_GPIO_H__ */
index b81cf6aff0ac344b33e364c55a7ecae9c25d1eae..534a4d27055e0f9c5b004105d5e9122f9be624a2 100644 (file)
@@ -1,2 +1,2 @@
-    zreladdr-y                 := 0x80008000
+    zreladdr-y                 += 0x80008000
 
index c7e75acfe6c9b1911a5825c2b3136ad9b719d445..ff0a4b5b0a82b5873a119ec072b3db781651ab86 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 
index 139930350d939289c729fdde62339873aa2989bd..97d7186484caf363502fc9f4907310bd839b3086 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
+#include <plat/gpio-nomadik.h>
 #include <plat/mtu.h>
 
 #include <mach/setup.h>
index ac58e3b03b1a5516e87379450ccffcd9dd4a1fb7..dc67717db6f078db7975adc873bf6efe2a64eaef 100644 (file)
@@ -21,8 +21,8 @@
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
 
+#include <plat/gpio-nomadik.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <asm/mach/map.h>
index abfe25a08d6b6e15f336048395013669efc06595..0fc2f6f1cc979097cf83de13a924c7fb05a105f1 100644 (file)
@@ -3,8 +3,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/i2c-gpio.h>
-#include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <plat/gpio-nomadik.h>
 
 /*
  * There are two busses in the 8815NHK.
index a057b546b6e5fa4b3887c2b2a723ff814a5424c3..6c3d421c2d11e797361ef9ab4ef82dc16d4bc419 100644 (file)
@@ -1,3 +1,3 @@
-zreladdr-y     := 0x00008000
+zreladdr-y     += 0x00008000
 params_phys-y  := 0x00000100
 
index 292d56c5a88804137d79a2970d977057626cf2ae..13bda8dbd6043f9d3c2754d93c634ba335bdaf4e 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y          := 0x10008000
+   zreladdr-y          += 0x10008000
 params_phys-y          := 0x10000100
 initrd_phys-y          := 0x10800000
index 312ea6b0409dcd5e93464e3fef1fe4334d63ddfe..d86e9af2822ba71b59997ed516953c1f4280c0a6 100644 (file)
@@ -11,7 +11,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/input.h>
@@ -30,7 +30,6 @@
 
 #include <plat/io.h>
 #include <plat/board-ams-delta.h>
-#include <mach/gpio.h>
 #include <plat/keypad.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
index a6b1bea50371e7144492af17f4d9163116d1ac0d..dd814b33cdd5c44f7b66fd69875043859c84a222 100644 (file)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -28,7 +28,6 @@
 #include <asm/mach/map.h>
 
 #include <plat/tc.h>
-#include <mach/gpio.h>
 #include <plat/mux.h>
 #include <plat/flash.h>
 #include <plat/fpga.h>
index 04fc356c40fa9c0fd8ea8f7c69b4afa64852716e..8f7d11581482f1417c2a9de4eb5505fe2763bb75 100644 (file)
@@ -12,7 +12,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -22,7 +22,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/board.h>
index f2fc43d8382b36c5e19e18e371abfce8e9595a74..da0e37d408237076ae8dda8255fa00e085f325e5 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 
 #include <linux/i2c/tps65010.h>
 
 #include <plat/mmc.h>
-#include <mach/gpio.h>
 
 #include "board-h2.h"
 
index cb7fb1aa3dca5e832374971add929ec1fdd49845..0796ad7e24b5b946397f4b02c8c16a6cff19f057 100644 (file)
@@ -18,7 +18,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
@@ -32,7 +32,6 @@
 #include <linux/smc91x.h>
 
 #include <mach/hardware.h>
-#include <asm/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index 2098525e7cc5dcd1de834fd8dd0a642077ee9ddf..f8242aa9b76321229f400ccf2b0bcb4a3f28c1f0 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 
 #include <linux/i2c/tps65010.h>
 
 #include <plat/mmc.h>
-#include <mach/gpio.h>
 
 #include "board-h3.h"
 
index 31f34875ffad370fc1da66e3d930731687185200..fe1814c5e748123ea0659d5e3cb502bdafa7eb33 100644 (file)
@@ -13,7 +13,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/major.h>
@@ -34,7 +34,6 @@
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <mach/hardware.h>
-#include <asm/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index 36e06ea7ec65c728e927cbdf27f07085c67d40fc..4af7bfa40e4a03ba3b2d3778aa99747e9b8291b3 100644 (file)
@@ -23,7 +23,6 @@
  * 02110-1301, USA.
  *
  */
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index 0b1ba462d3885824561ebb3ea0b6047b6f0efe35..e603e5eb32a89e5a2b0e0258d6aaef64541af5a7 100644 (file)
@@ -15,7 +15,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -34,7 +34,6 @@
 #include <plat/mux.h>
 #include <plat/flash.h>
 #include <plat/fpga.h>
-#include <mach/gpio.h>
 #include <plat/tc.h>
 #include <plat/usb.h>
 #include <plat/keypad.h>
index 5469ce247ffe913a31e7a61d82a4a94aafc59362..8420535fe51df3de67ed80ad3d98ab992794e18a 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
@@ -26,7 +26,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/board.h>
index b08a213807724d6027eb304fe3296a32cfdb31a1..bf1ebe5b244213ac8557b8e2ad8d60d4c6894b9c 100644 (file)
@@ -25,7 +25,7 @@
  * with this program; if not, write  to the Free Software Foundation, Inc.,
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -42,7 +42,6 @@
 #include <linux/i2c/tps65010.h>
 
 #include <mach/hardware.h>
-#include <asm/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index 459cb6bfed55aa36e3e2dd8a6cdccf53ee355fb7..45596b5acf09c09221a3e1e10bdcdb1906d8573c 100644 (file)
@@ -16,7 +16,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/input.h>
@@ -33,7 +33,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
index b214f45f646c558dcf18b65c0483dafed2940df6..f942221f6e712a882a5c46a3a6031709c90fd116 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -30,7 +31,6 @@
 #include <asm/mach/map.h>
 
 #include <plat/led.h>
-#include <mach/gpio.h>
 #include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
index 9b0ea48d35fd873b2c981e78466de4195319281a..2b912d46ceec902ee0057aca73f9dbf3f6b958a2 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -32,7 +33,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
index 67acd4142639a56a88cbe6a9601b45a06652b099..7e2efe52cc3546d0126794042071b2784481e5f9 100644 (file)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -28,7 +28,6 @@
 #include <asm/mach/map.h>
 
 #include <plat/tc.h>
-#include <mach/gpio.h>
 #include <plat/mux.h>
 #include <plat/fpga.h>
 #include <plat/flash.h>
index e8ddd86e3fda698f2227a86f78774f0603d89dd9..b59f78850e691d5933d1821d22b8f7fd630613b0 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 
 #include <mach/hardware.h>
 #include <plat/mmc.h>
-#include <mach/gpio.h>
 #include <plat/board-sx1.h>
 
 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
index 9c3b7c52d9cf60b4ed0b1ec45b62eaba08f8c668..172a28f9a34480e21265fc993c5722adb722b571 100644 (file)
@@ -14,7 +14,7 @@
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/input.h>
@@ -32,7 +32,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/dma.h>
index 036edc0ee9b6e8d41f74f0eb16023f9caafeee8d..236b7ded0cf8db98571cd5abc9a0836346fa1d6a 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -33,7 +34,6 @@
 
 #include <plat/board-voiceblue.h>
 #include <plat/common.h>
-#include <mach/gpio.h>
 #include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/tc.h>
index 36f26c3fa25ee5dc83291012718e8f2f5ea53aae..7c50ecf68123b645a3d506f9f9110c6ebadb496d 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -24,7 +25,6 @@
 #include <plat/tc.h>
 #include <plat/board.h>
 #include <plat/mux.h>
-#include <mach/gpio.h>
 #include <plat/mmc.h>
 #include <plat/omap7xx.h>
 #include <plat/mcbsp.h>
index cddbf8b089cef4c08e2d9138e886b7cd0f086e06..0a17a1a7e00d106aa80f169e3db59191ab5dbd65 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
@@ -28,7 +29,6 @@
 #include <asm/mach/irq.h>
 
 #include <plat/fpga.h>
-#include <mach/gpio.h>
 
 static void fpga_mask_irq(struct irq_data *d)
 {
index e2b9c901ab67c4d07a274e34def39bb5ace47644..e5b104b7fce65e1ca7e6ad1db216950905024ddd 100644 (file)
@@ -35,7 +35,7 @@
  * with this program; if not, write  to the Free Software Foundation, Inc.,
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -45,7 +45,6 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
-#include <mach/gpio.h>
 #include <plat/cpu.h>
 
 #define IRQ_BANK(irq) ((irq) >> 5)
index b4f9be52e1e841cbf7d4e697299f779c964438ec..4b818eb9f911111bc18134a1617041c07ddf29bc 100644 (file)
@@ -9,6 +9,7 @@
  * The "surfer" expansion board and H2 sample board also have two-color
  * green+red LEDs (in parallel), used here for timer and idle indicators.
  */
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
@@ -20,7 +21,6 @@
 #include <asm/mach-types.h>
 
 #include <plat/fpga.h>
-#include <mach/gpio.h>
 
 #include "leds.h"
 
index 499d7ad8697d175847a21fbf133a6cb772526429..da09f4364979808421b2f482b68a32ea84ec898c 100644 (file)
@@ -3,14 +3,13 @@
  *
  * LED driver for OSK with optional Mistral QVGA board
  */
+#include <linux/gpio.h>
 #include <linux/init.h>
 
 #include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 
-#include <mach/gpio.h>
-
 #include "leds.h"
 
 
index 22eb11dde9e7ac5408c5d8353614e66c8f147dcd..ae6dd93b8ddce87e755e954695092555c4514083 100644 (file)
@@ -3,13 +3,13 @@
  *
  * OMAP LEDs dispatcher
  */
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 
-#include <mach/gpio.h>
 #include <plat/mux.h>
 
 #include "leds.h"
index 943072d5a1d555106f3e1432721cbb5bb958e1f8..7868e75ad0772a95eaec0885696c52a12d3bac5a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
index 550ca9d9991d5b1fe1994ddd3c8871c800ae918c..93ae8f29727e61a002bcf705a6d2492f4772023a 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -24,7 +24,6 @@
 
 #include <plat/board.h>
 #include <plat/mux.h>
-#include <mach/gpio.h>
 #include <plat/fpga.h>
 
 #include "pm.h"
index 565aff7f37a9a8145a12c9069f22d2eb066e907d..b03e562acc60738badb856fdbd199447a55d3407 100644 (file)
@@ -1,3 +1,3 @@
-  zreladdr-y           := 0x80008000
+  zreladdr-y           += 0x80008000
 params_phys-y          := 0x80000100
 initrd_phys-y          := 0x80800000
index 54db41a84a9bc71b07c44b874b0c58a1fad91a1a..bb4af05c7f0af4769431d2a9947b68d984bfbc0b 100644 (file)
@@ -15,7 +15,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
@@ -25,7 +25,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/usb.h>
 #include <plat/board.h>
 #include <plat/common.h>
index 45de2b319ec9b631d968c5c5fe8454f640121da8..95319e761802e1c63c901fd3631a7b08db24991f 100644 (file)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -31,7 +31,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/usb.h>
 #include <plat/board.h>
 #include <plat/common.h>
index 218764c9377ee4c8dfd1c6500af1c1f84f586a8f..ddff45c1688c132efb4bffa18dc4caf8dfca9d8b 100644 (file)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -34,7 +34,6 @@
 #include <asm/mach/map.h>
 
 #include <plat/mcspi.h>
-#include <mach/gpio.h>
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/gpmc.h>
index 3ae16b4e3f52b4068399978a7bea43536b2fa9c2..9cc9fa9315d4bfa7f5fe653e36983fc188cba509 100644 (file)
@@ -378,7 +378,8 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
 static int __init omap3_beagle_i2c_init(void)
 {
        omap3_pmic_get_config(&beagle_twldata,
-                       TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO,
+                       TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
+                       TWL_COMMON_PDATA_AUDIO,
                        TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);
 
        beagle_twldata.vpll2->constraints.name = "VDVI";
@@ -456,9 +457,15 @@ static void __init omap3_beagle_init_irq(void)
        omap3_init_irq();
 }
 
+static struct platform_device madc_hwmon = {
+       .name   = "twl4030_madc_hwmon",
+       .id     = -1,
+};
+
 static struct platform_device *omap3_beagle_devices[] __initdata = {
        &leds_gpio,
        &keys_gpio,
+       &madc_hwmon,
 };
 
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
index 1077ad663f936e5174f0f3c7a137bee3f57a2972..5391079c868981ad10adfbf22471aa021c1460f6 100644 (file)
@@ -8,7 +8,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -26,7 +26,6 @@
 #include <plat/tc.h>
 #include <plat/board.h>
 #include <plat/mcbsp.h>
-#include <mach/gpio.h>
 #include <plat/mmc.h>
 #include <plat/dma.h>
 #include <plat/omap_hwmod.h>
index 67039c3e0c48fa6b94f1147b3316f74afcecba9e..760a0efe7580b0dd194ff9bfe4295624336bb806 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index a3e3e9e5e328c7534ac2c1e753e52be7afaeb067..6d771cbf06a49028394ecd97b0a0b85b6ceef546 100644 (file)
@@ -9,7 +9,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -21,7 +21,6 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/i2c.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index a6eddae82a0b5b236db29658bbeb2c8b8a1d30ff..64e68fa85b0e9a880efb11c4e4d8db2bd49da17d 100644 (file)
@@ -13,7 +13,7 @@
  * License, or (at your option) any later version.
  *
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -30,7 +30,6 @@
 #include <linux/phy.h>
 #include <linux/marvell_phy.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 43cf8bc9767bbe8cb5fab72f06b11da74c804d8d..b1b45fff776e614f68ed1058e1313361e03b487b 100644 (file)
@@ -9,12 +9,11 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <asm/gpio.h>
 #include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include "common.h"
index 00381249d7665ef6fea66d57f53cc2127d09814b..f88f54bb7562c4918dfcca24a8040d2c35268657 100644 (file)
@@ -7,7 +7,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -21,7 +21,6 @@
 #include <linux/serial_reg.h>
 #include <linux/ata_platform.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 63ff10c3c46481cf4b24c6de55ba04598e2efd21..525eb1286859e979b08c5d9b80673acefed08715 100644 (file)
@@ -7,7 +7,7 @@
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -20,7 +20,6 @@
 #include <linux/i2c.h>
 #include <linux/ata_platform.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <mach/orion5x.h>
 #include "common.h"
index 291d22bf44c9bf8d4a91b0d00b2e5c0ecbe63828..50aae6f571b8356be6858081580ecc9b9e39ec79 100644 (file)
@@ -7,7 +7,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -18,7 +18,6 @@
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
index 3f02362e1632bdfca2b4679557f899e1def14464..35f106ac593ad74479a24bce0c475204ac220027 100644 (file)
@@ -7,7 +7,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -19,7 +19,6 @@
 #include <linux/i2c.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
index 27fd38e658bd882f620999f80bd702ec32feff30..9bb2b8bafbfd3316f9f65bc95d20aa642337ac36 100644 (file)
@@ -9,7 +9,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -20,7 +20,6 @@
 #include <linux/ata_platform.h>
 #include <linux/i2c.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
index ad2eba9286adf3a1af1b9fa157fb297d68d48735..1d00df9ad4642eb7ce9661621fd3b8f5abe38365 100644 (file)
@@ -7,7 +7,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -21,7 +21,6 @@
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
index a34e4fac72b00993ac60ab69b1f0822810157a52..c9dd31d34866c11aab4766e8e11169d5508d13dd 100644 (file)
@@ -8,7 +8,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -20,7 +20,6 @@
 #include <linux/i2c.h>
 #include <linux/serial_reg.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index c9831614e355c9dcc22090766bc8136972a8d71e..764307b8abfce454a013cc2ee21bdf1baea6ab5b 100644 (file)
@@ -8,7 +8,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -23,7 +23,6 @@
 #include <linux/serial_reg.h>
 #include <linux/ata_platform.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index cc33b2222bad74858444466a9c939113876ac461..0572dd1c8aaa4fb2ddb3714b9272172a0cfd3f32 100644 (file)
@@ -11,7 +11,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -25,7 +25,6 @@
 #include <linux/i2c.h>
 #include <linux/serial_reg.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 6b7b54116f3048f82a75d0c2dcbed66fc9b46ecc..8ae53015eeb882a540d5bae29199baac0b9dfa40 100644 (file)
@@ -275,7 +275,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = {
                .partitions             = ts78xx_ts_nand_parts,
                .nr_partitions          = ARRAY_SIZE(ts78xx_ts_nand_parts),
                .chip_delay             = 15,
-               .options                = NAND_USE_FLASH_BBT,
+               .bbt_options            = NAND_BBT_USE_FLASH,
        },
        .ctrl   = {
                /*
index 2653595f901c598e012f6e5ae77f97a03d201157..cdad50bd489106c94e49d9a862f82caef8929577 100644 (file)
@@ -5,7 +5,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -17,7 +17,6 @@
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 251ef1543e53d3f0c2e3742a76183bf839204954..8f10ffd77ec33ed7a52ca485c9154f61f5ca13c2 100644 (file)
@@ -5,7 +5,7 @@
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -20,7 +20,6 @@
 #include <linux/input.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/gpio.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 44c7117e20ddfbfd6a78a3e777a98cf5a92c3d0d..9fa19baa7f2ef169e26b8ebcbdf8f5706944f994 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y          := 0x80008000
+   zreladdr-y          += 0x80008000
 params_phys-y          := 0x80000100
 initrd_phys-y          := 0x80800000
 
index f219914f5b291efdb9fdbe9391a26ac6c7307932..eef531b755cac3a4cebd9b8d8ffecf7b09a52e4a 100644 (file)
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-
+#include <linux/gpio.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <mach/gpio.h>
 
 /* register definitions */
 #define PIO_VA_BASE    IO_ADDRESS(PNX4008_PIO_BASE)
index f40961e519146d88ea39f92ca352dd9799a97211..eb29face3bb325ce80c58b39786c7d5fae33c066 100644 (file)
@@ -9,7 +9,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/io.h>
@@ -19,7 +19,6 @@
 
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
-#include <mach/gpio.h>
 
 #include <mach/clock.h>
 
index d023db3ae4fff3d17c6c9688b235bd0885fd1dc6..c77a4883a4eeb104578c9fb61290ebeb698a5de2 100644 (file)
@@ -1,3 +1,3 @@
-zreladdr-y             := 0x00008000
+zreladdr-y             += 0x00008000
 params_phys-y          := 0x00000100
 initrd_phys-y          := 0x00800000
index 1ead67178eca360ed51a5abe952fca4c31d8bad6..2c1ae92f2106ca1ef662f35e411c7642f2b7b9fe 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0xa0008000
+   zreladdr-y  += 0xa0008000
 
index b6a51340270b9a433c0fbce5335793237c30ee18..eac3846ce42cb538c1259464d10133fd42f41d6f 100644 (file)
@@ -424,8 +424,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
 static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
        .enable_arbiter = 1,
        .keep_config    = 1,
-       .parts          = cm_x300_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(cm_x300_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = cm_x300_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(cm_x300_nand_partitions),
 };
 
 static void __init cm_x300_init_nand(void)
index 3f9be419959da6356025a2b23a385a9e40db6ec7..2b8ca0de8a3d7369b4c133ad6c29796f2ca85d7e 100644 (file)
@@ -139,8 +139,9 @@ static struct mtd_partition colibri_nand_partitions[] = {
 static struct pxa3xx_nand_platform_data colibri_nand_info = {
        .enable_arbiter = 1,
        .keep_config    = 1,
-       .parts          = colibri_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(colibri_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = colibri_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(colibri_nand_partitions),
 };
 
 void __init colibri_pxa3xx_init_nand(void)
index f5d91efc2965a81053ad87573b4fe49a8c423bb9..5432ecb15defb2c0acd61068636aa78b24ccc949 100644 (file)
@@ -16,6 +16,7 @@
  * initialization stuff for PXA machines which can be overridden later if
  * need be.
  */
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -26,7 +27,6 @@
 #include <asm/mach-types.h>
 
 #include <mach/reset.h>
-#include <mach/gpio.h>
 #include <mach/smemc.h>
 #include <mach/pxa3xx-regs.h>
 
index 2a5726c15e0e446f855f857d4e773a6785ba8486..1c585a79a1c19d114bebe6fd097f66e66c903dc5 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __ASM_ARCH_LITTLETON_H
 #define __ASM_ARCH_LITTLETON_H
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #define LITTLETON_ETH_PHYS     0x30000000
 
index b09e848eb6c6f0ae27356dc3feedb8ab790c4835..dafb4bf6349e97badb7e211cdf8ca802c458480f 100644 (file)
@@ -11,7 +11,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -21,7 +21,6 @@
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
index 8f97e15e86e56e1834b3e4ac72254ed87368a0ae..cd9fda3c9e65bfb67847840825c9979d2aeb30ce 100644 (file)
@@ -325,8 +325,9 @@ static struct mtd_partition littleton_nand_partitions[] = {
 
 static struct pxa3xx_nand_platform_data littleton_nand_info = {
        .enable_arbiter = 1,
-       .parts          = littleton_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(littleton_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = littleton_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(littleton_nand_partitions),
 };
 
 static void __init littleton_init_nand(void)
index c171d6ebee49805e1e529e6af8a4d664125cd68d..a3acd968b44dd4a520176fd67f0cb15226309eba 100644 (file)
@@ -12,7 +12,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/syscore_ops.h>
@@ -39,7 +39,6 @@
 #include <asm/mach/flash.h>
 
 #include <mach/pxa27x.h>
-#include <mach/gpio.h>
 #include <mach/lpd270.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
index a8c696bfc132929bb6256851b6790ec7e11a4afa..c48ce6da9184f6d338e15ef729f8f043d66b8e77 100644 (file)
@@ -11,6 +11,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -42,7 +43,6 @@
 #include <asm/hardware/sa1111.h>
 
 #include <mach/pxa25x.h>
-#include <mach/gpio.h>
 #include <mach/audio.h>
 #include <mach/lubbock.h>
 #include <mach/udc.h>
index 4622eb78ef25172be578f29671476c2840012e50..6bc784bb3696e29028ff65e160808c48323ca742 100644 (file)
@@ -12,7 +12,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/syscore_ops.h>
@@ -43,7 +43,6 @@
 #include <asm/mach/flash.h>
 
 #include <mach/pxa27x.h>
-#include <mach/gpio.h>
 #include <mach/mainstone.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
index b27544bcafcb5c68b384d850ea522da8f8712afe..b129527832cb52266c1a9fe2d84d347a0f678a8a 100644 (file)
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/syscore_ops.h>
 
-#include <mach/gpio.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/mfp-pxa2xx.h>
 
index b5a8fd3fce04cff4f5ad83f20c285f985eeb3c7e..90928d6e1a5bc05f3579c2901a2036eb34872aa3 100644 (file)
@@ -389,10 +389,11 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
-       .enable_arbiter = 1,
-       .keep_config = 1,
-       .parts = mxm_8x10_nand_partitions,
-       .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions)
+       .enable_arbiter = 1,
+       .keep_config    = 1,
+       .num_cs         = 1,
+       .parts[0]       = mxm_8x10_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(mxm_8x10_nand_partitions)
 };
 
 static void __init mxm_8x10_nand_init(void)
index 6d5b7e0621248d50dcb4dd90c0f876c6ec7471f5..9a9c539f6c015b51b2c6eb45a5c483786b12338e 100644 (file)
@@ -19,7 +19,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
@@ -28,7 +28,6 @@
 
 #include <media/soc_camera.h>
 
-#include <asm/gpio.h>
 #include <mach/camera.h>
 #include <asm/mach/map.h>
 #include <mach/pxa27x.h>
index 9c434d21a271a9d5e49cf1e0776ac84cd27c72c2..6bb3fa5d85eeab922e38e4915f4d6be74a85e8d7 100644 (file)
@@ -16,6 +16,7 @@
  * initialization stuff for PXA machines which can be overridden later if
  * need be.
  */
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -28,7 +29,6 @@
 #include <asm/suspend.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
 #include <mach/pxa25x.h>
 #include <mach/reset.h>
 #include <mach/pm.h>
index 9d2400b5f503f617ff29e849cc49f1a7f2a33dc6..d2cdcd6ead25862bcfa3c63eb70cbe0e28af75d4 100644 (file)
@@ -11,6 +11,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -26,7 +27,6 @@
 #include <asm/irq.h>
 #include <asm/suspend.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
 #include <mach/pxa27x.h>
 #include <mach/reset.h>
 #include <mach/ohci.h>
index b5cd9e5aba31bcf4eaee282879bd5891c93c26cd..3ab9e8471e60fb6118b68d0e94475c48afc7ad7a 100644 (file)
@@ -12,7 +12,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -26,7 +26,6 @@
 #include <asm/mach/map.h>
 #include <asm/suspend.h>
 #include <mach/hardware.h>
-#include <mach/gpio.h>
 #include <mach/pxa3xx-regs.h>
 #include <mach/reset.h>
 #include <mach/ohci.h>
index 0ee166b61f81399448d48c119f101829b1a85158..de25cebf78aae4223164e00a2a97a972c6957f3c 100644 (file)
@@ -9,7 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -21,7 +21,6 @@
 #include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
-#include <mach/gpio.h>
 #include <mach/pxa3xx-regs.h>
 #include <mach/pxa930.h>
 #include <mach/reset.h>
index bbcd90562ebec2c70e6b662621a3b7c2e4004103..6a2f353de39af8c4e33339d66451021889364b58 100644 (file)
@@ -346,8 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = {
 static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
        .enable_arbiter = 1,
        .keep_config    = 1,
-       .parts          = raumfeld_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(raumfeld_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = raumfeld_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(raumfeld_nand_partitions),
 };
 
 /**
index df4356e8acae38996b56a746f5aff2cb63c6551e..72001ec6e7b5ae7e452c6f044f86c6afb945d4f3 100644 (file)
@@ -540,7 +540,7 @@ static struct mtd_partition saar_onenand_partitions[] = {
        }, {
                .name           = "filesystem",
                .offset         = MTDPART_OFS_APPEND,
-               .size           = SZ_48M,
+               .size           = SZ_32M + SZ_16M,
                .mask_flags     = 0,
        }
 };
index ebd6379c49692f8f03f47bcf870d878fd5dc2e22..87e9b757ef34d180b97477de5dcd31b7d4a8b7b5 100644 (file)
@@ -9,7 +9,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  publishhed by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
@@ -23,7 +23,6 @@
 #include <mach/hardware.h>
 #include <mach/mfp.h>
 #include <mach/mfp-pxa930.h>
-#include <mach/gpio.h>
 
 #include "generic.h"
 
index 15ec66b3471a80644da24083ceb8da43f9002ea2..90fbf879c019ba387539855819f84910d4e3f35e 100644 (file)
@@ -366,8 +366,9 @@ static struct mtd_partition zylonite_nand_partitions[] = {
 
 static struct pxa3xx_nand_platform_data zylonite_nand_info = {
        .enable_arbiter = 1,
-       .parts          = zylonite_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(zylonite_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = zylonite_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(zylonite_nand_partitions),
 };
 
 static void __init zylonite_init_nand(void)
index d97e003d3df4c2237be7e2b02a706d4819655b27..d2c3d788f6880b3e765bb44574f4ceb8177bbb4c 100644 (file)
@@ -1,9 +1,9 @@
 ifeq ($(CONFIG_REALVIEW_HIGH_PHYS_OFFSET),y)
-   zreladdr-y  := 0x70008000
+   zreladdr-y  += 0x70008000
 params_phys-y  := 0x70000100
 initrd_phys-y  := 0x70800000
 else
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 endif
index 94ff27678a46ff9492f9e3e172e75e818049bdb2..40a8c178f10d9e85a2873c83247c3f2fe553f408 100644 (file)
@@ -1,6 +1 @@
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
+/* empty */
index a30f2e3ec17852a8f865b2ddb8320f6c9b3f4987..6657ff23116139184061b66c52064cb81565e737 100644 (file)
@@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd)
         */
        if (realview_reset)
                realview_reset(mode);
+       dsb();
 }
 
 #endif
index 9c9e7685ec7cff5e64c1e8639b67b1ab9227713f..ae2df0d7d0376a1dc64eaa19b8caef8775fd63a6 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x10008000
+   zreladdr-y  += 0x10008000
 params_phys-y  := 0x10000100
 initrd_phys-y  := 0x18000000
 
index dde6b3c0e299c55574ef50f910da7ed1e0c293a6..050d63c74cc10eabf776429875a301c70f17fe81 100644 (file)
@@ -36,7 +36,7 @@
 
 #define EASI_SIZE              0x08000000      /* EASI I/O */
 #define EASI_START             0x08000000
-#define EASI_BASE              0xe5000000
+#define EASI_BASE              IOMEM(0xe5000000)
 
 #define IO_START               0x03000000      /* I/O */
 #define IO_SIZE                        0x01000000
 /*
  * IO Addresses
  */
-#define VIDC_BASE              IOMEM(0xe0400000)
-#define EXPMASK_BASE           0xe0360000
-#define IOMD_BASE              IOMEM(0xe0200000)
-#define IOC_BASE               IOMEM(0xe0200000)
-#define PCIO_BASE              IOMEM(0xe0010000)
-#define FLOPPYDMA_BASE         IOMEM(0xe002a000)
+#define ECARD_EASI_BASE                (EASI_BASE)
+#define VIDC_BASE              (IO_BASE + 0x00400000)
+#define EXPMASK_BASE           (IO_BASE + 0x00360000)
+#define ECARD_IOC4_BASE                (IO_BASE + 0x00270000)
+#define ECARD_IOC_BASE         (IO_BASE + 0x00240000)
+#define IOMD_BASE              (IO_BASE + 0x00200000)
+#define IOC_BASE               (IO_BASE + 0x00200000)
+#define ECARD_MEMC8_BASE       (IO_BASE + 0x0002b000)
+#define FLOPPYDMA_BASE         (IO_BASE + 0x0002a000)
+#define PCIO_BASE              (IO_BASE + 0x00010000)
+#define ECARD_MEMC_BASE                (IO_BASE + 0x00000000)
 
 #define vidc_writel(val)       __raw_writel(val, VIDC_BASE)
 
-#define IO_EC_EASI_BASE                0x81400000
-#define IO_EC_IOC4_BASE                0x8009c000
-#define IO_EC_IOC_BASE         0x80090000
-#define IO_EC_MEMC8_BASE       0x8000ac00
-#define IO_EC_MEMC_BASE                0x80000000
-
 #define NETSLOT_BASE           0x0302b000
 #define NETSLOT_SIZE           0x00001000
 
index 20da7f486e5167627378d3a9442db8fff0a7d370..695f4ed2e11bab87d45ccd8ee2574a2ca8939dcd 100644 (file)
 
 #include <mach/hardware.h>
 
-#define IO_SPACE_LIMIT 0xffffffff
+#define IO_SPACE_LIMIT 0xffff
 
 /*
- * We use two different types of addressing - PC style addresses, and ARM
- * addresses.  PC style accesses the PC hardware with the normal PC IO
- * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
- * and are translated to the start of IO.  Note that all addresses are
- * shifted left!
- */
-#define __PORT_PCIO(x) (!((x) & 0x80000000))
-
-/*
- * Dynamic IO functions.
- */
-static inline void __outb (unsigned int value, unsigned int port)
-{
-       unsigned long temp;
-       __asm__ __volatile__(
-       "tst    %2, #0x80000000\n\t"
-       "mov    %0, %4\n\t"
-       "addeq  %0, %0, %3\n\t"
-       "strb   %1, [%0, %2, lsl #2]    @ outb"
-       : "=&r" (temp)
-       : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
-       : "cc");
-}
-
-static inline void __outw (unsigned int value, unsigned int port)
-{
-       unsigned long temp;
-       __asm__ __volatile__(
-       "tst    %2, #0x80000000\n\t"
-       "mov    %0, %4\n\t"
-       "addeq  %0, %0, %3\n\t"
-       "str    %1, [%0, %2, lsl #2]    @ outw"
-       : "=&r" (temp)
-       : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
-       : "cc");
-}
-
-static inline void __outl (unsigned int value, unsigned int port)
-{
-       unsigned long temp;
-       __asm__ __volatile__(
-       "tst    %2, #0x80000000\n\t"
-       "mov    %0, %4\n\t"
-       "addeq  %0, %0, %3\n\t"
-       "str    %1, [%0, %2, lsl #2]    @ outl"
-       : "=&r" (temp)
-       : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
-       : "cc");
-}
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr)                                      \
-static inline unsigned sz __in##fnsuffix (unsigned int port)           \
-{                                                                              \
-       unsigned long temp, value;                                              \
-       __asm__ __volatile__(                                                   \
-       "tst    %2, #0x80000000\n\t"                                            \
-       "mov    %0, %4\n\t"                                                     \
-       "addeq  %0, %0, %3\n\t"                                                 \
-       "ldr" instr "   %1, [%0, %2, lsl #2]    @ in" #fnsuffix                 \
-       : "=&r" (temp), "=r" (value)                                            \
-       : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)                \
-       : "cc");                                                                \
-       return (unsigned sz)value;                                              \
-}
-
-static inline void __iomem *__deprecated __ioaddr(unsigned int port)
-{
-       void __iomem *ret;
-       if (__PORT_PCIO(port))
-               ret = PCIO_BASE;
-       else
-               ret = IO_BASE;
-       return ret + (port << 2);
-}
-
-#define DECLARE_IO(sz,fnsuffix,instr)  \
-       DECLARE_DYN_IN(sz,fnsuffix,instr)
-
-DECLARE_IO(char,b,"b")
-DECLARE_IO(short,w,"")
-DECLARE_IO(int,l,"")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
+ * We need PC style IO addressing for:
+ *  - floppy (at 0x3f2,0x3f4,0x3f5,0x3f7)
+ *  - parport (at 0x278-0x27a, 0x27b-0x27f, 0x778-0x77a)
+ *  - 8250 serial (only for compile)
  *
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
+ * These peripherals are found in an area of MMIO which looks very much
+ * like an ISA bus, but with registers at the low byte of each word.
  */
-#define __outbc(value,port)                                                    \
-({                                                                             \
-       if (__PORT_PCIO((port)))                                                \
-               __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]    @ outbc"                                \
-               : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));          \
-       else                                                                    \
-               __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]    @ outbc"                                \
-               : : "r" (value), "r" (IO_BASE), "r" ((port) << 2));             \
-})
-
-#define __inbc(port)                                                           \
-({                                                                             \
-       unsigned char result;                                                   \
-       if (__PORT_PCIO((port)))                                                \
-               __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]    @ inbc"                                 \
-               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
-       else                                                                    \
-               __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]    @ inbc"                                 \
-               : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
-       result;                                                                 \
-})
-
-#define __outwc(value,port)                                                    \
-({                                                                             \
-       unsigned long __v = value;                                              \
-       if (__PORT_PCIO((port)))                                                \
-               __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]    @ outwc"                                \
-               : : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));    \
-       else                                                                    \
-               __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]    @ outwc"                                \
-               : : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2));               \
-})
-
-#define __inwc(port)                                                           \
-({                                                                             \
-       unsigned short result;                                                  \
-       if (__PORT_PCIO((port)))                                                \
-               __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]    @ inwc"                                 \
-               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
-       else                                                                    \
-               __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]    @ inwc"                                 \
-               : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
-       result & 0xffff;                                                        \
-})
-
-#define __outlc(value,port)                                                    \
-({                                                                             \
-       unsigned long __v = value;                                              \
-       if (__PORT_PCIO((port)))                                                \
-               __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]    @ outlc"                                \
-               : : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2));            \
-       else                                                                    \
-               __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]    @ outlc"                                \
-               : : "r" (__v), "r" (IO_BASE), "r" ((port) << 2));               \
-})
-
-#define __inlc(port)                                                           \
-({                                                                             \
-       unsigned long result;                                                   \
-       if (__PORT_PCIO((port)))                                                \
-               __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]    @ inlc"                                 \
-               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
-       else                                                                    \
-               __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]    @ inlc"                                 \
-               : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
-       result;                                                                 \
-})
-
-#define inb(p)         (__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
-#define inw(p)         (__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
-#define inl(p)         (__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
-#define outb(v,p)      (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
-#define outw(v,p)      (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
-#define outl(v,p)      (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
-
-/* the following macro is deprecated */
-#define ioaddr(port)   ((unsigned long)__ioaddr((port)))
-
-#define insb(p,d,l)    __raw_readsb(__ioaddr(p),d,l)
-#define insw(p,d,l)    __raw_readsw(__ioaddr(p),d,l)
-
-#define outsb(p,d,l)   __raw_writesb(__ioaddr(p),d,l)
-#define outsw(p,d,l)   __raw_writesw(__ioaddr(p),d,l)
+#define __io(a)                (PCIO_BASE + ((a) << 2))
 
 /*
  * 1:1 mapping for ioremapped regions.
index 580b3c73d2c71ffd1b5d1a257615e4fe61bfdf61..1e0e60d04622f930eb58451a772d1f9ca813a1a9 100644 (file)
@@ -74,7 +74,7 @@ static struct map_desc rpc_io_desc[] __initdata = {
                .length         =       IO_SIZE  ,
                .type           = MT_DEVICE
        }, {    /* EASI space   */
-               .virtual        = EASI_BASE,
+               .virtual        = (unsigned long)EASI_BASE,
                .pfn            = __phys_to_pfn(EASI_START),
                .length         = EASI_SIZE,
                .type           = MT_DEVICE
index 58c1dd7f8e1dbe47afc9a1bb9411780c0f72076a..4457605ba04a1dbbe0aeedbd90ba6499f0945f1c 100644 (file)
@@ -1,7 +1,7 @@
 ifeq ($(CONFIG_PM_H1940),y)
-       zreladdr-y              := 0x30108000
+       zreladdr-y      += 0x30108000
        params_phys-y   := 0x30100100
 else
-       zreladdr-y              := 0x30008000
+       zreladdr-y      += 0x30008000
        params_phys-y   := 0x30000100
 endif
index 0d8e043804c21ddbfe1bca85cde6bed0199ddb97..dbe43df8cfec718596ef4c48a04b02876499cbf1 100644 (file)
@@ -47,38 +47,26 @@ static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
                .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
                .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
                .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_SPI0] = {
                .name           = "spi0",
                .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
        },
        [DMACH_SPI1] = {
                .name           = "spi1",
                .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
        },
        [DMACH_UART0] = {
                .name           = "uart0",
                .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
        },
        [DMACH_UART1] = {
                .name           = "uart1",
                .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
        },
        [DMACH_UART2] = {
                .name           = "uart2",
                .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
        },
        [DMACH_TIMER] = {
                .name           = "timer",
@@ -90,12 +78,10 @@ static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
                .name           = "i2s-sdi",
                .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
                .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_I2S_OUT] = {
                .name           = "i2s-sdo",
                .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_USB_EP1] = {
                .name           = "usb-ep1",
index f7f6b07df30eaa956acb0c08da276f44c08f8888..6fac70f3484e5b7f1733eb889916e20c69bda9a9 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
 /* some boards require extra gpio capacity to support external
  * devices that need GPIO.
  */
@@ -28,7 +23,6 @@
 #define ARCH_NR_GPIOS  (256 + CONFIG_S3C24XX_GPIO_EXTRA)
 #endif
 
-#include <asm-generic/gpio.h>
 #include <mach/gpio-nrs.h>
 #include <mach/gpio-fns.h>
 
index 97e42bfce81e4e675ac9d6eb8b90735e54696226..fc897d3a056cfc1d1c52c3f89dc8ed09f378187a 100644 (file)
@@ -14,7 +14,7 @@
 #ifndef __ASM_ARCH_H1940_LATCH_H
 #define __ASM_ARCH_H1940_LATCH_H
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #define H1940_LATCH_GPIO(x)            (S3C_GPIO_END + (x))
 
index 9813dbf2ae4f9c2f74012256422c48fda7eaebe6..118749f37c4cddf2df549218a218bd5dd850ee16 100644 (file)
@@ -199,8 +199,6 @@ DECLARE_IO(int,l,"")
 #define outw(v,p)      (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
 #define outl(v,p)      (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 #define __ioaddr(p)    (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
-/* the following macro is deprecated */
-#define ioaddr(port)   __ioaddr((port))
 
 #define insb(p,d,l)    __raw_readsb(__ioaddr(p),d,l)
 #define insw(p,d,l)    __raw_readsw(__ioaddr(p),d,l)
index 7abecfca0b7ed45f51924c05322eba8b337be3b1..c61e3261615d28be2444bf8c16f0833f9aefbb83 100644 (file)
@@ -50,64 +50,46 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
                .name           = "sdi",
                .channels       = MAP(S3C2412_DMAREQSEL_SDI),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_SDI),
-               .hw_addr.to     = S3C2410_PA_SDI + S3C2410_SDIDATA,
-               .hw_addr.from   = S3C2410_PA_SDI + S3C2410_SDIDATA,
        },
        [DMACH_SPI0] = {
                .name           = "spi0",
                .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI0RX),
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
        },
        [DMACH_SPI1] = {
                .name           = "spi1",
                .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI1RX),
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2412_SPI1  + S3C2410_SPRDAT,
        },
        [DMACH_UART0] = {
                .name           = "uart0",
                .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_0),
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
        },
        [DMACH_UART1] = {
                .name           = "uart1",
                .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_0),
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
        },
        [DMACH_UART2] = {
                .name           = "uart2",
                .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_0),
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
        },
        [DMACH_UART0_SRC2] = {
                .name           = "uart0",
                .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_1),
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
        },
        [DMACH_UART1_SRC2] = {
                .name           = "uart1",
                .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_1),
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
        },
        [DMACH_UART2_SRC2] = {
                .name           = "uart2",
                .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
                .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_1),
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
        },
        [DMACH_TIMER] = {
                .name           = "timer",
index 3b0529f54e9cf6f269c2af4827f2f643d9f28c5d..0e73f8f9d1327cf3b840c20009824ef5265409a4 100644 (file)
@@ -48,38 +48,26 @@ static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
                .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
                .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
                .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_SPI0] = {
                .name           = "spi0",
                .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
        },
        [DMACH_SPI1] = {
                .name           = "spi1",
                .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
        },
        [DMACH_UART0] = {
                .name           = "uart0",
                .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
        },
        [DMACH_UART1] = {
                .name           = "uart1",
                .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
        },
        [DMACH_UART2] = {
                .name           = "uart2",
                .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
        },
        [DMACH_TIMER] = {
                .name           = "timer",
@@ -91,31 +79,26 @@ static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
                .name           = "i2s-sdi",
                .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
                .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_I2S_OUT] = {
                .name           = "i2s-sdo",
                .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
                .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_PCM_IN] = {
                .name           = "pcm-in",
                .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
                .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
-               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
        },
        [DMACH_PCM_OUT] = {
                .name           = "pcm-out",
                .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
                .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
-               .hw_addr.to     = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
        },
        [DMACH_MIC_IN] = {
                .name           = "mic-in",
                .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
                .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
-               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
        },
        [DMACH_USB_EP1] = {
                .name           = "usb-ep1",
index 3f658685ec1685bbedda6df54e5e649d8bcfc696..fe52151d2e847fe99103b5805b240b5897843ba9 100644 (file)
@@ -54,68 +54,46 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
        [DMACH_SDI] = {
                .name           = "sdi",
                .channels       = MAP(S3C2443_DMAREQSEL_SDI),
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_SPI0] = {
                .name           = "spi0",
                .channels       = MAP(S3C2443_DMAREQSEL_SPI0TX),
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
        },
        [DMACH_SPI1] = {
                .name           = "spi1",
                .channels       = MAP(S3C2443_DMAREQSEL_SPI1TX),
-               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
        },
        [DMACH_UART0] = {
                .name           = "uart0",
                .channels       = MAP(S3C2443_DMAREQSEL_UART0_0),
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
        },
        [DMACH_UART1] = {
                .name           = "uart1",
                .channels       = MAP(S3C2443_DMAREQSEL_UART1_0),
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
        },
        [DMACH_UART2] = {
                .name           = "uart2",
                .channels       = MAP(S3C2443_DMAREQSEL_UART2_0),
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
        },
        [DMACH_UART3] = {
                .name           = "uart3",
                .channels       = MAP(S3C2443_DMAREQSEL_UART3_0),
-               .hw_addr.to     = S3C2443_PA_UART3 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2443_PA_UART3 + S3C2410_URXH,
        },
        [DMACH_UART0_SRC2] = {
                .name           = "uart0",
                .channels       = MAP(S3C2443_DMAREQSEL_UART0_1),
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
        },
        [DMACH_UART1_SRC2] = {
                .name           = "uart1",
                .channels       = MAP(S3C2443_DMAREQSEL_UART1_1),
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
        },
        [DMACH_UART2_SRC2] = {
                .name           = "uart2",
                .channels       = MAP(S3C2443_DMAREQSEL_UART2_1),
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
        },
        [DMACH_UART3_SRC2] = {
                .name           = "uart3",
                .channels       = MAP(S3C2443_DMAREQSEL_UART3_1),
-               .hw_addr.to     = S3C2443_PA_UART3 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2443_PA_UART3 + S3C2410_URXH,
        },
        [DMACH_TIMER] = {
                .name           = "timer",
@@ -124,27 +102,22 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
        [DMACH_I2S_IN] = {
                .name           = "i2s-sdi",
                .channels       = MAP(S3C2443_DMAREQSEL_I2SRX),
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_I2S_OUT] = {
                .name           = "i2s-sdo",
                .channels       = MAP(S3C2443_DMAREQSEL_I2STX),
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
        },
        [DMACH_PCM_IN] = {
                .name           = "pcm-in",
                .channels       = MAP(S3C2443_DMAREQSEL_PCMIN),
-               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
        },
        [DMACH_PCM_OUT] = {
                .name           = "pcm-out",
                .channels       = MAP(S3C2443_DMAREQSEL_PCMOUT),
-               .hw_addr.to     = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
        },
        [DMACH_MIC_IN] = {
                .name           = "mic-in",
                .channels       = MAP(S3C2443_DMAREQSEL_MICIN),
-               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
        },
 };
 
index f057b6ae4f905d65f9f837cceebf3e0c573bfd74..5552e048c2be510608bd6fbd1f1418c9e5ab74a7 100644 (file)
@@ -288,5 +288,6 @@ config MACH_WLF_CRAGG_6410
        select S3C_DEV_RTC
        select S3C64XX_DEV_SPI
        select S3C24XX_GPIO_EXTRA128
+       select I2C
        help
          Machine support for the Wolfson Cragganmore S3C6410 variant.
index 61b4034a0c224d24ea95a135487be42ecae112dc..5fdea6aa50d46d041816fc13abb74ba423c47a69 100644 (file)
@@ -55,7 +55,7 @@ obj-$(CONFIG_MACH_HMT)                += mach-hmt.o
 obj-$(CONFIG_MACH_SMARTQ)      += mach-smartq.o
 obj-$(CONFIG_MACH_SMARTQ5)     += mach-smartq5.o
 obj-$(CONFIG_MACH_SMARTQ7)     += mach-smartq7.o
-obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o
+obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
 
 # device support
 
index ba41fdc0a586e428c90340cc9fffce6c6c827d69..c642333af3ed3358fd6f2e1f88e93589bd52edc4 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x50008000
+   zreladdr-y  += 0x50008000
 params_phys-y  := 0x50000100
diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h
new file mode 100644 (file)
index 0000000..be9074e
--- /dev/null
@@ -0,0 +1,23 @@
+/* Cragganmore 6410 shared definitions
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *     Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MACH_CRAG6410_H
+#define MACH_CRAG6410_H
+
+#include <linux/gpio.h>
+
+#define BANFF_PMIC_IRQ_BASE            IRQ_BOARD_START
+#define GLENFARCLAS_PMIC_IRQ_BASE      (IRQ_BOARD_START + 64)
+
+#define PCA935X_GPIO_BASE              GPIO_BOARD_START
+#define CODEC_GPIO_BASE                (GPIO_BOARD_START + 8)
+#define GLENFARCLAS_PMIC_GPIO_BASE     (GPIO_BOARD_START + 16)
+
+#endif
index 0d46e994048a5ed1cb4bd4fba7be64ee864cbd38..6e34c2f6e670394ac6437662af481af2bfaa7e79 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
 /* GPIO bank sizes */
 #define S3C64XX_GPIO_A_NR      (8)
 #define S3C64XX_GPIO_B_NR      (7)
@@ -96,5 +91,3 @@ enum s3c_gpio_number {
 #define BOARD_NR_GPIOS 16
 
 #define ARCH_NR_GPIOS  (GPIO_BOARD_START + BOARD_NR_GPIOS)
-
-#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
new file mode 100644 (file)
index 0000000..0708fa0
--- /dev/null
@@ -0,0 +1,173 @@
+/* Speyside modules for Cragganmore - board data probing
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *     Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/gpio.h>
+
+#include <sound/wm8996.h>
+#include <sound/wm8962.h>
+#include <sound/wm9081.h>
+
+#include <mach/crag6410.h>
+
+static struct wm8996_retune_mobile_config wm8996_retune[] = {
+       {
+               .name = "Sub LPF",
+               .rate = 48000,
+               .regs = {
+                       0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+               },
+       },
+       {
+               .name = "Sub HPF",
+               .rate = 48000,
+               .regs = {
+                       0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+               },
+       },
+};
+
+static struct wm8996_pdata wm8996_pdata __initdata = {
+       .ldo_ena = S3C64XX_GPN(7),
+       .gpio_base = CODEC_GPIO_BASE,
+       .micdet_def = 1,
+       .inl_mode = WM8996_DIFFERRENTIAL_1,
+       .inr_mode = WM8996_DIFFERRENTIAL_1,
+
+       .irq_flags = IRQF_TRIGGER_RISING,
+
+       .gpio_default = {
+               0x8001, /* GPIO1 == ADCLRCLK1 */
+               0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
+               0x0141, /* GPIO3 == HP_SEL */
+               0x0002, /* GPIO4 == IRQ */
+               0x020e, /* GPIO5 == CLKOUT */
+       },
+
+       .retune_mobile_cfgs = wm8996_retune,
+       .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
+};
+
+static struct wm8962_pdata wm8962_pdata __initdata = {
+       .gpio_init = {
+               0,
+               WM8962_GPIO_FN_OPCLK,
+               WM8962_GPIO_FN_DMICCLK,
+               0,
+               0x8000 | WM8962_GPIO_FN_DMICDAT,
+               WM8962_GPIO_FN_IRQ,    /* Open drain mode */
+       },
+       .irq_active_low = true,
+};
+
+static struct wm9081_pdata wm9081_pdata __initdata = {
+       .irq_high = false,
+       .irq_cmos = false,
+};
+
+static const struct i2c_board_info wm1254_devs[] = {
+       { I2C_BOARD_INFO("wm8996", 0x1a),
+         .platform_data = &wm8996_pdata,
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+       },
+       { I2C_BOARD_INFO("wm9081", 0x6c),
+         .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1259_devs[] = {
+       { I2C_BOARD_INFO("wm8962", 0x1a),
+         .platform_data = &wm8962_pdata,
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+       },
+};
+
+
+static __devinitdata const struct {
+       u8 id;
+       const char *name;
+       const struct i2c_board_info *i2c_devs;
+       int num_i2c_devs;
+} gf_mods[] = {
+       { .id = 0x01, .name = "1250-EV1 Springbank" },
+       { .id = 0x02, .name = "1251-EV1 Jura" },
+       { .id = 0x03, .name = "1252-EV1 Glenlivet" },
+       { .id = 0x11, .name = "6249-EV2 Glenfarclas", },
+       { .id = 0x21, .name = "1275-EV1 Mortlach" },
+       { .id = 0x25, .name = "1274-EV1 Glencadam" },
+       { .id = 0x31, .name = "1253-EV1 Tomatin", },
+       { .id = 0x39, .name = "1254-EV1 Dallas Dhu",
+         .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
+       { .id = 0x3a, .name = "1259-EV1 Tobermory",
+         .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
+       { .id = 0x3b, .name = "1255-EV1 Kilchoman" },
+       { .id = 0x3c, .name = "1273-EV1 Longmorn" },
+};
+
+static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
+                                        const struct i2c_device_id *i2c_id)
+{
+       int ret, i, j, id, rev;
+
+       ret = i2c_smbus_read_byte_data(i2c, 0);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
+               return ret;
+       }
+
+       id = (ret & 0xfe) >> 2;
+       rev = ret & 0x3;
+       for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
+               if (id == gf_mods[i].id)
+                       break;
+
+       if (i < ARRAY_SIZE(gf_mods)) {
+               dev_info(&i2c->dev, "%s revision %d\n",
+                        gf_mods[i].name, rev + 1);
+               for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
+                       if (!i2c_new_device(i2c->adapter,
+                                           &(gf_mods[i].i2c_devs[j])))
+                               dev_err(&i2c->dev,
+                                       "Failed to register dev: %d\n", ret);
+               }
+       } else {
+               dev_warn(&i2c->dev, "Unknown module ID %d revision %d\n",
+                        id, rev);
+       }
+
+       return 0;
+}
+
+static const struct i2c_device_id wlf_gf_module_id[] = {
+       { "wlf-gf-module", 0 },
+       { }
+};
+
+static struct i2c_driver wlf_gf_module_driver = {
+       .driver = {
+               .name = "wlf-gf-module",
+               .owner = THIS_MODULE,
+       },
+       .probe = wlf_gf_module_probe,
+       .id_table = wlf_gf_module_id,
+};
+
+static int __init wlf_gf_module_register(void)
+{
+       return i2c_add_driver(&wlf_gf_module_driver);
+}
+module_init(wlf_gf_module_register);
index af0c2fe1ea378da587c2dc920d8a113342252fec..f74a8118de74f27ac73949d83b002f3c67e7801e 100644 (file)
@@ -47,6 +47,7 @@
 #include <mach/regs-sys.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-modem.h>
+#include <mach/crag6410.h>
 
 #include <mach/regs-gpio-memport.h>
 
 #include <plat/iic.h>
 #include <plat/pm.h>
 
-#include <sound/wm8996.h>
-#include <sound/wm8962.h>
-#include <sound/wm9081.h>
-
-#define BANFF_PMIC_IRQ_BASE            IRQ_BOARD_START
-#define GLENFARCLAS_PMIC_IRQ_BASE      (IRQ_BOARD_START + 64)
-
-#define PCA935X_GPIO_BASE              GPIO_BOARD_START
-#define CODEC_GPIO_BASE                (GPIO_BOARD_START + 8)
-#define GLENFARCLAS_PMIC_GPIO_BASE     (GPIO_BOARD_START + 16)
-
 /* serial port setup */
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
@@ -329,9 +319,6 @@ static struct platform_device *crag6410_devices[] __initdata = {
        &s3c_device_fb,
        &s3c_device_ohci,
        &s3c_device_usb_hsotg,
-       &s3c_device_adc,
-       &s3c_device_rtc,
-       &s3c_device_ts,
        &s3c_device_timer[0],
        &s3c64xx_device_iis0,
        &s3c64xx_device_iis1,
@@ -353,6 +340,12 @@ static struct pca953x_platform_data crag6410_pca_data = {
        .irq_base       = 0,
 };
 
+/* VDDARM is controlled by DVS1 connected to GPK(0) */
+static struct wm831x_buckv_pdata vddarm_pdata = {
+       .dvs_control_src = 1,
+       .dvs_gpio = S3C64XX_GPK(0),
+};
+
 static struct regulator_consumer_supply vddarm_consumers[] __initdata = {
        REGULATOR_SUPPLY("vddarm", NULL),
 };
@@ -368,6 +361,7 @@ static struct regulator_init_data vddarm __initdata = {
        .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers),
        .consumer_supplies = vddarm_consumers,
        .supply_regulator = "WALLVDD",
+       .driver_data = &vddarm_pdata,
 };
 
 static struct regulator_init_data vddint __initdata = {
@@ -503,6 +497,8 @@ static struct wm831x_pdata crag_pmic_pdata __initdata = {
        .backup = &banff_backup_pdata,
 
        .gpio_defaults = {
+               /* GPIO5: DVS1_REQ - CMOS, DBVDD, active high */
+               [4] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA | 0x8,
                /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/
                [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6,
                /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/
@@ -614,81 +610,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = {
        .disable_touch = true,
 };
 
-static struct wm8996_retune_mobile_config wm8996_retune[] = {
-       {
-               .name = "Sub LPF",
-               .rate = 48000,
-               .regs = {
-                       0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
-                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
-                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
-               },
-       },
-       {
-               .name = "Sub HPF",
-               .rate = 48000,
-               .regs = {
-                       0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
-                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
-                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
-               },
-       },
-};
-
-static struct wm8996_pdata wm8996_pdata __initdata = {
-       .ldo_ena = S3C64XX_GPN(7),
-       .gpio_base = CODEC_GPIO_BASE,
-       .micdet_def = 1,
-       .inl_mode = WM8996_DIFFERRENTIAL_1,
-       .inr_mode = WM8996_DIFFERRENTIAL_1,
-
-       .irq_flags = IRQF_TRIGGER_RISING,
-
-       .gpio_default = {
-               0x8001, /* GPIO1 == ADCLRCLK1 */
-               0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
-               0x0141, /* GPIO3 == HP_SEL */
-               0x0002, /* GPIO4 == IRQ */
-               0x020e, /* GPIO5 == CLKOUT */
-       },
-
-       .retune_mobile_cfgs = wm8996_retune,
-       .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
-};
-
-static struct wm8962_pdata wm8962_pdata __initdata = {
-       .gpio_init = {
-               0,
-               WM8962_GPIO_FN_OPCLK,
-               WM8962_GPIO_FN_DMICCLK,
-               0,
-               0x8000 | WM8962_GPIO_FN_DMICDAT,
-               WM8962_GPIO_FN_IRQ,    /* Open drain mode */
-       },
-       .irq_active_low = true,
-};
-
-static struct wm9081_pdata wm9081_pdata __initdata = {
-       .irq_high = false,
-       .irq_cmos = false,
-};
-
 static struct i2c_board_info i2c_devs1[] __initdata = {
        { I2C_BOARD_INFO("wm8311", 0x34),
          .irq = S3C_EINT(0),
          .platform_data = &glenfarclas_pmic_pdata },
 
+       { I2C_BOARD_INFO("wlf-gf-module", 0x24) },
+       { I2C_BOARD_INFO("wlf-gf-module", 0x25) },
+       { I2C_BOARD_INFO("wlf-gf-module", 0x26) },
+
        { I2C_BOARD_INFO("wm1250-ev1", 0x27) },
-       { I2C_BOARD_INFO("wm8996", 0x1a),
-         .platform_data = &wm8996_pdata,
-         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
-       },
-       { I2C_BOARD_INFO("wm9081", 0x6c),
-         .platform_data = &wm9081_pdata, },
-       { I2C_BOARD_INFO("wm8962", 0x1a),
-         .platform_data = &wm8962_pdata,
-         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
-       },
 };
 
 static void __init crag6410_map_io(void)
index 527f49bd1b57aadab2fc54ce869b2a27aca45449..8f34a3c104975e5cf0f7bbe96e106ed1f9b3c1a0 100644 (file)
@@ -205,12 +205,6 @@ static struct platform_device mini6410_lcd_powerdev = {
        .dev.platform_data      = &mini6410_lcd_power_data,
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 static struct platform_device *mini6410_devices[] __initdata = {
        &mini6410_device_eth,
        &s3c_device_hsmmc0,
@@ -319,7 +313,7 @@ static void __init mini6410_machine_init(void)
 
        s3c_nand_set_platdata(&mini6410_nand_info);
        s3c_fb_set_platdata(&mini6410_lcd_pdata);
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        /* configure nCS1 width to 16 bits */
 
index 95b04b1729e3634ecf02c16ffa79240fe46e9ead..1f5abfae4eac8519f09e1ae607f9c7f593fc91cb 100644 (file)
@@ -198,12 +198,6 @@ static struct platform_device *real6410_devices[] __initdata = {
        &s3c_device_ohci,
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 static void __init real6410_map_io(void)
 {
        u32 tmp;
@@ -300,7 +294,7 @@ static void __init real6410_machine_init(void)
 
        s3c_fb_set_platdata(&real6410_lcd_pdata);
        s3c_nand_set_platdata(&real6410_nand_info);
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        /* configure nCS1 width to 16 bits */
 
index ecbea92bf83b60d76d313ed68bb49eca091e262e..d831c97833ba4a058ea06b4a5a6e92ab064916eb 100644 (file)
@@ -262,45 +262,6 @@ static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
        .cols           = 8,
 };
 
-static int smdk6410_backlight_init(struct device *dev)
-{
-       int ret;
-
-       ret = gpio_request(S3C64XX_GPF(15), "Backlight");
-       if (ret) {
-               printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
-               return ret;
-       }
-
-       /* Configure GPIO pin with S3C64XX_GPF15_PWM_TOUT1 */
-       s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
-
-       return 0;
-}
-
-static void smdk6410_backlight_exit(struct device *dev)
-{
-       s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_OUTPUT);
-       gpio_free(S3C64XX_GPF(15));
-}
-
-static struct platform_pwm_backlight_data smdk6410_backlight_data = {
-       .pwm_id         = 1,
-       .max_brightness = 255,
-       .dft_brightness = 255,
-       .pwm_period_ns  = 78770,
-       .init           = smdk6410_backlight_init,
-       .exit           = smdk6410_backlight_exit,
-};
-
-static struct platform_device smdk6410_backlight_device = {
-       .name           = "pwm-backlight",
-       .dev            = {
-               .parent         = &s3c_device_timer[1].dev,
-               .platform_data  = &smdk6410_backlight_data,
-       },
-};
-
 static struct map_desc smdk6410_iodesc[] = {};
 
 static struct platform_device *smdk6410_devices[] __initdata = {
@@ -658,12 +619,6 @@ static struct i2c_board_info i2c_devs1[] __initdata = {
        { I2C_BOARD_INFO("24c128", 0x57), },    /* Samsung S524AD0XD1 */
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 /* LCD Backlight data */
 static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
        .no = S3C64XX_GPF(15),
@@ -705,7 +660,7 @@ static void __init smdk6410_machine_init(void)
 
        samsung_keypad_set_platdata(&smdk6410_keypad_data);
 
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        /* configure nCS1 width to 16 bits */
 
index 8bad64370689b4163501631e3b7fc85f7e184510..055e2858b0dd9a31c027ecd8d7032d6ecefbddc7 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/suspend.h>
 #include <linux/serial_core.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
index ff90aa13bd674b6befc96089b4c2097c101d1de4..79ece4055b0206299c562c54583ad61dacdf7dae 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x20008000
+   zreladdr-y  += 0x20008000
 params_phys-y  := 0x20000100
index adb5f298ead895a65db824705c7c8a7f38459ea6..06cd3c9b16ac14708831cffaf516f8d430b0a80b 100644 (file)
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H __FILE__
 
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
 /* GPIO bank sizes */
 
 #define S5P6440_GPIO_A_NR      (6)
@@ -134,6 +129,4 @@ enum s5p6450_gpio_number {
 
 #define ARCH_NR_GPIOS          (S5P64X0_GPIO_END + CONFIG_SAMSUNG_GPIO_EXTRA)
 
-#include <asm-generic/gpio.h>
-
 #endif /* __ASM_ARCH_GPIO_H */
index 69ed4545112b121aeafa1fa9d9d7a36617f6d9e1..fe7380f5c3cd858613753230a9ef0f0e973e76bf 100644 (file)
@@ -129,7 +129,7 @@ static int s5p64x0_alloc_gc(void)
        }
 
        ct = gc->chip_types;
-       ct->chip.irq_ack = irq_gc_ack;
+       ct->chip.irq_ack = irq_gc_ack_set_bit;
        ct->chip.irq_mask = irq_gc_mask_set_bit;
        ct->chip.irq_unmask = irq_gc_mask_clr_bit;
        ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
index 346f8dfa6f3539d500fbcdbb88c70e4847d0c5e1..340f30f4a3da1ab54120c235792be436e089112c 100644 (file)
@@ -129,12 +129,6 @@ static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = {
        /* To be populated */
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 /* LCD Backlight data */
 static struct samsung_bl_gpio_info smdk6440_bl_gpio_info = {
        .no = S5P6440_GPF(15),
@@ -155,7 +149,7 @@ static void __init smdk6440_map_io(void)
 
 static void __init smdk6440_machine_init(void)
 {
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        s3c_i2c0_set_platdata(&s5p6440_i2c0_data);
        s3c_i2c1_set_platdata(&s5p6440_i2c1_data);
index 33f2adf8f3fe01f592fd4a9ccdeba0b1f31dbe4f..ee0da14665b6d8d2c1481211402734b6e0a66e01 100644 (file)
@@ -148,12 +148,6 @@ static struct i2c_board_info smdk6450_i2c_devs1[] __initdata = {
        { I2C_BOARD_INFO("24c128", 0x57), },/* Samsung S524AD0XD1 EEPROM */
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 /* LCD Backlight data */
 static struct samsung_bl_gpio_info smdk6450_bl_gpio_info = {
        .no = S5P6450_GPF(15),
@@ -174,7 +168,7 @@ static void __init smdk6450_map_io(void)
 
 static void __init smdk6450_machine_init(void)
 {
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        s3c_i2c0_set_platdata(&s5p6450_i2c0_data);
        s3c_i2c1_set_platdata(&s5p6450_i2c1_data);
index ff90aa13bd674b6befc96089b4c2097c101d1de4..79ece4055b0206299c562c54583ad61dacdf7dae 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x20008000
+   zreladdr-y  += 0x20008000
 params_phys-y  := 0x20000100
index 29a8a12d9b4f9046a4cce984917329b74683bf2b..5e1a924b595f4ca5db5c5901c2111f8ba0af3c3d 100644 (file)
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H __FILE__
 
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
 /* GPIO bank sizes */
 #define S5PC100_GPIO_A0_NR     (8)
 #define S5PC100_GPIO_A1_NR     (5)
@@ -146,6 +141,4 @@ enum s5p_gpio_number {
 /* define the number of gpios we need to the one after the MP04() range */
 #define ARCH_NR_GPIOS          (S5PC100_GPIO_END + 1)
 
-#include <asm-generic/gpio.h>
-
 #endif /* __ASM_ARCH_GPIO_H */
index 227d8908aab6368e344f5eb60cc6b513d4237d3c..0b70762ebf1a358d45671de4ca9c0f1f873d12ec 100644 (file)
@@ -203,12 +203,6 @@ static struct platform_device *smdkc100_devices[] __initdata = {
        &s5pc100_device_spdif,
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 /* LCD Backlight data */
 static struct samsung_bl_gpio_info smdkc100_bl_gpio_info = {
        .no = S5PC100_GPD(0),
@@ -228,7 +222,7 @@ static void __init smdkc100_map_io(void)
 
 static void __init smdkc100_machine_init(void)
 {
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        /* I2C */
        s3c_i2c0_set_platdata(NULL);
index 69dd87cd8e225fce669648c7a94cba81e2ccbe80..aaeb44a73716349f5fa3e18a165b229ced31f18f 100644 (file)
@@ -14,7 +14,6 @@ config CPU_S5PV210
        select S3C_PL330_DMA
        select S5P_EXT_INT
        select S5P_HRT
-       select S5PV210_PM if PM
        help
          Enable S5PV210 CPU support
 
@@ -169,9 +168,4 @@ config MACH_TORBRECK
 
 endmenu
 
-config S5PV210_PM
-       bool
-       help
-         Power Management code common to S5PV210
-
 endif
index 599a3c0e8f6cd9c525cf556f513c94b8d4ffc584..ef7e4668d6706169219b2822fcf8e3ce04fad62d 100644 (file)
@@ -14,7 +14,7 @@ obj-                          :=
 
 obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o dma.o
 obj-$(CONFIG_CPU_S5PV210)      += setup-i2c0.o
-obj-$(CONFIG_S5PV210_PM)       += pm.o sleep.o
+obj-$(CONFIG_PM)               += pm.o sleep.o
 
 # machine support
 
index ff90aa13bd674b6befc96089b4c2097c101d1de4..79ece4055b0206299c562c54583ad61dacdf7dae 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x20008000
+   zreladdr-y  += 0x20008000
 params_phys-y  := 0x20000100
index a5a1e331f8ed2214f27ada9fa702cbab55c50813..6c8b903c02e422f7017a2573c270f413469f2b6f 100644 (file)
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H __FILE__
 
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
 /* Practically, GPIO banks up to MP03 are the configurable gpio banks */
 
 /* GPIO bank sizes */
@@ -142,6 +137,4 @@ enum s5p_gpio_number {
 #define ARCH_NR_GPIOS          (S5PV210_MP05(S5PV210_GPIO_MP05_NR) +   \
                                 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
 
-#include <asm-generic/gpio.h>
-
 #endif /* __ASM_ARCH_GPIO_H */
index 5e011fc6720d6373d2f48fdc8298dda046f84481..4b27bcaf676ae912592c105d34cfc70b3e0cbc3a 100644 (file)
@@ -265,12 +265,6 @@ static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {
        /* To Be Updated */
 };
 
-static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
 /* LCD Backlight data */
 static struct samsung_bl_gpio_info smdkv210_bl_gpio_info = {
        .no = S5PV210_GPD0(3),
@@ -296,7 +290,7 @@ static void __init smdkv210_machine_init(void)
        smdkv210_dm9000_init();
 
        samsung_keypad_set_platdata(&smdkv210_keypad_data);
-       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+       s3c24xx_ts_set_platdata(NULL);
 
        s3c_i2c0_set_platdata(NULL);
        s3c_i2c1_set_platdata(NULL);
index 309e388a8a83388d711b1956f71aa74874a2cab0..f149d278377b8f28f29a53f55ba303e450bd6a55 100644 (file)
@@ -88,7 +88,7 @@ static struct sleep_save s5pv210_core_save[] = {
        SAVE_ITEM(S3C2410_TCNTO(0)),
 };
 
-void s5pv210_cpu_suspend(unsigned long arg)
+static int s5pv210_cpu_suspend(unsigned long arg)
 {
        unsigned long tmp;
 
index 41252d22e6591d437e274d967126ed86dee0112a..73a5c643179209e3192ffe65dd4a5bcf6c1c21e7 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := clock.o generic.o gpio.o irq.o dma.o time.o #nmi-oopser.o
+obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
 obj-m :=
 obj-n :=
 obj-  :=
index a56ad0417cf280576ab32b9210a025880bb3ffd9..5a616f6e56120c850c9afa93af19513a4b80ef1c 100644 (file)
@@ -1,6 +1,7 @@
-   zreladdr-y  := 0xc0008000
 ifeq ($(CONFIG_ARCH_SA1100),y)
-   zreladdr-$(CONFIG_SA1111)           := 0xc0208000
+   zreladdr-$(CONFIG_SA1111)           += 0xc0208000
+else
+   zreladdr-y  += 0xc0008000
 endif
 params_phys-y  := 0xc0000100
 initrd_phys-y  := 0xc0800000
index e21f3470eeceeb0d40a89e856400c40fc3a9b104..5fa5ae1f39e1164f6745704ed23f7825f16c17b6 100644 (file)
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -24,7 +25,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 #include <asm/irq.h>
-#include <asm/gpio.h>
 
 #include "generic.h"
 
index 7befc104e9a97a2fef34fae884b32a8cb2d54d38..703631887c94ae0de4bb66ada4913ce7e05ea4a4 100644 (file)
@@ -28,6 +28,8 @@
 #include <asm/irq.h>
 #include <asm-generic/gpio.h>
 
+#define __ARM_GPIOLIB_COMPLEX
+
 static inline int gpio_get_value(unsigned gpio)
 {
        if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
@@ -51,7 +53,5 @@ static inline void gpio_set_value(unsigned gpio, int value)
 
 #define gpio_to_irq(gpio)      ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
                                        (IRQ_GPIO11 - 11 + gpio))
-#define irq_to_gpio(irq)       ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \
-                                       (irq - IRQ_GPIO11 + 11))
 
 #endif
index d8b43f3dcd2d92d6b6e72a59ed05f6d028b12622..dfc27ff083446397f4e6324bd76a419f20a31d37 100644 (file)
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffffffff
-
 /*
- * We don't actually have real ISA nor PCI buses, but there is so many 
- * drivers out there that might just work if we fake them...
+ * __io() is required to be an equivalent mapping to __mem_pci() for
+ * SOC_COMMON to work.
  */
 #define __io(a)                __typesafe_io(a)
 #define __mem_pci(a)   (a)
index 4320f8b927715cc142d0ebb41d312d83cfc34cef..e40e24e4ca3428c71a7c32fb7bdcf9ba203a3102 100644 (file)
@@ -1,2 +1,2 @@
-   zreladdr-y  := 0x08008000
+   zreladdr-y  += 0x08008000
 
index 1c08ee9de86a615fc3d48185d2e4f5f00132d61b..498efd99338d85b89e8d518a62f60b3299ee10c2 100644 (file)
@@ -1,7 +1,7 @@
 __ZRELADDR     := $(shell /bin/bash -c 'printf "0x%08x" \
                     $$[$(CONFIG_MEMORY_START) + 0x8000]')
 
-   zreladdr-y   := $(__ZRELADDR)
+   zreladdr-y   += $(__ZRELADDR)
 
 # Unsupported legacy stuff
 #
index ce5c2513c6ce93f62f37356d55f2835fbf3a6332..cdfdd624d21dd27719c156639588c06e95be1b9d 100644 (file)
@@ -341,6 +341,7 @@ static struct platform_device mipidsi0_device = {
 static struct sh_mobile_sdhi_info sdhi0_info = {
        .dma_slave_tx   = SHDMA_SLAVE_SDHI0_TX,
        .dma_slave_rx   = SHDMA_SLAVE_SDHI0_RX,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT,
        .tmio_caps      = MMC_CAP_SD_HIGHSPEED,
        .tmio_ocr_mask  = MMC_VDD_27_28 | MMC_VDD_28_29,
 };
@@ -382,7 +383,7 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
 }
 
 static struct sh_mobile_sdhi_info sh_sdhi1_info = {
-       .tmio_flags     = TMIO_MMC_WRPROTECT_DISABLE,
+       .tmio_flags     = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
        .tmio_caps      = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
        .tmio_ocr_mask  = MMC_VDD_32_33 | MMC_VDD_33_34,
        .set_pwr        = ag5evm_sdhi1_set_pwr,
index 9e0856b2f9e9fcc8adb4455267e0ec4964efa56d..4a21a50d59b0b2b9a0f8187bc59fe7410f643585 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/leds.h>
 #include <linux/input/sh_keysc.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/pm_clock.h>
 
 #include <media/sh_mobile_ceu.h>
 #include <media/sh_mobile_csi2.h>
index d41c01f83f152f75589cc228a186a6f98da59a5e..2bf2ab6872d1cff8d93991e4d04fb0bcc6eefe1b 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
-#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
 #include <linux/smsc911x.h>
 #include <linux/sh_intc.h>
 #include <linux/tca6416_keypad.h>
@@ -641,6 +641,8 @@ static struct usbhs_private usbhs0_private = {
                },
                .driver_param = {
                        .buswait_bwait  = 4,
+                       .d0_tx_id       = SHDMA_SLAVE_USB0_TX,
+                       .d1_rx_id       = SHDMA_SLAVE_USB0_RX,
                },
        },
 };
@@ -810,6 +812,8 @@ static struct usbhs_private usbhs1_private = {
                        .buswait_bwait  = 4,
                        .pipe_type      = usbhs1_pipe_cfg,
                        .pipe_size      = ARRAY_SIZE(usbhs1_pipe_cfg),
+                       .d0_tx_id       = SHDMA_SLAVE_USB1_TX,
+                       .d1_rx_id       = SHDMA_SLAVE_USB1_RX,
                },
        },
 };
index 6b1619a65dbac16bf4535f106ab3b2c03016ed9f..dc8c899aa5eb4aa0b70982bc64bae54498d30522 100644 (file)
@@ -511,8 +511,8 @@ enum { MSTP001,
        MSTP223,
        MSTP218, MSTP217, MSTP216,
        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
-       MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
-       MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
+       MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
+       MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, MSTP400,
        MSTP_NR };
 
 #define MSTP(_parent, _reg, _bit, _flags) \
@@ -545,7 +545,6 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
        [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
        [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
-       [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
        [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
        [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
        [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
@@ -559,6 +558,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
        [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
        [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+       [MSTP400] = MSTP(&r_clk, SMSTPCR4, 0, 0), /* CMT2 */
 };
 
 static struct clk_lookup lookups[] = {
@@ -636,7 +636,6 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
-       CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
        CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
        CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
@@ -654,6 +653,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
        CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+       CLKDEV_DEV_ID("sh_cmt.2", &mstp_clks[MSTP400]), /* CMT2 */
 
        CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
        CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
index 2b1bb9e43ddadc8b83505b021c5ca7ae4f4704c5..7bf0890e16ba43963171bf5dea4b3345c27e25d8 100644 (file)
 
 #ifdef CONFIG_GPIOLIB
 
-static inline int gpio_get_value(unsigned gpio)
-{
-       return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-       __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
-       return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
-       return __gpio_to_irq(gpio);
-}
-
 static inline int irq_to_gpio(unsigned int irq)
 {
        return -ENOSYS;
 }
 
+#else
+
+#define __ARM_GPIOLIB_COMPLEX
+
 #endif /* CONFIG_GPIOLIB */
 
 #endif /* __ASM_ARCH_GPIO_H */
index ce595cee86cd50e313984131ab5329578b98612d..713cd2111e853964d8453b3a89265b00dfcf17ea 100644 (file)
@@ -494,9 +494,12 @@ extern struct sh7372_pm_domain sh7372_a3sg;
 extern void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd);
 extern void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd,
                                        struct platform_device *pdev);
+extern void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
+                                   struct sh7372_pm_domain *sh7372_sd);
 #else
 #define sh7372_init_pm_domain(pd) do { } while(0)
 #define sh7372_add_device_to_domain(pd, pdev) do { } while(0)
+#define sh7372_pm_add_subdomain(pd, sd) do { } while(0)
 #endif /* CONFIG_PM */
 
 #endif /* __ASM_SH7372_H__ */
index 933fb411be0f2233b05c5f57009b0b4a0b99b670..5d35831e4fb1a8ba70a9b86a3e31b68b8d2d89b5 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/list.h>
 #include <linux/err.h>
 #include <linux/slab.h>
-#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <asm/system.h>
@@ -91,35 +91,6 @@ static int pd_power_up(struct generic_pm_domain *genpd)
        return ret;
 }
 
-static int pd_power_up_a3rv(struct generic_pm_domain *genpd)
-{
-       int ret = pd_power_up(genpd);
-
-       /* force A4LC on after A3RV has been requested on */
-       pm_genpd_poweron(&sh7372_a4lc.genpd);
-
-       return ret;
-}
-
-static int pd_power_down_a3rv(struct generic_pm_domain *genpd)
-{
-       int ret = pd_power_down(genpd);
-
-       /* try to power down A4LC after A3RV is requested off */
-       genpd_queue_power_off_work(&sh7372_a4lc.genpd);
-
-       return ret;
-}
-
-static int pd_power_down_a4lc(struct generic_pm_domain *genpd)
-{
-       /* only power down A4LC if A3RV is off */
-       if (!(__raw_readl(PSTR) & (1 << sh7372_a3rv.bit_shift)))
-               return pd_power_down(genpd);
-
-       return -EBUSY;
-}
-
 static bool pd_active_wakeup(struct device *dev)
 {
        return true;
@@ -133,17 +104,8 @@ void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
        genpd->stop_device = pm_clk_suspend;
        genpd->start_device = pm_clk_resume;
        genpd->active_wakeup = pd_active_wakeup;
-
-       if (sh7372_pd == &sh7372_a4lc) {
-               genpd->power_off = pd_power_down_a4lc;
-               genpd->power_on = pd_power_up;
-       } else if (sh7372_pd == &sh7372_a3rv) {
-               genpd->power_off = pd_power_down_a3rv;
-               genpd->power_on = pd_power_up_a3rv;
-       } else {
-               genpd->power_off = pd_power_down;
-               genpd->power_on = pd_power_up;
-       }
+       genpd->power_off = pd_power_down;
+       genpd->power_on = pd_power_up;
        genpd->power_on(&sh7372_pd->genpd);
 }
 
@@ -152,11 +114,15 @@ void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd,
 {
        struct device *dev = &pdev->dev;
 
-       if (!dev->power.subsys_data) {
-               pm_clk_init(dev);
-               pm_clk_add(dev, NULL);
-       }
        pm_genpd_add_device(&sh7372_pd->genpd, dev);
+       if (pm_clk_no_clocks(dev))
+               pm_clk_add(dev, NULL);
+}
+
+void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
+                            struct sh7372_pm_domain *sh7372_sd)
+{
+       pm_genpd_add_subdomain(&sh7372_pd->genpd, &sh7372_sd->genpd);
 }
 
 struct sh7372_pm_domain sh7372_a4lc = {
index 6ec454e1e063f15b7b4720b21619c845d8ba4f63..bd5c6a3b8c55792460316af56432a6a0f2a5775a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_clock.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/sh_clk.h>
index 79f0413d8725cb8af1bbc5e5ba9d91e7f29feca8..4dfa8dba0a6edcae3e11bd685b796dd9d01a0f14 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sh_dma.h>
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
+#include <linux/pm_domain.h>
 #include <mach/hardware.h>
 #include <mach/sh7372.h>
 #include <asm/mach-types.h>
@@ -169,35 +170,35 @@ static struct platform_device scif6_device = {
 };
 
 /* CMT */
-static struct sh_timer_config cmt10_platform_data = {
-       .name = "CMT10",
-       .channel_offset = 0x10,
-       .timer_bit = 0,
+static struct sh_timer_config cmt2_platform_data = {
+       .name = "CMT2",
+       .channel_offset = 0x40,
+       .timer_bit = 5,
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
 
-static struct resource cmt10_resources[] = {
+static struct resource cmt2_resources[] = {
        [0] = {
-               .name   = "CMT10",
-               .start  = 0xe6138010,
-               .end    = 0xe613801b,
+               .name   = "CMT2",
+               .start  = 0xe6130040,
+               .end    = 0xe613004b,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = evt2irq(0x0b00), /* CMT1_CMT10 */
+               .start  = evt2irq(0x0b80), /* CMT2 */
                .flags  = IORESOURCE_IRQ,
        },
 };
 
-static struct platform_device cmt10_device = {
+static struct platform_device cmt2_device = {
        .name           = "sh_cmt",
-       .id             = 10,
+       .id             = 2,
        .dev = {
-               .platform_data  = &cmt10_platform_data,
+               .platform_data  = &cmt2_platform_data,
        },
-       .resource       = cmt10_resources,
-       .num_resources  = ARRAY_SIZE(cmt10_resources),
+       .resource       = cmt2_resources,
+       .num_resources  = ARRAY_SIZE(cmt2_resources),
 };
 
 /* TMU */
@@ -818,7 +819,7 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
        &scif4_device,
        &scif5_device,
        &scif6_device,
-       &cmt10_device,
+       &cmt2_device,
        &tmu00_device,
        &tmu01_device,
 };
@@ -848,6 +849,8 @@ void __init sh7372_add_standard_devices(void)
        sh7372_init_pm_domain(&sh7372_a3ri);
        sh7372_init_pm_domain(&sh7372_a3sg);
 
+       sh7372_pm_add_subdomain(&sh7372_a4lc, &sh7372_a3rv);
+
        platform_add_devices(sh7372_early_devices,
                            ARRAY_SIZE(sh7372_early_devices));
 
index 7a1f3c0eadb82e44f27e71d9c3e7d4e8e77d72b6..4674a4c221dbcf58f9bc1b43a9fa97a0977d9489 100644 (file)
@@ -1,3 +1,3 @@
-zreladdr-y     := 0x00008000
+zreladdr-y     += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 7a1f3c0eadb82e44f27e71d9c3e7d4e8e77d72b6..4674a4c221dbcf58f9bc1b43a9fa97a0977d9489 100644 (file)
@@ -1,3 +1,3 @@
-zreladdr-y     := 0x00008000
+zreladdr-y     += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index f135c9deae1002789079dbe9c16c004c895af6f5..5e02d4156b045b3e1201b233002bae28e3862c6a 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y          := 0x20008000
+   zreladdr-y          += 0x20008000
 params_phys-y          := 0x20000100
 initrd_phys-y          := 0x20800000
index 428ad122be0394ca3b61b01c3d2159a1c83457bf..5e870d29eca13550289b7a8492726eb761efa034 100644 (file)
@@ -1,4 +1,4 @@
-zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC)   := 0x00008000
+zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC)   += 0x00008000
 params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC)        := 0x00000100
 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC)        := 0x00800000
 
index 47c596cdbf32e4012d003574388cd935099c54a0..bcb1916e68b99d1ffd9167065d4d82fcc662eb7f 100644 (file)
  * GNU General Public License for more details.
  *
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 
 #include <mach/pinmux.h>
-#include <mach/gpio.h>
 
 #include "gpio-names.h"
 #include "board-trimslice.h"
index 196f114dc241fa704f9972f478cc42afbc5331c9..e3538055f4095d638b9143386f4ad85406fd3f5b 100644 (file)
 
 #define TEGRA_NR_GPIOS         INT_GPIO_NR
 
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value         __gpio_get_value
-#define gpio_set_value         __gpio_set_value
-#define gpio_cansleep          __gpio_cansleep
-
 #define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
 #define TEGRA_IRQ_TO_GPIO(irq) ((irq) - INT_GPIO_BASE)
 
@@ -40,6 +34,7 @@ static inline int gpio_to_irq(unsigned int gpio)
                return INT_GPIO_BASE + gpio;
        return -EINVAL;
 }
+#define gpio_to_irq gpio_to_irq
 
 static inline int irq_to_gpio(unsigned int irq)
 {
index 6fbfc6ea2d35c1c83ae9d51c714a36b54be22dd3..69357affbd77f9eb2799ee4b16fadbf2b382ae28 100644 (file)
@@ -4,10 +4,10 @@
 #   INITRD_PHYS must be in RAM
 
 ifdef CONFIG_MACH_U300_SINGLE_RAM
-     zreladdr-y        := 0x28E08000
+     zreladdr-y        += 0x28E08000
   params_phys-y        := 0x28E00100
 else
-     zreladdr-y        := 0x48008000
+     zreladdr-y        += 0x48008000
   params_phys-y        := 0x48000100
 endif
 
diff --git a/arch/arm/mach-u300/include/mach/gpio-u300.h b/arch/arm/mach-u300/include/mach/gpio-u300.h
new file mode 100644 (file)
index 0000000..a611906
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2007-2011 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * GPIO block resgister definitions and inline macros for
+ * U300 GPIO COH 901 335 or COH 901 571/3
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_U300_GPIO_U300_H
+#define __MACH_U300_GPIO_U300_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+/* Switch type depending on platform/chip variant */
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+#define U300_COH901335
+#endif
+#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
+#define U300_COH901571_3
+#endif
+
+/* Get base address for regs here */
+#include "u300-regs.h"
+/* IRQ numbers */
+#include "irqs.h"
+
+/*
+ * This is the GPIO block definitions. GPIO (General Purpose I/O) can be
+ * used for anything, and often is. The event/enable etc figures are for
+ * the lowermost pin (pin 0 on each port), shift this left to match your
+ * pin if you're gonna use these values.
+ */
+#ifdef U300_COH901335
+#define U300_GPIO_PORTX_SPACING                                (0x1C)
+/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
+#define U300_GPIO_PXPDIR                               (0x00)
+#define U300_GPIO_PXPDOR                               (0x00)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_GPIO_PXPCR                                        (0x04)
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK             (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK                  (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT                 (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT                 (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL      (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN     (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE    (0x00000003UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_GPIO_PXIEV                                        (0x08)
+#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK             (0x000000FFUL)
+#define U300_GPIO_PXIEV_IRQ_EVENT                      (0x00000001UL)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_GPIO_PXIEN                                        (0x0C)
+#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK            (0x000000FFUL)
+#define U300_GPIO_PXIEN_IRQ_ENABLE                     (0x00000001UL)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_GPIO_PXIFR                                        (0x10)
+#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK             (0x000000FFUL)
+#define U300_GPIO_PXIFR_IRQ_FORCE                      (0x00000001UL)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_GPIO_PXICR                                        (0x14)
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK            (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK                        (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE                (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE         (0x00000001UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_GPIO_PXPER                                        (0x18)
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK       (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE                        (0x00000001UL)
+/* Control Register 32bit (R/W) */
+#define U300_GPIO_CR                                   (0x54)
+#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE                        (0x00000001UL)
+/* three ports of 8 bits each = GPIO pins 0..23 */
+#define U300_GPIO_NUM_PORTS 3
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX  (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
+#endif
+
+#ifdef U300_COH901571_3
+/*
+ * Control Register 32bit (R/W)
+ * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
+ * gives the number of GPIO pins.
+ * bit 8-2  (mask 0x000001FC) contains the core version ID.
+ */
+#define U300_GPIO_CR                                   (0x00)
+#define U300_GPIO_CR_SYNC_SEL_ENABLE                   (0x00000002UL)
+#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE                        (0x00000001UL)
+#define U300_GPIO_PORTX_SPACING                                (0x30)
+/* Port X Pin Data INPUT Register 32bit (R/W) */
+#define U300_GPIO_PXPDIR                               (0x04)
+/* Port X Pin Data OUTPUT Register 32bit (R/W) */
+#define U300_GPIO_PXPDOR                               (0x08)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_GPIO_PXPCR                                        (0x0C)
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK             (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK                  (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT                 (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT                 (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL      (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN     (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE    (0x00000003UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_GPIO_PXPER                                        (0x10)
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK       (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE                        (0x00000001UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_GPIO_PXIEV                                        (0x14)
+#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK             (0x000000FFUL)
+#define U300_GPIO_PXIEV_IRQ_EVENT                      (0x00000001UL)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_GPIO_PXIEN                                        (0x18)
+#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK            (0x000000FFUL)
+#define U300_GPIO_PXIEN_IRQ_ENABLE                     (0x00000001UL)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_GPIO_PXIFR                                        (0x1C)
+#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK             (0x000000FFUL)
+#define U300_GPIO_PXIFR_IRQ_FORCE                      (0x00000001UL)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_GPIO_PXICR                                        (0x20)
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK            (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK                        (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE                (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE         (0x00000001UL)
+#ifdef CONFIG_MACH_U300_BS335
+/* seven ports of 8 bits each = GPIO pins 0..55 */
+#define U300_GPIO_NUM_PORTS 7
+#else
+/* five ports of 8 bits each = GPIO pins 0..39 */
+#define U300_GPIO_NUM_PORTS 5
+#endif
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
+#endif
+
+/*
+ * Individual pin assignments for the B26/S26. Notice that the
+ * actual usage of these pins depends on the PAD MUX settings, that
+ * is why the same number can potentially appear several times.
+ * In the reference design each pin is only used for one purpose.
+ * These were determined by inspecting the B26/S26 schematic:
+ * 2/1911-ROA 128 1603
+ */
+#ifdef CONFIG_MACH_U300_BS2X
+#define U300_GPIO_PIN_UART_RX          0
+#define U300_GPIO_PIN_UART_TX          1
+#define U300_GPIO_PIN_GPIO02           2  /* Unrouted */
+#define U300_GPIO_PIN_GPIO03           3  /* Unrouted */
+#define U300_GPIO_PIN_CAM_SLEEP                4
+#define U300_GPIO_PIN_CAM_REG_EN       5
+#define U300_GPIO_PIN_GPIO06           6  /* Unrouted */
+#define U300_GPIO_PIN_GPIO07           7  /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO08           8  /* Service point SP2321 */
+#define U300_GPIO_PIN_GPIO09           9  /* Service point SP2322 */
+#define U300_GPIO_PIN_PHFSENSE         10 /* Headphone jack sensing */
+#define U300_GPIO_PIN_MMC_CLKRET       11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD           12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_FLIPSENSE                13 /* Mechanical flip sensing */
+#define U300_GPIO_PIN_GPIO14           14 /* DSP JTAG Port RTCK */
+#define U300_GPIO_PIN_GPIO15           15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16           16 /* Unrouted */
+#define U300_GPIO_PIN_GPIO17           17 /* Unrouted */
+#define U300_GPIO_PIN_GPIO18           18 /* Unrouted */
+#define U300_GPIO_PIN_GPIO19           19 /* Unrouted */
+#define U300_GPIO_PIN_GPIO20           20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21           21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22           22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23           23 /* Unrouted */
+#endif
+
+/*
+ * Individual pin assignments for the B330/S330 and B365/S365.
+ * Notice that the actual usage of these pins depends on the
+ * PAD MUX settings, that is why the same number can potentially
+ * appear several times. In the reference design each pin is only
+ * used for one purpose. These were determined by inspecting the
+ * S365 schematic.
+ */
+#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
+    defined(CONFIG_MACH_U300_BS335)
+#define U300_GPIO_PIN_UART_RX          0
+#define U300_GPIO_PIN_UART_TX          1
+#define U300_GPIO_PIN_UART_CTS         2
+#define U300_GPIO_PIN_UART_RTS         3
+#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
+#define U300_GPIO_PIN_GPIO05           5 /* Unrouted */
+#define U300_GPIO_PIN_MS_CD            6 /* Memory Stick Card insertion */
+#define U300_GPIO_PIN_GPIO07           7 /* Test point TP2430 */
+
+#define U300_GPIO_PIN_GPIO08           8 /* Test point TP2437 */
+#define U300_GPIO_PIN_GPIO09           9 /* Test point TP2431 */
+#define U300_GPIO_PIN_GPIO10           10 /* Test point TP2432 */
+#define U300_GPIO_PIN_MMC_CLKRET       11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD           12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_CAM_SUB_STANDBY  13 /* Camera SUB standby */
+#define U300_GPIO_PIN_GPIO14           14 /* Test point TP2436 */
+#define U300_GPIO_PIN_GPIO15           15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16           16 /* Test point TP2438 */
+#define U300_GPIO_PIN_PHFSENSE         17 /* Headphone jack sensing */
+#define U300_GPIO_PIN_GPIO18           18 /* Test point TP2439 */
+#define U300_GPIO_PIN_GPIO19           19 /* Routed somewhere */
+#define U300_GPIO_PIN_GPIO20           20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21           21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22           22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23           23 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO24           24 /* Unrouted */
+#define U300_GPIO_PIN_GPIO25           25 /* Unrouted */
+#define U300_GPIO_PIN_GPIO26           26 /* Unrouted */
+#define U300_GPIO_PIN_GPIO27           27 /* Unrouted */
+#define U300_GPIO_PIN_GPIO28           28 /* Unrouted */
+#define U300_GPIO_PIN_GPIO29           29 /* Unrouted */
+#define U300_GPIO_PIN_GPIO30           30 /* Unrouted */
+#define U300_GPIO_PIN_GPIO31           31 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO32           32 /* Unrouted */
+#define U300_GPIO_PIN_GPIO33           33 /* Unrouted */
+#define U300_GPIO_PIN_GPIO34           34 /* Unrouted */
+#define U300_GPIO_PIN_GPIO35           35 /* Unrouted */
+#define U300_GPIO_PIN_GPIO36           36 /* Unrouted */
+#define U300_GPIO_PIN_GPIO37           37 /* Unrouted */
+#define U300_GPIO_PIN_GPIO38           38 /* Unrouted */
+#define U300_GPIO_PIN_GPIO39           39 /* Unrouted */
+
+#ifdef CONFIG_MACH_U300_BS335
+
+#define U300_GPIO_PIN_GPIO40           40 /* Unrouted */
+#define U300_GPIO_PIN_GPIO41           41 /* Unrouted */
+#define U300_GPIO_PIN_GPIO42           42 /* Unrouted */
+#define U300_GPIO_PIN_GPIO43           43 /* Unrouted */
+#define U300_GPIO_PIN_GPIO44           44 /* Unrouted */
+#define U300_GPIO_PIN_GPIO45           45 /* Unrouted */
+#define U300_GPIO_PIN_GPIO46           46 /* Unrouted */
+#define U300_GPIO_PIN_GPIO47           47 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO48           48 /* Unrouted */
+#define U300_GPIO_PIN_GPIO49           49 /* Unrouted */
+#define U300_GPIO_PIN_GPIO50           50 /* Unrouted */
+#define U300_GPIO_PIN_GPIO51           51 /* Unrouted */
+#define U300_GPIO_PIN_GPIO52           52 /* Unrouted */
+#define U300_GPIO_PIN_GPIO53           53 /* Unrouted */
+#define U300_GPIO_PIN_GPIO54           54 /* Unrouted */
+#define U300_GPIO_PIN_GPIO55           55 /* Unrouted */
+#endif
+
+#endif
+
+#endif /* __MACH_U300_GPIO_U300_H */
index d5a71abcbaeaf5a8da0255e50e89f5982fd447d4..430a0544baff7db68f0bd6143debd90e9ed71938 100644 (file)
 #ifndef __MACH_U300_GPIO_H
 #define __MACH_U300_GPIO_H
 
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-/* Switch type depending on platform/chip variant */
-#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
-#define U300_COH901335
-#endif
-#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
-#define U300_COH901571_3
-#endif
-
-/* Get base address for regs here */
-#include "u300-regs.h"
-/* IRQ numbers */
-#include "irqs.h"
-
-/*
- * This is the GPIO block definitions. GPIO (General Purpose I/O) can be
- * used for anything, and often is. The event/enable etc figures are for
- * the lowermost pin (pin 0 on each port), shift this left to match your
- * pin if you're gonna use these values.
- */
-#ifdef U300_COH901335
-#define U300_GPIO_PORTX_SPACING                                (0x1C)
-/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
-#define U300_GPIO_PXPDIR                               (0x00)
-#define U300_GPIO_PXPDOR                               (0x00)
-/* Port X Pin Config Register 32bit (R/W) */
-#define U300_GPIO_PXPCR                                        (0x04)
-#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK             (0x0000FFFFUL)
-#define U300_GPIO_PXPCR_PIN_MODE_MASK                  (0x00000003UL)
-#define U300_GPIO_PXPCR_PIN_MODE_SHIFT                 (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_INPUT                 (0x00000000UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL      (0x00000001UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN     (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE    (0x00000003UL)
-/* Port X Interrupt Event Register 32bit (R/W) */
-#define U300_GPIO_PXIEV                                        (0x08)
-#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK             (0x000000FFUL)
-#define U300_GPIO_PXIEV_IRQ_EVENT                      (0x00000001UL)
-/* Port X Interrupt Enable Register 32bit (R/W) */
-#define U300_GPIO_PXIEN                                        (0x0C)
-#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK            (0x000000FFUL)
-#define U300_GPIO_PXIEN_IRQ_ENABLE                     (0x00000001UL)
-/* Port X Interrupt Force Register 32bit (R/W) */
-#define U300_GPIO_PXIFR                                        (0x10)
-#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK             (0x000000FFUL)
-#define U300_GPIO_PXIFR_IRQ_FORCE                      (0x00000001UL)
-/* Port X Interrupt Config Register 32bit (R/W) */
-#define U300_GPIO_PXICR                                        (0x14)
-#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK            (0x000000FFUL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_MASK                        (0x00000001UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE                (0x00000000UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE         (0x00000001UL)
-/* Port X Pull-up Enable Register 32bit (R/W) */
-#define U300_GPIO_PXPER                                        (0x18)
-#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK       (0x000000FFUL)
-#define U300_GPIO_PXPER_PULL_UP_DISABLE                        (0x00000001UL)
-/* Control Register 32bit (R/W) */
-#define U300_GPIO_CR                                   (0x54)
-#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE                        (0x00000001UL)
-/* three ports of 8 bits each = GPIO pins 0..23 */
-#define U300_GPIO_NUM_PORTS 3
-#define U300_GPIO_PINS_PER_PORT 8
-#define U300_GPIO_MAX  (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
-#endif
-
-#ifdef U300_COH901571_3
-/*
- * Control Register 32bit (R/W)
- * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
- * gives the number of GPIO pins.
- * bit 8-2  (mask 0x000001FC) contains the core version ID.
- */
-#define U300_GPIO_CR                                   (0x00)
-#define U300_GPIO_CR_SYNC_SEL_ENABLE                   (0x00000002UL)
-#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE                        (0x00000001UL)
-#define U300_GPIO_PORTX_SPACING                                (0x30)
-/* Port X Pin Data INPUT Register 32bit (R/W) */
-#define U300_GPIO_PXPDIR                               (0x04)
-/* Port X Pin Data OUTPUT Register 32bit (R/W) */
-#define U300_GPIO_PXPDOR                               (0x08)
-/* Port X Pin Config Register 32bit (R/W) */
-#define U300_GPIO_PXPCR                                        (0x0C)
-#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK             (0x0000FFFFUL)
-#define U300_GPIO_PXPCR_PIN_MODE_MASK                  (0x00000003UL)
-#define U300_GPIO_PXPCR_PIN_MODE_SHIFT                 (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_INPUT                 (0x00000000UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL      (0x00000001UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN     (0x00000002UL)
-#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE    (0x00000003UL)
-/* Port X Pull-up Enable Register 32bit (R/W) */
-#define U300_GPIO_PXPER                                        (0x10)
-#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK       (0x000000FFUL)
-#define U300_GPIO_PXPER_PULL_UP_DISABLE                        (0x00000001UL)
-/* Port X Interrupt Event Register 32bit (R/W) */
-#define U300_GPIO_PXIEV                                        (0x14)
-#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK             (0x000000FFUL)
-#define U300_GPIO_PXIEV_IRQ_EVENT                      (0x00000001UL)
-/* Port X Interrupt Enable Register 32bit (R/W) */
-#define U300_GPIO_PXIEN                                        (0x18)
-#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK            (0x000000FFUL)
-#define U300_GPIO_PXIEN_IRQ_ENABLE                     (0x00000001UL)
-/* Port X Interrupt Force Register 32bit (R/W) */
-#define U300_GPIO_PXIFR                                        (0x1C)
-#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK             (0x000000FFUL)
-#define U300_GPIO_PXIFR_IRQ_FORCE                      (0x00000001UL)
-/* Port X Interrupt Config Register 32bit (R/W) */
-#define U300_GPIO_PXICR                                        (0x20)
-#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK            (0x000000FFUL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_MASK                        (0x00000001UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE                (0x00000000UL)
-#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE         (0x00000001UL)
-#ifdef CONFIG_MACH_U300_BS335
-/* seven ports of 8 bits each = GPIO pins 0..55 */
-#define U300_GPIO_NUM_PORTS 7
-#else
-/* five ports of 8 bits each = GPIO pins 0..39 */
-#define U300_GPIO_NUM_PORTS 5
-#endif
-#define U300_GPIO_PINS_PER_PORT 8
-#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
-#endif
-
-/*
- * Individual pin assignments for the B26/S26. Notice that the
- * actual usage of these pins depends on the PAD MUX settings, that
- * is why the same number can potentially appear several times.
- * In the reference design each pin is only used for one purpose.
- * These were determined by inspecting the B26/S26 schematic:
- * 2/1911-ROA 128 1603
- */
-#ifdef CONFIG_MACH_U300_BS2X
-#define U300_GPIO_PIN_UART_RX          0
-#define U300_GPIO_PIN_UART_TX          1
-#define U300_GPIO_PIN_GPIO02           2  /* Unrouted */
-#define U300_GPIO_PIN_GPIO03           3  /* Unrouted */
-#define U300_GPIO_PIN_CAM_SLEEP                4
-#define U300_GPIO_PIN_CAM_REG_EN       5
-#define U300_GPIO_PIN_GPIO06           6  /* Unrouted */
-#define U300_GPIO_PIN_GPIO07           7  /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO08           8  /* Service point SP2321 */
-#define U300_GPIO_PIN_GPIO09           9  /* Service point SP2322 */
-#define U300_GPIO_PIN_PHFSENSE         10 /* Headphone jack sensing */
-#define U300_GPIO_PIN_MMC_CLKRET       11 /* Clock return from MMC/SD card */
-#define U300_GPIO_PIN_MMC_CD           12 /* MMC Card insertion detection */
-#define U300_GPIO_PIN_FLIPSENSE                13 /* Mechanical flip sensing */
-#define U300_GPIO_PIN_GPIO14           14 /* DSP JTAG Port RTCK */
-#define U300_GPIO_PIN_GPIO15           15 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO16           16 /* Unrouted */
-#define U300_GPIO_PIN_GPIO17           17 /* Unrouted */
-#define U300_GPIO_PIN_GPIO18           18 /* Unrouted */
-#define U300_GPIO_PIN_GPIO19           19 /* Unrouted */
-#define U300_GPIO_PIN_GPIO20           20 /* Unrouted */
-#define U300_GPIO_PIN_GPIO21           21 /* Unrouted */
-#define U300_GPIO_PIN_GPIO22           22 /* Unrouted */
-#define U300_GPIO_PIN_GPIO23           23 /* Unrouted */
-#endif
-
-/*
- * Individual pin assignments for the B330/S330 and B365/S365.
- * Notice that the actual usage of these pins depends on the
- * PAD MUX settings, that is why the same number can potentially
- * appear several times. In the reference design each pin is only
- * used for one purpose. These were determined by inspecting the
- * S365 schematic.
- */
-#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
-    defined(CONFIG_MACH_U300_BS335)
-#define U300_GPIO_PIN_UART_RX          0
-#define U300_GPIO_PIN_UART_TX          1
-#define U300_GPIO_PIN_UART_CTS         2
-#define U300_GPIO_PIN_UART_RTS         3
-#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
-#define U300_GPIO_PIN_GPIO05           5 /* Unrouted */
-#define U300_GPIO_PIN_MS_CD            6 /* Memory Stick Card insertion */
-#define U300_GPIO_PIN_GPIO07           7 /* Test point TP2430 */
-
-#define U300_GPIO_PIN_GPIO08           8 /* Test point TP2437 */
-#define U300_GPIO_PIN_GPIO09           9 /* Test point TP2431 */
-#define U300_GPIO_PIN_GPIO10           10 /* Test point TP2432 */
-#define U300_GPIO_PIN_MMC_CLKRET       11 /* Clock return from MMC/SD card */
-#define U300_GPIO_PIN_MMC_CD           12 /* MMC Card insertion detection */
-#define U300_GPIO_PIN_CAM_SUB_STANDBY  13 /* Camera SUB standby */
-#define U300_GPIO_PIN_GPIO14           14 /* Test point TP2436 */
-#define U300_GPIO_PIN_GPIO15           15 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO16           16 /* Test point TP2438 */
-#define U300_GPIO_PIN_PHFSENSE         17 /* Headphone jack sensing */
-#define U300_GPIO_PIN_GPIO18           18 /* Test point TP2439 */
-#define U300_GPIO_PIN_GPIO19           19 /* Routed somewhere */
-#define U300_GPIO_PIN_GPIO20           20 /* Unrouted */
-#define U300_GPIO_PIN_GPIO21           21 /* Unrouted */
-#define U300_GPIO_PIN_GPIO22           22 /* Unrouted */
-#define U300_GPIO_PIN_GPIO23           23 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO24           24 /* Unrouted */
-#define U300_GPIO_PIN_GPIO25           25 /* Unrouted */
-#define U300_GPIO_PIN_GPIO26           26 /* Unrouted */
-#define U300_GPIO_PIN_GPIO27           27 /* Unrouted */
-#define U300_GPIO_PIN_GPIO28           28 /* Unrouted */
-#define U300_GPIO_PIN_GPIO29           29 /* Unrouted */
-#define U300_GPIO_PIN_GPIO30           30 /* Unrouted */
-#define U300_GPIO_PIN_GPIO31           31 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO32           32 /* Unrouted */
-#define U300_GPIO_PIN_GPIO33           33 /* Unrouted */
-#define U300_GPIO_PIN_GPIO34           34 /* Unrouted */
-#define U300_GPIO_PIN_GPIO35           35 /* Unrouted */
-#define U300_GPIO_PIN_GPIO36           36 /* Unrouted */
-#define U300_GPIO_PIN_GPIO37           37 /* Unrouted */
-#define U300_GPIO_PIN_GPIO38           38 /* Unrouted */
-#define U300_GPIO_PIN_GPIO39           39 /* Unrouted */
-
-#ifdef CONFIG_MACH_U300_BS335
-
-#define U300_GPIO_PIN_GPIO40           40 /* Unrouted */
-#define U300_GPIO_PIN_GPIO41           41 /* Unrouted */
-#define U300_GPIO_PIN_GPIO42           42 /* Unrouted */
-#define U300_GPIO_PIN_GPIO43           43 /* Unrouted */
-#define U300_GPIO_PIN_GPIO44           44 /* Unrouted */
-#define U300_GPIO_PIN_GPIO45           45 /* Unrouted */
-#define U300_GPIO_PIN_GPIO46           46 /* Unrouted */
-#define U300_GPIO_PIN_GPIO47           47 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO48           48 /* Unrouted */
-#define U300_GPIO_PIN_GPIO49           49 /* Unrouted */
-#define U300_GPIO_PIN_GPIO50           50 /* Unrouted */
-#define U300_GPIO_PIN_GPIO51           51 /* Unrouted */
-#define U300_GPIO_PIN_GPIO52           52 /* Unrouted */
-#define U300_GPIO_PIN_GPIO53           53 /* Unrouted */
-#define U300_GPIO_PIN_GPIO54           54 /* Unrouted */
-#define U300_GPIO_PIN_GPIO55           55 /* Unrouted */
-#endif
-
-#endif
-
-/* translates a pin number to a port number */
-#define PIN_TO_PORT(val) (val >> 3)
+#define __ARM_GPIOLIB_COMPLEX
 
 /* These can be found in arch/arm/mach-u300/gpio.c */
 extern int gpio_is_valid(int number);
@@ -276,19 +34,14 @@ extern void gpio_set_value(unsigned gpio, int value);
 #define gpio_get_value_cansleep gpio_get_value
 #define gpio_set_value_cansleep gpio_set_value
 
+/* translates a pin number to a port number */
+#define PIN_TO_PORT(val) (val >> 3)
+
 /* wrappers to sleep-enable the previous two functions */
 static inline unsigned gpio_to_irq(unsigned gpio)
 {
        return PIN_TO_PORT(gpio) + IRQ_U300_GPIO_PORT0;
 }
+#define gpio_to_irq gpio_to_irq
 
-static inline unsigned irq_to_gpio(unsigned irq)
-{
-       /*
-        * FIXME: This is no 1-1 mapping at all, it points to the
-        * whole block of 8 pins.
-        */
-       return (irq - IRQ_U300_GPIO_PORT0) << 3;
-}
-
-#endif
+#endif /* __MACH_U300_GPIO_H */
index 677ccef5cd32eddbe1e309d0f169e70af547e041..d9a5c92db74a5cc0aa9a69276bdd17fc464628ff 100644 (file)
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 #include <linux/mmc/host.h>
-#include <linux/gpio.h>
 #include <linux/dmaengine.h>
 #include <linux/amba/mmci.h>
 #include <linux/slab.h>
 #include <mach/coh901318.h>
 #include <mach/dma_channels.h>
+#include <mach/gpio-u300.h>
 
 #include "mmc.h"
 #include "padmux.h"
index c7e75acfe6c9b1911a5825c2b3136ad9b719d445..ff0a4b5b0a82b5873a119ec072b3db781651ab86 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 
index f26fd76f72b4f26301b2af1226664c4767ae6b86..15b23e4bd48888cd9e5a83b9a89b3de7394ca8be 100644 (file)
@@ -6,10 +6,10 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
 #include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
 #include <mach/hardware.h>
 
 #include "pins-db8500.h"
index 8ce46c0fdfd5fc706afa8f710de8cd7f5fe3d463..feb5744d98b7d7658f3d58290b0b1c76ded8f295 100644 (file)
@@ -4,7 +4,7 @@
  * Board data for the U8500 UIB, also known as the New UIB
  * License terms: GNU General Public License (GPL), version 2
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
@@ -13,7 +13,6 @@
 #include <linux/mfd/tc3589x.h>
 #include <linux/input/matrix_keypad.h>
 
-#include <mach/gpio.h>
 #include <mach/irqs.h>
 
 #include "board-mop500.h"
index cd54abaccd96460e1a821d574223887dedb82f86..537ab63c1dc96dc45cd40e9986c3445f6e0384f8 100644 (file)
@@ -37,6 +37,7 @@
 #include <plat/i2c.h>
 #include <plat/ste_dma40.h>
 #include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
index 739fb4c5b1605e2ee19dab40501cb788a9de712f..63c3f8058ffcb370821f3d79a2f94dd7d0e44b88 100644 (file)
@@ -7,9 +7,9 @@
 
 #include <linux/amba/mmci.h>
 #include <linux/mmc/host.h>
-#include <linux/gpio.h>
 
 #include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
 #include <mach/db5500-regs.h>
 #include <plat/ste_dma40.h>
 
index e58f0f562426236c0cd91f11a583cf231003750d..2d9e191bd30aab720d59a13491479acb41862f02 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
-#include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
 
@@ -17,6 +16,7 @@
 
 #include <plat/pincfg.h>
 #include <plat/i2c.h>
+#include <plat/gpio-nomadik.h>
 
 #include <mach/hardware.h>
 #include <mach/devices.h>
index 22705d246fc7ee8262858f46e521a1bd86276f27..9de1af0080944cdcd57c3da3dd48634da24fd279 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/mach/map.h>
 #include <asm/pmu.h>
 
-#include <plat/gpio.h>
+#include <plat/gpio-nomadik.h>
 
 #include <mach/hardware.h>
 #include <mach/devices.h>
index 4598b06c8c554383a711b205f103ebfae29b87e7..13e8890a8b8aae91361998a8ac7c330fd7d9727c 100644 (file)
 #include <linux/amba/bus.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
 #include <asm/mach/map.h>
 #include <asm/pmu.h>
+#include <plat/gpio-nomadik.h>
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
index 13a4ce046ae55926961a22c08ba4820df5a54299..c563e5418d80b5af3e99e2a76f776e44c9b94e0a 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
 
-#include <plat/gpio.h>
+#include <plat/gpio-nomadik.h>
 
 #include <mach/hardware.h>
 
index c7e75acfe6c9b1911a5825c2b3136ad9b719d445..ff0a4b5b0a82b5873a119ec072b3db781651ab86 100644 (file)
@@ -1,4 +1,4 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 
index 94ff27678a46ff9492f9e3e172e75e818049bdb2..40a8c178f10d9e85a2873c83247c3f2fe553f408 100644 (file)
@@ -1,6 +1 @@
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
+/* empty */
index 07c2d9c457ecfd496d7f7061587d31062cd92420..8630b3d10a4d0252968718da5302dfed7934d979 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x60008000
+   zreladdr-y  += 0x60008000
 params_phys-y  := 0x60000100
 initrd_phys-y  := 0x60800000
index 748bb524ee716ed2e5f0ba5b7105b5e1ab6b25d5..13522d86685e2daa5f77bbe2d37c12d30e8e0ddc 100644 (file)
@@ -20,8 +20,6 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffffffff
-
 #define __io(a)                __typesafe_io(a)
 #define __mem_pci(a)   (a)
 
index a8acc4e24902e3bfdaed9c2a312cee04d78d1fca..b79c41cdfdffb10b5cbd629a92432f5c3a945cb6 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x01000000
index 94ff27678a46ff9492f9e3e172e75e818049bdb2..40a8c178f10d9e85a2873c83247c3f2fe553f408 100644 (file)
@@ -1,6 +1 @@
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
+/* empty */
index 9077239f78c90f6b939f0301d902bdcfa059aea3..46181eecf273978b22a883c44af363585f5ea7ca 100644 (file)
@@ -20,8 +20,6 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffff
-
 #define __io(a)                __typesafe_io((a) + 0xf0000000)
 #define __mem_pci(a)   (a)
 
index a057b546b6e5fa4b3887c2b2a723ff814a5424c3..6c3d421c2d11e797361ef9ab4ef82dc16d4bc419 100644 (file)
@@ -1,3 +1,3 @@
-zreladdr-y     := 0x00008000
+zreladdr-y     += 0x00008000
 params_phys-y  := 0x00000100
 
index 034da3e390c9b60e82a23ec18c7e778fcb611717..5385a42032779094043069f005b3e0a9cb8435b2 100644 (file)
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
 
 static inline int gpio_to_irq(unsigned gpio)
 {
        return gpio;
 }
+#define gpio_to_irq gpio_to_irq
 
 static inline int irq_to_gpio(unsigned irq)
 {
index 67039c3e0c48fa6b94f1147b3316f74afcecba9e..760a0efe7580b0dd194ff9bfe4295624336bb806 100644 (file)
@@ -1,3 +1,3 @@
-   zreladdr-y  := 0x00008000
+   zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
index 88633fe01a5dcdc2641afdd3d5010948a3263b73..2df55042f166362317b9e2208b45dab9125e76c2 100644 (file)
@@ -629,6 +629,19 @@ config IO_36
 
 comment "Processor Features"
 
+config ARM_LPAE
+       bool "Support for the Large Physical Address Extension"
+       depends on MMU && CPU_V7
+       help
+         Say Y if you have an ARMv7 processor supporting the LPAE page table
+         format and you would like to access memory beyond the 4GB limit.
+
+config ARCH_PHYS_ADDR_T_64BIT
+       def_bool ARM_LPAE
+
+config ARCH_DMA_ADDR_T_64BIT
+       def_bool ARM_LPAE
+
 config ARM_THUMB
        bool "Support Thumb user binaries"
        depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
index bca7e61928c7dbbde1e56737d8514cb221fd7857..48639e71af4f491f8b82d963747f3047ae04350c 100644 (file)
@@ -91,7 +91,11 @@ obj-$(CONFIG_CPU_MOHAWK)     += proc-mohawk.o
 obj-$(CONFIG_CPU_FEROCEON)     += proc-feroceon.o
 obj-$(CONFIG_CPU_V6)           += proc-v6.o
 obj-$(CONFIG_CPU_V6K)          += proc-v6.o
+ifeq ($(CONFIG_ARM_LPAE),y)
+obj-$(CONFIG_CPU_V7)           += proc-v7lpae.o
+else
 obj-$(CONFIG_CPU_V7)           += proc-v7.o
+endif
 
 AFLAGS_proc-v6.o       :=-Wa,-march=armv6
 AFLAGS_proc-v7.o       :=-Wa,-march=armv7-a
index cfbcf8b9559955a9919a5f7732afa826d516e28b..715eb1dbebb9c383bbe80d87e142332d4cf8dfcb 100644 (file)
@@ -968,7 +968,7 @@ static int __init alignment_init(void)
                ai_usermode = safe_usermode(ai_usermode, false);
        }
 
-       hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN,
+       hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
                        "alignment exception");
 
        /*
index 44c086710d2ba5d21a40741290ef8c40de35928c..c035b9aad55c29b42e9c7943444befa1fbd035e2 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
+#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -351,3 +354,103 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
        printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
                        ways, cache_id, aux, l2x0_size);
 }
+
+#ifdef CONFIG_OF
+static void __init l2x0_of_setup(const struct device_node *np,
+                                __u32 *aux_val, __u32 *aux_mask)
+{
+       u32 data[2] = { 0, 0 };
+       u32 tag = 0;
+       u32 dirty = 0;
+       u32 val = 0, mask = 0;
+
+       of_property_read_u32(np, "arm,tag-latency", &tag);
+       if (tag) {
+               mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
+               val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
+       }
+
+       of_property_read_u32_array(np, "arm,data-latency",
+                                  data, ARRAY_SIZE(data));
+       if (data[0] && data[1]) {
+               mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
+                       L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
+               val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
+                      ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
+       }
+
+       of_property_read_u32(np, "arm,dirty-latency", &dirty);
+       if (dirty) {
+               mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
+               val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
+       }
+
+       *aux_val &= ~mask;
+       *aux_val |= val;
+       *aux_mask &= ~mask;
+}
+
+static void __init pl310_of_setup(const struct device_node *np,
+                                 __u32 *aux_val, __u32 *aux_mask)
+{
+       u32 data[3] = { 0, 0, 0 };
+       u32 tag[3] = { 0, 0, 0 };
+       u32 filter[2] = { 0, 0 };
+
+       of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
+       if (tag[0] && tag[1] && tag[2])
+               writel_relaxed(
+                       ((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
+                       ((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
+                       ((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
+                       l2x0_base + L2X0_TAG_LATENCY_CTRL);
+
+       of_property_read_u32_array(np, "arm,data-latency",
+                                  data, ARRAY_SIZE(data));
+       if (data[0] && data[1] && data[2])
+               writel_relaxed(
+                       ((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
+                       ((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
+                       ((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
+                       l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+       of_property_read_u32_array(np, "arm,filter-ranges",
+                                  filter, ARRAY_SIZE(filter));
+       if (filter[0] && filter[1]) {
+               writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
+                              l2x0_base + L2X0_ADDR_FILTER_END);
+               writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
+                              l2x0_base + L2X0_ADDR_FILTER_START);
+       }
+}
+
+static const struct of_device_id l2x0_ids[] __initconst = {
+       { .compatible = "arm,pl310-cache", .data = pl310_of_setup },
+       { .compatible = "arm,l220-cache", .data = l2x0_of_setup },
+       { .compatible = "arm,l210-cache", .data = l2x0_of_setup },
+       {}
+};
+
+int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask)
+{
+       struct device_node *np;
+       void (*l2_setup)(const struct device_node *np,
+               __u32 *aux_val, __u32 *aux_mask);
+
+       np = of_find_matching_node(NULL, l2x0_ids);
+       if (!np)
+               return -ENODEV;
+       l2x0_base = of_iomap(np, 0);
+       if (!l2x0_base)
+               return -ENOMEM;
+
+       /* L2 configuration can only be changed if the cache is disabled */
+       if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+               l2_setup = of_match_node(l2x0_ids, np)->data;
+               if (l2_setup)
+                       l2_setup(np, &aux_val, &aux_mask);
+       }
+       l2x0_init(l2x0_base, aux_val, aux_mask);
+       return 0;
+}
+#endif
index b0ee9ba3cfab41a52853eca727466abff88ddf27..fcdb1017cdc6c9775b80083afe71479d922ff092 100644 (file)
@@ -22,6 +22,21 @@ unsigned int cpu_last_asid = ASID_FIRST_VERSION;
 DEFINE_PER_CPU(struct mm_struct *, current_mm);
 #endif
 
+#ifdef CONFIG_ARM_LPAE
+#define cpu_set_asid(asid) {                                           \
+       unsigned long ttbl, ttbh;                                       \
+       asm volatile(                                                   \
+       "       mrrc    p15, 0, %0, %1, c2              @ read TTBR0\n" \
+       "       mov     %1, %2, lsl #(48 - 32)          @ set ASID\n"   \
+       "       mcrr    p15, 0, %0, %1, c2              @ set TTBR0\n"  \
+       : "=&r" (ttbl), "=&r" (ttbh)                                    \
+       : "r" (asid & ~ASID_MASK));                                     \
+}
+#else
+#define cpu_set_asid(asid) \
+       asm("   mcr     p15, 0, %0, c13, c0, 1\n" : : "r" (asid))
+#endif
+
 /*
  * We fork()ed a process, and we need a new context for the child
  * to run in.  We reserve version 0 for initial tasks so we will
@@ -37,7 +52,7 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 static void flush_context(void)
 {
        /* set the reserved ASID before flushing the TLB */
-       asm("mcr        p15, 0, %0, c13, c0, 1\n" : : "r" (0));
+       cpu_set_asid(0);
        isb();
        local_flush_tlb_all();
        if (icache_is_vivt_asid_tagged()) {
@@ -99,7 +114,7 @@ static void reset_context(void *info)
        set_mm_context(mm, asid);
 
        /* set the new ASID */
-       asm("mcr        p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id));
+       cpu_set_asid(mm->context.id);
        isb();
 }
 
index 0a0a1e7c20d2b2b7f459197be96575f757171cfd..4f01bfd6899a6055bf0fceb68cb8e936163ee667 100644 (file)
@@ -123,8 +123,8 @@ static void __dma_free_buffer(struct page *page, size_t size)
 #endif
 
 #define CONSISTENT_OFFSET(x)   (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
-#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
-#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
+#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PMD_SHIFT)
+#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PMD_SHIFT)
 
 /*
  * These are the page tables (2MB each) covering uncached, DMA consistent allocations
@@ -183,7 +183,7 @@ static int __init consistent_init(void)
                }
 
                consistent_pte[i++] = pte;
-               base += (1 << PGDIR_SHIFT);
+               base += PMD_SIZE;
        } while (base < CONSISTENT_END);
 
        return ret;
index 3b5ea68acbb8bead82c3202b8c901141e7ca2d2e..91d1768023534b0bb306bbad5d7d8c69672cb20c 100644 (file)
 #define FSR_WRITE              (1 << 11)
 #define FSR_FS4                        (1 << 10)
 #define FSR_FS3_0              (15)
+#define FSR_FS5_0              (0x3f)
 
 static inline int fsr_fs(unsigned int fsr)
 {
+#ifdef CONFIG_ARM_LPAE
+       return fsr & FSR_FS5_0;
+#else
        return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6;
+#endif
 }
 
 #ifdef CONFIG_MMU
@@ -122,8 +127,10 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 
                pte = pte_offset_map(pmd, addr);
                printk(", *pte=%08llx", (long long)pte_val(*pte));
+#ifndef CONFIG_ARM_LPAE
                printk(", *ppte=%08llx",
                       (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
+#endif
                pte_unmap(pte);
        } while(0);
 
@@ -440,6 +447,12 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
        pmd = pmd_offset(pud, addr);
        pmd_k = pmd_offset(pud_k, addr);
 
+#ifdef CONFIG_ARM_LPAE
+       /*
+        * Only one hardware entry per PMD with LPAE.
+        */
+       index = 0;
+#else
        /*
         * On ARM one Linux PGD entry contains two hardware entries (see page
         * tables layout in pgtable.h). We normally guarantee that we always
@@ -449,6 +462,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
         * for the first of pair.
         */
        index = (addr >> SECTION_SHIFT) & 1;
+#endif
        if (pmd_none(pmd_k[index]))
                goto bad_area;
 
@@ -494,6 +508,72 @@ static struct fsr_info {
        int     code;
        const char *name;
 } fsr_info[] = {
+#ifdef CONFIG_ARM_LPAE
+       { do_bad,               SIGBUS,  0,             "unknown 0"                     },
+       { do_bad,               SIGBUS,  0,             "unknown 1"                     },
+       { do_bad,               SIGBUS,  0,             "unknown 2"                     },
+       { do_bad,               SIGBUS,  0,             "unknown 3"                     },
+       { do_bad,               SIGBUS,  0,             "reserved translation fault"    },
+       { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 1 translation fault"     },
+       { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 2 translation fault"     },
+       { do_page_fault,        SIGSEGV, SEGV_MAPERR,   "level 3 translation fault"     },
+       { do_bad,               SIGBUS,  0,             "reserved access flag fault"    },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 1 access flag fault"     },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault"     },
+       { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 access flag fault"     },
+       { do_bad,               SIGBUS,  0,             "reserved permission fault"     },
+       { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 1 permission fault"      },
+       { do_sect_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"      },
+       { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 permission fault"      },
+       { do_bad,               SIGBUS,  0,             "synchronous external abort"    },
+       { do_bad,               SIGBUS,  0,             "asynchronous external abort"   },
+       { do_bad,               SIGBUS,  0,             "unknown 18"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 19"                    },
+       { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error"      },
+       { do_bad,               SIGBUS,  0,             "asynchronous parity error"     },
+       { do_bad,               SIGBUS,  0,             "unknown 26"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 27"                    },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
+       { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },
+       { do_bad,               SIGBUS,  0,             "unknown 32"                    },
+       { do_bad,               SIGBUS,  BUS_ADRALN,    "alignment fault"               },
+       { do_bad,               SIGBUS,  0,             "debug event"                   },
+       { do_bad,               SIGBUS,  0,             "unknown 35"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 36"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 37"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 38"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 39"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 40"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 41"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 42"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 43"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 44"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 45"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 46"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 47"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 48"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 49"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 50"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 51"                    },
+       { do_bad,               SIGBUS,  0,             "implementation fault (lockdown abort)" },
+       { do_bad,               SIGBUS,  0,             "unknown 53"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 54"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 55"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 56"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 57"                    },
+       { do_bad,               SIGBUS,  0,             "implementation fault (coprocessor abort)" },
+       { do_bad,               SIGBUS,  0,             "unknown 59"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 60"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 61"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 62"                    },
+       { do_bad,               SIGBUS,  0,             "unknown 63"                    },
+#else  /* !CONFIG_ARM_LPAE */
        /*
         * The following are the standard ARMv3 and ARMv4 aborts.  ARMv5
         * defines these to be "precise" aborts.
@@ -535,6 +615,7 @@ static struct fsr_info {
        { do_bad,               SIGBUS,  0,             "unknown 29"                       },
        { do_bad,               SIGBUS,  0,             "unknown 30"                       },
        { do_bad,               SIGBUS,  0,             "unknown 31"                       }
+#endif /* CONFIG_ARM_LPAE */
 };
 
 void __init
@@ -573,6 +654,9 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 }
 
 
+#ifdef CONFIG_ARM_LPAE
+#define ifsr_info      fsr_info
+#else  /* !CONFIG_ARM_LPAE */
 static struct fsr_info ifsr_info[] = {
        { do_bad,               SIGBUS,  0,             "unknown 0"                        },
        { do_bad,               SIGBUS,  0,             "unknown 1"                        },
@@ -607,6 +691,7 @@ static struct fsr_info ifsr_info[] = {
        { do_bad,               SIGBUS,  0,             "unknown 30"                       },
        { do_bad,               SIGBUS,  0,             "unknown 31"                       },
 };
+#endif /* CONFIG_ARM_LPAE */
 
 void __init
 hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
@@ -642,6 +727,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
 
 static int __init exceptions_init(void)
 {
+#ifndef CONFIG_ARM_LPAE
        if (cpu_architecture() >= CPU_ARCH_ARMv6) {
                hook_fault_code(4, do_translation_fault, SIGSEGV, SEGV_MAPERR,
                                "I-cache maintenance fault");
@@ -657,6 +743,7 @@ static int __init exceptions_init(void)
                hook_fault_code(6, do_bad, SIGSEGV, SEGV_MAPERR,
                                "section access flag fault");
        }
+#endif
 
        return 0;
 }
index 2be9139a4ef3cc5af97f03a30eefefe7d019740e..24e06555bee49d51b525b0cbb2677f396c663d37 100644 (file)
@@ -1,9 +1,36 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 
 #include <asm/cputype.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 
+#ifdef CONFIG_ARM_LPAE
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
+       unsigned long prot)
+{
+       pmd_t *pmd;
+       unsigned long next;
+
+       if (pud_none_or_clear_bad(pud) || (pud_val(*pud) & L_PGD_SWAPPER)) {
+               pmd = pmd_alloc_one(NULL, addr);
+               if (!pmd) {
+                       pr_warning("Failed to allocate identity pmd.\n");
+                       return;
+               }
+               pud_populate(NULL, pud, pmd);
+               pmd += pmd_index(addr);
+       } else
+               pmd = pmd_offset(pud, addr);
+
+       do {
+               next = pmd_addr_end(addr, end);
+               *pmd = __pmd((addr & PMD_MASK) | prot);
+               flush_pmd_entry(pmd);
+       } while (pmd++, addr = next, addr != end);
+}
+#else  /* !CONFIG_ARM_LPAE */
 static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
        unsigned long prot)
 {
@@ -15,6 +42,7 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
        pmd[1] = __pmd(addr);
        flush_pmd_entry(pmd);
 }
+#endif /* CONFIG_ARM_LPAE */
 
 static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
        unsigned long prot)
@@ -32,7 +60,7 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
 {
        unsigned long prot, next;
 
-       prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
+       prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
        if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
                prot |= PMD_BIT4;
 
@@ -46,7 +74,11 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
 #ifdef CONFIG_SMP
 static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
 {
-       pmd_t *pmd = pmd_offset(pud, addr);
+       pmd_t *pmd;
+
+       if (pud_none_or_clear_bad(pud))
+               return;
+       pmd = pmd_offset(pud, addr);
        pmd_clear(pmd);
 }
 
index ab506272b2d3ef459b264b7741d61af46f6aa6b8..645011bf8d46acaca23af286ba848e113ae68bd2 100644 (file)
@@ -64,7 +64,7 @@ void __check_kvm_seq(struct mm_struct *mm)
        } while (seq != init_mm.context.kvm_seq);
 }
 
-#ifndef CONFIG_SMP
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
 /*
  * Section support is unsafe on SMP - If you iounmap and ioremap a region,
  * the other CPUs will not see this change until their next context switch.
@@ -79,13 +79,16 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
 {
        unsigned long addr = virt, end = virt + (size & ~(SZ_1M - 1));
        pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmdp;
 
        flush_cache_vunmap(addr, end);
        pgd = pgd_offset_k(addr);
+       pud = pud_offset(pgd, addr);
+       pmdp = pmd_offset(pud, addr);
        do {
-               pmd_t pmd, *pmdp = pmd_offset(pgd, addr);
+               pmd_t pmd = *pmdp;
 
-               pmd = *pmdp;
                if (!pmd_none(pmd)) {
                        /*
                         * Clear the PMD from the page table, and
@@ -104,8 +107,8 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
                                pte_free_kernel(&init_mm, pmd_page_vaddr(pmd));
                }
 
-               addr += PGDIR_SIZE;
-               pgd++;
+               addr += PMD_SIZE;
+               pmdp += 2;
        } while (addr < end);
 
        /*
@@ -124,6 +127,8 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
 {
        unsigned long addr = virt, end = virt + size;
        pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
 
        /*
         * Remove and free any PTE-based mapping, and
@@ -132,17 +137,17 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
        unmap_area_sections(virt, size);
 
        pgd = pgd_offset_k(addr);
+       pud = pud_offset(pgd, addr);
+       pmd = pmd_offset(pud, addr);
        do {
-               pmd_t *pmd = pmd_offset(pgd, addr);
-
                pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
                pfn += SZ_1M >> PAGE_SHIFT;
                pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
                pfn += SZ_1M >> PAGE_SHIFT;
                flush_pmd_entry(pmd);
 
-               addr += PGDIR_SIZE;
-               pgd++;
+               addr += PMD_SIZE;
+               pmd += 2;
        } while (addr < end);
 
        return 0;
@@ -154,6 +159,8 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
 {
        unsigned long addr = virt, end = virt + size;
        pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
 
        /*
         * Remove and free any PTE-based mapping, and
@@ -162,6 +169,8 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
        unmap_area_sections(virt, size);
 
        pgd = pgd_offset_k(virt);
+       pud = pud_offset(pgd, addr);
+       pmd = pmd_offset(pud, addr);
        do {
                unsigned long super_pmd_val, i;
 
@@ -170,14 +179,12 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
                super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20;
 
                for (i = 0; i < 8; i++) {
-                       pmd_t *pmd = pmd_offset(pgd, addr);
-
                        pmd[0] = __pmd(super_pmd_val);
                        pmd[1] = __pmd(super_pmd_val);
                        flush_pmd_entry(pmd);
 
-                       addr += PGDIR_SIZE;
-                       pgd++;
+                       addr += PMD_SIZE;
+                       pmd += 2;
                }
 
                pfn += SUPERSECTION_SIZE >> PAGE_SHIFT;
@@ -195,11 +202,13 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
        unsigned long addr;
        struct vm_struct * area;
 
+#ifndef CONFIG_ARM_LPAE
        /*
         * High mappings must be supersection aligned
         */
        if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
                return NULL;
+#endif
 
        /*
         * Don't allow RAM to be mapped - this causes problems with ARMv6+
@@ -221,7 +230,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
                return NULL;
        addr = (unsigned long)area->addr;
 
-#ifndef CONFIG_SMP
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
        if (DOMAIN_IO == 0 &&
            (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) ||
               cpu_is_xsc3()) && pfn >= 0x100000 &&
@@ -292,7 +301,7 @@ EXPORT_SYMBOL(__arm_ioremap);
 void __iounmap(volatile void __iomem *io_addr)
 {
        void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
-#ifndef CONFIG_SMP
+#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
        struct vm_struct **p, *tmp;
 
        /*
index 010566799c80c27680390154ae85a0a7b5124567..ad7cce3bc431bfda3060f98ea067bd4c5bb339e3 100644 (file)
@@ -12,8 +12,8 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
 
 struct mem_type {
        pteval_t prot_pte;
-       unsigned int prot_l1;
-       unsigned int prot_sect;
+       pmdval_t prot_l1;
+       pmdval_t prot_sect;
        unsigned int domain;
 };
 
index 594d677b92c883c25c4d5051bcc635394984b6f6..85aa25e2727a4e75f46da7d2b05922f6b141f4a8 100644 (file)
@@ -60,7 +60,7 @@ EXPORT_SYMBOL(pgprot_kernel);
 struct cachepolicy {
        const char      policy[16];
        unsigned int    cr_mask;
-       unsigned int    pmd;
+       pmdval_t        pmd;
        pteval_t        pte;
 };
 
@@ -150,6 +150,7 @@ static int __init early_nowrite(char *__unused)
 }
 early_param("nowb", early_nowrite);
 
+#ifndef CONFIG_ARM_LPAE
 static int __init early_ecc(char *p)
 {
        if (memcmp(p, "on", 2) == 0)
@@ -159,6 +160,7 @@ static int __init early_ecc(char *p)
        return 0;
 }
 early_param("ecc", early_ecc);
+#endif
 
 static int __init noalign_setup(char *__unused)
 {
@@ -228,10 +230,12 @@ static struct mem_type mem_types[] = {
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
                .domain    = DOMAIN_KERNEL,
        },
+#ifndef CONFIG_ARM_LPAE
        [MT_MINICLEAN] = {
                .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
                .domain    = DOMAIN_KERNEL,
        },
+#endif
        [MT_LOW_VECTORS] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_RDONLY,
@@ -288,7 +292,7 @@ static void __init build_mem_type_table(void)
 {
        struct cachepolicy *cp;
        unsigned int cr = get_cr();
-       unsigned int user_pgprot, kern_pgprot, vecs_pgprot;
+       pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
        int cpu_arch = cpu_architecture();
        int i;
 
@@ -421,6 +425,7 @@ static void __init build_mem_type_table(void)
         * ARMv6 and above have extended page tables.
         */
        if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
+#ifndef CONFIG_ARM_LPAE
                /*
                 * Mark cache clean areas and XIP ROM read only
                 * from SVC mode and no access from userspace.
@@ -428,6 +433,7 @@ static void __init build_mem_type_table(void)
                mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
                mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
                mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+#endif
 
                if (is_smp()) {
                        /*
@@ -466,6 +472,18 @@ static void __init build_mem_type_table(void)
                mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
        }
 
+#ifdef CONFIG_ARM_LPAE
+       /*
+        * Do not generate access flag faults for the kernel mappings.
+        */
+       for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+               mem_types[i].prot_pte |= PTE_EXT_AF;
+               mem_types[i].prot_sect |= PMD_SECT_AF;
+       }
+       kern_pgprot |= PTE_EXT_AF;
+       vecs_pgprot |= PTE_EXT_AF;
+#endif
+
        for (i = 0; i < 16; i++) {
                unsigned long v = pgprot_val(protection_map[i]);
                protection_map[i] = __pgprot(v | user_pgprot);
@@ -564,8 +582,10 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
        if (((addr | end | phys) & ~SECTION_MASK) == 0) {
                pmd_t *p = pmd;
 
+#ifndef CONFIG_ARM_LPAE
                if (addr & SECTION_SIZE)
                        pmd++;
+#endif
 
                do {
                        *pmd = __pmd(phys | type->prot_sect);
@@ -595,6 +615,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
        } while (pud++, addr = next, addr != end);
 }
 
+#ifndef CONFIG_ARM_LPAE
 static void __init create_36bit_mapping(struct map_desc *md,
                                        const struct mem_type *type)
 {
@@ -654,6 +675,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
                pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT;
        } while (addr != end);
 }
+#endif /* !CONFIG_ARM_LPAE */
 
 /*
  * Create the page directory entries and any necessary
@@ -685,6 +707,7 @@ static void __init create_mapping(struct map_desc *md)
 
        type = &mem_types[md->type];
 
+#ifndef CONFIG_ARM_LPAE
        /*
         * Catch 36-bit addresses
         */
@@ -692,6 +715,7 @@ static void __init create_mapping(struct map_desc *md)
                create_36bit_mapping(md, type);
                return;
        }
+#endif
 
        addr = md->virtual & PAGE_MASK;
        phys = __pfn_to_phys(md->pfn);
@@ -768,7 +792,8 @@ void __init sanity_check_meminfo(void)
                *bank = meminfo.bank[i];
 
 #ifdef CONFIG_HIGHMEM
-               if (__va(bank->start) >= vmalloc_min ||
+               if (bank->start > ULONG_MAX ||
+                   __va(bank->start) >= vmalloc_min ||
                    __va(bank->start) < (void *)PAGE_OFFSET)
                        highmem = 1;
 
@@ -778,7 +803,7 @@ void __init sanity_check_meminfo(void)
                 * Split those memory banks which are partially overlapping
                 * the vmalloc area greatly simplifying things later.
                 */
-               if (__va(bank->start) < vmalloc_min &&
+               if (!highmem && __va(bank->start) < vmalloc_min &&
                    bank->size > vmalloc_min - __va(bank->start)) {
                        if (meminfo.nr_banks >= NR_BANKS) {
                                printk(KERN_CRIT "NR_BANKS too low, "
@@ -863,14 +888,14 @@ static inline void prepare_page_table(void)
        /*
         * Clear out all the mappings below the kernel image.
         */
-       for (addr = 0; addr < MODULES_VADDR; addr += PGDIR_SIZE)
+       for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE)
                pmd_clear(pmd_off_k(addr));
 
 #ifdef CONFIG_XIP_KERNEL
        /* The XIP kernel is mapped in the module area -- skip over it */
-       addr = ((unsigned long)_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+       addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
 #endif
-       for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+       for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
                pmd_clear(pmd_off_k(addr));
 
        /*
@@ -885,10 +910,18 @@ static inline void prepare_page_table(void)
         * memory bank, up to the end of the vmalloc region.
         */
        for (addr = __phys_to_virt(end);
-            addr < VMALLOC_END; addr += PGDIR_SIZE)
+            addr < VMALLOC_END; addr += PMD_SIZE)
                pmd_clear(pmd_off_k(addr));
 }
 
+#ifdef CONFIG_ARM_LPAE
+/* the first page is reserved for pgd */
+#define SWAPPER_PG_DIR_SIZE    (PAGE_SIZE + \
+                                PTRS_PER_PGD * PTRS_PER_PMD * sizeof(pmd_t))
+#else
+#define SWAPPER_PG_DIR_SIZE    (PTRS_PER_PGD * sizeof(pgd_t))
+#endif
+
 /*
  * Reserve the special regions of memory
  */
@@ -898,7 +931,7 @@ void __init arm_mm_memblock_reserve(void)
         * Reserve the page tables.  These are already in use,
         * and can only be in node 0.
         */
-       memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
+       memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE);
 
 #ifdef CONFIG_SA1111
        /*
@@ -926,7 +959,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
         */
        vectors_page = early_alloc(PAGE_SIZE);
 
-       for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
+       for (addr = VMALLOC_END; addr; addr += PMD_SIZE)
                pmd_clear(pmd_off_k(addr));
 
        /*
index b2027c154b2a0c946198de99370a89be2f60b6eb..a3e78ccabd655ef871c74b66b6a277eee29290d6 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
 
 #include "mm.h"
 
+#ifdef CONFIG_ARM_LPAE
+#define __pgd_alloc()  kmalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL)
+#define __pgd_free(pgd)        kfree(pgd)
+#else
+#define __pgd_alloc()  (pgd_t *)__get_free_pages(GFP_KERNEL, 2)
+#define __pgd_free(pgd)        free_pages((unsigned long)pgd, 2)
+#endif
+
 /*
  * need to get a 16k page for level 1
  */
@@ -27,7 +36,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
        pmd_t *new_pmd, *init_pmd;
        pte_t *new_pte, *init_pte;
 
-       new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
+       new_pgd = __pgd_alloc();
        if (!new_pgd)
                goto no_pgd;
 
@@ -42,10 +51,25 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 
        clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
 
+#ifdef CONFIG_ARM_LPAE
+       /*
+        * Allocate PMD table for modules and pkmap mappings.
+        */
+       new_pud = pud_alloc(mm, new_pgd + pgd_index(MODULES_VADDR),
+                           MODULES_VADDR);
+       if (!new_pud)
+               goto no_pud;
+
+       new_pmd = pmd_alloc(mm, new_pud, 0);
+       if (!new_pmd)
+               goto no_pmd;
+#endif
+
        if (!vectors_high()) {
                /*
                 * On ARM, first page must always be allocated since it
-                * contains the machine vectors.
+                * contains the machine vectors. The vectors are always high
+                * with LPAE.
                 */
                new_pud = pud_alloc(mm, new_pgd, 0);
                if (!new_pud)
@@ -74,7 +98,7 @@ no_pte:
 no_pmd:
        pud_free(mm, new_pud);
 no_pud:
-       free_pages((unsigned long)new_pgd, 2);
+       __pgd_free(new_pgd);
 no_pgd:
        return NULL;
 }
@@ -111,5 +135,24 @@ no_pud:
        pgd_clear(pgd);
        pud_free(mm, pud);
 no_pgd:
-       free_pages((unsigned long) pgd_base, 2);
+#ifdef CONFIG_ARM_LPAE
+       /*
+        * Free modules/pkmap or identity pmd tables.
+        */
+       for (pgd = pgd_base; pgd < pgd_base + PTRS_PER_PGD; pgd++) {
+               if (pgd_none_or_clear_bad(pgd))
+                       continue;
+               if (pgd_val(*pgd) & L_PGD_SWAPPER)
+                       continue;
+               pud = pud_offset(pgd, 0);
+               if (pud_none_or_clear_bad(pud))
+                       continue;
+               pmd = pmd_offset(pud, 0);
+               pud_clear(pud);
+               pmd_free(mm, pmd);
+               pgd_clear(pgd);
+               pud_free(mm, pud);
+       }
+#endif
+       __pgd_free(pgd_base);
 }
index 307a4def8d3a7d6c89d06211e53f855a7e518fea..2d8ff3ad86d3e1a2b9d9abd83a1bdd3ab42eba3a 100644 (file)
@@ -91,8 +91,9 @@
 #if L_PTE_SHARED != PTE_EXT_SHARED
 #error PTE shared bit mismatch
 #endif
-#if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
-     L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
+#if !defined (CONFIG_ARM_LPAE) && \
+       (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
+        L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
 #error Invalid Linux PTE bit settings
 #endif
 #endif /* CONFIG_MMU */
index 219138d2f158843059fbfec5373e0dbf275dbab2..a923aa0fd00dd65fb977aad23145d514e3836b13 100644 (file)
@@ -223,6 +223,22 @@ __v6_setup:
        mrc     p15, 0, r0, c1, c0, 0           @ read control register
        bic     r0, r0, r5                      @ clear bits them
        orr     r0, r0, r6                      @ set them
+#ifdef CONFIG_ARM_ERRATA_364296
+       /*
+        * Workaround for the 364296 ARM1136 r0p2 erratum (possible cache data
+        * corruption with hit-under-miss enabled). The conditional code below
+        * (setting the undocumented bit 31 in the auxiliary control register
+        * and the FI bit in the control register) disables hit-under-miss
+        * without putting the processor into full low interrupt latency mode.
+        */
+       ldr     r6, =0x4107b362                 @ id for ARM1136 r0p2
+       mrc     p15, 0, r5, c0, c0, 0           @ get processor id
+       teq     r5, r6                          @ check for the faulty core
+       mrceq   p15, 0, r5, c1, c0, 1           @ load aux control reg
+       orreq   r5, r5, #(1 << 31)              @ set the undocumented bit 31
+       mcreq   p15, 0, r5, c1, c0, 1           @ write aux control reg
+       orreq   r0, r0, #(1 << 21)              @ low interrupt latency configuration
+#endif
        mov     pc, lr                          @ return to head.S:__ret
 
        /*
diff --git a/arch/arm/mm/proc-v7lpae.S b/arch/arm/mm/proc-v7lpae.S
new file mode 100644 (file)
index 0000000..0bee213
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * arch/arm/mm/proc-v7lpae.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2011 ARM Ltd.
+ * Author: Catalin Marinas <catalin.marinas@arm.com>
+ *   based on arch/arm/mm/proc-v7.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+
+#include "proc-macros.S"
+
+#define TTB_IRGN_NC    (0 << 8)
+#define TTB_IRGN_WBWA  (1 << 8)
+#define TTB_IRGN_WT    (2 << 8)
+#define TTB_IRGN_WB    (3 << 8)
+#define TTB_RGN_NC     (0 << 10)
+#define TTB_RGN_OC_WBWA        (1 << 10)
+#define TTB_RGN_OC_WT  (2 << 10)
+#define TTB_RGN_OC_WB  (3 << 10)
+#define TTB_S          (3 << 12)
+#define TTB_EAE                (1 << 31)
+
+/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
+#define TTB_FLAGS_UP   (TTB_IRGN_WB|TTB_RGN_OC_WB)
+#define PMD_FLAGS_UP   (PMD_SECT_WB)
+
+/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
+#define TTB_FLAGS_SMP  (TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA)
+#define PMD_FLAGS_SMP  (PMD_SECT_WBWA|PMD_SECT_S)
+
+ENTRY(cpu_v7_proc_init)
+       mov     pc, lr
+ENDPROC(cpu_v7_proc_init)
+
+ENTRY(cpu_v7_proc_fin)
+       mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
+       bic     r0, r0, #0x1000                 @ ...i............
+       bic     r0, r0, #0x0006                 @ .............ca.
+       mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       mov     pc, lr
+ENDPROC(cpu_v7_proc_fin)
+
+/*
+ *     cpu_v7_reset(loc)
+ *
+ *     Perform a soft reset of the system.  Put the CPU into the
+ *     same state as it would be if it had been reset, and branch
+ *     to what would be the reset vector.
+ *
+ *     - loc   - location to jump to for soft reset
+ */
+       .align  5
+ENTRY(cpu_v7_reset)
+       mov     pc, r0
+ENDPROC(cpu_v7_reset)
+
+/*
+ *     cpu_v7_do_idle()
+ *
+ *     Idle the processor (eg, wait for interrupt).
+ *
+ *     IRQs are already disabled.
+ */
+ENTRY(cpu_v7_do_idle)
+       dsb                                     @ WFI may enter a low-power mode
+       wfi
+       mov     pc, lr
+ENDPROC(cpu_v7_do_idle)
+
+ENTRY(cpu_v7_dcache_clean_area)
+#ifndef TLB_CAN_READ_FROM_L1_CACHE
+       dcache_line_size r2, r3
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+       add     r0, r0, r2
+       subs    r1, r1, r2
+       bhi     1b
+       dsb
+#endif
+       mov     pc, lr
+ENDPROC(cpu_v7_dcache_clean_area)
+
+/*
+ *     cpu_v7_switch_mm(pgd_phys, tsk)
+ *
+ *     Set the translation table base pointer to be pgd_phys
+ *
+ *     - pgd_phys - physical address of new TTB
+ *
+ *     It is assumed that:
+ *     - we are not using split page tables
+ */
+ENTRY(cpu_v7_switch_mm)
+#ifdef CONFIG_MMU
+       ldr     r1, [r1, #MM_CONTEXT_ID]        @ get mm->context.id
+       mov     r2, #0
+       and     r3, r1, #0xff
+       mov     r3, r3, lsl #(48 - 32)          @ ASID
+       mcrr    p15, 0, r0, r3, c2              @ set TTB 0
+       isb
+#endif
+       mov     pc, lr
+ENDPROC(cpu_v7_switch_mm)
+
+/*
+ *     cpu_v7_set_pte_ext(ptep, pte)
+ *
+ *     Set a level 2 translation table entry.
+ *
+ *     - ptep  - pointer to level 2 translation table entry
+ *               (hardware version is stored at +2048 bytes)
+ *     - pte   - PTE value to store
+ *     - ext   - value for extended PTE bits
+ */
+ENTRY(cpu_v7_set_pte_ext)
+#ifdef CONFIG_MMU
+       tst     r2, #L_PTE_PRESENT
+       beq     1f
+       tst     r3, #1 << (55 - 32)             @ L_PTE_DIRTY
+       orreq   r2, #L_PTE_RDONLY
+1:     strd    r2, r3, [r0]
+       mcr     p15, 0, r0, c7, c10, 1          @ flush_pte
+#endif
+       mov     pc, lr
+ENDPROC(cpu_v7_set_pte_ext)
+
+cpu_v7_name:
+       .ascii  "ARMv7 Processor"
+       .align
+
+       /*
+        * Memory region attributes for LPAE (defined in pgtable-3level.h):
+        *
+        *   n = AttrIndx[2:0]
+        *
+        *                      n       MAIR
+        *   UNCACHED           000     00000000
+        *   BUFFERABLE         001     01000100
+        *   DEV_WC             001     01000100
+        *   WRITETHROUGH       010     10101010
+        *   WRITEBACK          011     11101110
+        *   DEV_CACHED         011     11101110
+        *   DEV_SHARED         100     00000100
+        *   DEV_NONSHARED      100     00000100
+        *   unused             101
+        *   unused             110
+        *   WRITEALLOC         111     11111111
+        */
+.equ   MAIR0,  0xeeaa4400                      @ MAIR0
+.equ   MAIR1,  0xff000004                      @ MAIR1
+
+/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
+.globl cpu_v7_suspend_size
+.equ   cpu_v7_suspend_size, 4 * 10
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_v7_do_suspend)
+       stmfd   sp!, {r4 - r11, lr}
+       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mrc     p15, 0, r5, c13, c0, 1  @ Context ID
+       mrc     p15, 0, r6, c3, c0, 0   @ Domain ID
+       mrrc    p15, 0, r7, r8, c2      @ TTB 0
+       mrrc    p15, 1, r2, r3, c2      @ TTB 1
+       mrc     p15, 0, r9, c1, c0, 0   @ Control register
+       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
+       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access control
+       stmia   r0, {r2 - r11}
+       ldmfd   sp!, {r4 - r11, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+       mov     ip, #0
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate TLBs
+       mcr     p15, 0, ip, c7, c5, 0   @ invalidate I cache
+       ldmia   r0, {r2 - r11}
+       mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mcr     p15, 0, r5, c13, c0, 1  @ Context ID
+       mcr     p15, 0, r6, c3, c0, 0   @ Domain ID
+       mcrr    p15, 0, r7, r8, c2      @ TTB 0
+       mcrr    p15, 1, r2, r3, c2      @ TTB 1
+       mcr     p15, 0, ip, c2, c0, 2   @ TTB control register
+       mcr     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
+       mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access control
+       ldr     r4, =MAIR0
+       ldr     r5, =MAIR1
+       mcr     p15, 0, r4, c10, c2, 0  @ write MAIR0
+       mcr     p15, 0, r5, c10, c2, 1  @ write MAIR1
+       isb
+       mov     r0, r9                  @ control register
+       mov     r2, r7, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, cpu_resume_l1_flags
+       b       cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+       ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+       ALT_UP(.long  PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v7_do_suspend      0
+#define cpu_v7_do_resume       0
+#endif
+
+       __CPUINIT
+
+/*
+ *     __v7_setup
+ *
+ *     Initialise TLB, Caches, and MMU state ready to switch the MMU
+ *     on. Return in r0 the new CP15 C1 control register setting.
+ *
+ *     This should be able to cover all ARMv7 cores with LPAE.
+ *
+ *     It is assumed that:
+ *     - cache type register is implemented
+ */
+__v7_ca15mp_setup:
+       mov     r10, #0
+1:
+#ifdef CONFIG_SMP
+       ALT_SMP(mrc     p15, 0, r0, c1, c0, 1)
+       ALT_UP(mov      r0, #(1 << 6))          @ fake it for UP
+       tst     r0, #(1 << 6)                   @ SMP/nAMP mode enabled?
+       orreq   r0, r0, #(1 << 6)               @ Enable SMP/nAMP mode
+       orreq   r0, r0, r10                     @ Enable CPU-specific SMP bits
+       mcreq   p15, 0, r0, c1, c0, 1
+#endif
+__v7_setup:
+       adr     r12, __v7_setup_stack           @ the local stack
+       stmia   r12, {r0-r5, r7, r9, r11, lr}
+       bl      v7_flush_dcache_all
+       ldmia   r12, {r0-r5, r7, r9, r11, lr}
+
+       mov     r10, #0
+       mcr     p15, 0, r10, c7, c5, 0          @ I+BTB cache invalidate
+       dsb
+#ifdef CONFIG_MMU
+       mcr     p15, 0, r10, c8, c7, 0          @ invalidate I + D TLBs
+       mov     r5, #TTB_EAE
+       ALT_SMP(orr     r5, r5, #TTB_FLAGS_SMP)
+       ALT_SMP(orr     r5, r5, #TTB_FLAGS_SMP << 16)
+       ALT_UP(orr      r5, r5, #TTB_FLAGS_UP)
+       ALT_UP(orr      r5, r5, #TTB_FLAGS_UP << 16)
+       mrc     p15, 0, r10, c2, c0, 2
+       orr     r10, r10, r5
+#if PHYS_OFFSET <= PAGE_OFFSET
+       /*
+        * TTBR0/TTBR1 split (PAGE_OFFSET):
+        *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
+        *   0x80000000: T0SZ = 0, T1SZ = 1
+        *   0xc0000000: T0SZ = 0, T1SZ = 2
+        *
+        * Only use this feature if PAGE_OFFSET <=  PAGE_OFFSET, otherwise
+        * booting secondary CPUs would end up using TTBR1 for the identity
+        * mapping set up in TTBR0.
+        */
+       orr     r10, r10, #(((PAGE_OFFSET >> 30) - 1) << 16)    @ TTBCR.T1SZ
+#endif
+       mcr     p15, 0, r10, c2, c0, 2          @ TTB control register
+       mov     r5, #0
+#if defined CONFIG_VMSPLIT_2G
+       /* PAGE_OFFSET == 0x80000000, T1SZ == 1 */
+       add     r6, r8, #1 << 4                 @ skip two L1 entries
+#elif defined CONFIG_VMSPLIT_3G
+       /* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */
+       add     r6, r8, #4096 * (1 + 3)         @ only L2 used, skip pgd+3*pmd
+#else
+       mov     r6, r8
+#endif
+       mcrr    p15, 1, r6, r5, c2              @ load TTBR1
+       ldr     r5, =MAIR0
+       ldr     r6, =MAIR1
+       mcr     p15, 0, r5, c10, c2, 0          @ write MAIR0
+       mcr     p15, 0, r6, c10, c2, 1          @ write MAIR1
+#endif
+       adr     r5, v7_crval
+       ldmia   r5, {r5, r6}
+#ifdef CONFIG_CPU_ENDIAN_BE8
+       orr     r6, r6, #1 << 25                @ big-endian page tables
+#endif
+#ifdef CONFIG_SWP_EMULATE
+       orr     r5, r5, #(1 << 10)              @ set SW bit in "clear"
+       bic     r6, r6, #(1 << 10)              @ clear it in "mmuset"
+#endif
+       mrc     p15, 0, r0, c1, c0, 0           @ read control register
+       bic     r0, r0, r5                      @ clear bits them
+       orr     r0, r0, r6                      @ set them
+ THUMB(        orr     r0, r0, #1 << 30        )       @ Thumb exceptions
+       mov     pc, lr                          @ return to head.S:__ret
+ENDPROC(__v7_setup)
+
+       /*   AT
+        *  TFR   EV X F   IHD LR    S
+        * .EEE ..EE PUI. .TAT 4RVI ZWRS BLDP WCAM
+        * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
+        *   11    0 110    1  0011 1100 .111 1101 < we want
+        */
+       .type   v7_crval, #object
+v7_crval:
+       crval   clear=0x0120c302, mmuset=0x30c23c7d, ucset=0x00c01c7c
+
+__v7_setup_stack:
+       .space  4 * 11                          @ 11 registers
+
+       __INITDATA
+
+       .type   v7_processor_functions, #object
+ENTRY(v7_processor_functions)
+       .word   v7_early_abort
+       .word   v7_pabort
+       .word   cpu_v7_proc_init
+       .word   cpu_v7_proc_fin
+       .word   cpu_v7_reset
+       .word   cpu_v7_do_idle
+       .word   cpu_v7_dcache_clean_area
+       .word   cpu_v7_switch_mm
+       .word   cpu_v7_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
+       .size   v7_processor_functions, . - v7_processor_functions
+
+       .section ".rodata"
+
+       .type   cpu_arch_name, #object
+cpu_arch_name:
+       .asciz  "armv7"
+       .size   cpu_arch_name, . - cpu_arch_name
+
+       .type   cpu_elf_name, #object
+cpu_elf_name:
+       .asciz  "v7"
+       .size   cpu_elf_name, . - cpu_elf_name
+       .align
+
+       .section ".proc.info.init", #alloc, #execinstr
+
+       .type   __v7_ca15mp_proc_info, #object
+__v7_ca15mp_proc_info:
+       .long   0x410fc0f0              @ Required ID value
+       .long   0xff0ffff0              @ Mask for ID
+       ALT_SMP(.long \
+               PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_SECT_AF | \
+               PMD_FLAGS_SMP)
+       ALT_UP(.long \
+               PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_SECT_AF | \
+               PMD_FLAGS_UP)
+               /* PMD_SECT_XN is set explicitly in head.S for LPAE */
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_XN | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_SECT_AF
+       b       __v7_ca15mp_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
+       .long   cpu_v7_name
+       .long   v7_processor_functions
+       .long   v7wbi_tlb_fns
+       .long   v6_user_fns
+       .long   v7_cache_fns
+       .size   __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
+
+       /*
+        * Match any ARMv7 processor core.
+        */
+       .type   __v7_proc_info, #object
+__v7_proc_info:
+       .long   0x000f0000              @ Required ID value
+       .long   0x000f0000              @ Mask for ID
+       ALT_SMP(.long \
+               PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_SECT_AF | \
+               PMD_FLAGS_SMP)
+       ALT_UP(.long \
+               PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_SECT_AF | \
+               PMD_FLAGS_UP)
+               /* PMD_SECT_XN is set explicitly in head.S for LPAE */
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_XN | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ | \
+               PMD_SECT_AF
+       W(b)    __v7_setup
+       .long   cpu_arch_name
+       .long   cpu_elf_name
+       .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
+       .long   cpu_v7_name
+       .long   v7_processor_functions
+       .long   v7wbi_tlb_fns
+       .long   v6_user_fns
+       .long   v7_cache_fns
+       .size   __v7_proc_info, . - __v7_proc_info
index 31c820c1b7960eb3e0d64aa9dfc782f9c7e4ff00..3e1ffc8b8f0c2d56283bdbc92b476bb07f86196d 100644 (file)
 
 #include <linux/spinlock.h>
 #include <mach/hardware.h>
-#include <asm-generic/gpio.h>
 
 
 /* There's a off-by-one betweem the gpio bank number and the gpiochip */
 /* range e.g. GPIO_1_5 is gpio 5 under linux */
 #define IMX_GPIO_NR(bank, nr)          (((bank) - 1) * 32 + (nr))
 
-/* use gpiolib dispatchers */
-#define gpio_get_value         __gpio_get_value
-#define gpio_set_value         __gpio_set_value
-#define gpio_cansleep          __gpio_cansleep
-
 #define gpio_to_irq(gpio)      (MXC_GPIO_IRQ_START + (gpio))
 #define irq_to_gpio(irq)       ((irq) - MXC_GPIO_IRQ_START)
 
diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
new file mode 100644 (file)
index 0000000..3ba4d8f
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Structures and registers for GPIO access in the Nomadik SoC
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ *     Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_NOMADIK_GPIO
+#define __PLAT_NOMADIK_GPIO
+
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT   0x00
+#define NMK_GPIO_DATS  0x04
+#define NMK_GPIO_DATC  0x08
+#define NMK_GPIO_PDIS  0x0c
+#define NMK_GPIO_DIR   0x10
+#define NMK_GPIO_DIRS  0x14
+#define NMK_GPIO_DIRC  0x18
+#define NMK_GPIO_SLPC  0x1c
+#define NMK_GPIO_AFSLA 0x20
+#define NMK_GPIO_AFSLB 0x24
+
+#define NMK_GPIO_RIMSC 0x40
+#define NMK_GPIO_FIMSC 0x44
+#define NMK_GPIO_IS    0x48
+#define NMK_GPIO_IC    0x4c
+#define NMK_GPIO_RWIMSC        0x50
+#define NMK_GPIO_FWIMSC        0x54
+#define NMK_GPIO_WKS   0x58
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO      0
+#define NMK_GPIO_ALT_A 1
+#define NMK_GPIO_ALT_B 2
+#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+/* Pull up/down values */
+enum nmk_gpio_pull {
+       NMK_GPIO_PULL_NONE,
+       NMK_GPIO_PULL_UP,
+       NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+       NMK_GPIO_SLPM_INPUT,
+       NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
+       NMK_GPIO_SLPM_NOCHANGE,
+       NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
+};
+
+extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
+extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
+extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
+extern int nmk_gpio_get_mode(int gpio);
+
+extern void nmk_gpio_wakeups_suspend(void);
+extern void nmk_gpio_wakeups_resume(void);
+
+extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+       char *name;
+       int first_gpio;
+       int first_irq;
+       int num_gpio;
+       u32 (*get_secondary_status)(unsigned int bank);
+       void (*set_ioforce)(bool enable);
+       bool supports_sleepmode;
+};
+
+#endif /* __PLAT_NOMADIK_GPIO */
index d5d7e651269c3b434c5f500c5a491b9f7e3437c1..78c0c0fbadb782ef98506fd69e862c17f84ad2b7 100644 (file)
 #ifndef __ASM_PLAT_GPIO_H
 #define __ASM_PLAT_GPIO_H
 
-#include <asm-generic/gpio.h>
-
-/*
- * These currently cause a function call to happen, they may be optimized
- * if needed by adding cpu-specific defines to identify blocks
- * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
- */
-#define gpio_get_value  __gpio_get_value
-#define gpio_set_value  __gpio_set_value
-#define gpio_cansleep   __gpio_cansleep
-#define gpio_to_irq     __gpio_to_irq
-
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT   0x00
-#define NMK_GPIO_DATS  0x04
-#define NMK_GPIO_DATC  0x08
-#define NMK_GPIO_PDIS  0x0c
-#define NMK_GPIO_DIR   0x10
-#define NMK_GPIO_DIRS  0x14
-#define NMK_GPIO_DIRC  0x18
-#define NMK_GPIO_SLPC  0x1c
-#define NMK_GPIO_AFSLA 0x20
-#define NMK_GPIO_AFSLB 0x24
-
-#define NMK_GPIO_RIMSC 0x40
-#define NMK_GPIO_FIMSC 0x44
-#define NMK_GPIO_IS    0x48
-#define NMK_GPIO_IC    0x4c
-#define NMK_GPIO_RWIMSC        0x50
-#define NMK_GPIO_FWIMSC        0x54
-#define NMK_GPIO_WKS   0x58
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO      0
-#define NMK_GPIO_ALT_A 1
-#define NMK_GPIO_ALT_B 2
-#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-/* Pull up/down values */
-enum nmk_gpio_pull {
-       NMK_GPIO_PULL_NONE,
-       NMK_GPIO_PULL_UP,
-       NMK_GPIO_PULL_DOWN,
-};
-
-/* Sleep mode */
-enum nmk_gpio_slpm {
-       NMK_GPIO_SLPM_INPUT,
-       NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
-       NMK_GPIO_SLPM_NOCHANGE,
-       NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
-};
-
-extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
-extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
-extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
-extern int nmk_gpio_get_mode(int gpio);
-
-extern void nmk_gpio_wakeups_suspend(void);
-extern void nmk_gpio_wakeups_resume(void);
-
-extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
-
-/*
- * Platform data to register a block: only the initial gpio/irq number.
- */
-struct nmk_gpio_platform_data {
-       char *name;
-       int first_gpio;
-       int first_irq;
-       int num_gpio;
-       u32 (*get_secondary_status)(unsigned int bank);
-       void (*set_ioforce)(bool enable);
-       bool supports_sleepmode;
-};
+#include <linux/kernel.h>
 
 #endif /* __ASM_PLAT_GPIO_H */
index 923c9621096b85f63e6e8c6ba2fa9909b3c06311..caa1f7b6cc2145995bedeaa321a77078869c3bf7 100644 (file)
@@ -8,7 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -18,7 +18,6 @@
 #include <mach/hardware.h>
 
 #include <plat/board.h>
-#include <mach/gpio.h>
 
 
 /* Many OMAP development platforms reuse the same "debug board"; these
index fc05b10226026e6b514adaa10199bf270cbba7f2..61a1ec2a6af4273e1c7693fdd4191ba3c92a0616 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
@@ -19,7 +19,6 @@
 #include <asm/mach-types.h>
 
 #include <plat/fpga.h>
-#include <mach/gpio.h>
 
 
 /* Many OMAP development platforms reuse the same "debug board"; these
index ea28f98d5d6a63da2ab5ede0327ec9188f5caf97..64c3bd4aa54ecbd43c9d4f6eeccaaf97fa0001e1 100644 (file)
@@ -8,7 +8,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -24,7 +24,6 @@
 #include <plat/tc.h>
 #include <plat/board.h>
 #include <plat/mmc.h>
-#include <mach/gpio.h>
 #include <plat/menelaus.h>
 #include <plat/mcbsp.h>
 #include <plat/omap44xx.h>
index 91e8de3db085d195be80690fbb5139149d7040f6..9e86ee0aed0a05fb5ad448d144a84a93e21e5d53 100644 (file)
@@ -222,26 +222,6 @@ extern void omap_gpio_restore_context(void);
 #include <linux/errno.h>
 #include <asm-generic/gpio.h>
 
-static inline int gpio_get_value(unsigned gpio)
-{
-       return __gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-       __gpio_set_value(gpio, value);
-}
-
-static inline int gpio_cansleep(unsigned gpio)
-{
-       return __gpio_cansleep(gpio);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
-       return __gpio_to_irq(gpio);
-}
-
 static inline int irq_to_gpio(unsigned irq)
 {
        int tmp;
index 3075b9fdde831fc314522ca4636a9d4b99227b67..f7d76308603f541bab6b9274665f44c1c0fc06e8 100644 (file)
 #define __PLAT_GPIO_H
 
 #include <linux/init.h>
-#include <asm-generic/gpio.h>
-
-/*
- * GENERIC_GPIO primitives.
- */
-#define gpio_get_value  __gpio_get_value
-#define gpio_set_value  __gpio_set_value
-#define gpio_cansleep   __gpio_cansleep
-#define gpio_to_irq     __gpio_to_irq
 
 /*
  * Orion-specific GPIO API extensions.
index a11dc36705051956d992e30085f41e12dd5f68d7..5d6a86bfc68da67c6909583acfb4de9724868414 100644 (file)
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/syscore_ops.h>
 #include <linux/slab.h>
 
-#include <mach/gpio.h>
-
 int pxa_last_gpio;
 
 struct pxa_gpio_chip {
index 1ddd2b97a72995d90107cb05d0658b1c035236f5..6fc41db93e1c39669354bd591ae62a423229df77 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __PLAT_GPIO_H
 #define __PLAT_GPIO_H
 
+#define __ARM_GPIOLIB_COMPLEX
+
 struct irq_data;
 
 /*
index 442301fe48b4176d3403de8f535837317ec7213d..c42f39f20195374bf6f0f046b487bd8e8c4511a6 100644 (file)
@@ -41,6 +41,19 @@ struct pxa3xx_nand_flash {
        struct pxa3xx_nand_timing *timing;      /* NAND Flash timing */
 };
 
+/*
+ * Current pxa3xx_nand controller has two chip select which
+ * both be workable.
+ *
+ * Notice should be taken that:
+ * When you want to use this feature, you should not enable the
+ * keep configuration feature, for two chip select could be
+ * attached with different nand chip. The different page size
+ * and timing requirement make the keep configuration impossible.
+ */
+
+/* The max num of chip select current support */
+#define NUM_CHIP_SELECT                (2)
 struct pxa3xx_nand_platform_data {
 
        /* the data flash bus is shared between the Static Memory
@@ -52,8 +65,11 @@ struct pxa3xx_nand_platform_data {
        /* allow platform code to keep OBM/bootloader defined NFC config */
        int     keep_config;
 
-       const struct mtd_partition              *parts;
-       unsigned int                            nr_parts;
+       /* indicate how many chip selects will be used */
+       int     num_cs;
+
+       const struct mtd_partition              *parts[NUM_CHIP_SELECT];
+       unsigned int                            nr_parts[NUM_CHIP_SELECT];
 
        const struct pxa3xx_nand_flash *        flash;
        size_t                                  num_flash;
index 02af235298e2e1ff4f1e850afe3b67f0b43f9856..5f84a3f13ef9bb042eae6b85e96903ccdb2600a3 100644 (file)
@@ -192,7 +192,7 @@ unsigned long s5p_spdif_get_rate(struct clk *clk)
        if (IS_ERR(pclk))
                return -EINVAL;
 
-       rate = pclk->ops->get_rate(clk);
+       rate = pclk->ops->get_rate(pclk);
        clk_put(pclk);
 
        return rate;
index 327ab9f662e8bca3019489817bb649b0eff68389..f71078ef6bb55ca840afdc33ef0a7befef4cdafc 100644 (file)
@@ -23,6 +23,8 @@
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 
+#include <asm/mach/irq.h>
+
 #define GPIO_BASE(chip)                (((unsigned long)(chip)->base) & 0xFFFFF000u)
 
 #define CON_OFFSET             0x700
@@ -81,6 +83,9 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
        int group, pend_offset, mask_offset;
        unsigned int pend, mask;
 
+       struct irq_chip *chip = irq_get_chip(irq);
+       chained_irq_enter(chip, desc);
+
        for (group = 0; group < bank->nr_groups; group++) {
                struct s3c_gpio_chip *chip = bank->chips[group];
                if (!chip)
@@ -102,6 +107,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
                        pend &= ~BIT(offset);
                }
        }
+       chained_irq_exit(chip, desc);
 }
 
 static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
index db7a65c7f127a62b93ee78ba450c6d3bbaec69a8..06825c4276de41fe3fbb08524764a053f9c7705c 100644 (file)
@@ -58,22 +58,5 @@ struct platform_device s3c_device_hsmmc0 = {
 
 void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
 {
-       struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
-
-       set->cd_type = pd->cd_type;
-       set->ext_cd_init = pd->ext_cd_init;
-       set->ext_cd_cleanup = pd->ext_cd_cleanup;
-       set->ext_cd_gpio = pd->ext_cd_gpio;
-       set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-       if (pd->max_width)
-               set->max_width = pd->max_width;
-       if (pd->cfg_gpio)
-               set->cfg_gpio = pd->cfg_gpio;
-       if (pd->cfg_card)
-               set->cfg_card = pd->cfg_card;
-       if (pd->host_caps)
-               set->host_caps |= pd->host_caps;
-       if (pd->clk_type)
-               set->clk_type = pd->clk_type;
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
 }
index 2497321f08d7ddc3a17fb3e9eedb6293cbb6df97..4524ef4400105587a5edbc07861be46c66fa0778 100644 (file)
@@ -58,22 +58,5 @@ struct platform_device s3c_device_hsmmc1 = {
 
 void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
 {
-       struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
-
-       set->cd_type = pd->cd_type;
-       set->ext_cd_init = pd->ext_cd_init;
-       set->ext_cd_cleanup = pd->ext_cd_cleanup;
-       set->ext_cd_gpio = pd->ext_cd_gpio;
-       set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-       if (pd->max_width)
-               set->max_width = pd->max_width;
-       if (pd->cfg_gpio)
-               set->cfg_gpio = pd->cfg_gpio;
-       if (pd->cfg_card)
-               set->cfg_card = pd->cfg_card;
-       if (pd->host_caps)
-               set->host_caps |= pd->host_caps;
-       if (pd->clk_type)
-               set->clk_type = pd->clk_type;
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
 }
index f60aedba417cdaea81c7d53763359a9bf0871660..9cede9615e48af943f9c5e874fdb44347aea23d3 100644 (file)
@@ -59,22 +59,5 @@ struct platform_device s3c_device_hsmmc2 = {
 
 void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
 {
-       struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
-
-       set->cd_type = pd->cd_type;
-       set->ext_cd_init = pd->ext_cd_init;
-       set->ext_cd_cleanup = pd->ext_cd_cleanup;
-       set->ext_cd_gpio = pd->ext_cd_gpio;
-       set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-       if (pd->max_width)
-               set->max_width = pd->max_width;
-       if (pd->cfg_gpio)
-               set->cfg_gpio = pd->cfg_gpio;
-       if (pd->cfg_card)
-               set->cfg_card = pd->cfg_card;
-       if (pd->host_caps)
-               set->host_caps |= pd->host_caps;
-       if (pd->clk_type)
-               set->clk_type = pd->clk_type;
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
 }
index ede776f20e62eb6d42f29fe768f50db2c4b20202..0358ef4a8f6607a05687ba85b4760ea0f48ec6b2 100644 (file)
@@ -62,22 +62,5 @@ struct platform_device s3c_device_hsmmc3 = {
 
 void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
 {
-       struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
-
-       set->cd_type = pd->cd_type;
-       set->ext_cd_init = pd->ext_cd_init;
-       set->ext_cd_cleanup = pd->ext_cd_cleanup;
-       set->ext_cd_gpio = pd->ext_cd_gpio;
-       set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-       if (pd->max_width)
-               set->max_width = pd->max_width;
-       if (pd->cfg_gpio)
-               set->cfg_gpio = pd->cfg_gpio;
-       if (pd->cfg_card)
-               set->cfg_card = pd->cfg_card;
-       if (pd->host_caps)
-               set->host_caps |= pd->host_caps;
-       if (pd->clk_type)
-               set->clk_type = pd->clk_type;
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
 }
index 82543f0248ac38ae4f50bfb7b5a102659cf8952f..5f3d46a9bd88d032eba5c63a517e5f60895db014 100644 (file)
@@ -43,8 +43,17 @@ struct platform_device s3c_device_ts = {
        .resource       = s3c_ts_resource,
 };
 
+static struct s3c2410_ts_mach_info default_ts_data __initdata = {
+       .delay                  = 10000,
+       .presc                  = 49,
+       .oversampling_shift     = 2,
+};
+
 void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
 {
+       if (!pd)
+               pd = &default_ts_data;
+
        s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
                         &s3c_device_ts);
 }
index 51d8da846a629281c77ff29c78018185d049bf03..ad530c78fe8c3563535a5c682a76125eb1571ffc 100644 (file)
@@ -20,7 +20,7 @@ struct samsung_bl_gpio_info {
        int func;
 };
 
-extern void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
        struct platform_pwm_backlight_data *bl_data);
 
 #endif /* __ASM_PLAT_BACKLIGHT_H */
index 336d5ac02035b219c9f008e433a8176899f4858d..ab9bce637cbdfeb8de93e10014cd0f57b722b2ba 100644 (file)
@@ -18,11 +18,6 @@ extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
 #define DMA_CH_VALID           (1<<31)
 #define DMA_CH_NEVER           (1<<30)
 
-struct s3c24xx_dma_addr {
-       unsigned long           from;
-       unsigned long           to;
-};
-
 /* struct s3c24xx_dma_map
  *
  * this holds the mapping information for the channel selected
@@ -31,7 +26,6 @@ struct s3c24xx_dma_addr {
 
 struct s3c24xx_dma_map {
        const char              *name;
-       struct s3c24xx_dma_addr  hw_addr;
 
        unsigned long            channels[S3C_DMA_CHANNELS];
        unsigned long            channels_rx[S3C_DMA_CHANNELS];
index 058e09654fe80bbc8112e4d47901aa273aae38fb..4a6552066c7ef1ee71b92620dab90ecdc9f65847 100644 (file)
@@ -86,6 +86,13 @@ struct s3c_sdhci_platdata {
                            struct mmc_card *card);
 };
 
+/* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data
+ * @pd: The default platform data for this device.
+ * @set: Pointer to the platform data to fill in.
+ */
+extern void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
+                                   struct s3c_sdhci_platdata *set);
+
 /**
  * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
  * @pd: Platform data to register to device.
index f714d060370d6f1647e29e2367591dafa242b4b6..51583cd301645483f110622ef2fc8dff362bf90d 100644 (file)
 #include <plat/irq-vic-timer.h>
 #include <plat/regs-timer.h>
 
+#include <asm/mach/irq.h>
+
 static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
 {
+       struct irq_chip *chip = irq_get_chip(irq);
+       chained_irq_enter(chip, desc);
        generic_handle_irq((int)desc->irq_data.handler_data);
+       chained_irq_exit(chip, desc);
 }
 
 /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
index 7cf2e1e3b20f87a30805ac49d46c3f50e93a2157..6de1a38259276de08a0b1dbe9835801fb5affba8 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 
 #include <plat/devs.h>
+#include <plat/sdhci.h>
 
 void __init *s3c_set_platdata(void *pd, size_t pdsize,
                              struct platform_device *pdev)
@@ -35,3 +36,24 @@ void __init *s3c_set_platdata(void *pd, size_t pdsize,
        pdev->dev.platform_data = npd;
        return npd;
 }
+
+void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
+                            struct s3c_sdhci_platdata *set)
+{
+       set->cd_type = pd->cd_type;
+       set->ext_cd_init = pd->ext_cd_init;
+       set->ext_cd_cleanup = pd->ext_cd_cleanup;
+       set->ext_cd_gpio = pd->ext_cd_gpio;
+       set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+
+       if (pd->max_width)
+               set->max_width = pd->max_width;
+       if (pd->cfg_gpio)
+               set->cfg_gpio = pd->cfg_gpio;
+       if (pd->cfg_card)
+               set->cfg_card = pd->cfg_card;
+       if (pd->host_caps)
+               set->host_caps |= pd->host_caps;
+       if (pd->clk_type)
+               set->clk_type = pd->clk_type;
+}
index b857c91257dde3c885c1b3bf1d813b0ae4adf961..40a8c178f10d9e85a2873c83247c3f2fe553f408 100644 (file)
@@ -1,24 +1 @@
-/*
- * arch/arm/plat-spear/include/plat/gpio.h
- *
- * GPIO macros for SPEAr platform
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_GPIO_H
-#define __PLAT_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep  __gpio_cansleep
-#define gpio_to_irq    __gpio_to_irq
-
-#endif /* __PLAT_GPIO_H */
+/* empty */
index fff68d0d521b095f0594fbf79bda99df8c3f21e4..f9bd7c5187503a639752fd7ae3ac435a809ee89d 100644 (file)
@@ -17,7 +17,7 @@
 # XXX: the last 12 months.  If your entry is missing please email rmk at
 # XXX: <linux@arm.linux.org.uk>
 #
-# Last update: Sat May 7 08:48:24 2011
+# Last update: Fri Aug 19 08:51:33 2011
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -65,6 +65,7 @@ h7201                 ARCH_H7201              H7201                   161
 h7202                  ARCH_H7202              H7202                   162
 iq80321                        ARCH_IQ80321            IQ80321                 169
 ks8695                 ARCH_KS8695             KS8695                  180
+karo                   ARCH_KARO               KARO                    190
 smdk2410               ARCH_SMDK2410           SMDK2410                193
 ceiva                  ARCH_CEIVA              CEIVA                   200
 voiceblue              MACH_VOICEBLUE          VOICEBLUE               218
@@ -188,6 +189,7 @@ omap_2430sdp                MACH_OMAP_2430SDP       OMAP_2430SDP            900
 davinci_evm            MACH_DAVINCI_EVM        DAVINCI_EVM             901
 palmz72                        MACH_PALMZ72            PALMZ72                 904
 nxdb500                        MACH_NXDB500            NXDB500                 905
+apf9328                        MACH_APF9328            APF9328                 906
 palmt5                 MACH_PALMT5             PALMT5                  917
 palmtc                 MACH_PALMTC             PALMTC                  918
 omap_apollon           MACH_OMAP_APOLLON       OMAP_APOLLON            919
@@ -268,7 +270,6 @@ dns323                      MACH_DNS323             DNS323                  1542
 omap3_beagle           MACH_OMAP3_BEAGLE       OMAP3_BEAGLE            1546
 nokia_n810             MACH_NOKIA_N810         NOKIA_N810              1548
 pcm038                 MACH_PCM038             PCM038                  1551
-ts_x09                 MACH_TS209              TS209                   1565
 at91cap9adk            MACH_AT91CAP9ADK        AT91CAP9ADK             1566
 mx31moboard            MACH_MX31MOBOARD        MX31MOBOARD             1574
 terastation_pro2       MACH_TERASTATION_PRO2   TERASTATION_PRO2        1584
@@ -318,7 +319,6 @@ lb88rc8480          MACH_LB88RC8480         LB88RC8480              1769
 mx25_3ds               MACH_MX25_3DS           MX25_3DS                1771
 omap3530_lv_som                MACH_OMAP3530_LV_SOM    OMAP3530_LV_SOM         1773
 davinci_da830_evm      MACH_DAVINCI_DA830_EVM  DAVINCI_DA830_EVM       1781
-at572d940hfek          MACH_AT572D940HFEB      AT572D940HFEB           1783
 dove_db                        MACH_DOVE_DB            DOVE_DB                 1788
 overo                  MACH_OVERO              OVERO                   1798
 at2440evb              MACH_AT2440EVB          AT2440EVB               1799
@@ -351,7 +351,6 @@ centro                      MACH_CENTRO             CENTRO                  1944
 nokia_rx51             MACH_NOKIA_RX51         NOKIA_RX51              1955
 omap_zoom2             MACH_OMAP_ZOOM2         OMAP_ZOOM2              1967
 cpuat9260              MACH_CPUAT9260          CPUAT9260               1973
-eukrea_cpuimx27                MACH_CPUIMX27           CPUIMX27                1975
 acs5k                  MACH_ACS5K              ACS5K                   1982
 snapper_9260           MACH_SNAPPER_9260       SNAPPER_9260            1987
 dsm320                 MACH_DSM320             DSM320                  1988
@@ -369,6 +368,7 @@ pcm043                      MACH_PCM043             PCM043                  2072
 sheevaplug             MACH_SHEEVAPLUG         SHEEVAPLUG              2097
 avengers_lite          MACH_AVENGERS_LITE      AVENGERS_LITE           2104
 mx51_babbage           MACH_MX51_BABBAGE       MX51_BABBAGE            2125
+tx37                   MACH_TX37               TX37                    2127
 rd78x00_masa           MACH_RD78X00_MASA       RD78X00_MASA            2135
 dm355_leopard          MACH_DM355_LEOPARD      DM355_LEOPARD           2138
 ts219                  MACH_TS219              TS219                   2139
@@ -379,6 +379,7 @@ omap_4430sdp                MACH_OMAP_4430SDP       OMAP_4430SDP            2160
 magx_zn5               MACH_MAGX_ZN5           MAGX_ZN5                2162
 btmavb101              MACH_BTMAVB101          BTMAVB101               2172
 btmawb101              MACH_BTMAWB101          BTMAWB101               2173
+tx25                   MACH_TX25               TX25                    2177
 omap3_torpedo          MACH_OMAP3_TORPEDO      OMAP3_TORPEDO           2178
 anw6410                        MACH_ANW6410            ANW6410                 2183
 imx27_visstrim_m10     MACH_IMX27_VISSTRIM_M10 IMX27_VISSTRIM_M10      2187
@@ -423,6 +424,7 @@ raumfeld_rc         MACH_RAUMFELD_RC        RAUMFELD_RC             2413
 raumfeld_connector     MACH_RAUMFELD_CONNECTOR RAUMFELD_CONNECTOR      2414
 raumfeld_speaker       MACH_RAUMFELD_SPEAKER   RAUMFELD_SPEAKER        2415
 tnetv107x              MACH_TNETV107X          TNETV107X               2418
+mx51_m2id              MACH_MX51_M2ID          MX51_M2ID               2428
 smdkv210               MACH_SMDKV210           SMDKV210                2456
 omap_zoom3             MACH_OMAP_ZOOM3         OMAP_ZOOM3              2464
 omap_3630sdp           MACH_OMAP_3630SDP       OMAP_3630SDP            2465
@@ -433,6 +435,7 @@ omapl138_hawkboard  MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD      2495
 ts41x                  MACH_TS41X              TS41X                   2502
 phy3250                        MACH_PHY3250            PHY3250                 2511
 mini6410               MACH_MINI6410           MINI6410                2520
+tx51                   MACH_TX51               TX51                    2529
 mx28evk                        MACH_MX28EVK            MX28EVK                 2531
 smartq5                        MACH_SMARTQ5            SMARTQ5                 2534
 davinci_dm6467tevm     MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM      2548
@@ -441,6 +444,7 @@ riot_bei2           MACH_RIOT_BEI2          RIOT_BEI2               2576
 riot_x37               MACH_RIOT_X37           RIOT_X37                2578
 capc7117               MACH_CAPC7117           CAPC7117                2612
 icontrol               MACH_ICONTROL           ICONTROL                2624
+gplugd                 MACH_GPLUGD             GPLUGD                  2625
 qsd8x50a_st1_5         MACH_QSD8X50A_ST1_5     QSD8X50A_ST1_5          2627
 mx23evk                        MACH_MX23EVK            MX23EVK                 2629
 ap4evb                 MACH_AP4EVB             AP4EVB                  2630
@@ -449,7 +453,6 @@ guruplug            MACH_GURUPLUG           GURUPLUG                2659
 spear310               MACH_SPEAR310           SPEAR310                2660
 spear320               MACH_SPEAR320           SPEAR320                2661
 aquila                 MACH_AQUILA             AQUILA                  2676
-sheeva_esata           MACH_ESATA_SHEEVAPLUG   ESATA_SHEEVAPLUG        2678
 msm7x30_surf           MACH_MSM7X30_SURF       MSM7X30_SURF            2679
 ea2478devkit           MACH_EA2478DEVKIT       EA2478DEVKIT            2683
 terastation_wxl                MACH_TERASTATION_WXL    TERASTATION_WXL         2697
@@ -476,198 +479,36 @@ cns3420vb                MACH_CNS3420VB          CNS3420VB               2776
 omap4_panda            MACH_OMAP4_PANDA        OMAP4_PANDA             2791
 ti8168evm              MACH_TI8168EVM          TI8168EVM               2800
 teton_bga              MACH_TETON_BGA          TETON_BGA               2816
-eukrea_cpuimx25sd      MACH_EUKREA_CPUIMX25    EUKREA_CPUIMX25         2820
-eukrea_cpuimx35sd      MACH_EUKREA_CPUIMX35    EUKREA_CPUIMX35         2821
 eukrea_cpuimx51sd      MACH_EUKREA_CPUIMX51SD  EUKREA_CPUIMX51SD       2822
 eukrea_cpuimx51                MACH_EUKREA_CPUIMX51    EUKREA_CPUIMX51         2823
 smdkc210               MACH_SMDKC210           SMDKC210                2838
-omap3_braillo          MACH_OMAP3_BRAILLO      OMAP3_BRAILLO           2839
-spyplug                        MACH_SPYPLUG            SPYPLUG                 2840
-ginger                 MACH_GINGER             GINGER                  2841
-tny_t3530              MACH_TNY_T3530          TNY_T3530               2842
-pca102                 MACH_PCA102             PCA102                  2843
-spade                  MACH_SPADE              SPADE                   2844
-mxc25_topaz            MACH_MXC25_TOPAZ        MXC25_TOPAZ             2845
 t5325                  MACH_T5325              T5325                   2846
-gw2361                 MACH_GW2361             GW2361                  2847
-elog                   MACH_ELOG               ELOG                    2848
 income                 MACH_INCOME             INCOME                  2849
-bcm589x                        MACH_BCM589X            BCM589X                 2850
-etna                   MACH_ETNA               ETNA                    2851
-hawks                  MACH_HAWKS              HAWKS                   2852
-meson                  MACH_MESON              MESON                   2853
-xsbase255              MACH_XSBASE255          XSBASE255               2854
-pvm2030                        MACH_PVM2030            PVM2030                 2855
-mioa502                        MACH_MIOA502            MIOA502                 2856
 vvbox_sdorig2          MACH_VVBOX_SDORIG2      VVBOX_SDORIG2           2857
 vvbox_sdlite2          MACH_VVBOX_SDLITE2      VVBOX_SDLITE2           2858
 vvbox_sdpro4           MACH_VVBOX_SDPRO4       VVBOX_SDPRO4            2859
-htc_spv_m700           MACH_HTC_SPV_M700       HTC_SPV_M700            2860
 mx257sx                        MACH_MX257SX            MX257SX                 2861
 goni                   MACH_GONI               GONI                    2862
-msm8x55_svlte_ffa      MACH_MSM8X55_SVLTE_FFA  MSM8X55_SVLTE_FFA       2863
-msm8x55_svlte_surf     MACH_MSM8X55_SVLTE_SURF MSM8X55_SVLTE_SURF      2864
-quickstep              MACH_QUICKSTEP          QUICKSTEP               2865
-dmw96                  MACH_DMW96              DMW96                   2866
-hammerhead             MACH_HAMMERHEAD         HAMMERHEAD              2867
-trident                        MACH_TRIDENT            TRIDENT                 2868
-lightning              MACH_LIGHTNING          LIGHTNING               2869
-iconnect               MACH_ICONNECT           ICONNECT                2870
-autobot                        MACH_AUTOBOT            AUTOBOT                 2871
-coconut                        MACH_COCONUT            COCONUT                 2872
-durian                 MACH_DURIAN             DURIAN                  2873
-cayenne                        MACH_CAYENNE            CAYENNE                 2874
-fuji                   MACH_FUJI               FUJI                    2875
-synology_6282          MACH_SYNOLOGY_6282      SYNOLOGY_6282           2876
-em1sy                  MACH_EM1SY              EM1SY                   2877
-m502                   MACH_M502               M502                    2878
-matrix518              MACH_MATRIX518          MATRIX518               2879
-tiny_gurnard           MACH_TINY_GURNARD       TINY_GURNARD            2880
-spear1310              MACH_SPEAR1310          SPEAR1310               2881
 bv07                   MACH_BV07               BV07                    2882
-mxt_td61               MACH_MXT_TD61           MXT_TD61                2883
 openrd_ultimate                MACH_OPENRD_ULTIMATE    OPENRD_ULTIMATE         2884
-devixp                 MACH_DEVIXP             DEVIXP                  2885
-miccpt                 MACH_MICCPT             MICCPT                  2886
-mic256                 MACH_MIC256             MIC256                  2887
-as1167                 MACH_AS1167             AS1167                  2888
-omap3_ibiza            MACH_OMAP3_IBIZA        OMAP3_IBIZA             2889
 u5500                  MACH_U5500              U5500                   2890
-davinci_picto          MACH_DAVINCI_PICTO      DAVINCI_PICTO           2891
-mecha                  MACH_MECHA              MECHA                   2892
-bubba3                 MACH_BUBBA3             BUBBA3                  2893
-pupitre                        MACH_PUPITRE            PUPITRE                 2894
-tegra_vogue            MACH_TEGRA_VOGUE        TEGRA_VOGUE             2896
-tegra_e1165            MACH_TEGRA_E1165        TEGRA_E1165             2897
-simplenet              MACH_SIMPLENET          SIMPLENET               2898
-ec4350tbm              MACH_EC4350TBM          EC4350TBM               2899
-pec_tc                 MACH_PEC_TC             PEC_TC                  2900
-pec_hc2                        MACH_PEC_HC2            PEC_HC2                 2901
-esl_mobilis_a          MACH_ESL_MOBILIS_A      ESL_MOBILIS_A           2902
-esl_mobilis_b          MACH_ESL_MOBILIS_B      ESL_MOBILIS_B           2903
-esl_wave_a             MACH_ESL_WAVE_A         ESL_WAVE_A              2904
-esl_wave_b             MACH_ESL_WAVE_B         ESL_WAVE_B              2905
-unisense_mmm           MACH_UNISENSE_MMM       UNISENSE_MMM            2906
-blueshark              MACH_BLUESHARK          BLUESHARK               2907
-e10                    MACH_E10                E10                     2908
-app3k_robin            MACH_APP3K_ROBIN        APP3K_ROBIN             2909
-pov15hd                        MACH_POV15HD            POV15HD                 2910
-stella                 MACH_STELLA             STELLA                  2911
 linkstation_lschl      MACH_LINKSTATION_LSCHL  LINKSTATION_LSCHL       2913
-netwalker              MACH_NETWALKER          NETWALKER               2914
-acsx106                        MACH_ACSX106            ACSX106                 2915
-atlas5_c1              MACH_ATLAS5_C1          ATLAS5_C1               2916
-nsb3ast                        MACH_NSB3AST            NSB3AST                 2917
-gnet_slc               MACH_GNET_SLC           GNET_SLC                2918
-af4000                 MACH_AF4000             AF4000                  2919
-ark9431                        MACH_ARK9431            ARK9431                 2920
-fs_s5pc100             MACH_FS_S5PC100         FS_S5PC100              2921
-omap3505nova8          MACH_OMAP3505NOVA8      OMAP3505NOVA8           2922
-omap3621_edp1          MACH_OMAP3621_EDP1      OMAP3621_EDP1           2923
-oratisaes              MACH_ORATISAES          ORATISAES               2924
 smdkv310               MACH_SMDKV310           SMDKV310                2925
-siemens_l0             MACH_SIEMENS_L0         SIEMENS_L0              2926
-ventana                        MACH_VENTANA            VENTANA                 2927
 wm8505_7in_netbook     MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK      2928
-ec4350sdb              MACH_EC4350SDB          EC4350SDB               2929
-mimas                  MACH_MIMAS              MIMAS                   2930
-titan                  MACH_TITAN              TITAN                   2931
 craneboard             MACH_CRANEBOARD         CRANEBOARD              2932
-es2440                 MACH_ES2440             ES2440                  2933
-najay_a9263            MACH_NAJAY_A9263        NAJAY_A9263             2934
-htctornado             MACH_HTCTORNADO         HTCTORNADO              2935
-dimm_mx257             MACH_DIMM_MX257         DIMM_MX257              2936
-jigen301               MACH_JIGEN              JIGEN                   2937
 smdk6450               MACH_SMDK6450           SMDK6450                2938
-meno_qng               MACH_MENO_QNG           MENO_QNG                2939
-ns2416                 MACH_NS2416             NS2416                  2940
-rpc353                 MACH_RPC353             RPC353                  2941
-tq6410                 MACH_TQ6410             TQ6410                  2942
-sky6410                        MACH_SKY6410            SKY6410                 2943
-dynasty                        MACH_DYNASTY            DYNASTY                 2944
-vivo                   MACH_VIVO               VIVO                    2945
-bury_bl7582            MACH_BURY_BL7582        BURY_BL7582             2946
-bury_bps5270           MACH_BURY_BPS5270       BURY_BPS5270            2947
-basi                   MACH_BASI               BASI                    2948
-tn200                  MACH_TN200              TN200                   2949
-c2mmi                  MACH_C2MMI              C2MMI                   2950
-meson_6236m            MACH_MESON_6236M        MESON_6236M             2951
-meson_8626m            MACH_MESON_8626M        MESON_8626M             2952
-tube                   MACH_TUBE               TUBE                    2953
-messina                        MACH_MESSINA            MESSINA                 2954
-mx50_arm2              MACH_MX50_ARM2          MX50_ARM2               2955
-cetus9263              MACH_CETUS9263          CETUS9263               2956
 brownstone             MACH_BROWNSTONE         BROWNSTONE              2957
-vmx25                  MACH_VMX25              VMX25                   2958
-vmx51                  MACH_VMX51              VMX51                   2959
-abacus                 MACH_ABACUS             ABACUS                  2960
-cm4745                 MACH_CM4745             CM4745                  2961
-oratislink             MACH_ORATISLINK         ORATISLINK              2962
-davinci_dm365_dvr      MACH_DAVINCI_DM365_DVR  DAVINCI_DM365_DVR       2963
-netviz                 MACH_NETVIZ             NETVIZ                  2964
 flexibity              MACH_FLEXIBITY          FLEXIBITY               2965
-wlan_computer          MACH_WLAN_COMPUTER      WLAN_COMPUTER           2966
-lpc24xx                        MACH_LPC24XX            LPC24XX                 2967
-spica                  MACH_SPICA              SPICA                   2968
-gpsdisplay             MACH_GPSDISPLAY         GPSDISPLAY              2969
-bipnet                 MACH_BIPNET             BIPNET                  2970
-overo_ctu_inertial     MACH_OVERO_CTU_INERTIAL OVERO_CTU_INERTIAL      2971
-davinci_dm355_mmm      MACH_DAVINCI_DM355_MMM  DAVINCI_DM355_MMM       2972
-pc9260_v2              MACH_PC9260_V2          PC9260_V2               2973
-ptx7545                        MACH_PTX7545            PTX7545                 2974
-tm_efdc                        MACH_TM_EFDC            TM_EFDC                 2975
-omap3_waldo1           MACH_OMAP3_WALDO1       OMAP3_WALDO1            2977
-flyer                  MACH_FLYER              FLYER                   2978
-tornado3240            MACH_TORNADO3240        TORNADO3240             2979
-soli_01                        MACH_SOLI_01            SOLI_01                 2980
-omapl138_europalc      MACH_OMAPL138_EUROPALC  OMAPL138_EUROPALC       2981
-helios_v1              MACH_HELIOS_V1          HELIOS_V1               2982
-netspace_lite_v2       MACH_NETSPACE_LITE_V2   NETSPACE_LITE_V2        2983
-ssc                    MACH_SSC                SSC                     2984
-premierwave_en         MACH_PREMIERWAVE_EN     PREMIERWAVE_EN          2985
-wasabi                 MACH_WASABI             WASABI                  2986
 mx50_rdp               MACH_MX50_RDP           MX50_RDP                2988
 universal_c210         MACH_UNIVERSAL_C210     UNIVERSAL_C210          2989
 real6410               MACH_REAL6410           REAL6410                2990
-spx_sakura             MACH_SPX_SAKURA         SPX_SAKURA              2991
-ij3k_2440              MACH_IJ3K_2440          IJ3K_2440               2992
-omap3_bc10             MACH_OMAP3_BC10         OMAP3_BC10              2993
-thebe                  MACH_THEBE              THEBE                   2994
-rv082                  MACH_RV082              RV082                   2995
-armlguest              MACH_ARMLGUEST          ARMLGUEST               2996
-tjinc1000              MACH_TJINC1000          TJINC1000               2997
 dockstar               MACH_DOCKSTAR           DOCKSTAR                2998
-ax8008                 MACH_AX8008             AX8008                  2999
-gnet_sgce              MACH_GNET_SGCE          GNET_SGCE               3000
-pxwnas_500_1000                MACH_PXWNAS_500_1000    PXWNAS_500_1000         3001
-ea20                   MACH_EA20               EA20                    3002
-awm2                   MACH_AWM2               AWM2                    3003
-ti8148evm              MACH_TI8148EVM          TI8148EVM               3004
 seaboard               MACH_SEABOARD           SEABOARD                3005
-linkstation_chlv2      MACH_LINKSTATION_CHLV2  LINKSTATION_CHLV2       3006
-tera_pro2_rack         MACH_TERA_PRO2_RACK     TERA_PRO2_RACK          3007
-rubys                  MACH_RUBYS              RUBYS                   3008
-aquarius               MACH_AQUARIUS           AQUARIUS                3009
 mx53_ard               MACH_MX53_ARD           MX53_ARD                3010
 mx53_smd               MACH_MX53_SMD           MX53_SMD                3011
-lswxl                  MACH_LSWXL              LSWXL                   3012
-dove_avng_v3           MACH_DOVE_AVNG_V3       DOVE_AVNG_V3            3013
-sdi_ess_9263           MACH_SDI_ESS_9263       SDI_ESS_9263            3014
-jocpu550               MACH_JOCPU550           JOCPU550                3015
 msm8x60_rumi3          MACH_MSM8X60_RUMI3      MSM8X60_RUMI3           3016
 msm8x60_ffa            MACH_MSM8X60_FFA        MSM8X60_FFA             3017
-yanomami               MACH_YANOMAMI           YANOMAMI                3018
-gta04                  MACH_GTA04              GTA04                   3019
 cm_a510                        MACH_CM_A510            CM_A510                 3020
-omap3_rfs200           MACH_OMAP3_RFS200       OMAP3_RFS200            3021
-kx33xx                 MACH_KX33XX             KX33XX                  3022
-ptx7510                        MACH_PTX7510            PTX7510                 3023
-top9000                        MACH_TOP9000            TOP9000                 3024
-teenote                        MACH_TEENOTE            TEENOTE                 3025
-ts3                    MACH_TS3                TS3                     3026
-a0                     MACH_A0                 A0                      3027
-fsm9xxx_surf           MACH_FSM9XXX_SURF       FSM9XXX_SURF            3028
-fsm9xxx_ffa            MACH_FSM9XXX_FFA        FSM9XXX_FFA             3029
 frrhwcdma60w           MACH_FRRHWCDMA60W       FRRHWCDMA60W            3030
 remus                  MACH_REMUS              REMUS                   3031
 at91cap7xdk            MACH_AT91CAP7XDK        AT91CAP7XDK             3032
@@ -823,7 +664,6 @@ mmm                 MACH_MMM                MMM                     3187
 davinci_dm365_bv       MACH_DAVINCI_DM365_BV   DAVINCI_DM365_BV        3188
 ag5evm                 MACH_AG5EVM             AG5EVM                  3189
 sc575plc               MACH_SC575PLC           SC575PLC                3190
-sc575hmi               MACH_SC575IPC           SC575IPC                3191
 omap3_tdm3730          MACH_OMAP3_TDM3730      OMAP3_TDM3730           3192
 top9000_eval           MACH_TOP9000_EVAL       TOP9000_EVAL            3194
 top9000_su             MACH_TOP9000_SU         TOP9000_SU              3195
@@ -939,13 +779,11 @@ koi                       MACH_KOI                KOI                     3312
 ts4800                 MACH_TS4800             TS4800                  3313
 tqma9263               MACH_TQMA9263           TQMA9263                3314
 holiday                        MACH_HOLIDAY            HOLIDAY                 3315
-dma_6410               MACH_DMA6410            DMA6410                 3316
 pcats_overlay          MACH_PCATS_OVERLAY      PCATS_OVERLAY           3317
 hwgw6410               MACH_HWGW6410           HWGW6410                3318
 shenzhou               MACH_SHENZHOU           SHENZHOU                3319
 cwme9210               MACH_CWME9210           CWME9210                3320
 cwme9210js             MACH_CWME9210JS         CWME9210JS              3321
-pgs_v1                 MACH_PGS_SITARA         PGS_SITARA              3322
 colibri_tegra2         MACH_COLIBRI_TEGRA2     COLIBRI_TEGRA2          3323
 w21                    MACH_W21                W21                     3324
 polysat1               MACH_POLYSAT1           POLYSAT1                3325
@@ -1011,13 +849,11 @@ viprinet         MACH_VIPRINET           VIPRINET                3385
 bockw                  MACH_BOCKW              BOCKW                   3386
 eva2000                        MACH_EVA2000            EVA2000                 3387
 steelyard              MACH_STEELYARD          STEELYARD               3388
-sdh001                 MACH_MACH_SDH001        MACH_SDH001             3390
 nsslsboard             MACH_NSSLSBOARD         NSSLSBOARD              3392
 geneva_b5              MACH_GENEVA_B5          GENEVA_B5               3393
 spear1340              MACH_SPEAR1340          SPEAR1340               3394
 rexmas                 MACH_REXMAS             REXMAS                  3395
 msm8960_cdp            MACH_MSM8960_CDP        MSM8960_CDP             3396
-msm8960_mdp            MACH_MSM8960_MDP        MSM8960_MDP             3397
 msm8960_fluid          MACH_MSM8960_FLUID      MSM8960_FLUID           3398
 msm8960_apq            MACH_MSM8960_APQ        MSM8960_APQ             3399
 helios_v2              MACH_HELIOS_V2          HELIOS_V2               3400
@@ -1113,3 +949,193 @@ blissc                   MACH_BLISSC             BLISSC                  3491
 thales_adc             MACH_THALES_ADC         THALES_ADC              3492
 ubisys_p9d_evp         MACH_UBISYS_P9D_EVP     UBISYS_P9D_EVP          3493
 atdgp318               MACH_ATDGP318           ATDGP318                3494
+dma210u                        MACH_DMA210U            DMA210U                 3495
+em_t3                  MACH_EM_T3              EM_T3                   3496
+htx3250                        MACH_HTX3250            HTX3250                 3497
+g50                    MACH_G50                G50                     3498
+eco5                   MACH_ECO5               ECO5                    3499
+wintergrasp            MACH_WINTERGRASP        WINTERGRASP             3500
+puro                   MACH_PURO               PURO                    3501
+shooter_k              MACH_SHOOTER_K          SHOOTER_K               3502
+nspire                 MACH_NSPIRE             NSPIRE                  3503
+mickxx                 MACH_MICKXX             MICKXX                  3504
+lxmb                   MACH_LXMB               LXMB                    3505
+adam                   MACH_ADAM               ADAM                    3507
+b1004                  MACH_B1004              B1004                   3508
+oboea                  MACH_OBOEA              OBOEA                   3509
+a1015                  MACH_A1015              A1015                   3510
+robin_vbdt30           MACH_ROBIN_VBDT30       ROBIN_VBDT30            3511
+tegra_enterprise       MACH_TEGRA_ENTERPRISE   TEGRA_ENTERPRISE        3512
+rfl108200_mk10         MACH_RFL108200_MK10     RFL108200_MK10          3513
+rfl108300_mk16         MACH_RFL108300_MK16     RFL108300_MK16          3514
+rover_v7               MACH_ROVER_V7           ROVER_V7                3515
+miphone                        MACH_MIPHONE            MIPHONE                 3516
+femtobts               MACH_FEMTOBTS           FEMTOBTS                3517
+monopoli               MACH_MONOPOLI           MONOPOLI                3518
+boss                   MACH_BOSS               BOSS                    3519
+davinci_dm368_vtam     MACH_DAVINCI_DM368_VTAM DAVINCI_DM368_VTAM      3520
+clcon                  MACH_CLCON              CLCON                   3521
+nokia_rm696            MACH_NOKIA_RM696        NOKIA_RM696             3522
+tahiti                 MACH_TAHITI             TAHITI                  3523
+fighter                        MACH_FIGHTER            FIGHTER                 3524
+sgh_i710               MACH_SGH_I710           SGH_I710                3525
+integreproscb          MACH_INTEGREPROSCB      INTEGREPROSCB           3526
+monza                  MACH_MONZA              MONZA                   3527
+calimain               MACH_CALIMAIN           CALIMAIN                3528
+mx6q_sabreauto         MACH_MX6Q_SABREAUTO     MX6Q_SABREAUTO          3529
+gma01x                 MACH_GMA01X             GMA01X                  3530
+sbc51                  MACH_SBC51              SBC51                   3531
+fit                    MACH_FIT                FIT                     3532
+steelhead              MACH_STEELHEAD          STEELHEAD               3533
+panther                        MACH_PANTHER            PANTHER                 3534
+msm8960_liquid         MACH_MSM8960_LIQUID     MSM8960_LIQUID          3535
+lexikonct              MACH_LEXIKONCT          LEXIKONCT               3536
+ns2816_stb             MACH_NS2816_STB         NS2816_STB              3537
+sei_mm2_lpc3250                MACH_SEI_MM2_LPC3250    SEI_MM2_LPC3250         3538
+cmimx53                        MACH_CMIMX53            CMIMX53                 3539
+sandwich               MACH_SANDWICH           SANDWICH                3540
+chief                  MACH_CHIEF              CHIEF                   3541
+pogo_e02               MACH_POGO_E02           POGO_E02                3542
+mikrap_x168            MACH_MIKRAP_X168        MIKRAP_X168             3543
+htcmozart              MACH_HTCMOZART          HTCMOZART               3544
+htcgold                        MACH_HTCGOLD            HTCGOLD                 3545
+mt72xx                 MACH_MT72XX             MT72XX                  3546
+mx51_ivy               MACH_MX51_IVY           MX51_IVY                3547
+mx51_lvd               MACH_MX51_LVD           MX51_LVD                3548
+omap3_wiser2           MACH_OMAP3_WISER2       OMAP3_WISER2            3549
+dreamplug              MACH_DREAMPLUG          DREAMPLUG               3550
+cobas_c_111            MACH_COBAS_C_111        COBAS_C_111             3551
+cobas_u_411            MACH_COBAS_U_411        COBAS_U_411             3552
+hssd                   MACH_HSSD               HSSD                    3553
+iom35x                 MACH_IOM35X             IOM35X                  3554
+psom_omap              MACH_PSOM_OMAP          PSOM_OMAP               3555
+iphone_2g              MACH_IPHONE_2G          IPHONE_2G               3556
+iphone_3g              MACH_IPHONE_3G          IPHONE_3G               3557
+ipod_touch_1g          MACH_IPOD_TOUCH_1G      IPOD_TOUCH_1G           3558
+pharos_tpc             MACH_PHAROS_TPC         PHAROS_TPC              3559
+mx53_hydra             MACH_MX53_HYDRA         MX53_HYDRA              3560
+ns2816_dev_board       MACH_NS2816_DEV_BOARD   NS2816_DEV_BOARD        3561
+iphone_3gs             MACH_IPHONE_3GS         IPHONE_3GS              3562
+iphone_4               MACH_IPHONE_4           IPHONE_4                3563
+ipod_touch_4g          MACH_IPOD_TOUCH_4G      IPOD_TOUCH_4G           3564
+dragon_e1100           MACH_DRAGON_E1100       DRAGON_E1100            3565
+topside                        MACH_TOPSIDE            TOPSIDE                 3566
+irisiii                        MACH_IRISIII            IRISIII                 3567
+deto_macarm9           MACH_DETO_MACARM9       DETO_MACARM9            3568
+eti_d1                 MACH_ETI_D1             ETI_D1                  3569
+som3530sdk             MACH_SOM3530SDK         SOM3530SDK              3570
+oc_engine              MACH_OC_ENGINE          OC_ENGINE               3571
+apq8064_sim            MACH_APQ8064_SIM        APQ8064_SIM             3572
+alps                   MACH_ALPS               ALPS                    3575
+tny_t3730              MACH_TNY_T3730          TNY_T3730               3576
+geryon_nfe             MACH_GERYON_NFE         GERYON_NFE              3577
+ns2816_ref_board       MACH_NS2816_REF_BOARD   NS2816_REF_BOARD        3578
+silverstone            MACH_SILVERSTONE        SILVERSTONE             3579
+mtt2440                        MACH_MTT2440            MTT2440                 3580
+ynicdb                 MACH_YNICDB             YNICDB                  3581
+bct                    MACH_BCT                BCT                     3582
+tuscan                 MACH_TUSCAN             TUSCAN                  3583
+xbt_sam9g45            MACH_XBT_SAM9G45        XBT_SAM9G45             3584
+enbw_cmc               MACH_ENBW_CMC           ENBW_CMC                3585
+ch104mx257             MACH_CH104MX257         CH104MX257              3587
+openpri                        MACH_OPENPRI            OPENPRI                 3588
+picodmb                        MACH_PICODMB            PICODMB                 3590
+waluigi                        MACH_WALUIGI            WALUIGI                 3591
+punicag7               MACH_PUNICAG7           PUNICAG7                3592
+ipad_1g                        MACH_IPAD_1G            IPAD_1G                 3593
+appletv_2g             MACH_APPLETV_2G         APPLETV_2G              3594
+mach_ecog45            MACH_MACH_ECOG45        MACH_ECOG45             3595
+ait_cam_enc_4xx                MACH_AIT_CAM_ENC_4XX    AIT_CAM_ENC_4XX         3596
+runnymede              MACH_RUNNYMEDE          RUNNYMEDE               3597
+play                   MACH_PLAY               PLAY                    3598
+hw90260                        MACH_HW90260            HW90260                 3599
+tagh                   MACH_TAGH               TAGH                    3600
+filbert                        MACH_FILBERT            FILBERT                 3601
+getinge_netcomv3       MACH_GETINGE_NETCOMV3   GETINGE_NETCOMV3        3602
+cw20                   MACH_CW20               CW20                    3603
+cinema                 MACH_CINEMA             CINEMA                  3604
+cinema_tea             MACH_CINEMA_TEA         CINEMA_TEA              3605
+cinema_coffee          MACH_CINEMA_COFFEE      CINEMA_COFFEE           3606
+cinema_juice           MACH_CINEMA_JUICE       CINEMA_JUICE            3607
+mx53_mirage2           MACH_MX53_MIRAGE2       MX53_MIRAGE2            3609
+mx53_efikasb           MACH_MX53_EFIKASB       MX53_EFIKASB            3610
+stm_b2000              MACH_STM_B2000          STM_B2000               3612
+m28evk                 MACH_M28EVK             M28EVK                  3613
+pda                    MACH_PDA                PDA                     3614
+meraki_mr58            MACH_MERAKI_MR58        MERAKI_MR58             3615
+kota2                  MACH_KOTA2              KOTA2                   3616
+letcool                        MACH_LETCOOL            LETCOOL                 3617
+mx27iat                        MACH_MX27IAT            MX27IAT                 3618
+apollo_td              MACH_APOLLO_TD          APOLLO_TD               3619
+arena                  MACH_ARENA              ARENA                   3620
+gsngateway             MACH_GSNGATEWAY         GSNGATEWAY              3621
+lf2000                 MACH_LF2000             LF2000                  3622
+bonito                 MACH_BONITO             BONITO                  3623
+asymptote              MACH_ASYMPTOTE          ASYMPTOTE               3624
+bst2brd                        MACH_BST2BRD            BST2BRD                 3625
+tx335s                 MACH_TX335S             TX335S                  3626
+pelco_tesla            MACH_PELCO_TESLA        PELCO_TESLA             3627
+rrhtestplat            MACH_RRHTESTPLAT        RRHTESTPLAT             3628
+vidtonic_pro           MACH_VIDTONIC_PRO       VIDTONIC_PRO            3629
+pl_apollo              MACH_PL_APOLLO          PL_APOLLO               3630
+pl_phoenix             MACH_PL_PHOENIX         PL_PHOENIX              3631
+m28cu3                 MACH_M28CU3             M28CU3                  3632
+vvbox_hd               MACH_VVBOX_HD           VVBOX_HD                3633
+coreware_sam9260_      MACH_COREWARE_SAM9260_  COREWARE_SAM9260_       3634
+marmaduke              MACH_MARMADUKE          MARMADUKE               3635
+amg_xlcore_camera      MACH_AMG_XLCORE_CAMERA  AMG_XLCORE_CAMERA       3636
+omap3_egf              MACH_OMAP3_EGF          OMAP3_EGF               3637
+smdk4212               MACH_SMDK4212           SMDK4212                3638
+dnp9200                        MACH_DNP9200            DNP9200                 3639
+tf101                  MACH_TF101              TF101                   3640
+omap3silvio            MACH_OMAP3SILVIO        OMAP3SILVIO             3641
+picasso2               MACH_PICASSO2           PICASSO2                3642
+vangogh2               MACH_VANGOGH2           VANGOGH2                3643
+olpc_xo_1_75           MACH_OLPC_XO_1_75       OLPC_XO_1_75            3644
+gx400                  MACH_GX400              GX400                   3645
+gs300                  MACH_GS300              GS300                   3646
+acer_a9                        MACH_ACER_A9            ACER_A9                 3647
+vivow_evm              MACH_VIVOW_EVM          VIVOW_EVM               3648
+veloce_cxq             MACH_VELOCE_CXQ         VELOCE_CXQ              3649
+veloce_cxm             MACH_VELOCE_CXM         VELOCE_CXM              3650
+p1852                  MACH_P1852              P1852                   3651
+naxy100                        MACH_NAXY100            NAXY100                 3652
+taishan                        MACH_TAISHAN            TAISHAN                 3653
+touchlink              MACH_TOUCHLINK          TOUCHLINK               3654
+stm32f103ze            MACH_STM32F103ZE        STM32F103ZE             3655
+mcx                    MACH_MCX                MCX                     3656
+stm_nmhdk_fli7610      MACH_STM_NMHDK_FLI7610  STM_NMHDK_FLI7610       3657
+top28x                 MACH_TOP28X             TOP28X                  3658
+okl4vp_microvisor      MACH_OKL4VP_MICROVISOR  OKL4VP_MICROVISOR       3659
+pop                    MACH_POP                POP                     3660
+layer                  MACH_LAYER              LAYER                   3661
+trondheim              MACH_TRONDHEIM          TRONDHEIM               3662
+eva                    MACH_EVA                EVA                     3663
+trust_taurus           MACH_TRUST_TAURUS       TRUST_TAURUS            3664
+ns2816_huashan         MACH_NS2816_HUASHAN     NS2816_HUASHAN          3665
+ns2816_yangcheng       MACH_NS2816_YANGCHENG   NS2816_YANGCHENG        3666
+p852                   MACH_P852               P852                    3667
+flea3                  MACH_FLEA3              FLEA3                   3668
+bowfin                 MACH_BOWFIN             BOWFIN                  3669
+mv88de3100             MACH_MV88DE3100         MV88DE3100              3670
+pia_am35x              MACH_PIA_AM35X          PIA_AM35X               3671
+cedar                  MACH_CEDAR              CEDAR                   3672
+picasso_e              MACH_PICASSO_E          PICASSO_E               3673
+samsung_e60            MACH_SAMSUNG_E60        SAMSUNG_E60             3674
+sdvr_mini              MACH_SDVR_MINI          SDVR_MINI               3676
+omap3_ij3k             MACH_OMAP3_IJ3K         OMAP3_IJ3K              3677
+modasmc1               MACH_MODASMC1           MODASMC1                3678
+apq8064_rumi3          MACH_APQ8064_RUMI3      APQ8064_RUMI3           3679
+matrix506              MACH_MATRIX506          MATRIX506               3680
+msm9615_mtp            MACH_MSM9615_MTP        MSM9615_MTP             3681
+dm36x_spawndc          MACH_DM36X_SPAWNDC      DM36X_SPAWNDC           3682
+sff792                 MACH_SFF792             SFF792                  3683
+am335xiaevm            MACH_AM335XIAEVM        AM335XIAEVM             3684
+g3c2440                        MACH_G3C2440            G3C2440                 3685
+tion270                        MACH_TION270            TION270                 3686
+w22q7arm02             MACH_W22Q7ARM02         W22Q7ARM02              3687
+omap_cat               MACH_OMAP_CAT           OMAP_CAT                3688
+at91sam9n12ek          MACH_AT91SAM9N12EK      AT91SAM9N12EK           3689
+morrison               MACH_MORRISON           MORRISON                3690
+svdu                   MACH_SVDU               SVDU                    3691
+lpp01                  MACH_LPP01              LPP01                   3692
index fafed4c38fd25c18989661edcd1150b5dd3a5b4f..1f17bde52cd4dca07e6ec59aac6a13588ed8096b 100644 (file)
@@ -90,11 +90,6 @@ static struct mtd_partition nand_partitions[] = {
        },
 };
 
-static struct mtd_partition *nand_part_info(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(nand_partitions);
-       return nand_partitions;
-}
 
 static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
        .cle            = 21,
@@ -102,7 +97,8 @@ static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
        .rdy_pin        = GPIO_PIN_PB(28),
        .enable_pin     = GPIO_PIN_PE(23),
        .bus_width_16   = true,
-       .partition_info = nand_part_info,
+       .parts          = nand_partitions,
+       .num_parts      = ARRAY_SIZE(nand_partitions),
 };
 #endif
 
index 6ce30fb2ec94924464a313aece641f392d6deb64..4643ff5107c9f76ea4b3fa10a2c02f217696a22e 100644 (file)
@@ -90,18 +90,13 @@ static struct mtd_partition nand_partitions[] = {
        },
 };
 
-static struct mtd_partition *nand_part_info(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(nand_partitions);
-       return nand_partitions;
-}
-
 static struct atmel_nand_data atstk1006_nand_data __initdata = {
        .cle            = 21,
        .ale            = 22,
        .rdy_pin        = GPIO_PIN_PB(30),
        .enable_pin     = GPIO_PIN_PB(29),
-       .partition_info = nand_part_info,
+       .parts          = nand_partitions,
+       .num_parts      = ARRAY_SIZE(num_partitions),
 };
 #endif
 
index 7a9c03dcb0b6d631b137604f54a94e7bfbbdd0b3..e5deda4691db248781f0d127ca4b383cea4b794d 100644 (file)
@@ -85,7 +85,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_RESTORE_SIGMASK    7       /* restore signal mask in do_signal */
 #define TIF_CPU_GOING_TO_SLEEP 8       /* CPU is entering sleep 0 mode */
 #define TIF_NOTIFY_RESUME      9       /* callback before returning to user */
-#define TIF_FREEZE             29
 #define TIF_DEBUG              30      /* debugging enabled */
 #define TIF_USERSPACE          31      /* true if FS sets userspace */
 
@@ -98,7 +97,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 /* Note: The masks below must never span more than 16 bits! */
 
index 679458d9a622365afd30fe371c229567dedc83cb..5d7ffca7d69f01bb5b28cec422b8afb702d27859 100644 (file)
@@ -128,7 +128,8 @@ struct atmel_nand_data {
        u8      ale;            /* address line number connected to ALE */
        u8      cle;            /* address line number connected to CLE */
        u8      bus_width_16;   /* buswidth is 16 bit */
-       struct mtd_partition *(*partition_info)(int size, int *num_partitions);
+       struct mtd_partition *parts;
+       unsigned int    num_parts;
 };
 struct platform_device *
 at32_add_device_nand(unsigned int id, struct atmel_nand_data *data);
index 7a075eaf604116ff3df5e9ae4ebec090ef3846c1..5a0625aad6a0a45fa773f2bffc9994b1c4577e4a 100644 (file)
@@ -21,6 +21,7 @@ generic-y += local64.h
 generic-y += local.h
 generic-y += mman.h
 generic-y += msgbuf.h
+generic-y += mutex.h
 generic-y += param.h
 generic-y += percpu.h
 generic-y += pgalloc.h
diff --git a/arch/blackfin/include/asm/mutex.h b/arch/blackfin/include/asm/mutex.h
deleted file mode 100644 (file)
index ff6101a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/mutex-dec.h>
index 02560fd8a12182f019802e2f7b4c392110c2eb66..53ad10005ae37db4fbf6c3d6cb21eee6485b8db6 100644 (file)
@@ -100,7 +100,6 @@ static inline struct thread_info *current_thread_info(void)
                                           TIF_NEED_RESCHED */
 #define TIF_MEMDIE             4       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
-#define TIF_FREEZE             6       /* is freezing for suspend */
 #define TIF_IRQ_SYNC           7       /* sync pipeline stage */
 #define TIF_NOTIFY_RESUME      8       /* callback before returning to user */
 #define TIF_SINGLESTEP         9
@@ -111,7 +110,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 #define _TIF_IRQ_SYNC          (1<<TIF_IRQ_SYNC)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
index 1c0d190adaefa7a6555dfd079b7bac0da273b175..5cc111502822f70a970a6c91daf9971c3386cc84 100644 (file)
@@ -195,17 +195,17 @@ static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        if (access_ok(VERIFY_READ, from, n))
-               memcpy(to, from, n);
+               memcpy(to, (const void __force *)from, n);
        else
                return n;
        return 0;
 }
 
 static inline unsigned long __must_check
-copy_to_user(void *to, const void __user *from, unsigned long n)
+copy_to_user(void __user *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
-               memcpy(to, from, n);
+               memcpy((void __force *)to, from, n);
        else
                return n;
        return 0;
index eb325ed6607eb2019ba5dde3e9d620cc368e7c55..5da5787fc4efa8a091b3b67663d91ccbeffd9251 100644 (file)
@@ -54,7 +54,8 @@ static struct resource dm9000_resources[] = {
        [2] = {
                .start  = IRQ_PF10,
                .end    = IRQ_PF10,
-               .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IRQF_SHARED | IRQF_TRIGGER_HIGH),
+               .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                          IORESOURCE_IRQ_SHAREABLE),
        },
 };
 
index 642c6fed43d753b4375ff97ffa3f215eec849349..f8476d9e856b9d06da038eb49c90db2c60f053af 100644 (file)
@@ -1394,11 +1394,10 @@ static int create_md5_pad(int alloc_flag, unsigned long long hashed_length, char
 
        if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH;
 
-       p = kmalloc(padlen, alloc_flag);
+       p = kzalloc(padlen, alloc_flag);
        if (!p) return -ENOMEM;
 
        *p = 0x80;
-       memset(p+1, 0, padlen - 1);
 
        DEBUG(printk("create_md5_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
 
@@ -1426,11 +1425,10 @@ static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, cha
 
        if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH;
 
-       p = kmalloc(padlen, alloc_flag);
+       p = kzalloc(padlen, alloc_flag);
        if (!p) return -ENOMEM;
 
        *p = 0x80;
-       memset(p+1, 0, padlen - 1);
 
        DEBUG(printk("create_sha1_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
 
index f58f2c1c529526f0521448dcbe53eda6c795085e..7fb52128ddc900ebfba2952654798ab04d8e5b97 100644 (file)
@@ -163,7 +163,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
        this->ecc.mode = NAND_ECC_SOFT;
 
        /* Enable the following for a flash based bad block table */
-       /* this->options = NAND_USE_FLASH_BBT; */
+       /* this->bbt_options = NAND_BBT_USE_FLASH; */
 
        /* Scan to find existence of the device */
        if (nand_scan(crisv32_mtd, 1)) {
index d5b0cc9f976bbf15637679dbedd78f4cd57d8fc2..e03238454b0ee541e0daa556493039cedf776dbc 100644 (file)
@@ -154,7 +154,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
        this->ecc.mode = NAND_ECC_SOFT;
 
        /* Enable the following for a flash based bad block table */
-       /* this->options = NAND_USE_FLASH_BBT; */
+       /* this->bbt_options = NAND_BBT_USE_FLASH; */
 
        /* Scan to find existence of the device */
        if (nand_scan(crisv32_mtd, 1)) {
index 511ece94a574a7b6ae2538774923e3d8e760140f..42ed6c7970667ce42266559eebce92c13263c755 100644 (file)
@@ -115,8 +115,6 @@ void user_disable_single_step(struct task_struct *child)
 void
 ptrace_disable(struct task_struct *child)
 {
-       unsigned long tmp;
-
        /* Deconfigure SPC and S-bit. */
        user_disable_single_step(child);
        put_reg(child, PT_SPC, 0);
index 1de779f4f240e6747bc86828896cc2c06971a0c0..7caf25d58e6b6e3b76f75251e0831e1251ced43a 100644 (file)
@@ -7,7 +7,7 @@
 #define L1_CACHE_BYTES 32
 #define L1_CACHE_SHIFT 5
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 void flush_dma_list(dma_descr_data *descr);
 void flush_dma_descr(dma_descr_data *descr, int flush_buf);
index 332f19c54557aa09b8bdf9788f1c6998cdf93423..29b92884d79361e9c38c61fda9e6868b4d175d84 100644 (file)
@@ -86,7 +86,6 @@ struct thread_info {
 #define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* is terminating due to OOM killer */
-#define TIF_FREEZE             18      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
@@ -94,7 +93,6 @@ struct thread_info {
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index cefbe73dc119c5b265e59c83d3da7d230278560e..92d83ea99ae53efedcae511dc7a0d496a746a27e 100644 (file)
@@ -111,7 +111,6 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* is terminating due to OOM killer */
-#define TIF_FREEZE             18      /* freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
@@ -120,7 +119,6 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index d6f1784bfdeee1dc8a719d726b7a0acbb223792b..9c126e0c09aa0717f4c976586440ad18d01a7232 100644 (file)
@@ -90,7 +90,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_MEMDIE             4       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
 #define TIF_NOTIFY_RESUME      6       /* callback before returning to user */
-#define TIF_FREEZE             16      /* is freezing for suspend */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -99,7 +98,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 
index 7e81966ce48106852b18b9ec7495ef954dae903e..47afcc61f6e54235353e4f5c55d634395e08aa49 100644 (file)
@@ -172,7 +172,7 @@ static const struct net_device_ops simeth_netdev_ops = {
        .ndo_stop               = simeth_close,
        .ndo_start_xmit         = simeth_tx,
        .ndo_get_stats          = simeth_get_stats,
-       .ndo_set_multicast_list = set_multicast_list, /* not yet used */
+       .ndo_set_rx_mode        = set_multicast_list, /* not yet used */
 
 };
 
index ff0cc84e7bcc11cfb4af82d819d25e9610bdd387..e054bcc4273c1c812867914fdba0ca357d8cfe64 100644 (file)
@@ -113,7 +113,6 @@ struct thread_info {
 #define TIF_MEMDIE             17      /* is terminating due to OOM killer */
 #define TIF_MCA_INIT           18      /* this task is processing MCA or INIT */
 #define TIF_DB_DISABLED                19      /* debug trap disabled for fsyscall */
-#define TIF_FREEZE             20      /* is freezing for suspend */
 #define TIF_RESTORE_RSE                21      /* user RBS is newer than kernel RBS */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
@@ -126,7 +125,6 @@ struct thread_info {
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_MCA_INIT          (1 << TIF_MCA_INIT)
 #define _TIF_DB_DISABLED       (1 << TIF_DB_DISABLED)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_RESTORE_RSE       (1 << TIF_RESTORE_RSE)
 
 /* "work to do on user-return" bits */
index 30862c0358cd7a3644f9dd204e203bb2d7efa239..2de41d44266ebc2e860ad185e88cb4ff07e0eab7 100644 (file)
@@ -615,11 +615,15 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
                }
        }
 
-       if (cpu == SN_HWPERF_ARG_ANY_CPU || cpu == get_cpu()) {
-               /* don't care, or already on correct cpu */
+       if (cpu == SN_HWPERF_ARG_ANY_CPU) {
+               /* don't care which cpu */
                sn_hwperf_call_sal(op_info);
-       }
-       else {
+       } else if (cpu == get_cpu()) {
+               /* already on correct cpu */
+               sn_hwperf_call_sal(op_info);
+               put_cpu();
+       } else {
+               put_cpu();
                if (use_ipi) {
                        /* use an interprocessor interrupt to call SAL */
                        smp_call_function_single(cpu, sn_hwperf_call_sal,
index 0227dba44068b87b8e4406f05d57340fcdec3c87..bf8fa3c06f4ee8e970b27934e1b2aa615a4c6cb7 100644 (file)
@@ -138,7 +138,6 @@ static inline unsigned int get_thread_fault_code(void)
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
-#define TIF_FREEZE             19      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
@@ -149,7 +148,6 @@ static inline unsigned int get_thread_fault_code(void)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index 9e8ee9d2b8ca3c55ce540aee8addcbf308ea9e06..6c28582fb98f5559a39c3a0122104c561d4fa573 100644 (file)
@@ -21,6 +21,15 @@ config ARCH_HAS_ILOG2_U32
 config ARCH_HAS_ILOG2_U64
        bool
 
+config GENERIC_CLOCKEVENTS
+       bool
+
+config GENERIC_CMOS_UPDATE
+       def_bool !MMU
+
+config GENERIC_GPIO
+       bool
+
 config GENERIC_HWEIGHT
        bool
        default y
@@ -29,10 +38,16 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
+config GENERIC_IOMAP
+       def_bool MMU
+
 config TIME_LOW_RES
        bool
        default y
 
+config ARCH_USES_GETTIMEOFFSET
+       def_bool MMU
+
 config NO_IOPORT
        def_bool y
 
@@ -62,13 +77,31 @@ config MMU
          Select if you want MMU-based virtualised addressing space
          support by paged memory management. If unsure, say 'Y'.
 
-menu "Platform dependent setup"
+config MMU_MOTOROLA
+       bool
+
+config MMU_SUN3
+       bool
+       depends on MMU && !MMU_MOTOROLA
+
+menu "Platform setup"
+
+source arch/m68k/Kconfig.cpu
+
+source arch/m68k/Kconfig.machine
+
+source arch/m68k/Kconfig.bus
+
+endmenu
+
+menu "Kernel Features"
 
-if MMU
-source arch/m68k/Kconfig.mmu
+if COLDFIRE
+source "kernel/Kconfig.preempt"
 endif
-if !MMU
-source arch/m68k/Kconfig.nommu
+
+if !MMU || COLDFIRE
+source "kernel/time/Kconfig"
 endif
 
 source "mm/Kconfig"
@@ -85,9 +118,9 @@ if !MMU
 menu "Power management options"
 
 config PM
-        bool "Power Management support"
-        help
-          Support processor power management modes
+       bool "Power Management support"
+       help
+         Support processor power management modes
 
 endmenu
 endif
@@ -96,151 +129,7 @@ source "net/Kconfig"
 
 source "drivers/Kconfig"
 
-if MMU
-
-menu "Character devices"
-
-config ATARI_MFPSER
-       tristate "Atari MFP serial support"
-       depends on ATARI
-       ---help---
-         If you like to use the MFP serial ports ("Modem1", "Serial1") under
-         Linux, say Y. The driver equally supports all kinds of MFP serial
-         ports and automatically detects whether Serial1 is available.
-
-         To compile this driver as a module, choose M here.
-
-         Note for Falcon users: You also have an MFP port, it's just not
-         wired to the outside... But you could use the port under Linux.
-
-config ATARI_MIDI
-       tristate "Atari MIDI serial support"
-       depends on ATARI
-       help
-         If you want to use your Atari's MIDI port in Linux, say Y.
-
-         To compile this driver as a module, choose M here.
-
-config ATARI_DSP56K
-       tristate "Atari DSP56k support (EXPERIMENTAL)"
-       depends on ATARI && EXPERIMENTAL
-       help
-         If you want to be able to use the DSP56001 in Falcons, say Y. This
-         driver is still experimental, and if you don't know what it is, or
-         if you don't have this processor, just say N.
-
-         To compile this driver as a module, choose M here.
-
-config AMIGA_BUILTIN_SERIAL
-       tristate "Amiga builtin serial support"
-       depends on AMIGA
-       help
-         If you want to use your Amiga's built-in serial port in Linux,
-         answer Y.
-
-         To compile this driver as a module, choose M here.
-
-config MULTIFACE_III_TTY
-       tristate "Multiface Card III serial support"
-       depends on AMIGA
-       help
-         If you want to use a Multiface III card's serial port in Linux,
-         answer Y.
-
-         To compile this driver as a module, choose M here.
-
-config GVPIOEXT
-       tristate "GVP IO-Extender support"
-       depends on PARPORT=n && ZORRO
-       help
-         If you want to use a GVP IO-Extender serial card in Linux, say Y.
-         Otherwise, say N.
-
-config GVPIOEXT_LP
-       tristate "GVP IO-Extender parallel printer support"
-       depends on GVPIOEXT
-       help
-         Say Y to enable driving a printer from the parallel port on your
-         GVP IO-Extender card, N otherwise.
-
-config GVPIOEXT_PLIP
-       tristate "GVP IO-Extender PLIP support"
-       depends on GVPIOEXT
-       help
-         Say Y to enable doing IP over the parallel port on your GVP
-         IO-Extender card, N otherwise.
-
-config MAC_HID
-       bool
-       depends on INPUT_ADBHID
-       default y
-
-config HPDCA
-       tristate "HP DCA serial support"
-       depends on DIO && SERIAL_8250
-       help
-         If you want to use the internal "DCA" serial ports on an HP300
-         machine, say Y here.
-
-config HPAPCI
-       tristate "HP APCI serial support"
-       depends on HP300 && SERIAL_8250 && EXPERIMENTAL
-       help
-         If you want to use the internal "APCI" serial ports on an HP400
-         machine, say Y here.
-
-config MVME147_SCC
-       bool "SCC support for MVME147 serial ports"
-       depends on MVME147 && BROKEN
-       help
-         This is the driver for the serial ports on the Motorola MVME147
-         boards.  Everyone using one of these boards should say Y here.
-
-config MVME162_SCC
-       bool "SCC support for MVME162 serial ports"
-       depends on MVME16x && BROKEN
-       help
-         This is the driver for the serial ports on the Motorola MVME162 and
-         172 boards.  Everyone using one of these boards should say Y here.
-
-config BVME6000_SCC
-       bool "SCC support for BVME6000 serial ports"
-       depends on BVME6000 && BROKEN
-       help
-         This is the driver for the serial ports on the BVME4000 and BVME6000
-         boards from BVM Ltd.  Everyone using one of these boards should say
-         Y here.
-
-config DN_SERIAL
-       bool "Support for DN serial port (dummy)"
-       depends on APOLLO
-
-config SERIAL_CONSOLE
-       bool "Support for serial port console"
-       depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
-       ---help---
-         If you say Y here, it will be possible to use a serial port as the
-         system console (the system console is the device which receives all
-         kernel messages and warnings and which allows logins in single user
-         mode). This could be useful if some terminal or printer is connected
-         to that serial port.
-
-         Even if you say Y here, the currently visible virtual console
-         (/dev/tty0) will still be used as the system console by default, but
-         you can alter that using a kernel command line option such as
-         "console=ttyS1". (Try "man bootparam" or see the documentation of
-         your boot loader (lilo or loadlin) about how to pass options to the
-         kernel at boot time.)
-
-         If you don't have a VGA card installed and you say Y here, the
-         kernel will automatically use the first serial line, /dev/ttyS0, as
-         system console.
-
-         If unsure, say N.
-
-endmenu
-
-endif
+source "arch/m68k/Kconfig.devices"
 
 source "fs/Kconfig"
 
diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus
new file mode 100644 (file)
index 0000000..8294f0c
--- /dev/null
@@ -0,0 +1,55 @@
+if MMU
+
+comment "Bus Support"
+
+config NUBUS
+       bool
+       depends on MAC
+       default y
+
+config ZORRO
+       bool "Amiga Zorro (AutoConfig) bus support"
+       depends on AMIGA
+       help
+         This enables support for the Zorro bus in the Amiga. If you have
+         expansion cards in your Amiga that conform to the Amiga
+         AutoConfig(tm) specification, say Y, otherwise N. Note that even
+         expansion cards that do not fit in the Zorro slots but fit in e.g.
+         the CPU slot may fall in this category, so you have to say Y to let
+         Linux use these.
+
+config AMIGA_PCMCIA
+       bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)"
+       depends on AMIGA && EXPERIMENTAL
+       help
+         Include support in the kernel for pcmcia on Amiga 1200 and Amiga
+         600. If you intend to use pcmcia cards say Y; otherwise say N.
+
+config ISA
+       bool
+       depends on Q40 || AMIGA_PCMCIA
+       default y
+       help
+         Find out whether you have ISA slots on your motherboard.  ISA is the
+         name of a bus system, i.e. the way the CPU talks to the other stuff
+         inside your box.  Other bus systems are PCI, EISA, MicroChannel
+         (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
+         newer boards don't support it.  If you have ISA, say Y, otherwise N.
+
+config GENERIC_ISA_DMA
+       def_bool ISA
+
+source "drivers/pci/Kconfig"
+
+source "drivers/zorro/Kconfig"
+
+endif
+
+if !MMU
+
+config ISA_DMA_API
+        def_bool !M5272
+
+source "drivers/pcmcia/Kconfig"
+
+endif
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
new file mode 100644 (file)
index 0000000..e632b2d
--- /dev/null
@@ -0,0 +1,429 @@
+comment "Processor Type"
+
+config M68000
+       bool
+       select CPU_HAS_NO_BITFIELDS
+       help
+         The Freescale (was Motorola) 68000 CPU is the first generation of
+         the well known M68K family of processors. The CPU core as well as
+         being available as a stand alone CPU was also used in many
+         System-On-Chip devices (eg 68328, 68302, etc). It does not contain
+         a paging MMU.
+
+config MCPU32
+       bool
+       select CPU_HAS_NO_BITFIELDS
+       help
+         The Freescale (was then Motorola) CPU32 is a CPU core that is
+         based on the 68020 processor. For the most part it is used in
+         System-On-Chip parts, and does not contain a paging MMU.
+
+config COLDFIRE
+       bool
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       select CPU_HAS_NO_BITFIELDS
+       help
+         The Freescale ColdFire family of processors is a modern derivitive
+         of the 68000 processor family. They are mainly targeted at embedded
+         applications, and are all System-On-Chip (SOC) devices, as opposed
+         to stand alone CPUs. They implement a subset of the original 68000
+         processor instruction set.
+
+config M68020
+       bool "68020 support"
+       depends on MMU
+       help
+         If you anticipate running this kernel on a computer with a MC68020
+         processor, say Y. Otherwise, say N. Note that the 68020 requires a
+         68851 MMU (Memory Management Unit) to run Linux/m68k, except on the
+         Sun 3, which provides its own version.
+
+config M68030
+       bool "68030 support"
+       depends on MMU && !MMU_SUN3
+       help
+         If you anticipate running this kernel on a computer with a MC68030
+         processor, say Y. Otherwise, say N. Note that a MC68EC030 will not
+         work, as it does not include an MMU (Memory Management Unit).
+
+config M68040
+       bool "68040 support"
+       depends on MMU && !MMU_SUN3
+       help
+         If you anticipate running this kernel on a computer with a MC68LC040
+         or MC68040 processor, say Y. Otherwise, say N. Note that an
+         MC68EC040 will not work, as it does not include an MMU (Memory
+         Management Unit).
+
+config M68060
+       bool "68060 support"
+       depends on MMU && !MMU_SUN3
+       help
+         If you anticipate running this kernel on a computer with a MC68060
+         processor, say Y. Otherwise, say N.
+
+config M68328
+       bool "MC68328"
+       depends on !MMU
+       select M68000
+       help
+         Motorola 68328 processor support.
+
+config M68EZ328
+       bool "MC68EZ328"
+       depends on !MMU
+       select M68000
+       help
+         Motorola 68EX328 processor support.
+
+config M68VZ328
+       bool "MC68VZ328"
+       depends on !MMU
+       select M68000
+       help
+         Motorola 68VZ328 processor support.
+
+config M68360
+       bool "MC68360"
+       depends on !MMU
+       select MCPU32
+       help
+         Motorola 68360 processor support.
+
+config M5206
+       bool "MCF5206"
+       depends on !MMU
+       select COLDFIRE
+       select COLDFIRE_SW_A7
+       select HAVE_MBAR
+       help
+         Motorola ColdFire 5206 processor support.
+
+config M5206e
+       bool "MCF5206e"
+       depends on !MMU
+       select COLDFIRE
+       select COLDFIRE_SW_A7
+       select HAVE_MBAR
+       help
+         Motorola ColdFire 5206e processor support.
+
+config M520x
+       bool "MCF520x"
+       depends on !MMU
+       select COLDFIRE
+       select GENERIC_CLOCKEVENTS
+       select HAVE_CACHE_SPLIT
+       help
+          Freescale Coldfire 5207/5208 processor support.
+
+config M523x
+       bool "MCF523x"
+       depends on !MMU
+       select COLDFIRE
+       select GENERIC_CLOCKEVENTS
+       select HAVE_CACHE_SPLIT
+       select HAVE_IPSBAR
+       help
+         Freescale Coldfire 5230/1/2/4/5 processor support
+
+config M5249
+       bool "MCF5249"
+       depends on !MMU
+       select COLDFIRE
+       select COLDFIRE_SW_A7
+       select HAVE_MBAR
+       help
+         Motorola ColdFire 5249 processor support.
+
+config M527x
+       bool
+
+config M5271
+       bool "MCF5271"
+       depends on !MMU
+       select COLDFIRE
+       select M527x
+       select HAVE_CACHE_SPLIT
+       select HAVE_IPSBAR
+       select GENERIC_CLOCKEVENTS
+       help
+         Freescale (Motorola) ColdFire 5270/5271 processor support.
+
+config M5272
+       bool "MCF5272"
+       depends on !MMU
+       select COLDFIRE
+       select COLDFIRE_SW_A7
+       select HAVE_MBAR
+       help
+         Motorola ColdFire 5272 processor support.
+
+config M5275
+       bool "MCF5275"
+       depends on !MMU
+       select COLDFIRE
+       select M527x
+       select HAVE_CACHE_SPLIT
+       select HAVE_IPSBAR
+       select GENERIC_CLOCKEVENTS
+       help
+         Freescale (Motorola) ColdFire 5274/5275 processor support.
+
+config M528x
+       bool "MCF528x"
+       depends on !MMU
+       select COLDFIRE
+       select GENERIC_CLOCKEVENTS
+       select HAVE_CACHE_SPLIT
+       select HAVE_IPSBAR
+       help
+         Motorola ColdFire 5280/5282 processor support.
+
+config M5307
+       bool "MCF5307"
+       depends on !MMU
+       select COLDFIRE
+       select COLDFIRE_SW_A7
+       select HAVE_CACHE_CB
+       select HAVE_MBAR
+       help
+         Motorola ColdFire 5307 processor support.
+
+config M532x
+       bool "MCF532x"
+       depends on !MMU
+       select COLDFIRE
+       select HAVE_CACHE_CB
+       help
+         Freescale (Motorola) ColdFire 532x processor support.
+
+config M5407
+       bool "MCF5407"
+       depends on !MMU
+       select COLDFIRE
+       select COLDFIRE_SW_A7
+       select HAVE_CACHE_CB
+       select HAVE_MBAR
+       help
+         Motorola ColdFire 5407 processor support.
+
+config M54xx
+       bool
+
+config M547x
+       bool "MCF547x"
+       depends on !MMU
+       select COLDFIRE
+       select M54xx
+       select HAVE_CACHE_CB
+       select HAVE_MBAR
+       help
+         Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
+
+config M548x
+       bool "MCF548x"
+       depends on !MMU
+       select COLDFIRE
+       select M54xx
+       select HAVE_CACHE_CB
+       select HAVE_MBAR
+       help
+         Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
+
+
+comment "Processor Specific Options"
+
+config M68KFPU_EMU
+       bool "Math emulation support (EXPERIMENTAL)"
+       depends on MMU
+       depends on EXPERIMENTAL
+       help
+         At some point in the future, this will cause floating-point math
+         instructions to be emulated by the kernel on machines that lack a
+         floating-point math coprocessor.  Thrill-seekers and chronically
+         sleep-deprived psychotic hacker types can say Y now, everyone else
+         should probably wait a while.
+
+config M68KFPU_EMU_EXTRAPREC
+       bool "Math emulation extra precision"
+       depends on M68KFPU_EMU
+       help
+         The fpu uses normally a few bit more during calculations for
+         correct rounding, the emulator can (often) do the same but this
+         extra calculation can cost quite some time, so you can disable
+         it here. The emulator will then "only" calculate with a 64 bit
+         mantissa and round slightly incorrect, what is more than enough
+         for normal usage.
+
+config M68KFPU_EMU_ONLY
+       bool "Math emulation only kernel"
+       depends on M68KFPU_EMU
+       help
+         This option prevents any floating-point instructions from being
+         compiled into the kernel, thereby the kernel doesn't save any
+         floating point context anymore during task switches, so this
+         kernel will only be usable on machines without a floating-point
+         math coprocessor. This makes the kernel a bit faster as no tests
+         needs to be executed whether a floating-point instruction in the
+         kernel should be executed or not.
+
+config ADVANCED
+       bool "Advanced configuration options"
+       depends on MMU
+       ---help---
+         This gives you access to some advanced options for the CPU. The
+         defaults should be fine for most users, but these options may make
+         it possible for you to improve performance somewhat if you know what
+         you are doing.
+
+         Note that the answer to this question won't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about these options.
+
+         Most users should say N to this question.
+
+config RMW_INSNS
+       bool "Use read-modify-write instructions"
+       depends on ADVANCED
+       ---help---
+         This allows to use certain instructions that work with indivisible
+         read-modify-write bus cycles. While this is faster than the
+         workaround of disabling interrupts, it can conflict with DMA
+         ( = direct memory access) on many Amiga systems, and it is also said
+         to destabilize other machines. It is very likely that this will
+         cause serious problems on any Amiga or Atari Medusa if set. The only
+         configuration where it should work are 68030-based Ataris, where it
+         apparently improves performance. But you've been warned! Unless you
+         really know what you are doing, say N. Try Y only if you're quite
+         adventurous.
+
+config SINGLE_MEMORY_CHUNK
+       bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
+       depends on MMU
+       default y if SUN3
+       select NEED_MULTIPLE_NODES
+       help
+         Ignore all but the first contiguous chunk of physical memory for VM
+         purposes.  This will save a few bytes kernel size and may speed up
+         some operations.  Say N if not sure.
+
+config ARCH_DISCONTIGMEM_ENABLE
+       def_bool MMU && !SINGLE_MEMORY_CHUNK
+
+config 060_WRITETHROUGH
+       bool "Use write-through caching for 68060 supervisor accesses"
+       depends on ADVANCED && M68060
+       ---help---
+         The 68060 generally uses copyback caching of recently accessed data.
+         Copyback caching means that memory writes will be held in an on-chip
+         cache and only written back to memory some time later.  Saying Y
+         here will force supervisor (kernel) accesses to use writethrough
+         caching.  Writethrough caching means that data is written to memory
+         straight away, so that cache and memory data always agree.
+         Writethrough caching is less efficient, but is needed for some
+         drivers on 68060 based systems where the 68060 bus snooping signal
+         is hardwired on.  The 53c710 SCSI driver is known to suffer from
+         this problem.
+
+config M68K_L2_CACHE
+       bool
+       depends on MAC
+       default y
+
+config NODES_SHIFT
+       int
+       default "3"
+       depends on !SINGLE_MEMORY_CHUNK
+
+config FPU
+       bool
+
+config COLDFIRE_SW_A7
+       bool
+
+config HAVE_CACHE_SPLIT
+       bool
+
+config HAVE_CACHE_CB
+       bool
+
+config HAVE_MBAR
+       bool
+
+config HAVE_IPSBAR
+       bool
+
+config CLOCK_SET
+       bool "Enable setting the CPU clock frequency"
+       depends on COLDFIRE
+       default n
+       help
+         On some CPU's you do not need to know what the core CPU clock
+         frequency is. On these you can disable clock setting. On some
+         traditional 68K parts, and on all ColdFire parts you need to set
+         the appropriate CPU clock frequency. On these devices many of the
+         onboard peripherals derive their timing from the master CPU clock
+         frequency.
+
+config CLOCK_FREQ
+       int "Set the core clock frequency"
+       default "66666666"
+       depends on CLOCK_SET
+       help
+         Define the CPU clock frequency in use. This is the core clock
+         frequency, it may or may not be the same as the external clock
+         crystal fitted to your board. Some processors have an internal
+         PLL and can have their frequency programmed at run time, others
+         use internal dividers. In general the kernel won't setup a PLL
+         if it is fitted (there are some exceptions). This value will be
+         specific to the exact CPU that you are using.
+
+config OLDMASK
+       bool "Old mask 5307 (1H55J) silicon"
+       depends on M5307
+       help
+         Build support for the older revision ColdFire 5307 silicon.
+         Specifically this is the 1H55J mask revision.
+
+if HAVE_CACHE_SPLIT
+choice
+       prompt "Split Cache Configuration"
+       default CACHE_I
+
+config CACHE_I
+       bool "Instruction"
+       help
+         Use all of the ColdFire CPU cache memory as an instruction cache.
+
+config CACHE_D
+       bool "Data"
+       help
+         Use all of the ColdFire CPU cache memory as a data cache.
+
+config CACHE_BOTH
+       bool "Both"
+       help
+         Split the ColdFire CPU cache, and use half as an instruction cache
+         and half as a data cache.
+endchoice
+endif
+
+if HAVE_CACHE_CB
+choice
+       prompt "Data cache mode"
+       default CACHE_WRITETHRU
+
+config CACHE_WRITETHRU
+       bool "Write-through"
+       help
+         The ColdFire CPU cache is set into Write-through mode.
+
+config CACHE_COPYBACK
+       bool "Copy-back"
+       help
+         The ColdFire CPU cache is set into Copy-back mode.
+endchoice
+endif
+
diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
new file mode 100644 (file)
index 0000000..d964dc4
--- /dev/null
@@ -0,0 +1,171 @@
+if MMU
+
+config ARCH_MAY_HAVE_PC_FDC
+       bool
+       depends on BROKEN && (Q40 || SUN3X)
+       default y
+
+menu "Platform devices"
+
+config HEARTBEAT
+       bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
+       default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
+       help
+         Use the power-on LED on your machine as a load meter.  The exact
+         behavior is platform-dependent, but normally the flash frequency is
+         a hyperbolic function of the 5-minute load average.
+
+# We have a dedicated heartbeat LED. :-)
+config PROC_HARDWARE
+       bool "/proc/hardware support"
+       help
+         Say Y here to support the /proc/hardware file, which gives you
+         access to information about the machine you're running on,
+         including the model, CPU, MMU, clock speed, BogoMIPS rating,
+         and memory size.
+
+endmenu
+
+menu "Character devices"
+
+config ATARI_MFPSER
+       tristate "Atari MFP serial support"
+       depends on ATARI
+       ---help---
+         If you like to use the MFP serial ports ("Modem1", "Serial1") under
+         Linux, say Y. The driver equally supports all kinds of MFP serial
+         ports and automatically detects whether Serial1 is available.
+
+         To compile this driver as a module, choose M here.
+
+         Note for Falcon users: You also have an MFP port, it's just not
+         wired to the outside... But you could use the port under Linux.
+
+config ATARI_MIDI
+       tristate "Atari MIDI serial support"
+       depends on ATARI
+       help
+         If you want to use your Atari's MIDI port in Linux, say Y.
+
+         To compile this driver as a module, choose M here.
+
+config ATARI_DSP56K
+       tristate "Atari DSP56k support (EXPERIMENTAL)"
+       depends on ATARI && EXPERIMENTAL
+       help
+         If you want to be able to use the DSP56001 in Falcons, say Y. This
+         driver is still experimental, and if you don't know what it is, or
+         if you don't have this processor, just say N.
+
+         To compile this driver as a module, choose M here.
+
+config AMIGA_BUILTIN_SERIAL
+       tristate "Amiga builtin serial support"
+       depends on AMIGA
+       help
+         If you want to use your Amiga's built-in serial port in Linux,
+         answer Y.
+
+         To compile this driver as a module, choose M here.
+
+config MULTIFACE_III_TTY
+       tristate "Multiface Card III serial support"
+       depends on AMIGA
+       help
+         If you want to use a Multiface III card's serial port in Linux,
+         answer Y.
+
+         To compile this driver as a module, choose M here.
+
+config GVPIOEXT
+       tristate "GVP IO-Extender support"
+       depends on PARPORT=n && ZORRO
+       help
+         If you want to use a GVP IO-Extender serial card in Linux, say Y.
+         Otherwise, say N.
+
+config GVPIOEXT_LP
+       tristate "GVP IO-Extender parallel printer support"
+       depends on GVPIOEXT
+       help
+         Say Y to enable driving a printer from the parallel port on your
+         GVP IO-Extender card, N otherwise.
+
+config GVPIOEXT_PLIP
+       tristate "GVP IO-Extender PLIP support"
+       depends on GVPIOEXT
+       help
+         Say Y to enable doing IP over the parallel port on your GVP
+         IO-Extender card, N otherwise.
+
+config MAC_HID
+       bool
+       depends on INPUT_ADBHID
+       default y
+
+config HPDCA
+       tristate "HP DCA serial support"
+       depends on DIO && SERIAL_8250
+       help
+         If you want to use the internal "DCA" serial ports on an HP300
+         machine, say Y here.
+
+config HPAPCI
+       tristate "HP APCI serial support"
+       depends on HP300 && SERIAL_8250 && EXPERIMENTAL
+       help
+         If you want to use the internal "APCI" serial ports on an HP400
+         machine, say Y here.
+
+config MVME147_SCC
+       bool "SCC support for MVME147 serial ports"
+       depends on MVME147 && BROKEN
+       help
+         This is the driver for the serial ports on the Motorola MVME147
+         boards.  Everyone using one of these boards should say Y here.
+
+config MVME162_SCC
+       bool "SCC support for MVME162 serial ports"
+       depends on MVME16x && BROKEN
+       help
+         This is the driver for the serial ports on the Motorola MVME162 and
+         172 boards.  Everyone using one of these boards should say Y here.
+
+config BVME6000_SCC
+       bool "SCC support for BVME6000 serial ports"
+       depends on BVME6000 && BROKEN
+       help
+         This is the driver for the serial ports on the BVME4000 and BVME6000
+         boards from BVM Ltd.  Everyone using one of these boards should say
+         Y here.
+
+config DN_SERIAL
+       bool "Support for DN serial port (dummy)"
+       depends on APOLLO
+
+config SERIAL_CONSOLE
+       bool "Support for serial port console"
+       depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
+       ---help---
+         If you say Y here, it will be possible to use a serial port as the
+         system console (the system console is the device which receives all
+         kernel messages and warnings and which allows logins in single user
+         mode). This could be useful if some terminal or printer is connected
+         to that serial port.
+
+         Even if you say Y here, the currently visible virtual console
+         (/dev/tty0) will still be used as the system console by default, but
+         you can alter that using a kernel command line option such as
+         "console=ttyS1". (Try "man bootparam" or see the documentation of
+         your boot loader (lilo or loadlin) about how to pass options to the
+         kernel at boot time.)
+
+         If you don't have a VGA card installed and you say Y here, the
+         kernel will automatically use the first serial line, /dev/ttyS0, as
+         system console.
+
+         If unsure, say N.
+
+endmenu
+
+endif
similarity index 62%
rename from arch/m68k/Kconfig.nommu
rename to arch/m68k/Kconfig.machine
index ff46383112a4174bcd26c57eaa094baa0b7f2e79..7d5c20b896c78a704ab3508bcb21fb72b1e15459 100644 (file)
-config FPU
-       bool
-       default n
-
-config GENERIC_GPIO
-       bool
-       default n
-
-config GENERIC_CMOS_UPDATE
-       bool
-       default y
-
-config GENERIC_CLOCKEVENTS
-       bool
-       default n
-
-config M68000
-       bool
-       select CPU_HAS_NO_BITFIELDS
-       help
-         The Freescale (was Motorola) 68000 CPU is the first generation of
-         the well known M68K family of processors. The CPU core as well as
-         being available as a stand alone CPU was also used in many
-         System-On-Chip devices (eg 68328, 68302, etc). It does not contain
-         a paging MMU.
-
-config MCPU32
-       bool
-       select CPU_HAS_NO_BITFIELDS
-       help
-         The Freescale (was then Motorola) CPU32 is a CPU core that is
-         based on the 68020 processor. For the most part it is used in
-         System-On-Chip parts, and does not contain a paging MMU.
-
-config COLDFIRE
-       bool
-       select GENERIC_GPIO
-       select ARCH_REQUIRE_GPIOLIB
-       select CPU_HAS_NO_BITFIELDS
-       help
-         The Freescale ColdFire family of processors is a modern derivitive
-         of the 68000 processor family. They are mainly targeted at embedded
-         applications, and are all System-On-Chip (SOC) devices, as opposed
-         to stand alone CPUs. They implement a subset of the original 68000
-         processor instruction set.
-
-config COLDFIRE_SW_A7
-       bool
-       default n
-
-config HAVE_CACHE_SPLIT
-       bool
-
-config HAVE_CACHE_CB
-       bool
-
-config HAVE_MBAR
-       bool
-
-config HAVE_IPSBAR
-       bool
-
-choice
-       prompt "CPU"
-       default M68EZ328
-
-config M68328
-       bool "MC68328"
-       select M68000
-       help
-         Motorola 68328 processor support.
-
-config M68EZ328
-       bool "MC68EZ328"
-       select M68000
-       help
-         Motorola 68EX328 processor support.
-
-config M68VZ328
-       bool "MC68VZ328"
-       select M68000
-       help
-         Motorola 68VZ328 processor support.
-
-config M68360
-       bool "MC68360"
-       select MCPU32
-       help
-         Motorola 68360 processor support.
-
-config M5206
-       bool "MCF5206"
-       select COLDFIRE
-       select COLDFIRE_SW_A7
-       select HAVE_MBAR
-       help
-         Motorola ColdFire 5206 processor support.
+comment "Machine Types"
+
+config AMIGA
+       bool "Amiga support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         This option enables support for the Amiga series of computers. If
+         you plan to use this kernel on an Amiga, say Y here and browse the
+         material available in <file:Documentation/m68k>; otherwise say N.
+
+config ATARI
+       bool "Atari support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         This option enables support for the 68000-based Atari series of
+         computers (including the TT, Falcon and Medusa). If you plan to use
+         this kernel on an Atari, say Y here and browse the material
+         available in <file:Documentation/m68k>; otherwise say N.
+
+config MAC
+       bool "Macintosh support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         This option enables support for the Apple Macintosh series of
+         computers (yes, there is experimental support now, at least for part
+         of the series).
+
+         Say N unless you're willing to code the remaining necessary support.
+         ;)
+
+config APOLLO
+       bool "Apollo support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         Say Y here if you want to run Linux on an MC680x0-based Apollo
+         Domain workstation such as the DN3500.
+
+config VME
+       bool "VME (Motorola and BVM) support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         Say Y here if you want to build a kernel for a 680x0 based VME
+         board.  Boards currently supported include Motorola boards MVME147,
+         MVME162, MVME166, MVME167, MVME172, and MVME177.  BVME4000 and
+         BVME6000 boards from BVM Ltd are also supported.
+
+config MVME147
+       bool "MVME147 support"
+       depends on MMU
+       depends on VME
+       help
+         Say Y to include support for early Motorola VME boards.  This will
+         build a kernel which can run on MVME147 single-board computers.  If
+         you select this option you will have to select the appropriate
+         drivers for SCSI, Ethernet and serial ports later on.
+
+config MVME16x
+       bool "MVME162, 166 and 167 support"
+       depends on MMU
+       depends on VME
+       help
+         Say Y to include support for Motorola VME boards.  This will build a
+         kernel which can run on MVME162, MVME166, MVME167, MVME172, and
+         MVME177 boards.  If you select this option you will have to select
+         the appropriate drivers for SCSI, Ethernet and serial ports later
+         on.
+
+config BVME6000
+       bool "BVME4000 and BVME6000 support"
+       depends on MMU
+       depends on VME
+       help
+         Say Y to include support for VME boards from BVM Ltd.  This will
+         build a kernel which can run on BVME4000 and BVME6000 boards.  If
+         you select this option you will have to select the appropriate
+         drivers for SCSI, Ethernet and serial ports later on.
+
+config HP300
+       bool "HP9000/300 and HP9000/400 support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         This option enables support for the HP9000/300 and HP9000/400 series
+         of workstations. Support for these machines is still somewhat
+         experimental. If you plan to try to use the kernel on such a machine
+         say Y here.
+         Everybody else says N.
+
+config SUN3X
+       bool "Sun3x support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       select M68030
+       help
+         This option enables support for the Sun 3x series of workstations.
+         Be warned that this support is very experimental.
+         Note that Sun 3x kernels are not compatible with Sun 3 hardware.
+         General Linux information on the Sun 3x series (now discontinued)
+         is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
+
+         If you don't want to compile a kernel for a Sun 3x, say N.
+
+config Q40
+       bool "Q40/Q60 support"
+       depends on MMU
+       select MMU_MOTOROLA if MMU
+       help
+         The Q40 is a Motorola 68040-based successor to the Sinclair QL
+         manufactured in Germany.  There is an official Q40 home page at
+         <http://www.q40.de/>.  This option enables support for the Q40 and
+         Q60. Select your CPU below.  For 68LC060 don't forget to enable FPU
+         emulation.
+
+config SUN3
+       bool "Sun3 support"
+       depends on MMU
+       depends on !MMU_MOTOROLA
+       select MMU_SUN3 if MMU
+       select M68020
+       help
+         This option enables support for the Sun 3 series of workstations
+         (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires
+         that all other hardware types must be disabled, as Sun 3 kernels
+         are incompatible with all other m68k targets (including Sun 3x!).
+
+         If you don't want to compile a kernel exclusively for a Sun 3, say N.
 
-config M5206e
-       bool "MCF5206e"
-       select COLDFIRE
-       select COLDFIRE_SW_A7
-       select HAVE_MBAR
-       help
-         Motorola ColdFire 5206e processor support.
-
-config M520x
-       bool "MCF520x"
-       select COLDFIRE
-       select GENERIC_CLOCKEVENTS
-       select HAVE_CACHE_SPLIT
-       help
-          Freescale Coldfire 5207/5208 processor support.
-
-config M523x
-       bool "MCF523x"
-       select COLDFIRE
-       select GENERIC_CLOCKEVENTS
-       select HAVE_CACHE_SPLIT
-       select HAVE_IPSBAR
-       help
-         Freescale Coldfire 5230/1/2/4/5 processor support
-
-config M5249
-       bool "MCF5249"
-       select COLDFIRE
-       select COLDFIRE_SW_A7
-       select HAVE_MBAR
-       help
-         Motorola ColdFire 5249 processor support.
-
-config M5271
-       bool "MCF5271"
-       select COLDFIRE
-       select HAVE_CACHE_SPLIT
-       select HAVE_IPSBAR
-       help
-         Freescale (Motorola) ColdFire 5270/5271 processor support.
-
-config M5272
-       bool "MCF5272"
-       select COLDFIRE
-       select COLDFIRE_SW_A7
-       select HAVE_MBAR
-       help
-         Motorola ColdFire 5272 processor support.
-
-config M5275
-       bool "MCF5275"
-       select COLDFIRE
-       select HAVE_CACHE_SPLIT
-       select HAVE_IPSBAR
-       help
-         Freescale (Motorola) ColdFire 5274/5275 processor support.
-
-config M528x
-       bool "MCF528x"
-       select COLDFIRE
-       select GENERIC_CLOCKEVENTS
-       select HAVE_CACHE_SPLIT
-       select HAVE_IPSBAR
-       help
-         Motorola ColdFire 5280/5282 processor support.
-
-config M5307
-       bool "MCF5307"
-       select COLDFIRE
-       select COLDFIRE_SW_A7
-       select HAVE_CACHE_CB
-       select HAVE_MBAR
-       help
-         Motorola ColdFire 5307 processor support.
-
-config M532x
-       bool "MCF532x"
-       select COLDFIRE
-       select HAVE_CACHE_CB
-       help
-         Freescale (Motorola) ColdFire 532x processor support.
-
-config M5407
-       bool "MCF5407"
-       select COLDFIRE
-       select COLDFIRE_SW_A7
-       select HAVE_CACHE_CB
-       select HAVE_MBAR
-       help
-         Motorola ColdFire 5407 processor support.
-
-config M547x
-       bool "MCF547x"
-       select COLDFIRE
-       select HAVE_CACHE_CB
-       select HAVE_MBAR
-       help
-         Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
-
-config M548x
-       bool "MCF548x"
-       select COLDFIRE
-       select HAVE_CACHE_CB
-       select HAVE_MBAR
-       help
-         Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
-
-endchoice
-
-config M527x
-       bool
-       depends on (M5271 || M5275)
-       select GENERIC_CLOCKEVENTS
-       default y
-
-config M54xx
+config PILOT
        bool
-       depends on (M548x || M547x)
-       default y
-
-config CLOCK_SET
-       bool "Enable setting the CPU clock frequency"
-       default n
-       help
-         On some CPU's you do not need to know what the core CPU clock
-         frequency is. On these you can disable clock setting. On some
-         traditional 68K parts, and on all ColdFire parts you need to set
-         the appropriate CPU clock frequency. On these devices many of the
-         onboard peripherals derive their timing from the master CPU clock
-         frequency.
-
-config CLOCK_FREQ
-       int "Set the core clock frequency"
-       default "66666666"
-       depends on CLOCK_SET
-       help
-         Define the CPU clock frequency in use. This is the core clock
-         frequency, it may or may not be the same as the external clock
-         crystal fitted to your board. Some processors have an internal
-         PLL and can have their frequency programmed at run time, others
-         use internal dividers. In general the kernel won't setup a PLL
-         if it is fitted (there are some exceptions). This value will be
-         specific to the exact CPU that you are using.
-
-config OLDMASK
-       bool "Old mask 5307 (1H55J) silicon"
-       depends on M5307
-       help
-         Build support for the older revision ColdFire 5307 silicon.
-         Specifically this is the 1H55J mask revision.
-
-if HAVE_CACHE_SPLIT
-choice
-       prompt "Split Cache Configuration"
-       default CACHE_I
-
-config CACHE_I
-       bool "Instruction"
-       help
-         Use all of the ColdFire CPU cache memory as an instruction cache.
-
-config CACHE_D
-       bool "Data"
-       help
-         Use all of the ColdFire CPU cache memory as a data cache.
-
-config CACHE_BOTH
-       bool "Both"
-       help
-         Split the ColdFire CPU cache, and use half as an instruction cache
-         and half as a data cache.
-endchoice
-endif
-
-if HAVE_CACHE_CB
-choice
-       prompt "Data cache mode"
-       default CACHE_WRITETHRU
-
-config CACHE_WRITETHRU
-       bool "Write-through"
-       help
-         The ColdFire CPU cache is set into Write-through mode.
-
-config CACHE_COPYBACK
-       bool "Copy-back"
-       help
-         The ColdFire CPU cache is set into Copy-back mode.
-endchoice
-endif
-
-comment "Platform"
 
 config PILOT3
        bool "Pilot 1000/5000, PalmPilot Personal/Pro, or PalmIII support"
        depends on M68328
+       select PILOT
        help
          Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII.
 
@@ -302,7 +147,7 @@ config XCOPILOT_BUGS
          Support the bugs of Xcopilot.
 
 config UC5272
-       bool 'Arcturus Networks uC5272 dimm board support'
+       bool "Arcturus Networks uC5272 dimm board support"
        depends on M5272
        help
          Support for the Arcturus Networks uC5272 dimm board.
@@ -356,15 +201,23 @@ config UCQUICC
        help
          Support for the Lineo uCquicc board.
 
+config ARNEWSH
+       bool
+
 config ARN5206
        bool "Arnewsh 5206 board support"
        depends on M5206
+       select ARNEWSH
        help
          Support for the Arnewsh 5206 board.
 
+config FREESCALE
+       bool
+
 config M5206eC3
        bool "Motorola M5206eC3 board support"
        depends on M5206e
+       select FREESCALE
        help
          Support for the Motorola M5206eC3 board.
 
@@ -377,75 +230,95 @@ config ELITE
 config M5208EVB
        bool "Freescale M5208EVB board support"
        depends on M520x
+       select FREESCALE
        help
          Support for the Freescale Coldfire M5208EVB.
 
 config M5235EVB
        bool "Freescale M5235EVB support"
        depends on M523x
+       select FREESCALE
        help
          Support for the Freescale M5235EVB board.
 
 config M5249C3
        bool "Motorola M5249C3 board support"
        depends on M5249
+       select FREESCALE
        help
          Support for the Motorola M5249C3 board.
 
 config M5271EVB
        bool "Freescale (Motorola) M5271EVB board support"
        depends on M5271
+       select FREESCALE
        help
          Support for the Freescale (Motorola) M5271EVB board.
 
 config M5275EVB
        bool "Freescale (Motorola) M5275EVB board support"
        depends on M5275
+       select FREESCALE
        help
          Support for the Freescale (Motorola) M5275EVB board.
 
 config M5272C3
        bool "Motorola M5272C3 board support"
        depends on M5272
+       select FREESCALE
        help
          Support for the Motorola M5272C3 board.
 
+config senTec
+       bool
+
 config COBRA5272
        bool "senTec COBRA5272 board support"
        depends on M5272
+       select senTec
        help
          Support for the senTec COBRA5272 board.
 
+config AVNET
+       bool
+
 config AVNET5282
        bool "Avnet 5282 board support"
        depends on M528x
+       select AVNET
        help
-         Support for the Avnet 5282 board.  
-         
+         Support for the Avnet 5282 board.
+
 config M5282EVB
        bool "Motorola M5282EVB board support"
        depends on M528x
+       select FREESCALE
        help
          Support for the Motorola M5282EVB board.
 
 config COBRA5282
        bool "senTec COBRA5282 board support"
        depends on M528x
+       select senTec
        help
          Support for the senTec COBRA5282 board.
-         
+
+config EMAC_INC
+       bool
+
 config SOM5282EM
        bool "EMAC.Inc SOM5282EM board support"
        depends on M528x
+       select EMAC_INC
        help
-         Support for the EMAC.Inc SOM5282EM module.  
-         
+         Support for the EMAC.Inc SOM5282EM module.
+
 config WILDFIRE
        bool "Intec Automation Inc. WildFire board support"
        depends on M528x
        help
          Support for the Intec Automation Inc. WildFire.
-         
+
 config WILDFIREMOD
        bool "Intec Automation Inc. WildFire module support"
        depends on M528x
@@ -455,12 +328,14 @@ config WILDFIREMOD
 config ARN5307
        bool "Arnewsh 5307 board support"
        depends on M5307
+       select ARNEWSH
        help
          Support for the Arnewsh 5307 board.
 
 config M5307C3
        bool "Motorola M5307C3 board support"
        depends on M5307
+       select FREESCALE
        help
          Support for the Motorola M5307C3 board.
 
@@ -473,6 +348,7 @@ config SECUREEDGEMP3
 config M5329EVB
        bool "Freescale (Motorola) M5329EVB board support"
        depends on M532x
+       select FREESCALE
        help
          Support for the Freescale (Motorola) M5329EVB board.
 
@@ -485,6 +361,7 @@ config COBRA5329
 config M5407C3
        bool "Motorola M5407C3 board support"
        depends on M5407
+       select FREESCALE
        help
          Support for the Motorola M5407C3 board.
 
@@ -494,21 +371,27 @@ config FIREBEE
        help
          Support for the FireBee ColdFire 5475 based board.
 
+config HW_FEITH
+       bool
+
 config CLEOPATRA
        bool "Feith CLEOPATRA board support"
        depends on (M5307 || M5407)
+       select HW_FEITH
        help
          Support for the Feith Cleopatra boards.
 
 config CANCam
        bool "Feith CANCam board support"
        depends on M5272
+       select HW_FEITH
        help
          Support for the Feith CANCam board.
 
 config SCALES
        bool "Feith SCALES board support"
        depends on M5272
+       select HW_FEITH
        help
          Support for the Feith SCALES board.
 
@@ -524,9 +407,13 @@ config SNAPGEAR
        help
          Special additional support for SnapGear router boards.
 
+config SNEHA
+       bool
+
 config CPU16B
        bool "Sneha Technologies S.L. Sarasvati board support"
        depends on M5272
+       select SNEHA
        help
          Support for the SNEHA CPU16B board.
 
@@ -536,12 +423,21 @@ config MOD5272
        help
          Support for the Netburner MOD-5272 board.
 
+config SAVANT
+       bool
+
 config SAVANTrosie1
        bool "Savant Rosie1 board support"
        depends on M523x
+       select SAVANT
        help
          Support for the Savant Rosie1 board.
 
+
+if !MMU || COLDFIRE
+
+comment "Machine Options"
+
 config ROMFS_FROM_ROM
        bool "ROMFS image not RAM resident"
        depends on (NETtel || SNAPGEAR)
@@ -549,51 +445,6 @@ config ROMFS_FROM_ROM
          The ROMfs filesystem will stay resident in the FLASH/ROM, not be
          moved into RAM.
 
-config PILOT
-       bool
-       default y
-       depends on (PILOT3 || PILOT5)
-
-config ARNEWSH
-       bool
-       default y
-       depends on (ARN5206 || ARN5307)
-
-config FREESCALE
-       bool
-       default y
-       depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5329EVB || M5407C3)
-
-config HW_FEITH
-       bool
-       default y
-       depends on (CLEOPATRA || CANCam || SCALES)
-
-config senTec
-       bool
-       default y
-       depends on (COBRA5272 || COBRA5282)
-       
-config EMAC_INC
-       bool
-       default y
-       depends on (SOM5282EM)
-
-config SNEHA
-       bool
-       default y
-       depends on CPU16B
-
-config SAVANT
-       bool
-       default y
-       depends on SAVANTrosie1
-
-config AVNET
-       bool
-       default y
-       depends on (AVNET5282)
-
 config UBOOT
        bool "Support for U-Boot command line parameters"
        help
@@ -772,16 +623,4 @@ config ROMKERNEL
 
 endchoice
 
-if COLDFIRE
-source "kernel/Kconfig.preempt"
 endif
-
-source "kernel/time/Kconfig"
-
-config ISA_DMA_API
-       bool
-       depends on !M5272
-       default y
-
-source "drivers/pcmcia/Kconfig"
-
diff --git a/arch/m68k/Kconfig.mmu b/arch/m68k/Kconfig.mmu
deleted file mode 100644 (file)
index 13e20bb..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-config GENERIC_IOMAP
-       bool
-       default y
-
-config ARCH_MAY_HAVE_PC_FDC
-       bool
-       depends on BROKEN && (Q40 || SUN3X)
-       default y
-
-config ARCH_USES_GETTIMEOFFSET
-       def_bool y
-
-config EISA
-       bool
-       ---help---
-         The Extended Industry Standard Architecture (EISA) bus was
-         developed as an open alternative to the IBM MicroChannel bus.
-
-         The EISA bus provided some of the features of the IBM MicroChannel
-         bus while maintaining backward compatibility with cards made for
-         the older ISA bus.  The EISA bus saw limited use between 1988 and
-         1995 when it was made obsolete by the PCI bus.
-
-         Say Y here if you are building a kernel for an EISA-based machine.
-
-         Otherwise, say N.
-
-config MCA
-       bool
-       help
-         MicroChannel Architecture is found in some IBM PS/2 machines and
-         laptops.  It is a bus system similar to PCI or ISA. See
-         <file:Documentation/mca.txt> (and especially the web page given
-         there) before attempting to build an MCA bus kernel.
-
-config PCMCIA
-       tristate
-       ---help---
-         Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
-         computer.  These are credit-card size devices such as network cards,
-         modems or hard drives often used with laptops computers.  There are
-         actually two varieties of these cards: the older 16 bit PCMCIA cards
-         and the newer 32 bit CardBus cards.  If you want to use CardBus
-         cards, you need to say Y here and also to "CardBus support" below.
-
-         To use your PC-cards, you will need supporting software from David
-         Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
-         for location).  Please also read the PCMCIA-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as modules, choose M here: the
-         modules will be called pcmcia_core and ds.
-
-config AMIGA
-       bool "Amiga support"
-       select MMU_MOTOROLA if MMU
-       help
-         This option enables support for the Amiga series of computers. If
-         you plan to use this kernel on an Amiga, say Y here and browse the
-         material available in <file:Documentation/m68k>; otherwise say N.
-
-config ATARI
-       bool "Atari support"
-       select MMU_MOTOROLA if MMU
-       help
-         This option enables support for the 68000-based Atari series of
-         computers (including the TT, Falcon and Medusa). If you plan to use
-         this kernel on an Atari, say Y here and browse the material
-         available in <file:Documentation/m68k>; otherwise say N.
-
-config MAC
-       bool "Macintosh support"
-       select MMU_MOTOROLA if MMU
-       help
-         This option enables support for the Apple Macintosh series of
-         computers (yes, there is experimental support now, at least for part
-         of the series).
-
-         Say N unless you're willing to code the remaining necessary support.
-         ;)
-
-config NUBUS
-       bool
-       depends on MAC
-       default y
-
-config M68K_L2_CACHE
-       bool
-       depends on MAC
-       default y
-
-config APOLLO
-       bool "Apollo support"
-       select MMU_MOTOROLA if MMU
-       help
-         Say Y here if you want to run Linux on an MC680x0-based Apollo
-         Domain workstation such as the DN3500.
-
-config VME
-       bool "VME (Motorola and BVM) support"
-       select MMU_MOTOROLA if MMU
-       help
-         Say Y here if you want to build a kernel for a 680x0 based VME
-         board.  Boards currently supported include Motorola boards MVME147,
-         MVME162, MVME166, MVME167, MVME172, and MVME177.  BVME4000 and
-         BVME6000 boards from BVM Ltd are also supported.
-
-config MVME147
-       bool "MVME147 support"
-       depends on VME
-       help
-         Say Y to include support for early Motorola VME boards.  This will
-         build a kernel which can run on MVME147 single-board computers.  If
-         you select this option you will have to select the appropriate
-         drivers for SCSI, Ethernet and serial ports later on.
-
-config MVME16x
-       bool "MVME162, 166 and 167 support"
-       depends on VME
-       help
-         Say Y to include support for Motorola VME boards.  This will build a
-         kernel which can run on MVME162, MVME166, MVME167, MVME172, and
-         MVME177 boards.  If you select this option you will have to select
-         the appropriate drivers for SCSI, Ethernet and serial ports later
-         on.
-
-config BVME6000
-       bool "BVME4000 and BVME6000 support"
-       depends on VME
-       help
-         Say Y to include support for VME boards from BVM Ltd.  This will
-         build a kernel which can run on BVME4000 and BVME6000 boards.  If
-         you select this option you will have to select the appropriate
-         drivers for SCSI, Ethernet and serial ports later on.
-
-config HP300
-       bool "HP9000/300 and HP9000/400 support"
-       select MMU_MOTOROLA if MMU
-       help
-         This option enables support for the HP9000/300 and HP9000/400 series
-         of workstations. Support for these machines is still somewhat
-         experimental. If you plan to try to use the kernel on such a machine
-         say Y here.
-         Everybody else says N.
-
-config DIO
-       bool "DIO bus support"
-       depends on HP300
-       default y
-       help
-         Say Y here to enable support for the "DIO" expansion bus used in
-         HP300 machines. If you are using such a system you almost certainly
-         want this.
-
-config SUN3X
-       bool "Sun3x support"
-       select MMU_MOTOROLA if MMU
-       select M68030
-       help
-         This option enables support for the Sun 3x series of workstations.
-         Be warned that this support is very experimental.
-         Note that Sun 3x kernels are not compatible with Sun 3 hardware.
-         General Linux information on the Sun 3x series (now discontinued)
-         is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
-
-         If you don't want to compile a kernel for a Sun 3x, say N.
-
-config Q40
-       bool "Q40/Q60 support"
-       select MMU_MOTOROLA if MMU
-       help
-         The Q40 is a Motorola 68040-based successor to the Sinclair QL
-         manufactured in Germany.  There is an official Q40 home page at
-         <http://www.q40.de/>.  This option enables support for the Q40 and
-         Q60. Select your CPU below.  For 68LC060 don't forget to enable FPU
-         emulation.
-
-config SUN3
-       bool "Sun3 support"
-       depends on !MMU_MOTOROLA
-       select MMU_SUN3 if MMU
-       select M68020
-       help
-         This option enables support for the Sun 3 series of workstations
-         (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires
-         that all other hardware types must be disabled, as Sun 3 kernels
-         are incompatible with all other m68k targets (including Sun 3x!).
-
-         If you don't want to compile a kernel exclusively for a Sun 3, say N.
-
-config NATFEAT
-       bool "ARAnyM emulator support"
-       depends on ATARI
-       help
-         This option enables support for ARAnyM native features, such as
-         access to a disk image as /dev/hda.
-
-config NFBLOCK
-       tristate "NatFeat block device support"
-       depends on BLOCK && NATFEAT
-       help
-         Say Y to include support for the ARAnyM NatFeat block device
-         which allows direct access to the hard drives without using
-         the hardware emulation.
-
-config NFCON
-       tristate "NatFeat console driver"
-       depends on NATFEAT
-       help
-         Say Y to include support for the ARAnyM NatFeat console driver
-         which allows the console output to be redirected to the stderr
-         output of ARAnyM.
-
-config NFETH
-       tristate "NatFeat Ethernet support"
-       depends on NET_ETHERNET && NATFEAT
-       help
-         Say Y to include support for the ARAnyM NatFeat network device
-         which will emulate a regular ethernet device while presenting an
-         ethertap device to the host system.
-
-comment "Processor type"
-
-config M68020
-       bool "68020 support"
-       help
-         If you anticipate running this kernel on a computer with a MC68020
-         processor, say Y. Otherwise, say N. Note that the 68020 requires a
-         68851 MMU (Memory Management Unit) to run Linux/m68k, except on the
-         Sun 3, which provides its own version.
-
-config M68030
-       bool "68030 support"
-       depends on !MMU_SUN3
-       help
-         If you anticipate running this kernel on a computer with a MC68030
-         processor, say Y. Otherwise, say N. Note that a MC68EC030 will not
-         work, as it does not include an MMU (Memory Management Unit).
-
-config M68040
-       bool "68040 support"
-       depends on !MMU_SUN3
-       help
-         If you anticipate running this kernel on a computer with a MC68LC040
-         or MC68040 processor, say Y. Otherwise, say N. Note that an
-         MC68EC040 will not work, as it does not include an MMU (Memory
-         Management Unit).
-
-config M68060
-       bool "68060 support"
-       depends on !MMU_SUN3
-       help
-         If you anticipate running this kernel on a computer with a MC68060
-         processor, say Y. Otherwise, say N.
-
-config MMU_MOTOROLA
-       bool
-
-config MMU_SUN3
-       bool
-       depends on MMU && !MMU_MOTOROLA
-
-config M68KFPU_EMU
-       bool "Math emulation support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       help
-         At some point in the future, this will cause floating-point math
-         instructions to be emulated by the kernel on machines that lack a
-         floating-point math coprocessor.  Thrill-seekers and chronically
-         sleep-deprived psychotic hacker types can say Y now, everyone else
-         should probably wait a while.
-
-config M68KFPU_EMU_EXTRAPREC
-       bool "Math emulation extra precision"
-       depends on M68KFPU_EMU
-       help
-         The fpu uses normally a few bit more during calculations for
-         correct rounding, the emulator can (often) do the same but this
-         extra calculation can cost quite some time, so you can disable
-         it here. The emulator will then "only" calculate with a 64 bit
-         mantissa and round slightly incorrect, what is more than enough
-         for normal usage.
-
-config M68KFPU_EMU_ONLY
-       bool "Math emulation only kernel"
-       depends on M68KFPU_EMU
-       help
-         This option prevents any floating-point instructions from being
-         compiled into the kernel, thereby the kernel doesn't save any
-         floating point context anymore during task switches, so this
-         kernel will only be usable on machines without a floating-point
-         math coprocessor. This makes the kernel a bit faster as no tests
-         needs to be executed whether a floating-point instruction in the
-         kernel should be executed or not.
-
-config ADVANCED
-       bool "Advanced configuration options"
-       ---help---
-         This gives you access to some advanced options for the CPU. The
-         defaults should be fine for most users, but these options may make
-         it possible for you to improve performance somewhat if you know what
-         you are doing.
-
-         Note that the answer to this question won't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about these options.
-
-         Most users should say N to this question.
-
-config RMW_INSNS
-       bool "Use read-modify-write instructions"
-       depends on ADVANCED
-       ---help---
-         This allows to use certain instructions that work with indivisible
-         read-modify-write bus cycles. While this is faster than the
-         workaround of disabling interrupts, it can conflict with DMA
-         ( = direct memory access) on many Amiga systems, and it is also said
-         to destabilize other machines. It is very likely that this will
-         cause serious problems on any Amiga or Atari Medusa if set. The only
-         configuration where it should work are 68030-based Ataris, where it
-         apparently improves performance. But you've been warned! Unless you
-         really know what you are doing, say N. Try Y only if you're quite
-         adventurous.
-
-config SINGLE_MEMORY_CHUNK
-       bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
-       default y if SUN3
-       select NEED_MULTIPLE_NODES
-       help
-         Ignore all but the first contiguous chunk of physical memory for VM
-         purposes.  This will save a few bytes kernel size and may speed up
-         some operations.  Say N if not sure.
-
-config 060_WRITETHROUGH
-       bool "Use write-through caching for 68060 supervisor accesses"
-       depends on ADVANCED && M68060
-       ---help---
-         The 68060 generally uses copyback caching of recently accessed data.
-         Copyback caching means that memory writes will be held in an on-chip
-         cache and only written back to memory some time later.  Saying Y
-         here will force supervisor (kernel) accesses to use writethrough
-         caching.  Writethrough caching means that data is written to memory
-         straight away, so that cache and memory data always agree.
-         Writethrough caching is less efficient, but is needed for some
-         drivers on 68060 based systems where the 68060 bus snooping signal
-         is hardwired on.  The 53c710 SCSI driver is known to suffer from
-         this problem.
-
-config ARCH_DISCONTIGMEM_ENABLE
-       def_bool !SINGLE_MEMORY_CHUNK
-
-config NODES_SHIFT
-       int
-       default "3"
-       depends on !SINGLE_MEMORY_CHUNK
-
-config ZORRO
-       bool "Amiga Zorro (AutoConfig) bus support"
-       depends on AMIGA
-       help
-         This enables support for the Zorro bus in the Amiga. If you have
-         expansion cards in your Amiga that conform to the Amiga
-         AutoConfig(tm) specification, say Y, otherwise N. Note that even
-         expansion cards that do not fit in the Zorro slots but fit in e.g.
-         the CPU slot may fall in this category, so you have to say Y to let
-         Linux use these.
-
-config AMIGA_PCMCIA
-       bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)"
-       depends on AMIGA && EXPERIMENTAL
-       help
-         Include support in the kernel for pcmcia on Amiga 1200 and Amiga
-         600. If you intend to use pcmcia cards say Y; otherwise say N.
-
-config HEARTBEAT
-       bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
-       default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
-       help
-         Use the power-on LED on your machine as a load meter.  The exact
-         behavior is platform-dependent, but normally the flash frequency is
-         a hyperbolic function of the 5-minute load average.
-
-# We have a dedicated heartbeat LED. :-)
-config PROC_HARDWARE
-       bool "/proc/hardware support"
-       help
-         Say Y here to support the /proc/hardware file, which gives you
-         access to information about the machine you're running on,
-         including the model, CPU, MMU, clock speed, BogoMIPS rating,
-         and memory size.
-
-config ISA
-       bool
-       depends on Q40 || AMIGA_PCMCIA
-       default y
-       help
-         Find out whether you have ISA slots on your motherboard.  ISA is the
-         name of a bus system, i.e. the way the CPU talks to the other stuff
-         inside your box.  Other bus systems are PCI, EISA, MicroChannel
-         (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
-         newer boards don't support it.  If you have ISA, say Y, otherwise N.
-
-config GENERIC_ISA_DMA
-       bool
-       depends on Q40 || AMIGA_PCMCIA
-       default y
-
-source "drivers/pci/Kconfig"
-
-source "drivers/zorro/Kconfig"
-
index be46cadd401781b6796a3888e18085b864080e0b..cf318f20c64d615674cbe990fa8661b83c197ce9 100644 (file)
@@ -1,7 +1,171 @@
+#
+# m68k/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Hamish Macdonald
+# Copyright (C) 2002,2011 Greg Ungerer <gerg@snapgear.com>
+#
+
 KBUILD_DEFCONFIG := multi_defconfig
 
+#
+#      Enable processor type. Ordering of these is important - we want to
+#      use the minimum processor type of the range we support. The logic
+#      for 680x0 will only allow use of the -m68060 or -m68040 if no other
+#      680x0 type is specified - and no option is specified for 68030 or
+#      68020. The other m68k/ColdFire types always specify some type of
+#      compiler cpu type flag.
+#
+ifndef CONFIG_M68040
+cpuflags-$(CONFIG_M68060)      := -m68060
+endif
+ifndef CONFIG_M68060
+cpuflags-$(CONFIG_M68040)      := -m68040
+endif
+cpuflags-$(CONFIG_M68030)      :=
+cpuflags-$(CONFIG_M68020)      :=
+cpuflags-$(CONFIG_M68360)      := -m68332
+cpuflags-$(CONFIG_M68000)      := -m68000
+cpuflags-$(CONFIG_M54xx)       := $(call cc-option,-mcpu=5475,-m5200)
+cpuflags-$(CONFIG_M5407)       := $(call cc-option,-mcpu=5407,-m5200)
+cpuflags-$(CONFIG_M532x)       := $(call cc-option,-mcpu=532x,-m5307)
+cpuflags-$(CONFIG_M5307)       := $(call cc-option,-mcpu=5307,-m5200)
+cpuflags-$(CONFIG_M528x)       := $(call cc-option,-mcpu=528x,-m5307)
+cpuflags-$(CONFIG_M5275)       := $(call cc-option,-mcpu=5275,-m5307)
+cpuflags-$(CONFIG_M5272)       := $(call cc-option,-mcpu=5272,-m5307)
+cpuflags-$(CONFIG_M5271)       := $(call cc-option,-mcpu=5271,-m5307)
+cpuflags-$(CONFIG_M523x)       := $(call cc-option,-mcpu=523x,-m5307)
+cpuflags-$(CONFIG_M5249)       := $(call cc-option,-mcpu=5249,-m5200)
+cpuflags-$(CONFIG_M520x)       := $(call cc-option,-mcpu=5208,-m5200)
+cpuflags-$(CONFIG_M5206e)      := $(call cc-option,-mcpu=5206e,-m5200)
+cpuflags-$(CONFIG_M5206)       := $(call cc-option,-mcpu=5206,-m5200)
+
+KBUILD_AFLAGS += $(cpuflags-y)
+KBUILD_CFLAGS += $(cpuflags-y) -pipe
 ifdef CONFIG_MMU
-include $(srctree)/arch/m68k/Makefile_mm
+# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
+KBUILD_CFLAGS += -fno-strength-reduce -ffixed-a2
+else
+# we can use a m68k-linux-gcc toolchain with these in place
+KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+KBUILD_CFLAGS += -D__uClinux__
+KBUILD_AFLAGS += -D__uClinux__
+endif
+
+LDFLAGS := -m m68kelf
+KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
+ifneq ($(SUBARCH),$(ARCH))
+       ifeq ($(CROSS_COMPILE),)
+               CROSS_COMPILE := $(call cc-cross-prefix, \
+                       m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
+       endif
+endif
+
+ifdef CONFIG_SUN3
+LDFLAGS_vmlinux = -N
+endif
+
+CHECKFLAGS += -D__mc68000__
+
+
+ifdef CONFIG_KGDB
+# If configured for kgdb support, include debugging infos and keep the
+# frame pointer
+KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
+endif
+
+#
+# Select the assembler head startup code. Order is important. The default
+# head code is first, processor specific selections can override it after.
+#
+head-y                         := arch/m68k/kernel/head.o
+head-$(CONFIG_SUN3)            := arch/m68k/kernel/sun3-head.o
+head-$(CONFIG_M68360)          := arch/m68k/platform/68360/head.o
+head-$(CONFIG_M68000)          := arch/m68k/platform/68328/head.o
+head-$(CONFIG_COLDFIRE)                := arch/m68k/platform/coldfire/head.o
+
+core-y                         += arch/m68k/kernel/    arch/m68k/mm/
+libs-y                         += arch/m68k/lib/
+
+core-$(CONFIG_Q40)             += arch/m68k/q40/
+core-$(CONFIG_AMIGA)           += arch/m68k/amiga/
+core-$(CONFIG_ATARI)           += arch/m68k/atari/
+core-$(CONFIG_MAC)             += arch/m68k/mac/
+core-$(CONFIG_HP300)           += arch/m68k/hp300/
+core-$(CONFIG_APOLLO)          += arch/m68k/apollo/
+core-$(CONFIG_MVME147)         += arch/m68k/mvme147/
+core-$(CONFIG_MVME16x)         += arch/m68k/mvme16x/
+core-$(CONFIG_BVME6000)                += arch/m68k/bvme6000/
+core-$(CONFIG_SUN3X)           += arch/m68k/sun3x/     arch/m68k/sun3/
+core-$(CONFIG_SUN3)            += arch/m68k/sun3/      arch/m68k/sun3/prom/
+core-$(CONFIG_NATFEAT)         += arch/m68k/emu/
+core-$(CONFIG_M68040)          += arch/m68k/fpsp040/
+core-$(CONFIG_M68060)          += arch/m68k/ifpsp060/
+core-$(CONFIG_M68KFPU_EMU)     += arch/m68k/math-emu/
+core-$(CONFIG_M68360)          += arch/m68k/platform/68360/
+core-$(CONFIG_M68000)          += arch/m68k/platform/68328/
+core-$(CONFIG_M68EZ328)                += arch/m68k/platform/68EZ328/
+core-$(CONFIG_M68VZ328)                += arch/m68k/platform/68VZ328/
+core-$(CONFIG_COLDFIRE)                += arch/m68k/platform/coldfire/
+core-$(CONFIG_M5206)           += arch/m68k/platform/5206/
+core-$(CONFIG_M5206e)          += arch/m68k/platform/5206/
+core-$(CONFIG_M520x)           += arch/m68k/platform/520x/
+core-$(CONFIG_M523x)           += arch/m68k/platform/523x/
+core-$(CONFIG_M5249)           += arch/m68k/platform/5249/
+core-$(CONFIG_M527x)           += arch/m68k/platform/527x/
+core-$(CONFIG_M5272)           += arch/m68k/platform/5272/
+core-$(CONFIG_M528x)           += arch/m68k/platform/528x/
+core-$(CONFIG_M5307)           += arch/m68k/platform/5307/
+core-$(CONFIG_M532x)           += arch/m68k/platform/532x/
+core-$(CONFIG_M5407)           += arch/m68k/platform/5407/
+core-$(CONFIG_M54xx)           += arch/m68k/platform/54xx/
+
+
+all:   zImage
+
+lilo:  vmlinux
+       if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
+       if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
+       cat vmlinux > $(INSTALL_PATH)/vmlinux
+       cp System.map $(INSTALL_PATH)/System.map
+       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+
+zImage compressed: vmlinux.gz
+
+vmlinux.gz: vmlinux
+
+ifndef CONFIG_KGDB
+       cp vmlinux vmlinux.tmp
+       $(STRIP) vmlinux.tmp
+       gzip -9c vmlinux.tmp >vmlinux.gz
+       rm vmlinux.tmp
 else
-include $(srctree)/arch/m68k/Makefile_no
+       gzip -9c vmlinux >vmlinux.gz
 endif
+
+bzImage: vmlinux.bz2
+
+vmlinux.bz2: vmlinux
+
+ifndef CONFIG_KGDB
+       cp vmlinux vmlinux.tmp
+       $(STRIP) vmlinux.tmp
+       bzip2 -1c vmlinux.tmp >vmlinux.bz2
+       rm vmlinux.tmp
+else
+       bzip2 -1c vmlinux >vmlinux.bz2
+endif
+
+archclean:
+       rm -f vmlinux.gz vmlinux.bz2
+
+install:
+       sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
diff --git a/arch/m68k/Makefile_mm b/arch/m68k/Makefile_mm
deleted file mode 100644 (file)
index d449b6d..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#
-# m68k/Makefile
-#
-# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Hamish Macdonald
-#
-
-# override top level makefile
-AS += -m68020
-LDFLAGS := -m m68kelf
-KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
-ifneq ($(SUBARCH),$(ARCH))
-       ifeq ($(CROSS_COMPILE),)
-               CROSS_COMPILE := $(call cc-cross-prefix, \
-                       m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
-       endif
-endif
-
-ifdef CONFIG_SUN3
-LDFLAGS_vmlinux = -N
-endif
-
-CHECKFLAGS += -D__mc68000__
-
-# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
-KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
-
-# enable processor switch if compiled only for a single cpu
-ifndef CONFIG_M68020
-ifndef CONFIG_M68030
-
-ifndef CONFIG_M68060
-KBUILD_CFLAGS += -m68040
-endif
-
-ifndef CONFIG_M68040
-KBUILD_CFLAGS += -m68060
-endif
-
-endif
-endif
-
-ifdef CONFIG_KGDB
-# If configured for kgdb support, include debugging infos and keep the
-# frame pointer
-KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
-endif
-
-ifndef CONFIG_SUN3
-head-y := arch/m68k/kernel/head.o
-else
-head-y := arch/m68k/kernel/sun3-head.o
-endif
-
-core-y                         += arch/m68k/kernel/    arch/m68k/mm/
-libs-y                         += arch/m68k/lib/
-
-core-$(CONFIG_Q40)             += arch/m68k/q40/
-core-$(CONFIG_AMIGA)           += arch/m68k/amiga/
-core-$(CONFIG_ATARI)           += arch/m68k/atari/
-core-$(CONFIG_MAC)             += arch/m68k/mac/
-core-$(CONFIG_HP300)           += arch/m68k/hp300/
-core-$(CONFIG_APOLLO)          += arch/m68k/apollo/
-core-$(CONFIG_MVME147)         += arch/m68k/mvme147/
-core-$(CONFIG_MVME16x)         += arch/m68k/mvme16x/
-core-$(CONFIG_BVME6000)                += arch/m68k/bvme6000/
-core-$(CONFIG_SUN3X)           += arch/m68k/sun3x/     arch/m68k/sun3/
-core-$(CONFIG_SUN3)            += arch/m68k/sun3/      arch/m68k/sun3/prom/
-core-$(CONFIG_NATFEAT)         += arch/m68k/emu/
-core-$(CONFIG_M68040)          += arch/m68k/fpsp040/
-core-$(CONFIG_M68060)          += arch/m68k/ifpsp060/
-core-$(CONFIG_M68KFPU_EMU)     += arch/m68k/math-emu/
-
-all:   zImage
-
-lilo:  vmlinux
-       if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
-       if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
-       cat vmlinux > $(INSTALL_PATH)/vmlinux
-       cp System.map $(INSTALL_PATH)/System.map
-       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
-
-zImage compressed: vmlinux.gz
-
-vmlinux.gz: vmlinux
-
-ifndef CONFIG_KGDB
-       cp vmlinux vmlinux.tmp
-       $(STRIP) vmlinux.tmp
-       gzip -9c vmlinux.tmp >vmlinux.gz
-       rm vmlinux.tmp
-else
-       gzip -9c vmlinux >vmlinux.gz
-endif
-
-bzImage: vmlinux.bz2
-
-vmlinux.bz2: vmlinux
-
-ifndef CONFIG_KGDB
-       cp vmlinux vmlinux.tmp
-       $(STRIP) vmlinux.tmp
-       bzip2 -1c vmlinux.tmp >vmlinux.bz2
-       rm vmlinux.tmp
-else
-       bzip2 -1c vmlinux >vmlinux.bz2
-endif
-
-archclean:
-       rm -f vmlinux.gz vmlinux.bz2
-
-install:
-       sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
diff --git a/arch/m68k/Makefile_no b/arch/m68k/Makefile_no
deleted file mode 100644 (file)
index 844d3f1..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-#
-# arch/m68k/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com>
-#
-
-platform-$(CONFIG_M68328)      := 68328
-platform-$(CONFIG_M68EZ328)    := 68EZ328
-platform-$(CONFIG_M68VZ328)    := 68VZ328
-platform-$(CONFIG_M68360)      := 68360
-platform-$(CONFIG_M5206)       := 5206
-platform-$(CONFIG_M5206e)      := 5206
-platform-$(CONFIG_M520x)       := 520x
-platform-$(CONFIG_M523x)       := 523x
-platform-$(CONFIG_M5249)       := 5249
-platform-$(CONFIG_M527x)       := 527x
-platform-$(CONFIG_M5272)       := 5272
-platform-$(CONFIG_M528x)       := 528x
-platform-$(CONFIG_M5307)       := 5307
-platform-$(CONFIG_M532x)       := 532x
-platform-$(CONFIG_M5407)       := 5407
-platform-$(CONFIG_M54xx)       := 54xx
-PLATFORM := $(platform-y)
-
-board-$(CONFIG_PILOT)          := pilot
-board-$(CONFIG_UC5272)          := UC5272
-board-$(CONFIG_UC5282)          := UC5282
-board-$(CONFIG_UCSIMM)         := ucsimm
-board-$(CONFIG_UCDIMM)         := ucdimm
-board-$(CONFIG_UCQUICC)                := uCquicc
-board-$(CONFIG_DRAGEN2)                := de2
-board-$(CONFIG_ARNEWSH)                := ARNEWSH
-board-$(CONFIG_FREESCALE)      := FREESCALE
-board-$(CONFIG_M5235EVB)       := M5235EVB
-board-$(CONFIG_M5271EVB)       := M5271EVB
-board-$(CONFIG_M5275EVB)       := M5275EVB
-board-$(CONFIG_M5282EVB)       := M5282EVB
-board-$(CONFIG_ELITE)          := eLITE
-board-$(CONFIG_NETtel)         := NETtel
-board-$(CONFIG_SECUREEDGEMP3)  := MP3
-board-$(CONFIG_CLEOPATRA)      := CLEOPATRA
-board-$(CONFIG_senTec)         := senTec
-board-$(CONFIG_SNEHA)          := SNEHA
-board-$(CONFIG_M5208EVB)       := M5208EVB
-board-$(CONFIG_MOD5272)                := MOD5272
-board-$(CONFIG_AVNET)           := AVNET
-board-$(CONFIG_SAVANT)         := SAVANT
-BOARD := $(board-y)
-
-model-$(CONFIG_RAMKERNEL)      := ram
-model-$(CONFIG_ROMKERNEL)      := rom
-MODEL := $(model-y)
-
-#
-# Some code support is grouped together for a common cpu-subclass (for
-# example all ColdFire cpu's are very similar). Determine the sub-class
-# for the selected cpu. ONLY need to define this for the non-base member
-# of the family.
-#
-cpuclass-$(CONFIG_M5206)       := coldfire
-cpuclass-$(CONFIG_M5206e)      := coldfire
-cpuclass-$(CONFIG_M520x)       := coldfire
-cpuclass-$(CONFIG_M523x)       := coldfire
-cpuclass-$(CONFIG_M5249)       := coldfire
-cpuclass-$(CONFIG_M527x)       := coldfire
-cpuclass-$(CONFIG_M5272)       := coldfire
-cpuclass-$(CONFIG_M528x)       := coldfire
-cpuclass-$(CONFIG_M5307)       := coldfire
-cpuclass-$(CONFIG_M532x)       := coldfire
-cpuclass-$(CONFIG_M5407)       := coldfire
-cpuclass-$(CONFIG_M54xx)       := coldfire
-cpuclass-$(CONFIG_M68328)      := 68328
-cpuclass-$(CONFIG_M68EZ328)    := 68328
-cpuclass-$(CONFIG_M68VZ328)    := 68328
-cpuclass-$(CONFIG_M68360)      := 68360
-CPUCLASS := $(cpuclass-y)
-
-ifneq ($(CPUCLASS),$(PLATFORM))
-CLASSDIR := arch/m68k/platform/$(cpuclass-y)/
-endif
-
-export PLATFORM BOARD MODEL CPUCLASS
-
-#
-# Some CFLAG additions based on specific CPU type.
-#
-cflags-$(CONFIG_M5206)         := $(call cc-option,-mcpu=5206,-m5200)
-cflags-$(CONFIG_M5206e)                := $(call cc-option,-mcpu=5206e,-m5200)
-cflags-$(CONFIG_M520x)         := $(call cc-option,-mcpu=5208,-m5200)
-cflags-$(CONFIG_M523x)         := $(call cc-option,-mcpu=523x,-m5307)
-cflags-$(CONFIG_M5249)         := $(call cc-option,-mcpu=5249,-m5200)
-cflags-$(CONFIG_M5271)         := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5272,-m5307)
-cflags-$(CONFIG_M5275)         := $(call cc-option,-mcpu=5275,-m5307)
-cflags-$(CONFIG_M528x)         := $(call cc-option,-mcpu=528x,-m5307)
-cflags-$(CONFIG_M5307)         := $(call cc-option,-mcpu=5307,-m5200)
-cflags-$(CONFIG_M532x)         := $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407)         := $(call cc-option,-mcpu=5407,-m5200)
-cflags-$(CONFIG_M54xx)         := $(call cc-option,-mcpu=5475,-m5200)
-cflags-$(CONFIG_M68328)                := -m68000
-cflags-$(CONFIG_M68EZ328)      := -m68000
-cflags-$(CONFIG_M68VZ328)      := -m68000
-cflags-$(CONFIG_M68360)                := -m68332
-
-KBUILD_AFLAGS += $(cflags-y)
-
-KBUILD_CFLAGS += $(cflags-y)
-KBUILD_CFLAGS += -D__linux__
-KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
-
-head-y := arch/m68k/platform/$(cpuclass-y)/head.o
-
-core-y += arch/m68k/kernel/ \
-          arch/m68k/mm/ \
-          $(CLASSDIR) \
-          arch/m68k/platform/$(PLATFORM)/
-libs-y += arch/m68k/lib/
-
-archclean:
-
index 876eec6f2b52a03e3f92801ca92077abd207b278..c3c5a8643e15c784e096189f1a29ef59e251d115 100644 (file)
@@ -1,5 +1,254 @@
-#ifdef __uClinux__
-#include "entry_no.h"
+#ifndef __M68K_ENTRY_H
+#define __M68K_ENTRY_H
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#ifdef __ASSEMBLY__
+#include <asm/thread_info.h>
+#endif
+
+/*
+ * Stack layout in 'ret_from_exception':
+ *
+ *     This allows access to the syscall arguments in registers d1-d5
+ *
+ *      0(sp) - d1
+ *      4(sp) - d2
+ *      8(sp) - d3
+ *      C(sp) - d4
+ *     10(sp) - d5
+ *     14(sp) - a0
+ *     18(sp) - a1
+ *     1C(sp) - a2
+ *     20(sp) - d0
+ *     24(sp) - orig_d0
+ *     28(sp) - stack adjustment
+ *     2C(sp) - [ sr              ] [ format & vector ]
+ *     2E(sp) - [ pc-hiword       ] [ sr              ]
+ *     30(sp) - [ pc-loword       ] [ pc-hiword       ]
+ *     32(sp) - [ format & vector ] [ pc-loword       ]
+ *               ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
+ *                     M68K              COLDFIRE
+ */
+
+/* the following macro is used when enabling interrupts */
+#if defined(MACH_ATARI_ONLY)
+       /* block out HSYNC on the atari */
+#define ALLOWINT       (~0x400)
+#define        MAX_NOINT_IPL   3
 #else
-#include "entry_mm.h"
+       /* portable version */
+#define ALLOWINT       (~0x700)
+#define        MAX_NOINT_IPL   0
+#endif /* machine compilation types */
+
+#ifdef __ASSEMBLY__
+/*
+ * This defines the normal kernel pt-regs layout.
+ *
+ * regs a3-a6 and d6-d7 are preserved by C code
+ * the kernel doesn't mess with usp unless it needs to
+ */
+#define SWITCH_STACK_SIZE      (6*4+4) /* includes return address */
+
+#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
+/*
+ * This is made a little more tricky on older ColdFires. There is no
+ * separate supervisor and user stack pointers. Need to artificially
+ * construct a usp in software... When doing this we need to disable
+ * interrupts, otherwise bad things will happen.
+ */
+.globl sw_usp
+.globl sw_ksp
+
+.macro SAVE_ALL_SYS
+       move    #0x2700,%sr             /* disable intrs */
+       btst    #5,%sp@(2)              /* from user? */
+       bnes    6f                      /* no, skip */
+       movel   %sp,sw_usp              /* save user sp */
+       addql   #8,sw_usp               /* remove exception */
+       movel   sw_ksp,%sp              /* kernel sp */
+       subql   #8,%sp                  /* room for exception */
+       clrl    %sp@-                   /* stkadj */
+       movel   %d0,%sp@-               /* orig d0 */
+       movel   %d0,%sp@-               /* d0 */
+       lea     %sp@(-32),%sp           /* space for 8 regs */
+       moveml  %d1-%d5/%a0-%a2,%sp@
+       movel   sw_usp,%a0              /* get usp */
+       movel   %a0@-,%sp@(PT_OFF_PC)   /* copy exception program counter */
+       movel   %a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
+       bra     7f
+       6:
+       clrl    %sp@-                   /* stkadj */
+       movel   %d0,%sp@-               /* orig d0 */
+       movel   %d0,%sp@-               /* d0 */
+       lea     %sp@(-32),%sp           /* space for 8 regs */
+       moveml  %d1-%d5/%a0-%a2,%sp@
+       7:
+.endm
+
+.macro SAVE_ALL_INT
+       SAVE_ALL_SYS
+       moveq   #-1,%d0                 /* not system call entry */
+       movel   %d0,%sp@(PT_OFF_ORIG_D0)
+.endm
+
+.macro RESTORE_USER
+       move    #0x2700,%sr             /* disable intrs */
+       movel   sw_usp,%a0              /* get usp */
+       movel   %sp@(PT_OFF_PC),%a0@-   /* copy exception program counter */
+       movel   %sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
+       moveml  %sp@,%d1-%d5/%a0-%a2
+       lea     %sp@(32),%sp            /* space for 8 regs */
+       movel   %sp@+,%d0
+       addql   #4,%sp                  /* orig d0 */
+       addl    %sp@+,%sp               /* stkadj */
+       addql   #8,%sp                  /* remove exception */
+       movel   %sp,sw_ksp              /* save ksp */
+       subql   #8,sw_usp               /* set exception */
+       movel   sw_usp,%sp              /* restore usp */
+       rte
+.endm
+
+.macro RDUSP
+       movel   sw_usp,%a3
+.endm
+
+.macro WRUSP
+       movel   %a3,sw_usp
+.endm
+
+#else /* !CONFIG_COLDFIRE_SW_A7 */
+/*
+ * Modern ColdFire parts have separate supervisor and user stack
+ * pointers. Simple load and restore macros for this case.
+ */
+.macro SAVE_ALL_SYS
+       move    #0x2700,%sr             /* disable intrs */
+       clrl    %sp@-                   /* stkadj */
+       movel   %d0,%sp@-               /* orig d0 */
+       movel   %d0,%sp@-               /* d0 */
+       lea     %sp@(-32),%sp           /* space for 8 regs */
+       moveml  %d1-%d5/%a0-%a2,%sp@
+.endm
+
+.macro SAVE_ALL_INT
+       move    #0x2700,%sr             /* disable intrs */
+       clrl    %sp@-                   /* stkadj */
+       pea     -1:w                    /* orig d0 */
+       movel   %d0,%sp@-               /* d0 */
+       lea     %sp@(-32),%sp           /* space for 8 regs */
+       moveml  %d1-%d5/%a0-%a2,%sp@
+.endm
+
+.macro RESTORE_USER
+       moveml  %sp@,%d1-%d5/%a0-%a2
+       lea     %sp@(32),%sp            /* space for 8 regs */
+       movel   %sp@+,%d0
+       addql   #4,%sp                  /* orig d0 */
+       addl    %sp@+,%sp               /* stkadj */
+       rte
+.endm
+
+.macro RDUSP
+       /*move  %usp,%a3*/
+       .word   0x4e6b
+.endm
+
+.macro WRUSP
+       /*move  %a3,%usp*/
+       .word   0x4e63
+.endm
+
+#endif /* !CONFIG_COLDFIRE_SW_A7 */
+
+.macro SAVE_SWITCH_STACK
+       lea     %sp@(-24),%sp           /* 6 regs */
+       moveml  %a3-%a6/%d6-%d7,%sp@
+.endm
+
+.macro RESTORE_SWITCH_STACK
+       moveml  %sp@,%a3-%a6/%d6-%d7
+       lea     %sp@(24),%sp            /* 6 regs */
+.endm
+
+#else /* !CONFIG_COLDFIRE */
+
+/*
+ * All other types of m68k parts (68000, 680x0, CPU32) have the same
+ * entry and exit code.
+ */
+
+/*
+ * a -1 in the orig_d0 field signifies
+ * that the stack frame is NOT for syscall
+ */
+.macro SAVE_ALL_INT
+       clrl    %sp@-                   /* stk_adj */
+       pea     -1:w                    /* orig d0 */
+       movel   %d0,%sp@-               /* d0 */
+       moveml  %d1-%d5/%a0-%a2,%sp@-
+.endm
+
+.macro SAVE_ALL_SYS
+       clrl    %sp@-                   /* stk_adj */
+       movel   %d0,%sp@-               /* orig d0 */
+       movel   %d0,%sp@-               /* d0 */
+       moveml  %d1-%d5/%a0-%a2,%sp@-
+.endm
+
+.macro RESTORE_ALL
+       moveml  %sp@+,%a0-%a2/%d1-%d5
+       movel   %sp@+,%d0
+       addql   #4,%sp                  /* orig d0 */
+       addl    %sp@+,%sp               /* stk adj */
+       rte
+.endm
+
+
+.macro SAVE_SWITCH_STACK
+       moveml  %a3-%a6/%d6-%d7,%sp@-
+.endm
+
+.macro RESTORE_SWITCH_STACK
+       moveml  %sp@+,%a3-%a6/%d6-%d7
+.endm
+
+#endif /* !CONFIG_COLDFIRE */
+
+/*
+ * Register %a2 is reserved and set to current task on MMU enabled systems.
+ * Non-MMU systems do not reserve %a2 in this way, and this definition is
+ * not used for them.
+ */
+#define curptr a2
+
+#define GET_CURRENT(tmp) get_current tmp
+.macro get_current reg=%d0
+       movel   %sp,\reg
+       andw    #-THREAD_SIZE,\reg
+       movel   \reg,%curptr
+       movel   %curptr@,%curptr
+.endm
+
+#else /* C source */
+
+#define STR(X) STR1(X)
+#define STR1(X) #X
+
+#define SAVE_ALL_INT                           \
+       "clrl   %%sp@-;"    /* stk_adj */       \
+       "pea    -1:w;"      /* orig d0 = -1 */  \
+       "movel  %%d0,%%sp@-;" /* d0 */          \
+       "moveml %%d1-%%d5/%%a0-%%a2,%%sp@-"
+
+#define GET_CURRENT(tmp) \
+       "movel  %%sp,"#tmp"\n\t" \
+       "andw   #-"STR(THREAD_SIZE)","#tmp"\n\t" \
+       "movel  "#tmp",%%a2\n\t" \
+       "movel  %%a2@,%%a2"
+
 #endif
+
+#endif /* __M68K_ENTRY_H */
diff --git a/arch/m68k/include/asm/entry_mm.h b/arch/m68k/include/asm/entry_mm.h
deleted file mode 100644 (file)
index 73b8c8f..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#ifndef __M68K_ENTRY_H
-#define __M68K_ENTRY_H
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#ifdef __ASSEMBLY__
-#include <asm/thread_info.h>
-#endif
-
-/*
- * Stack layout in 'ret_from_exception':
- *
- *     This allows access to the syscall arguments in registers d1-d5
- *
- *      0(sp) - d1
- *      4(sp) - d2
- *      8(sp) - d3
- *      C(sp) - d4
- *     10(sp) - d5
- *     14(sp) - a0
- *     18(sp) - a1
- *     1C(sp) - a2
- *     20(sp) - d0
- *     24(sp) - orig_d0
- *     28(sp) - stack adjustment
- *     2C(sp) - sr
- *     2E(sp) - pc
- *     32(sp) - format & vector
- */
-
-/*
- * 97/05/14 Andreas: Register %a2 is now set to the current task throughout
- *                  the whole kernel.
- */
-
-/* the following macro is used when enabling interrupts */
-#if defined(MACH_ATARI_ONLY)
-       /* block out HSYNC on the atari */
-#define ALLOWINT       (~0x400)
-#define        MAX_NOINT_IPL   3
-#else
-       /* portable version */
-#define ALLOWINT       (~0x700)
-#define        MAX_NOINT_IPL   0
-#endif /* machine compilation types */
-
-#ifdef __ASSEMBLY__
-
-#define curptr a2
-
-LFLUSH_I_AND_D = 0x00000808
-
-#define SAVE_ALL_INT save_all_int
-#define SAVE_ALL_SYS save_all_sys
-#define RESTORE_ALL restore_all
-/*
- * This defines the normal kernel pt-regs layout.
- *
- * regs a3-a6 and d6-d7 are preserved by C code
- * the kernel doesn't mess with usp unless it needs to
- */
-
-/*
- * a -1 in the orig_d0 field signifies
- * that the stack frame is NOT for syscall
- */
-.macro save_all_int
-       clrl    %sp@-           | stk_adj
-       pea     -1:w            | orig d0
-       movel   %d0,%sp@-       | d0
-       moveml  %d1-%d5/%a0-%a1/%curptr,%sp@-
-.endm
-
-.macro save_all_sys
-       clrl    %sp@-           | stk_adj
-       movel   %d0,%sp@-       | orig d0
-       movel   %d0,%sp@-       | d0
-       moveml  %d1-%d5/%a0-%a1/%curptr,%sp@-
-.endm
-
-.macro restore_all
-       moveml  %sp@+,%a0-%a1/%curptr/%d1-%d5
-       movel   %sp@+,%d0
-       addql   #4,%sp          | orig d0
-       addl    %sp@+,%sp       | stk adj
-       rte
-.endm
-
-#define SWITCH_STACK_SIZE (6*4+4)      /* includes return address */
-
-#define SAVE_SWITCH_STACK save_switch_stack
-#define RESTORE_SWITCH_STACK restore_switch_stack
-#define GET_CURRENT(tmp) get_current tmp
-
-.macro save_switch_stack
-       moveml  %a3-%a6/%d6-%d7,%sp@-
-.endm
-
-.macro restore_switch_stack
-       moveml  %sp@+,%a3-%a6/%d6-%d7
-.endm
-
-.macro get_current reg=%d0
-       movel   %sp,\reg
-       andw    #-THREAD_SIZE,\reg
-       movel   \reg,%curptr
-       movel   %curptr@,%curptr
-.endm
-
-#else /* C source */
-
-#define STR(X) STR1(X)
-#define STR1(X) #X
-
-#define SAVE_ALL_INT                           \
-       "clrl   %%sp@-;"    /* stk_adj */       \
-       "pea    -1:w;"      /* orig d0 = -1 */  \
-       "movel  %%d0,%%sp@-;" /* d0 */          \
-       "moveml %%d1-%%d5/%%a0-%%a2,%%sp@-"
-#define GET_CURRENT(tmp) \
-       "movel  %%sp,"#tmp"\n\t" \
-       "andw   #-"STR(THREAD_SIZE)","#tmp"\n\t" \
-       "movel  "#tmp",%%a2\n\t" \
-       "movel  %%a2@,%%a2"
-
-#endif
-
-#endif /* __M68K_ENTRY_H */
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h
deleted file mode 100644 (file)
index 68611e3..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-#ifndef __M68KNOMMU_ENTRY_H
-#define __M68KNOMMU_ENTRY_H
-
-#include <asm/setup.h>
-#include <asm/page.h>
-
-/*
- * Stack layout in 'ret_from_exception':
- *
- * This allows access to the syscall arguments in registers d1-d5
- *
- *      0(sp) - d1
- *      4(sp) - d2
- *      8(sp) - d3
- *      C(sp) - d4
- *     10(sp) - d5
- *     14(sp) - a0
- *     18(sp) - a1
- *     1C(sp) - a2
- *     20(sp) - d0
- *     24(sp) - orig_d0
- *     28(sp) - stack adjustment
- *     2C(sp) - [ sr              ] [ format & vector ]
- *     2E(sp) - [ pc-hiword       ] [ sr              ]
- *     30(sp) - [ pc-loword       ] [ pc-hiword       ]
- *     32(sp) - [ format & vector ] [ pc-loword       ]
- *               ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
- *                     M68K              COLDFIRE
- */
-
-#define ALLOWINT (~0x700)
-
-#ifdef __ASSEMBLY__
-
-#define SWITCH_STACK_SIZE (6*4+4)      /* Includes return address */
-
-/*
- * This defines the normal kernel pt-regs layout.
- *
- * regs are a2-a6 and d6-d7 preserved by C code
- * the kernel doesn't mess with usp unless it needs to
- */
-
-#ifdef CONFIG_COLDFIRE
-#ifdef CONFIG_COLDFIRE_SW_A7
-/*
- * This is made a little more tricky on older ColdFires. There is no
- * separate supervisor and user stack pointers. Need to artificially
- * construct a usp in software... When doing this we need to disable
- * interrupts, otherwise bad things will happen.
- */
-.globl sw_usp
-.globl sw_ksp
-
-.macro SAVE_ALL
-       move    #0x2700,%sr             /* disable intrs */
-       btst    #5,%sp@(2)              /* from user? */
-       bnes    6f                      /* no, skip */
-       movel   %sp,sw_usp              /* save user sp */
-       addql   #8,sw_usp               /* remove exception */
-       movel   sw_ksp,%sp              /* kernel sp */
-       subql   #8,%sp                  /* room for exception */
-       clrl    %sp@-                   /* stkadj */
-       movel   %d0,%sp@-               /* orig d0 */
-       movel   %d0,%sp@-               /* d0 */
-       lea     %sp@(-32),%sp           /* space for 8 regs */
-       moveml  %d1-%d5/%a0-%a2,%sp@
-       movel   sw_usp,%a0              /* get usp */
-       movel   %a0@-,%sp@(PT_OFF_PC)   /* copy exception program counter */
-       movel   %a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
-       bra     7f
-       6:
-       clrl    %sp@-                   /* stkadj */
-       movel   %d0,%sp@-               /* orig d0 */
-       movel   %d0,%sp@-               /* d0 */
-       lea     %sp@(-32),%sp           /* space for 8 regs */
-       moveml  %d1-%d5/%a0-%a2,%sp@
-       7:
-.endm
-
-.macro RESTORE_USER
-       move    #0x2700,%sr             /* disable intrs */
-       movel   sw_usp,%a0              /* get usp */
-       movel   %sp@(PT_OFF_PC),%a0@-   /* copy exception program counter */
-       movel   %sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
-       moveml  %sp@,%d1-%d5/%a0-%a2
-       lea     %sp@(32),%sp            /* space for 8 regs */
-       movel   %sp@+,%d0
-       addql   #4,%sp                  /* orig d0 */
-       addl    %sp@+,%sp               /* stkadj */
-       addql   #8,%sp                  /* remove exception */
-       movel   %sp,sw_ksp              /* save ksp */
-       subql   #8,sw_usp               /* set exception */
-       movel   sw_usp,%sp              /* restore usp */
-       rte
-.endm
-
-.macro RDUSP
-       movel   sw_usp,%a3
-.endm
-
-.macro WRUSP
-       movel   %a3,sw_usp
-.endm
-
-#else /* !CONFIG_COLDFIRE_SW_A7 */
-/*
- * Modern ColdFire parts have separate supervisor and user stack
- * pointers. Simple load and restore macros for this case.
- */
-.macro SAVE_ALL
-       move    #0x2700,%sr             /* disable intrs */
-       clrl    %sp@-                   /* stkadj */
-       movel   %d0,%sp@-               /* orig d0 */
-       movel   %d0,%sp@-               /* d0 */
-       lea     %sp@(-32),%sp           /* space for 8 regs */
-       moveml  %d1-%d5/%a0-%a2,%sp@
-.endm
-
-.macro RESTORE_USER
-       moveml  %sp@,%d1-%d5/%a0-%a2
-       lea     %sp@(32),%sp            /* space for 8 regs */
-       movel   %sp@+,%d0
-       addql   #4,%sp                  /* orig d0 */
-       addl    %sp@+,%sp               /* stkadj */
-       rte
-.endm
-
-.macro RDUSP
-       /*move  %usp,%a3*/
-       .word   0x4e6b
-.endm
-
-.macro WRUSP
-       /*move  %a3,%usp*/
-       .word   0x4e63
-.endm
-
-#endif /* !CONFIG_COLDFIRE_SW_A7 */
-
-.macro SAVE_SWITCH_STACK
-       lea     %sp@(-24),%sp           /* 6 regs */
-       moveml  %a3-%a6/%d6-%d7,%sp@
-.endm
-
-.macro RESTORE_SWITCH_STACK
-       moveml  %sp@,%a3-%a6/%d6-%d7
-       lea     %sp@(24),%sp            /* 6 regs */
-.endm
-
-#else /* !CONFIG_COLDFIRE */
-
-/*
- * Standard 68k interrupt entry and exit macros.
- */
-.macro SAVE_ALL
-       clrl    %sp@-                   /* stkadj */
-       movel   %d0,%sp@-               /* orig d0 */
-       movel   %d0,%sp@-               /* d0 */
-       moveml  %d1-%d5/%a0-%a2,%sp@-
-.endm
-
-.macro RESTORE_ALL
-       moveml  %sp@+,%a0-%a2/%d1-%d5
-       movel   %sp@+,%d0
-       addql   #4,%sp                  /* orig d0 */
-       addl    %sp@+,%sp               /* stkadj */
-       rte
-.endm
-
-.macro SAVE_SWITCH_STACK
-       moveml  %a3-%a6/%d6-%d7,%sp@-
-.endm
-
-.macro RESTORE_SWITCH_STACK
-       moveml  %sp@+,%a3-%a6/%d6-%d7
-.endm
-
-#endif /* !COLDFIRE_SW_A7 */
-#endif /* __ASSEMBLY__ */
-#endif /* __M68KNOMMU_ENTRY_H */
index b6bf2c518baccd4314dd7aee3aa1053a092ef669..eda62de7e607aeb07132a96bbb995caf28a90b49 100644 (file)
 #define MCFGPIO_PDDR_FECH              0xFC0A4013
 #define MCFGPIO_PDDR_FECL              0xFC0A4014
 
-#define MCFGPIO_PPDSDR_BUSCTL          0xFC0A401A
-#define MCFGPIO_PPDSDR_BE              0xFC0A401B
-#define MCFGPIO_PPDSDR_CS              0xFC0A401C
-#define MCFGPIO_PPDSDR_FECI2C          0xFC0A401D
-#define MCFGPIO_PPDSDR_QSPI            0xFC0A401E
-#define MCFGPIO_PPDSDR_TIMER           0xFC0A401F
-#define MCFGPIO_PPDSDR_UART            0xFC0A4021
-#define MCFGPIO_PPDSDR_FECH            0xFC0A4021
-#define MCFGPIO_PPDSDR_FECL            0xFC0A4022
+#define MCFGPIO_PPDSDR_CS              0xFC0A401A
+#define MCFGPIO_PPDSDR_FECI2C          0xFC0A401B
+#define MCFGPIO_PPDSDR_QSPI            0xFC0A401C
+#define MCFGPIO_PPDSDR_TIMER           0xFC0A401D
+#define MCFGPIO_PPDSDR_UART            0xFC0A401E
+#define MCFGPIO_PPDSDR_FECH            0xFC0A401F
+#define MCFGPIO_PPDSDR_FECL            0xFC0A4020
 
 #define MCFGPIO_PCLRR_BUSCTL           0xFC0A4024
 #define MCFGPIO_PCLRR_BE               0xFC0A4025
 /*
  * Generic GPIO support
  */
-#define MCFGPIO_PODR                   MCFGPIO_PODR_BUSCTL
-#define MCFGPIO_PDDR                   MCFGPIO_PDDR_BUSCTL
-#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_BUSCTL
-#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_BUSCTL
-#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_BUSCTL
+#define MCFGPIO_PODR                   MCFGPIO_PODR_CS
+#define MCFGPIO_PDDR                   MCFGPIO_PDDR_CS
+#define MCFGPIO_PPDR                   MCFGPIO_PPDSDR_CS
+#define MCFGPIO_SETR                   MCFGPIO_PPDSDR_CS
+#define MCFGPIO_CLRR                   MCFGPIO_PCLRR_CS
 
 #define MCFGPIO_PIN_MAX                        80
 #define MCFGPIO_IRQ_MAX                        8
index 39d90d51111d76dab3a63d0e44d0f374ac9c6cd6..7fe631972f1f5192acfb0e3f11229246b42e31ae 100644 (file)
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
 #define        MCFQSPI_IOBASE          (MCF_IPSBAR + 0x340)
 #elif defined(CONFIG_M5249)
-#define MCFQSPI_IOBASE         (MCF_MBAR + 0x300)
-#elif defined(CONFIG_M520x) || defined(CONFIG_M532x)
-#define MCFQSPI_IOBASE         0xFC058000
+#define MCFQSPI_IOBASE         (MCF_MBAR + 0x300)
+#elif defined(CONFIG_M520x)
+#define MCFQSPI_IOBASE         0xFC05C000
+#elif defined(CONFIG_M532x)
+#define MCFQSPI_IOBASE         0xFC058000
 #endif
 #define MCFQSPI_IOSIZE         0x40
 
index 31d5570d65676784afd92a95665073e9179bb2e2..89f201434b5aa2575a5837bc6730346e06cc7e30 100644 (file)
@@ -162,7 +162,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
        pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn);          \
 })
 #define page_to_pfn(_page) ({                                          \
-       struct page *__p = (_page);                                     \
+       const struct page *__p = (_page);                               \
        struct pglist_data *pgdat;                                      \
        pgdat = &pg_data_map[page_to_nid(__p)];                         \
        ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn;          \
index 90595721185fc20a4b3ba79cacab1461fd50e3b4..a8d1c60eb9cec846ad26662497513f676623c7e1 100644 (file)
@@ -5,6 +5,9 @@
  
 extern unsigned long memory_start;
 extern unsigned long memory_end;
+extern unsigned long _rambase;
+extern unsigned long _ramstart;
+extern unsigned long _ramend;
 
 #define get_user_page(vaddr)           __get_free_page(GFP_KERNEL)
 #define free_user_page(page, addr)     free_page(addr)
index d8ef53ac03f92fbaa4f1d92d0c58076b9791aa55..568facf30276693e1ae7466b95c26b1e34e71ef0 100644 (file)
@@ -135,6 +135,12 @@ do {                                                    \
        wrusp(_usp);                                    \
 } while(0)
 
+static inline  int handle_kernel_fault(struct pt_regs *regs)
+{
+       /* Any fault in kernel is fatal on non-mmu */
+       return 0;
+}
+
 #endif
 
 /* Forward declaration, a strange C thing */
index d64967ecfec647e19e02caa8e279f4ea437aeb9e..5277e52715ec27cfd20d3c25dee440334ae510d9 100644 (file)
@@ -3,4 +3,6 @@
 
 #include <asm-generic/sections.h>
 
+extern char _sbss[], _ebss[];
+
 #endif /* _ASM_M68K_SECTIONS_H */
index 790988967ba7ed10ae54eb2dbc5e917012cff088..294df1592de51b2a254f8aa76dae35a5ec034e6b 100644 (file)
@@ -103,7 +103,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_DELAYED_TRACE      14      /* single step a syscall */
 #define TIF_SYSCALL_TRACE      15      /* syscall trace active */
 #define TIF_MEMDIE             16      /* is terminating due to OOM killer */
-#define TIF_FREEZE             17      /* thread is freezing for suspend */
 #define TIF_RESTORE_SIGMASK    18      /* restore signal mask in do_signal */
 
 #endif /* _ASM_M68K_THREAD_INFO_H */
index c482ebc9dd543515b1d413653a2f88616d1722f2..e7f0f2e5ad4478a767732c70f229b78aca753383 100644 (file)
@@ -1,5 +1,21 @@
-ifdef CONFIG_MMU
-include arch/m68k/kernel/Makefile_mm
-else
-include arch/m68k/kernel/Makefile_no
+#
+# Makefile for the linux kernel.
+#
+
+extra-$(CONFIG_MMU)    := head.o
+extra-$(CONFIG_SUN3)   := sun3-head.o
+extra-y                        += vmlinux.lds
+
+obj-y  := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \
+          sys_m68k.o syscalltable.o time.o traps.o
+
+obj-$(CONFIG_MMU)      += ints.o devres.o vectors.o
+devres-$(CONFIG_MMU)   = ../../../kernel/irq/devres.o
+
+ifndef CONFIG_MMU_SUN3
+obj-y                  += dma.o
 endif
+ifndef CONFIG_MMU
+obj-y                  += init_task.o irq.o
+endif
+
diff --git a/arch/m68k/kernel/Makefile_mm b/arch/m68k/kernel/Makefile_mm
deleted file mode 100644 (file)
index aced678..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-ifndef CONFIG_SUN3
-  extra-y := head.o
-else
-  extra-y := sun3-head.o
-endif
-extra-y        += vmlinux.lds
-
-obj-y  := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
-          sys_m68k.o time.o setup.o m68k_ksyms.o devres.o syscalltable.o
-
-devres-y = ../../../kernel/irq/devres.o
-
-obj-y$(CONFIG_MMU_SUN3) += dma.o       # no, it's not a typo
diff --git a/arch/m68k/kernel/Makefile_no b/arch/m68k/kernel/Makefile_no
deleted file mode 100644 (file)
index 37c3fc0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for arch/m68knommu/kernel.
-#
-
-extra-y := vmlinux.lds
-
-obj-y += dma.o entry.o init_task.o irq.o m68k_ksyms.o process.o ptrace.o \
-        setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o
-
-obj-$(CONFIG_MODULES)  += module.o
index 5f0f6b598b5a6d1ee347436f6f7232491ca9ae36..1b4289061a64a6ea261e2bce71eed7f2fb573e87 100644 (file)
@@ -43,7 +43,7 @@
 .globl sys_vfork
 
 ENTRY(buserr)
-       SAVE_ALL
+       SAVE_ALL_INT
        moveq   #-1,%d0
        movel   %d0,%sp@(PT_OFF_ORIG_D0)
        movel   %sp,%sp@-               /* stack frame pointer argument */
@@ -52,7 +52,7 @@ ENTRY(buserr)
        jra     ret_from_exception
 
 ENTRY(trap)
-       SAVE_ALL
+       SAVE_ALL_INT
        moveq   #-1,%d0
        movel   %d0,%sp@(PT_OFF_ORIG_D0)
        movel   %sp,%sp@-               /* stack frame pointer argument */
@@ -64,7 +64,7 @@ ENTRY(trap)
 
 .globl dbginterrupt
 ENTRY(dbginterrupt)
-       SAVE_ALL
+       SAVE_ALL_INT
        moveq   #-1,%d0
        movel   %d0,%sp@(PT_OFF_ORIG_D0)
        movel   %sp,%sp@-               /* stack frame pointer argument */
index 16b2de7f51013b10d17033bc4520b741d71fac4f..2ed8c0fb1517defe078c1aa38b8f4b7fbf9bf865 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/pgtable.h>
+#include <asm/sections.h>
 
 unsigned long memory_start;
 unsigned long memory_end;
@@ -80,9 +81,6 @@ void (*mach_power_off)(void);
 #define        CPU_INSTR_PER_JIFFY     16
 #endif
 
-extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
-extern int _ramstart, _ramend;
-
 #if defined(CONFIG_UBOOT)
 /*
  * parse_uboot_commandline
index c98add3f5f0f45b106925a4f79be435ee83443c2..89362f2bb56a3e8bae88a364a1b06de7a68e8a61 100644 (file)
-#ifdef CONFIG_MMU
-#include "traps_mm.c"
+/*
+ *  linux/arch/m68k/kernel/traps.c
+ *
+ *  Copyright (C) 1993, 1994 by Hamish Macdonald
+ *
+ *  68040 fixes by Michael Rausch
+ *  68040 fixes by Martin Apel
+ *  68040 fixes and writeback by Richard Zidlicky
+ *  68060 fixes by Roman Hodek
+ *  68060 fixes by Jesper Skov
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Sets up all exception vectors
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+#include <linux/kallsyms.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/pgalloc.h>
+#include <asm/machdep.h>
+#include <asm/siginfo.h>
+
+
+static const char *vec_names[] = {
+       [VEC_RESETSP]   = "RESET SP",
+       [VEC_RESETPC]   = "RESET PC",
+       [VEC_BUSERR]    = "BUS ERROR",
+       [VEC_ADDRERR]   = "ADDRESS ERROR",
+       [VEC_ILLEGAL]   = "ILLEGAL INSTRUCTION",
+       [VEC_ZERODIV]   = "ZERO DIVIDE",
+       [VEC_CHK]       = "CHK",
+       [VEC_TRAP]      = "TRAPcc",
+       [VEC_PRIV]      = "PRIVILEGE VIOLATION",
+       [VEC_TRACE]     = "TRACE",
+       [VEC_LINE10]    = "LINE 1010",
+       [VEC_LINE11]    = "LINE 1111",
+       [VEC_RESV12]    = "UNASSIGNED RESERVED 12",
+       [VEC_COPROC]    = "COPROCESSOR PROTOCOL VIOLATION",
+       [VEC_FORMAT]    = "FORMAT ERROR",
+       [VEC_UNINT]     = "UNINITIALIZED INTERRUPT",
+       [VEC_RESV16]    = "UNASSIGNED RESERVED 16",
+       [VEC_RESV17]    = "UNASSIGNED RESERVED 17",
+       [VEC_RESV18]    = "UNASSIGNED RESERVED 18",
+       [VEC_RESV19]    = "UNASSIGNED RESERVED 19",
+       [VEC_RESV20]    = "UNASSIGNED RESERVED 20",
+       [VEC_RESV21]    = "UNASSIGNED RESERVED 21",
+       [VEC_RESV22]    = "UNASSIGNED RESERVED 22",
+       [VEC_RESV23]    = "UNASSIGNED RESERVED 23",
+       [VEC_SPUR]      = "SPURIOUS INTERRUPT",
+       [VEC_INT1]      = "LEVEL 1 INT",
+       [VEC_INT2]      = "LEVEL 2 INT",
+       [VEC_INT3]      = "LEVEL 3 INT",
+       [VEC_INT4]      = "LEVEL 4 INT",
+       [VEC_INT5]      = "LEVEL 5 INT",
+       [VEC_INT6]      = "LEVEL 6 INT",
+       [VEC_INT7]      = "LEVEL 7 INT",
+       [VEC_SYS]       = "SYSCALL",
+       [VEC_TRAP1]     = "TRAP #1",
+       [VEC_TRAP2]     = "TRAP #2",
+       [VEC_TRAP3]     = "TRAP #3",
+       [VEC_TRAP4]     = "TRAP #4",
+       [VEC_TRAP5]     = "TRAP #5",
+       [VEC_TRAP6]     = "TRAP #6",
+       [VEC_TRAP7]     = "TRAP #7",
+       [VEC_TRAP8]     = "TRAP #8",
+       [VEC_TRAP9]     = "TRAP #9",
+       [VEC_TRAP10]    = "TRAP #10",
+       [VEC_TRAP11]    = "TRAP #11",
+       [VEC_TRAP12]    = "TRAP #12",
+       [VEC_TRAP13]    = "TRAP #13",
+       [VEC_TRAP14]    = "TRAP #14",
+       [VEC_TRAP15]    = "TRAP #15",
+       [VEC_FPBRUC]    = "FPCP BSUN",
+       [VEC_FPIR]      = "FPCP INEXACT",
+       [VEC_FPDIVZ]    = "FPCP DIV BY 0",
+       [VEC_FPUNDER]   = "FPCP UNDERFLOW",
+       [VEC_FPOE]      = "FPCP OPERAND ERROR",
+       [VEC_FPOVER]    = "FPCP OVERFLOW",
+       [VEC_FPNAN]     = "FPCP SNAN",
+       [VEC_FPUNSUP]   = "FPCP UNSUPPORTED OPERATION",
+       [VEC_MMUCFG]    = "MMU CONFIGURATION ERROR",
+       [VEC_MMUILL]    = "MMU ILLEGAL OPERATION ERROR",
+       [VEC_MMUACC]    = "MMU ACCESS LEVEL VIOLATION ERROR",
+       [VEC_RESV59]    = "UNASSIGNED RESERVED 59",
+       [VEC_UNIMPEA]   = "UNASSIGNED RESERVED 60",
+       [VEC_UNIMPII]   = "UNASSIGNED RESERVED 61",
+       [VEC_RESV62]    = "UNASSIGNED RESERVED 62",
+       [VEC_RESV63]    = "UNASSIGNED RESERVED 63",
+};
+
+static const char *space_names[] = {
+       [0]             = "Space 0",
+       [USER_DATA]     = "User Data",
+       [USER_PROGRAM]  = "User Program",
+#ifndef CONFIG_SUN3
+       [3]             = "Space 3",
 #else
-#include "traps_no.c"
+       [FC_CONTROL]    = "Control",
+#endif
+       [4]             = "Space 4",
+       [SUPER_DATA]    = "Super Data",
+       [SUPER_PROGRAM] = "Super Program",
+       [CPU_SPACE]     = "CPU"
+};
+
+void die_if_kernel(char *,struct pt_regs *,int);
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+                             unsigned long error_code);
+int send_fault_sig(struct pt_regs *regs);
+
+asmlinkage void trap_c(struct frame *fp);
+
+#if defined (CONFIG_M68060)
+static inline void access_error060 (struct frame *fp)
+{
+       unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
+
+#ifdef DEBUG
+       printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
+#endif
+
+       if (fslw & MMU060_BPE) {
+               /* branch prediction error -> clear branch cache */
+               __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
+                                     "orl   #0x00400000,%/d0\n\t"
+                                     "movec %/d0,%/cacr"
+                                     : : : "d0" );
+               /* return if there's no other error */
+               if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))
+                       return;
+       }
+
+       if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
+               unsigned long errorcode;
+               unsigned long addr = fp->un.fmt4.effaddr;
+
+               if (fslw & MMU060_MA)
+                       addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
+
+               errorcode = 1;
+               if (fslw & MMU060_DESC_ERR) {
+                       __flush_tlb040_one(addr);
+                       errorcode = 0;
+               }
+               if (fslw & MMU060_W)
+                       errorcode |= 2;
+#ifdef DEBUG
+               printk("errorcode = %d\n", errorcode );
+#endif
+               do_page_fault(&fp->ptregs, addr, errorcode);
+       } else if (fslw & (MMU060_SEE)){
+               /* Software Emulation Error.
+                * fault during mem_read/mem_write in ifpsp060/os.S
+                */
+               send_fault_sig(&fp->ptregs);
+       } else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
+                  send_fault_sig(&fp->ptregs) > 0) {
+               printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
+               printk( "68060 access error, fslw=%lx\n", fslw );
+               trap_c( fp );
+       }
+}
+#endif /* CONFIG_M68060 */
+
+#if defined (CONFIG_M68040)
+static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
+{
+       unsigned long mmusr;
+       mm_segment_t old_fs = get_fs();
+
+       set_fs(MAKE_MM_SEG(wbs));
+
+       if (iswrite)
+               asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
+       else
+               asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
+
+       asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
+
+       set_fs(old_fs);
+
+       return mmusr;
+}
+
+static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
+                                  unsigned long wbd)
+{
+       int res = 0;
+       mm_segment_t old_fs = get_fs();
+
+       /* set_fs can not be moved, otherwise put_user() may oops */
+       set_fs(MAKE_MM_SEG(wbs));
+
+       switch (wbs & WBSIZ_040) {
+       case BA_SIZE_BYTE:
+               res = put_user(wbd & 0xff, (char __user *)wba);
+               break;
+       case BA_SIZE_WORD:
+               res = put_user(wbd & 0xffff, (short __user *)wba);
+               break;
+       case BA_SIZE_LONG:
+               res = put_user(wbd, (int __user *)wba);
+               break;
+       }
+
+       /* set_fs can not be moved, otherwise put_user() may oops */
+       set_fs(old_fs);
+
+
+#ifdef DEBUG
+       printk("do_040writeback1, res=%d\n",res);
+#endif
+
+       return res;
+}
+
+/* after an exception in a writeback the stack frame corresponding
+ * to that exception is discarded, set a few bits in the old frame
+ * to simulate what it should look like
+ */
+static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
+{
+       fp->un.fmt7.faddr = wba;
+       fp->un.fmt7.ssw = wbs & 0xff;
+       if (wba != current->thread.faddr)
+           fp->un.fmt7.ssw |= MA_040;
+}
+
+static inline void do_040writebacks(struct frame *fp)
+{
+       int res = 0;
+#if 0
+       if (fp->un.fmt7.wb1s & WBV_040)
+               printk("access_error040: cannot handle 1st writeback. oops.\n");
+#endif
+
+       if ((fp->un.fmt7.wb2s & WBV_040) &&
+           !(fp->un.fmt7.wb2s & WBTT_040)) {
+               res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
+                                      fp->un.fmt7.wb2d);
+               if (res)
+                       fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
+               else
+                       fp->un.fmt7.wb2s = 0;
+       }
+
+       /* do the 2nd wb only if the first one was successful (except for a kernel wb) */
+       if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
+               res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
+                                      fp->un.fmt7.wb3d);
+               if (res)
+                   {
+                       fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
+
+                       fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
+                       fp->un.fmt7.wb3s &= (~WBV_040);
+                       fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
+                       fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
+                   }
+               else
+                       fp->un.fmt7.wb3s = 0;
+       }
+
+       if (res)
+               send_fault_sig(&fp->ptregs);
+}
+
+/*
+ * called from sigreturn(), must ensure userspace code didn't
+ * manipulate exception frame to circumvent protection, then complete
+ * pending writebacks
+ * we just clear TM2 to turn it into a userspace access
+ */
+asmlinkage void berr_040cleanup(struct frame *fp)
+{
+       fp->un.fmt7.wb2s &= ~4;
+       fp->un.fmt7.wb3s &= ~4;
+
+       do_040writebacks(fp);
+}
+
+static inline void access_error040(struct frame *fp)
+{
+       unsigned short ssw = fp->un.fmt7.ssw;
+       unsigned long mmusr;
+
+#ifdef DEBUG
+       printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
+        printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
+               fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
+       printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
+               fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
+               fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
+#endif
+
+       if (ssw & ATC_040) {
+               unsigned long addr = fp->un.fmt7.faddr;
+               unsigned long errorcode;
+
+               /*
+                * The MMU status has to be determined AFTER the address
+                * has been corrected if there was a misaligned access (MA).
+                */
+               if (ssw & MA_040)
+                       addr = (addr + 7) & -8;
+
+               /* MMU error, get the MMUSR info for this access */
+               mmusr = probe040(!(ssw & RW_040), addr, ssw);
+#ifdef DEBUG
+               printk("mmusr = %lx\n", mmusr);
+#endif
+               errorcode = 1;
+               if (!(mmusr & MMU_R_040)) {
+                       /* clear the invalid atc entry */
+                       __flush_tlb040_one(addr);
+                       errorcode = 0;
+               }
+
+               /* despite what documentation seems to say, RMW
+                * accesses have always both the LK and RW bits set */
+               if (!(ssw & RW_040) || (ssw & LK_040))
+                       errorcode |= 2;
+
+               if (do_page_fault(&fp->ptregs, addr, errorcode)) {
+#ifdef DEBUG
+                       printk("do_page_fault() !=0\n");
+#endif
+                       if (user_mode(&fp->ptregs)){
+                               /* delay writebacks after signal delivery */
+#ifdef DEBUG
+                               printk(".. was usermode - return\n");
+#endif
+                               return;
+                       }
+                       /* disable writeback into user space from kernel
+                        * (if do_page_fault didn't fix the mapping,
+                         * the writeback won't do good)
+                        */
+disable_wb:
+#ifdef DEBUG
+                       printk(".. disabling wb2\n");
+#endif
+                       if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
+                               fp->un.fmt7.wb2s &= ~WBV_040;
+                       if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
+                               fp->un.fmt7.wb3s &= ~WBV_040;
+               }
+       } else {
+               /* In case of a bus error we either kill the process or expect
+                * the kernel to catch the fault, which then is also responsible
+                * for cleaning up the mess.
+                */
+               current->thread.signo = SIGBUS;
+               current->thread.faddr = fp->un.fmt7.faddr;
+               if (send_fault_sig(&fp->ptregs) >= 0)
+                       printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
+                              fp->un.fmt7.faddr);
+               goto disable_wb;
+       }
+
+       do_040writebacks(fp);
+}
+#endif /* CONFIG_M68040 */
+
+#if defined(CONFIG_SUN3)
+#include <asm/sun3mmu.h>
+
+extern int mmu_emu_handle_fault (unsigned long, int, int);
+
+/* sun3 version of bus_error030 */
+
+static inline void bus_error030 (struct frame *fp)
+{
+       unsigned char buserr_type = sun3_get_buserr ();
+       unsigned long addr, errorcode;
+       unsigned short ssw = fp->un.fmtb.ssw;
+       extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
+
+#ifdef DEBUG
+       if (ssw & (FC | FB))
+               printk ("Instruction fault at %#010lx\n",
+                       ssw & FC ?
+                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
+                       :
+                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
+       if (ssw & DF)
+               printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+                       ssw & RW ? "read" : "write",
+                       fp->un.fmtb.daddr,
+                       space_names[ssw & DFC], fp->ptregs.pc);
+#endif
+
+       /*
+        * Check if this page should be demand-mapped. This needs to go before
+        * the testing for a bad kernel-space access (demand-mapping applies
+        * to kernel accesses too).
+        */
+
+       if ((ssw & DF)
+           && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
+               if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
+                       return;
+       }
+
+       /* Check for kernel-space pagefault (BAD). */
+       if (fp->ptregs.sr & PS_S) {
+               /* kernel fault must be a data fault to user space */
+               if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
+                    // try checking the kernel mappings before surrender
+                    if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
+                         return;
+                       /* instruction fault or kernel data fault! */
+                       if (ssw & (FC | FB))
+                               printk ("Instruction fault at %#010lx\n",
+                                       fp->ptregs.pc);
+                       if (ssw & DF) {
+                               /* was this fault incurred testing bus mappings? */
+                               if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
+                                  (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
+                                       send_fault_sig(&fp->ptregs);
+                                       return;
+                               }
+
+                               printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+                                       ssw & RW ? "read" : "write",
+                                       fp->un.fmtb.daddr,
+                                       space_names[ssw & DFC], fp->ptregs.pc);
+                       }
+                       printk ("BAD KERNEL BUSERR\n");
+
+                       die_if_kernel("Oops", &fp->ptregs,0);
+                       force_sig(SIGKILL, current);
+                       return;
+               }
+       } else {
+               /* user fault */
+               if (!(ssw & (FC | FB)) && !(ssw & DF))
+                       /* not an instruction fault or data fault! BAD */
+                       panic ("USER BUSERR w/o instruction or data fault");
+       }
+
+
+       /* First handle the data fault, if any.  */
+       if (ssw & DF) {
+               addr = fp->un.fmtb.daddr;
+
+// errorcode bit 0:    0 -> no page            1 -> protection fault
+// errorcode bit 1:    0 -> read fault         1 -> write fault
+
+// (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault
+// (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault
+
+               if (buserr_type & SUN3_BUSERR_PROTERR)
+                       errorcode = 0x01;
+               else if (buserr_type & SUN3_BUSERR_INVALID)
+                       errorcode = 0x00;
+               else {
+#ifdef DEBUG
+                       printk ("*** unexpected busfault type=%#04x\n", buserr_type);
+                       printk ("invalid %s access at %#lx from pc %#lx\n",
+                               !(ssw & RW) ? "write" : "read", addr,
+                               fp->ptregs.pc);
+#endif
+                       die_if_kernel ("Oops", &fp->ptregs, buserr_type);
+                       force_sig (SIGBUS, current);
+                       return;
+               }
+
+//todo: wtf is RM bit? --m
+               if (!(ssw & RW) || ssw & RM)
+                       errorcode |= 0x02;
+
+               /* Handle page fault. */
+               do_page_fault (&fp->ptregs, addr, errorcode);
+
+               /* Retry the data fault now. */
+               return;
+       }
+
+       /* Now handle the instruction fault. */
+
+       /* Get the fault address. */
+       if (fp->ptregs.format == 0xA)
+               addr = fp->ptregs.pc + 4;
+       else
+               addr = fp->un.fmtb.baddr;
+       if (ssw & FC)
+               addr -= 2;
+
+       if (buserr_type & SUN3_BUSERR_INVALID) {
+               if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))
+                       do_page_fault (&fp->ptregs, addr, 0);
+       } else {
+#ifdef DEBUG
+               printk ("protection fault on insn access (segv).\n");
+#endif
+               force_sig (SIGSEGV, current);
+       }
+}
+#else
+#if defined(CPU_M68020_OR_M68030)
+static inline void bus_error030 (struct frame *fp)
+{
+       volatile unsigned short temp;
+       unsigned short mmusr;
+       unsigned long addr, errorcode;
+       unsigned short ssw = fp->un.fmtb.ssw;
+#ifdef DEBUG
+       unsigned long desc;
+
+       printk ("pid = %x  ", current->pid);
+       printk ("SSW=%#06x  ", ssw);
+
+       if (ssw & (FC | FB))
+               printk ("Instruction fault at %#010lx\n",
+                       ssw & FC ?
+                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
+                       :
+                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
+       if (ssw & DF)
+               printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+                       ssw & RW ? "read" : "write",
+                       fp->un.fmtb.daddr,
+                       space_names[ssw & DFC], fp->ptregs.pc);
+#endif
+
+       /* ++andreas: If a data fault and an instruction fault happen
+          at the same time map in both pages.  */
+
+       /* First handle the data fault, if any.  */
+       if (ssw & DF) {
+               addr = fp->un.fmtb.daddr;
+
+#ifdef DEBUG
+               asm volatile ("ptestr %3,%2@,#7,%0\n\t"
+                             "pmove %%psr,%1@"
+                             : "=a&" (desc)
+                             : "a" (&temp), "a" (addr), "d" (ssw));
+#else
+               asm volatile ("ptestr %2,%1@,#7\n\t"
+                             "pmove %%psr,%0@"
+                             : : "a" (&temp), "a" (addr), "d" (ssw));
+#endif
+               mmusr = temp;
+
+#ifdef DEBUG
+               printk("mmusr is %#x for addr %#lx in task %p\n",
+                      mmusr, addr, current);
+               printk("descriptor address is %#lx, contents %#lx\n",
+                      __va(desc), *(unsigned long *)__va(desc));
+#endif
+
+               errorcode = (mmusr & MMU_I) ? 0 : 1;
+               if (!(ssw & RW) || (ssw & RM))
+                       errorcode |= 2;
+
+               if (mmusr & (MMU_I | MMU_WP)) {
+                       if (ssw & 4) {
+                               printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+                                      ssw & RW ? "read" : "write",
+                                      fp->un.fmtb.daddr,
+                                      space_names[ssw & DFC], fp->ptregs.pc);
+                               goto buserr;
+                       }
+                       /* Don't try to do anything further if an exception was
+                          handled. */
+                       if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
+                               return;
+               } else if (!(mmusr & MMU_I)) {
+                       /* probably a 020 cas fault */
+                       if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
+                               printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);
+               } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+                       printk("invalid %s access at %#lx from pc %#lx\n",
+                              !(ssw & RW) ? "write" : "read", addr,
+                              fp->ptregs.pc);
+                       die_if_kernel("Oops",&fp->ptregs,mmusr);
+                       force_sig(SIGSEGV, current);
+                       return;
+               } else {
+#if 0
+                       static volatile long tlong;
+#endif
+
+                       printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
+                              !(ssw & RW) ? "write" : "read", addr,
+                              fp->ptregs.pc, ssw);
+                       asm volatile ("ptestr #1,%1@,#0\n\t"
+                                     "pmove %%psr,%0@"
+                                     : /* no outputs */
+                                     : "a" (&temp), "a" (addr));
+                       mmusr = temp;
+
+                       printk ("level 0 mmusr is %#x\n", mmusr);
+#if 0
+                       asm volatile ("pmove %%tt0,%0@"
+                                     : /* no outputs */
+                                     : "a" (&tlong));
+                       printk("tt0 is %#lx, ", tlong);
+                       asm volatile ("pmove %%tt1,%0@"
+                                     : /* no outputs */
+                                     : "a" (&tlong));
+                       printk("tt1 is %#lx\n", tlong);
+#endif
+#ifdef DEBUG
+                       printk("Unknown SIGSEGV - 1\n");
+#endif
+                       die_if_kernel("Oops",&fp->ptregs,mmusr);
+                       force_sig(SIGSEGV, current);
+                       return;
+               }
+
+               /* setup an ATC entry for the access about to be retried */
+               if (!(ssw & RW) || (ssw & RM))
+                       asm volatile ("ploadw %1,%0@" : /* no outputs */
+                                     : "a" (addr), "d" (ssw));
+               else
+                       asm volatile ("ploadr %1,%0@" : /* no outputs */
+                                     : "a" (addr), "d" (ssw));
+       }
+
+       /* Now handle the instruction fault. */
+
+       if (!(ssw & (FC|FB)))
+               return;
+
+       if (fp->ptregs.sr & PS_S) {
+               printk("Instruction fault at %#010lx\n",
+                       fp->ptregs.pc);
+       buserr:
+               printk ("BAD KERNEL BUSERR\n");
+               die_if_kernel("Oops",&fp->ptregs,0);
+               force_sig(SIGKILL, current);
+               return;
+       }
+
+       /* get the fault address */
+       if (fp->ptregs.format == 10)
+               addr = fp->ptregs.pc + 4;
+       else
+               addr = fp->un.fmtb.baddr;
+       if (ssw & FC)
+               addr -= 2;
+
+       if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
+               /* Insn fault on same page as data fault.  But we
+                  should still create the ATC entry.  */
+               goto create_atc_entry;
+
+#ifdef DEBUG
+       asm volatile ("ptestr #1,%2@,#7,%0\n\t"
+                     "pmove %%psr,%1@"
+                     : "=a&" (desc)
+                     : "a" (&temp), "a" (addr));
+#else
+       asm volatile ("ptestr #1,%1@,#7\n\t"
+                     "pmove %%psr,%0@"
+                     : : "a" (&temp), "a" (addr));
+#endif
+       mmusr = temp;
+
+#ifdef DEBUG
+       printk ("mmusr is %#x for addr %#lx in task %p\n",
+               mmusr, addr, current);
+       printk ("descriptor address is %#lx, contents %#lx\n",
+               __va(desc), *(unsigned long *)__va(desc));
+#endif
+
+       if (mmusr & MMU_I)
+               do_page_fault (&fp->ptregs, addr, 0);
+       else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+               printk ("invalid insn access at %#lx from pc %#lx\n",
+                       addr, fp->ptregs.pc);
+#ifdef DEBUG
+               printk("Unknown SIGSEGV - 2\n");
+#endif
+               die_if_kernel("Oops",&fp->ptregs,mmusr);
+               force_sig(SIGSEGV, current);
+               return;
+       }
+
+create_atc_entry:
+       /* setup an ATC entry for the access about to be retried */
+       asm volatile ("ploadr #2,%0@" : /* no outputs */
+                     : "a" (addr));
+}
+#endif /* CPU_M68020_OR_M68030 */
+#endif /* !CONFIG_SUN3 */
+
+asmlinkage void buserr_c(struct frame *fp)
+{
+       /* Only set esp0 if coming from user mode */
+       if (user_mode(&fp->ptregs))
+               current->thread.esp0 = (unsigned long) fp;
+
+#ifdef DEBUG
+       printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
+#endif
+
+       switch (fp->ptregs.format) {
+#if defined (CONFIG_M68060)
+       case 4:                         /* 68060 access error */
+         access_error060 (fp);
+         break;
+#endif
+#if defined (CONFIG_M68040)
+       case 0x7:                       /* 68040 access error */
+         access_error040 (fp);
+         break;
+#endif
+#if defined (CPU_M68020_OR_M68030)
+       case 0xa:
+       case 0xb:
+         bus_error030 (fp);
+         break;
+#endif
+       default:
+         die_if_kernel("bad frame format",&fp->ptregs,0);
+#ifdef DEBUG
+         printk("Unknown SIGSEGV - 4\n");
+#endif
+         force_sig(SIGSEGV, current);
+       }
+}
+
+
+static int kstack_depth_to_print = 48;
+
+void show_trace(unsigned long *stack)
+{
+       unsigned long *endstack;
+       unsigned long addr;
+       int i;
+
+       printk("Call Trace:");
+       addr = (unsigned long)stack + THREAD_SIZE - 1;
+       endstack = (unsigned long *)(addr & -THREAD_SIZE);
+       i = 0;
+       while (stack + 1 <= endstack) {
+               addr = *stack++;
+               /*
+                * If the address is either in the text segment of the
+                * kernel, or in the region which contains vmalloc'ed
+                * memory, it *may* be the address of a calling
+                * routine; if so, print it so that someone tracing
+                * down the cause of the crash will be able to figure
+                * out the call path that was taken.
+                */
+               if (__kernel_text_address(addr)) {
+#ifndef CONFIG_KALLSYMS
+                       if (i % 5 == 0)
+                               printk("\n       ");
+#endif
+                       printk(" [<%08lx>] %pS\n", addr, (void *)addr);
+                       i++;
+               }
+       }
+       printk("\n");
+}
+
+void show_registers(struct pt_regs *regs)
+{
+       struct frame *fp = (struct frame *)regs;
+       mm_segment_t old_fs = get_fs();
+       u16 c, *cp;
+       unsigned long addr;
+       int i;
+
+       print_modules();
+       printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
+       printk("SR: %04x  SP: %p  a2: %08lx\n", regs->sr, regs, regs->a2);
+       printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
+              regs->d0, regs->d1, regs->d2, regs->d3);
+       printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
+              regs->d4, regs->d5, regs->a0, regs->a1);
+
+       printk("Process %s (pid: %d, task=%p)\n",
+               current->comm, task_pid_nr(current), current);
+       addr = (unsigned long)&fp->un;
+       printk("Frame format=%X ", regs->format);
+       switch (regs->format) {
+       case 0x2:
+               printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
+               addr += sizeof(fp->un.fmt2);
+               break;
+       case 0x3:
+               printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
+               addr += sizeof(fp->un.fmt3);
+               break;
+       case 0x4:
+               printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
+                       : "eff addr=%08lx pc=%08lx\n"),
+                       fp->un.fmt4.effaddr, fp->un.fmt4.pc);
+               addr += sizeof(fp->un.fmt4);
+               break;
+       case 0x7:
+               printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
+                       fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
+               printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
+                       fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
+               printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
+                       fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
+               printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
+                       fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
+               printk("push data: %08lx %08lx %08lx %08lx\n",
+                       fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
+                       fp->un.fmt7.pd3);
+               addr += sizeof(fp->un.fmt7);
+               break;
+       case 0x9:
+               printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
+               addr += sizeof(fp->un.fmt9);
+               break;
+       case 0xa:
+               printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
+                       fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
+                       fp->un.fmta.daddr, fp->un.fmta.dobuf);
+               addr += sizeof(fp->un.fmta);
+               break;
+       case 0xb:
+               printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
+                       fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
+                       fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
+               printk("baddr=%08lx dibuf=%08lx ver=%x\n",
+                       fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
+               addr += sizeof(fp->un.fmtb);
+               break;
+       default:
+               printk("\n");
+       }
+       show_stack(NULL, (unsigned long *)addr);
+
+       printk("Code:");
+       set_fs(KERNEL_DS);
+       cp = (u16 *)regs->pc;
+       for (i = -8; i < 16; i++) {
+               if (get_user(c, cp + i) && i >= 0) {
+                       printk(" Bad PC value.");
+                       break;
+               }
+               printk(i ? " %04x" : " <%04x>", c);
+       }
+       set_fs(old_fs);
+       printk ("\n");
+}
+
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+       unsigned long *p;
+       unsigned long *endstack;
+       int i;
+
+       if (!stack) {
+               if (task)
+                       stack = (unsigned long *)task->thread.esp0;
+               else
+                       stack = (unsigned long *)&stack;
+       }
+       endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
+
+       printk("Stack from %08lx:", (unsigned long)stack);
+       p = stack;
+       for (i = 0; i < kstack_depth_to_print; i++) {
+               if (p + 1 > endstack)
+                       break;
+               if (i % 8 == 0)
+                       printk("\n       ");
+               printk(" %08lx", *p++);
+       }
+       printk("\n");
+       show_trace(stack);
+}
+
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+       unsigned long stack;
+
+       show_trace(&stack);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+/*
+ * The vector number returned in the frame pointer may also contain
+ * the "fs" (Fault Status) bits on ColdFire. These are in the bottom
+ * 2 bits, and upper 2 bits. So we need to mask out the real vector
+ * number before using it in comparisons. You don't need to do this on
+ * real 68k parts, but it won't hurt either.
+ */
+
+void bad_super_trap (struct frame *fp)
+{
+       int vector = (fp->ptregs.vector >> 2) & 0xff;
+
+       console_verbose();
+       if (vector < ARRAY_SIZE(vec_names))
+               printk ("*** %s ***   FORMAT=%X\n",
+                       vec_names[vector],
+                       fp->ptregs.format);
+       else
+               printk ("*** Exception %d ***   FORMAT=%X\n",
+                       vector, fp->ptregs.format);
+       if (vector == VEC_ADDRERR && CPU_IS_020_OR_030) {
+               unsigned short ssw = fp->un.fmtb.ssw;
+
+               printk ("SSW=%#06x  ", ssw);
+
+               if (ssw & RC)
+                       printk ("Pipe stage C instruction fault at %#010lx\n",
+                               (fp->ptregs.format) == 0xA ?
+                               fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
+               if (ssw & RB)
+                       printk ("Pipe stage B instruction fault at %#010lx\n",
+                               (fp->ptregs.format) == 0xA ?
+                               fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
+               if (ssw & DF)
+                       printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+                               ssw & RW ? "read" : "write",
+                               fp->un.fmtb.daddr, space_names[ssw & DFC],
+                               fp->ptregs.pc);
+       }
+       printk ("Current process id is %d\n", task_pid_nr(current));
+       die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
+}
+
+asmlinkage void trap_c(struct frame *fp)
+{
+       int sig;
+       int vector = (fp->ptregs.vector >> 2) & 0xff;
+       siginfo_t info;
+
+       if (fp->ptregs.sr & PS_S) {
+               if (vector == VEC_TRACE) {
+                       /* traced a trapping instruction on a 68020/30,
+                        * real exception will be executed afterwards.
+                        */
+               } else if (!handle_kernel_fault(&fp->ptregs))
+                       bad_super_trap(fp);
+               return;
+       }
+
+       /* send the appropriate signal to the user program */
+       switch (vector) {
+           case VEC_ADDRERR:
+               info.si_code = BUS_ADRALN;
+               sig = SIGBUS;
+               break;
+           case VEC_ILLEGAL:
+           case VEC_LINE10:
+           case VEC_LINE11:
+               info.si_code = ILL_ILLOPC;
+               sig = SIGILL;
+               break;
+           case VEC_PRIV:
+               info.si_code = ILL_PRVOPC;
+               sig = SIGILL;
+               break;
+           case VEC_COPROC:
+               info.si_code = ILL_COPROC;
+               sig = SIGILL;
+               break;
+           case VEC_TRAP1:
+           case VEC_TRAP2:
+           case VEC_TRAP3:
+           case VEC_TRAP4:
+           case VEC_TRAP5:
+           case VEC_TRAP6:
+           case VEC_TRAP7:
+           case VEC_TRAP8:
+           case VEC_TRAP9:
+           case VEC_TRAP10:
+           case VEC_TRAP11:
+           case VEC_TRAP12:
+           case VEC_TRAP13:
+           case VEC_TRAP14:
+               info.si_code = ILL_ILLTRP;
+               sig = SIGILL;
+               break;
+           case VEC_FPBRUC:
+           case VEC_FPOE:
+           case VEC_FPNAN:
+               info.si_code = FPE_FLTINV;
+               sig = SIGFPE;
+               break;
+           case VEC_FPIR:
+               info.si_code = FPE_FLTRES;
+               sig = SIGFPE;
+               break;
+           case VEC_FPDIVZ:
+               info.si_code = FPE_FLTDIV;
+               sig = SIGFPE;
+               break;
+           case VEC_FPUNDER:
+               info.si_code = FPE_FLTUND;
+               sig = SIGFPE;
+               break;
+           case VEC_FPOVER:
+               info.si_code = FPE_FLTOVF;
+               sig = SIGFPE;
+               break;
+           case VEC_ZERODIV:
+               info.si_code = FPE_INTDIV;
+               sig = SIGFPE;
+               break;
+           case VEC_CHK:
+           case VEC_TRAP:
+               info.si_code = FPE_INTOVF;
+               sig = SIGFPE;
+               break;
+           case VEC_TRACE:             /* ptrace single step */
+               info.si_code = TRAP_TRACE;
+               sig = SIGTRAP;
+               break;
+           case VEC_TRAP15:            /* breakpoint */
+               info.si_code = TRAP_BRKPT;
+               sig = SIGTRAP;
+               break;
+           default:
+               info.si_code = ILL_ILLOPC;
+               sig = SIGILL;
+               break;
+       }
+       info.si_signo = sig;
+       info.si_errno = 0;
+       switch (fp->ptregs.format) {
+           default:
+               info.si_addr = (void *) fp->ptregs.pc;
+               break;
+           case 2:
+               info.si_addr = (void *) fp->un.fmt2.iaddr;
+               break;
+           case 7:
+               info.si_addr = (void *) fp->un.fmt7.effaddr;
+               break;
+           case 9:
+               info.si_addr = (void *) fp->un.fmt9.iaddr;
+               break;
+           case 10:
+               info.si_addr = (void *) fp->un.fmta.daddr;
+               break;
+           case 11:
+               info.si_addr = (void *) fp->un.fmtb.daddr;
+               break;
+       }
+       force_sig_info (sig, &info, current);
+}
+
+void die_if_kernel (char *str, struct pt_regs *fp, int nr)
+{
+       if (!(fp->sr & PS_S))
+               return;
+
+       console_verbose();
+       printk("%s: %08x\n",str,nr);
+       show_registers(fp);
+       add_taint(TAINT_DIE);
+       do_exit(SIGSEGV);
+}
+
+asmlinkage void set_esp0(unsigned long ssp)
+{
+       current->thread.esp0 = ssp;
+}
+
+/*
+ * This function is called if an error occur while accessing
+ * user-space from the fpsp040 code.
+ */
+asmlinkage void fpsp040_die(void)
+{
+       do_exit(SIGSEGV);
+}
+
+#ifdef CONFIG_M68KFPU_EMU
+asmlinkage void fpemu_signal(int signal, int code, void *addr)
+{
+       siginfo_t info;
+
+       info.si_signo = signal;
+       info.si_errno = 0;
+       info.si_code = code;
+       info.si_addr = addr;
+       force_sig_info(signal, &info, current);
+}
 #endif
diff --git a/arch/m68k/kernel/traps_mm.c b/arch/m68k/kernel/traps_mm.c
deleted file mode 100644 (file)
index 4022bbc..0000000
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*
- *  linux/arch/m68k/kernel/traps.c
- *
- *  Copyright (C) 1993, 1994 by Hamish Macdonald
- *
- *  68040 fixes by Michael Rausch
- *  68040 fixes by Martin Apel
- *  68040 fixes and writeback by Richard Zidlicky
- *  68060 fixes by Roman Hodek
- *  68060 fixes by Jesper Skov
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/*
- * Sets up all exception vectors
- */
-
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/user.h>
-#include <linux/string.h>
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/kallsyms.h>
-
-#include <asm/setup.h>
-#include <asm/fpu.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/traps.h>
-#include <asm/pgalloc.h>
-#include <asm/machdep.h>
-#include <asm/siginfo.h>
-
-/* assembler routines */
-asmlinkage void system_call(void);
-asmlinkage void buserr(void);
-asmlinkage void trap(void);
-asmlinkage void nmihandler(void);
-#ifdef CONFIG_M68KFPU_EMU
-asmlinkage void fpu_emu(void);
-#endif
-
-e_vector vectors[256];
-
-/* nmi handler for the Amiga */
-asm(".text\n"
-    __ALIGN_STR "\n"
-    "nmihandler: rte");
-
-/*
- * this must be called very early as the kernel might
- * use some instruction that are emulated on the 060
- * and so we're prepared for early probe attempts (e.g. nf_init).
- */
-void __init base_trap_init(void)
-{
-       if (MACH_IS_SUN3X) {
-               extern e_vector *sun3x_prom_vbr;
-
-               __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));
-       }
-
-       /* setup the exception vector table */
-       __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
-
-       if (CPU_IS_060) {
-               /* set up ISP entry points */
-               asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
-
-               vectors[VEC_UNIMPII] = unimp_vec;
-       }
-
-       vectors[VEC_BUSERR] = buserr;
-       vectors[VEC_ILLEGAL] = trap;
-       vectors[VEC_SYS] = system_call;
-}
-
-void __init trap_init (void)
-{
-       int i;
-
-       for (i = VEC_SPUR; i <= VEC_INT7; i++)
-               vectors[i] = bad_inthandler;
-
-       for (i = 0; i < VEC_USER; i++)
-               if (!vectors[i])
-                       vectors[i] = trap;
-
-       for (i = VEC_USER; i < 256; i++)
-               vectors[i] = bad_inthandler;
-
-#ifdef CONFIG_M68KFPU_EMU
-       if (FPU_IS_EMU)
-               vectors[VEC_LINE11] = fpu_emu;
-#endif
-
-       if (CPU_IS_040 && !FPU_IS_EMU) {
-               /* set up FPSP entry points */
-               asmlinkage void dz_vec(void) asm ("dz");
-               asmlinkage void inex_vec(void) asm ("inex");
-               asmlinkage void ovfl_vec(void) asm ("ovfl");
-               asmlinkage void unfl_vec(void) asm ("unfl");
-               asmlinkage void snan_vec(void) asm ("snan");
-               asmlinkage void operr_vec(void) asm ("operr");
-               asmlinkage void bsun_vec(void) asm ("bsun");
-               asmlinkage void fline_vec(void) asm ("fline");
-               asmlinkage void unsupp_vec(void) asm ("unsupp");
-
-               vectors[VEC_FPDIVZ] = dz_vec;
-               vectors[VEC_FPIR] = inex_vec;
-               vectors[VEC_FPOVER] = ovfl_vec;
-               vectors[VEC_FPUNDER] = unfl_vec;
-               vectors[VEC_FPNAN] = snan_vec;
-               vectors[VEC_FPOE] = operr_vec;
-               vectors[VEC_FPBRUC] = bsun_vec;
-               vectors[VEC_LINE11] = fline_vec;
-               vectors[VEC_FPUNSUP] = unsupp_vec;
-       }
-
-       if (CPU_IS_060 && !FPU_IS_EMU) {
-               /* set up IFPSP entry points */
-               asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");
-               asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");
-               asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");
-               asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");
-               asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");
-               asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");
-               asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");
-               asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");
-               asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");
-
-               vectors[VEC_FPNAN] = snan_vec6;
-               vectors[VEC_FPOE] = operr_vec6;
-               vectors[VEC_FPOVER] = ovfl_vec6;
-               vectors[VEC_FPUNDER] = unfl_vec6;
-               vectors[VEC_FPDIVZ] = dz_vec6;
-               vectors[VEC_FPIR] = inex_vec6;
-               vectors[VEC_LINE11] = fline_vec6;
-               vectors[VEC_FPUNSUP] = unsupp_vec6;
-               vectors[VEC_UNIMPEA] = effadd_vec6;
-       }
-
-        /* if running on an amiga, make the NMI interrupt do nothing */
-       if (MACH_IS_AMIGA) {
-               vectors[VEC_INT7] = nmihandler;
-       }
-}
-
-
-static const char *vec_names[] = {
-       [VEC_RESETSP]   = "RESET SP",
-       [VEC_RESETPC]   = "RESET PC",
-       [VEC_BUSERR]    = "BUS ERROR",
-       [VEC_ADDRERR]   = "ADDRESS ERROR",
-       [VEC_ILLEGAL]   = "ILLEGAL INSTRUCTION",
-       [VEC_ZERODIV]   = "ZERO DIVIDE",
-       [VEC_CHK]       = "CHK",
-       [VEC_TRAP]      = "TRAPcc",
-       [VEC_PRIV]      = "PRIVILEGE VIOLATION",
-       [VEC_TRACE]     = "TRACE",
-       [VEC_LINE10]    = "LINE 1010",
-       [VEC_LINE11]    = "LINE 1111",
-       [VEC_RESV12]    = "UNASSIGNED RESERVED 12",
-       [VEC_COPROC]    = "COPROCESSOR PROTOCOL VIOLATION",
-       [VEC_FORMAT]    = "FORMAT ERROR",
-       [VEC_UNINT]     = "UNINITIALIZED INTERRUPT",
-       [VEC_RESV16]    = "UNASSIGNED RESERVED 16",
-       [VEC_RESV17]    = "UNASSIGNED RESERVED 17",
-       [VEC_RESV18]    = "UNASSIGNED RESERVED 18",
-       [VEC_RESV19]    = "UNASSIGNED RESERVED 19",
-       [VEC_RESV20]    = "UNASSIGNED RESERVED 20",
-       [VEC_RESV21]    = "UNASSIGNED RESERVED 21",
-       [VEC_RESV22]    = "UNASSIGNED RESERVED 22",
-       [VEC_RESV23]    = "UNASSIGNED RESERVED 23",
-       [VEC_SPUR]      = "SPURIOUS INTERRUPT",
-       [VEC_INT1]      = "LEVEL 1 INT",
-       [VEC_INT2]      = "LEVEL 2 INT",
-       [VEC_INT3]      = "LEVEL 3 INT",
-       [VEC_INT4]      = "LEVEL 4 INT",
-       [VEC_INT5]      = "LEVEL 5 INT",
-       [VEC_INT6]      = "LEVEL 6 INT",
-       [VEC_INT7]      = "LEVEL 7 INT",
-       [VEC_SYS]       = "SYSCALL",
-       [VEC_TRAP1]     = "TRAP #1",
-       [VEC_TRAP2]     = "TRAP #2",
-       [VEC_TRAP3]     = "TRAP #3",
-       [VEC_TRAP4]     = "TRAP #4",
-       [VEC_TRAP5]     = "TRAP #5",
-       [VEC_TRAP6]     = "TRAP #6",
-       [VEC_TRAP7]     = "TRAP #7",
-       [VEC_TRAP8]     = "TRAP #8",
-       [VEC_TRAP9]     = "TRAP #9",
-       [VEC_TRAP10]    = "TRAP #10",
-       [VEC_TRAP11]    = "TRAP #11",
-       [VEC_TRAP12]    = "TRAP #12",
-       [VEC_TRAP13]    = "TRAP #13",
-       [VEC_TRAP14]    = "TRAP #14",
-       [VEC_TRAP15]    = "TRAP #15",
-       [VEC_FPBRUC]    = "FPCP BSUN",
-       [VEC_FPIR]      = "FPCP INEXACT",
-       [VEC_FPDIVZ]    = "FPCP DIV BY 0",
-       [VEC_FPUNDER]   = "FPCP UNDERFLOW",
-       [VEC_FPOE]      = "FPCP OPERAND ERROR",
-       [VEC_FPOVER]    = "FPCP OVERFLOW",
-       [VEC_FPNAN]     = "FPCP SNAN",
-       [VEC_FPUNSUP]   = "FPCP UNSUPPORTED OPERATION",
-       [VEC_MMUCFG]    = "MMU CONFIGURATION ERROR",
-       [VEC_MMUILL]    = "MMU ILLEGAL OPERATION ERROR",
-       [VEC_MMUACC]    = "MMU ACCESS LEVEL VIOLATION ERROR",
-       [VEC_RESV59]    = "UNASSIGNED RESERVED 59",
-       [VEC_UNIMPEA]   = "UNASSIGNED RESERVED 60",
-       [VEC_UNIMPII]   = "UNASSIGNED RESERVED 61",
-       [VEC_RESV62]    = "UNASSIGNED RESERVED 62",
-       [VEC_RESV63]    = "UNASSIGNED RESERVED 63",
-};
-
-static const char *space_names[] = {
-       [0]             = "Space 0",
-       [USER_DATA]     = "User Data",
-       [USER_PROGRAM]  = "User Program",
-#ifndef CONFIG_SUN3
-       [3]             = "Space 3",
-#else
-       [FC_CONTROL]    = "Control",
-#endif
-       [4]             = "Space 4",
-       [SUPER_DATA]    = "Super Data",
-       [SUPER_PROGRAM] = "Super Program",
-       [CPU_SPACE]     = "CPU"
-};
-
-void die_if_kernel(char *,struct pt_regs *,int);
-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
-                             unsigned long error_code);
-int send_fault_sig(struct pt_regs *regs);
-
-asmlinkage void trap_c(struct frame *fp);
-
-#if defined (CONFIG_M68060)
-static inline void access_error060 (struct frame *fp)
-{
-       unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
-
-#ifdef DEBUG
-       printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
-#endif
-
-       if (fslw & MMU060_BPE) {
-               /* branch prediction error -> clear branch cache */
-               __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
-                                     "orl   #0x00400000,%/d0\n\t"
-                                     "movec %/d0,%/cacr"
-                                     : : : "d0" );
-               /* return if there's no other error */
-               if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))
-                       return;
-       }
-
-       if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
-               unsigned long errorcode;
-               unsigned long addr = fp->un.fmt4.effaddr;
-
-               if (fslw & MMU060_MA)
-                       addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
-
-               errorcode = 1;
-               if (fslw & MMU060_DESC_ERR) {
-                       __flush_tlb040_one(addr);
-                       errorcode = 0;
-               }
-               if (fslw & MMU060_W)
-                       errorcode |= 2;
-#ifdef DEBUG
-               printk("errorcode = %d\n", errorcode );
-#endif
-               do_page_fault(&fp->ptregs, addr, errorcode);
-       } else if (fslw & (MMU060_SEE)){
-               /* Software Emulation Error.
-                * fault during mem_read/mem_write in ifpsp060/os.S
-                */
-               send_fault_sig(&fp->ptregs);
-       } else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
-                  send_fault_sig(&fp->ptregs) > 0) {
-               printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
-               printk( "68060 access error, fslw=%lx\n", fslw );
-               trap_c( fp );
-       }
-}
-#endif /* CONFIG_M68060 */
-
-#if defined (CONFIG_M68040)
-static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
-{
-       unsigned long mmusr;
-       mm_segment_t old_fs = get_fs();
-
-       set_fs(MAKE_MM_SEG(wbs));
-
-       if (iswrite)
-               asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
-       else
-               asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
-
-       asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
-
-       set_fs(old_fs);
-
-       return mmusr;
-}
-
-static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
-                                  unsigned long wbd)
-{
-       int res = 0;
-       mm_segment_t old_fs = get_fs();
-
-       /* set_fs can not be moved, otherwise put_user() may oops */
-       set_fs(MAKE_MM_SEG(wbs));
-
-       switch (wbs & WBSIZ_040) {
-       case BA_SIZE_BYTE:
-               res = put_user(wbd & 0xff, (char __user *)wba);
-               break;
-       case BA_SIZE_WORD:
-               res = put_user(wbd & 0xffff, (short __user *)wba);
-               break;
-       case BA_SIZE_LONG:
-               res = put_user(wbd, (int __user *)wba);
-               break;
-       }
-
-       /* set_fs can not be moved, otherwise put_user() may oops */
-       set_fs(old_fs);
-
-
-#ifdef DEBUG
-       printk("do_040writeback1, res=%d\n",res);
-#endif
-
-       return res;
-}
-
-/* after an exception in a writeback the stack frame corresponding
- * to that exception is discarded, set a few bits in the old frame
- * to simulate what it should look like
- */
-static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
-{
-       fp->un.fmt7.faddr = wba;
-       fp->un.fmt7.ssw = wbs & 0xff;
-       if (wba != current->thread.faddr)
-           fp->un.fmt7.ssw |= MA_040;
-}
-
-static inline void do_040writebacks(struct frame *fp)
-{
-       int res = 0;
-#if 0
-       if (fp->un.fmt7.wb1s & WBV_040)
-               printk("access_error040: cannot handle 1st writeback. oops.\n");
-#endif
-
-       if ((fp->un.fmt7.wb2s & WBV_040) &&
-           !(fp->un.fmt7.wb2s & WBTT_040)) {
-               res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
-                                      fp->un.fmt7.wb2d);
-               if (res)
-                       fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
-               else
-                       fp->un.fmt7.wb2s = 0;
-       }
-
-       /* do the 2nd wb only if the first one was successful (except for a kernel wb) */
-       if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
-               res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
-                                      fp->un.fmt7.wb3d);
-               if (res)
-                   {
-                       fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
-
-                       fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
-                       fp->un.fmt7.wb3s &= (~WBV_040);
-                       fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
-                       fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
-                   }
-               else
-                       fp->un.fmt7.wb3s = 0;
-       }
-
-       if (res)
-               send_fault_sig(&fp->ptregs);
-}
-
-/*
- * called from sigreturn(), must ensure userspace code didn't
- * manipulate exception frame to circumvent protection, then complete
- * pending writebacks
- * we just clear TM2 to turn it into a userspace access
- */
-asmlinkage void berr_040cleanup(struct frame *fp)
-{
-       fp->un.fmt7.wb2s &= ~4;
-       fp->un.fmt7.wb3s &= ~4;
-
-       do_040writebacks(fp);
-}
-
-static inline void access_error040(struct frame *fp)
-{
-       unsigned short ssw = fp->un.fmt7.ssw;
-       unsigned long mmusr;
-
-#ifdef DEBUG
-       printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
-        printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
-               fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
-       printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
-               fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
-               fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
-#endif
-
-       if (ssw & ATC_040) {
-               unsigned long addr = fp->un.fmt7.faddr;
-               unsigned long errorcode;
-
-               /*
-                * The MMU status has to be determined AFTER the address
-                * has been corrected if there was a misaligned access (MA).
-                */
-               if (ssw & MA_040)
-                       addr = (addr + 7) & -8;
-
-               /* MMU error, get the MMUSR info for this access */
-               mmusr = probe040(!(ssw & RW_040), addr, ssw);
-#ifdef DEBUG
-               printk("mmusr = %lx\n", mmusr);
-#endif
-               errorcode = 1;
-               if (!(mmusr & MMU_R_040)) {
-                       /* clear the invalid atc entry */
-                       __flush_tlb040_one(addr);
-                       errorcode = 0;
-               }
-
-               /* despite what documentation seems to say, RMW
-                * accesses have always both the LK and RW bits set */
-               if (!(ssw & RW_040) || (ssw & LK_040))
-                       errorcode |= 2;
-
-               if (do_page_fault(&fp->ptregs, addr, errorcode)) {
-#ifdef DEBUG
-                       printk("do_page_fault() !=0\n");
-#endif
-                       if (user_mode(&fp->ptregs)){
-                               /* delay writebacks after signal delivery */
-#ifdef DEBUG
-                               printk(".. was usermode - return\n");
-#endif
-                               return;
-                       }
-                       /* disable writeback into user space from kernel
-                        * (if do_page_fault didn't fix the mapping,
-                         * the writeback won't do good)
-                        */
-disable_wb:
-#ifdef DEBUG
-                       printk(".. disabling wb2\n");
-#endif
-                       if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
-                               fp->un.fmt7.wb2s &= ~WBV_040;
-                       if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
-                               fp->un.fmt7.wb3s &= ~WBV_040;
-               }
-       } else {
-               /* In case of a bus error we either kill the process or expect
-                * the kernel to catch the fault, which then is also responsible
-                * for cleaning up the mess.
-                */
-               current->thread.signo = SIGBUS;
-               current->thread.faddr = fp->un.fmt7.faddr;
-               if (send_fault_sig(&fp->ptregs) >= 0)
-                       printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
-                              fp->un.fmt7.faddr);
-               goto disable_wb;
-       }
-
-       do_040writebacks(fp);
-}
-#endif /* CONFIG_M68040 */
-
-#if defined(CONFIG_SUN3)
-#include <asm/sun3mmu.h>
-
-extern int mmu_emu_handle_fault (unsigned long, int, int);
-
-/* sun3 version of bus_error030 */
-
-static inline void bus_error030 (struct frame *fp)
-{
-       unsigned char buserr_type = sun3_get_buserr ();
-       unsigned long addr, errorcode;
-       unsigned short ssw = fp->un.fmtb.ssw;
-       extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
-
-#ifdef DEBUG
-       if (ssw & (FC | FB))
-               printk ("Instruction fault at %#010lx\n",
-                       ssw & FC ?
-                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
-                       :
-                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
-       if (ssw & DF)
-               printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
-                       ssw & RW ? "read" : "write",
-                       fp->un.fmtb.daddr,
-                       space_names[ssw & DFC], fp->ptregs.pc);
-#endif
-
-       /*
-        * Check if this page should be demand-mapped. This needs to go before
-        * the testing for a bad kernel-space access (demand-mapping applies
-        * to kernel accesses too).
-        */
-
-       if ((ssw & DF)
-           && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
-               if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
-                       return;
-       }
-
-       /* Check for kernel-space pagefault (BAD). */
-       if (fp->ptregs.sr & PS_S) {
-               /* kernel fault must be a data fault to user space */
-               if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
-                    // try checking the kernel mappings before surrender
-                    if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
-                         return;
-                       /* instruction fault or kernel data fault! */
-                       if (ssw & (FC | FB))
-                               printk ("Instruction fault at %#010lx\n",
-                                       fp->ptregs.pc);
-                       if (ssw & DF) {
-                               /* was this fault incurred testing bus mappings? */
-                               if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
-                                  (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
-                                       send_fault_sig(&fp->ptregs);
-                                       return;
-                               }
-
-                               printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
-                                       ssw & RW ? "read" : "write",
-                                       fp->un.fmtb.daddr,
-                                       space_names[ssw & DFC], fp->ptregs.pc);
-                       }
-                       printk ("BAD KERNEL BUSERR\n");
-
-                       die_if_kernel("Oops", &fp->ptregs,0);
-                       force_sig(SIGKILL, current);
-                       return;
-               }
-       } else {
-               /* user fault */
-               if (!(ssw & (FC | FB)) && !(ssw & DF))
-                       /* not an instruction fault or data fault! BAD */
-                       panic ("USER BUSERR w/o instruction or data fault");
-       }
-
-
-       /* First handle the data fault, if any.  */
-       if (ssw & DF) {
-               addr = fp->un.fmtb.daddr;
-
-// errorcode bit 0:    0 -> no page            1 -> protection fault
-// errorcode bit 1:    0 -> read fault         1 -> write fault
-
-// (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault
-// (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault
-
-               if (buserr_type & SUN3_BUSERR_PROTERR)
-                       errorcode = 0x01;
-               else if (buserr_type & SUN3_BUSERR_INVALID)
-                       errorcode = 0x00;
-               else {
-#ifdef DEBUG
-                       printk ("*** unexpected busfault type=%#04x\n", buserr_type);
-                       printk ("invalid %s access at %#lx from pc %#lx\n",
-                               !(ssw & RW) ? "write" : "read", addr,
-                               fp->ptregs.pc);
-#endif
-                       die_if_kernel ("Oops", &fp->ptregs, buserr_type);
-                       force_sig (SIGBUS, current);
-                       return;
-               }
-
-//todo: wtf is RM bit? --m
-               if (!(ssw & RW) || ssw & RM)
-                       errorcode |= 0x02;
-
-               /* Handle page fault. */
-               do_page_fault (&fp->ptregs, addr, errorcode);
-
-               /* Retry the data fault now. */
-               return;
-       }
-
-       /* Now handle the instruction fault. */
-
-       /* Get the fault address. */
-       if (fp->ptregs.format == 0xA)
-               addr = fp->ptregs.pc + 4;
-       else
-               addr = fp->un.fmtb.baddr;
-       if (ssw & FC)
-               addr -= 2;
-
-       if (buserr_type & SUN3_BUSERR_INVALID) {
-               if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))
-                       do_page_fault (&fp->ptregs, addr, 0);
-       } else {
-#ifdef DEBUG
-               printk ("protection fault on insn access (segv).\n");
-#endif
-               force_sig (SIGSEGV, current);
-       }
-}
-#else
-#if defined(CPU_M68020_OR_M68030)
-static inline void bus_error030 (struct frame *fp)
-{
-       volatile unsigned short temp;
-       unsigned short mmusr;
-       unsigned long addr, errorcode;
-       unsigned short ssw = fp->un.fmtb.ssw;
-#ifdef DEBUG
-       unsigned long desc;
-
-       printk ("pid = %x  ", current->pid);
-       printk ("SSW=%#06x  ", ssw);
-
-       if (ssw & (FC | FB))
-               printk ("Instruction fault at %#010lx\n",
-                       ssw & FC ?
-                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
-                       :
-                       fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
-       if (ssw & DF)
-               printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
-                       ssw & RW ? "read" : "write",
-                       fp->un.fmtb.daddr,
-                       space_names[ssw & DFC], fp->ptregs.pc);
-#endif
-
-       /* ++andreas: If a data fault and an instruction fault happen
-          at the same time map in both pages.  */
-
-       /* First handle the data fault, if any.  */
-       if (ssw & DF) {
-               addr = fp->un.fmtb.daddr;
-
-#ifdef DEBUG
-               asm volatile ("ptestr %3,%2@,#7,%0\n\t"
-                             "pmove %%psr,%1@"
-                             : "=a&" (desc)
-                             : "a" (&temp), "a" (addr), "d" (ssw));
-#else
-               asm volatile ("ptestr %2,%1@,#7\n\t"
-                             "pmove %%psr,%0@"
-                             : : "a" (&temp), "a" (addr), "d" (ssw));
-#endif
-               mmusr = temp;
-
-#ifdef DEBUG
-               printk("mmusr is %#x for addr %#lx in task %p\n",
-                      mmusr, addr, current);
-               printk("descriptor address is %#lx, contents %#lx\n",
-                      __va(desc), *(unsigned long *)__va(desc));
-#endif
-
-               errorcode = (mmusr & MMU_I) ? 0 : 1;
-               if (!(ssw & RW) || (ssw & RM))
-                       errorcode |= 2;
-
-               if (mmusr & (MMU_I | MMU_WP)) {
-                       if (ssw & 4) {
-                               printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",
-                                      ssw & RW ? "read" : "write",
-                                      fp->un.fmtb.daddr,
-                                      space_names[ssw & DFC], fp->ptregs.pc);
-                               goto buserr;
-                       }
-                       /* Don't try to do anything further if an exception was
-                          handled. */
-                       if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
-                               return;
-               } else if (!(mmusr & MMU_I)) {
-                       /* probably a 020 cas fault */
-                       if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
-                               printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);
-               } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
-                       printk("invalid %s access at %#lx from pc %#lx\n",
-                              !(ssw & RW) ? "write" : "read", addr,
-                              fp->ptregs.pc);
-                       die_if_kernel("Oops",&fp->ptregs,mmusr);
-                       force_sig(SIGSEGV, current);
-                       return;
-               } else {
-#if 0
-                       static volatile long tlong;
-#endif
-
-                       printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
-                              !(ssw & RW) ? "write" : "read", addr,
-                              fp->ptregs.pc, ssw);
-                       asm volatile ("ptestr #1,%1@,#0\n\t"
-                                     "pmove %%psr,%0@"
-                                     : /* no outputs */
-                                     : "a" (&temp), "a" (addr));
-                       mmusr = temp;
-
-                       printk ("level 0 mmusr is %#x\n", mmusr);
-#if 0
-                       asm volatile ("pmove %%tt0,%0@"
-                                     : /* no outputs */
-                                     : "a" (&tlong));
-                       printk("tt0 is %#lx, ", tlong);
-                       asm volatile ("pmove %%tt1,%0@"
-                                     : /* no outputs */
-                                     : "a" (&tlong));
-                       printk("tt1 is %#lx\n", tlong);
-#endif
-#ifdef DEBUG
-                       printk("Unknown SIGSEGV - 1\n");
-#endif
-                       die_if_kernel("Oops",&fp->ptregs,mmusr);
-                       force_sig(SIGSEGV, current);
-                       return;
-               }
-
-               /* setup an ATC entry for the access about to be retried */
-               if (!(ssw & RW) || (ssw & RM))
-                       asm volatile ("ploadw %1,%0@" : /* no outputs */
-                                     : "a" (addr), "d" (ssw));
-               else
-                       asm volatile ("ploadr %1,%0@" : /* no outputs */
-                                     : "a" (addr), "d" (ssw));
-       }
-
-       /* Now handle the instruction fault. */
-
-       if (!(ssw & (FC|FB)))
-               return;
-
-       if (fp->ptregs.sr & PS_S) {
-               printk("Instruction fault at %#010lx\n",
-                       fp->ptregs.pc);
-       buserr:
-               printk ("BAD KERNEL BUSERR\n");
-               die_if_kernel("Oops",&fp->ptregs,0);
-               force_sig(SIGKILL, current);
-               return;
-       }
-
-       /* get the fault address */
-       if (fp->ptregs.format == 10)
-               addr = fp->ptregs.pc + 4;
-       else
-               addr = fp->un.fmtb.baddr;
-       if (ssw & FC)
-               addr -= 2;
-
-       if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
-               /* Insn fault on same page as data fault.  But we
-                  should still create the ATC entry.  */
-               goto create_atc_entry;
-
-#ifdef DEBUG
-       asm volatile ("ptestr #1,%2@,#7,%0\n\t"
-                     "pmove %%psr,%1@"
-                     : "=a&" (desc)
-                     : "a" (&temp), "a" (addr));
-#else
-       asm volatile ("ptestr #1,%1@,#7\n\t"
-                     "pmove %%psr,%0@"
-                     : : "a" (&temp), "a" (addr));
-#endif
-       mmusr = temp;
-
-#ifdef DEBUG
-       printk ("mmusr is %#x for addr %#lx in task %p\n",
-               mmusr, addr, current);
-       printk ("descriptor address is %#lx, contents %#lx\n",
-               __va(desc), *(unsigned long *)__va(desc));
-#endif
-
-       if (mmusr & MMU_I)
-               do_page_fault (&fp->ptregs, addr, 0);
-       else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
-               printk ("invalid insn access at %#lx from pc %#lx\n",
-                       addr, fp->ptregs.pc);
-#ifdef DEBUG
-               printk("Unknown SIGSEGV - 2\n");
-#endif
-               die_if_kernel("Oops",&fp->ptregs,mmusr);
-               force_sig(SIGSEGV, current);
-               return;
-       }
-
-create_atc_entry:
-       /* setup an ATC entry for the access about to be retried */
-       asm volatile ("ploadr #2,%0@" : /* no outputs */
-                     : "a" (addr));
-}
-#endif /* CPU_M68020_OR_M68030 */
-#endif /* !CONFIG_SUN3 */
-
-asmlinkage void buserr_c(struct frame *fp)
-{
-       /* Only set esp0 if coming from user mode */
-       if (user_mode(&fp->ptregs))
-               current->thread.esp0 = (unsigned long) fp;
-
-#ifdef DEBUG
-       printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
-#endif
-
-       switch (fp->ptregs.format) {
-#if defined (CONFIG_M68060)
-       case 4:                         /* 68060 access error */
-         access_error060 (fp);
-         break;
-#endif
-#if defined (CONFIG_M68040)
-       case 0x7:                       /* 68040 access error */
-         access_error040 (fp);
-         break;
-#endif
-#if defined (CPU_M68020_OR_M68030)
-       case 0xa:
-       case 0xb:
-         bus_error030 (fp);
-         break;
-#endif
-       default:
-         die_if_kernel("bad frame format",&fp->ptregs,0);
-#ifdef DEBUG
-         printk("Unknown SIGSEGV - 4\n");
-#endif
-         force_sig(SIGSEGV, current);
-       }
-}
-
-
-static int kstack_depth_to_print = 48;
-
-void show_trace(unsigned long *stack)
-{
-       unsigned long *endstack;
-       unsigned long addr;
-       int i;
-
-       printk("Call Trace:");
-       addr = (unsigned long)stack + THREAD_SIZE - 1;
-       endstack = (unsigned long *)(addr & -THREAD_SIZE);
-       i = 0;
-       while (stack + 1 <= endstack) {
-               addr = *stack++;
-               /*
-                * If the address is either in the text segment of the
-                * kernel, or in the region which contains vmalloc'ed
-                * memory, it *may* be the address of a calling
-                * routine; if so, print it so that someone tracing
-                * down the cause of the crash will be able to figure
-                * out the call path that was taken.
-                */
-               if (__kernel_text_address(addr)) {
-#ifndef CONFIG_KALLSYMS
-                       if (i % 5 == 0)
-                               printk("\n       ");
-#endif
-                       printk(" [<%08lx>] %pS\n", addr, (void *)addr);
-                       i++;
-               }
-       }
-       printk("\n");
-}
-
-void show_registers(struct pt_regs *regs)
-{
-       struct frame *fp = (struct frame *)regs;
-       mm_segment_t old_fs = get_fs();
-       u16 c, *cp;
-       unsigned long addr;
-       int i;
-
-       print_modules();
-       printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
-       printk("SR: %04x  SP: %p  a2: %08lx\n", regs->sr, regs, regs->a2);
-       printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
-              regs->d0, regs->d1, regs->d2, regs->d3);
-       printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
-              regs->d4, regs->d5, regs->a0, regs->a1);
-
-       printk("Process %s (pid: %d, task=%p)\n",
-               current->comm, task_pid_nr(current), current);
-       addr = (unsigned long)&fp->un;
-       printk("Frame format=%X ", regs->format);
-       switch (regs->format) {
-       case 0x2:
-               printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
-               addr += sizeof(fp->un.fmt2);
-               break;
-       case 0x3:
-               printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
-               addr += sizeof(fp->un.fmt3);
-               break;
-       case 0x4:
-               printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
-                       : "eff addr=%08lx pc=%08lx\n"),
-                       fp->un.fmt4.effaddr, fp->un.fmt4.pc);
-               addr += sizeof(fp->un.fmt4);
-               break;
-       case 0x7:
-               printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
-                       fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
-               printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
-                       fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
-               printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
-                       fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
-               printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
-                       fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
-               printk("push data: %08lx %08lx %08lx %08lx\n",
-                       fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
-                       fp->un.fmt7.pd3);
-               addr += sizeof(fp->un.fmt7);
-               break;
-       case 0x9:
-               printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
-               addr += sizeof(fp->un.fmt9);
-               break;
-       case 0xa:
-               printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
-                       fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
-                       fp->un.fmta.daddr, fp->un.fmta.dobuf);
-               addr += sizeof(fp->un.fmta);
-               break;
-       case 0xb:
-               printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
-                       fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
-                       fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
-               printk("baddr=%08lx dibuf=%08lx ver=%x\n",
-                       fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
-               addr += sizeof(fp->un.fmtb);
-               break;
-       default:
-               printk("\n");
-       }
-       show_stack(NULL, (unsigned long *)addr);
-
-       printk("Code:");
-       set_fs(KERNEL_DS);
-       cp = (u16 *)regs->pc;
-       for (i = -8; i < 16; i++) {
-               if (get_user(c, cp + i) && i >= 0) {
-                       printk(" Bad PC value.");
-                       break;
-               }
-               printk(i ? " %04x" : " <%04x>", c);
-       }
-       set_fs(old_fs);
-       printk ("\n");
-}
-
-void show_stack(struct task_struct *task, unsigned long *stack)
-{
-       unsigned long *p;
-       unsigned long *endstack;
-       int i;
-
-       if (!stack) {
-               if (task)
-                       stack = (unsigned long *)task->thread.esp0;
-               else
-                       stack = (unsigned long *)&stack;
-       }
-       endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
-
-       printk("Stack from %08lx:", (unsigned long)stack);
-       p = stack;
-       for (i = 0; i < kstack_depth_to_print; i++) {
-               if (p + 1 > endstack)
-                       break;
-               if (i % 8 == 0)
-                       printk("\n       ");
-               printk(" %08lx", *p++);
-       }
-       printk("\n");
-       show_trace(stack);
-}
-
-/*
- * The architecture-independent backtrace generator
- */
-void dump_stack(void)
-{
-       unsigned long stack;
-
-       show_trace(&stack);
-}
-
-EXPORT_SYMBOL(dump_stack);
-
-void bad_super_trap (struct frame *fp)
-{
-       console_verbose();
-       if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names))
-               printk ("*** %s ***   FORMAT=%X\n",
-                       vec_names[(fp->ptregs.vector) >> 2],
-                       fp->ptregs.format);
-       else
-               printk ("*** Exception %d ***   FORMAT=%X\n",
-                       (fp->ptregs.vector) >> 2,
-                       fp->ptregs.format);
-       if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) {
-               unsigned short ssw = fp->un.fmtb.ssw;
-
-               printk ("SSW=%#06x  ", ssw);
-
-               if (ssw & RC)
-                       printk ("Pipe stage C instruction fault at %#010lx\n",
-                               (fp->ptregs.format) == 0xA ?
-                               fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
-               if (ssw & RB)
-                       printk ("Pipe stage B instruction fault at %#010lx\n",
-                               (fp->ptregs.format) == 0xA ?
-                               fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
-               if (ssw & DF)
-                       printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
-                               ssw & RW ? "read" : "write",
-                               fp->un.fmtb.daddr, space_names[ssw & DFC],
-                               fp->ptregs.pc);
-       }
-       printk ("Current process id is %d\n", task_pid_nr(current));
-       die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
-}
-
-asmlinkage void trap_c(struct frame *fp)
-{
-       int sig;
-       siginfo_t info;
-
-       if (fp->ptregs.sr & PS_S) {
-               if (fp->ptregs.vector == VEC_TRACE << 2) {
-                       /* traced a trapping instruction on a 68020/30,
-                        * real exception will be executed afterwards.
-                        */
-               } else if (!handle_kernel_fault(&fp->ptregs))
-                       bad_super_trap(fp);
-               return;
-       }
-
-       /* send the appropriate signal to the user program */
-       switch ((fp->ptregs.vector) >> 2) {
-           case VEC_ADDRERR:
-               info.si_code = BUS_ADRALN;
-               sig = SIGBUS;
-               break;
-           case VEC_ILLEGAL:
-           case VEC_LINE10:
-           case VEC_LINE11:
-               info.si_code = ILL_ILLOPC;
-               sig = SIGILL;
-               break;
-           case VEC_PRIV:
-               info.si_code = ILL_PRVOPC;
-               sig = SIGILL;
-               break;
-           case VEC_COPROC:
-               info.si_code = ILL_COPROC;
-               sig = SIGILL;
-               break;
-           case VEC_TRAP1:
-           case VEC_TRAP2:
-           case VEC_TRAP3:
-           case VEC_TRAP4:
-           case VEC_TRAP5:
-           case VEC_TRAP6:
-           case VEC_TRAP7:
-           case VEC_TRAP8:
-           case VEC_TRAP9:
-           case VEC_TRAP10:
-           case VEC_TRAP11:
-           case VEC_TRAP12:
-           case VEC_TRAP13:
-           case VEC_TRAP14:
-               info.si_code = ILL_ILLTRP;
-               sig = SIGILL;
-               break;
-           case VEC_FPBRUC:
-           case VEC_FPOE:
-           case VEC_FPNAN:
-               info.si_code = FPE_FLTINV;
-               sig = SIGFPE;
-               break;
-           case VEC_FPIR:
-               info.si_code = FPE_FLTRES;
-               sig = SIGFPE;
-               break;
-           case VEC_FPDIVZ:
-               info.si_code = FPE_FLTDIV;
-               sig = SIGFPE;
-               break;
-           case VEC_FPUNDER:
-               info.si_code = FPE_FLTUND;
-               sig = SIGFPE;
-               break;
-           case VEC_FPOVER:
-               info.si_code = FPE_FLTOVF;
-               sig = SIGFPE;
-               break;
-           case VEC_ZERODIV:
-               info.si_code = FPE_INTDIV;
-               sig = SIGFPE;
-               break;
-           case VEC_CHK:
-           case VEC_TRAP:
-               info.si_code = FPE_INTOVF;
-               sig = SIGFPE;
-               break;
-           case VEC_TRACE:             /* ptrace single step */
-               info.si_code = TRAP_TRACE;
-               sig = SIGTRAP;
-               break;
-           case VEC_TRAP15:            /* breakpoint */
-               info.si_code = TRAP_BRKPT;
-               sig = SIGTRAP;
-               break;
-           default:
-               info.si_code = ILL_ILLOPC;
-               sig = SIGILL;
-               break;
-       }
-       info.si_signo = sig;
-       info.si_errno = 0;
-       switch (fp->ptregs.format) {
-           default:
-               info.si_addr = (void *) fp->ptregs.pc;
-               break;
-           case 2:
-               info.si_addr = (void *) fp->un.fmt2.iaddr;
-               break;
-           case 7:
-               info.si_addr = (void *) fp->un.fmt7.effaddr;
-               break;
-           case 9:
-               info.si_addr = (void *) fp->un.fmt9.iaddr;
-               break;
-           case 10:
-               info.si_addr = (void *) fp->un.fmta.daddr;
-               break;
-           case 11:
-               info.si_addr = (void *) fp->un.fmtb.daddr;
-               break;
-       }
-       force_sig_info (sig, &info, current);
-}
-
-void die_if_kernel (char *str, struct pt_regs *fp, int nr)
-{
-       if (!(fp->sr & PS_S))
-               return;
-
-       console_verbose();
-       printk("%s: %08x\n",str,nr);
-       show_registers(fp);
-       add_taint(TAINT_DIE);
-       do_exit(SIGSEGV);
-}
-
-/*
- * This function is called if an error occur while accessing
- * user-space from the fpsp040 code.
- */
-asmlinkage void fpsp040_die(void)
-{
-       do_exit(SIGSEGV);
-}
-
-#ifdef CONFIG_M68KFPU_EMU
-asmlinkage void fpemu_signal(int signal, int code, void *addr)
-{
-       siginfo_t info;
-
-       info.si_signo = signal;
-       info.si_errno = 0;
-       info.si_code = code;
-       info.si_addr = addr;
-       force_sig_info(signal, &info, current);
-}
-#endif
diff --git a/arch/m68k/kernel/traps_no.c b/arch/m68k/kernel/traps_no.c
deleted file mode 100644 (file)
index e67b8c8..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- *  linux/arch/m68knommu/kernel/traps.c
- *
- *  Copyright (C) 1993, 1994 by Hamish Macdonald
- *
- *  68040 fixes by Michael Rausch
- *  68040 fixes by Martin Apel
- *  68060 fixes by Roman Hodek
- *  68060 fixes by Jesper Skov
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/*
- * Sets up all exception vectors
- */
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/user.h>
-#include <linux/string.h>
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/kallsyms.h>
-
-#include <asm/setup.h>
-#include <asm/fpu.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/traps.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/siginfo.h>
-
-static char const * const vec_names[] = {
-       "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
-       "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
-       "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
-       "UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
-       "FORMAT ERROR", "UNINITIALIZED INTERRUPT",
-       "UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
-       "UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
-       "UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
-       "UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
-       "SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
-       "LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
-       "SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
-       "TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
-       "TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
-       "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
-       "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
-       "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
-       "FPCP UNSUPPORTED OPERATION",
-       "MMU CONFIGURATION ERROR"
-};
-
-void die_if_kernel(char *str, struct pt_regs *fp, int nr)
-{
-       if (!(fp->sr & PS_S))
-               return;
-
-       console_verbose();
-       printk(KERN_EMERG "%s: %08x\n",str,nr);
-       printk(KERN_EMERG "PC: [<%08lx>]\nSR: %04x  SP: %p  a2: %08lx\n",
-              fp->pc, fp->sr, fp, fp->a2);
-       printk(KERN_EMERG "d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
-              fp->d0, fp->d1, fp->d2, fp->d3);
-       printk(KERN_EMERG "d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
-              fp->d4, fp->d5, fp->a0, fp->a1);
-
-       printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
-               current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
-       show_stack(NULL, (unsigned long *)(fp + 1));
-       add_taint(TAINT_DIE);
-       do_exit(SIGSEGV);
-}
-
-asmlinkage void buserr_c(struct frame *fp)
-{
-       /* Only set esp0 if coming from user mode */
-       if (user_mode(&fp->ptregs))
-               current->thread.esp0 = (unsigned long) fp;
-
-#if defined(DEBUG)
-       printk (KERN_DEBUG "*** Bus Error *** Format is %x\n", fp->ptregs.format);
-#endif
-
-       die_if_kernel("bad frame format",&fp->ptregs,0);
-#if defined(DEBUG)
-       printk(KERN_DEBUG "Unknown SIGSEGV - 4\n");
-#endif
-       force_sig(SIGSEGV, current);
-}
-
-static void print_this_address(unsigned long addr, int i)
-{
-#ifdef CONFIG_KALLSYMS
-       printk(KERN_EMERG " [%08lx] ", addr);
-       print_symbol(KERN_CONT "%s\n", addr);
-#else
-       if (i % 5)
-               printk(KERN_CONT " [%08lx] ", addr);
-       else
-               printk(KERN_EMERG " [%08lx] ", addr);
-       i++;
-#endif
-}
-
-int kstack_depth_to_print = 48;
-
-static void __show_stack(struct task_struct *task, unsigned long *stack)
-{
-       unsigned long *endstack, addr;
-#ifdef CONFIG_FRAME_POINTER
-       unsigned long *last_stack;
-#endif
-       int i;
-
-       if (!stack)
-               stack = (unsigned long *)task->thread.ksp;
-
-       addr = (unsigned long) stack;
-       endstack = (unsigned long *) PAGE_ALIGN(addr);
-
-       printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
-       for (i = 0; i < kstack_depth_to_print; i++) {
-               if (stack + 1 + i > endstack)
-                       break;
-               if (i % 8 == 0)
-                       printk(KERN_EMERG "       ");
-               printk(KERN_CONT " %08lx", *(stack + i));
-       }
-       printk("\n");
-       i = 0;
-
-#ifdef CONFIG_FRAME_POINTER
-       printk(KERN_EMERG "Call Trace:\n");
-
-       last_stack = stack - 1;
-       while (stack <= endstack && stack > last_stack) {
-
-               addr = *(stack + 1);
-               print_this_address(addr, i);
-               i++;
-
-               last_stack = stack;
-               stack = (unsigned long *)*stack;
-       }
-       printk("\n");
-#else
-       printk(KERN_EMERG "Call Trace with CONFIG_FRAME_POINTER disabled:\n");
-       while (stack <= endstack) {
-               addr = *stack++;
-               /*
-                * If the address is either in the text segment of the kernel,
-                * or in a region which is occupied by a module then it *may*
-                * be the address of a calling routine; if so, print it so that
-                * someone tracing down the cause of the crash will be able to
-                * figure out the call path that was taken.
-                */
-               if (__kernel_text_address(addr)) {
-                       print_this_address(addr, i);
-                       i++;
-               }
-       }
-       printk(KERN_CONT "\n");
-#endif
-}
-
-void bad_super_trap(struct frame *fp)
-{
-       int vector = (fp->ptregs.vector >> 2) & 0xff;
-
-       console_verbose();
-       if (vector < ARRAY_SIZE(vec_names))
-               printk (KERN_WARNING "*** %s ***   FORMAT=%X\n",
-                       vec_names[vector],
-                       fp->ptregs.format);
-       else
-               printk (KERN_WARNING "*** Exception %d ***   FORMAT=%X\n",
-                       vector,
-                       fp->ptregs.format);
-       printk (KERN_WARNING "Current process id is %d\n", current->pid);
-       die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
-}
-
-asmlinkage void trap_c(struct frame *fp)
-{
-       int sig;
-       int vector = (fp->ptregs.vector >> 2) & 0xff;
-       siginfo_t info;
-
-       if (fp->ptregs.sr & PS_S) {
-               if (vector == VEC_TRACE) {
-                       /* traced a trapping instruction */
-               } else
-                       bad_super_trap(fp);
-               return;
-       }
-
-       /* send the appropriate signal to the user program */
-       switch (vector) {
-           case VEC_ADDRERR:
-               info.si_code = BUS_ADRALN;
-               sig = SIGBUS;
-               break;
-           case VEC_ILLEGAL:
-           case VEC_LINE10:
-           case VEC_LINE11:
-               info.si_code = ILL_ILLOPC;
-               sig = SIGILL;
-               break;
-           case VEC_PRIV:
-               info.si_code = ILL_PRVOPC;
-               sig = SIGILL;
-               break;
-           case VEC_COPROC:
-               info.si_code = ILL_COPROC;
-               sig = SIGILL;
-               break;
-           case VEC_TRAP1: /* gdbserver breakpoint */
-               fp->ptregs.pc -= 2;
-               info.si_code = TRAP_TRACE;
-               sig = SIGTRAP;
-               break;
-           case VEC_TRAP2:
-           case VEC_TRAP3:
-           case VEC_TRAP4:
-           case VEC_TRAP5:
-           case VEC_TRAP6:
-           case VEC_TRAP7:
-           case VEC_TRAP8:
-           case VEC_TRAP9:
-           case VEC_TRAP10:
-           case VEC_TRAP11:
-           case VEC_TRAP12:
-           case VEC_TRAP13:
-           case VEC_TRAP14:
-               info.si_code = ILL_ILLTRP;
-               sig = SIGILL;
-               break;
-           case VEC_FPBRUC:
-           case VEC_FPOE:
-           case VEC_FPNAN:
-               info.si_code = FPE_FLTINV;
-               sig = SIGFPE;
-               break;
-           case VEC_FPIR:
-               info.si_code = FPE_FLTRES;
-               sig = SIGFPE;
-               break;
-           case VEC_FPDIVZ:
-               info.si_code = FPE_FLTDIV;
-               sig = SIGFPE;
-               break;
-           case VEC_FPUNDER:
-               info.si_code = FPE_FLTUND;
-               sig = SIGFPE;
-               break;
-           case VEC_FPOVER:
-               info.si_code = FPE_FLTOVF;
-               sig = SIGFPE;
-               break;
-           case VEC_ZERODIV:
-               info.si_code = FPE_INTDIV;
-               sig = SIGFPE;
-               break;
-           case VEC_CHK:
-           case VEC_TRAP:
-               info.si_code = FPE_INTOVF;
-               sig = SIGFPE;
-               break;
-           case VEC_TRACE:             /* ptrace single step */
-               info.si_code = TRAP_TRACE;
-               sig = SIGTRAP;
-               break;
-           case VEC_TRAP15:            /* breakpoint */
-               info.si_code = TRAP_BRKPT;
-               sig = SIGTRAP;
-               break;
-           default:
-               info.si_code = ILL_ILLOPC;
-               sig = SIGILL;
-               break;
-       }
-       info.si_signo = sig;
-       info.si_errno = 0;
-       switch (fp->ptregs.format) {
-           default:
-               info.si_addr = (void *) fp->ptregs.pc;
-               break;
-           case 2:
-               info.si_addr = (void *) fp->un.fmt2.iaddr;
-               break;
-           case 7:
-               info.si_addr = (void *) fp->un.fmt7.effaddr;
-               break;
-           case 9:
-               info.si_addr = (void *) fp->un.fmt9.iaddr;
-               break;
-           case 10:
-               info.si_addr = (void *) fp->un.fmta.daddr;
-               break;
-           case 11:
-               info.si_addr = (void *) fp->un.fmtb.daddr;
-               break;
-       }
-       force_sig_info (sig, &info, current);
-}
-
-asmlinkage void set_esp0(unsigned long ssp)
-{
-       current->thread.esp0 = ssp;
-}
-
-/*
- * The architecture-independent backtrace generator
- */
-void dump_stack(void)
-{
-       /*
-        * We need frame pointers for this little trick, which works as follows:
-        *
-        * +------------+ 0x00
-        * | Next SP    |       -> 0x0c
-        * +------------+ 0x04
-        * | Caller     |
-        * +------------+ 0x08
-        * | Local vars |       -> our stack var
-        * +------------+ 0x0c
-        * | Next SP    |       -> 0x18, that is what we pass to show_stack()
-        * +------------+ 0x10
-        * | Caller     |
-        * +------------+ 0x14
-        * | Local vars |
-        * +------------+ 0x18
-        * | ...        |
-        * +------------+
-        */
-
-       unsigned long *stack;
-
-       stack = (unsigned long *)&stack;
-       stack++;
-       __show_stack(current, stack);
-}
-EXPORT_SYMBOL(dump_stack);
-
-void show_stack(struct task_struct *task, unsigned long *stack)
-{
-       if (!stack && !task)
-               dump_stack();
-       else
-               __show_stack(task, stack);
-}
diff --git a/arch/m68k/kernel/vectors.c b/arch/m68k/kernel/vectors.c
new file mode 100644 (file)
index 0000000..147b03f
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  vectors.c
+ *
+ *  Copyright (C) 1993, 1994 by Hamish Macdonald
+ *
+ *  68040 fixes by Michael Rausch
+ *  68040 fixes by Martin Apel
+ *  68040 fixes and writeback by Richard Zidlicky
+ *  68060 fixes by Roman Hodek
+ *  68060 fixes by Jesper Skov
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Sets up all exception vectors
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/kallsyms.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void nmihandler(void);
+#ifdef CONFIG_M68KFPU_EMU
+asmlinkage void fpu_emu(void);
+#endif
+
+e_vector vectors[256];
+
+/* nmi handler for the Amiga */
+asm(".text\n"
+    __ALIGN_STR "\n"
+    "nmihandler: rte");
+
+/*
+ * this must be called very early as the kernel might
+ * use some instruction that are emulated on the 060
+ * and so we're prepared for early probe attempts (e.g. nf_init).
+ */
+void __init base_trap_init(void)
+{
+       if (MACH_IS_SUN3X) {
+               extern e_vector *sun3x_prom_vbr;
+
+               __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));
+       }
+
+       /* setup the exception vector table */
+       __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
+
+       if (CPU_IS_060) {
+               /* set up ISP entry points */
+               asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
+
+               vectors[VEC_UNIMPII] = unimp_vec;
+       }
+
+       vectors[VEC_BUSERR] = buserr;
+       vectors[VEC_ILLEGAL] = trap;
+       vectors[VEC_SYS] = system_call;
+}
+
+void __init trap_init (void)
+{
+       int i;
+
+       for (i = VEC_SPUR; i <= VEC_INT7; i++)
+               vectors[i] = bad_inthandler;
+
+       for (i = 0; i < VEC_USER; i++)
+               if (!vectors[i])
+                       vectors[i] = trap;
+
+       for (i = VEC_USER; i < 256; i++)
+               vectors[i] = bad_inthandler;
+
+#ifdef CONFIG_M68KFPU_EMU
+       if (FPU_IS_EMU)
+               vectors[VEC_LINE11] = fpu_emu;
+#endif
+
+       if (CPU_IS_040 && !FPU_IS_EMU) {
+               /* set up FPSP entry points */
+               asmlinkage void dz_vec(void) asm ("dz");
+               asmlinkage void inex_vec(void) asm ("inex");
+               asmlinkage void ovfl_vec(void) asm ("ovfl");
+               asmlinkage void unfl_vec(void) asm ("unfl");
+               asmlinkage void snan_vec(void) asm ("snan");
+               asmlinkage void operr_vec(void) asm ("operr");
+               asmlinkage void bsun_vec(void) asm ("bsun");
+               asmlinkage void fline_vec(void) asm ("fline");
+               asmlinkage void unsupp_vec(void) asm ("unsupp");
+
+               vectors[VEC_FPDIVZ] = dz_vec;
+               vectors[VEC_FPIR] = inex_vec;
+               vectors[VEC_FPOVER] = ovfl_vec;
+               vectors[VEC_FPUNDER] = unfl_vec;
+               vectors[VEC_FPNAN] = snan_vec;
+               vectors[VEC_FPOE] = operr_vec;
+               vectors[VEC_FPBRUC] = bsun_vec;
+               vectors[VEC_LINE11] = fline_vec;
+               vectors[VEC_FPUNSUP] = unsupp_vec;
+       }
+
+       if (CPU_IS_060 && !FPU_IS_EMU) {
+               /* set up IFPSP entry points */
+               asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");
+               asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");
+               asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");
+               asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");
+               asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");
+               asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");
+               asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");
+               asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");
+               asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");
+
+               vectors[VEC_FPNAN] = snan_vec6;
+               vectors[VEC_FPOE] = operr_vec6;
+               vectors[VEC_FPOVER] = ovfl_vec6;
+               vectors[VEC_FPUNDER] = unfl_vec6;
+               vectors[VEC_FPDIVZ] = dz_vec6;
+               vectors[VEC_FPIR] = inex_vec6;
+               vectors[VEC_LINE11] = fline_vec6;
+               vectors[VEC_FPUNSUP] = unsupp_vec6;
+               vectors[VEC_UNIMPEA] = effadd_vec6;
+       }
+
+        /* if running on an amiga, make the NMI interrupt do nothing */
+       if (MACH_IS_AMIGA) {
+               vectors[VEC_INT7] = nmihandler;
+       }
+}
+
index 064889316974756878ff3a5f969068ab71b5cc2a..10ca051d56b83cd2b8c9263c01d8ef08cc7383e0 100644 (file)
@@ -22,6 +22,15 @@ void *memcpy(void *to, const void *from, size_t n)
                from = cfrom;
                n--;
        }
+#if defined(CONFIG_M68000)
+       if ((long)from & 1) {
+               char *cto = to;
+               const char *cfrom = from;
+               for (; n; n--)
+                       *cto++ = *cfrom++;
+               return xto;
+       }
+#endif
        if (n > 2 && (long)to & 2) {
                short *sto = to;
                const short *sfrom = from;
index 900d899f33235c32f02cc27a393d1e642f11810b..f92190c159b47f48ee0648d64c0a353f87488477 100644 (file)
@@ -370,7 +370,7 @@ int mac_irq_pending(unsigned int irq)
                break;
        case 4:
                if (psc_present)
-                       psc_irq_pending(irq);
+                       return psc_irq_pending(irq);
                break;
        }
        return 0;
index e023fc6b37e5b88677b4ca5a84821079131b22ea..eb915551de6900d79920f549694d900c04d89ca1 100644 (file)
@@ -304,35 +304,41 @@ static void via_write_pram(int offset, __u8 data)
 static long via_read_time(void)
 {
        union {
-               __u8  cdata[4];
-               long  idata;
+               __u8 cdata[4];
+               long idata;
        } result, last_result;
-       int     ct;
+       int count = 1;
+
+       via_pram_command(0x81, &last_result.cdata[3]);
+       via_pram_command(0x85, &last_result.cdata[2]);
+       via_pram_command(0x89, &last_result.cdata[1]);
+       via_pram_command(0x8D, &last_result.cdata[0]);
 
        /*
         * The NetBSD guys say to loop until you get the same reading
         * twice in a row.
         */
 
-       ct = 0;
-       do {
-               if (++ct > 10) {
-                       printk("via_read_time: couldn't get valid time, "
-                              "last read = 0x%08lx and 0x%08lx\n",
-                              last_result.idata, result.idata);
-                       break;
-               }
-
-               last_result.idata = result.idata;
-               result.idata = 0;
-
+       while (1) {
                via_pram_command(0x81, &result.cdata[3]);
                via_pram_command(0x85, &result.cdata[2]);
                via_pram_command(0x89, &result.cdata[1]);
                via_pram_command(0x8D, &result.cdata[0]);
-       } while (result.idata != last_result.idata);
 
-       return result.idata - RTC_OFFSET;
+               if (result.idata == last_result.idata)
+                       return result.idata - RTC_OFFSET;
+
+               if (++count > 10)
+                       break;
+
+               last_result.idata = result.idata;
+       }
+
+       pr_err("via_read_time: failed to read a stable value; "
+              "got 0x%08lx then 0x%08lx\n",
+              last_result.idata, result.idata);
+
+       return 0;
 }
 
 /*
index 50cd12cf28d97555bdfa45c7e6c256d1af82df3f..1e33d39ca9a029d51bcd730f59eb4f725f4cecda 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/gfp.h>
 
 #include <asm/setup.h>
+#include <asm/sections.h>
 #include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -44,9 +45,6 @@
  */
 void *empty_zero_page;
 
-extern unsigned long memory_start;
-extern unsigned long memory_end;
-
 /*
  * paging_init() continues the virtual memory environment setup which
  * was begun by the code in arch/head.S.
@@ -78,8 +76,6 @@ void __init mem_init(void)
 {
        int codek = 0, datak = 0, initk = 0;
        unsigned long tmp;
-       extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
-       extern unsigned int _ramend, _rambase;
        unsigned long len = _ramend - _rambase;
        unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
        unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
@@ -95,9 +91,9 @@ void __init mem_init(void)
        /* this will put all memory onto the freelists */
        totalram_pages = free_all_bootmem();
 
-       codek = (&_etext - &_stext) >> 10;
-       datak = (&_ebss - &_sdata) >> 10;
-       initk = (&__init_begin - &__init_end) >> 10;
+       codek = (_etext - _stext) >> 10;
+       datak = (_ebss - _sdata) >> 10;
+       initk = (__init_begin - __init_end) >> 10;
 
        tmp = nr_free_pages() << PAGE_SHIFT;
        printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n",
@@ -129,22 +125,21 @@ void free_initmem(void)
 {
 #ifdef CONFIG_RAMKERNEL
        unsigned long addr;
-       extern char __init_begin, __init_end;
        /*
         * The following code should be cool even if these sections
         * are not page aligned.
         */
-       addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+       addr = PAGE_ALIGN((unsigned long) __init_begin);
        /* next to check that the page we free is not a partial page */
-       for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
+       for (; addr + PAGE_SIZE < ((unsigned long) __init_end); addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
                init_page_count(virt_to_page(addr));
                free_page(addr);
                totalram_pages++;
        }
        pr_notice("Freeing unused kernel memory: %luk freed (0x%x - 0x%x)\n",
-                       (addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
-                       (int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
+                       (addr - PAGE_ALIGN((unsigned long) __init_begin)) >> 10,
+                       (int)(PAGE_ALIGN((unsigned long) __init_begin)),
                        (int)(addr - PAGE_SIZE));
 #endif
 }
index 621238f1a219cc857c7962d527dfa5d673c26b97..8a98683f1b15a4062abee4497643c23fe96edf00 100644 (file)
@@ -91,9 +91,9 @@ static struct resource m520x_qspi_resources[] = {
        },
 };
 
-#define MCFQSPI_CS0    62
-#define MCFQSPI_CS1    63
-#define MCFQSPI_CS2    44
+#define MCFQSPI_CS0    46
+#define MCFQSPI_CS1    47
+#define MCFQSPI_CS2    27
 
 static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control)
 {
index d757328563d1df49d8bdd12fe81807733d621b30..9bcc3e4b60c582950a9e8698bb63b883452d56b5 100644 (file)
@@ -36,42 +36,6 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                .podr                           = (void __iomem *) MCFEPORT_EPDR,
                .ppdr                           = (void __iomem *) MCFEPORT_EPPDR,
        },
-       {
-               .gpio_chip                      = {
-                       .label                  = "BUSCTL",
-                       .request                = mcf_gpio_request,
-                       .free                   = mcf_gpio_free,
-                       .direction_input        = mcf_gpio_direction_input,
-                       .direction_output       = mcf_gpio_direction_output,
-                       .get                    = mcf_gpio_get_value,
-                       .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 8,
-                       .ngpio                  = 4,
-               },
-               .pddr                           = (void __iomem *) MCFGPIO_PDDR_BUSCTL,
-               .podr                           = (void __iomem *) MCFGPIO_PODR_BUSCTL,
-               .ppdr                           = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL,
-               .setr                           = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL,
-               .clrr                           = (void __iomem *) MCFGPIO_PCLRR_BUSCTL,
-       },
-       {
-               .gpio_chip                      = {
-                       .label                  = "BE",
-                       .request                = mcf_gpio_request,
-                       .free                   = mcf_gpio_free,
-                       .direction_input        = mcf_gpio_direction_input,
-                       .direction_output       = mcf_gpio_direction_output,
-                       .get                    = mcf_gpio_get_value,
-                       .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 16,
-                       .ngpio                  = 4,
-               },
-               .pddr                           = (void __iomem *) MCFGPIO_PDDR_BE,
-               .podr                           = (void __iomem *) MCFGPIO_PODR_BE,
-               .ppdr                           = (void __iomem *) MCFGPIO_PPDSDR_BE,
-               .setr                           = (void __iomem *) MCFGPIO_PPDSDR_BE,
-               .clrr                           = (void __iomem *) MCFGPIO_PCLRR_BE,
-       },
        {
                .gpio_chip                      = {
                        .label                  = "CS",
@@ -81,7 +45,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 25,
+                       .base                   = 9,
                        .ngpio                  = 3,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_CS,
@@ -99,7 +63,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 32,
+                       .base                   = 16,
                        .ngpio                  = 4,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_FECI2C,
@@ -117,7 +81,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 40,
+                       .base                   = 24,
                        .ngpio                  = 4,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_QSPI,
@@ -135,7 +99,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 48,
+                       .base                   = 32,
                        .ngpio                  = 4,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_TIMER,
@@ -153,7 +117,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 56,
+                       .base                   = 40,
                        .ngpio                  = 8,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_UART,
@@ -171,7 +135,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 64,
+                       .base                   = 48,
                        .ngpio                  = 8,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_FECH,
@@ -189,7 +153,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
                        .direction_output       = mcf_gpio_direction_output,
                        .get                    = mcf_gpio_get_value,
                        .set                    = mcf_gpio_set_value_fast,
-                       .base                   = 72,
+                       .base                   = 56,
                        .ngpio                  = 8,
                },
                .pddr                           = (void __iomem *) MCFGPIO_PDDR_FECL,
index 5e5435552d5652da8b4e1b0fa6f81c24a9a028b4..e4dfd8fde068b9ed9738590d13db02ddb1bdc0f0 100644 (file)
@@ -2,7 +2,10 @@
 # Makefile for arch/m68knommu/platform/68328.
 #
 
-head-y                 = head-$(MODEL).o
+model-y                          := ram
+model-$(CONFIG_ROMKERNEL) := rom
+
+head-y                 = head-$(model-y).o
 head-$(CONFIG_PILOT)   = head-pilot.o
 head-$(CONFIG_DRAGEN2) = head-de2.o
 
index 293e1eba9accd3551f5d266704a7ffefda4c02ec..5c39b80ed7de0bf16362a1e51a9ede3086a7ad9a 100644 (file)
@@ -67,7 +67,7 @@ ret_from_signal:
        jra     ret_from_exception
 
 ENTRY(system_call)
-       SAVE_ALL
+       SAVE_ALL_SYS
 
        /* save top of frame*/
        pea     %sp@
@@ -129,7 +129,7 @@ Lsignal_return:
  * This is the main interrupt handler, responsible for calling process_int()
  */
 inthandler1:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -140,7 +140,7 @@ inthandler1:
        bra     ret_from_interrupt
 
 inthandler2:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -151,7 +151,7 @@ inthandler2:
        bra     ret_from_interrupt
 
 inthandler3:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -162,7 +162,7 @@ inthandler3:
        bra     ret_from_interrupt
 
 inthandler4:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -173,7 +173,7 @@ inthandler4:
        bra     ret_from_interrupt
 
 inthandler5:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -184,7 +184,7 @@ inthandler5:
        bra     ret_from_interrupt
 
 inthandler6:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -195,7 +195,7 @@ inthandler6:
        bra     ret_from_interrupt
 
 inthandler7:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
@@ -206,7 +206,7 @@ inthandler7:
        bra     ret_from_interrupt
 
 inthandler:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and     #0x3ff, %d0
 
index cf5af73a57899cf4e85ebe5886f84a03ef079530..f6f43438304935908f59705dfa24ae7f174e29cb 100644 (file)
@@ -1,10 +1,12 @@
 #
 # Makefile for arch/m68knommu/platform/68360.
 #
+model-y                          := ram
+model-$(CONFIG_ROMKERNEL) := rom
 
 obj-y := config.o commproc.o entry.o ints.o
 
 extra-y := head.o
 
-$(obj)/head.o: $(obj)/head-$(MODEL).o
-       ln -sf head-$(MODEL).o $(obj)/head.o
+$(obj)/head.o: $(obj)/head-$(model-y).o
+       ln -sf head-$(model-y).o $(obj)/head.o
index abbb89672ea02789b4364b7c261e0f3cd2a5f53a..aa47d1d49929cb508824a0cccde1fad4066309af 100644 (file)
@@ -63,7 +63,7 @@ ret_from_signal:
        jra     ret_from_exception
 
 ENTRY(system_call)
-       SAVE_ALL
+       SAVE_ALL_SYS
 
        /* save top of frame*/
        pea     %sp@
@@ -125,7 +125,7 @@ Lsignal_return:
  * This is the main interrupt handler, responsible for calling do_IRQ()
  */
 inthandler:
-       SAVE_ALL
+       SAVE_ALL_INT
        movew   %sp@(PT_OFF_FORMATVEC), %d0
        and.l   #0x3ff, %d0
        lsr.l   #0x02,  %d0
index bd27242c2f431da58a0e5bebb78aa4deb803ba92..3157461a8d1da8c6cd07af7709abd17ba03b3a3b 100644 (file)
@@ -61,7 +61,7 @@ enosys:
        bra     1f
 
 ENTRY(system_call)
-       SAVE_ALL
+       SAVE_ALL_SYS
        move    #0x2000,%sr             /* enable intrs again */
 
        cmpl    #NR_syscalls,%d0
@@ -165,9 +165,7 @@ Lsignal_return:
  * sources). Calls up to high level code to do all the work.
  */
 ENTRY(inthandler)
-       SAVE_ALL
-       moveq   #-1,%d0
-       movel   %d0,%sp@(PT_OFF_ORIG_D0)
+       SAVE_ALL_INT
 
        movew   %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
        andl    #0x03fc,%d0             /* mask out vector only */
index b73da2ac21b34e350439b2ec4359ba5454a5cf16..1a8ab6a5c03fc3ab399cd8fa75003b4220e69cd5 100644 (file)
@@ -125,7 +125,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_MEMDIE             6       /* is terminating due to OOM killer */
 #define TIF_SYSCALL_AUDIT      9       /* syscall auditing active */
 #define TIF_SECCOMP            10      /* secure computing */
-#define TIF_FREEZE             14      /* Freezing for suspend */
 
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_POLLING_NRFLAG     16
@@ -137,7 +136,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_IRET              (1 << TIF_IRET)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 
index 177cdaf835644fdf613dbafd203a8e2dcf0e08d3..fabcaeda7afa1fb5e48ab247c7c173b532ff4925 100644 (file)
@@ -24,6 +24,7 @@ config MIPS
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_JUMP_LABEL
+       select IRQ_FORCED_THREADING
 
 menu "Machine selection"
 
@@ -91,15 +92,8 @@ config BCM47XX
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
-       select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
-       select SSB
-       select SSB_DRIVER_MIPS
-       select SSB_DRIVER_EXTIF
-       select SSB_EMBEDDED
-       select SSB_B43_PCI_BRIDGE if PCI
-       select SSB_PCICORE_HOSTMODE if PCI
        select GENERIC_GPIO
        select SYS_HAS_EARLY_PRINTK
        select CFE
@@ -788,6 +782,7 @@ endchoice
 
 source "arch/mips/alchemy/Kconfig"
 source "arch/mips/ath79/Kconfig"
+source "arch/mips/bcm47xx/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
index 53e3514ba10e93c249d837f460fb86fbe3879f52..eede9b350803b230649c189b34ff16543025d107 100644 (file)
@@ -295,7 +295,9 @@ endif
 
 install:
        $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
+ifdef CONFIG_SYS_SUPPORTS_ZBOOT
        $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE)
+endif
        $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
        $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
 
index 3b2c18b14341c22c10af18699bc36b844466ea9a..f72c48d4804c30989e78324639ec516f6d1aea75 100644 (file)
@@ -492,7 +492,7 @@ static void __init alchemy_setup_macs(int ctype)
                memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
 
        ret = platform_device_register(&au1xxx_eth0_device);
-       if (!ret)
+       if (ret)
                printk(KERN_INFO "Alchemy: failed to register MAC0\n");
 
 
index 647e518c90bc4bf239a0f3499822edd58616ec3c..b86324a42601105f7b540d25c3b89c1245b69b5e 100644 (file)
@@ -158,15 +158,21 @@ static void restore_core_regs(void)
 
 void au_sleep(void)
 {
-       int cpuid = alchemy_get_cputype();
-       if (cpuid != ALCHEMY_CPU_UNKNOWN) {
-               save_core_regs();
-               if (cpuid <= ALCHEMY_CPU_AU1500)
-                       alchemy_sleep_au1000();
-               else if (cpuid <= ALCHEMY_CPU_AU1200)
-                       alchemy_sleep_au1550();
-               restore_core_regs();
+       save_core_regs();
+
+       switch (alchemy_get_cputype()) {
+       case ALCHEMY_CPU_AU1000:
+       case ALCHEMY_CPU_AU1500:
+       case ALCHEMY_CPU_AU1100:
+               alchemy_sleep_au1000();
+               break;
+       case ALCHEMY_CPU_AU1550:
+       case ALCHEMY_CPU_AU1200:
+               alchemy_sleep_au1550();
+               break;
        }
+
+       restore_core_regs();
 }
 
 #endif /* CONFIG_PM */
index fbb55935b99e71ee3be1475657ca8fdfdf981ee5..dda090bf74e6bb1a9f47a8492324fd167b5b06ad 100644 (file)
@@ -422,6 +422,7 @@ static struct resource au1200_psc1_res[] = {
        },
 };
 
+/* AC97 or I2S device */
 static struct platform_device db1200_audio_dev = {
        /* name assigned later based on switch setting */
        .id             = 1,    /* PSC ID */
@@ -429,19 +430,32 @@ static struct platform_device db1200_audio_dev = {
        .resource       = au1200_psc1_res,
 };
 
+/* DB1200 ASoC card device */
+static struct platform_device db1200_sound_dev = {
+       /* name assigned later based on switch setting */
+       .id             = 1,    /* PSC ID */
+};
+
 static struct platform_device db1200_stac_dev = {
        .name           = "ac97-codec",
        .id             = 1,    /* on PSC1 */
 };
 
+static struct platform_device db1200_audiodma_dev = {
+       .name           = "au1xpsc-pcm",
+       .id             = 1,    /* PSC ID */
+};
+
 static struct platform_device *db1200_devs[] __initdata = {
        NULL,           /* PSC0, selected by S6.8 */
        &db1200_ide_dev,
        &db1200_eth_dev,
        &db1200_rtc_dev,
        &db1200_nand_dev,
+       &db1200_audiodma_dev,
        &db1200_audio_dev,
        &db1200_stac_dev,
+       &db1200_sound_dev,
 };
 
 static int __init db1200_dev_init(void)
@@ -501,10 +515,12 @@ static int __init db1200_dev_init(void)
        if (sw == BCSR_SWITCHES_DIP_8) {
                bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
                db1200_audio_dev.name = "au1xpsc_i2s";
+               db1200_sound_dev.name = "db1200-i2s";
                printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
        } else {
                bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
                db1200_audio_dev.name = "au1xpsc_ac97";
+               db1200_sound_dev.name = "db1200-ac97";
                printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
        }
 
index 978d5ab3d6781781eb5cb2d5acb117b3c443a81c..7057d28f73016dffb4136fb7d5856c1e19f66dac 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/platform_device.h>
 
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-db1x00/bcsr.h>
 #include "../platform.h"
 #endif
 #endif
 
+static struct resource alchemy_ac97c_res[] = {
+       [0] = {
+               .start  = AU1000_AC97_PHYS_ADDR,
+               .end    = AU1000_AC97_PHYS_ADDR + 0xfff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMA_ID_AC97C_TX,
+               .end    = DMA_ID_AC97C_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMA_ID_AC97C_RX,
+               .end    = DMA_ID_AC97C_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct platform_device alchemy_ac97c_dev = {
+       .name           = "alchemy-ac97c",
+       .id             = -1,
+       .resource       = alchemy_ac97c_res,
+       .num_resources  = ARRAY_SIZE(alchemy_ac97c_res),
+};
+
+static struct platform_device alchemy_ac97c_dma_dev = {
+       .name           = "alchemy-pcm-dma",
+       .id             = 0,
+};
+
+static struct platform_device db1x00_codec_dev = {
+       .name           = "ac97-codec",
+       .id             = -1,
+};
+
+static struct platform_device db1x00_audio_dev = {
+       .name           = "db1000-audio",
+};
+
 static int __init db1xxx_dev_init(void)
 {
 #ifdef DB1XXX_HAS_PCMCIA
@@ -113,6 +155,12 @@ static int __init db1xxx_dev_init(void)
                                    1);
 #endif
        db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
+
+       platform_device_register(&db1x00_codec_dev);
+       platform_device_register(&alchemy_ac97c_dma_dev);
+       platform_device_register(&alchemy_ac97c_dev);
+       platform_device_register(&db1x00_audio_dev);
+
        return 0;
 }
 device_initcall(db1xxx_dev_init);
index 03db3daadbd8f95524783ae7c802e9524e9fb346..88c4babfdb5d491dd151906f20d3c5df068f946c 100644 (file)
@@ -98,7 +98,8 @@ static struct irq_chip ar7_sec_irq_type = {
 
 static struct irqaction ar7_cascade_action = {
        .handler = no_action,
-       .name = "AR7 cascade interrupt"
+       .name = "AR7 cascade interrupt",
+       .flags = IRQF_NO_THREAD,
 };
 
 static void __init ar7_irq_init(int base)
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
new file mode 100644 (file)
index 0000000..6210b8d
--- /dev/null
@@ -0,0 +1,31 @@
+if BCM47XX
+
+config BCM47XX_SSB
+       bool "SSB Support for Broadcom BCM47XX"
+       select SYS_HAS_CPU_MIPS32_R1
+       select SSB
+       select SSB_DRIVER_MIPS
+       select SSB_DRIVER_EXTIF
+       select SSB_EMBEDDED
+       select SSB_B43_PCI_BRIDGE if PCI
+       select SSB_PCICORE_HOSTMODE if PCI
+       default y
+       help
+        Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
+
+        This will generate an image with support for SSB and MIPS32 R1 instruction set.
+
+config BCM47XX_BCMA
+       bool "BCMA Support for Broadcom BCM47XX"
+       select SYS_HAS_CPU_MIPS32_R2
+       select BCMA
+       select BCMA_HOST_SOC
+       select BCMA_DRIVER_MIPS
+       select BCMA_DRIVER_PCI_HOSTMODE if PCI
+       default y
+       help
+        Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
+
+        This will generate an image with support for BCMA and MIPS32 R2 instruction set.
+
+endif
index 7465e8a72d9a674cd425bb705e99bbd6eb2cfff4..4add17349ff9549a264da1814249ae533144e042 100644 (file)
@@ -3,4 +3,5 @@
 # under Linux.
 #
 
-obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
+obj-y                          += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
+obj-$(CONFIG_BCM47XX_SSB)      += wgt634u.o
index e4a5ee9c97217381e324774d2c4777f7801d85c5..57b425fd4d412b2e685804065255fef55af7affc 100644 (file)
@@ -20,42 +20,82 @@ static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
 
 int gpio_request(unsigned gpio, const char *tag)
 {
-       if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-           ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-               return -EINVAL;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
+                   ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+                       return -EINVAL;
 
-       if (ssb_extif_available(&ssb_bcm47xx.extif) &&
-           ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-               return -EINVAL;
+               if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+                   ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+                       return -EINVAL;
 
-       if (test_and_set_bit(gpio, gpio_in_use))
-               return -EBUSY;
+               if (test_and_set_bit(gpio, gpio_in_use))
+                       return -EBUSY;
 
-       return 0;
+               return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
+                       return -EINVAL;
+
+               if (test_and_set_bit(gpio, gpio_in_use))
+                       return -EBUSY;
+
+               return 0;
+#endif
+       }
+       return -EINVAL;
 }
 EXPORT_SYMBOL(gpio_request);
 
 void gpio_free(unsigned gpio)
 {
-       if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-           ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-               return;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
+                   ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+                       return;
+
+               if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+                   ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+                       return;
 
-       if (ssb_extif_available(&ssb_bcm47xx.extif) &&
-           ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+               clear_bit(gpio, gpio_in_use);
                return;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
+                       return;
 
-       clear_bit(gpio, gpio_in_use);
+               clear_bit(gpio, gpio_in_use);
+               return;
+#endif
+       }
 }
 EXPORT_SYMBOL(gpio_free);
 
 int gpio_to_irq(unsigned gpio)
 {
-       if (ssb_chipco_available(&ssb_bcm47xx.chipco))
-               return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
-       else if (ssb_extif_available(&ssb_bcm47xx.extif))
-               return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
-       else
-               return -EINVAL;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
+                       return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
+               else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
+                       return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
+               else
+                       return -EINVAL;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
+#endif
+       }
+       return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(gpio_to_irq);
index 325757acd020932670f4bc68ee5b62ee7ad36746..8cf3833b2d293626189b0d1a8f130e6fe726ae37 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/irq_cpu.h>
+#include <bcm47xx.h>
 
 void plat_irq_dispatch(void)
 {
@@ -51,5 +52,16 @@ void plat_irq_dispatch(void)
 
 void __init arch_init_irq(void)
 {
+#ifdef CONFIG_BCM47XX_BCMA
+       if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
+               bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
+                            BCMA_MIPS_MIPS74K_INTMASK(5), 1 << 31);
+               /*
+                * the kernel reads the timer irq from some register and thinks
+                * it's #5, but we offset it by 2 and route to #7
+                */
+               cp0_compare_irq = 7;
+       }
+#endif
        mips_cpu_irq_init();
 }
index 54db815bc86c46e3586e5b9c7061cb32e96f1e37..a84e3bb7387f685bc7025e689e01e57cfa97bd21 100644 (file)
@@ -26,14 +26,35 @@ static char nvram_buf[NVRAM_SPACE];
 /* Probe for NVRAM header */
 static void early_nvram_init(void)
 {
-       struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+#ifdef CONFIG_BCM47XX_SSB
+       struct ssb_mipscore *mcore_ssb;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       struct bcma_drv_cc *bcma_cc;
+#endif
        struct nvram_header *header;
        int i;
-       u32 base, lim, off;
+       u32 base = 0;
+       u32 lim = 0;
+       u32 off;
        u32 *src, *dst;
 
-       base = mcore->flash_window;
-       lim = mcore->flash_window_size;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               mcore_ssb = &bcm47xx_bus.ssb.mipscore;
+               base = mcore_ssb->flash_window;
+               lim = mcore_ssb->flash_window_size;
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
+               base = bcma_cc->pflash.window;
+               lim = bcma_cc->pflash.window_size;
+               break;
+#endif
+       }
 
        off = FLASH_MIN;
        while (off <= lim) {
index 59c11afdb2abe2deaed46f9725ceeac1fa7ef098..57981e4fe2bc94c143070ee99ecf66d09ceae223 100644 (file)
@@ -23,10 +23,11 @@ static struct platform_device uart8250_device = {
        },
 };
 
-static int __init uart8250_init(void)
+#ifdef CONFIG_BCM47XX_SSB
+static int __init uart8250_init_ssb(void)
 {
        int i;
-       struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore);
+       struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
 
        memset(&uart8250_data, 0,  sizeof(uart8250_data));
 
@@ -44,6 +45,47 @@ static int __init uart8250_init(void)
        }
        return platform_device_register(&uart8250_device);
 }
+#endif
+
+#ifdef CONFIG_BCM47XX_BCMA
+static int __init uart8250_init_bcma(void)
+{
+       int i;
+       struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
+
+       memset(&uart8250_data, 0,  sizeof(uart8250_data));
+
+       for (i = 0; i < cc->nr_serial_ports; i++) {
+               struct plat_serial8250_port *p = &(uart8250_data[i]);
+               struct bcma_serial_port *bcma_port;
+               bcma_port = &(cc->serial_ports[i]);
+
+               p->mapbase = (unsigned int) bcma_port->regs;
+               p->membase = (void *) bcma_port->regs;
+               p->irq = bcma_port->irq + 2;
+               p->uartclk = bcma_port->baud_base;
+               p->regshift = bcma_port->reg_shift;
+               p->iotype = UPIO_MEM;
+               p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       }
+       return platform_device_register(&uart8250_device);
+}
+#endif
+
+static int __init uart8250_init(void)
+{
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               return uart8250_init_ssb();
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return uart8250_init_bcma();
+#endif
+       }
+       return -EINVAL;
+}
 
 module_init(uart8250_init);
 
index cfae81571dedd91d9411d7457fc9322497b93896..17c3d14d7c4900d5e06c5a0549a27de5db86f06e 100644 (file)
 #include <linux/types.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
+#include <linux/bcma/bcma_soc.h>
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
 #include <asm/mach-bcm47xx/nvram.h>
 
-struct ssb_bus ssb_bcm47xx;
-EXPORT_SYMBOL(ssb_bcm47xx);
+union bcm47xx_bus bcm47xx_bus;
+EXPORT_SYMBOL(bcm47xx_bus);
+
+enum bcm47xx_bus_type bcm47xx_bus_type;
+EXPORT_SYMBOL(bcm47xx_bus_type);
 
 static void bcm47xx_machine_restart(char *command)
 {
        printk(KERN_ALERT "Please stand by while rebooting the system...\n");
        local_irq_disable();
        /* Set the watchdog timer to reset immediately */
-       ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
+               break;
+#endif
+       }
        while (1)
                cpu_relax();
 }
@@ -52,11 +67,23 @@ static void bcm47xx_machine_halt(void)
 {
        /* Disable interrupts and watchdog and spin forever */
        local_irq_disable();
-       ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
+               break;
+#endif
+       }
        while (1)
                cpu_relax();
 }
 
+#ifdef CONFIG_BCM47XX_SSB
 #define READ_FROM_NVRAM(_outvar, name, buf) \
        if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
                sprom->_outvar = simple_strtoul(buf, NULL, 0);
@@ -247,7 +274,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
        return 0;
 }
 
-void __init plat_mem_setup(void)
+static void __init bcm47xx_register_ssb(void)
 {
        int err;
        char buf[100];
@@ -258,12 +285,12 @@ void __init plat_mem_setup(void)
                printk(KERN_WARNING "bcm47xx: someone else already registered"
                        " a ssb SPROM callback handler (err %d)\n", err);
 
-       err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
+       err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
                                      bcm47xx_get_invariants);
        if (err)
                panic("Failed to initialize SSB bus (err %d)\n", err);
 
-       mcore = &ssb_bcm47xx.mipscore;
+       mcore = &bcm47xx_bus.ssb.mipscore;
        if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
                if (strstr(buf, "console=ttyS1")) {
                        struct ssb_serial_port port;
@@ -276,8 +303,57 @@ void __init plat_mem_setup(void)
                        memcpy(&mcore->serial_ports[1], &port, sizeof(port));
                }
        }
+}
+#endif
+
+#ifdef CONFIG_BCM47XX_BCMA
+static void __init bcm47xx_register_bcma(void)
+{
+       int err;
+
+       err = bcma_host_soc_register(&bcm47xx_bus.bcma);
+       if (err)
+               panic("Failed to initialize BCMA bus (err %d)\n", err);
+}
+#endif
+
+void __init plat_mem_setup(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       if (c->cputype == CPU_74K) {
+               printk(KERN_INFO "bcm47xx: using bcma bus\n");
+#ifdef CONFIG_BCM47XX_BCMA
+               bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
+               bcm47xx_register_bcma();
+#endif
+       } else {
+               printk(KERN_INFO "bcm47xx: using ssb bus\n");
+#ifdef CONFIG_BCM47XX_SSB
+               bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
+               bcm47xx_register_ssb();
+#endif
+       }
 
        _machine_restart = bcm47xx_machine_restart;
        _machine_halt = bcm47xx_machine_halt;
        pm_power_off = bcm47xx_machine_halt;
 }
+
+static int __init bcm47xx_register_bus_complete(void)
+{
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               /* Nothing to do */
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_bus_register(&bcm47xx_bus.bcma.bus);
+               break;
+#endif
+       }
+       return 0;
+}
+device_initcall(bcm47xx_register_bus_complete);
index 0c6f47b3fd9482d838d4ffec4c5e47150523a74b..536374dcba78995981b2a0bc04ab7ae62941aa00 100644 (file)
@@ -30,7 +30,7 @@
 
 void __init plat_time_init(void)
 {
-       unsigned long hz;
+       unsigned long hz = 0;
 
        /*
         * Use deterministic values for initial counter interrupt
@@ -39,7 +39,19 @@ void __init plat_time_init(void)
        write_c0_count(0);
        write_c0_compare(0xffff);
 
-       hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
+               break;
+#endif
+       }
+
        if (!hz)
                hz = 100000000;
 
index 74d06965326f7ccd6e140b367b088a04d915d809..e9f9ec8d443b5b959ef4b164b0a46197cad7ebb9 100644 (file)
@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int irq, void *ignored)
 
        /* Interrupts are shared, check if the current one is
           a GPIO interrupt. */
-       if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
+       if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
                                   SSB_CHIPCO_IRQ_GPIO))
                return IRQ_NONE;
 
@@ -132,22 +132,26 @@ static int __init wgt634u_init(void)
         * machine. Use the MAC address as an heuristic. Netgear Inc. has
         * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
         */
+       u8 *et0mac;
 
-       u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+       if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
+               return -ENODEV;
+
+       et0mac = bcm47xx_bus.ssb.sprom.et0mac;
 
        if (et0mac[0] == 0x00 &&
            ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
             (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
-               struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+               struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
 
                printk(KERN_INFO "WGT634U machine detected.\n");
 
                if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
                                 gpio_interrupt, IRQF_SHARED,
-                                "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
+                                "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
                        gpio_direction_input(WGT634U_GPIO_RESET);
                        gpio_intmask(WGT634U_GPIO_RESET, 1);
-                       ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
+                       ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
                                            SSB_CHIPCO_IRQ_GPIO,
                                            SSB_CHIPCO_IRQ_GPIO);
                }
index cea6021cb8d7a3172976bd1a8c7b378b41331c93..162e11b4ed755f7e227d4cfc485d40170716abdf 100644 (file)
@@ -222,6 +222,7 @@ static struct irq_chip bcm63xx_external_irq_chip = {
 static struct irqaction cpu_ip2_cascade_action = {
        .handler        = no_action,
        .name           = "cascade_ip2",
+       .flags          = IRQF_NO_THREAD,
 };
 
 void __init arch_init_irq(void)
index cb9bf820fe53b4640a7b72264be61deacf998fa7..965c777d356132df575aa6f42534a58b17443415 100644 (file)
@@ -48,6 +48,7 @@ asmlinkage void plat_irq_dispatch(void)
 static struct irqaction cascade = {
        .handler        = no_action,
        .name           = "cascade",
+       .flags          = IRQF_NO_THREAD,
 };
 
 void __init arch_init_irq(void)
index fa45e924be05b9e40cf9d23b5a6a866034dfb8f3..f7b7ba6d5c45f589951f301bca6f29bc1e8bacba 100644 (file)
@@ -101,20 +101,24 @@ int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
 static struct irqaction ioirq = {
        .handler = no_action,
        .name = "cascade",
+       .flags = IRQF_NO_THREAD,
 };
 static struct irqaction fpuirq = {
        .handler = no_action,
        .name = "fpu",
+       .flags = IRQF_NO_THREAD,
 };
 
 static struct irqaction busirq = {
        .flags = IRQF_DISABLED,
        .name = "bus error",
+       .flags = IRQF_NO_THREAD,
 };
 
 static struct irqaction haltirq = {
        .handler = dec_intr_halt,
        .name = "halt",
+       .flags = IRQF_NO_THREAD,
 };
 
 
index 3dbd7a5a6ad33f5ab8335c0c45d84f235adb9d01..7798887a1288a7fc529e29d536287536a6dd628b 100644 (file)
@@ -169,7 +169,7 @@ void emma2rh_gpio_irq_init(void)
 
 static struct irqaction irq_cascade = {
           .handler = no_action,
-          .flags = 0,
+          .flags = IRQF_NO_THREAD,
           .name = "cascade",
           .dev_id = NULL,
           .next = NULL,
index 40bb9fde205ff9756812134cc826120f5d8bcb30..69468ded282820efd9547f7aa3837562e56db016 100644 (file)
@@ -114,4 +114,28 @@ unsigned long run_uncached(void *func);
 extern void *kmap_coherent(struct page *page, unsigned long addr);
 extern void kunmap_coherent(void);
 
+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+static inline void flush_kernel_dcache_page(struct page *page)
+{
+       BUG_ON(cpu_has_dc_aliases && PageHighMem(page));
+}
+
+/*
+ * For now flush_kernel_vmap_range and invalidate_kernel_vmap_range both do a
+ * cache writeback and invalidate operation.
+ */
+extern void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
+
+static inline void flush_kernel_vmap_range(void *vaddr, int size)
+{
+       if (cpu_has_dc_aliases)
+               __flush_kernel_vmap_range((unsigned long) vaddr, size);
+}
+
+static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
+{
+       if (cpu_has_dc_aliases)
+               __flush_kernel_vmap_range((unsigned long) vaddr, size);
+}
+
 #endif /* _ASM_CACHEFLUSH_H */
index b04e4de5dd2e0a2cf39074cd82b8d67f3eb81cce..a58f22998a86507729e3d72d379ef6e23ddad019 100644 (file)
@@ -329,14 +329,10 @@ static inline void pfx##write##bwlq(type val,                             \
                        "dsrl32 %L0, %L0, 0"                    "\n\t"  \
                        "dsll32 %M0, %M0, 0"                    "\n\t"  \
                        "or     %L0, %L0, %M0"                  "\n\t"  \
-                       ".set   push"                           "\n\t"  \
-                       ".set   noreorder"                      "\n\t"  \
-                       ".set   nomacro"                        "\n\t"  \
                        "sd     %L0, %2"                        "\n\t"  \
-                       ".set   pop"                            "\n\t"  \
                        ".set   mips0"                          "\n"    \
                        : "=r" (__tmp)                                  \
-                       : "0" (__val), "R" (*__mem));                   \
+                       : "0" (__val), "m" (*__mem));                   \
                if (irq)                                                \
                        local_irq_restore(__flags);                     \
        } else                                                          \
@@ -359,16 +355,12 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem)      \
                        local_irq_save(__flags);                        \
                __asm__ __volatile__(                                   \
                        ".set   mips3"          "\t\t# __readq" "\n\t"  \
-                       ".set   push"                           "\n\t"  \
-                       ".set   noreorder"                      "\n\t"  \
-                       ".set   nomacro"                        "\n\t"  \
                        "ld     %L0, %1"                        "\n\t"  \
-                       ".set   pop"                            "\n\t"  \
                        "dsra32 %M0, %L0, 0"                    "\n\t"  \
                        "sll    %L0, %L0, 0"                    "\n\t"  \
                        ".set   mips0"                          "\n"    \
                        : "=r" (__val)                                  \
-                       : "R" (*__mem));                                \
+                       : "m" (*__mem));                                \
                if (irq)                                                \
                        local_irq_restore(__flags);                     \
        } else {                                                        \
index d008f47a28bdf8d9a9473c9a4f034dc406e02a1e..de95e0723e2bb058d3164a54c6cc9a1153b9b6e0 100644 (file)
 #ifndef __ASM_BCM47XX_H
 #define __ASM_BCM47XX_H
 
-/* SSB bus */
-extern struct ssb_bus ssb_bcm47xx;
+#include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_soc.h>
+
+enum bcm47xx_bus_type {
+#ifdef CONFIG_BCM47XX_SSB
+       BCM47XX_BUS_TYPE_SSB,
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       BCM47XX_BUS_TYPE_BCMA,
+#endif
+};
+
+union bcm47xx_bus {
+#ifdef CONFIG_BCM47XX_SSB
+       struct ssb_bus ssb;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       struct bcma_soc bcma;
+#endif
+};
+
+extern union bcm47xx_bus bcm47xx_bus;
+extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
 #endif /* __ASM_BCM47XX_H */
index 98504142124ec97ed571b2c36696c87d3c91e6ac..76961cabeedfe1cdac4caaef7e9989ca04a345be 100644 (file)
@@ -10,6 +10,7 @@
 #define __BCM47XX_GPIO_H
 
 #include <linux/ssb/ssb_embedded.h>
+#include <linux/bcma/bcma.h>
 #include <asm/mach-bcm47xx/bcm47xx.h>
 
 #define BCM47XX_EXTIF_GPIO_LINES       5
@@ -21,41 +22,118 @@ extern int gpio_to_irq(unsigned gpio);
 
 static inline int gpio_get_value(unsigned gpio)
 {
-       return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
+                                          1 << gpio);
+#endif
+       }
+       return -EINVAL;
 }
 
 static inline void gpio_set_value(unsigned gpio, int value)
 {
-       ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
+                            value ? 1 << gpio : 0);
+               return;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                    value ? 1 << gpio : 0);
+               return;
+#endif
+       }
 }
 
 static inline int gpio_direction_input(unsigned gpio)
 {
-       ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
-       return 0;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
+               return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                      0);
+               return 0;
+#endif
+       }
+       return -EINVAL;
 }
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-       /* first set the gpio out value */
-       ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
-       /* then set the gpio mode */
-       ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
-       return 0;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               /* first set the gpio out value */
+               ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
+                            value ? 1 << gpio : 0);
+               /* then set the gpio mode */
+               ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
+               return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               /* first set the gpio out value */
+               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                    value ? 1 << gpio : 0);
+               /* then set the gpio mode */
+               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                      1 << gpio);
+               return 0;
+#endif
+       }
+       return -EINVAL;
 }
 
 static inline int gpio_intmask(unsigned gpio, int value)
 {
-       ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
-                        value ? 1 << gpio : 0);
-       return 0;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
+                                value ? 1 << gpio : 0);
+               return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
+                                        1 << gpio, value ? 1 << gpio : 0);
+               return 0;
+#endif
+       }
+       return -EINVAL;
 }
 
 static inline int gpio_polarity(unsigned gpio, int value)
 {
-       ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
-                         value ? 1 << gpio : 0);
-       return 0;
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
+                                 value ? 1 << gpio : 0);
+               return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
+                                         1 << gpio, value ? 1 << gpio : 0);
+               return 0;
+#endif
+       }
+       return -EINVAL;
 }
 
 
index 0d5a42b5f47abb4091d3257270b72f80ed1fe3ce..a58addb98cfd7f9b3d94d1f5bd165675f2ea3232 100644 (file)
@@ -54,7 +54,6 @@
 #define cpu_has_mips_r2_exec_hazard 0
 #define cpu_has_dsp            0
 #define cpu_has_mipsmt         0
-#define cpu_has_userlocal      0
 #define cpu_has_vint           0
 #define cpu_has_veic           0
 #define cpu_hwrena_impl_bits   0xc0000000
index 146d41b67adc301462407abbc80dce0c11475d99..e93943fabeac7ba4877b2f79a8c7ab262f674dc0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MIPS_PROM_H
-#define __ASM_MIPS_PROM_H
+#ifndef __ASM_MIPSPROM_H
+#define __ASM_MIPSPROM_H
 
 #define PROM_RESET             0
 #define PROM_EXEC              1
@@ -73,4 +73,4 @@
 
 extern char *prom_getenv(char *);
 
-#endif /* __ASM_MIPS_PROM_H */
+#endif /* __ASM_MIPSPROM_H */
index 857d9b7858ad6265a6406d355c71eb68e7a45a3e..7a6e82ef449b3bf4e8747974dd3ed81c2a231401 100644 (file)
@@ -8,8 +8,8 @@
  * published by the Free Software Foundation.
  *
  */
-#ifndef __ASM_MIPS_PROM_H
-#define __ASM_MIPS_PROM_H
+#ifndef __ASM_PROM_H
+#define __ASM_PROM_H
 
 #ifdef CONFIG_OF
 #include <asm/bootinfo.h>
@@ -25,4 +25,4 @@ extern void device_tree_init(void);
 static inline void device_tree_init(void) { }
 #endif /* CONFIG_OF */
 
-#endif /* _ASM_MIPS_PROM_H */
+#endif /* __ASM_PROM_H */
index 97f8bf6639e7b6f15620e552e05fe7cd1f26d7f7..0d85d8e440c555b584fa51b1082e603e1b542b4e 100644 (file)
@@ -117,7 +117,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
-#define TIF_FREEZE             19
 #define TIF_FIXADE             20      /* Fix address errors in software */
 #define TIF_LOGADE             21      /* Log address errors to syslog */
 #define TIF_32BIT_REGS         22      /* also implies 16/32 fprs */
@@ -141,7 +140,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 #define _TIF_FIXADE            (1<<TIF_FIXADE)
 #define _TIF_LOGADE            (1<<TIF_LOGADE)
 #define _TIF_32BIT_REGS                (1<<TIF_32BIT_REGS)
index feb8021a305f49a4e6f366183e27626316398ed3..6a2d758dd8e9ed0b4a0afb043d2972869620834c 100644 (file)
 
 #include <asm-generic/sections.h>
 
+#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
+#define MCOUNT_OFFSET_INSNS 5
+#else
+#define MCOUNT_OFFSET_INSNS 4
+#endif
+
+/*
+ * Check if the address is in kernel space
+ *
+ * Clone core_kernel_text() from kernel/extable.c, but doesn't call
+ * init_kernel_text() for Ftrace doesn't trace functions in init sections.
+ */
+static inline int in_kernel_space(unsigned long ip)
+{
+       if (ip >= (unsigned long)_stext &&
+           ip <= (unsigned long)_etext)
+               return 1;
+       return 0;
+}
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 #define JAL 0x0c000000         /* jump & link: ip --> ra, jump to target */
@@ -54,20 +74,6 @@ static inline void ftrace_dyn_arch_init_insns(void)
 #endif
 }
 
-/*
- * Check if the address is in kernel space
- *
- * Clone core_kernel_text() from kernel/extable.c, but doesn't call
- * init_kernel_text() for Ftrace doesn't trace functions in init sections.
- */
-static inline int in_kernel_space(unsigned long ip)
-{
-       if (ip >= (unsigned long)_stext &&
-           ip <= (unsigned long)_etext)
-               return 1;
-       return 0;
-}
-
 static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
 {
        int faulted;
@@ -112,11 +118,6 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
  *                                  1: offset = 4 instructions
  */
 
-#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
-#define MCOUNT_OFFSET_INSNS 5
-#else
-#define MCOUNT_OFFSET_INSNS 4
-#endif
 #define INSN_B_1F (0x10000000 | MCOUNT_OFFSET_INSNS)
 
 int ftrace_make_nop(struct module *mod,
index e521420a45a54896f16c6caa0e73ebd39718fd4b..805f897097d09fba09bdda2deeccf8419c87a2d9 100644 (file)
@@ -496,7 +496,7 @@ einval:     li      v0, -ENOSYS
        sys     sys_lookup_dcookie      4
        sys     sys_epoll_create        1
        sys     sys_epoll_ctl           4
-       sys     sys_epoll_wait          3       /* 4250 */
+       sys     sys_epoll_wait          4       /* 4250 */
        sys     sys_remap_file_pages    5
        sys     sys_set_tid_address     1
        sys     sys_restart_syscall     0
index dbbe0ce48d89a4957a349febda33d0934c97d9af..f8524003676ac99f06d0ebb297206dfab415edce 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/cache.h>
+#include <linux/irqflags.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/personality.h>
@@ -658,6 +659,8 @@ static void do_signal(struct pt_regs *regs)
 asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
        __u32 thread_info_flags)
 {
+       local_irq_enable();
+
        /* deal with pending signal delivery */
        if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
                do_signal(regs);
index b7517e3abc8527721fdffca5ded64a035d33fddb..01eff7e609e898e943857a75a9823ca79f4bdb7f 100644 (file)
@@ -364,7 +364,7 @@ static int regs_to_trapnr(struct pt_regs *regs)
        return (regs->cp0_cause >> 2) & 0x1f;
 }
 
-static DEFINE_SPINLOCK(die_lock);
+static DEFINE_RAW_SPINLOCK(die_lock);
 
 void __noreturn die(const char *str, struct pt_regs *regs)
 {
@@ -378,7 +378,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
                sig = 0;
 
        console_verbose();
-       spin_lock_irq(&die_lock);
+       raw_spin_lock_irq(&die_lock);
        bust_spinlocks(1);
 #ifdef CONFIG_MIPS_MT_SMTC
        mips_mt_regdump(dvpret);
@@ -387,7 +387,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
        printk("%s[#%d]:\n", str, ++die_counter);
        show_registers(regs);
        add_taint(TAINT_DIE);
-       spin_unlock_irq(&die_lock);
+       raw_spin_unlock_irq(&die_lock);
 
        if (in_interrupt())
                panic("Fatal exception in interrupt");
index fc89795cafdb6ad1fecb5274b76f74bc8fd85121..f9737bb3c5ab7442b055a6d0d7aa0e7529b37b6d 100644 (file)
@@ -123,11 +123,10 @@ void ltq_enable_irq(struct irq_data *d)
 static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
 {
        int i;
-       int irq_nr = d->irq - INT_NUM_IRQ0;
 
        ltq_enable_irq(d);
        for (i = 0; i < MAX_EIU; i++) {
-               if (irq_nr == ltq_eiu_irq[i]) {
+               if (d->irq == ltq_eiu_irq[i]) {
                        /* low level - we should really handle set_type */
                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
                                (0x6 << (i * 4)), LTQ_EIU_EXIN_C);
@@ -147,11 +146,10 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
 static void ltq_shutdown_eiu_irq(struct irq_data *d)
 {
        int i;
-       int irq_nr = d->irq - INT_NUM_IRQ0;
 
        ltq_disable_irq(d);
        for (i = 0; i < MAX_EIU; i++) {
-               if (irq_nr == ltq_eiu_irq[i]) {
+               if (d->irq == ltq_eiu_irq[i]) {
                        /* disable */
                        ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
                                LTQ_EIU_EXIN_INEN);
index de4c165515d780571712c81e9e641c9a31728c8c..d608b6ef0edd7712aa9d34c5668d2590a8e3a962 100644 (file)
@@ -105,6 +105,7 @@ asmlinkage void plat_irq_dispatch(void)
 static struct irqaction cascade = {
        .handler        = no_action,
        .name           = "cascade",
+       .flags          = IRQF_NO_THREAD,
 };
 
 void __init arch_init_irq(void)
index d61a04222b87217563543b8fb1ead4241c3ff859..3cf1fef29f0e76cbdff9828b896b21d5c6b568d4 100644 (file)
@@ -42,6 +42,7 @@ asmlinkage void mach_irq_dispatch(unsigned int pending)
 static struct irqaction cascade_irqaction = {
        .handler = no_action,
        .name = "cascade",
+       .flags = IRQF_NO_THREAD,
 };
 
 void __init mach_init_irq(void)
index 081db102bb9835d7c15dd4f71db536e5783c40b8..14b081841b6b0d7ed2117917dc2306cfbf46ce0d 100644 (file)
@@ -96,12 +96,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id)
 struct irqaction ip6_irqaction = {
        .handler = ip6_action,
        .name = "cascade",
-       .flags = IRQF_SHARED,
+       .flags = IRQF_SHARED | IRQF_NO_THREAD,
 };
 
 struct irqaction cascade_irqaction = {
        .handler = no_action,
        .name = "cascade",
+       .flags = IRQF_NO_THREAD,
 };
 
 void __init mach_init_irq(void)
index 16c4d256b76f3f7179e5a77b856bd3a7a3825a52..daa81f7284ac89a5411b88d86f77ff6df1585f55 100644 (file)
@@ -169,6 +169,10 @@ static void octeon_flush_cache_page(struct vm_area_struct *vma,
                octeon_flush_icache_all_cores(vma);
 }
 
+static void octeon_flush_kernel_vmap_range(unsigned long vaddr, int size)
+{
+       BUG();
+}
 
 /**
  * Probe Octeon's caches
@@ -273,6 +277,8 @@ void __cpuinit octeon_cache_init(void)
        flush_icache_range              = octeon_flush_icache_range;
        local_flush_icache_range        = local_octeon_flush_icache_range;
 
+       __flush_kernel_vmap_range       = octeon_flush_kernel_vmap_range;
+
        build_clear_page();
        build_copy_page();
 }
index e6b0efd3f6a4ed0746141c0ecdad4a9b22c71d76..0765583d0c924f6252ccb313052c46be2d81315e 100644 (file)
@@ -299,6 +299,11 @@ static void r3k_flush_cache_sigtramp(unsigned long addr)
        write_c0_status(flags);
 }
 
+static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size)
+{
+       BUG();
+}
+
 static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
        /* Catch bad driver code */
@@ -323,6 +328,8 @@ void __cpuinit r3k_cache_init(void)
        flush_icache_range = r3k_flush_icache_range;
        local_flush_icache_range = r3k_flush_icache_range;
 
+       __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range;
+
        flush_cache_sigtramp = r3k_flush_cache_sigtramp;
        local_flush_data_cache_page = local_r3k_flush_data_cache_page;
        flush_data_cache_page = r3k_flush_data_cache_page;
index b9aabb998a32ab5856fb53e910785063eea78613..a79fe9aa7721aa56f05d8ab7995b6503cd98f618 100644 (file)
@@ -722,6 +722,39 @@ static void r4k_flush_icache_all(void)
                r4k_blast_icache();
 }
 
+struct flush_kernel_vmap_range_args {
+       unsigned long   vaddr;
+       int             size;
+};
+
+static inline void local_r4k_flush_kernel_vmap_range(void *args)
+{
+       struct flush_kernel_vmap_range_args *vmra = args;
+       unsigned long vaddr = vmra->vaddr;
+       int size = vmra->size;
+
+       /*
+        * Aliases only affect the primary caches so don't bother with
+        * S-caches or T-caches.
+        */
+       if (cpu_has_safe_index_cacheops && size >= dcache_size)
+               r4k_blast_dcache();
+       else {
+               R4600_HIT_CACHEOP_WAR_IMPL;
+               blast_dcache_range(vaddr, vaddr + size);
+       }
+}
+
+static void r4k_flush_kernel_vmap_range(unsigned long vaddr, int size)
+{
+       struct flush_kernel_vmap_range_args args;
+
+       args.vaddr = (unsigned long) vaddr;
+       args.size = size;
+
+       r4k_on_each_cpu(local_r4k_flush_kernel_vmap_range, &args);
+}
+
 static inline void rm7k_erratum31(void)
 {
        const unsigned long ic_lsize = 32;
@@ -1403,6 +1436,8 @@ void __cpuinit r4k_cache_init(void)
        flush_cache_page        = r4k_flush_cache_page;
        flush_cache_range       = r4k_flush_cache_range;
 
+       __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range;
+
        flush_cache_sigtramp    = r4k_flush_cache_sigtramp;
        flush_icache_all        = r4k_flush_icache_all;
        local_flush_data_cache_page     = local_r4k_flush_data_cache_page;
index d352fad3e45101b03191fcdd994adfdb6444f9de..a43c197ccf8c48bd02f27281cba92df44221137b 100644 (file)
@@ -253,6 +253,11 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end)
        }
 }
 
+static void tx39_flush_kernel_vmap_range(unsigned long vaddr, int size)
+{
+       BUG();
+}
+
 static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
        unsigned long end;
@@ -394,6 +399,8 @@ void __cpuinit tx39_cache_init(void)
                flush_icache_range = tx39_flush_icache_range;
                local_flush_icache_range = tx39_flush_icache_range;
 
+               __flush_kernel_vmap_range = tx39_flush_kernel_vmap_range;
+
                flush_cache_sigtramp = tx39_flush_cache_sigtramp;
                local_flush_data_cache_page = local_tx39_flush_data_cache_page;
                flush_data_cache_page = tx39_flush_data_cache_page;
index 12af739048fada0927f50e414f30097b8bbb96d6..829320c7b175372f3695248aee63329f18f7661f 100644 (file)
@@ -35,6 +35,11 @@ void (*local_flush_icache_range)(unsigned long start, unsigned long end);
 void (*__flush_cache_vmap)(void);
 void (*__flush_cache_vunmap)(void);
 
+void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
+void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
+
+EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
+
 /* MIPS specific cache operations */
 void (*flush_cache_sigtramp)(unsigned long addr);
 void (*local_flush_data_cache_page)(void * addr);
index b6e1cff5066704de206ed92febcb6e8bb7da49b3..46f33c7c1a098b2ad54c9c68d7a997374ae32d71 100644 (file)
@@ -1759,14 +1759,13 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
        u32 *p = handle_tlbm;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
-       struct work_registers wr;
 
        memset(handle_tlbm, 0, sizeof(handle_tlbm));
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
        build_r3000_tlbchange_handler_head(&p, K0, K1);
-       build_pte_modifiable(&p, &r, wr.r1, wr.r2,  wr.r3, label_nopage_tlbm);
+       build_pte_modifiable(&p, &r, K0, K1,  -1, label_nopage_tlbm);
        uasm_i_nop(&p); /* load delay */
        build_make_write(&p, &r, K0, K1);
        build_r3000_pte_reload_tlbwi(&p, K0, K1);
index 1d36c511a7a5951c227800f917dd815449baf064..d53ff91b277c8f358a96058ddffada9901345ba1 100644 (file)
@@ -350,12 +350,14 @@ unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
 
 static struct irqaction i8259irq = {
        .handler = no_action,
-       .name = "XT-PIC cascade"
+       .name = "XT-PIC cascade",
+       .flags = IRQF_NO_THREAD,
 };
 
 static struct irqaction corehi_irqaction = {
        .handler = no_action,
-       .name = "CoreHi"
+       .name = "CoreHi",
+       .flags = IRQF_NO_THREAD,
 };
 
 static msc_irqmap_t __initdata msc_irqmap[] = {
index f87c1640abb5cd13894c8c2d953c3b4b6e73b218..b648b487fd6674b2cdcedb1420e1d5759decba92 100644 (file)
@@ -4,6 +4,11 @@
 cflags-$(CONFIG_NLM_COMMON)  += -I$(srctree)/arch/mips/include/asm/mach-netlogic
 cflags-$(CONFIG_NLM_COMMON)  += -I$(srctree)/arch/mips/include/asm/netlogic
 
+#
+# use mips64 if xlr is not available
+#
+cflags-$(CONFIG_NLM_XLR)       += $(call cc-option,-march=xlr,-march=mips64)
+
 #
 # NETLOGIC XLR/XLS SoC, Simulator and boards
 #
index 482802569e74919298d35c829327c0ee7d5b0350..cee25ddd0887470ebe167b5e0cb6a91d2e5d3a1e 100644 (file)
@@ -53,7 +53,7 @@ unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE);
 unsigned long nlm_common_ebase = 0x0;
 struct psb_info nlm_prom_info;
 
-static void nlm_early_serial_setup(void)
+static void __init nlm_early_serial_setup(void)
 {
        struct uart_port s;
        nlm_reg_t *uart_base;
@@ -101,7 +101,7 @@ void __init prom_free_prom_memory(void)
        /* Nothing yet */
 }
 
-static void build_arcs_cmdline(int *argv)
+static void __init build_arcs_cmdline(int *argv)
 {
        int i, remain, len;
        char *arg;
index d842bce5c9405a2f267bb7f3de5cfda97f8e835e..e2372121307cd4698f5e7ca1811ee37c1b2470b5 100644 (file)
@@ -191,7 +191,7 @@ struct plat_smp_ops nlm_smp_ops = {
 
 unsigned long secondary_entry_point;
 
-int nlm_wakeup_secondary_cpus(u32 wakeup_mask)
+int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
 {
        unsigned int tid, pid, ipi, i, boot_cpu;
        void *reset_vec;
index b8e074402c990916aebc933568e3f80b633cf52e..8cb7889ce0cca112bef5b2d9ea06ece68aae0689 100644 (file)
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/init.h>
+
 #include <asm/asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 
-
-/* Don't jump to linux function from Bootloader stack. Change it
- * here. Kernel might allocate bootloader memory before all the CPUs are
- * brought up (eg: Inode cache region) and we better don't overwrite this
- * memory
+/*
+ * Early code for secondary CPUs. This will get them out of the bootloader
+ * code and into linux. Needed because the bootloader area will be taken
+ * and initialized by linux.
  */
+       __CPUINIT
 NESTED(prom_pre_boot_secondary_cpus, 16, sp)
        .set    mips64
        mfc0    t0, $15, 1      # read ebase
@@ -73,7 +75,11 @@ NESTED(prom_pre_boot_secondary_cpus, 16, sp)
        jr      t0
        nop
 END(prom_pre_boot_secondary_cpus)
+       __FINIT
 
+/*
+ * NMI code, used for CPU wakeup, copied to reset entry
+ */
 NESTED(nlm_boot_smp_nmi, 0, sp)
        .set push
        .set noat
diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c
deleted file mode 100644 (file)
index 98e86dd..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *
- * Author: source@mvista.com
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <pci.h>
-#include <glb.h>
-#include <nand.h>
-
-static struct resource pci_io_resource = {
-       .start  = PNX8550_PCIIO + 0x1000,       /* reserve regacy I/O space */
-       .end    = PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
-       .name   = "pci IO space",
-       .flags  = IORESOURCE_IO
-};
-
-static struct resource pci_mem_resource = {
-       .start  = PNX8550_PCIMEM,
-       .end    = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
-       .name   = "pci memory space",
-       .flags  = IORESOURCE_MEM
-};
-
-extern struct pci_ops pnx8550_pci_ops;
-
-static struct pci_controller pnx8550_controller = {
-       .pci_ops        = &pnx8550_pci_ops,
-       .io_map_base    = PNX8550_PORT_BASE,
-       .io_resource    = &pci_io_resource,
-       .mem_resource   = &pci_mem_resource,
-};
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-static inline unsigned long get_system_mem_size(void)
-{
-       /* Read IP2031_RANK0_ADDR_LO */
-       unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
-       /* Read IP2031_RANK1_ADDR_HI */
-       unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
-       return dram_r1_hi - dram_r0_lo + 1;
-}
-
-static int __init pnx8550_pci_setup(void)
-{
-       int pci_mem_code;
-       int mem_size = get_system_mem_size() >> 20;
-
-       /* Clear the Global 2 Register, PCI Inta Output Enable Registers
-          Bit 1:Enable DAC Powerdown
-         -> 0:DACs are enabled and are working normally
-            1:DACs are powerdown
-          Bit 0:Enable of PCI inta output
-         -> 0 = Disable PCI inta output
-            1 = Enable PCI inta output
-       */
-       PNX8550_GLB2_ENAB_INTA_O = 0;
-
-       /* Calc the PCI mem size code */
-       if (mem_size >= 128)
-               pci_mem_code = SIZE_128M;
-       else if (mem_size >= 64)
-               pci_mem_code = SIZE_64M;
-       else if (mem_size >= 32)
-               pci_mem_code = SIZE_32M;
-       else
-               pci_mem_code = SIZE_16M;
-
-       /* Set PCI_XIO registers */
-       outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
-       outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
-       outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
-       outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
-
-       /* Send memory transaction via PCI_BASE2 */
-       outl(0x00000001, PCI_BASE | PCI_IO);
-
-       /* Unlock the setup register */
-       outl(0xca, PCI_BASE | PCI_UNLOCKREG);
-
-       /*
-        * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
-        * to work, and in order for bus_to_baddr to work without any
-        * hacks.
-        */
-       outl(0x00000000, PCI_BASE | PCI_BASE10);
-
-       /*
-        *These two bars are set by default or the boot code.
-        * However, it's safer to set them here so we're not boot
-        * code dependent.
-        */
-       outl(0x1be00000, PCI_BASE | PCI_BASE14);  /* PNX MMIO */
-       outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18);  /* XIO      */
-
-       outl(PCI_EN_TA |
-            PCI_EN_PCI2MMI |
-            PCI_EN_XIO |
-            PCI_SETUP_BASE18_SIZE(SIZE_32M) |
-            PCI_SETUP_BASE18_EN |
-            PCI_SETUP_BASE14_EN |
-            PCI_SETUP_BASE10_PREF |
-            PCI_SETUP_BASE10_SIZE(pci_mem_code) |
-            PCI_SETUP_CFGMANAGE_EN |
-            PCI_SETUP_PCIARB_EN,
-            PCI_BASE |
-            PCI_SETUP);        /* PCI_SETUP */
-       outl(0x00000000, PCI_BASE | PCI_CTRL);  /* PCI_CONTROL */
-
-       register_pci_controller(&pnx8550_controller);
-
-       return 0;
-}
-
-arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c
deleted file mode 100644 (file)
index 71adac3..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *
- * 2.6 port, Embedded Alley Solutions, Inc
- *
- *  Based on Per Hallsmark, per.hallsmark@mvista.com
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/serial_pnx8xxx.h>
-#include <linux/pm.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/reboot.h>
-#include <asm/pgtable.h>
-#include <asm/time.h>
-
-#include <glb.h>
-#include <int.h>
-#include <pci.h>
-#include <uart.h>
-#include <nand.h>
-
-extern void __init board_setup(void);
-extern void pnx8550_machine_restart(char *);
-extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
-extern struct resource ioport_resource;
-extern struct resource iomem_resource;
-extern char *prom_getcmdline(void);
-
-struct resource standard_io_resources[] = {
-       {
-               .start  = 0x00,
-               .end    = 0x1f,
-               .name   = "dma1",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0x40,
-               .end    = 0x5f,
-               .name   = "timer",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0x80,
-               .end    = 0x8f,
-               .name   = "dma page reg",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0xc0,
-               .end    = 0xdf,
-               .name   = "dma2",
-               .flags  = IORESOURCE_BUSY
-       },
-};
-
-#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
-
-extern struct resource pci_io_resource;
-extern struct resource pci_mem_resource;
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-unsigned long get_system_mem_size(void)
-{
-       /* Read IP2031_RANK0_ADDR_LO */
-       unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
-       /* Read IP2031_RANK1_ADDR_HI */
-       unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
-       return dram_r1_hi - dram_r0_lo + 1;
-}
-
-int pnx8550_console_port = -1;
-
-void __init plat_mem_setup(void)
-{
-       int i;
-       char* argptr;
-
-       board_setup();  /* board specific setup */
-
-        _machine_restart = pnx8550_machine_restart;
-        _machine_halt = pnx8550_machine_halt;
-        pm_power_off = pnx8550_machine_power_off;
-
-       /* Clear the Global 2 Register, PCI Inta Output Enable Registers
-          Bit 1:Enable DAC Powerdown
-         -> 0:DACs are enabled and are working normally
-            1:DACs are powerdown
-          Bit 0:Enable of PCI inta output
-         -> 0 = Disable PCI inta output
-            1 = Enable PCI inta output
-       */
-       PNX8550_GLB2_ENAB_INTA_O = 0;
-
-       /* IO/MEM resources. */
-       set_io_port_base(PNX8550_PORT_BASE);
-       ioport_resource.start = 0;
-       ioport_resource.end = ~0;
-       iomem_resource.start = 0;
-       iomem_resource.end = ~0;
-
-       /* Request I/O space for devices on this board */
-       for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-               request_resource(&ioport_resource, standard_io_resources + i);
-
-       /* Place the Mode Control bit for GPIO pin 16 in primary function */
-       /* Pin 16 is used by UART1, UA1_TX                                */
-       outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
-                       (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
-                       PNX8550_GPIO_MC1);
-
-       argptr = prom_getcmdline();
-       if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
-               argptr += strlen("console=ttyS");
-               pnx8550_console_port = *argptr == '0' ? 0 : 1;
-
-               /* We must initialize the UART (console) before early printk */
-               /* Set LCR to 8-bit and BAUD to 38400 (no 5)                */
-               ip3106_lcr(UART_BASE, pnx8550_console_port) =
-                       PNX8XXX_UART_LCR_8BIT;
-               ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
-       }
-}
index 455f8e50a0070b6be32c0e2c0cde56af487aafac..400535a955d02daea0b4c96a836b5f2ac6cc8854 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/ssb/ssb.h>
+#include <bcm47xx.h>
 
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
@@ -33,9 +34,13 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 
 int pcibios_plat_dev_init(struct pci_dev *dev)
 {
+#ifdef CONFIG_BCM47XX_SSB
        int res;
        u8 slot, pin;
 
+       if (bcm47xx_bus_type !=  BCM47XX_BUS_TYPE_SSB)
+               return 0;
+
        res = ssb_pcibios_plat_dev_init(dev);
        if (res < 0) {
                printk(KERN_ALERT "PCI: Failed to init device %s\n",
@@ -55,5 +60,6 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
        }
 
        dev->irq = res;
+#endif
        return 0;
 }
index 603d7493e9660308cd63e0343c41911a932b5b9c..8656388b34bd4fac95d7dadf6584d9fe6cdbceb6 100644 (file)
@@ -171,8 +171,13 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
        u32 temp_buffer;
 
        /* set clock to 33Mhz */
-       ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
-       ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
+       if (ltq_is_ar9()) {
+               ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR);
+               ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR);
+       } else {
+               ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
+               ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
+       }
 
        /* external or internal clock ? */
        if (conf->clock) {
index 764362ce5e404119b375f327d0c01111ee559383..5f3a69cebad1d51554052bec403279972d5023ee 100644 (file)
@@ -215,7 +215,7 @@ static int __init rc32434_pci_init(void)
        rc32434_pcibridge_init();
 
        io_map_base = ioremap(rc32434_res_pci_io1.start,
-                             resource_size(&rcrc32434_res_pci_io1));
+                             resource_size(&rc32434_res_pci_io1));
 
        if (!io_map_base)
                return -ENOMEM;
index 4531c4a514bc499b2dedfbe9bf497149a39947df..d3c3d81757a538ea13ee3ab56942d1aeea00df3c 100644 (file)
@@ -108,12 +108,14 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 
 static struct irqaction cic_cascade_msp = {
        .handler = no_action,
-       .name    = "MSP CIC cascade"
+       .name    = "MSP CIC cascade",
+       .flags   = IRQF_NO_THREAD,
 };
 
 static struct irqaction per_cascade_msp = {
        .handler = no_action,
-       .name    = "MSP PER cascade"
+       .name    = "MSP PER cascade",
+       .flags   = IRQF_NO_THREAD,
 };
 
 void __init arch_init_irq(void)
index 0abfbe04ffc9795213e4109b51c8bdffae252d9d..655308a4e1cda2c02c6d63f9202531cc7ffaabd8 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/cacheflush.h>
 #include <asm/r4kcache.h>
 #include <asm/reboot.h>
+#include <asm/smp-ops.h>
 #include <asm/time.h>
 
 #include <msp_prom.h>
index 434d7b1a8c6a7abf4c492a14b975111a21b1a4ab..b7f1d9c4a8a3c7d588b270d6bd6e1bad0590f6b2 100644 (file)
@@ -65,15 +65,11 @@ static unsigned char readb_outer_space(unsigned long long phys)
 
        __asm__ __volatile__ (
        "       .set    mips3           \n"
-       "       .set    push            \n"
-       "       .set    noreorder       \n"
-       "       .set    nomacro         \n"
        "       ld      %0, %1          \n"
-       "       .set    pop             \n"
        "       lbu     %0, (%0)        \n"
        "       .set    mips0           \n"
        : "=r" (res)
-       : "R" (vaddr));
+       : "m" (vaddr));
 
        write_c0_status(sr);
        ssnop_4();
@@ -93,15 +89,11 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
 
        __asm__ __volatile__ (
        "       .set    mips3           \n"
-       "       .set    push            \n"
-       "       .set    noreorder       \n"
-       "       .set    nomacro         \n"
        "       ld      %0, %1          \n"
-       "       .set    pop             \n"
        "       sb      %2, (%0)        \n"
        "       .set    mips0           \n"
        : "=&r" (tmp)
-       : "R" (vaddr), "r" (c));
+       : "m" (vaddr), "r" (c));
 
        write_c0_status(sr);
        ssnop_4();
index 6b93c81779c1a6166ca0a5ead00f81b1632badd4..1ebe22bdadc87668c35587687434af376876bafc 100644 (file)
@@ -167,7 +167,7 @@ static struct irq_chip level_irq_type = {
 
 static struct irqaction gic_action = {
        .handler =      no_action,
-       .flags =        IRQF_DISABLED,
+       .flags =        IRQF_DISABLED | IRQF_NO_THREAD,
        .name =         "GIC",
 };
 
index 32f70097c3c746e1584537e7fb8c451a5f80346c..49639e8120d86d527cca879cb553e2e063426ae3 100644 (file)
@@ -30,7 +30,7 @@ typedef struct
 }t_env_var;
 
 
-char * prom_getcmdline(void)
+char * __init prom_getcmdline(void)
 {
        return &(arcs_cmdline[0]);
 }
index b4d08e4d2ea949b6818f8bac47d2f7576d516918..f72c336ea27b3b059ca4c6a169e3b1cefce23d47 100644 (file)
@@ -155,32 +155,32 @@ static void __irq_entry indy_buserror_irq(void)
 
 static struct irqaction local0_cascade = {
        .handler        = no_action,
-       .flags          = IRQF_DISABLED,
+       .flags          = IRQF_DISABLED | IRQF_NO_THREAD,
        .name           = "local0 cascade",
 };
 
 static struct irqaction local1_cascade = {
        .handler        = no_action,
-       .flags          = IRQF_DISABLED,
+       .flags          = IRQF_DISABLED | IRQF_NO_THREAD,
        .name           = "local1 cascade",
 };
 
 static struct irqaction buserr = {
        .handler        = no_action,
-       .flags          = IRQF_DISABLED,
+       .flags          = IRQF_DISABLED | IRQF_NO_THREAD,
        .name           = "Bus Error",
 };
 
 static struct irqaction map0_cascade = {
        .handler        = no_action,
-       .flags          = IRQF_DISABLED,
+       .flags          = IRQF_DISABLED | IRQF_NO_THREAD,
        .name           = "mapable0 cascade",
 };
 
 #ifdef USE_LIO3_IRQ
 static struct irqaction map1_cascade = {
        .handler        = no_action,
-       .flags          = IRQF_DISABLED,
+       .flags          = IRQF_DISABLED | IRQF_NO_THREAD,
        .name           = "mapable1 cascade",
 };
 #define SGI_INTERRUPTS SGINT_END
index b18b04e48577550f6b42c43d393d06c91741285b..f90dce315e0477b960cd68e01002794612bbb101 100644 (file)
@@ -337,12 +337,12 @@ static struct irq_chip bridge_irq_type = {
        .irq_unmask     = enable_bridge_irq,
 };
 
-void __devinit register_bridge_irq(unsigned int irq)
+void register_bridge_irq(unsigned int irq)
 {
        irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
 }
 
-int __devinit request_bridge_irq(struct bridge_controller *bc)
+int request_bridge_irq(struct bridge_controller *bc)
 {
        int irq = allocate_irqno();
        int swlevel, cpu;
index a7e5a6d917b1572c283903729f7f495f3fb334f0..3ab5b5d25b0acca9aeeb2c3306a38af4b8637d89 100644 (file)
@@ -359,6 +359,7 @@ void sni_rm200_init_8259A(void)
 static struct irqaction sni_rm200_irq2 = {
        .handler = no_action,
        .name = "cascade",
+       .flags = IRQF_NO_THREAD,
 };
 
 static struct resource sni_rm200_pic1_resource = {
index 70a3b85f37576dcc8ac6ad8f68155c79c5ae747b..fad2bef432cdd94ad509fe2d6b45d74ee36d3661 100644 (file)
@@ -34,6 +34,7 @@ static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned;
 static struct irqaction cascade_irqaction = {
        .handler        = no_action,
        .name           = "cascade",
+       .flags          = IRQF_NO_THREAD,
 };
 
 int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int))
index 87c213002d4c9b30834b88aff215262160193541..28cf52100baaa0e0cd581cbda0969b00a51b4c4f 100644 (file)
@@ -165,7 +165,6 @@ extern void free_thread_info(struct thread_info *);
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* is terminating due to OOM killer */
-#define TIF_FREEZE             18      /* freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     +(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     +(1 << TIF_NOTIFY_RESUME)
@@ -174,7 +173,6 @@ extern void free_thread_info(struct thread_info *);
 #define _TIF_SINGLESTEP                +(1 << TIF_SINGLESTEP)
 #define _TIF_RESTORE_SIGMASK   +(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    +(1 << TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            +(1 << TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index 54a5c50132e35e4000e45f874c6c1618894b9f9f..b79c2b19afbe6cfe9f4327535e257e12c9aaa29f 100644 (file)
 
 /* This struct is saved by setup_frame in signal.c, to keep the current
    context while a signal handler is executed. It's restored by sys_sigreturn.
-
-   To keep things simple, we use pt_regs here even though normally you just
-   specify the list of regs to save. Then we can use copy_from_user on the
-   entire regs instead of a bunch of get_user's as well...
 */
 
 struct sigcontext {
-       struct pt_regs regs;  /* needs to be first */
+       struct user_regs_struct regs;  /* needs to be first */
        unsigned long oldmask;
-       unsigned long usp;    /* usp before stacking this gunk on it */
 };
 
 #endif /* __ASM_OPENRISC_SIGCONTEXT_H */
index 5f759c76834eee10dd821edc8a0b560d6d3931df..fc3eb88d567bde0b6c19a037cdcb17fa5ccc1bf5 100644 (file)
@@ -52,7 +52,6 @@ struct rt_sigframe {
 static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
        unsigned int err = 0;
-       unsigned long old_usp;
 
        /* Alwys make any pending restarted system call return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -61,22 +60,14 @@ static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
         * (sc is already checked for VERIFY_READ since the sigframe was
         *  checked in sys_sigreturn previously)
         */
-
-       if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
+       if (__copy_from_user(regs, sc->regs.gpr, 33*sizeof(unsigned long)))
+               goto badframe;
+       if (__copy_from_user(&regs->sr, &sc->regs.sr, sizeof(unsigned long)))
                goto badframe;
 
        /* make sure the SM-bit is cleared so user-mode cannot fool us */
        regs->sr &= ~SPR_SR_SM;
 
-       /* restore the old USP as it was before we stacked the sc etc.
-        * (we cannot just pop the sigcontext since we aligned the sp and
-        *  stuff after pushing it)
-        */
-
-       err |= __get_user(old_usp, &sc->usp);
-
-       regs->sp = old_usp;
-
        /* TODO: the other ports use regs->orig_XX to disable syscall checks
         * after this completes, but we don't use that mechanism. maybe we can
         * use it now ?
@@ -137,18 +128,16 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
                            unsigned long mask)
 {
        int err = 0;
-       unsigned long usp = regs->sp;
 
        /* copy the regs. they are first in sc so we can use sc directly */
 
-       err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
+       err |= __copy_to_user(sc->regs.gpr, regs, 33*sizeof(unsigned long));
+       err |= __copy_to_user(&sc->regs.sr, &regs->sr, sizeof(unsigned long));
 
        /* then some other stuff */
 
        err |= __put_user(mask, &sc->oldmask);
 
-       err |= __put_user(usp, &sc->usp);
-
        return err;
 }
 
index aa8de727e90ba28f77eb81162e429d328ff5390d..6d9c7c7973d0375d1c7858736c19b855e6cbb37a 100644 (file)
@@ -58,7 +58,6 @@ struct thread_info {
 #define TIF_32BIT               4       /* 32 bit binary */
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    6       /* restore saved signal mask */
-#define TIF_FREEZE             7       /* is freezing for suspend */
 #define TIF_NOTIFY_RESUME      8       /* callback before returning to user */
 #define TIF_SINGLESTEP         9       /* single stepping? */
 #define TIF_BLOCKSTEP          10      /* branch stepping? */
@@ -69,7 +68,6 @@ struct thread_info {
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_32BIT             (1 << TIF_32BIT)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
index 6926b61acfeac74133f6fe2d3d206e06b92162f1..b1a9cfc812ce0068266b0a2bd0769c5fb8fd94d1 100644 (file)
@@ -345,7 +345,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL
+       depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !47x)) && EXPERIMENTAL
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
@@ -656,6 +656,8 @@ config SBUS
 
 config FSL_SOC
        bool
+       select HAVE_CAN_FLEXCAN if NET && CAN
+       select PPC_CLOCK if CAN_FLEXCAN
 
 config FSL_PCI
        bool
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts
new file mode 100644 (file)
index 0000000..0e00e50
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * charon board Device Tree Source
+ *
+ * Copyright (C) 2007 Semihalf
+ * Marian Balakowicz <m8@semihalf.com>
+ *
+ * Copyright (C) 2010 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "anon,charon";
+       compatible = "anon,charon";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&mpc5200_pic>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,5200@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;
+                       i-cache-line-size = <32>;
+                       d-cache-size = <0x4000>;        // L1, 16K
+                       i-cache-size = <0x4000>;        // L1, 16K
+                       timebase-frequency = <0>;       // from bootloader
+                       bus-frequency = <0>;            // from bootloader
+                       clock-frequency = <0>;          // from bootloader
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x08000000>;  // 128MB
+       };
+
+       soc5200@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc5200-immr";
+               ranges = <0 0xf0000000 0x0000c000>;
+               reg = <0xf0000000 0x00000100>;
+               bus-frequency = <0>;            // from bootloader
+               system-frequency = <0>;         // from bootloader
+
+               cdm@200 {
+                       compatible = "fsl,mpc5200-cdm";
+                       reg = <0x200 0x38>;
+               };
+
+               mpc5200_pic: interrupt-controller@500 {
+                       // 5200 interrupts are encoded into two levels;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       compatible = "fsl,mpc5200-pic";
+                       reg = <0x500 0x80>;
+               };
+
+               timer@600 {     // General Purpose Timer
+                       compatible = "fsl,mpc5200-gpt";
+                       reg = <0x600 0x10>;
+                       interrupts = <1 9 0>;
+                       fsl,has-wdt;
+               };
+
+               can@900 {
+                       compatible = "fsl,mpc5200-mscan";
+                       interrupts = <2 17 0>;
+                       reg = <0x900 0x80>;
+               };
+
+               can@980 {
+                       compatible = "fsl,mpc5200-mscan";
+                       interrupts = <2 18 0>;
+                       reg = <0x980 0x80>;
+               };
+
+               gpio_simple: gpio@b00 {
+                       compatible = "fsl,mpc5200-gpio";
+                       reg = <0xb00 0x40>;
+                       interrupts = <1 7 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               usb@1000 {
+                       compatible = "fsl,mpc5200-ohci","ohci-be";
+                       reg = <0x1000 0xff>;
+                       interrupts = <2 6 0>;
+               };
+
+               dma-controller@1200 {
+                       device_type = "dma-controller";
+                       compatible = "fsl,mpc5200-bestcomm";
+                       reg = <0x1200 0x80>;
+                       interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+                                     3 4 0  3 5 0  3 6 0  3 7 0
+                                     3 8 0  3 9 0  3 10 0  3 11 0
+                                     3 12 0  3 13 0  3 14 0  3 15 0>;
+               };
+
+               xlb@1f00 {
+                       compatible = "fsl,mpc5200-xlb";
+                       reg = <0x1f00 0x100>;
+               };
+
+               serial@2000 {           // PSC1
+                       compatible = "fsl,mpc5200-psc-uart";
+                       reg = <0x2000 0x100>;
+                       interrupts = <2 1 0>;
+               };
+
+               serial@2400 {           // PSC3
+                       compatible = "fsl,mpc5200-psc-uart";
+                       reg = <0x2400 0x100>;
+                       interrupts = <2 3 0>;
+               };
+
+               ethernet@3000 {
+                       compatible = "fsl,mpc5200-fec";
+                       reg = <0x3000 0x400>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <2 5 0>;
+                       fixed-link = <1 1 100 0 0>;
+               };
+
+               mdio@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200-mdio";
+                       reg = <0x3000 0x400>;       // fec range, since we need to setup fec interrupts
+                       interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
+               };
+
+               ata@3a00 {
+                       compatible = "fsl,mpc5200-ata";
+                       reg = <0x3a00 0x100>;
+                       interrupts = <2 7 0>;
+               };
+
+               i2c@3d00 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200-i2c","fsl-i2c";
+                       reg = <0x3d00 0x40>;
+                       interrupts = <2 15 0>;
+               };
+
+
+               i2c@3d40 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200-i2c","fsl-i2c";
+                       reg = <0x3d40 0x40>;
+                       interrupts = <2 16 0>;
+
+                       dtt@28 {
+                               compatible = "national,lm80";
+                               reg = <0x28>;
+                       };
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                       };
+               };
+
+               sram@8000 {
+                       compatible = "fsl,mpc5200-sram";
+                       reg = <0x8000 0x4000>;
+               };
+       };
+
+       localbus {
+               compatible = "fsl,mpc5200-lpb","simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <      0 0 0xfc000000 0x02000000
+                               1 0 0xe0000000 0x04000000 // CS1 range, SM501
+                               3 0 0xe8000000 0x00080000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x02000000>;
+                       bank-width = <4>;
+                       device-width = <2>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+               };
+
+               display@1,0 {
+                       compatible = "smi,sm501";
+                       reg = <1 0x00000000 0x00800000
+                              1 0x03e00000 0x00200000>;
+                       mode = "640x480-32@60";
+                       interrupts = <1 1 3>;
+                       little-endian;
+               };
+
+               mram0@3,0 {
+                       compatible = "mtd-ram";
+                       reg = <3 0x00000 0x80000>;
+                       bank-width = <1>;
+               };
+       };
+
+       pci@f0000d00 {
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               device_type = "pci";
+               compatible = "fsl,mpc5200-pci";
+               reg = <0xf0000d00 0x100>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3
+                                0xc000 0 0 2 &mpc5200_pic 0 0 3
+                                0xc000 0 0 3 &mpc5200_pic 0 0 3
+                                0xc000 0 0 4 &mpc5200_pic 0 0 3>;
+               clock-frequency = <0>; // From boot loader
+               interrupts = <2 8 0 2 9 0 2 10 0>;
+               bus-range = <0 0>;
+               ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
+                         0x02000000 0 0x90000000 0x90000000 0 0x10000000
+                         0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
+       };
+};
diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts
deleted file mode 100644 (file)
index 7988598..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-* Device Tree Source for Netstal Maschinen HCU4
-* based on the IBM Walnut
-*
-* Copyright 2008
-* Niklaus Giger <niklaus.giger@member.fsf.org>
-*
-* Copyright 2007 IBM Corp.
-* Josh Boyer <jwboyer@linux.vnet.ibm.com>
-*
-* This file is licensed under the terms of the GNU General Public
-* License version 2.  This program is licensed "as is" without
-* any warranty of any kind, whether express or implied.
-*/
-
-/dts-v1/;
-
-/ {
-       #address-cells = <0x1>;
-       #size-cells = <0x1>;
-       model = "netstal,hcu4";
-       compatible = "netstal,hcu4";
-       dcr-parent = <0x1>;
-
-       aliases {
-               ethernet0 = "/plb/opb/ethernet@ef600800";
-               serial0 = "/plb/opb/serial@ef600300";
-       };
-
-       cpus {
-               #address-cells = <0x1>;
-               #size-cells = <0x0>;
-
-               cpu@0 {
-                       device_type = "cpu";
-                       model = "PowerPC,405GPr";
-                       reg = <0x0>;
-                       clock-frequency = <0>;          /* Filled in by U-Boot */
-                       timebase-frequency = <0x0>;     /* Filled in by U-Boot */
-                       i-cache-line-size = <0x20>;
-                       d-cache-line-size = <0x20>;
-                       i-cache-size = <0x4000>;
-                       d-cache-size = <0x4000>;
-                       dcr-controller;
-                       dcr-access-method = "native";
-                       linux,phandle = <0x1>;
-               };
-       };
-
-       memory {
-               device_type = "memory";
-               reg = <0x0 0x0>;        /* Filled in by U-Boot */
-       };
-
-       UIC0: interrupt-controller {
-               compatible = "ibm,uic";
-               interrupt-controller;
-               cell-index = <0x0>;
-               dcr-reg = <0xc0 0x9>;
-               #address-cells = <0x0>;
-               #size-cells = <0x0>;
-               #interrupt-cells = <0x2>;
-               linux,phandle = <0x2>;
-       };
-
-       plb {
-               compatible = "ibm,plb3";
-               #address-cells = <0x1>;
-               #size-cells = <0x1>;
-               ranges;
-               clock-frequency = <0x0>;        /* Filled in by U-Boot */
-
-               SDRAM0: memory-controller {
-                       compatible = "ibm,sdram-405gp";
-                       dcr-reg = <0x10 0x2>;
-               };
-
-               MAL: mcmal {
-                       compatible = "ibm,mcmal-405gp", "ibm,mcmal";
-                       dcr-reg = <0x180 0x62>;
-                       num-tx-chans = <0x1>;
-                       num-rx-chans = <0x1>;
-                       interrupt-parent = <0x2>;
-                       interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>;
-                       linux,phandle = <0x3>;
-               };
-
-               POB0: opb {
-                       compatible = "ibm,opb-405gp", "ibm,opb";
-                       #address-cells = <0x1>;
-                       #size-cells = <0x1>;
-                       ranges = <0xef600000 0xef600000 0xa00000>;
-                       dcr-reg = <0xa0 0x5>;
-                       clock-frequency = <0x0>;        /* Filled in by U-Boot */
-
-                       UART0: serial@ef600300 {
-                               device_type = "serial";
-                               compatible = "ns16550";
-                               reg = <0xef600300 0x8>;
-                               virtual-reg = <0xef600300>;
-                               clock-frequency = <0x0>;/* Filled in by U-Boot */
-                               current-speed = <0>;    /* Filled in by U-Boot */
-                               interrupt-parent = <0x2>;
-                               interrupts = <0x0 0x4>;
-                       };
-
-                       IIC: i2c@ef600500 {
-                               compatible = "ibm,iic-405gp", "ibm,iic";
-                               reg = <0xef600500 0x11>;
-                               interrupt-parent = <0x2>;
-                               interrupts = <0x2 0x4>;
-                       };
-
-                       GPIO: gpio@ef600700 {
-                               compatible = "ibm,gpio-405gp";
-                               reg = <0xef600700 0x20>;
-                       };
-
-                       EMAC: ethernet@ef600800 {
-                               device_type = "network";
-                               compatible = "ibm,emac-405gp", "ibm,emac";
-                               interrupt-parent = <0x2>;
-                               interrupts = <0xf 0x4 0x9 0x4>;
-                               local-mac-address = [00 00 00 00 00 00];
-                               reg = <0xef600800 0x70>;
-                               mal-device = <0x3>;
-                               mal-tx-channel = <0x0>;
-                               mal-rx-channel = <0x0>;
-                               cell-index = <0x0>;
-                               max-frame-size = <0x5dc>;
-                               rx-fifo-size = <0x1000>;
-                               tx-fifo-size = <0x800>;
-                               phy-mode = "rmii";
-                               phy-map = <0x1>;
-                       };
-               };
-
-               EBC0: ebc {
-                       compatible = "ibm,ebc-405gp", "ibm,ebc";
-                       dcr-reg = <0x12 0x2>;
-                       #address-cells = <0x2>;
-                       #size-cells = <0x1>;
-                       clock-frequency = <0x0>;        /* Filled in by U-Boot */
-
-                       sram@0,0 {
-                               reg = <0x0 0x0 0x80000>;
-                       };
-
-                       flash@0,80000 {
-                               compatible = "jedec-flash";
-                               bank-width = <0x1>;
-                               reg = <0x0 0x80000 0x80000>;
-                               #address-cells = <0x1>;
-                               #size-cells = <0x1>;
-
-                               partition@0 {
-                                       label = "OpenBIOS";
-                                       reg = <0x0 0x80000>;
-                                       read-only;
-                               };
-                       };
-               };
-       };
-
-       chosen {
-               linux,stdout-path = "/plb/opb/serial@ef600300";
-       };
-};
index 6b33b73a5ba0bc37b0eeae1afd48bdafed0a1b2e..d6c669c888e9f9571595e0bc4a70b66ee1e20607 100644 (file)
@@ -23,6 +23,8 @@
                ethernet2 = &enet2;
                pci0 = &pci0;
                pci1 = &pci1;
+               can0 = &can0;
+               can1 = &can1;
        };
 
        memory {
                        };
                };
 
-               can0@1c000 {
-                       fsl,flexcan-clock-source = "platform";
-               };
-
-               can1@1d000 {
-                       fsl,flexcan-clock-source = "platform";
-               };
-
                usb@22000 {
                        phy_type = "utmi";
                };
index 7f51104f2e36ce3ce6b0de835b5e5f31e484de86..cabe0a453ae65c08af5315aa2d7e9af47a6149a9 100644 (file)
                        interrupt-parent = <&mpic>;
                };
 
-               can0@1c000 {
-                       compatible = "fsl,flexcan-v1.0";
+               can0: can@1c000 {
+                       compatible = "fsl,p1010-flexcan";
                        reg = <0x1c000 0x1000>;
                        interrupts = <48 0x2>;
                        interrupt-parent = <&mpic>;
-                       fsl,flexcan-clock-divider = <2>;
                };
 
-               can1@1d000 {
-                       compatible = "fsl,flexcan-v1.0";
+               can1: can@1d000 {
+                       compatible = "fsl,p1010-flexcan";
                        reg = <0x1d000 0x1000>;
                        interrupts = <61 0x2>;
                        interrupt-parent = <&mpic>;
-                       fsl,flexcan-clock-divider = <2>;
                };
 
                L2: l2-cache-controller@20000 {
index 64923245f0e5adb8d481a62a49f95f709b8ed048..30bb4753577a92652d3524ac7632894e207a5c5a 100644 (file)
                                clock-frequency = <0>; /* Filled in by zImage */
                                interrupts = <0x5 0x1>;
                                interrupt-parent = <&UIC1>;
+
+                               nor_flash@0,0 {
+                                       compatible = "amd,s29gl256n", "cfi-flash";
+                                       bank-width = <2>;
+                                       reg = <0x00000000 0x00000000 0x04000000>;
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       partition@0 {
+                                               label = "kernel";
+                                               reg = <0x00000000 0x001e0000>;
+                                       };
+                                       partition@1e0000 {
+                                               label = "dtb";
+                                               reg = <0x001e0000 0x00020000>;
+                                       };
+                                       partition@200000 {
+                                               label = "ramdisk";
+                                               reg = <0x00200000 0x01400000>;
+                                       };
+                                       partition@1600000 {
+                                               label = "jffs2";
+                                               reg = <0x01600000 0x00400000>;
+                                       };
+                                       partition@1a00000 {
+                                               label = "user";
+                                               reg = <0x01a00000 0x02540000>;
+                                       };
+                                       partition@3f40000 {
+                                               label = "env";
+                                               reg = <0x03f40000 0x00040000>;
+                                       };
+                                       partition@3f80000 {
+                                               label = "u-boot";
+                                               reg = <0x03f80000 0x00080000>;
+                                       };
+                               };
                        };
 
                        UART0: serial@ef600300 {
index 4182c772340bed92697e563f989aaab7f813a5d9..ed3bab72a8344b8713a8fc961032e795d4a7c554 100644 (file)
@@ -44,12 +44,13 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
 CONFIG_MII=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
-CONFIG_IBM_NEW_EMAC_DEBUG=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
+CONFIG_IBM_EMAC_DEBUG=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index 2dbb293163f5b3299d8f778ab62cd0a8009546ed..17582a3420fbfeb599f9e8d4bb4be16e777bae9a 100644 (file)
@@ -42,8 +42,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig
deleted file mode 100644 (file)
index ebeb4ac..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-CONFIG_40x=y
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_HCU4=y
-# CONFIG_WALNUT is not set
-CONFIG_SPARSE_IRQ=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_PROC_DEVICETREE=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
index 532ea9d93a15c8c9629134e6b56f0269e6f00350..f2d4be936e08eed46970c5cb9f3b45387dad006b 100644 (file)
@@ -51,10 +51,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index 3c142ac1b344d3d9986208d3c59dce1ee971eb81..42b979355f9bbf2ce0efc992fc79a5f0f3d0aa9f 100644 (file)
@@ -43,10 +43,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index ff57d4828ffc3c0dfbf923f9f5e2753a3d0a44a8..aa1a4cac3708baf18cd4ca346db95b56c707b3bb 100644 (file)
@@ -40,8 +40,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
index 3ed16d5c909db4d207d793b13dfbf0718959c9a2..329f9a3b892ec0501db87002647fdaa4888a06f7 100644 (file)
@@ -44,10 +44,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index b1b7d2c5c059fcdd40e352ad260abf1f655cb79b..cef7d62560c48ee930aebbcb014add4ac9767085 100644 (file)
@@ -32,8 +32,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
index 30a0a8e08fdd9c2436343eca79c43c2c82c1a372..20c8d26d7fc043836cf0ff8b452ba74356617c76 100644 (file)
@@ -38,10 +38,11 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=2
index a46942aac695184448df89b0324a75676867f5cf..d5be93e6e92d6e9477ad142228f9eede3f8e990e 100644 (file)
@@ -49,10 +49,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index 07d77e51f1ba0637529033cce1f7f258e643a7dd..f9269fc4ffcc008b1eff7038c637d70fd8f36a29 100644 (file)
@@ -40,8 +40,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
index 2ce7e9aff09e916d07fc6978ce914270d6e60f7b..9be089038fd7ba602a529b21c4c521489c1222b3 100644 (file)
@@ -55,10 +55,11 @@ CONFIG_FUSION=y
 CONFIG_FUSION_SAS=y
 CONFIG_I2O=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 CONFIG_E1000E=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index 18730ff9de7c887325481e40de065dfe741371de..82f73035a7ce8f8c520877eb1ae089174f8c665e 100644 (file)
@@ -56,8 +56,9 @@ CONFIG_FUSION_SAS=y
 CONFIG_FUSION_CTL=y
 CONFIG_FUSION_LOGGING=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_WLAN is not set
index 34c09144a6990895e1ff7e9f4a1e9d647f6919c5..109562c3c6be90124c2263e7acb61e55da861dc3 100644 (file)
@@ -42,8 +42,9 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_MACINTOSH_DRIVERS=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
index 01cc2b1a7f9a2563c6c9409d508c70a973384ff7..48802811da76bf7605ece2c4ce28a7d674a8c4a3 100644 (file)
@@ -53,11 +53,12 @@ CONFIG_FUSION=y
 CONFIG_FUSION_SAS=y
 CONFIG_I2O=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
-CONFIG_IBM_NEW_EMAC_DEBUG=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
+CONFIG_IBM_EMAC_DEBUG=y
 CONFIG_E1000E=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index dfcffede16adcf56d2f4900757b582c2cceed446..ca088cd581afb0d5f455b782799c0f9f89249597 100644 (file)
@@ -44,8 +44,9 @@ CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_SATA_SIL=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_INPUT_FF_MEMLESS=m
index 47e399f2892ff4ebbec659430cd355585d949691..b7a653b626dbb67e14990278d1a5a0446626a872 100644 (file)
@@ -46,8 +46,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
index a6a002ed5681065a88e01819bea3d32d4c1f9081..30de97f158a409b53d4883133c929e926435dbae 100644 (file)
@@ -40,8 +40,9 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_MACINTOSH_DRIVERS=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
index abf74dc1f79c34031ac4d0c274f4127c6bc0e337..105bc56f4b2b445a57970a77c583b48c56b8c200 100644 (file)
@@ -54,9 +54,10 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
 CONFIG_MII=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_EMAC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set
index 959cd2cfc2756488fcbe4080a29b396653d5e8d5..716a37be16e33b5d071416592ca8eb39fc7cca2f 100644 (file)
@@ -1,9 +1,10 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
+CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_EPOLL is not set
@@ -17,7 +18,6 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_BESTCOMM=y
-CONFIG_SPARSE_IRQ=y
 CONFIG_PM=y
 # CONFIG_PCI is not set
 CONFIG_NET=y
@@ -38,17 +38,18 @@ CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_ROM=y
 CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_MISC_DEVICES is not set
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=y
@@ -56,13 +57,11 @@ CONFIG_PATA_MPC52xx=y
 CONFIG_PATA_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_LXT_PHY=y
+CONFIG_FIXED_PHY=y
 CONFIG_NET_ETHERNET=y
 CONFIG_FEC_MPC52xx=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
@@ -70,7 +69,13 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MPC=y
+CONFIG_SENSORS_LM80=y
 CONFIG_WATCHDOG=y
+CONFIG_MFD_SM501=y
+CONFIG_FB=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_SM501=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
@@ -80,10 +85,10 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_STORAGE=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_PROC_KCORE=y
@@ -102,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
index bfd634b5ada798b88e4bbacf4fe4af9ad75c4444..1eb19ac45d09ac35172c7a57f1d046c71bc30401 100644 (file)
@@ -14,7 +14,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_PPC4xx_GPIO=y
 CONFIG_ACADIA=y
 CONFIG_EP405=y
-CONFIG_HCU4=y
 CONFIG_HOTFOOT=y
 CONFIG_KILAUEA=y
 CONFIG_MAKALU=y
@@ -50,8 +49,9 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_XILINX_SYSACE=m
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 CONFIG_SERIO=m
 # CONFIG_SERIO_I8042 is not set
index 47133202a6253fb806728d88367432efbe12e954..6cdf1c0d2c8a10acc43796c20af80d52f7b78d64 100644 (file)
@@ -63,8 +63,9 @@ CONFIG_BLK_DEV_SD=m
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 CONFIG_SERIO=m
 # CONFIG_SERIO_I8042 is not set
index 84a685a505fe115a39ebfbe99ce3baa399bf85d3..9a424c4cb0f2714cb947f824a297f55f20fcc3ff 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_HZ_100=y
 CONFIG_BINFMT_MISC=m
-CONFIG_HOTPLUG_CPU=y
 CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTREMOVE=y
@@ -75,7 +74,6 @@ CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_SCTP=m
@@ -133,7 +131,6 @@ CONFIG_NETFILTER_XT_MATCH_U32=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_TTL=m
@@ -145,7 +142,6 @@ CONFIG_NF_NAT=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -176,7 +172,6 @@ CONFIG_CHR_DEV_SG=y
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_SCSI_CXGB3_ISCSI=m
 CONFIG_SCSI_CXGB4_ISCSI=m
 CONFIG_SCSI_BNX2_ISCSI=m
@@ -208,13 +203,6 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_IEEE1394=y
-CONFIG_IEEE1394_OHCI1394=y
-CONFIG_IEEE1394_SBP2=m
-CONFIG_IEEE1394_ETH1394=m
-CONFIG_IEEE1394_RAWIO=y
-CONFIG_IEEE1394_VIDEO1394=m
-CONFIG_IEEE1394_DV1394=m
 CONFIG_ADB_PMU=y
 CONFIG_PMAC_SMU=y
 CONFIG_THERM_PM72=y
@@ -223,43 +211,49 @@ CONFIG_WINDFARM_PM81=y
 CONFIG_WINDFARM_PM91=y
 CONFIG_WINDFARM_PM112=y
 CONFIG_WINDFARM_PM121=y
-CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
 CONFIG_TUN=m
 CONFIG_MARVELL_PHY=y
 CONFIG_BROADCOM_PHY=m
-CONFIG_NET_ETHERNET=y
-CONFIG_SUNGEM=y
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=y
-CONFIG_IBMVETH=m
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=y
-CONFIG_E100=y
+CONFIG_NET_VENDOR_ALTEON=y
 CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
-CONFIG_E1000=y
-CONFIG_E1000E=y
+CONFIG_NET_VENDOR_AMD=y
+CONFIG_PCNET32=y
 CONFIG_TIGON3=y
-CONFIG_BNX2=m
-CONFIG_SPIDER_NET=m
-CONFIG_GELIC_NET=m
-CONFIG_GELIC_WIRELESS=y
 CONFIG_CHELSIO_T1=m
-CONFIG_CHELSIO_T3=m
-CONFIG_CHELSIO_T4=m
+CONFIG_NET_VENDOR_EMULEX=y
+CONFIG_BE2NET=m
+CONFIG_NET_VENDOR_EXAR=y
+CONFIG_S2IO=m
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBMVETH=m
+CONFIG_ISERIES_VETH=m
 CONFIG_EHEA=m
-CONFIG_IXGBE=m
+CONFIG_NET_VENDOR_INTEL=y
+CONFIG_E100=y
+CONFIG_E1000=y
+CONFIG_E1000E=y
 CONFIG_IXGB=m
-CONFIG_S2IO=m
+CONFIG_IXGBE=m
+CONFIG_MLX4_EN=m
+CONFIG_NET_VENDOR_MYRI=y
 CONFIG_MYRI10GE=m
-CONFIG_NETXEN_NIC=m
+CONFIG_NET_VENDOR_NVIDIA=y
+CONFIG_NET_VENDOR_PASEMI=y
 CONFIG_PASEMI_MAC=y
-CONFIG_MLX4_EN=m
+CONFIG_NET_VENDOR_QLOGIC=y
 CONFIG_QLGE=m
-CONFIG_BE2NET=m
-CONFIG_ISERIES_VETH=m
+CONFIG_NETXEN_NIC=m
+CONFIG_NET_VENDOR_SUN=y
+CONFIG_SUNGEM=y
+CONFIG_NET_VENDOR_TOSHIBA=y
+CONFIG_GELIC_NET=m
+CONFIG_GELIC_WIRELESS=y
+CONFIG_SPIDER_NET=m
 CONFIG_PPP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
@@ -331,7 +325,6 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=m
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_STORAGE=m
@@ -373,11 +366,9 @@ CONFIG_JFS_POSIX_ACL=y
 CONFIG_JFS_SECURITY=y
 CONFIG_XFS_FS=m
 CONFIG_XFS_POSIX_ACL=y
-CONFIG_OCFS2_FS=m
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_NILFS2_FS=m
-CONFIG_INOTIFY=y
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 CONFIG_ISO9660_FS=y
@@ -398,7 +389,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
-CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_CIFS=m
 CONFIG_CIFS_XATTR=y
 CONFIG_CIFS_POSIX=y
@@ -444,15 +434,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOCKUP_DETECTOR=y
-CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_CODE_PATCHING_SELFTEST=y
 CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
@@ -463,10 +451,8 @@ CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -474,7 +460,6 @@ CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_KHAZAD=m
index 8a33698c61bd7ab98c0b7e08ee21e6a17aeeb409..f921eb121d39730265d54c6f1a97eb1881c897fe 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_POWERPC_KEXEC_H
 #ifdef __KERNEL__
 
-#ifdef CONFIG_FSL_BOOKE
+#if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_44x)
 
 /*
  * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
index 836f231ec1f0b2ed1301f383b75113ab352ba363..964714940961a729c9b8d7404abb133dedb94c28 100644 (file)
@@ -109,7 +109,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_RESTOREALL         11      /* Restore all regs (implies NOERROR) */
 #define TIF_NOERROR            12      /* Force successful syscall return */
 #define TIF_NOTIFY_RESUME      13      /* callback before returning to user */
-#define TIF_FREEZE             14      /* Freezing for suspend */
 #define TIF_SYSCALL_TRACEPOINT 15      /* syscall tracepoint instrumentation */
 #define TIF_RUNLATCH           16      /* Is the runlatch enabled? */
 
@@ -127,7 +126,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTOREALL                (1<<TIF_RESTOREALL)
 #define _TIF_NOERROR           (1<<TIF_NOERROR)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 #define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 #define _TIF_RUNLATCH          (1<<TIF_RUNLATCH)
 #define _TIF_SYSCALL_T_OR_A    (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
index 998a100286086a289f569a0f83346df8feacd53e..f7d760ab5ca1fd6851502352a7a958759c429c7f 100644 (file)
@@ -8,6 +8,8 @@
  * kexec bits:
  * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
  * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ * PPC44x port. Copyright (C) 2011,  IBM Corporation
+ *             Author: Suzuki Poulose <suzuki@in.ibm.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -735,6 +737,175 @@ relocate_new_kernel:
        mr      r4, r30
        mr      r5, r31
 
+       li      r0, 0
+#elif defined(CONFIG_44x)  && !defined(CONFIG_47x)
+
+/*
+ * Code for setting up 1:1 mapping for PPC440x for KEXEC
+ *
+ * We cannot switch off the MMU on PPC44x.
+ * So we:
+ * 1) Invalidate all the mappings except the one we are running from.
+ * 2) Create a tmp mapping for our code in the other address space(TS) and
+ *    jump to it. Invalidate the entry we started in.
+ * 3) Create a 1:1 mapping for 0-2GiB in chunks of 256M in original TS.
+ * 4) Jump to the 1:1 mapping in original TS.
+ * 5) Invalidate the tmp mapping.
+ *
+ * - Based on the kexec support code for FSL BookE
+ * - Doesn't support 47x yet.
+ *
+ */
+       /* Save our parameters */
+       mr      r29, r3
+       mr      r30, r4
+       mr      r31, r5
+
+       /* Load our MSR_IS and TID to MMUCR for TLB search */
+       mfspr   r3,SPRN_PID
+       mfmsr   r4
+       andi.   r4,r4,MSR_IS@l
+       beq     wmmucr
+       oris    r3,r3,PPC44x_MMUCR_STS@h
+wmmucr:
+       mtspr   SPRN_MMUCR,r3
+       sync
+
+       /*
+        * Invalidate all the TLB entries except the current entry
+        * where we are running from
+        */
+       bl      0f                              /* Find our address */
+0:     mflr    r5                              /* Make it accessible */
+       tlbsx   r23,0,r5                        /* Find entry we are in */
+       li      r4,0                            /* Start at TLB entry 0 */
+       li      r3,0                            /* Set PAGEID inval value */
+1:     cmpw    r23,r4                          /* Is this our entry? */
+       beq     skip                            /* If so, skip the inval */
+       tlbwe   r3,r4,PPC44x_TLB_PAGEID         /* If not, inval the entry */
+skip:
+       addi    r4,r4,1                         /* Increment */
+       cmpwi   r4,64                           /* Are we done? */
+       bne     1b                              /* If not, repeat */
+       isync
+
+       /* Create a temp mapping and jump to it */
+       andi.   r6, r23, 1              /* Find the index to use */
+       addi    r24, r6, 1              /* r24 will contain 1 or 2 */
+
+       mfmsr   r9                      /* get the MSR */
+       rlwinm  r5, r9, 27, 31, 31      /* Extract the MSR[IS] */
+       xori    r7, r5, 1               /* Use the other address space */
+
+       /* Read the current mapping entries */
+       tlbre   r3, r23, PPC44x_TLB_PAGEID
+       tlbre   r4, r23, PPC44x_TLB_XLAT
+       tlbre   r5, r23, PPC44x_TLB_ATTRIB
+
+       /* Save our current XLAT entry */
+       mr      r25, r4
+
+       /* Extract the TLB PageSize */
+       li      r10, 1                  /* r10 will hold PageSize */
+       rlwinm  r11, r3, 0, 24, 27      /* bits 24-27 */
+
+       /* XXX: As of now we use 256M, 4K pages */
+       cmpwi   r11, PPC44x_TLB_256M
+       bne     tlb_4k
+       rotlwi  r10, r10, 28            /* r10 = 256M */
+       b       write_out
+tlb_4k:
+       cmpwi   r11, PPC44x_TLB_4K
+       bne     default
+       rotlwi  r10, r10, 12            /* r10 = 4K */
+       b       write_out
+default:
+       rotlwi  r10, r10, 10            /* r10 = 1K */
+
+write_out:
+       /*
+        * Write out the tmp 1:1 mapping for this code in other address space
+        * Fixup  EPN = RPN , TS=other address space
+        */
+       insrwi  r3, r7, 1, 23           /* Bit 23 is TS for PAGEID field */
+
+       /* Write out the tmp mapping entries */
+       tlbwe   r3, r24, PPC44x_TLB_PAGEID
+       tlbwe   r4, r24, PPC44x_TLB_XLAT
+       tlbwe   r5, r24, PPC44x_TLB_ATTRIB
+
+       subi    r11, r10, 1             /* PageOffset Mask = PageSize - 1 */
+       not     r10, r11                /* Mask for PageNum */
+
+       /* Switch to other address space in MSR */
+       insrwi  r9, r7, 1, 26           /* Set MSR[IS] = r7 */
+
+       bl      1f
+1:     mflr    r8
+       addi    r8, r8, (2f-1b)         /* Find the target offset */
+
+       /* Jump to the tmp mapping */
+       mtspr   SPRN_SRR0, r8
+       mtspr   SPRN_SRR1, r9
+       rfi
+
+2:
+       /* Invalidate the entry we were executing from */
+       li      r3, 0
+       tlbwe   r3, r23, PPC44x_TLB_PAGEID
+
+       /* attribute fields. rwx for SUPERVISOR mode */
+       li      r5, 0
+       ori     r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
+
+       /* Create 1:1 mapping in 256M pages */
+       xori    r7, r7, 1                       /* Revert back to Original TS */
+
+       li      r8, 0                           /* PageNumber */
+       li      r6, 3                           /* TLB Index, start at 3  */
+
+next_tlb:
+       rotlwi  r3, r8, 28                      /* Create EPN (bits 0-3) */
+       mr      r4, r3                          /* RPN = EPN  */
+       ori     r3, r3, (PPC44x_TLB_VALID | PPC44x_TLB_256M) /* SIZE = 256M, Valid */
+       insrwi  r3, r7, 1, 23                   /* Set TS from r7 */
+
+       tlbwe   r3, r6, PPC44x_TLB_PAGEID       /* PageID field : EPN, V, SIZE */
+       tlbwe   r4, r6, PPC44x_TLB_XLAT         /* Address translation : RPN   */
+       tlbwe   r5, r6, PPC44x_TLB_ATTRIB       /* Attributes */
+
+       addi    r8, r8, 1                       /* Increment PN */
+       addi    r6, r6, 1                       /* Increment TLB Index */
+       cmpwi   r8, 8                           /* Are we done ? */
+       bne     next_tlb
+       isync
+
+       /* Jump to the new mapping 1:1 */
+       li      r9,0
+       insrwi  r9, r7, 1, 26                   /* Set MSR[IS] = r7 */
+
+       bl      1f
+1:     mflr    r8
+       and     r8, r8, r11                     /* Get our offset within page */
+       addi    r8, r8, (2f-1b)
+
+       and     r5, r25, r10                    /* Get our target PageNum */
+       or      r8, r8, r5                      /* Target jump address */
+
+       mtspr   SPRN_SRR0, r8
+       mtspr   SPRN_SRR1, r9
+       rfi
+2:
+       /* Invalidate the tmp entry we used */
+       li      r3, 0
+       tlbwe   r3, r24, PPC44x_TLB_PAGEID
+       sync
+
+       /* Restore the parameters */
+       mr      r3, r29
+       mr      r4, r30
+       mr      r5, r31
+
        li      r0, 0
 #else
        li      r0, 0
index d733d7ca939c476e69be1994277460b216138175..8f9c3e245cff6d149d2bc59402acf0cf6fd7776c 100644 (file)
@@ -32,14 +32,6 @@ config EP405
        help
          This option enables support for the EP405/EP405PC boards.
 
-config HCU4
-       bool "Hcu4"
-       depends on 40x
-       default n
-       select 405GPR
-       help
-         This option enables support for the Nestal Maschinen HCU4 board.
-
 config HOTFOOT
         bool "Hotfoot"
        depends on 40x
@@ -130,21 +122,21 @@ config 405GP
        bool
        select IBM405_ERR77
        select IBM405_ERR51
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_ZMII
 
 config 405EP
        bool
 
 config 405EX
        bool
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_RGMII
 
 config 405EZ
        bool
-       select IBM_NEW_EMAC_NO_FLOW_CTRL
-       select IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
-       select IBM_NEW_EMAC_MAL_COMMON_ERR
+       select IBM_EMAC_NO_FLOW_CTRL
+       select IBM_EMAC_MAL_CLR_ICINTSTAT
+       select IBM_EMAC_MAL_COMMON_ERR
 
 config 405GPR
        bool
index 56e89004c468cc3e43f1a8037354152be20130a2..88c22de0c85051baecd4123e3dfd0b0a9538ce9d 100644 (file)
@@ -1,4 +1,3 @@
-obj-$(CONFIG_HCU4)                             += hcu4.o
 obj-$(CONFIG_WALNUT)                           += walnut.o
 obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)      += virtex.o
 obj-$(CONFIG_EP405)                            += ep405.o
diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c
deleted file mode 100644 (file)
index 60b2afe..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Architecture- / platform-specific boot-time initialization code for
- * IBM PowerPC 4xx based boards. Adapted from original
- * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
- * <dan@net4x.com>.
- *
- * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
- *
- * Rewritten and ported to the merged powerpc tree:
- * Copyright 2007 IBM Corporation
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- *
- * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id hcu4_of_bus[] = {
-       { .compatible = "ibm,plb3", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init hcu4_device_probe(void)
-{
-       of_platform_bus_probe(NULL, hcu4_of_bus, NULL);
-       return 0;
-}
-machine_device_initcall(hcu4, hcu4_device_probe);
-
-static int __init hcu4_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "netstal,hcu4"))
-               return 0;
-
-       return 1;
-}
-
-define_machine(hcu4) {
-       .name                   = "HCU4",
-       .probe                  = hcu4_probe,
-       .progress               = udbg_progress,
-       .init_IRQ               = uic_init_tree,
-       .get_irq                = uic_get_irq,
-       .restart                = ppc4xx_reset_system,
-       .calibrate_decr         = generic_calibrate_decr,
-};
index e958b6f48ec283073e678bb8fdf815ae3bdcdea0..762322ce24a9712345d5905d67e0ccec764d1c68 100644 (file)
@@ -23,7 +23,7 @@ config BLUESTONE
        default n
        select PPC44x_SIMPLE
        select APM821xx
-       select IBM_NEW_EMAC_RGMII
+       select IBM_EMAC_RGMII
        help
          This option enables support for the APM APM821xx Evaluation board.
 
@@ -122,8 +122,8 @@ config CANYONLANDS
        select PPC4xx_PCI_EXPRESS
        select PCI_MSI
        select PPC4xx_MSI
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII
        help
          This option enables support for the AMCC PPC460EX evaluation board.
 
@@ -135,8 +135,8 @@ config GLACIER
        select 460EX # Odd since it uses 460GT but the effects are the same
        select PCI
        select PPC4xx_PCI_EXPRESS
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII
        help
          This option enables support for the AMCC PPC460GT evaluation board.
 
@@ -161,7 +161,7 @@ config EIGER
        select 460SX
        select PCI
        select PPC4xx_PCI_EXPRESS
-       select IBM_NEW_EMAC_RGMII
+       select IBM_EMAC_RGMII
        help
          This option enables support for the AMCC PPC460SX evaluation board.
 
@@ -260,59 +260,59 @@ config 440EP
        bool
        select PPC_FPU
        select IBM440EP_ERR42
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_ZMII
        select USB_ARCH_HAS_OHCI
 
 config 440EPX
        bool
        select PPC_FPU
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII
 
 config 440GRX
        bool
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII
 
 config 440GP
        bool
-       select IBM_NEW_EMAC_ZMII
+       select IBM_EMAC_ZMII
 
 config 440GX
        bool
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII #test only
-       select IBM_NEW_EMAC_TAH  #test only
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII #test only
+       select IBM_EMAC_TAH  #test only
 
 config 440SP
        bool
 
 config 440SPe
        bool
-       select IBM_NEW_EMAC_EMAC4
+       select IBM_EMAC_EMAC4
 
 config 460EX
        bool
        select PPC_FPU
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_TAH
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_TAH
 
 config 460SX
        bool
        select PPC_FPU
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII
-       select IBM_NEW_EMAC_TAH
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII
+       select IBM_EMAC_TAH
 
 config APM821xx
        bool
        select PPC_FPU
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_TAH
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_TAH
 
 # 44x errata/workaround config symbols, selected by the CPU models above
 config IBM440EP_ERR42
index e41ebbdb3e123fb8413c89559ff156ac7f89f245..3dc62f907a1ef6aa53ef6b2503d4e5a4147d7b0a 100644 (file)
@@ -66,8 +66,8 @@ struct fsl_diu_shared_fb {
        bool            in_use;
 };
 
-unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
-                                     int monitor_port)
+u32 mpc512x_get_pixel_format(enum fsl_diu_monitor_port port,
+                            unsigned int bits_per_pixel)
 {
        switch (bits_per_pixel) {
        case 32:
@@ -80,11 +80,12 @@ unsigned int mpc512x_get_pixel_format(unsigned int bits_per_pixel,
        return 0x00000400;
 }
 
-void mpc512x_set_gamma_table(int monitor_port, char *gamma_table_base)
+void mpc512x_set_gamma_table(enum fsl_diu_monitor_port port,
+                            char *gamma_table_base)
 {
 }
 
-void mpc512x_set_monitor_port(int monitor_port)
+void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
 {
 }
 
@@ -182,14 +183,10 @@ void mpc512x_set_pixel_clock(unsigned int pixclock)
        iounmap(ccm);
 }
 
-ssize_t mpc512x_show_monitor_port(int monitor_port, char *buf)
+enum fsl_diu_monitor_port
+mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
-       return sprintf(buf, "0 - 5121 LCD\n");
-}
-
-int mpc512x_set_sysfs_monitor_port(int val)
-{
-       return 0;
+       return FSL_DIU_PORT_DVI;
 }
 
 static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
@@ -332,8 +329,7 @@ void __init mpc512x_setup_diu(void)
        diu_ops.set_gamma_table         = mpc512x_set_gamma_table;
        diu_ops.set_monitor_port        = mpc512x_set_monitor_port;
        diu_ops.set_pixel_clock         = mpc512x_set_pixel_clock;
-       diu_ops.show_monitor_port       = mpc512x_show_monitor_port;
-       diu_ops.set_sysfs_monitor_port  = mpc512x_set_sysfs_monitor_port;
+       diu_ops.valid_monitor_port      = mpc512x_valid_monitor_port;
        diu_ops.release_bootmem         = mpc512x_release_bootmem;
 #endif
 }
index e36d6e232ae66f4bf3033e5b60363cea25e46008..846b789fb1953000d15f90f1da723f0b0d81ff43 100644 (file)
@@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void)
 
 /* list of the supported boards */
 static const char *board[] __initdata = {
+       "anon,charon",
        "intercontrol,digsy-mtc",
        "manroland,mucmc52",
        "manroland,uc101",
index 266b3aadfe5e2671d9ab11d1100dfcfcef52829b..c01c7277888c1e3655fddd6be2dfe2da21705182 100644 (file)
@@ -93,8 +93,8 @@
  * The Area Descriptor is a 32-bit value that determine which bits in each
  * pixel are to be used for each color.
  */
-static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
-       int monitor_port)
+static u32 p1022ds_get_pixel_format(enum fsl_diu_monitor_port port,
+                                   unsigned int bits_per_pixel)
 {
        switch (bits_per_pixel) {
        case 32:
@@ -118,7 +118,8 @@ static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
  * On some boards, the gamma table for some ports may need to be modified.
  * This is not the case on the P1022DS, so we do nothing.
 */
-static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
+static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
+                                   char *gamma_table_base)
 {
 }
 
@@ -126,7 +127,7 @@ static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
  * p1022ds_set_monitor_port: switch the output to a different monitor port
  *
  */
-static void p1022ds_set_monitor_port(int monitor_port)
+static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
 {
        struct device_node *pixis_node;
        void __iomem *pixis;
@@ -145,19 +146,21 @@ static void p1022ds_set_monitor_port(int monitor_port)
        }
        brdcfg1 = pixis + 9;    /* BRDCFG1 is at offset 9 in the ngPIXIS */
 
-       switch (monitor_port) {
-       case 0: /* DVI */
+       switch (port) {
+       case FSL_DIU_PORT_DVI:
+               printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
                /* Enable the DVI port, disable the DFP and the backlight */
                clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
                             PX_BRDCFG1_DVIEN);
                break;
-       case 1: /* Single link LVDS */
+       case FSL_DIU_PORT_LVDS:
+               printk(KERN_INFO "%s:%u\n", __func__, __LINE__);
                /* Enable the DFP port, disable the DVI and the backlight */
                clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
                             PX_BRDCFG1_DFPEN);
                break;
        default:
-               pr_err("p1022ds: unsupported monitor port %i\n", monitor_port);
+               pr_err("p1022ds: unsupported monitor port %i\n", port);
        }
 
        iounmap(pixis);
@@ -214,23 +217,18 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
 }
 
 /**
- * p1022ds_show_monitor_port: show the current monitor
- *
- * This function returns a string indicating whether the current monitor is
- * set to DVI or LVDS.
- */
-ssize_t p1022ds_show_monitor_port(int monitor_port, char *buf)
-{
-       return sprintf(buf, "%c0 - DVI\n%c1 - Single link LVDS\n",
-               monitor_port == 0 ? '*' : ' ', monitor_port == 1 ? '*' : ' ');
-}
-
-/**
- * p1022ds_set_sysfs_monitor_port: set the monitor port for sysfs
+ * p1022ds_valid_monitor_port: set the monitor port for sysfs
  */
-int p1022ds_set_sysfs_monitor_port(int val)
+enum fsl_diu_monitor_port
+p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
-       return val < 2 ? val : 0;
+       switch (port) {
+       case FSL_DIU_PORT_DVI:
+       case FSL_DIU_PORT_LVDS:
+               return port;
+       default:
+               return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
+       }
 }
 
 #endif
@@ -305,8 +303,7 @@ static void __init p1022_ds_setup_arch(void)
        diu_ops.set_gamma_table         = p1022ds_set_gamma_table;
        diu_ops.set_monitor_port        = p1022ds_set_monitor_port;
        diu_ops.set_pixel_clock         = p1022ds_set_pixel_clock;
-       diu_ops.show_monitor_port       = p1022ds_show_monitor_port;
-       diu_ops.set_sysfs_monitor_port  = p1022ds_set_sysfs_monitor_port;
+       diu_ops.valid_monitor_port      = p1022ds_valid_monitor_port;
 #endif
 
 #ifdef CONFIG_SMP
index 74e018ef724b0acc0aed5574e0bc483f2be37b83..13fa9a6403e6fc8820554126b113038209e7fb91 100644 (file)
@@ -152,10 +152,10 @@ machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
        (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
        (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
 
-unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
-                                               int monitor_port)
+u32 mpc8610hpcd_get_pixel_format(enum fsl_diu_monitor_port port,
+                                unsigned int bits_per_pixel)
 {
-       static const unsigned long pixelformat[][3] = {
+       static const u32 pixelformat[][3] = {
                {
                        MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8),
                        MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0),
@@ -170,7 +170,8 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
        unsigned int arch_monitor;
 
        /* The DVI port is mis-wired on revision 1 of this board. */
-       arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1;
+       arch_monitor =
+               ((*pixis_arch == 0x01) && (port == FSL_DIU_PORT_DVI)) ? 0 : 1;
 
        switch (bits_per_pixel) {
        case 32:
@@ -185,10 +186,11 @@ unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
        }
 }
 
-void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
+void mpc8610hpcd_set_gamma_table(enum fsl_diu_monitor_port port,
+                                char *gamma_table_base)
 {
        int i;
-       if (monitor_port == 2) {                /* dual link LVDS */
+       if (port == FSL_DIU_PORT_DLVDS) {
                for (i = 0; i < 256*3; i++)
                        gamma_table_base[i] = (gamma_table_base[i] << 2) |
                                         ((gamma_table_base[i] >> 6) & 0x03);
@@ -199,17 +201,21 @@ void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
 #define PX_BRDCFG0_DLINK       (1 << 4)
 #define PX_BRDCFG0_DIU_MASK    (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK)
 
-void mpc8610hpcd_set_monitor_port(int monitor_port)
+void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port)
 {
-       static const u8 bdcfg[] = {
-               PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK,
-               PX_BRDCFG0_DLINK,
-               0,
-       };
-
-       if (monitor_port < 3)
+       switch (port) {
+       case FSL_DIU_PORT_DVI:
                clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
-                            bdcfg[monitor_port]);
+                            PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK);
+               break;
+       case FSL_DIU_PORT_LVDS:
+               clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK,
+                            PX_BRDCFG0_DLINK);
+               break;
+       case FSL_DIU_PORT_DLVDS:
+               clrbits8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK);
+               break;
+       }
 }
 
 /**
@@ -262,20 +268,10 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
        iounmap(guts);
 }
 
-ssize_t mpc8610hpcd_show_monitor_port(int monitor_port, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE,
-                       "%c0 - DVI\n"
-                       "%c1 - Single link LVDS\n"
-                       "%c2 - Dual link LVDS\n",
-                       monitor_port == 0 ? '*' : ' ',
-                       monitor_port == 1 ? '*' : ' ',
-                       monitor_port == 2 ? '*' : ' ');
-}
-
-int mpc8610hpcd_set_sysfs_monitor_port(int val)
+enum fsl_diu_monitor_port
+mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
-       return val < 3 ? val : 0;
+       return port;
 }
 
 #endif
@@ -307,8 +303,7 @@ static void __init mpc86xx_hpcd_setup_arch(void)
        diu_ops.set_gamma_table         = mpc8610hpcd_set_gamma_table;
        diu_ops.set_monitor_port        = mpc8610hpcd_set_monitor_port;
        diu_ops.set_pixel_clock         = mpc8610hpcd_set_pixel_clock;
-       diu_ops.show_monitor_port       = mpc8610hpcd_show_monitor_port;
-       diu_ops.set_sysfs_monitor_port  = mpc8610hpcd_set_sysfs_monitor_port;
+       diu_ops.valid_monitor_port      = mpc8610hpcd_valid_monitor_port;
 #endif
 
        pixis_node = of_find_compatible_node(NULL, NULL, "fsl,fpga-pixis");
index 67d5009b4e86d51b836d9da2294133716eb40720..2e7ff0c5cf42fd3492516c2f0a28c0fc3cec548b 100644 (file)
@@ -17,10 +17,10 @@ config PPC_CELL_NATIVE
        select PPC_CELL_COMMON
        select MPIC
        select PPC_IO_WORKAROUNDS
-       select IBM_NEW_EMAC_EMAC4
-       select IBM_NEW_EMAC_RGMII
-       select IBM_NEW_EMAC_ZMII #test only
-       select IBM_NEW_EMAC_TAH  #test only
+       select IBM_EMAC_EMAC4
+       select IBM_EMAC_RGMII
+       select IBM_EMAC_ZMII #test only
+       select IBM_EMAC_TAH  #test only
        default n
 
 config PPC_IBM_CELL_BLADE
index 2ece02beb8ffed1a0828877d02adf251d779ed96..c6d00736f07f559f677e25344c15c09943a3b25e 100644 (file)
@@ -22,15 +22,24 @@ struct device_node;
 extern void fsl_rstcr_restart(char *cmd);
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
+
+/* The different ports that the DIU can be connected to */
+enum fsl_diu_monitor_port {
+       FSL_DIU_PORT_DVI,       /* DVI */
+       FSL_DIU_PORT_LVDS,      /* Single-link LVDS */
+       FSL_DIU_PORT_DLVDS      /* Dual-link LVDS */
+};
+
 struct platform_diu_data_ops {
-       unsigned int (*get_pixel_format) (unsigned int bits_per_pixel,
-               int monitor_port);
-       void (*set_gamma_table) (int monitor_port, char *gamma_table_base);
-       void (*set_monitor_port) (int monitor_port);
-       void (*set_pixel_clock) (unsigned int pixclock);
-       ssize_t (*show_monitor_port) (int monitor_port, char *buf);
-       int (*set_sysfs_monitor_port) (int val);
-       void (*release_bootmem) (void);
+       u32 (*get_pixel_format)(enum fsl_diu_monitor_port port,
+               unsigned int bpp);
+       void (*set_gamma_table)(enum fsl_diu_monitor_port port,
+               char *gamma_table_base);
+       void (*set_monitor_port)(enum fsl_diu_monitor_port port);
+       void (*set_pixel_clock)(unsigned int pixclock);
+       enum fsl_diu_monitor_port (*valid_monitor_port)
+               (enum fsl_diu_monitor_port port);
+       void (*release_bootmem)(void);
 };
 
 extern struct platform_diu_data_ops diu_ops;
index dbfe96bc878a2578c9171266012323b085e6c8b6..2ec046d0a394a148cf4d865e92cb44854d2d869f 100644 (file)
@@ -1092,6 +1092,10 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
        mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
        mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
 
+       /* Set HSS PRBS enabled */
+       mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130);
+       mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130);
+
        udelay(100);
 
        /* De-assert PLLRESET */
@@ -1132,9 +1136,6 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
                dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
                                0, 0x01000000);
 
-       /*Gen-1*/
-       mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
-
        dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
                        (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
                        PESDRx_RCSSET_RSTPYN);
@@ -1148,14 +1149,42 @@ static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
 {
        /* Max 128 Bytes */
        out_be32 (port->utl_base + PEUTL_PBBSZ,   0x00000000);
+       /* Assert VRB and TXE - per datasheet turn off addr validation */
+       out_be32(port->utl_base + PEUTL_PCTL,  0x80800000);
        return 0;
 }
 
+static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port)
+{
+       void __iomem *mbase;
+       int attempt = 50;
+
+       port->link = 0;
+
+       mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
+       if (mbase == NULL) {
+               printk(KERN_ERR "%s: Can't map internal config space !",
+                       port->node->full_name);
+               goto done;
+       }
+
+       while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA)
+                       & PECFG_460SX_DLLSTA_LINKUP))) {
+               attempt--;
+               mdelay(10);
+       }
+       if (attempt)
+               port->link = 1;
+done:
+       iounmap(mbase);
+
+}
+
 static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
        .core_init      = ppc460sx_pciex_core_init,
        .port_init_hw   = ppc460sx_pciex_init_port_hw,
        .setup_utl      = ppc460sx_pciex_init_utl,
-       .check_link     = ppc4xx_pciex_check_link_sdr,
+       .check_link     = ppc460sx_pciex_check_link,
 };
 
 #endif /* CONFIG_44x */
@@ -1338,15 +1367,15 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
        if (rc != 0)
                return rc;
 
-       if (ppc4xx_pciex_hwops->check_link)
-               ppc4xx_pciex_hwops->check_link(port);
-
        /*
         * Initialize mapping: disable all regions and configure
         * CFG and REG regions based on resources in the device tree
         */
        ppc4xx_pciex_port_init_mapping(port);
 
+       if (ppc4xx_pciex_hwops->check_link)
+               ppc4xx_pciex_hwops->check_link(port);
+
        /*
         * Map UTL
         */
@@ -1360,13 +1389,23 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
                ppc4xx_pciex_hwops->setup_utl(port);
 
        /*
-        * Check for VC0 active and assert RDY.
+        * Check for VC0 active or PLL Locked and assert RDY.
         */
        if (port->sdr_base) {
-               if (port->link &&
-                   ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
-                                            1 << 16, 1 << 16, 5000)) {
-                       printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
+               if (of_device_is_compatible(port->node,
+                               "ibm,plb-pciex-460sx")){
+                       if (port->link && ppc4xx_pciex_wait_on_sdr(port,
+                                       PESDRn_RCSSTS,
+                                       1 << 12, 1 << 12, 5000)) {
+                               printk(KERN_INFO "PCIE%d: PLL not locked\n",
+                                               port->index);
+                               port->link = 0;
+                       }
+               } else if (port->link &&
+                       ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
+                               1 << 16, 1 << 16, 5000)) {
+                       printk(KERN_INFO "PCIE%d: VC0 not active\n",
+                                       port->index);
                        port->link = 0;
                }
 
@@ -1573,8 +1612,15 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port    *port,
                dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
-               /* Note that 3 here means enabled | single region */
-               dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
+               /*Enabled and single region */
+               if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+                       dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
+                               sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT
+                                       | DCRO_PEGPL_OMRxMSKL_VAL);
+               else
+                       dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
+                               sa | DCRO_PEGPL_OMR1MSKL_UOT
+                                       | DCRO_PEGPL_OMRxMSKL_VAL);
                break;
        case 1:
                out_le32(mbase + PECFG_POM1LAH, pciah);
@@ -1582,8 +1628,8 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port     *port,
                dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
-               /* Note that 3 here means enabled | single region */
-               dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
+               dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL,
+                               sa | DCRO_PEGPL_OMRxMSKL_VAL);
                break;
        case 2:
                out_le32(mbase + PECFG_POM2LAH, pciah);
@@ -1592,7 +1638,9 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port     *port,
                dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
                /* Note that 3 here means enabled | IO space !!! */
-               dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3);
+               dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL,
+                               sa | DCRO_PEGPL_OMR3MSKL_IO
+                                       | DCRO_PEGPL_OMRxMSKL_VAL);
                break;
        }
 
@@ -1693,6 +1741,9 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
                if (res->flags & IORESOURCE_PREFETCH)
                        sa |= 0x8;
 
+               if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+                       sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+
                out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
                out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
 
@@ -1854,6 +1905,10 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
        }
        out_le16(mbase + 0x202, val);
 
+       /* Enable Bus master, memory, and io space */
+       if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+               out_le16(mbase + 0x204, 0x7);
+
        if (!port->endpoint) {
                /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
                out_le32(mbase + 0x208, 0x06040001);
index c39a134e86843594abb4ea753203d271399dfc88..32ce763a375a4c80867ac0b7c5f9ea85d2422032 100644 (file)
 #define PECFG_POM2LAL          0x390
 #define PECFG_POM2LAH          0x394
 
+/* 460sx only */
+#define PECFG_460SX_DLLSTA     0x3f8
+
+/* 460sx Bit Mappings */
+#define PECFG_460SX_DLLSTA_LINKUP       0x00000010
+#define DCRO_PEGPL_460SX_OMR1MSKL_UOT   0x00000004
+
+/* PEGPL Bit Mappings */
+#define DCRO_PEGPL_OMRxMSKL_VAL         0x00000001
+#define DCRO_PEGPL_OMR1MSKL_UOT         0x00000002
+#define DCRO_PEGPL_OMR3MSKL_IO  0x00000002
+
 /* SDR Bit Mappings */
 #define PESDRx_RCSSET_HLDPLB   0x10000000
 #define PESDRx_RCSSET_RSTGU    0x01000000
index ed5cb5af52816940d45c6610e3e2e0d8c1d60a82..a9fbd43395f71814d85a284a63900dc5a7dcc018 100644 (file)
@@ -91,6 +91,7 @@ config S390
        select HAVE_ARCH_MUTEX_CPU_RELAX
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
        select HAVE_RCU_TABLE_FREE if SMP
+       select ARCH_SAVE_PAGE_KEYS if HIBERNATION
        select ARCH_INLINE_SPIN_TRYLOCK
        select ARCH_INLINE_SPIN_TRYLOCK_BH
        select ARCH_INLINE_SPIN_LOCK
@@ -568,6 +569,16 @@ config KEXEC
          current kernel, and to start another kernel.  It is like a reboot
          but is independent of hardware/microcode support.
 
+config CRASH_DUMP
+       bool "kernel crash dumps"
+       depends on 64BIT
+       help
+         Generate crash dump after being started by kexec.
+         Crash dump kernels are loaded in the main kernel with kexec-tools
+         into a specially reserved region and then later executed after
+         a crash by kdump/kexec.
+         For more details see Documentation/kdump/kdump.txt
+
 config ZFCPDUMP
        def_bool n
        prompt "zfcpdump support"
index 97cc4403fabfe6a0a4ad0b21a4b9b5fa41df6e28..6940abfbe1d93aaab0189bb8e77a0b2b99f8caa7 100644 (file)
@@ -168,5 +168,6 @@ enum diag308_rc {
 
 extern int diag308(unsigned long subcode, void *addr);
 extern void diag308_reset(void);
+extern void store_status(void);
 
 #endif /* _ASM_S390_IPL_H */
index bb729b84a21e4c3c48b3a290676236c12d6a4616..fb1c96fa348cee2ea06cb7f4b002b7a76cb4c4e2 100644 (file)
@@ -30,6 +30,9 @@
 /* Not more than 2GB */
 #define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31)
 
+/* Maximum address we can use for the crash control pages */
+#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT (-1UL)
+
 /* Allocate one page for the pdp and the second for the code */
 #define KEXEC_CONTROL_PAGE_SIZE 4096
 
index 15c97625df8d3f0411c17a44c999b117ef1ff49d..21993623da9a576f0d97c0c6784c20512f73adff 100644 (file)
@@ -122,6 +122,40 @@ struct slibe {
        u64 parms;
 };
 
+/**
+ * struct qaob - queue asynchronous operation block
+ * @res0: reserved parameters
+ * @res1: reserved parameter
+ * @res2: reserved parameter
+ * @res3: reserved parameter
+ * @aorc: asynchronous operation return code
+ * @flags: internal flags
+ * @cbtbs: control block type
+ * @sb_count: number of storage blocks
+ * @sba: storage block element addresses
+ * @dcount: size of storage block elements
+ * @user0: user defineable value
+ * @res4: reserved paramater
+ * @user1: user defineable value
+ * @user2: user defineable value
+ */
+struct qaob {
+       u64 res0[6];
+       u8 res1;
+       u8 res2;
+       u8 res3;
+       u8 aorc;
+       u8 flags;
+       u16 cbtbs;
+       u8 sb_count;
+       u64 sba[QDIO_MAX_ELEMENTS_PER_BUFFER];
+       u16 dcount[QDIO_MAX_ELEMENTS_PER_BUFFER];
+       u64 user0;
+       u64 res4[2];
+       u64 user1;
+       u64 user2;
+} __attribute__ ((packed, aligned(256)));
+
 /**
  * struct slib - storage list information block (SLIB)
  * @nsliba: next SLIB address (if any)
@@ -225,6 +259,41 @@ struct slsb {
 #define CHSC_AC2_DATA_DIV_AVAILABLE    0x0010
 #define CHSC_AC2_DATA_DIV_ENABLED      0x0002
 
+/**
+ * struct qdio_outbuf_state - SBAL related asynchronous operation information
+ *   (for communication with upper layer programs)
+ *   (only required for use with completion queues)
+ * @flags: flags indicating state of buffer
+ * @aob: pointer to QAOB used for the particular SBAL
+ * @user: pointer to upper layer program's state information related to SBAL
+ *        (stored in user1 data of QAOB)
+ */
+struct qdio_outbuf_state {
+       u8 flags;
+       struct qaob *aob;
+       void *user;
+};
+
+#define QDIO_OUTBUF_STATE_FLAG_NONE    0x00
+#define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01
+
+#define CHSC_AC1_INITIATE_INPUTQ       0x80
+
+
+/* qdio adapter-characteristics-1 flag */
+#define AC1_SIGA_INPUT_NEEDED          0x40    /* process input queues */
+#define AC1_SIGA_OUTPUT_NEEDED         0x20    /* process output queues */
+#define AC1_SIGA_SYNC_NEEDED           0x10    /* ask hypervisor to sync */
+#define AC1_AUTOMATIC_SYNC_ON_THININT  0x08    /* set by hypervisor */
+#define AC1_AUTOMATIC_SYNC_ON_OUT_PCI  0x04    /* set by hypervisor */
+#define AC1_SC_QEBSM_AVAILABLE         0x02    /* available for subchannel */
+#define AC1_SC_QEBSM_ENABLED           0x01    /* enabled for subchannel */
+
+#define CHSC_AC2_DATA_DIV_AVAILABLE    0x0010
+#define CHSC_AC2_DATA_DIV_ENABLED      0x0002
+
+#define CHSC_AC3_FORMAT2_CQ_AVAILABLE  0x8000
+
 struct qdio_ssqd_desc {
        u8 flags;
        u8:8;
@@ -243,8 +312,7 @@ struct qdio_ssqd_desc {
        u64 sch_token;
        u8 mro;
        u8 mri;
-       u8:8;
-       u8 sbalic;
+       u16 qdioac3;
        u16:16;
        u8:8;
        u8 mmwc;
@@ -280,9 +348,11 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
  * @no_output_qs: number of output queues
  * @input_handler: handler to be called for input queues
  * @output_handler: handler to be called for output queues
+ * @queue_start_poll: polling handlers (one per input queue or NULL)
  * @int_parm: interruption parameter
  * @input_sbal_addr_array:  address of no_input_qs * 128 pointers
  * @output_sbal_addr_array: address of no_output_qs * 128 pointers
+ * @output_sbal_state_array: no_output_qs * 128 state info (for CQ or NULL)
  */
 struct qdio_initialize {
        struct ccw_device *cdev;
@@ -297,11 +367,12 @@ struct qdio_initialize {
        unsigned int no_output_qs;
        qdio_handler_t *input_handler;
        qdio_handler_t *output_handler;
-       void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
+       void (**queue_start_poll) (struct ccw_device *, int, unsigned long);
        int scan_threshold;
        unsigned long int_parm;
        void **input_sbal_addr_array;
        void **output_sbal_addr_array;
+       struct qdio_outbuf_state *output_sbal_state_array;
 };
 
 #define QDIO_STATE_INACTIVE            0x00000002 /* after qdio_cleanup */
@@ -316,6 +387,7 @@ struct qdio_initialize {
 extern int qdio_allocate(struct qdio_initialize *);
 extern int qdio_establish(struct qdio_initialize *);
 extern int qdio_activate(struct ccw_device *);
+extern void qdio_release_aob(struct qaob *);
 extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
                   unsigned int);
 extern int qdio_start_irq(struct ccw_device *, int);
index d5e2ef10537d9a93882e3bc38b857cb2edf4f764..fb90e8af663da76eec9c9d918402972545dd97bb 100644 (file)
 #define IPL_DEVICE        (*(unsigned long *)  (0x10400))
 #define INITRD_START      (*(unsigned long *)  (0x10408))
 #define INITRD_SIZE       (*(unsigned long *)  (0x10410))
+#define OLDMEM_BASE      (*(unsigned long *)  (0x10418))
+#define OLDMEM_SIZE      (*(unsigned long *)  (0x10420))
 #endif /* __s390x__ */
 #define COMMAND_LINE      ((char *)            (0x10480))
 
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY  1
+#define CHUNK_OLDMEM    4
+#define CHUNK_CRASHK    5
 
 struct mem_chunk {
        unsigned long addr;
@@ -48,6 +52,8 @@ extern int memory_end_set;
 extern unsigned long memory_end;
 
 void detect_memory_layout(struct mem_chunk chunk[]);
+void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
+                    unsigned long size, int type);
 
 #define PRIMARY_SPACE_MODE     0
 #define ACCESS_REGISTER_MODE   1
@@ -106,6 +112,7 @@ extern unsigned int user_mode;
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE      (32UL<<20)
+#define ZFCPDUMP_HSA_SIZE_MAX  (64UL<<20)
 
 /*
  * Console mode. Override with conmode=
@@ -138,6 +145,8 @@ extern char kernel_nss_name[];
 #define IPL_DEVICE        0x10400
 #define INITRD_START      0x10408
 #define INITRD_SIZE       0x10410
+#define OLDMEM_BASE      0x10418
+#define OLDMEM_SIZE      0x10420
 #endif /* __s390x__ */
 #define COMMAND_LINE      0x10480
 
index 6582f69f23899b4989c05b9aacf0fb6de4bed4c2..afb849e4bf4b57101bf4eead361df3030c40ad2e 100644 (file)
@@ -114,6 +114,8 @@ extern void pfault_fini(void);
 extern void cmma_init(void);
 extern int memcpy_real(void *, void *, size_t);
 extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
+extern int copy_to_user_real(void __user *dest, void *src, size_t count);
+extern int copy_from_user_real(void *dest, void __user *src, size_t count);
 
 #define finish_arch_switch(prev) do {                                       \
        set_fs(current->thread.mm_segment);                                  \
index 1a5dbb6f1495468c4c16dfc4695f4aaa10aa9698..c6ce7ca49351daec2db696d2501d572c8728b225 100644 (file)
@@ -101,7 +101,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    19      /* restore signal mask in do_signal() */
 #define TIF_SINGLE_STEP                20      /* This task is single stepped */
-#define TIF_FREEZE             21      /* thread is freezing for suspend */
 
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
@@ -117,8 +116,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SIE               (1<<TIF_SIE)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT             (1<<TIF_31BIT)
-#define _TIF_SINGLE_STEP       (1<<TIF_FREEZE)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
+#define _TIF_SINGLE_STEP       (1<<TIF_SINGLE_STEP)
 
 #ifdef CONFIG_64BIT
 #define is_32bit_task()                (test_thread_flag(TIF_31BIT))
index df3732249baafa3f0c30474d26da5243412890d1..dd4f076409190c22a0154e9bac693e7b2a75f3b9 100644 (file)
@@ -48,6 +48,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o)
 obj-$(CONFIG_DYNAMIC_FTRACE)   += ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
+obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
new file mode 100644 (file)
index 0000000..c63dd71
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * S390 kdump implementation
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <linux/crash_dump.h>
+#include <asm/lowcore.h>
+
+/*
+ * Copy one page from "oldmem"
+ *
+ * For the kdump reserved memory this functions performs a swap operation:
+ *  - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE].
+ *  - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+                        size_t csize, unsigned long offset, int userbuf)
+{
+       unsigned long src;
+       int rc;
+
+       if (!csize)
+               return 0;
+
+       src = (pfn << PAGE_SHIFT) + offset;
+       if (src < OLDMEM_SIZE)
+               src += OLDMEM_BASE;
+       else if (src > OLDMEM_BASE &&
+                src < OLDMEM_BASE + OLDMEM_SIZE)
+               src -= OLDMEM_BASE;
+       if (userbuf)
+               rc = copy_to_user_real((void __user *) buf, (void *) src,
+                                      csize);
+       else
+               rc = memcpy_real(buf, (void *) src, csize);
+       return rc < 0 ? rc : csize;
+}
index 068f8465c4ee07c0156978517f9efe88dcc5e96a..f297456dba7a9eb3282fe0377097e99f97a488d0 100644 (file)
@@ -396,17 +396,19 @@ static __init void detect_machine_facilities(void)
 static __init void rescue_initrd(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
+       unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
        /*
-        * Move the initrd right behind the bss section in case it starts
-        * within the bss section. So we don't overwrite it when the bss
-        * section gets cleared.
+        * Just like in case of IPL from VM reader we make sure there is a
+        * gap of 4MB between end of kernel and start of initrd.
+        * That way we can also be sure that saving an NSS will succeed,
+        * which however only requires different segments.
         */
        if (!INITRD_START || !INITRD_SIZE)
                return;
-       if (INITRD_START >= (unsigned long) __bss_stop)
+       if (INITRD_START >= min_initrd_addr)
                return;
-       memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE);
-       INITRD_START = (unsigned long) __bss_stop;
+       memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
+       INITRD_START = min_initrd_addr;
 #endif
 }
 
index 2d781bab37bbcefd69fd9af74e49a66ac0f42293..a6f0e466648dfa655048705e7e148b2dec3d1f73 100644 (file)
@@ -449,10 +449,22 @@ ENTRY(start)
 #
        .org    0x10000
 ENTRY(startup)
+       j       .Lep_startup_normal
+       .org    0x10008
+       .ascii  "S390EP"
+       .byte   0x00,0x01
+#
+# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
+#
+       .org    0x10010
+ENTRY(startup_kdump)
+       j       .Lep_startup_kdump
+.Lep_startup_normal:
        basr    %r13,0                  # get base
 .LPG0:
        xc      0x200(256),0x200        # partially clear lowcore
        xc      0x300(256),0x300
+       xc      0xe00(256),0xe00
        stck    __LC_LAST_UPDATE_CLOCK
        spt     5f-.LPG0(%r13)
        mvc     __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
@@ -534,6 +546,8 @@ ENTRY(startup)
        .align  8
 5:     .long   0x7fffffff,0xffffffff
 
+#include "head_kdump.S"
+
 #
 # params at 10400 (setup.h)
 #
@@ -541,6 +555,8 @@ ENTRY(startup)
        .long   0,0                     # IPL_DEVICE
        .long   0,0                     # INITRD_START
        .long   0,0                     # INITRD_SIZE
+       .long   0,0                     # OLDMEM_BASE
+       .long   0,0                     # OLDMEM_SIZE
 
        .org    COMMAND_LINE
        .byte   "root=/dev/ram0 ro"
diff --git a/arch/s390/kernel/head_kdump.S b/arch/s390/kernel/head_kdump.S
new file mode 100644 (file)
index 0000000..9d5ed9e
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * S390 kdump lowlevel functions (new kernel)
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#define DATAMOVER_ADDR 0x4000
+#define COPY_PAGE_ADDR 0x6000
+
+#ifdef CONFIG_CRASH_DUMP
+
+#
+# kdump entry (new kernel - not yet relocated)
+#
+# Note: This code has to be position independent
+#
+
+.align 2
+.Lep_startup_kdump:
+       basr    %r13,0
+.Lbase:
+       larl    %r2,.Lbase_addr                 # Check, if we have been
+       lg      %r2,0(%r2)                      # already relocated:
+       clgr    %r2,%r13                        #
+       jne     .Lrelocate                      # No : Start data mover
+       lghi    %r2,0                           # Yes: Start kdump kernel
+       brasl   %r14,startup_kdump_relocated
+
+.Lrelocate:
+       larl    %r4,startup
+       lg      %r2,0x418(%r4)                  # Get kdump base
+       lg      %r3,0x420(%r4)                  # Get kdump size
+
+       larl    %r10,.Lcopy_start               # Source of data mover
+       lghi    %r8,DATAMOVER_ADDR              # Target of data mover
+       mvc     0(256,%r8),0(%r10)              # Copy data mover code
+
+       agr     %r8,%r2                         # Copy data mover to
+       mvc     0(256,%r8),0(%r10)              # reserved mem
+
+       lghi    %r14,DATAMOVER_ADDR             # Jump to copied data mover
+       basr    %r14,%r14
+.Lbase_addr:
+       .quad   .Lbase
+
+#
+# kdump data mover code (runs at address DATAMOVER_ADDR)
+#
+# r2: kdump base address
+# r3: kdump size
+#
+.Lcopy_start:
+       basr    %r13,0                          # Base
+0:
+       lgr     %r11,%r2                        # Save kdump base address
+       lgr     %r12,%r2
+       agr     %r12,%r3                        # Compute kdump end address
+
+       lghi    %r5,0
+       lghi    %r10,COPY_PAGE_ADDR             # Load copy page address
+1:
+       mvc     0(256,%r10),0(%r5)              # Copy old kernel to tmp
+       mvc     0(256,%r5),0(%r11)              # Copy new kernel to old
+       mvc     0(256,%r11),0(%r10)             # Copy tmp to new
+       aghi    %r11,256
+       aghi    %r5,256
+       clgr    %r11,%r12
+       jl      1b
+
+       lg      %r14,.Lstartup_kdump-0b(%r13)
+       basr    %r14,%r14                       # Start relocated kernel
+.Lstartup_kdump:
+       .long   0x00000000,0x00000000 + startup_kdump_relocated
+.Lcopy_end:
+
+#
+# Startup of kdump (relocated new kernel)
+#
+.align 2
+startup_kdump_relocated:
+       basr    %r13,0
+0:
+       mvc     0(8,%r0),.Lrestart_psw-0b(%r13) # Setup restart PSW
+       mvc     464(16,%r0),.Lpgm_psw-0b(%r13)  # Setup pgm check PSW
+       lhi     %r1,1                           # Start new kernel
+       diag    %r1,%r1,0x308                   # with diag 308
+
+.Lno_diag308:                                  # No diag 308
+       sam31                                   # Switch to 31 bit addr mode
+       sr      %r1,%r1                         # Erase register r1
+       sr      %r2,%r2                         # Erase register r2
+       sigp    %r1,%r2,0x12                    # Switch to 31 bit arch mode
+       lpsw    0                               # Start new kernel...
+.align 8
+.Lrestart_psw:
+       .long   0x00080000,0x80000000 + startup
+.Lpgm_psw:
+       .quad   0x0000000180000000,0x0000000000000000 + .Lno_diag308
+#else
+.align 2
+.Lep_startup_kdump:
+#ifdef CONFIG_64BIT
+       larl    %r13,startup_kdump_crash
+       lpswe   0(%r13)
+.align 8
+startup_kdump_crash:
+       .quad   0x0002000080000000,0x0000000000000000 + startup_kdump_crash
+#else
+       basr    %r13,0
+0:     lpsw    startup_kdump_crash-0b(%r13)
+.align 8
+startup_kdump_crash:
+       .long   0x000a0000,0x00000000 + startup_kdump_crash
+#endif /* CONFIG_64BIT */
+#endif /* CONFIG_CRASH_DUMP */
index 04361d5a42794524419bd1898ac78ef755491449..3a606e0468504e06fefcc0de0e4c6e9dec5c9e4e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/ctype.h>
 #include <linux/fs.h>
 #include <linux/gfp.h>
+#include <linux/crash_dump.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -1220,7 +1221,7 @@ static int __init reipl_fcp_init(void)
        /* sysfs: create fcp kset for mixing attr group and bin attrs */
        reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
                                             &reipl_kset->kobj);
-       if (!reipl_kset) {
+       if (!reipl_fcp_kset) {
                free_page((unsigned long) reipl_block_fcp);
                return -ENOMEM;
        }
@@ -1738,6 +1739,9 @@ static struct kobj_attribute on_restart_attr =
 void do_restart(void)
 {
        smp_send_stop();
+#ifdef CONFIG_CRASH_DUMP
+       crash_kexec(NULL);
+#endif
        on_restart_trigger.action->fn(&on_restart_trigger);
        stop_run(&on_restart_trigger);
 }
index b09b9c62573e7bb77c145670dbd3e0e777ea8cdd..76b557d8f0c7745ca0866f36ffe91358e370c253 100644 (file)
 #include <asm/smp.h>
 #include <asm/reset.h>
 #include <asm/ipl.h>
+#include <asm/diag.h>
 
 typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long);
 
 extern const unsigned char relocate_kernel[];
 extern const unsigned long long relocate_kernel_len;
 
+#ifdef CONFIG_CRASH_DUMP
+
+#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
+
+#ifndef NT_FPREGSET
+#define NT_FPREGSET 2
+#endif
+
+/*
+ * fpregset ELF Note
+ */
+struct nt_fpregset_64 {
+       u32     fpc;
+       u32     pad;
+       u64     fprs[16];
+} __packed;
+
+/*
+ * Initialize ELF note
+ */
+static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len,
+                    const char *name)
+{
+       Elf64_Nhdr *note;
+       u64 len;
+
+       note = (Elf64_Nhdr *)buf;
+       note->n_namesz = strlen(name) + 1;
+       note->n_descsz = d_len;
+       note->n_type = type;
+       len = sizeof(Elf64_Nhdr);
+
+       memcpy(buf + len, name, note->n_namesz);
+       len = ROUNDUP(len + note->n_namesz, 4);
+
+       memcpy(buf + len, desc, note->n_descsz);
+       len = ROUNDUP(len + note->n_descsz, 4);
+
+       return PTR_ADD(buf, len);
+}
+
+/*
+ * Initialize prstatus note
+ */
+static void *nt_prstatus(void *ptr, struct save_area *sa)
+{
+       struct elf_prstatus nt_prstatus;
+       static int cpu_nr = 1;
+
+       memset(&nt_prstatus, 0, sizeof(nt_prstatus));
+       memcpy(&nt_prstatus.pr_reg.gprs, sa->gp_regs, sizeof(sa->gp_regs));
+       memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
+       memcpy(&nt_prstatus.pr_reg.acrs, sa->acc_regs, sizeof(sa->acc_regs));
+       nt_prstatus.pr_pid = cpu_nr;
+       cpu_nr++;
+
+       return nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus),
+                        "CORE");
+}
+
+/*
+ * Initialize fpregset (floating point) note
+ */
+static void *nt_fpregset(void *ptr, struct save_area *sa)
+{
+       struct nt_fpregset_64 nt_fpregset;
+
+       memset(&nt_fpregset, 0, sizeof(nt_fpregset));
+       memcpy(&nt_fpregset.fpc, &sa->fp_ctrl_reg, sizeof(sa->fp_ctrl_reg));
+       memcpy(&nt_fpregset.fprs, &sa->fp_regs, sizeof(sa->fp_regs));
+
+       return nt_init(ptr, NT_FPREGSET, &nt_fpregset, sizeof(nt_fpregset),
+                        "CORE");
+}
+
+/*
+ * Initialize timer note
+ */
+static void *nt_s390_timer(void *ptr, struct save_area *sa)
+{
+       return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer),
+                        KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize TOD clock comparator note
+ */
+static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa)
+{
+       return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp,
+                      sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize TOD programmable register note
+ */
+static void *nt_s390_tod_preg(void *ptr, struct save_area *sa)
+{
+       return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg,
+                      sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize control register note
+ */
+static void *nt_s390_ctrs(void *ptr, struct save_area *sa)
+{
+       return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs,
+                      sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize prefix register note
+ */
+static void *nt_s390_prefix(void *ptr, struct save_area *sa)
+{
+       return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg,
+                        sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Final empty node
+ */
+static void nt_final(void *ptr)
+{
+       memset(ptr, 0, sizeof(struct elf_note));
+}
+
+/*
+ * Add create ELF notes for CPU
+ */
+static void add_elf_notes(int cpu)
+{
+       struct save_area *sa = (void *) 4608 + store_prefix();
+       void *ptr;
+
+       memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa));
+       ptr = (u64 *) per_cpu_ptr(crash_notes, cpu);
+       ptr = nt_prstatus(ptr, sa);
+       ptr = nt_fpregset(ptr, sa);
+       ptr = nt_s390_timer(ptr, sa);
+       ptr = nt_s390_tod_cmp(ptr, sa);
+       ptr = nt_s390_tod_preg(ptr, sa);
+       ptr = nt_s390_ctrs(ptr, sa);
+       ptr = nt_s390_prefix(ptr, sa);
+       nt_final(ptr);
+}
+
+/*
+ * Store status of next available physical CPU
+ */
+static int store_status_next(int start_cpu, int this_cpu)
+{
+       struct save_area *sa = (void *) 4608 + store_prefix();
+       int cpu, rc;
+
+       for (cpu = start_cpu; cpu < 65536; cpu++) {
+               if (cpu == this_cpu)
+                       continue;
+               do {
+                       rc = raw_sigp(cpu, sigp_stop_and_store_status);
+               } while (rc == sigp_busy);
+               if (rc != sigp_order_code_accepted)
+                       continue;
+               if (sa->pref_reg)
+                       return cpu;
+       }
+       return -1;
+}
+
+/*
+ * Initialize CPU ELF notes
+ */
+void setup_regs(void)
+{
+       int cpu, this_cpu, phys_cpu = 0, first = 1;
+
+       this_cpu = stap();
+
+       store_status();
+       if (!S390_lowcore.prefixreg_save_area)
+               first = 0;
+       for_each_online_cpu(cpu) {
+               if (first) {
+                       add_elf_notes(cpu);
+                       first = 0;
+                       continue;
+               }
+               phys_cpu = store_status_next(phys_cpu, this_cpu);
+               if (phys_cpu == -1)
+                       return;
+               add_elf_notes(cpu);
+               phys_cpu++;
+       }
+}
+
+/*
+ * Start kdump
+ */
+static void __machine_kdump(void *image)
+{
+       int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
+
+       pfault_fini();
+       s390_reset_system();
+       __load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
+       setup_regs();
+       start_kdump(1);
+       disabled_wait((unsigned long) __builtin_return_address(0));
+}
+
+#endif
+
+/*
+ * Give back memory to hypervisor before new kdump is loaded
+ */
+static int machine_kexec_prepare_kdump(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+       if (MACHINE_IS_VM)
+               diag10_range(PFN_DOWN(crashk_res.start),
+                            PFN_DOWN(crashk_res.end - crashk_res.start + 1));
+       return 0;
+#else
+       return -EINVAL;
+#endif
+}
+
 int machine_kexec_prepare(struct kimage *image)
 {
        void *reboot_code_buffer;
@@ -35,6 +265,9 @@ int machine_kexec_prepare(struct kimage *image)
        if (ipl_flags & IPL_NSS_VALID)
                return -ENOSYS;
 
+       if (image->type == KEXEC_TYPE_CRASH)
+               return machine_kexec_prepare_kdump();
+
        /* We don't support anything but the default image type for now. */
        if (image->type != KEXEC_TYPE_DEFAULT)
                return -EINVAL;
@@ -73,6 +306,18 @@ static void __machine_kexec(void *data)
 void machine_kexec(struct kimage *image)
 {
        tracer_disable();
+#ifdef CONFIG_CRASH_DUMP
+       if (image->type == KEXEC_TYPE_CRASH) {
+               int (*start_kdump)(int) = (void *)image->start;
+               int rc;
+               __arch_local_irq_stnsm(0xfb); /* disable DAT */
+               rc = start_kdump(0);
+               __arch_local_irq_stosm(0x04); /* enable DAT */
+               if (rc)
+                       return;
+               smp_switch_to_ipl_cpu(__machine_kdump, image);
+       }
+#endif
        smp_send_stop();
        smp_switch_to_ipl_cpu(__machine_kexec, image);
 }
index 0fbe4e32f7ba298c83b22dfe831b66545fba8ace..19b4568f4ceec4ada5aa86db7251a2b8dc0afa75 100644 (file)
@@ -62,3 +62,72 @@ void detect_memory_layout(struct mem_chunk chunk[])
        arch_local_irq_restore(flags);
 }
 EXPORT_SYMBOL(detect_memory_layout);
+
+/*
+ * Create memory hole with given address, size, and type
+ */
+void create_mem_hole(struct mem_chunk chunks[], unsigned long addr,
+                    unsigned long size, int type)
+{
+       unsigned long start, end, new_size;
+       int i;
+
+       for (i = 0; i < MEMORY_CHUNKS; i++) {
+               if (chunks[i].size == 0)
+                       continue;
+               if (addr + size < chunks[i].addr)
+                       continue;
+               if (addr >= chunks[i].addr + chunks[i].size)
+                       continue;
+               start = max(addr, chunks[i].addr);
+               end = min(addr + size, chunks[i].addr + chunks[i].size);
+               new_size = end - start;
+               if (new_size == 0)
+                       continue;
+               if (start == chunks[i].addr &&
+                   end == chunks[i].addr + chunks[i].size) {
+                       /* Remove chunk */
+                       chunks[i].type = type;
+               } else if (start == chunks[i].addr) {
+                       /* Make chunk smaller at start */
+                       if (i >= MEMORY_CHUNKS - 1)
+                               panic("Unable to create memory hole");
+                       memmove(&chunks[i + 1], &chunks[i],
+                               sizeof(struct mem_chunk) *
+                               (MEMORY_CHUNKS - (i + 1)));
+                       chunks[i + 1].addr = chunks[i].addr + new_size;
+                       chunks[i + 1].size = chunks[i].size - new_size;
+                       chunks[i].size = new_size;
+                       chunks[i].type = type;
+                       i += 1;
+               } else if (end == chunks[i].addr + chunks[i].size) {
+                       /* Make chunk smaller at end */
+                       if (i >= MEMORY_CHUNKS - 1)
+                               panic("Unable to create memory hole");
+                       memmove(&chunks[i + 1], &chunks[i],
+                               sizeof(struct mem_chunk) *
+                               (MEMORY_CHUNKS - (i + 1)));
+                       chunks[i + 1].addr = start;
+                       chunks[i + 1].size = new_size;
+                       chunks[i + 1].type = type;
+                       chunks[i].size -= new_size;
+                       i += 1;
+               } else {
+                       /* Create memory hole */
+                       if (i >= MEMORY_CHUNKS - 2)
+                               panic("Unable to create memory hole");
+                       memmove(&chunks[i + 2], &chunks[i],
+                               sizeof(struct mem_chunk) *
+                               (MEMORY_CHUNKS - (i + 2)));
+                       chunks[i + 1].addr = addr;
+                       chunks[i + 1].size = size;
+                       chunks[i + 1].type = type;
+                       chunks[i + 2].addr = addr + size;
+                       chunks[i + 2].size =
+                               chunks[i].addr + chunks[i].size - (addr + size);
+                       chunks[i + 2].type = chunks[i].type;
+                       chunks[i].size = addr - chunks[i].addr;
+                       i += 2;
+               }
+       }
+}
index 7b371c37061de424892068ea7838a946f4f95e14..9c8d72edf598b0b3ec15e57cff1d7707b151826b 100644 (file)
@@ -42,6 +42,9 @@
 #include <linux/reboot.h>
 #include <linux/topology.h>
 #include <linux/ftrace.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
+#include <linux/memory.h>
 
 #include <asm/ipl.h>
 #include <asm/uaccess.h>
@@ -57,6 +60,7 @@
 #include <asm/ebcdic.h>
 #include <asm/compat.h>
 #include <asm/kvm_virtio.h>
+#include <asm/diag.h>
 
 long psw_kernel_bits   = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
                           PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
@@ -435,6 +439,9 @@ static void __init setup_resources(void)
        for (i = 0; i < MEMORY_CHUNKS; i++) {
                if (!memory_chunk[i].size)
                        continue;
+               if (memory_chunk[i].type == CHUNK_OLDMEM ||
+                   memory_chunk[i].type == CHUNK_CRASHK)
+                       continue;
                res = alloc_bootmem_low(sizeof(*res));
                res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
                switch (memory_chunk[i].type) {
@@ -479,6 +486,7 @@ static void __init setup_memory_end(void)
        unsigned long max_mem;
        int i;
 
+
 #ifdef CONFIG_ZFCPDUMP
        if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
                memory_end = ZFCPDUMP_HSA_SIZE;
@@ -550,6 +558,182 @@ static void __init setup_restart_psw(void)
        copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
 }
 
+#ifdef CONFIG_CRASH_DUMP
+
+/*
+ * Find suitable location for crashkernel memory
+ */
+static unsigned long __init find_crash_base(unsigned long crash_size,
+                                           char **msg)
+{
+       unsigned long crash_base;
+       struct mem_chunk *chunk;
+       int i;
+
+       if (memory_chunk[0].size < crash_size) {
+               *msg = "first memory chunk must be at least crashkernel size";
+               return 0;
+       }
+       if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE))
+               return OLDMEM_BASE;
+
+       for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
+               chunk = &memory_chunk[i];
+               if (chunk->size == 0)
+                       continue;
+               if (chunk->type != CHUNK_READ_WRITE)
+                       continue;
+               if (chunk->size < crash_size)
+                       continue;
+               crash_base = (chunk->addr + chunk->size) - crash_size;
+               if (crash_base < crash_size)
+                       continue;
+               if (crash_base < ZFCPDUMP_HSA_SIZE_MAX)
+                       continue;
+               if (crash_base < (unsigned long) INITRD_START + INITRD_SIZE)
+                       continue;
+               return crash_base;
+       }
+       *msg = "no suitable area found";
+       return 0;
+}
+
+/*
+ * Check if crash_base and crash_size is valid
+ */
+static int __init verify_crash_base(unsigned long crash_base,
+                                   unsigned long crash_size,
+                                   char **msg)
+{
+       struct mem_chunk *chunk;
+       int i;
+
+       /*
+        * Because we do the swap to zero, we must have at least 'crash_size'
+        * bytes free space before crash_base
+        */
+       if (crash_size > crash_base) {
+               *msg = "crashkernel offset must be greater than size";
+               return -EINVAL;
+       }
+
+       /* First memory chunk must be at least crash_size */
+       if (memory_chunk[0].size < crash_size) {
+               *msg = "first memory chunk must be at least crashkernel size";
+               return -EINVAL;
+       }
+       /* Check if we fit into the respective memory chunk */
+       for (i = 0; i < MEMORY_CHUNKS; i++) {
+               chunk = &memory_chunk[i];
+               if (chunk->size == 0)
+                       continue;
+               if (crash_base < chunk->addr)
+                       continue;
+               if (crash_base >= chunk->addr + chunk->size)
+                       continue;
+               /* we have found the memory chunk */
+               if (crash_base + crash_size > chunk->addr + chunk->size) {
+                       *msg = "selected memory chunk is too small for "
+                               "crashkernel memory";
+                       return -EINVAL;
+               }
+               return 0;
+       }
+       *msg = "invalid memory range specified";
+       return -EINVAL;
+}
+
+/*
+ * Reserve kdump memory by creating a memory hole in the mem_chunk array
+ */
+static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size,
+                                        int type)
+{
+
+       create_mem_hole(memory_chunk, addr, size, type);
+}
+
+/*
+ * When kdump is enabled, we have to ensure that no memory from
+ * the area [0 - crashkernel memory size] is set offline
+ */
+static int kdump_mem_notifier(struct notifier_block *nb,
+                             unsigned long action, void *data)
+{
+       struct memory_notify *arg = data;
+
+       if (arg->start_pfn >= PFN_DOWN(crashk_res.end - crashk_res.start + 1))
+               return NOTIFY_OK;
+       return NOTIFY_BAD;
+}
+
+static struct notifier_block kdump_mem_nb = {
+       .notifier_call = kdump_mem_notifier,
+};
+
+#endif
+
+/*
+ * Make sure that oldmem, where the dump is stored, is protected
+ */
+static void reserve_oldmem(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+       if (!is_kdump_kernel())
+               return;
+
+       reserve_kdump_bootmem(OLDMEM_BASE, OLDMEM_SIZE, CHUNK_OLDMEM);
+       reserve_kdump_bootmem(OLDMEM_SIZE, memory_end - OLDMEM_SIZE,
+                             CHUNK_OLDMEM);
+       if (OLDMEM_BASE + OLDMEM_SIZE == real_memory_size)
+               saved_max_pfn = PFN_DOWN(OLDMEM_BASE) - 1;
+       else
+               saved_max_pfn = PFN_DOWN(real_memory_size) - 1;
+#endif
+}
+
+/*
+ * Reserve memory for kdump kernel to be loaded with kexec
+ */
+static void __init reserve_crashkernel(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+       unsigned long long crash_base, crash_size;
+       char *msg;
+       int rc;
+
+       rc = parse_crashkernel(boot_command_line, memory_end, &crash_size,
+                              &crash_base);
+       if (rc || crash_size == 0)
+               return;
+       crash_base = PAGE_ALIGN(crash_base);
+       crash_size = PAGE_ALIGN(crash_size);
+       if (register_memory_notifier(&kdump_mem_nb))
+               return;
+       if (!crash_base)
+               crash_base = find_crash_base(crash_size, &msg);
+       if (!crash_base) {
+               pr_info("crashkernel reservation failed: %s\n", msg);
+               unregister_memory_notifier(&kdump_mem_nb);
+               return;
+       }
+       if (verify_crash_base(crash_base, crash_size, &msg)) {
+               pr_info("crashkernel reservation failed: %s\n", msg);
+               unregister_memory_notifier(&kdump_mem_nb);
+               return;
+       }
+       if (!is_kdump_kernel() && MACHINE_IS_VM)
+               diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
+       crashk_res.start = crash_base;
+       crashk_res.end = crash_base + crash_size - 1;
+       insert_resource(&iomem_resource, &crashk_res);
+       reserve_kdump_bootmem(crash_base, crash_size, CHUNK_READ_WRITE);
+       pr_info("Reserving %lluMB of memory at %lluMB "
+               "for crashkernel (System RAM: %luMB)\n",
+               crash_size >> 20, crash_base >> 20, memory_end >> 20);
+#endif
+}
+
 static void __init
 setup_memory(void)
 {
@@ -580,6 +764,14 @@ setup_memory(void)
                if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
                        start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
 
+#ifdef CONFIG_CRASH_DUMP
+                       if (is_kdump_kernel()) {
+                               /* Move initrd behind kdump oldmem */
+                               if (start + INITRD_SIZE > OLDMEM_BASE &&
+                                   start < OLDMEM_BASE + OLDMEM_SIZE)
+                                       start = OLDMEM_BASE + OLDMEM_SIZE;
+                       }
+#endif
                        if (start + INITRD_SIZE > memory_end) {
                                pr_err("initrd extends beyond end of "
                                       "memory (0x%08lx > 0x%08lx) "
@@ -635,6 +827,10 @@ setup_memory(void)
        reserve_bootmem((unsigned long)_stext,
                        PFN_PHYS(start_pfn) - (unsigned long)_stext,
                        BOOTMEM_DEFAULT);
+       if (crashk_res.start)
+               reserve_bootmem(crashk_res.start,
+                               crashk_res.end - crashk_res.start + 1,
+                               BOOTMEM_DEFAULT);
        /*
         * Reserve the bootmem bitmap itself as well. We do this in two
         * steps (first step was init_bootmem()) because this catches
@@ -644,6 +840,11 @@ setup_memory(void)
        reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size,
                        BOOTMEM_DEFAULT);
 
+#ifdef CONFIG_CRASH_DUMP
+       if (is_kdump_kernel())
+               reserve_bootmem(elfcorehdr_addr - OLDMEM_BASE,
+                               PAGE_ALIGN(elfcorehdr_size), BOOTMEM_DEFAULT);
+#endif
 #ifdef CONFIG_BLK_DEV_INITRD
        if (INITRD_START && INITRD_SIZE) {
                if (INITRD_START + INITRD_SIZE <= memory_end) {
@@ -812,6 +1013,8 @@ setup_arch(char **cmdline_p)
        setup_ipl();
        setup_memory_end();
        setup_addressing_mode();
+       reserve_oldmem();
+       reserve_crashkernel();
        setup_memory();
        setup_resources();
        setup_restart_psw();
index cf9e5c6d55274ce2da221e5f258fab08c58ee21e..b6f9afed74ec8e3c7e1082c82185e491b8b213aa 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/pfn.h>
+#include <linux/mm.h>
 #include <asm/system.h>
 
 /*
  */
 extern const void __nosave_begin, __nosave_end;
 
+/*
+ * The restore of the saved pages in an hibernation image will set
+ * the change and referenced bits in the storage key for each page.
+ * Overindication of the referenced bits after an hibernation cycle
+ * does not cause any harm but the overindication of the change bits
+ * would cause trouble.
+ * Use the ARCH_SAVE_PAGE_KEYS hooks to save the storage key of each
+ * page to the most significant byte of the associated page frame
+ * number in the hibernation image.
+ */
+
+/*
+ * Key storage is allocated as a linked list of pages.
+ * The size of the keys array is (PAGE_SIZE - sizeof(long))
+ */
+struct page_key_data {
+       struct page_key_data *next;
+       unsigned char data[];
+};
+
+#define PAGE_KEY_DATA_SIZE     (PAGE_SIZE - sizeof(struct page_key_data *))
+
+static struct page_key_data *page_key_data;
+static struct page_key_data *page_key_rp, *page_key_wp;
+static unsigned long page_key_rx, page_key_wx;
+
+/*
+ * For each page in the hibernation image one additional byte is
+ * stored in the most significant byte of the page frame number.
+ * On suspend no additional memory is required but on resume the
+ * keys need to be memorized until the page data has been restored.
+ * Only then can the storage keys be set to their old state.
+ */
+unsigned long page_key_additional_pages(unsigned long pages)
+{
+       return DIV_ROUND_UP(pages, PAGE_KEY_DATA_SIZE);
+}
+
+/*
+ * Free page_key_data list of arrays.
+ */
+void page_key_free(void)
+{
+       struct page_key_data *pkd;
+
+       while (page_key_data) {
+               pkd = page_key_data;
+               page_key_data = pkd->next;
+               free_page((unsigned long) pkd);
+       }
+}
+
+/*
+ * Allocate page_key_data list of arrays with enough room to store
+ * one byte for each page in the hibernation image.
+ */
+int page_key_alloc(unsigned long pages)
+{
+       struct page_key_data *pk;
+       unsigned long size;
+
+       size = DIV_ROUND_UP(pages, PAGE_KEY_DATA_SIZE);
+       while (size--) {
+               pk = (struct page_key_data *) get_zeroed_page(GFP_KERNEL);
+               if (!pk) {
+                       page_key_free();
+                       return -ENOMEM;
+               }
+               pk->next = page_key_data;
+               page_key_data = pk;
+       }
+       page_key_rp = page_key_wp = page_key_data;
+       page_key_rx = page_key_wx = 0;
+       return 0;
+}
+
+/*
+ * Save the storage key into the upper 8 bits of the page frame number.
+ */
+void page_key_read(unsigned long *pfn)
+{
+       unsigned long addr;
+
+       addr = (unsigned long) page_address(pfn_to_page(*pfn));
+       *(unsigned char *) pfn = (unsigned char) page_get_storage_key(addr);
+}
+
+/*
+ * Extract the storage key from the upper 8 bits of the page frame number
+ * and store it in the page_key_data list of arrays.
+ */
+void page_key_memorize(unsigned long *pfn)
+{
+       page_key_wp->data[page_key_wx] = *(unsigned char *) pfn;
+       *(unsigned char *) pfn = 0;
+       if (++page_key_wx < PAGE_KEY_DATA_SIZE)
+               return;
+       page_key_wp = page_key_wp->next;
+       page_key_wx = 0;
+}
+
+/*
+ * Get the next key from the page_key_data list of arrays and set the
+ * storage key of the page referred by @address. If @address refers to
+ * a "safe" page the swsusp_arch_resume code will transfer the storage
+ * key from the buffer page to the original page.
+ */
+void page_key_write(void *address)
+{
+       page_set_storage_key((unsigned long) address,
+                            page_key_rp->data[page_key_rx], 0);
+       if (++page_key_rx >= PAGE_KEY_DATA_SIZE)
+               return;
+       page_key_rp = page_key_rp->next;
+       page_key_rx = 0;
+}
+
 int pfn_is_nosave(unsigned long pfn)
 {
        unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
index 51bcdb50a23011a520afb29b092cc8aa871d1c80..acb78cdee896c1b9fe9c2d74ce212b254044a461 100644 (file)
@@ -136,11 +136,14 @@ ENTRY(swsusp_arch_resume)
 0:
        lg      %r2,8(%r1)
        lg      %r4,0(%r1)
+       iske    %r0,%r4
        lghi    %r3,PAGE_SIZE
        lghi    %r5,PAGE_SIZE
 1:
        mvcle   %r2,%r4,0
        jo      1b
+       lg      %r2,8(%r1)
+       sske    %r0,%r2
        lg      %r1,16(%r1)
        ltgr    %r1,%r1
        jnz     0b
index 5dbbaa6e594c8192302a23525bfcbfb05685c50e..d22a81bfb5b49a1598960099dfd5895638eeeaae 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <asm/system.h>
 
 /*
@@ -60,6 +61,9 @@ long probe_kernel_write(void *dst, const void *src, size_t size)
        return copied < 0 ? -EFAULT : 0;
 }
 
+/*
+ * Copy memory in real mode (kernel to kernel)
+ */
 int memcpy_real(void *dest, void *src, size_t count)
 {
        register unsigned long _dest asm("2") = (unsigned long) dest;
@@ -101,3 +105,56 @@ void copy_to_absolute_zero(void *dest, void *src, size_t count)
        __ctl_load(cr0, 0, 0);
        preempt_enable();
 }
+
+/*
+ * Copy memory from kernel (real) to user (virtual)
+ */
+int copy_to_user_real(void __user *dest, void *src, size_t count)
+{
+       int offs = 0, size, rc;
+       char *buf;
+
+       buf = (char *) __get_free_page(GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       rc = -EFAULT;
+       while (offs < count) {
+               size = min(PAGE_SIZE, count - offs);
+               if (memcpy_real(buf, src + offs, size))
+                       goto out;
+               if (copy_to_user(dest + offs, buf, size))
+                       goto out;
+               offs += size;
+       }
+       rc = 0;
+out:
+       free_page((unsigned long) buf);
+       return rc;
+}
+
+/*
+ * Copy memory from user (virtual) to kernel (real)
+ */
+int copy_from_user_real(void *dest, void __user *src, size_t count)
+{
+       int offs = 0, size, rc;
+       char *buf;
+
+       buf = (char *) __get_free_page(GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       rc = -EFAULT;
+       while (offs < count) {
+               size = min(PAGE_SIZE, count - offs);
+               if (copy_from_user(buf, src + offs, size))
+                       goto out;
+               if (memcpy_real(dest + offs, buf, size))
+                       goto out;
+               offs += size;
+       }
+       rc = 0;
+out:
+       free_page((unsigned long) buf);
+       return rc;
+}
+
index 781ff51695602cf215bf462fe2c1d9358d26575d..4799383e2df9551c45ad69f08f57455bb9771dc0 100644 (file)
@@ -335,6 +335,9 @@ void __init vmem_map_init(void)
        ro_start = ((unsigned long)&_stext) & PAGE_MASK;
        ro_end = PFN_ALIGN((unsigned long)&_eshared);
        for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
+               if (memory_chunk[i].type == CHUNK_CRASHK ||
+                   memory_chunk[i].type == CHUNK_OLDMEM)
+                       continue;
                start = memory_chunk[i].addr;
                end = memory_chunk[i].addr + memory_chunk[i].size;
                if (start >= ro_end || end <= ro_start)
@@ -368,6 +371,9 @@ static int __init vmem_convert_memory_chunk(void)
        for (i = 0; i < MEMORY_CHUNKS; i++) {
                if (!memory_chunk[i].size)
                        continue;
+               if (memory_chunk[i].type == CHUNK_CRASHK ||
+                   memory_chunk[i].type == CHUNK_OLDMEM)
+                       continue;
                seg = kzalloc(sizeof(*seg), GFP_KERNEL);
                if (!seg)
                        panic("Out of memory...\n");
index b24d69d509e7d7ccfe7e78454fca4014b5c286a4..22faf2a2d8fc063f537892f366e453cfe0c183fa 100644 (file)
@@ -248,6 +248,10 @@ static struct renesas_usbhs_platform_info usbhs_info = {
        .driver_param = {
                .buswait_bwait          = 4,
                .detection_delay        = 5,
+               .d0_tx_id = SHDMA_SLAVE_USB1D0_TX,
+               .d0_rx_id = SHDMA_SLAVE_USB1D0_RX,
+               .d1_tx_id = SHDMA_SLAVE_USB1D1_TX,
+               .d1_rx_id = SHDMA_SLAVE_USB1D1_RX,
        },
 };
 
index b97baf81a87bb8afda8a4d1558786cd14afa4f0b..2d3679b2447f262c4c83eebe5e6ff89890c2e0a2 100644 (file)
@@ -123,7 +123,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
 struct perf_event;
 struct perf_sample_data;
 
-extern void ptrace_triggered(struct perf_event *bp, int nmi,
+extern void ptrace_triggered(struct perf_event *bp,
                      struct perf_sample_data *data, struct pt_regs *regs);
 
 #define task_pt_regs(task) \
index ea2d5089de1ed27492c5fca9aefd195a2f787831..20ee40af16e9b5fae4b6bf7e4f29ba27c6fe698c 100644 (file)
@@ -122,7 +122,6 @@ extern void init_thread_xstate(void);
 #define TIF_SYSCALL_TRACEPOINT 8       /* for ftrace syscall instrumentation */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
-#define TIF_FREEZE             19      /* Freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
@@ -133,7 +132,6 @@ extern void init_thread_xstate(void);
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACEPOINT        (1 << TIF_SYSCALL_TRACEPOINT)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 /*
  * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within 2 bytes, or we
index 32114e0941ae7616aae53de88a9f79b895e973db..db4ecd731a003792783ddbc524fcc60f020d4bf7 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/atomic.h>
 #include <asm/smp.h>
 
-static void (*pm_idle)(void);
+void (*pm_idle)(void);
 
 static int hlt_counter;
 
index fb23fd6b186a1b0ffeeace7cca9e9a5a136fbfa6..9bc241afc436dfadf837f956eab3b87e846363d3 100644 (file)
@@ -2,9 +2,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
@@ -42,9 +40,10 @@ CONFIG_SCSI_QLOGICPTI=m
 CONFIG_SCSI_SUNESP=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
+CONFIG_NET_VENDOR_AMD=y
 CONFIG_SUNLANCE=y
+CONFIG_NET_VENDOR_SUN=y
 CONFIG_HAPPYMEAL=m
 CONFIG_SUNBMAC=m
 CONFIG_SUNQE=m
@@ -64,26 +63,22 @@ CONFIG_SERIAL_SUNSU=y
 CONFIG_SERIAL_SUNSU_CONSOLE=y
 CONFIG_SPI=y
 CONFIG_SPI_XILINX=m
-CONFIG_SPI_XILINX_PLTFM=m
 CONFIG_SUN_OPENPROMIO=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_ISO9660_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_ROMFS_FS=m
 CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
-CONFIG_RPCSEC_GSS_KRB5=m
 CONFIG_NLS=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_KGDB=y
 CONFIG_KGDB_TESTS=y
 CONFIG_CRYPTO_NULL=m
index 3c1e85807403819d814f7495bef78d30a4cab0e7..5732728a846e90475afa67e610d3047b6c90df18 100644 (file)
@@ -37,8 +37,6 @@ CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
 CONFIG_IP_MROUTE=y
 CONFIG_IP_PIMSM_V1=y
 CONFIG_IP_PIMSM_V2=y
@@ -95,17 +93,19 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
+CONFIG_NET_VENDOR_AMD=y
 CONFIG_SUNLANCE=m
+CONFIG_NET_VENDOR_BROADCOM=y
+CONFIG_BNX2=m
+CONFIG_TIGON3=m
+CONFIG_NET_VENDOR_INTEL=y
+CONFIG_E1000=m
+CONFIG_E1000E=m
+CONFIG_NET_VENDOR_SUN=y
 CONFIG_HAPPYMEAL=m
 CONFIG_SUNGEM=m
 CONFIG_SUNVNET=m
-CONFIG_NET_PCI=y
-CONFIG_E1000=m
-CONFIG_E1000E=m
-CONFIG_TIGON3=m
-CONFIG_BNX2=m
 CONFIG_NIU=m
 # CONFIG_WLAN is not set
 CONFIG_PPP=m
@@ -126,13 +126,13 @@ CONFIG_INPUT_SPARCSPKR=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_PCIPS2=m
 CONFIG_SERIO_RAW=m
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_SUNSU=y
 CONFIG_SERIAL_SUNSU_CONSOLE=y
 CONFIG_SERIAL_SUNSAB=y
 CONFIG_SERIAL_SUNSAB_CONSOLE=y
 CONFIG_SERIAL_SUNHV=y
-# CONFIG_LEGACY_PTYS is not set
 CONFIG_FB=y
 CONFIG_FB_TILEBLITTING=y
 CONFIG_FB_SBUS=y
@@ -206,10 +206,8 @@ CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOCKUP_DETECTOR=y
-CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_SCHEDSTATS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_KEYS=y
index a1607d1803547cd075090f6835839e0f3236910e..69914d748130a9b151d4f4c8f17a496fe2d5d39e 100644 (file)
@@ -45,6 +45,19 @@ typedef struct {
        int                     si_mask;
 } __siginfo32_t;
 
+#define __SIGC_MAXWIN  7
+
+typedef struct {
+       unsigned long locals[8];
+       unsigned long ins[8];
+} __siginfo_reg_window;
+
+typedef struct {
+       int                     wsaved;
+       __siginfo_reg_window    reg_window[__SIGC_MAXWIN];
+       unsigned long           rwbuf_stkptrs[__SIGC_MAXWIN];
+} __siginfo_rwin_t;
+
 #ifdef CONFIG_SPARC64
 typedef struct {
        unsigned   int si_float_regs [64];
@@ -73,6 +86,7 @@ struct sigcontext {
                unsigned long   ss_size;
        }                       sigc_stack;
        unsigned long           sigc_mask;
+       __siginfo_rwin_t *      sigc_rwin_save;
 };
 
 #else
index fa5753233410baaf9c489fe7968675b418fcdde1..5cc5888ad5a3e8f54d153e2d0f4eca26ef3df509 100644 (file)
@@ -133,7 +133,6 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
 #define TIF_POLLING_NRFLAG     9       /* true if poll_idle() is polling
                                         * TIF_NEED_RESCHED */
 #define TIF_MEMDIE             10      /* is terminating due to OOM killer */
-#define TIF_FREEZE             11      /* is freezing for suspend */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -147,7 +146,6 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
 #define _TIF_DO_NOTIFY_RESUME_MASK     (_TIF_NOTIFY_RESUME | \
                                         _TIF_SIGPENDING | \
                                         _TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #endif /* __KERNEL__ */
 
index 60d86be1a53381bd0fd09c3b133c0c0c80e60bd1..01d057fe6a3f498032692792c4dfd7b012440e5b 100644 (file)
@@ -225,7 +225,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
 /* flag bit 12 is available */
 #define TIF_MEMDIE             13      /* is terminating due to OOM killer */
 #define TIF_POLLING_NRFLAG     14
-#define TIF_FREEZE             15      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
@@ -237,7 +236,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #define _TIF_USER_WORK_MASK    ((0xff << TI_FLAG_WSAVED_SHIFT) | \
                                 _TIF_DO_NOTIFY_RESUME_MASK | \
index b90b4a1d070ad3e33b6b2ba6e3de59327c59677d..cb85458f89d2c495dd80e6f649e865eea6d71929 100644 (file)
@@ -32,6 +32,7 @@ obj-$(CONFIG_SPARC32)   += sun4m_irq.o sun4c_irq.o sun4d_irq.o
 
 obj-y                   += process_$(BITS).o
 obj-y                   += signal_$(BITS).o
+obj-y                   += sigutil_$(BITS).o
 obj-$(CONFIG_SPARC32)   += ioport.o
 obj-y                   += setup_$(BITS).o
 obj-y                   += idprom.o
index 75fad425e249bc40559f98d14ead5699839bbbb8..1ba95aff5d5958cdeb1142a24f18ea0c63717722 100644 (file)
@@ -29,6 +29,8 @@
 #include <asm/visasm.h>
 #include <asm/compat_signal.h>
 
+#include "sigutil.h"
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 /* This magic should be in g_upper[0] for all upper parts
@@ -44,14 +46,14 @@ typedef struct {
 struct signal_frame32 {
        struct sparc_stackf32   ss;
        __siginfo32_t           info;
-       /* __siginfo_fpu32_t * */ u32 fpu_save;
+       /* __siginfo_fpu_t * */ u32 fpu_save;
        unsigned int            insns[2];
        unsigned int            extramask[_COMPAT_NSIG_WORDS - 1];
        unsigned int            extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
        /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
        siginfo_extra_v8plus_t  v8plus;
-       __siginfo_fpu_t         fpu_state;
-};
+       /* __siginfo_rwin_t * */u32 rwin_save;
+} __attribute__((aligned(8)));
 
 typedef struct compat_siginfo{
        int si_signo;
@@ -110,18 +112,14 @@ struct rt_signal_frame32 {
        compat_siginfo_t        info;
        struct pt_regs32        regs;
        compat_sigset_t         mask;
-       /* __siginfo_fpu32_t * */ u32 fpu_save;
+       /* __siginfo_fpu_t * */ u32 fpu_save;
        unsigned int            insns[2];
        stack_t32               stack;
        unsigned int            extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
        /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
        siginfo_extra_v8plus_t  v8plus;
-       __siginfo_fpu_t         fpu_state;
-};
-
-/* Align macros */
-#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 15) & (~15)))
-#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
+       /* __siginfo_rwin_t * */u32 rwin_save;
+} __attribute__((aligned(8)));
 
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
@@ -192,30 +190,13 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
        return 0;
 }
 
-static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-       unsigned long *fpregs = current_thread_info()->fpregs;
-       unsigned long fprs;
-       int err;
-       
-       err = __get_user(fprs, &fpu->si_fprs);
-       fprs_write(0);
-       regs->tstate &= ~TSTATE_PEF;
-       if (fprs & FPRS_DL)
-               err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
-       if (fprs & FPRS_DU)
-               err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
-       err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-       err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-       current_thread_info()->fpsaved[0] |= fprs;
-       return err;
-}
-
 void do_sigreturn32(struct pt_regs *regs)
 {
        struct signal_frame32 __user *sf;
+       compat_uptr_t fpu_save;
+       compat_uptr_t rwin_save;
        unsigned int psr;
-       unsigned pc, npc, fpu_save;
+       unsigned pc, npc;
        sigset_t set;
        unsigned seta[_COMPAT_NSIG_WORDS];
        int err, i;
@@ -273,8 +254,13 @@ void do_sigreturn32(struct pt_regs *regs)
        pt_regs_clear_syscall(regs);
 
        err |= __get_user(fpu_save, &sf->fpu_save);
-       if (fpu_save)
-               err |= restore_fpu_state32(regs, &sf->fpu_state);
+       if (!err && fpu_save)
+               err |= restore_fpu_state(regs, compat_ptr(fpu_save));
+       err |= __get_user(rwin_save, &sf->rwin_save);
+       if (!err && rwin_save) {
+               if (restore_rwin_state(compat_ptr(rwin_save)))
+                       goto segv;
+       }
        err |= __get_user(seta[0], &sf->info.si_mask);
        err |= copy_from_user(seta+1, &sf->extramask,
                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
@@ -300,7 +286,9 @@ segv:
 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 {
        struct rt_signal_frame32 __user *sf;
-       unsigned int psr, pc, npc, fpu_save, u_ss_sp;
+       unsigned int psr, pc, npc, u_ss_sp;
+       compat_uptr_t fpu_save;
+       compat_uptr_t rwin_save;
        mm_segment_t old_fs;
        sigset_t set;
        compat_sigset_t seta;
@@ -359,8 +347,8 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
        pt_regs_clear_syscall(regs);
 
        err |= __get_user(fpu_save, &sf->fpu_save);
-       if (fpu_save)
-               err |= restore_fpu_state32(regs, &sf->fpu_state);
+       if (!err && fpu_save)
+               err |= restore_fpu_state(regs, compat_ptr(fpu_save));
        err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
        err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
        st.ss_sp = compat_ptr(u_ss_sp);
@@ -376,6 +364,12 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
        do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
        set_fs(old_fs);
        
+       err |= __get_user(rwin_save, &sf->rwin_save);
+       if (!err && rwin_save) {
+               if (restore_rwin_state(compat_ptr(rwin_save)))
+                       goto segv;
+       }
+
        switch (_NSIG_WORDS) {
                case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
                case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
@@ -433,26 +427,6 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
        return (void __user *) sp;
 }
 
-static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-       unsigned long *fpregs = current_thread_info()->fpregs;
-       unsigned long fprs;
-       int err = 0;
-       
-       fprs = current_thread_info()->fpsaved[0];
-       if (fprs & FPRS_DL)
-               err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
-                                   (sizeof(unsigned int) * 32));
-       if (fprs & FPRS_DU)
-               err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
-                                   (sizeof(unsigned int) * 32));
-       err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-       err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-       err |= __put_user(fprs, &fpu->si_fprs);
-
-       return err;
-}
-
 /* The I-cache flush instruction only works in the primary ASI, which
  * right now is the nucleus, aka. kernel space.
  *
@@ -515,18 +489,23 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                         int signo, sigset_t *oldset)
 {
        struct signal_frame32 __user *sf;
+       int i, err, wsaved;
+       void __user *tail;
        int sigframe_size;
        u32 psr;
-       int i, err;
        unsigned int seta[_COMPAT_NSIG_WORDS];
 
        /* 1. Make sure everything is clean */
        synchronize_user_stack();
        save_and_clear_fpu();
        
-       sigframe_size = SF_ALIGNEDSZ;
-       if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
-               sigframe_size -= sizeof(__siginfo_fpu_t);
+       wsaved = get_thread_wsaved();
+
+       sigframe_size = sizeof(*sf);
+       if (current_thread_info()->fpsaved[0] & FPRS_FEF)
+               sigframe_size += sizeof(__siginfo_fpu_t);
+       if (wsaved)
+               sigframe_size += sizeof(__siginfo_rwin_t);
 
        sf = (struct signal_frame32 __user *)
                get_sigframe(&ka->sa, regs, sigframe_size);
@@ -534,8 +513,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
        if (invalid_frame_pointer(sf, sigframe_size))
                goto sigill;
 
-       if (get_thread_wsaved() != 0)
-               goto sigill;
+       tail = (sf + 1);
 
        /* 2. Save the current process state */
        if (test_thread_flag(TIF_32BIT)) {
@@ -560,11 +538,22 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                          &sf->v8plus.asi);
 
        if (psr & PSR_EF) {
-               err |= save_fpu_state32(regs, &sf->fpu_state);
-               err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+               __siginfo_fpu_t __user *fp = tail;
+               tail += sizeof(*fp);
+               err |= save_fpu_state(regs, fp);
+               err |= __put_user((u64)fp, &sf->fpu_save);
        } else {
                err |= __put_user(0, &sf->fpu_save);
        }
+       if (wsaved) {
+               __siginfo_rwin_t __user *rwp = tail;
+               tail += sizeof(*rwp);
+               err |= save_rwin_state(wsaved, rwp);
+               err |= __put_user((u64)rwp, &sf->rwin_save);
+               set_thread_wsaved(0);
+       } else {
+               err |= __put_user(0, &sf->rwin_save);
+       }
 
        switch (_NSIG_WORDS) {
        case 4: seta[7] = (oldset->sig[3] >> 32);
@@ -580,10 +569,21 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
        err |= __copy_to_user(sf->extramask, seta + 1,
                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
 
-       err |= copy_in_user((u32 __user *)sf,
-                           (u32 __user *)(regs->u_regs[UREG_FP]),
-                           sizeof(struct reg_window32));
-       
+       if (!wsaved) {
+               err |= copy_in_user((u32 __user *)sf,
+                                   (u32 __user *)(regs->u_regs[UREG_FP]),
+                                   sizeof(struct reg_window32));
+       } else {
+               struct reg_window *rp;
+
+               rp = &current_thread_info()->reg_window[wsaved - 1];
+               for (i = 0; i < 8; i++)
+                       err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
+               for (i = 0; i < 6; i++)
+                       err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
+               err |= __put_user(rp->ins[6], &sf->ss.fp);
+               err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
+       }       
        if (err)
                goto sigsegv;
 
@@ -613,7 +613,6 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
                if (err)
                        goto sigsegv;
-
                flush_signal_insns(address);
        }
        return 0;
@@ -632,18 +631,23 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                            siginfo_t *info)
 {
        struct rt_signal_frame32 __user *sf;
+       int i, err, wsaved;
+       void __user *tail;
        int sigframe_size;
        u32 psr;
-       int i, err;
        compat_sigset_t seta;
 
        /* 1. Make sure everything is clean */
        synchronize_user_stack();
        save_and_clear_fpu();
        
-       sigframe_size = RT_ALIGNEDSZ;
-       if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
-               sigframe_size -= sizeof(__siginfo_fpu_t);
+       wsaved = get_thread_wsaved();
+
+       sigframe_size = sizeof(*sf);
+       if (current_thread_info()->fpsaved[0] & FPRS_FEF)
+               sigframe_size += sizeof(__siginfo_fpu_t);
+       if (wsaved)
+               sigframe_size += sizeof(__siginfo_rwin_t);
 
        sf = (struct rt_signal_frame32 __user *)
                get_sigframe(&ka->sa, regs, sigframe_size);
@@ -651,8 +655,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
        if (invalid_frame_pointer(sf, sigframe_size))
                goto sigill;
 
-       if (get_thread_wsaved() != 0)
-               goto sigill;
+       tail = (sf + 1);
 
        /* 2. Save the current process state */
        if (test_thread_flag(TIF_32BIT)) {
@@ -677,11 +680,22 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
                          &sf->v8plus.asi);
 
        if (psr & PSR_EF) {
-               err |= save_fpu_state32(regs, &sf->fpu_state);
-               err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+               __siginfo_fpu_t __user *fp = tail;
+               tail += sizeof(*fp);
+               err |= save_fpu_state(regs, fp);
+               err |= __put_user((u64)fp, &sf->fpu_save);
        } else {
                err |= __put_user(0, &sf->fpu_save);
        }
+       if (wsaved) {
+               __siginfo_rwin_t __user *rwp = tail;
+               tail += sizeof(*rwp);
+               err |= save_rwin_state(wsaved, rwp);
+               err |= __put_user((u64)rwp, &sf->rwin_save);
+               set_thread_wsaved(0);
+       } else {
+               err |= __put_user(0, &sf->rwin_save);
+       }
 
        /* Update the siginfo structure.  */
        err |= copy_siginfo_to_user32(&sf->info, info);
@@ -703,9 +717,21 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
        }
        err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
 
-       err |= copy_in_user((u32 __user *)sf,
-                           (u32 __user *)(regs->u_regs[UREG_FP]),
-                           sizeof(struct reg_window32));
+       if (!wsaved) {
+               err |= copy_in_user((u32 __user *)sf,
+                                   (u32 __user *)(regs->u_regs[UREG_FP]),
+                                   sizeof(struct reg_window32));
+       } else {
+               struct reg_window *rp;
+
+               rp = &current_thread_info()->reg_window[wsaved - 1];
+               for (i = 0; i < 8; i++)
+                       err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
+               for (i = 0; i < 6; i++)
+                       err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
+               err |= __put_user(rp->ins[6], &sf->ss.fp);
+               err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
+       }
        if (err)
                goto sigsegv;
        
index 5e5c5fd03783c997f5c344025e8f4784182a0ddc..04ede8f04add3f397ca46c8ebee249d85c92213c 100644 (file)
@@ -26,6 +26,8 @@
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>    /* flush_sig_insns */
 
+#include "sigutil.h"
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
@@ -39,8 +41,8 @@ struct signal_frame {
        unsigned long           insns[2] __attribute__ ((aligned (8)));
        unsigned int            extramask[_NSIG_WORDS - 1];
        unsigned int            extra_size; /* Should be 0 */
-       __siginfo_fpu_t         fpu_state;
-};
+       __siginfo_rwin_t __user *rwin_save;
+} __attribute__((aligned(8)));
 
 struct rt_signal_frame {
        struct sparc_stackf     ss;
@@ -51,8 +53,8 @@ struct rt_signal_frame {
        unsigned int            insns[2];
        stack_t                 stack;
        unsigned int            extra_size; /* Should be 0 */
-       __siginfo_fpu_t         fpu_state;
-};
+       __siginfo_rwin_t __user *rwin_save;
+} __attribute__((aligned(8)));
 
 /* Align macros */
 #define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7)))
@@ -79,43 +81,13 @@ asmlinkage int sys_sigsuspend(old_sigset_t set)
        return _sigpause_common(set);
 }
 
-static inline int
-restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-       int err;
-#ifdef CONFIG_SMP
-       if (test_tsk_thread_flag(current, TIF_USEDFPU))
-               regs->psr &= ~PSR_EF;
-#else
-       if (current == last_task_used_math) {
-               last_task_used_math = NULL;
-               regs->psr &= ~PSR_EF;
-       }
-#endif
-       set_used_math();
-       clear_tsk_thread_flag(current, TIF_USEDFPU);
-
-       if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
-               return -EFAULT;
-
-       err = __copy_from_user(&current->thread.float_regs[0], &fpu->si_float_regs[0],
-                              (sizeof(unsigned long) * 32));
-       err |= __get_user(current->thread.fsr, &fpu->si_fsr);
-       err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
-       if (current->thread.fpqdepth != 0)
-               err |= __copy_from_user(&current->thread.fpqueue[0],
-                                       &fpu->si_fpqueue[0],
-                                       ((sizeof(unsigned long) +
-                                       (sizeof(unsigned long *)))*16));
-       return err;
-}
-
 asmlinkage void do_sigreturn(struct pt_regs *regs)
 {
        struct signal_frame __user *sf;
        unsigned long up_psr, pc, npc;
        sigset_t set;
        __siginfo_fpu_t __user *fpu_save;
+       __siginfo_rwin_t __user *rwin_save;
        int err;
 
        /* Always make any pending restarted system calls return -EINTR */
@@ -150,9 +122,11 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
        pt_regs_clear_syscall(regs);
 
        err |= __get_user(fpu_save, &sf->fpu_save);
-
        if (fpu_save)
                err |= restore_fpu_state(regs, fpu_save);
+       err |= __get_user(rwin_save, &sf->rwin_save);
+       if (rwin_save)
+               err |= restore_rwin_state(rwin_save);
 
        /* This is pretty much atomic, no amount locking would prevent
         * the races which exist anyways.
@@ -180,6 +154,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
        struct rt_signal_frame __user *sf;
        unsigned int psr, pc, npc;
        __siginfo_fpu_t __user *fpu_save;
+       __siginfo_rwin_t __user *rwin_save;
        mm_segment_t old_fs;
        sigset_t set;
        stack_t st;
@@ -207,8 +182,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
        pt_regs_clear_syscall(regs);
 
        err |= __get_user(fpu_save, &sf->fpu_save);
-
-       if (fpu_save)
+       if (!err && fpu_save)
                err |= restore_fpu_state(regs, fpu_save);
        err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
        
@@ -228,6 +202,12 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
        do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
        set_fs(old_fs);
 
+       err |= __get_user(rwin_save, &sf->rwin_save);
+       if (!err && rwin_save) {
+               if (restore_rwin_state(rwin_save))
+                       goto segv;
+       }
+
        sigdelsetmask(&set, ~_BLOCKABLE);
        spin_lock_irq(&current->sighand->siglock);
        current->blocked = set;
@@ -280,53 +260,23 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
        return (void __user *) sp;
 }
 
-static inline int
-save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-       int err = 0;
-#ifdef CONFIG_SMP
-       if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
-               put_psr(get_psr() | PSR_EF);
-               fpsave(&current->thread.float_regs[0], &current->thread.fsr,
-                      &current->thread.fpqueue[0], &current->thread.fpqdepth);
-               regs->psr &= ~(PSR_EF);
-               clear_tsk_thread_flag(current, TIF_USEDFPU);
-       }
-#else
-       if (current == last_task_used_math) {
-               put_psr(get_psr() | PSR_EF);
-               fpsave(&current->thread.float_regs[0], &current->thread.fsr,
-                      &current->thread.fpqueue[0], &current->thread.fpqdepth);
-               last_task_used_math = NULL;
-               regs->psr &= ~(PSR_EF);
-       }
-#endif
-       err |= __copy_to_user(&fpu->si_float_regs[0],
-                             &current->thread.float_regs[0],
-                             (sizeof(unsigned long) * 32));
-       err |= __put_user(current->thread.fsr, &fpu->si_fsr);
-       err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
-       if (current->thread.fpqdepth != 0)
-               err |= __copy_to_user(&fpu->si_fpqueue[0],
-                                     &current->thread.fpqueue[0],
-                                     ((sizeof(unsigned long) +
-                                     (sizeof(unsigned long *)))*16));
-       clear_used_math();
-       return err;
-}
-
 static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
                       int signo, sigset_t *oldset)
 {
        struct signal_frame __user *sf;
-       int sigframe_size, err;
+       int sigframe_size, err, wsaved;
+       void __user *tail;
 
        /* 1. Make sure everything is clean */
        synchronize_user_stack();
 
-       sigframe_size = SF_ALIGNEDSZ;
-       if (!used_math())
-               sigframe_size -= sizeof(__siginfo_fpu_t);
+       wsaved = current_thread_info()->w_saved;
+
+       sigframe_size = sizeof(*sf);
+       if (used_math())
+               sigframe_size += sizeof(__siginfo_fpu_t);
+       if (wsaved)
+               sigframe_size += sizeof(__siginfo_rwin_t);
 
        sf = (struct signal_frame __user *)
                get_sigframe(&ka->sa, regs, sigframe_size);
@@ -334,8 +284,7 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
        if (invalid_frame_pointer(sf, sigframe_size))
                goto sigill_and_return;
 
-       if (current_thread_info()->w_saved != 0)
-               goto sigill_and_return;
+       tail = sf + 1;
 
        /* 2. Save the current process state */
        err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs));
@@ -343,17 +292,34 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
        err |= __put_user(0, &sf->extra_size);
 
        if (used_math()) {
-               err |= save_fpu_state(regs, &sf->fpu_state);
-               err |= __put_user(&sf->fpu_state, &sf->fpu_save);
+               __siginfo_fpu_t __user *fp = tail;
+               tail += sizeof(*fp);
+               err |= save_fpu_state(regs, fp);
+               err |= __put_user(fp, &sf->fpu_save);
        } else {
                err |= __put_user(0, &sf->fpu_save);
        }
+       if (wsaved) {
+               __siginfo_rwin_t __user *rwp = tail;
+               tail += sizeof(*rwp);
+               err |= save_rwin_state(wsaved, rwp);
+               err |= __put_user(rwp, &sf->rwin_save);
+       } else {
+               err |= __put_user(0, &sf->rwin_save);
+       }
 
        err |= __put_user(oldset->sig[0], &sf->info.si_mask);
        err |= __copy_to_user(sf->extramask, &oldset->sig[1],
                              (_NSIG_WORDS - 1) * sizeof(unsigned int));
-       err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
-                             sizeof(struct reg_window32));
+       if (!wsaved) {
+               err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
+                                     sizeof(struct reg_window32));
+       } else {
+               struct reg_window32 *rp;
+
+               rp = &current_thread_info()->reg_window[wsaved - 1];
+               err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
+       }
        if (err)
                goto sigsegv;
        
@@ -399,21 +365,24 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
                          int signo, sigset_t *oldset, siginfo_t *info)
 {
        struct rt_signal_frame __user *sf;
-       int sigframe_size;
+       int sigframe_size, wsaved;
+       void __user *tail;
        unsigned int psr;
        int err;
 
        synchronize_user_stack();
-       sigframe_size = RT_ALIGNEDSZ;
-       if (!used_math())
-               sigframe_size -= sizeof(__siginfo_fpu_t);
+       wsaved = current_thread_info()->w_saved;
+       sigframe_size = sizeof(*sf);
+       if (used_math())
+               sigframe_size += sizeof(__siginfo_fpu_t);
+       if (wsaved)
+               sigframe_size += sizeof(__siginfo_rwin_t);
        sf = (struct rt_signal_frame __user *)
                get_sigframe(&ka->sa, regs, sigframe_size);
        if (invalid_frame_pointer(sf, sigframe_size))
                goto sigill;
-       if (current_thread_info()->w_saved != 0)
-               goto sigill;
 
+       tail = sf + 1;
        err  = __put_user(regs->pc, &sf->regs.pc);
        err |= __put_user(regs->npc, &sf->regs.npc);
        err |= __put_user(regs->y, &sf->regs.y);
@@ -425,11 +394,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        err |= __put_user(0, &sf->extra_size);
 
        if (psr & PSR_EF) {
-               err |= save_fpu_state(regs, &sf->fpu_state);
-               err |= __put_user(&sf->fpu_state, &sf->fpu_save);
+               __siginfo_fpu_t *fp = tail;
+               tail += sizeof(*fp);
+               err |= save_fpu_state(regs, fp);
+               err |= __put_user(fp, &sf->fpu_save);
        } else {
                err |= __put_user(0, &sf->fpu_save);
        }
+       if (wsaved) {
+               __siginfo_rwin_t *rwp = tail;
+               tail += sizeof(*rwp);
+               err |= save_rwin_state(wsaved, rwp);
+               err |= __put_user(rwp, &sf->rwin_save);
+       } else {
+               err |= __put_user(0, &sf->rwin_save);
+       }
        err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
        
        /* Setup sigaltstack */
@@ -437,8 +416,15 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
        err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
        
-       err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
-                             sizeof(struct reg_window32));
+       if (!wsaved) {
+               err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
+                                     sizeof(struct reg_window32));
+       } else {
+               struct reg_window32 *rp;
+
+               rp = &current_thread_info()->reg_window[wsaved - 1];
+               err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
+       }
 
        err |= copy_siginfo_to_user(&sf->info, info);
 
index 006fe4515886dc6ae2a7a8e6cc9b6df9c16fda46..47509df3b893acfb365ec503cbe00f2dabeea2ac 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "entry.h"
 #include "systbls.h"
+#include "sigutil.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
@@ -236,7 +237,7 @@ struct rt_signal_frame {
        __siginfo_fpu_t __user  *fpu_save;
        stack_t                 stack;
        sigset_t                mask;
-       __siginfo_fpu_t         fpu_state;
+       __siginfo_rwin_t        *rwin_save;
 };
 
 static long _sigpause_common(old_sigset_t set)
@@ -266,33 +267,12 @@ asmlinkage long sys_sigsuspend(old_sigset_t set)
        return _sigpause_common(set);
 }
 
-static inline int
-restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-       unsigned long *fpregs = current_thread_info()->fpregs;
-       unsigned long fprs;
-       int err;
-
-       err = __get_user(fprs, &fpu->si_fprs);
-       fprs_write(0);
-       regs->tstate &= ~TSTATE_PEF;
-       if (fprs & FPRS_DL)
-               err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
-                              (sizeof(unsigned int) * 32));
-       if (fprs & FPRS_DU)
-               err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
-                              (sizeof(unsigned int) * 32));
-       err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-       err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-       current_thread_info()->fpsaved[0] |= fprs;
-       return err;
-}
-
 void do_rt_sigreturn(struct pt_regs *regs)
 {
        struct rt_signal_frame __user *sf;
        unsigned long tpc, tnpc, tstate;
        __siginfo_fpu_t __user *fpu_save;
+       __siginfo_rwin_t __user *rwin_save;
        sigset_t set;
        int err;
 
@@ -325,8 +305,8 @@ void do_rt_sigreturn(struct pt_regs *regs)
        regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
 
        err |= __get_user(fpu_save, &sf->fpu_save);
-       if (fpu_save)
-               err |= restore_fpu_state(regs, &sf->fpu_state);
+       if (!err && fpu_save)
+               err |= restore_fpu_state(regs, fpu_save);
 
        err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
        err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
@@ -334,6 +314,12 @@ void do_rt_sigreturn(struct pt_regs *regs)
        if (err)
                goto segv;
 
+       err |= __get_user(rwin_save, &sf->rwin_save);
+       if (!err && rwin_save) {
+               if (restore_rwin_state(rwin_save))
+                       goto segv;
+       }
+
        regs->tpc = tpc;
        regs->tnpc = tnpc;
 
@@ -351,34 +337,13 @@ segv:
 }
 
 /* Checks if the fp is valid */
-static int invalid_frame_pointer(void __user *fp, int fplen)
+static int invalid_frame_pointer(void __user *fp)
 {
        if (((unsigned long) fp) & 15)
                return 1;
        return 0;
 }
 
-static inline int
-save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-       unsigned long *fpregs = current_thread_info()->fpregs;
-       unsigned long fprs;
-       int err = 0;
-       
-       fprs = current_thread_info()->fpsaved[0];
-       if (fprs & FPRS_DL)
-               err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
-                                   (sizeof(unsigned int) * 32));
-       if (fprs & FPRS_DU)
-               err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
-                                   (sizeof(unsigned int) * 32));
-       err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-       err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-       err |= __put_user(fprs, &fpu->si_fprs);
-
-       return err;
-}
-
 static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
 {
        unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
@@ -414,34 +379,48 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
               int signo, sigset_t *oldset, siginfo_t *info)
 {
        struct rt_signal_frame __user *sf;
-       int sigframe_size, err;
+       int wsaved, err, sf_size;
+       void __user *tail;
 
        /* 1. Make sure everything is clean */
        synchronize_user_stack();
        save_and_clear_fpu();
        
-       sigframe_size = sizeof(struct rt_signal_frame);
-       if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
-               sigframe_size -= sizeof(__siginfo_fpu_t);
+       wsaved = get_thread_wsaved();
 
+       sf_size = sizeof(struct rt_signal_frame);
+       if (current_thread_info()->fpsaved[0] & FPRS_FEF)
+               sf_size += sizeof(__siginfo_fpu_t);
+       if (wsaved)
+               sf_size += sizeof(__siginfo_rwin_t);
        sf = (struct rt_signal_frame __user *)
-               get_sigframe(ka, regs, sigframe_size);
-       
-       if (invalid_frame_pointer (sf, sigframe_size))
-               goto sigill;
+               get_sigframe(ka, regs, sf_size);
 
-       if (get_thread_wsaved() != 0)
+       if (invalid_frame_pointer (sf))
                goto sigill;
 
+       tail = (sf + 1);
+
        /* 2. Save the current process state */
        err = copy_to_user(&sf->regs, regs, sizeof (*regs));
 
        if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
-               err |= save_fpu_state(regs, &sf->fpu_state);
-               err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+               __siginfo_fpu_t __user *fpu_save = tail;
+               tail += sizeof(__siginfo_fpu_t);
+               err |= save_fpu_state(regs, fpu_save);
+               err |= __put_user((u64)fpu_save, &sf->fpu_save);
        } else {
                err |= __put_user(0, &sf->fpu_save);
        }
+       if (wsaved) {
+               __siginfo_rwin_t __user *rwin_save = tail;
+               tail += sizeof(__siginfo_rwin_t);
+               err |= save_rwin_state(wsaved, rwin_save);
+               err |= __put_user((u64)rwin_save, &sf->rwin_save);
+               set_thread_wsaved(0);
+       } else {
+               err |= __put_user(0, &sf->rwin_save);
+       }
        
        /* Setup sigaltstack */
        err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
@@ -450,10 +429,17 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
 
        err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
 
-       err |= copy_in_user((u64 __user *)sf,
-                           (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
-                           sizeof(struct reg_window));
+       if (!wsaved) {
+               err |= copy_in_user((u64 __user *)sf,
+                                   (u64 __user *)(regs->u_regs[UREG_FP] +
+                                                  STACK_BIAS),
+                                   sizeof(struct reg_window));
+       } else {
+               struct reg_window *rp;
 
+               rp = &current_thread_info()->reg_window[wsaved - 1];
+               err |= copy_to_user(sf, rp, sizeof(struct reg_window));
+       }
        if (info)
                err |= copy_siginfo_to_user(&sf->info, info);
        else {
diff --git a/arch/sparc/kernel/sigutil.h b/arch/sparc/kernel/sigutil.h
new file mode 100644 (file)
index 0000000..d223aa4
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _SIGUTIL_H
+#define _SIGUTIL_H
+
+int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
+int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
+int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin);
+int restore_rwin_state(__siginfo_rwin_t __user *rp);
+
+#endif /* _SIGUTIL_H */
diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c
new file mode 100644 (file)
index 0000000..35c7897
--- /dev/null
@@ -0,0 +1,120 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/thread_info.h>
+#include <linux/uaccess.h>
+#include <linux/sched.h>
+
+#include <asm/sigcontext.h>
+#include <asm/fpumacro.h>
+#include <asm/ptrace.h>
+
+#include "sigutil.h"
+
+int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+       int err = 0;
+#ifdef CONFIG_SMP
+       if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
+               put_psr(get_psr() | PSR_EF);
+               fpsave(&current->thread.float_regs[0], &current->thread.fsr,
+                      &current->thread.fpqueue[0], &current->thread.fpqdepth);
+               regs->psr &= ~(PSR_EF);
+               clear_tsk_thread_flag(current, TIF_USEDFPU);
+       }
+#else
+       if (current == last_task_used_math) {
+               put_psr(get_psr() | PSR_EF);
+               fpsave(&current->thread.float_regs[0], &current->thread.fsr,
+                      &current->thread.fpqueue[0], &current->thread.fpqdepth);
+               last_task_used_math = NULL;
+               regs->psr &= ~(PSR_EF);
+       }
+#endif
+       err |= __copy_to_user(&fpu->si_float_regs[0],
+                             &current->thread.float_regs[0],
+                             (sizeof(unsigned long) * 32));
+       err |= __put_user(current->thread.fsr, &fpu->si_fsr);
+       err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
+       if (current->thread.fpqdepth != 0)
+               err |= __copy_to_user(&fpu->si_fpqueue[0],
+                                     &current->thread.fpqueue[0],
+                                     ((sizeof(unsigned long) +
+                                     (sizeof(unsigned long *)))*16));
+       clear_used_math();
+       return err;
+}
+
+int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+       int err;
+#ifdef CONFIG_SMP
+       if (test_tsk_thread_flag(current, TIF_USEDFPU))
+               regs->psr &= ~PSR_EF;
+#else
+       if (current == last_task_used_math) {
+               last_task_used_math = NULL;
+               regs->psr &= ~PSR_EF;
+       }
+#endif
+       set_used_math();
+       clear_tsk_thread_flag(current, TIF_USEDFPU);
+
+       if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
+               return -EFAULT;
+
+       err = __copy_from_user(&current->thread.float_regs[0], &fpu->si_float_regs[0],
+                              (sizeof(unsigned long) * 32));
+       err |= __get_user(current->thread.fsr, &fpu->si_fsr);
+       err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
+       if (current->thread.fpqdepth != 0)
+               err |= __copy_from_user(&current->thread.fpqueue[0],
+                                       &fpu->si_fpqueue[0],
+                                       ((sizeof(unsigned long) +
+                                       (sizeof(unsigned long *)))*16));
+       return err;
+}
+
+int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
+{
+       int i, err = __put_user(wsaved, &rwin->wsaved);
+
+       for (i = 0; i < wsaved; i++) {
+               struct reg_window32 *rp;
+               unsigned long fp;
+
+               rp = &current_thread_info()->reg_window[i];
+               fp = current_thread_info()->rwbuf_stkptrs[i];
+               err |= copy_to_user(&rwin->reg_window[i], rp,
+                                   sizeof(struct reg_window32));
+               err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
+       }
+       return err;
+}
+
+int restore_rwin_state(__siginfo_rwin_t __user *rp)
+{
+       struct thread_info *t = current_thread_info();
+       int i, wsaved, err;
+
+       __get_user(wsaved, &rp->wsaved);
+       if (wsaved > NSWINS)
+               return -EFAULT;
+
+       err = 0;
+       for (i = 0; i < wsaved; i++) {
+               err |= copy_from_user(&t->reg_window[i],
+                                     &rp->reg_window[i],
+                                     sizeof(struct reg_window32));
+               err |= __get_user(t->rwbuf_stkptrs[i],
+                                 &rp->rwbuf_stkptrs[i]);
+       }
+       if (err)
+               return err;
+
+       t->w_saved = wsaved;
+       synchronize_user_stack();
+       if (t->w_saved)
+               return -EFAULT;
+       return 0;
+
+}
diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c
new file mode 100644 (file)
index 0000000..e7dc508
--- /dev/null
@@ -0,0 +1,93 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/thread_info.h>
+#include <linux/uaccess.h>
+
+#include <asm/sigcontext.h>
+#include <asm/fpumacro.h>
+#include <asm/ptrace.h>
+
+#include "sigutil.h"
+
+int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+       unsigned long *fpregs = current_thread_info()->fpregs;
+       unsigned long fprs;
+       int err = 0;
+       
+       fprs = current_thread_info()->fpsaved[0];
+       if (fprs & FPRS_DL)
+               err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
+                                   (sizeof(unsigned int) * 32));
+       if (fprs & FPRS_DU)
+               err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
+                                   (sizeof(unsigned int) * 32));
+       err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+       err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
+       err |= __put_user(fprs, &fpu->si_fprs);
+
+       return err;
+}
+
+int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+       unsigned long *fpregs = current_thread_info()->fpregs;
+       unsigned long fprs;
+       int err;
+
+       err = __get_user(fprs, &fpu->si_fprs);
+       fprs_write(0);
+       regs->tstate &= ~TSTATE_PEF;
+       if (fprs & FPRS_DL)
+               err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
+                              (sizeof(unsigned int) * 32));
+       if (fprs & FPRS_DU)
+               err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
+                              (sizeof(unsigned int) * 32));
+       err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+       err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
+       current_thread_info()->fpsaved[0] |= fprs;
+       return err;
+}
+
+int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
+{
+       int i, err = __put_user(wsaved, &rwin->wsaved);
+
+       for (i = 0; i < wsaved; i++) {
+               struct reg_window *rp = &current_thread_info()->reg_window[i];
+               unsigned long fp = current_thread_info()->rwbuf_stkptrs[i];
+
+               err |= copy_to_user(&rwin->reg_window[i], rp,
+                                   sizeof(struct reg_window));
+               err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
+       }
+       return err;
+}
+
+int restore_rwin_state(__siginfo_rwin_t __user *rp)
+{
+       struct thread_info *t = current_thread_info();
+       int i, wsaved, err;
+
+       __get_user(wsaved, &rp->wsaved);
+       if (wsaved > NSWINS)
+               return -EFAULT;
+
+       err = 0;
+       for (i = 0; i < wsaved; i++) {
+               err |= copy_from_user(&t->reg_window[i],
+                                     &rp->reg_window[i],
+                                     sizeof(struct reg_window));
+               err |= __get_user(t->rwbuf_stkptrs[i],
+                                 &rp->rwbuf_stkptrs[i]);
+       }
+       if (err)
+               return err;
+
+       set_thread_wsaved(wsaved);
+       synchronize_user_stack();
+       if (get_thread_wsaved())
+               return -EFAULT;
+       return 0;
+}
index fc94607f0bd50c8d5cdbf9f98bfcd42b26b51b03..72ade79b621bcd8b23ec44650e3d4af4fdbf0b66 100644 (file)
@@ -21,7 +21,7 @@
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
 #include <asm/irqflags.h>
-#include <linux/atomic.h>
+#include <asm/atomic.h>
 #include <asm/asm-offsets.h>
 #include <hv/hypervisor.h>
 #include <arch/abi.h>
index 1f75a2a561011220f27b9d97cd27bd4f78567ea2..24448734f6f17c3f70f95f4252afbf98c5dcce00 100644 (file)
@@ -70,7 +70,7 @@
  */
 
 #include <linux/linkage.h>
-#include <linux/atomic.h>
+#include <asm/atomic.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 
index 22745b47c82956c086d1dfff5fdd82be18dec3cc..a492e59883a313b7cdae28ea426c5821c21da3c0 100644 (file)
@@ -368,7 +368,7 @@ static const struct net_device_ops uml_netdev_ops = {
        .ndo_open               = uml_net_open,
        .ndo_stop               = uml_net_close,
        .ndo_start_xmit         = uml_net_start_xmit,
-       .ndo_set_multicast_list = uml_net_set_multicast_list,
+       .ndo_set_rx_mode        = uml_net_set_multicast_list,
        .ndo_tx_timeout         = uml_net_tx_timeout,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = uml_net_change_mtu,
index 5bd1bad33fab65fdd8f8857c3452768377e88290..200c4ab1240c3deeaad3eb98d8ef1a46ef3c64e6 100644 (file)
@@ -71,7 +71,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_SYSCALL_AUDIT      6
 #define TIF_RESTORE_SIGMASK    7
-#define TIF_FREEZE             16      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
@@ -80,6 +79,5 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_MEMDIE            (1 << TIF_MEMDIE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 #endif
index b0954a2d23cfaf5b4db0bbe1b6e95493d75ebc03..950a9afa38f8632239df166ac21ffe094229217e 100644 (file)
@@ -10,8 +10,8 @@
 # Copyright (C) 2001~2010 GUAN Xue-tao
 #
 
-EXTRA_CFLAGS   := -fpic -fno-builtin
-EXTRA_AFLAGS   := -Wa,-march=all
+ccflags-y      := -fpic -fno-builtin
+asflags-y      := -Wa,-march=all
 
 OBJS           := misc.o
 
index c9dd3198b6f701d3e07b50c81528fb240da7b9ca..6265e7360dcd77bfe5e0209847f2ce9c4ff7aa0a 100644 (file)
@@ -64,7 +64,6 @@ CONFIG_I2C_BATTERY_BQ27200=n
 CONFIG_I2C_EEPROM_AT24=n
 CONFIG_LCD_BACKLIGHT=n
 
-CONFIG_PUV3_UMAL=y
 CONFIG_PUV3_MUSB=n
 CONFIG_PUV3_AC97=n
 CONFIG_PUV3_NAND=n
@@ -101,6 +100,7 @@ CONFIG_SATA_VIA=y
 #      Network device support
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
+CONFIG_MAC_PUV3=y
 CONFIG_NETDEV_1000=y
 #      Wireless LAN
 CONFIG_WLAN_80211=n
index 1628a63289946218c12cebed99246c87087e8a18..401f597bc38cfcdf102ff6188f8bd3c27f46dde5 100644 (file)
 #ifndef __UNICORE_BITOPS_H__
 #define __UNICORE_BITOPS_H__
 
-#define find_next_bit          __uc32_find_next_bit
-#define find_next_zero_bit     __uc32_find_next_zero_bit
-
-#define find_first_bit         __uc32_find_first_bit
-#define find_first_zero_bit    __uc32_find_first_zero_bit
-
 #define _ASM_GENERIC_BITOPS_FLS_H_
 #define _ASM_GENERIC_BITOPS___FLS_H_
 #define _ASM_GENERIC_BITOPS_FFS_H_
@@ -44,4 +38,10 @@ static inline int fls(int x)
 
 #include <asm-generic/bitops.h>
 
+/* following definitions: to avoid using codes in lib/find_*.c */
+#define find_next_bit          find_next_bit
+#define find_next_zero_bit     find_next_zero_bit
+#define find_first_bit         find_first_bit
+#define find_first_zero_bit    find_first_zero_bit
+
 #endif /* __UNICORE_BITOPS_H__ */
index 4bd87f3d13d43c90d97a6bfb1504b385980a19e2..3e789bddc51ac006efcc0f255448317885bf2752 100644 (file)
@@ -37,15 +37,9 @@ extern void __uc32_iounmap(volatile void __iomem *addr);
  */
 #define ioremap(cookie, size)          __uc32_ioremap(cookie, size)
 #define ioremap_cached(cookie, size)   __uc32_ioremap_cached(cookie, size)
+#define ioremap_nocache(cookie, size)  __uc32_ioremap(cookie, size)
 #define iounmap(cookie)                        __uc32_iounmap(cookie)
 
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#undef xlate_dev_mem_ptr
-#define xlate_dev_mem_ptr(p)   __va(p)
-
 #define HAVE_ARCH_PIO_SIZE
 #define PIO_OFFSET             (unsigned int)(PCI_IOBASE)
 #define PIO_MASK               (unsigned int)(IO_SPACE_LIMIT)
index c270e9e04861f257696b6405b68040469a159db7..89f7557583b82d9bfe86d6bd967251c99e66de0b 100644 (file)
@@ -135,14 +135,12 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_NOTIFY_RESUME      2       /* callback before returning to user */
 #define TIF_SYSCALL_TRACE      8
 #define TIF_MEMDIE             18
-#define TIF_FREEZE             19
 #define TIF_RESTORE_SIGMASK    20
 
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 
 /*
index a8970809428a65985873e42ffd417782c0f47ae9..d98bd812cae1ea17efcb314a1cccee9639636b37 100644 (file)
@@ -24,8 +24,8 @@
 
 #include "ksyms.h"
 
-EXPORT_SYMBOL(__uc32_find_next_zero_bit);
-EXPORT_SYMBOL(__uc32_find_next_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(find_next_bit);
 
 EXPORT_SYMBOL(__backtrace);
 
index c360ce905d8b7bcb0d9b84b796089987c5cf967b..c77746247d3698856f26e27531c7454382178a6e 100644 (file)
@@ -17,7 +17,7 @@
  * Purpose  : Find a 'zero' bit
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
-__uc32_find_first_zero_bit:
+ENTRY(find_first_zero_bit)
                cxor.a  r1, #0
                beq     3f
                mov     r2, #0
@@ -29,13 +29,14 @@ __uc32_find_first_zero_bit:
                bub     1b
 3:             mov     r0, r1                  @ no free bits
                mov     pc, lr
+ENDPROC(find_first_zero_bit)
 
 /*
  * Purpose  : Find next 'zero' bit
  * Prototype: int find_next_zero_bit
  *             (void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(__uc32_find_next_zero_bit)
+ENTRY(find_next_zero_bit)
                cxor.a  r1, #0
                beq     3b
                and.a   ip, r2, #7
@@ -47,14 +48,14 @@ ENTRY(__uc32_find_next_zero_bit)
                or      r2, r2, #7              @ if zero, then no bits here
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
-ENDPROC(__uc32_find_next_zero_bit)
+ENDPROC(find_next_zero_bit)
 
 /*
  * Purpose  : Find a 'one' bit
  * Prototype: int find_first_bit
  *             (const unsigned long *addr, unsigned int maxbit);
  */
-__uc32_find_first_bit:
+ENTRY(find_first_bit)
                cxor.a  r1, #0
                beq     3f
                mov     r2, #0
@@ -66,13 +67,14 @@ __uc32_find_first_bit:
                bub     1b
 3:             mov     r0, r1                  @ no free bits
                mov     pc, lr
+ENDPROC(find_first_bit)
 
 /*
  * Purpose  : Find next 'one' bit
  * Prototype: int find_next_zero_bit
  *             (void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(__uc32_find_next_bit)
+ENTRY(find_next_bit)
                cxor.a  r1, #0
                beq     3b
                and.a   ip, r2, #7
@@ -83,7 +85,7 @@ ENTRY(__uc32_find_next_bit)
                or      r2, r2, #7              @ if zero, then no bits here
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
-ENDPROC(__uc32_find_next_bit)
+ENDPROC(find_next_bit)
 
 /*
  * One or more bits in the LSB of r3 are assumed to be set.
index 6a47bb22657fd3d55835c32b2e834cd42e3ad28c..f1833e34b16b01045db3bb346f3d462e74f445a0 100644 (file)
@@ -1452,6 +1452,15 @@ config ARCH_USES_PG_UNCACHED
        def_bool y
        depends on X86_PAT
 
+config ARCH_RANDOM
+       def_bool y
+       prompt "x86 architectural random number generator" if EXPERT
+       ---help---
+         Enable the x86 architectural RDRAND instruction
+         (Intel Bull Mountain technology) to generate random numbers.
+         If supported, this is a high bandwidth, cryptographically
+         secure hardware random number generator.
+
 config EFI
        bool "EFI runtime service support"
        depends on ACPI
index c04f1b7a91397e6901ade2e09e498066b5697df2..57c7f7b4436de65edaa19eb7ae5e1d8d3ebfd97e 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
 obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 
 obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
+obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
 
 aes-i586-y := aes-i586-asm_32.o aes_glue.o
 twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
@@ -25,3 +26,10 @@ salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
 aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o
 
 ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
+
+# enable AVX support only when $(AS) can actually assemble the instructions
+ifeq ($(call as-instr,vpxor %xmm0$(comma)%xmm1$(comma)%xmm2,yes,no),yes)
+AFLAGS_sha1_ssse3_asm.o += -DSHA1_ENABLE_AVX_SUPPORT
+CFLAGS_sha1_ssse3_glue.o += -DSHA1_ENABLE_AVX_SUPPORT
+endif
+sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o
diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S
new file mode 100644 (file)
index 0000000..b2c2f57
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ * This is a SIMD SHA-1 implementation. It requires the Intel(R) Supplemental
+ * SSE3 instruction set extensions introduced in Intel Core Microarchitecture
+ * processors. CPUs supporting Intel(R) AVX extensions will get an additional
+ * boost.
+ *
+ * This work was inspired by the vectorized implementation of Dean Gaudet.
+ * Additional information on it can be found at:
+ *    http://www.arctic.org/~dean/crypto/sha1.html
+ *
+ * It was improved upon with more efficient vectorization of the message
+ * scheduling. This implementation has also been optimized for all current and
+ * several future generations of Intel CPUs.
+ *
+ * See this article for more information about the implementation details:
+ *   http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/
+ *
+ * Copyright (C) 2010, Intel Corp.
+ *   Authors: Maxim Locktyukhin <maxim.locktyukhin@intel.com>
+ *            Ronen Zohar <ronen.zohar@intel.com>
+ *
+ * Converted to AT&T syntax and adapted for inclusion in the Linux kernel:
+ *   Author: Mathias Krause <minipli@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define CTX    %rdi    // arg1
+#define BUF    %rsi    // arg2
+#define CNT    %rdx    // arg3
+
+#define REG_A  %ecx
+#define REG_B  %esi
+#define REG_C  %edi
+#define REG_D  %ebp
+#define REG_E  %edx
+
+#define REG_T1 %eax
+#define REG_T2 %ebx
+
+#define K_BASE         %r8
+#define HASH_PTR       %r9
+#define BUFFER_PTR     %r10
+#define BUFFER_END     %r11
+
+#define W_TMP1 %xmm0
+#define W_TMP2 %xmm9
+
+#define W0     %xmm1
+#define W4     %xmm2
+#define W8     %xmm3
+#define W12    %xmm4
+#define W16    %xmm5
+#define W20    %xmm6
+#define W24    %xmm7
+#define W28    %xmm8
+
+#define XMM_SHUFB_BSWAP        %xmm10
+
+/* we keep window of 64 w[i]+K pre-calculated values in a circular buffer */
+#define WK(t)  (((t) & 15) * 4)(%rsp)
+#define W_PRECALC_AHEAD        16
+
+/*
+ * This macro implements the SHA-1 function's body for single 64-byte block
+ * param: function's name
+ */
+.macro SHA1_VECTOR_ASM  name
+       .global \name
+       .type   \name, @function
+       .align 32
+\name:
+       push    %rbx
+       push    %rbp
+       push    %r12
+
+       mov     %rsp, %r12
+       sub     $64, %rsp               # allocate workspace
+       and     $~15, %rsp              # align stack
+
+       mov     CTX, HASH_PTR
+       mov     BUF, BUFFER_PTR
+
+       shl     $6, CNT                 # multiply by 64
+       add     BUF, CNT
+       mov     CNT, BUFFER_END
+
+       lea     K_XMM_AR(%rip), K_BASE
+       xmm_mov BSWAP_SHUFB_CTL(%rip), XMM_SHUFB_BSWAP
+
+       SHA1_PIPELINED_MAIN_BODY
+
+       # cleanup workspace
+       mov     $8, %ecx
+       mov     %rsp, %rdi
+       xor     %rax, %rax
+       rep stosq
+
+       mov     %r12, %rsp              # deallocate workspace
+
+       pop     %r12
+       pop     %rbp
+       pop     %rbx
+       ret
+
+       .size   \name, .-\name
+.endm
+
+/*
+ * This macro implements 80 rounds of SHA-1 for one 64-byte block
+ */
+.macro SHA1_PIPELINED_MAIN_BODY
+       INIT_REGALLOC
+
+       mov       (HASH_PTR), A
+       mov      4(HASH_PTR), B
+       mov      8(HASH_PTR), C
+       mov     12(HASH_PTR), D
+       mov     16(HASH_PTR), E
+
+  .set i, 0
+  .rept W_PRECALC_AHEAD
+       W_PRECALC i
+    .set i, (i+1)
+  .endr
+
+.align 4
+1:
+       RR F1,A,B,C,D,E,0
+       RR F1,D,E,A,B,C,2
+       RR F1,B,C,D,E,A,4
+       RR F1,E,A,B,C,D,6
+       RR F1,C,D,E,A,B,8
+
+       RR F1,A,B,C,D,E,10
+       RR F1,D,E,A,B,C,12
+       RR F1,B,C,D,E,A,14
+       RR F1,E,A,B,C,D,16
+       RR F1,C,D,E,A,B,18
+
+       RR F2,A,B,C,D,E,20
+       RR F2,D,E,A,B,C,22
+       RR F2,B,C,D,E,A,24
+       RR F2,E,A,B,C,D,26
+       RR F2,C,D,E,A,B,28
+
+       RR F2,A,B,C,D,E,30
+       RR F2,D,E,A,B,C,32
+       RR F2,B,C,D,E,A,34
+       RR F2,E,A,B,C,D,36
+       RR F2,C,D,E,A,B,38
+
+       RR F3,A,B,C,D,E,40
+       RR F3,D,E,A,B,C,42
+       RR F3,B,C,D,E,A,44
+       RR F3,E,A,B,C,D,46
+       RR F3,C,D,E,A,B,48
+
+       RR F3,A,B,C,D,E,50
+       RR F3,D,E,A,B,C,52
+       RR F3,B,C,D,E,A,54
+       RR F3,E,A,B,C,D,56
+       RR F3,C,D,E,A,B,58
+
+       add     $64, BUFFER_PTR         # move to the next 64-byte block
+       cmp     BUFFER_END, BUFFER_PTR  # if the current is the last one use
+       cmovae  K_BASE, BUFFER_PTR      # dummy source to avoid buffer overrun
+
+       RR F4,A,B,C,D,E,60
+       RR F4,D,E,A,B,C,62
+       RR F4,B,C,D,E,A,64
+       RR F4,E,A,B,C,D,66
+       RR F4,C,D,E,A,B,68
+
+       RR F4,A,B,C,D,E,70
+       RR F4,D,E,A,B,C,72
+       RR F4,B,C,D,E,A,74
+       RR F4,E,A,B,C,D,76
+       RR F4,C,D,E,A,B,78
+
+       UPDATE_HASH   (HASH_PTR), A
+       UPDATE_HASH  4(HASH_PTR), B
+       UPDATE_HASH  8(HASH_PTR), C
+       UPDATE_HASH 12(HASH_PTR), D
+       UPDATE_HASH 16(HASH_PTR), E
+
+       RESTORE_RENAMED_REGS
+       cmp     K_BASE, BUFFER_PTR      # K_BASE means, we reached the end
+       jne     1b
+.endm
+
+.macro INIT_REGALLOC
+  .set A, REG_A
+  .set B, REG_B
+  .set C, REG_C
+  .set D, REG_D
+  .set E, REG_E
+  .set T1, REG_T1
+  .set T2, REG_T2
+.endm
+
+.macro RESTORE_RENAMED_REGS
+       # order is important (REG_C is where it should be)
+       mov     B, REG_B
+       mov     D, REG_D
+       mov     A, REG_A
+       mov     E, REG_E
+.endm
+
+.macro SWAP_REG_NAMES  a, b
+  .set _T, \a
+  .set \a, \b
+  .set \b, _T
+.endm
+
+.macro F1  b, c, d
+       mov     \c, T1
+       SWAP_REG_NAMES \c, T1
+       xor     \d, T1
+       and     \b, T1
+       xor     \d, T1
+.endm
+
+.macro F2  b, c, d
+       mov     \d, T1
+       SWAP_REG_NAMES \d, T1
+       xor     \c, T1
+       xor     \b, T1
+.endm
+
+.macro F3  b, c ,d
+       mov     \c, T1
+       SWAP_REG_NAMES \c, T1
+       mov     \b, T2
+       or      \b, T1
+       and     \c, T2
+       and     \d, T1
+       or      T2, T1
+.endm
+
+.macro F4  b, c, d
+       F2 \b, \c, \d
+.endm
+
+.macro UPDATE_HASH  hash, val
+       add     \hash, \val
+       mov     \val, \hash
+.endm
+
+/*
+ * RR does two rounds of SHA-1 back to back with W[] pre-calc
+ *   t1 = F(b, c, d);   e += w(i)
+ *   e += t1;           b <<= 30;   d  += w(i+1);
+ *   t1 = F(a, b, c);
+ *   d += t1;           a <<= 5;
+ *   e += a;
+ *   t1 = e;            a >>= 7;
+ *   t1 <<= 5;
+ *   d += t1;
+ */
+.macro RR  F, a, b, c, d, e, round
+       add     WK(\round), \e
+       \F   \b, \c, \d         # t1 = F(b, c, d);
+       W_PRECALC (\round + W_PRECALC_AHEAD)
+       rol     $30, \b
+       add     T1, \e
+       add     WK(\round + 1), \d
+
+       \F   \a, \b, \c
+       W_PRECALC (\round + W_PRECALC_AHEAD + 1)
+       rol     $5, \a
+       add     \a, \e
+       add     T1, \d
+       ror     $7, \a          # (a <<r 5) >>r 7) => a <<r 30)
+
+       mov     \e, T1
+       SWAP_REG_NAMES \e, T1
+
+       rol     $5, T1
+       add     T1, \d
+
+       # write:  \a, \b
+       # rotate: \a<=\d, \b<=\e, \c<=\a, \d<=\b, \e<=\c
+.endm
+
+.macro W_PRECALC  r
+  .set i, \r
+
+  .if (i < 20)
+    .set K_XMM, 0
+  .elseif (i < 40)
+    .set K_XMM, 16
+  .elseif (i < 60)
+    .set K_XMM, 32
+  .elseif (i < 80)
+    .set K_XMM, 48
+  .endif
+
+  .if ((i < 16) || ((i >= 80) && (i < (80 + W_PRECALC_AHEAD))))
+    .set i, ((\r) % 80)            # pre-compute for the next iteration
+    .if (i == 0)
+       W_PRECALC_RESET
+    .endif
+       W_PRECALC_00_15
+  .elseif (i<32)
+       W_PRECALC_16_31
+  .elseif (i < 80)   // rounds 32-79
+       W_PRECALC_32_79
+  .endif
+.endm
+
+.macro W_PRECALC_RESET
+  .set W,          W0
+  .set W_minus_04, W4
+  .set W_minus_08, W8
+  .set W_minus_12, W12
+  .set W_minus_16, W16
+  .set W_minus_20, W20
+  .set W_minus_24, W24
+  .set W_minus_28, W28
+  .set W_minus_32, W
+.endm
+
+.macro W_PRECALC_ROTATE
+  .set W_minus_32, W_minus_28
+  .set W_minus_28, W_minus_24
+  .set W_minus_24, W_minus_20
+  .set W_minus_20, W_minus_16
+  .set W_minus_16, W_minus_12
+  .set W_minus_12, W_minus_08
+  .set W_minus_08, W_minus_04
+  .set W_minus_04, W
+  .set W,          W_minus_32
+.endm
+
+.macro W_PRECALC_SSSE3
+
+.macro W_PRECALC_00_15
+       W_PRECALC_00_15_SSSE3
+.endm
+.macro W_PRECALC_16_31
+       W_PRECALC_16_31_SSSE3
+.endm
+.macro W_PRECALC_32_79
+       W_PRECALC_32_79_SSSE3
+.endm
+
+/* message scheduling pre-compute for rounds 0-15 */
+.macro W_PRECALC_00_15_SSSE3
+  .if ((i & 3) == 0)
+       movdqu  (i*4)(BUFFER_PTR), W_TMP1
+  .elseif ((i & 3) == 1)
+       pshufb  XMM_SHUFB_BSWAP, W_TMP1
+       movdqa  W_TMP1, W
+  .elseif ((i & 3) == 2)
+       paddd   (K_BASE), W_TMP1
+  .elseif ((i & 3) == 3)
+       movdqa  W_TMP1, WK(i&~3)
+       W_PRECALC_ROTATE
+  .endif
+.endm
+
+/* message scheduling pre-compute for rounds 16-31
+ *
+ * - calculating last 32 w[i] values in 8 XMM registers
+ * - pre-calculate K+w[i] values and store to mem, for later load by ALU add
+ *   instruction
+ *
+ * some "heavy-lifting" vectorization for rounds 16-31 due to w[i]->w[i-3]
+ * dependency, but improves for 32-79
+ */
+.macro W_PRECALC_16_31_SSSE3
+  # blended scheduling of vector and scalar instruction streams, one 4-wide
+  # vector iteration / 4 scalar rounds
+  .if ((i & 3) == 0)
+       movdqa  W_minus_12, W
+       palignr $8, W_minus_16, W       # w[i-14]
+       movdqa  W_minus_04, W_TMP1
+       psrldq  $4, W_TMP1              # w[i-3]
+       pxor    W_minus_08, W
+  .elseif ((i & 3) == 1)
+       pxor    W_minus_16, W_TMP1
+       pxor    W_TMP1, W
+       movdqa  W, W_TMP2
+       movdqa  W, W_TMP1
+       pslldq  $12, W_TMP2
+  .elseif ((i & 3) == 2)
+       psrld   $31, W
+       pslld   $1, W_TMP1
+       por     W, W_TMP1
+       movdqa  W_TMP2, W
+       psrld   $30, W_TMP2
+       pslld   $2, W
+  .elseif ((i & 3) == 3)
+       pxor    W, W_TMP1
+       pxor    W_TMP2, W_TMP1
+       movdqa  W_TMP1, W
+       paddd   K_XMM(K_BASE), W_TMP1
+       movdqa  W_TMP1, WK(i&~3)
+       W_PRECALC_ROTATE
+  .endif
+.endm
+
+/* message scheduling pre-compute for rounds 32-79
+ *
+ * in SHA-1 specification: w[i] = (w[i-3] ^ w[i-8]  ^ w[i-14] ^ w[i-16]) rol 1
+ * instead we do equal:    w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]) rol 2
+ * allows more efficient vectorization since w[i]=>w[i-3] dependency is broken
+ */
+.macro W_PRECALC_32_79_SSSE3
+  .if ((i & 3) == 0)
+       movdqa  W_minus_04, W_TMP1
+       pxor    W_minus_28, W           # W is W_minus_32 before xor
+       palignr $8, W_minus_08, W_TMP1
+  .elseif ((i & 3) == 1)
+       pxor    W_minus_16, W
+       pxor    W_TMP1, W
+       movdqa  W, W_TMP1
+  .elseif ((i & 3) == 2)
+       psrld   $30, W
+       pslld   $2, W_TMP1
+       por     W, W_TMP1
+  .elseif ((i & 3) == 3)
+       movdqa  W_TMP1, W
+       paddd   K_XMM(K_BASE), W_TMP1
+       movdqa  W_TMP1, WK(i&~3)
+       W_PRECALC_ROTATE
+  .endif
+.endm
+
+.endm          // W_PRECALC_SSSE3
+
+
+#define K1     0x5a827999
+#define K2     0x6ed9eba1
+#define K3     0x8f1bbcdc
+#define K4     0xca62c1d6
+
+.section .rodata
+.align 16
+
+K_XMM_AR:
+       .long K1, K1, K1, K1
+       .long K2, K2, K2, K2
+       .long K3, K3, K3, K3
+       .long K4, K4, K4, K4
+
+BSWAP_SHUFB_CTL:
+       .long 0x00010203
+       .long 0x04050607
+       .long 0x08090a0b
+       .long 0x0c0d0e0f
+
+
+.section .text
+
+W_PRECALC_SSSE3
+.macro xmm_mov a, b
+       movdqu  \a,\b
+.endm
+
+/* SSSE3 optimized implementation:
+ *  extern "C" void sha1_transform_ssse3(u32 *digest, const char *data, u32 *ws,
+ *                                       unsigned int rounds);
+ */
+SHA1_VECTOR_ASM     sha1_transform_ssse3
+
+#ifdef SHA1_ENABLE_AVX_SUPPORT
+
+.macro W_PRECALC_AVX
+
+.purgem W_PRECALC_00_15
+.macro  W_PRECALC_00_15
+    W_PRECALC_00_15_AVX
+.endm
+.purgem W_PRECALC_16_31
+.macro  W_PRECALC_16_31
+    W_PRECALC_16_31_AVX
+.endm
+.purgem W_PRECALC_32_79
+.macro  W_PRECALC_32_79
+    W_PRECALC_32_79_AVX
+.endm
+
+.macro W_PRECALC_00_15_AVX
+  .if ((i & 3) == 0)
+       vmovdqu (i*4)(BUFFER_PTR), W_TMP1
+  .elseif ((i & 3) == 1)
+       vpshufb XMM_SHUFB_BSWAP, W_TMP1, W
+  .elseif ((i & 3) == 2)
+       vpaddd  (K_BASE), W, W_TMP1
+  .elseif ((i & 3) == 3)
+       vmovdqa W_TMP1, WK(i&~3)
+       W_PRECALC_ROTATE
+  .endif
+.endm
+
+.macro W_PRECALC_16_31_AVX
+  .if ((i & 3) == 0)
+       vpalignr $8, W_minus_16, W_minus_12, W  # w[i-14]
+       vpsrldq $4, W_minus_04, W_TMP1          # w[i-3]
+       vpxor   W_minus_08, W, W
+       vpxor   W_minus_16, W_TMP1, W_TMP1
+  .elseif ((i & 3) == 1)
+       vpxor   W_TMP1, W, W
+       vpslldq $12, W, W_TMP2
+       vpslld  $1, W, W_TMP1
+  .elseif ((i & 3) == 2)
+       vpsrld  $31, W, W
+       vpor    W, W_TMP1, W_TMP1
+       vpslld  $2, W_TMP2, W
+       vpsrld  $30, W_TMP2, W_TMP2
+  .elseif ((i & 3) == 3)
+       vpxor   W, W_TMP1, W_TMP1
+       vpxor   W_TMP2, W_TMP1, W
+       vpaddd  K_XMM(K_BASE), W, W_TMP1
+       vmovdqu W_TMP1, WK(i&~3)
+       W_PRECALC_ROTATE
+  .endif
+.endm
+
+.macro W_PRECALC_32_79_AVX
+  .if ((i & 3) == 0)
+       vpalignr $8, W_minus_08, W_minus_04, W_TMP1
+       vpxor   W_minus_28, W, W                # W is W_minus_32 before xor
+  .elseif ((i & 3) == 1)
+       vpxor   W_minus_16, W_TMP1, W_TMP1
+       vpxor   W_TMP1, W, W
+  .elseif ((i & 3) == 2)
+       vpslld  $2, W, W_TMP1
+       vpsrld  $30, W, W
+       vpor    W, W_TMP1, W
+  .elseif ((i & 3) == 3)
+       vpaddd  K_XMM(K_BASE), W, W_TMP1
+       vmovdqu W_TMP1, WK(i&~3)
+       W_PRECALC_ROTATE
+  .endif
+.endm
+
+.endm    // W_PRECALC_AVX
+
+W_PRECALC_AVX
+.purgem xmm_mov
+.macro xmm_mov a, b
+       vmovdqu \a,\b
+.endm
+
+
+/* AVX optimized implementation:
+ *  extern "C" void sha1_transform_avx(u32 *digest, const char *data, u32 *ws,
+ *                                     unsigned int rounds);
+ */
+SHA1_VECTOR_ASM     sha1_transform_avx
+
+#endif
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c
new file mode 100644 (file)
index 0000000..f916499
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Cryptographic API.
+ *
+ * Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
+ * Supplemental SSE3 instructions.
+ *
+ * This file is based on sha1_generic.c
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) Mathias Krause <minipli@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
+#include <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <crypto/sha.h>
+#include <asm/byteorder.h>
+#include <asm/i387.h>
+#include <asm/xcr.h>
+#include <asm/xsave.h>
+
+
+asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data,
+                                    unsigned int rounds);
+#ifdef SHA1_ENABLE_AVX_SUPPORT
+asmlinkage void sha1_transform_avx(u32 *digest, const char *data,
+                                  unsigned int rounds);
+#endif
+
+static asmlinkage void (*sha1_transform_asm)(u32 *, const char *, unsigned int);
+
+
+static int sha1_ssse3_init(struct shash_desc *desc)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       *sctx = (struct sha1_state){
+               .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
+       };
+
+       return 0;
+}
+
+static int __sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
+                              unsigned int len, unsigned int partial)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+       unsigned int done = 0;
+
+       sctx->count += len;
+
+       if (partial) {
+               done = SHA1_BLOCK_SIZE - partial;
+               memcpy(sctx->buffer + partial, data, done);
+               sha1_transform_asm(sctx->state, sctx->buffer, 1);
+       }
+
+       if (len - done >= SHA1_BLOCK_SIZE) {
+               const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
+
+               sha1_transform_asm(sctx->state, data + done, rounds);
+               done += rounds * SHA1_BLOCK_SIZE;
+       }
+
+       memcpy(sctx->buffer, data + done, len - done);
+
+       return 0;
+}
+
+static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
+                            unsigned int len)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+       unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
+       int res;
+
+       /* Handle the fast case right here */
+       if (partial + len < SHA1_BLOCK_SIZE) {
+               sctx->count += len;
+               memcpy(sctx->buffer + partial, data, len);
+
+               return 0;
+       }
+
+       if (!irq_fpu_usable()) {
+               res = crypto_sha1_update(desc, data, len);
+       } else {
+               kernel_fpu_begin();
+               res = __sha1_ssse3_update(desc, data, len, partial);
+               kernel_fpu_end();
+       }
+
+       return res;
+}
+
+
+/* Add padding and return the message digest. */
+static int sha1_ssse3_final(struct shash_desc *desc, u8 *out)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+       unsigned int i, index, padlen;
+       __be32 *dst = (__be32 *)out;
+       __be64 bits;
+       static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
+
+       bits = cpu_to_be64(sctx->count << 3);
+
+       /* Pad out to 56 mod 64 and append length */
+       index = sctx->count % SHA1_BLOCK_SIZE;
+       padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index);
+       if (!irq_fpu_usable()) {
+               crypto_sha1_update(desc, padding, padlen);
+               crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
+       } else {
+               kernel_fpu_begin();
+               /* We need to fill a whole block for __sha1_ssse3_update() */
+               if (padlen <= 56) {
+                       sctx->count += padlen;
+                       memcpy(sctx->buffer + index, padding, padlen);
+               } else {
+                       __sha1_ssse3_update(desc, padding, padlen, index);
+               }
+               __sha1_ssse3_update(desc, (const u8 *)&bits, sizeof(bits), 56);
+               kernel_fpu_end();
+       }
+
+       /* Store state in digest */
+       for (i = 0; i < 5; i++)
+               dst[i] = cpu_to_be32(sctx->state[i]);
+
+       /* Wipe context */
+       memset(sctx, 0, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha1_ssse3_export(struct shash_desc *desc, void *out)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(out, sctx, sizeof(*sctx));
+
+       return 0;
+}
+
+static int sha1_ssse3_import(struct shash_desc *desc, const void *in)
+{
+       struct sha1_state *sctx = shash_desc_ctx(desc);
+
+       memcpy(sctx, in, sizeof(*sctx));
+
+       return 0;
+}
+
+static struct shash_alg alg = {
+       .digestsize     =       SHA1_DIGEST_SIZE,
+       .init           =       sha1_ssse3_init,
+       .update         =       sha1_ssse3_update,
+       .final          =       sha1_ssse3_final,
+       .export         =       sha1_ssse3_export,
+       .import         =       sha1_ssse3_import,
+       .descsize       =       sizeof(struct sha1_state),
+       .statesize      =       sizeof(struct sha1_state),
+       .base           =       {
+               .cra_name       =       "sha1",
+               .cra_driver_name=       "sha1-ssse3",
+               .cra_priority   =       150,
+               .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
+               .cra_blocksize  =       SHA1_BLOCK_SIZE,
+               .cra_module     =       THIS_MODULE,
+       }
+};
+
+#ifdef SHA1_ENABLE_AVX_SUPPORT
+static bool __init avx_usable(void)
+{
+       u64 xcr0;
+
+       if (!cpu_has_avx || !cpu_has_osxsave)
+               return false;
+
+       xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
+       if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) {
+               pr_info("AVX detected but unusable.\n");
+
+               return false;
+       }
+
+       return true;
+}
+#endif
+
+static int __init sha1_ssse3_mod_init(void)
+{
+       /* test for SSSE3 first */
+       if (cpu_has_ssse3)
+               sha1_transform_asm = sha1_transform_ssse3;
+
+#ifdef SHA1_ENABLE_AVX_SUPPORT
+       /* allow AVX to override SSSE3, it's a little faster */
+       if (avx_usable())
+               sha1_transform_asm = sha1_transform_avx;
+#endif
+
+       if (sha1_transform_asm) {
+               pr_info("Using %s optimized SHA-1 implementation\n",
+                       sha1_transform_asm == sha1_transform_ssse3 ? "SSSE3"
+                                                                  : "AVX");
+               return crypto_register_shash(&alg);
+       }
+       pr_info("Neither AVX nor SSSE3 is available/usable.\n");
+
+       return -ENODEV;
+}
+
+static void __exit sha1_ssse3_mod_fini(void)
+{
+       crypto_unregister_shash(&alg);
+}
+
+module_init(sha1_ssse3_mod_init);
+module_exit(sha1_ssse3_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, Supplemental SSE3 accelerated");
+
+MODULE_ALIAS("sha1");
diff --git a/arch/x86/include/asm/archrandom.h b/arch/x86/include/asm/archrandom.h
new file mode 100644 (file)
index 0000000..0d9ec77
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the Linux kernel.
+ *
+ * Copyright (c) 2011, Intel Corporation
+ * Authors: Fenghua Yu <fenghua.yu@intel.com>,
+ *          H. Peter Anvin <hpa@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef ASM_X86_ARCHRANDOM_H
+#define ASM_X86_ARCHRANDOM_H
+
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
+#include <asm/nops.h>
+
+#define RDRAND_RETRY_LOOPS     10
+
+#define RDRAND_INT     ".byte 0x0f,0xc7,0xf0"
+#ifdef CONFIG_X86_64
+# define RDRAND_LONG   ".byte 0x48,0x0f,0xc7,0xf0"
+#else
+# define RDRAND_LONG   RDRAND_INT
+#endif
+
+#ifdef CONFIG_ARCH_RANDOM
+
+#define GET_RANDOM(name, type, rdrand, nop)                    \
+static inline int name(type *v)                                        \
+{                                                              \
+       int ok;                                                 \
+       alternative_io("movl $0, %0\n\t"                        \
+                      nop,                                     \
+                      "\n1: " rdrand "\n\t"                    \
+                      "jc 2f\n\t"                              \
+                      "decl %0\n\t"                            \
+                      "jnz 1b\n\t"                             \
+                      "2:",                                    \
+                      X86_FEATURE_RDRAND,                      \
+                      ASM_OUTPUT2("=r" (ok), "=a" (*v)),       \
+                      "0" (RDRAND_RETRY_LOOPS));               \
+       return ok;                                              \
+}
+
+#ifdef CONFIG_X86_64
+
+GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP5);
+GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP4);
+
+#else
+
+GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP3);
+GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);
+
+#endif /* CONFIG_X86_64 */
+
+#endif  /* CONFIG_ARCH_RANDOM */
+
+extern void x86_init_rdrand(struct cpuinfo_x86 *c);
+
+#endif /* ASM_X86_ARCHRANDOM_H */
index 3deb7250624c268c3b8ae819f6ef2c8081abc8c4..d4b09d9a98efd962bf442554ab854d34d5ac4dea 100644 (file)
@@ -280,6 +280,27 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
 
 #endif
 
+#define xadd(ptr, inc)                                                 \
+       do {                                                            \
+               switch (sizeof(*(ptr))) {                               \
+               case 1:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddb %b0, %1\n"     \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               case 2:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddw %w0, %1\n"     \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               case 4:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddl %0, %1\n"      \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               }                                                       \
+       } while(0)
+
 #define cmpxchg8b(ptr, o1, o2, n1, n2)                         \
 ({                                                             \
        char __ret;                                             \
index 7cf5c0a2443405532b274e872b7e2063ab57de8e..8c5c836eccd6d1e43f2e6303809809f85f832e8a 100644 (file)
@@ -151,6 +151,32 @@ extern void __cmpxchg_wrong_size(void);
        cmpxchg_local((ptr), (o), (n));                                 \
 })
 
+#define xadd(ptr, inc)                                                 \
+       do {                                                            \
+               switch (sizeof(*(ptr))) {                               \
+               case 1:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddb %b0, %1\n"     \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               case 2:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddw %w0, %1\n"     \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               case 4:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddl %0, %1\n"      \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               case 8:                                                 \
+                       asm volatile (LOCK_PREFIX "xaddq %q0, %1\n"     \
+                                     : "+r" (inc), "+m" (*(ptr))       \
+                                     : : "memory", "cc");              \
+                       break;                                          \
+               }                                                       \
+       } while(0)
+
 #define cmpxchg16b(ptr, o1, o2, n1, n2)                                \
 ({                                                             \
        char __ret;                                             \
index 4258aac99a6e8b6493164929c3c75173cb2941c6..48a93ef5c84b3bfdf6e4ce9ca8651747bc610689 100644 (file)
@@ -257,7 +257,9 @@ extern const char * const x86_power_flags[32];
 #define cpu_has_xmm            boot_cpu_has(X86_FEATURE_XMM)
 #define cpu_has_xmm2           boot_cpu_has(X86_FEATURE_XMM2)
 #define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
+#define cpu_has_ssse3          boot_cpu_has(X86_FEATURE_SSSE3)
 #define cpu_has_aes            boot_cpu_has(X86_FEATURE_AES)
+#define cpu_has_avx            boot_cpu_has(X86_FEATURE_AVX)
 #define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
 #define cpu_has_mp             boot_cpu_has(X86_FEATURE_MP)
 #define cpu_has_nx             boot_cpu_has(X86_FEATURE_NX)
@@ -285,6 +287,7 @@ extern const char * const x86_power_flags[32];
 #define cpu_has_xmm4_2         boot_cpu_has(X86_FEATURE_XMM4_2)
 #define cpu_has_x2apic         boot_cpu_has(X86_FEATURE_X2APIC)
 #define cpu_has_xsave          boot_cpu_has(X86_FEATURE_XSAVE)
+#define cpu_has_osxsave                boot_cpu_has(X86_FEATURE_OSXSAVE)
 #define cpu_has_hypervisor     boot_cpu_has(X86_FEATURE_HYPERVISOR)
 #define cpu_has_pclmulqdq      boot_cpu_has(X86_FEATURE_PCLMULQDQ)
 #define cpu_has_perfctr_core   boot_cpu_has(X86_FEATURE_PERFCTR_CORE)
index f2ad2163109daab72f9fed6bee91839f3e83601e..5f962df30d0f18ed08fe2e321621617d1da39df3 100644 (file)
@@ -4,6 +4,7 @@
 /*
  * ELF register definitions..
  */
+#include <linux/thread_info.h>
 
 #include <asm/ptrace.h>
 #include <asm/user.h>
@@ -320,4 +321,34 @@ extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
+/*
+ * True on X86_32 or when emulating IA32 on X86_64
+ */
+static inline int mmap_is_ia32(void)
+{
+#ifdef CONFIG_X86_32
+       return 1;
+#endif
+#ifdef CONFIG_IA32_EMULATION
+       if (test_thread_flag(TIF_IA32))
+               return 1;
+#endif
+       return 0;
+}
+
+/* The first two values are special, do not change. See align_addr() */
+enum align_flags {
+       ALIGN_VA_32     = BIT(0),
+       ALIGN_VA_64     = BIT(1),
+       ALIGN_VDSO      = BIT(2),
+       ALIGN_TOPDOWN   = BIT(3),
+};
+
+struct va_alignment {
+       int flags;
+       unsigned long mask;
+} ____cacheline_aligned;
+
+extern struct va_alignment va_align;
+extern unsigned long align_addr(unsigned long, struct file *, enum align_flags);
 #endif /* _ASM_X86_ELF_H */
index 013286a10c2c03680d10e5a2938f800e90581514..0a1129371f820b028c57b655268c86ac0953dfb2 100644 (file)
@@ -301,7 +301,6 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
 /* Install a pte for a particular vaddr in kernel space. */
 void set_pte_vaddr(unsigned long vaddr, pte_t pte);
 
-extern void native_pagetable_reserve(u64 start, u64 end);
 #ifdef CONFIG_X86_32
 extern void native_pagetable_setup_start(pgd_t *base);
 extern void native_pagetable_setup_done(pgd_t *base);
index ee67edf86fdd98929998276ad8e5ab02c93c333a..7edca0d03c450d432298327e4db72a221422f45d 100644 (file)
  * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock
  * (PPro errata 66, 92)
  */
-# define UNLOCK_LOCK_PREFIX LOCK_PREFIX
+static __always_inline void __ticket_unlock_release(struct arch_spinlock *lock)
+{
+       if (sizeof(lock->tickets.head) == sizeof(u8))
+               asm volatile(LOCK_PREFIX "incb %0"
+                            : "+m" (lock->tickets.head) : : "memory");
+       else
+               asm volatile(LOCK_PREFIX "incw %0"
+                            : "+m" (lock->tickets.head) : : "memory");
+
+}
 #else
-# define UNLOCK_LOCK_PREFIX
+static __always_inline void __ticket_unlock_release(struct arch_spinlock *lock)
+{
+       lock->tickets.head++;
+}
 #endif
 
 /*
  * save some instructions and make the code more elegant. There really isn't
  * much between them in performance though, especially as locks are out of line.
  */
-#if (NR_CPUS < 256)
-#define TICKET_SHIFT 8
-
-static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
+static __always_inline struct __raw_tickets __ticket_spin_claim(struct arch_spinlock *lock)
 {
-       short inc = 0x0100;
-
-       asm volatile (
-               LOCK_PREFIX "xaddw %w0, %1\n"
-               "1:\t"
-               "cmpb %h0, %b0\n\t"
-               "je 2f\n\t"
-               "rep ; nop\n\t"
-               "movb %1, %b0\n\t"
-               /* don't need lfence here, because loads are in-order */
-               "jmp 1b\n"
-               "2:"
-               : "+Q" (inc), "+m" (lock->slock)
-               :
-               : "memory", "cc");
-}
+       register struct __raw_tickets tickets = { .tail = 1 };
 
-static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
-{
-       int tmp, new;
-
-       asm volatile("movzwl %2, %0\n\t"
-                    "cmpb %h0,%b0\n\t"
-                    "leal 0x100(%" REG_PTR_MODE "0), %1\n\t"
-                    "jne 1f\n\t"
-                    LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
-                    "1:"
-                    "sete %b1\n\t"
-                    "movzbl %b1,%0\n\t"
-                    : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
-                    :
-                    : "memory", "cc");
-
-       return tmp;
-}
+       xadd(&lock->tickets, tickets);
 
-static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
-{
-       asm volatile(UNLOCK_LOCK_PREFIX "incb %0"
-                    : "+m" (lock->slock)
-                    :
-                    : "memory", "cc");
+       return tickets;
 }
-#else
-#define TICKET_SHIFT 16
 
-static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(struct arch_spinlock *lock)
 {
-       int inc = 0x00010000;
-       int tmp;
-
-       asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
-                    "movzwl %w0, %2\n\t"
-                    "shrl $16, %0\n\t"
-                    "1:\t"
-                    "cmpl %0, %2\n\t"
-                    "je 2f\n\t"
-                    "rep ; nop\n\t"
-                    "movzwl %1, %2\n\t"
-                    /* don't need lfence here, because loads are in-order */
-                    "jmp 1b\n"
-                    "2:"
-                    : "+r" (inc), "+m" (lock->slock), "=&r" (tmp)
-                    :
-                    : "memory", "cc");
+       register struct __raw_tickets inc;
+
+       inc = __ticket_spin_claim(lock);
+
+       for (;;) {
+               if (inc.head == inc.tail)
+                       goto out;
+               cpu_relax();
+               inc.head = ACCESS_ONCE(lock->tickets.head);
+       }
+out:   barrier();              /* make sure nothing creeps before the lock is taken */
 }
 
 static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
 {
-       int tmp;
-       int new;
-
-       asm volatile("movl %2,%0\n\t"
-                    "movl %0,%1\n\t"
-                    "roll $16, %0\n\t"
-                    "cmpl %0,%1\n\t"
-                    "leal 0x00010000(%" REG_PTR_MODE "0), %1\n\t"
-                    "jne 1f\n\t"
-                    LOCK_PREFIX "cmpxchgl %1,%2\n\t"
-                    "1:"
-                    "sete %b1\n\t"
-                    "movzbl %b1,%0\n\t"
-                    : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
-                    :
-                    : "memory", "cc");
-
-       return tmp;
+       arch_spinlock_t old, new;
+
+       old.tickets = ACCESS_ONCE(lock->tickets);
+       if (old.tickets.head != old.tickets.tail)
+               return 0;
+
+       new.head_tail = old.head_tail + (1 << TICKET_SHIFT);
+
+       /* cmpxchg is a full barrier, so nothing can move before it */
+       return cmpxchg(&lock->head_tail, old.head_tail, new.head_tail) == old.head_tail;
 }
 
 static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
 {
-       asm volatile(UNLOCK_LOCK_PREFIX "incw %0"
-                    : "+m" (lock->slock)
-                    :
-                    : "memory", "cc");
+       barrier();              /* prevent reordering out of locked region */
+       __ticket_unlock_release(lock);
+       barrier();              /* prevent reordering into locked region */
 }
-#endif
 
 static inline int __ticket_spin_is_locked(arch_spinlock_t *lock)
 {
-       int tmp = ACCESS_ONCE(lock->slock);
+       struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets);
 
-       return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1 << TICKET_SHIFT) - 1));
+       return !!(tmp.tail ^ tmp.head);
 }
 
 static inline int __ticket_spin_is_contended(arch_spinlock_t *lock)
 {
-       int tmp = ACCESS_ONCE(lock->slock);
+       struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets);
 
-       return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1;
+       return ((tmp.tail - tmp.head) & TICKET_MASK) > 1;
 }
 
 #ifndef CONFIG_PARAVIRT_SPINLOCKS
index 7c7a486fcb6811e68dc140085061e15df8bbd569..8ebd5df7451e28b88a8a155bf3ff7dcb081ddb35 100644 (file)
@@ -5,11 +5,29 @@
 # error "please don't include this file directly"
 #endif
 
+#include <linux/types.h>
+
+#if (CONFIG_NR_CPUS < 256)
+typedef u8  __ticket_t;
+typedef u16 __ticketpair_t;
+#else
+typedef u16 __ticket_t;
+typedef u32 __ticketpair_t;
+#endif
+
+#define TICKET_SHIFT   (sizeof(__ticket_t) * 8)
+#define TICKET_MASK    ((__ticket_t)((1 << TICKET_SHIFT) - 1))
+
 typedef struct arch_spinlock {
-       unsigned int slock;
+       union {
+               __ticketpair_t head_tail;
+               struct __raw_tickets {
+                       __ticket_t head, tail;
+               } tickets;
+       };
 } arch_spinlock_t;
 
-#define __ARCH_SPIN_LOCK_UNLOCKED      { 0 }
+#define __ARCH_SPIN_LOCK_UNLOCKED      { { 0 } }
 
 #include <asm/rwlock.h>
 
index a1fe5c127b52f353ba55c3f12eb14ad71e0010fb..32125af20d32a8f50c61dfc474d6a2b45a01ad41 100644 (file)
@@ -90,7 +90,6 @@ struct thread_info {
 #define TIF_MEMDIE             20      /* is terminating due to OOM killer */
 #define TIF_DEBUG              21      /* uses debug registers */
 #define TIF_IO_BITMAP          22      /* uses I/O bitmap */
-#define TIF_FREEZE             23      /* is freezing for suspend */
 #define TIF_FORCED_TF          24      /* true if TF in eflags artificially */
 #define TIF_BLOCKSTEP          25      /* set when we want DEBUGCTLMSR_BTF */
 #define TIF_LAZY_MMU_UPDATES   27      /* task is updating the mmu lazily */
@@ -112,7 +111,6 @@ struct thread_info {
 #define _TIF_FORK              (1 << TIF_FORK)
 #define _TIF_DEBUG             (1 << TIF_DEBUG)
 #define _TIF_IO_BITMAP         (1 << TIF_IO_BITMAP)
-#define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_FORCED_TF         (1 << TIF_FORCED_TF)
 #define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
 #define _TIF_LAZY_MMU_UPDATES  (1 << TIF_LAZY_MMU_UPDATES)
index d3d859035af9e1968d0ad9d4a39000331c27c8f1..643ebf2e2ad8733ddbec5ca884ee21bf405c0226 100644 (file)
@@ -67,17 +67,6 @@ struct x86_init_oem {
        void (*banner)(void);
 };
 
-/**
- * struct x86_init_mapping - platform specific initial kernel pagetable setup
- * @pagetable_reserve: reserve a range of addresses for kernel pagetable usage
- *
- * For more details on the purpose of this hook, look in
- * init_memory_mapping and the commit that added it.
- */
-struct x86_init_mapping {
-       void (*pagetable_reserve)(u64 start, u64 end);
-};
-
 /**
  * struct x86_init_paging - platform specific paging functions
  * @pagetable_setup_start:     platform specific pre paging_init() call
@@ -134,7 +123,6 @@ struct x86_init_ops {
        struct x86_init_mpparse         mpparse;
        struct x86_init_irqs            irqs;
        struct x86_init_oem             oem;
-       struct x86_init_mapping         mapping;
        struct x86_init_paging          paging;
        struct x86_init_timers          timers;
        struct x86_init_iommu           iommu;
index adc66c3a1fef2417be8741d334d5f8460c23ff10..34b18594e72467212f0e430c329e9fa523f3aa09 100644 (file)
@@ -207,7 +207,6 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri
            ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
            APIC_DM_INIT;
        uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
-       mdelay(10);
 
        val = (1UL << UVH_IPI_INT_SEND_SHFT) |
            (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
index 6042981d0309c492bdfb5032312a8e4f7cb0a5d1..0e3a82a41a6673d3aac217d6320c29242f049a62 100644 (file)
@@ -15,6 +15,7 @@ CFLAGS_common.o               := $(nostackp)
 obj-y                  := intel_cacheinfo.o scattered.o topology.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
 obj-y                  += vmware.o hypervisor.o sched.o mshyperv.o
+obj-y                  += rdrand.o
 
 obj-$(CONFIG_X86_32)   += bugs.o
 obj-$(CONFIG_X86_64)   += bugs_64.o
index b13ed393dfcee83b330443e378a922ed016d0514..13c6ec81254582e69eae8b6c69b703370b25fb18 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/elf.h>
 #include <linux/mm.h>
 
 #include <linux/io.h>
@@ -410,6 +411,34 @@ static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
 #endif
 }
 
+static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
+{
+       if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
+
+               if (c->x86 > 0x10 ||
+                   (c->x86 == 0x10 && c->x86_model >= 0x2)) {
+                       u64 val;
+
+                       rdmsrl(MSR_K7_HWCR, val);
+                       if (!(val & BIT(24)))
+                               printk(KERN_WARNING FW_BUG "TSC doesn't count "
+                                       "with P0 frequency!\n");
+               }
+       }
+
+       if (c->x86 == 0x15) {
+               unsigned long upperbit;
+               u32 cpuid, assoc;
+
+               cpuid    = cpuid_edx(0x80000005);
+               assoc    = cpuid >> 16 & 0xff;
+               upperbit = ((cpuid >> 24) << 10) / assoc;
+
+               va_align.mask     = (upperbit - 1) & PAGE_MASK;
+               va_align.flags    = ALIGN_VA_32 | ALIGN_VA_64;
+       }
+}
+
 static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
 {
        early_init_amd_mc(c);
@@ -441,23 +470,6 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
        }
 #endif
-
-       /* We need to do the following only once */
-       if (c != &boot_cpu_data)
-               return;
-
-       if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
-
-               if (c->x86 > 0x10 ||
-                   (c->x86 == 0x10 && c->x86_model >= 0x2)) {
-                       u64 val;
-
-                       rdmsrl(MSR_K7_HWCR, val);
-                       if (!(val & BIT(24)))
-                               printk(KERN_WARNING FW_BUG "TSC doesn't count "
-                                       "with P0 frequency!\n");
-               }
-       }
 }
 
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
@@ -679,6 +691,7 @@ static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
        .c_size_cache   = amd_size_cache,
 #endif
        .c_early_init   = early_init_amd,
+       .c_bsp_init     = bsp_init_amd,
        .c_init         = init_amd,
        .c_x86_vendor   = X86_VENDOR_AMD,
 };
index 62184390a60121ec74465ae5e17d01be86853f4a..aa003b13a83131db63e3f594c0cadb34e9f89b93 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/stackprotector.h>
 #include <asm/perf_event.h>
 #include <asm/mmu_context.h>
+#include <asm/archrandom.h>
 #include <asm/hypervisor.h>
 #include <asm/processor.h>
 #include <asm/sections.h>
@@ -681,6 +682,9 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
        filter_cpuid_features(c, false);
 
        setup_smep(c);
+
+       if (this_cpu->c_bsp_init)
+               this_cpu->c_bsp_init(c);
 }
 
 void __init early_cpu_init(void)
@@ -857,6 +861,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 #endif
 
        init_hypervisor(c);
+       x86_init_rdrand(c);
 
        /*
         * Clear/Set all flags overriden by options, need do it
index e765633f210ed893f56bc23ba26e6cfea6c074fd..1b22dcc51af44dceefe3eed0e532f2aa514c8c65 100644 (file)
@@ -18,6 +18,7 @@ struct cpu_dev {
        struct          cpu_model_info c_models[4];
 
        void            (*c_early_init)(struct cpuinfo_x86 *);
+       void            (*c_bsp_init)(struct cpuinfo_x86 *);
        void            (*c_init)(struct cpuinfo_x86 *);
        void            (*c_identify)(struct cpuinfo_x86 *);
        unsigned int    (*c_size_cache)(struct cpuinfo_x86 *, unsigned int);
index 08363b0421222b92b5765bd2116cf9d4ecfca4d9..63aad2742d8a20dddfc867ce7c24e7b3f393ddd1 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/debugfs.h>
-#include <linux/edac_mce.h>
 #include <linux/irq_work.h>
 
 #include <asm/processor.h>
@@ -144,23 +143,20 @@ static struct mce_log mcelog = {
 void mce_log(struct mce *mce)
 {
        unsigned next, entry;
+       int ret = 0;
 
        /* Emit the trace record: */
        trace_mce_record(mce);
 
+       ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
+       if (ret == NOTIFY_STOP)
+               return;
+
        mce->finished = 0;
        wmb();
        for (;;) {
                entry = rcu_dereference_check_mce(mcelog.next);
                for (;;) {
-                       /*
-                        * If edac_mce is enabled, it will check the error type
-                        * and will process it, if it is a known error.
-                        * Otherwise, the error will be sent through mcelog
-                        * interface
-                        */
-                       if (edac_mce_parse(mce))
-                               return;
 
                        /*
                         * When the buffer fills up discard new entries.
@@ -551,10 +547,8 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
                 * Don't get the IP here because it's unlikely to
                 * have anything to do with the actual error location.
                 */
-               if (!(flags & MCP_DONTLOG) && !mce_dont_log_ce) {
+               if (!(flags & MCP_DONTLOG) && !mce_dont_log_ce)
                        mce_log(&m);
-                       atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, &m);
-               }
 
                /*
                 * Clear state for this bank.
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c
new file mode 100644 (file)
index 0000000..feca286
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the Linux kernel.
+ *
+ * Copyright (c) 2011, Intel Corporation
+ * Authors: Fenghua Yu <fenghua.yu@intel.com>,
+ *          H. Peter Anvin <hpa@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm/archrandom.h>
+#include <asm/sections.h>
+
+static int __init x86_rdrand_setup(char *s)
+{
+       setup_clear_cpu_cap(X86_FEATURE_RDRAND);
+       return 1;
+}
+__setup("nordrand", x86_rdrand_setup);
+
+/* We can't use arch_get_random_long() here since alternatives haven't run */
+static inline int rdrand_long(unsigned long *v)
+{
+       int ok;
+       asm volatile("1: " RDRAND_LONG "\n\t"
+                    "jc 2f\n\t"
+                    "decl %0\n\t"
+                    "jnz 1b\n\t"
+                    "2:"
+                    : "=r" (ok), "=a" (*v)
+                    : "0" (RDRAND_RETRY_LOOPS));
+       return ok;
+}
+
+/*
+ * Force a reseed cycle; we are architecturally guaranteed a reseed
+ * after no more than 512 128-bit chunks of random data.  This also
+ * acts as a test of the CPU capability.
+ */
+#define RESEED_LOOP ((512*128)/sizeof(unsigned long))
+
+void __cpuinit x86_init_rdrand(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_ARCH_RANDOM
+       unsigned long tmp;
+       int i, count, ok;
+
+       if (!cpu_has(c, X86_FEATURE_RDRAND))
+               return;         /* Nothing to do */
+
+       for (count = i = 0; i < RESEED_LOOP; i++) {
+               ok = rdrand_long(&tmp);
+               if (ok)
+                       count++;
+       }
+
+       if (count != RESEED_LOOP)
+               clear_cpu_cap(c, X86_FEATURE_RDRAND);
+#endif
+}
index ff14a5044ce6ec66366f95acbffef82c732d23c5..fe7d2dac7fa3e250bc0b01ac2c8d7c5007bd89f6 100644 (file)
 #include <asm/ia32.h>
 #include <asm/syscalls.h>
 
+/*
+ * Align a virtual address to avoid aliasing in the I$ on AMD F15h.
+ *
+ * @flags denotes the allocation direction - bottomup or topdown -
+ * or vDSO; see call sites below.
+ */
+unsigned long align_addr(unsigned long addr, struct file *filp,
+                        enum align_flags flags)
+{
+       unsigned long tmp_addr;
+
+       /* handle 32- and 64-bit case with a single conditional */
+       if (va_align.flags < 0 || !(va_align.flags & (2 - mmap_is_ia32())))
+               return addr;
+
+       if (!(current->flags & PF_RANDOMIZE))
+               return addr;
+
+       if (!((flags & ALIGN_VDSO) || filp))
+               return addr;
+
+       tmp_addr = addr;
+
+       /*
+        * We need an address which is <= than the original
+        * one only when in topdown direction.
+        */
+       if (!(flags & ALIGN_TOPDOWN))
+               tmp_addr += va_align.mask;
+
+       tmp_addr &= ~va_align.mask;
+
+       return tmp_addr;
+}
+
+static int __init control_va_addr_alignment(char *str)
+{
+       /* guard against enabling this on other CPU families */
+       if (va_align.flags < 0)
+               return 1;
+
+       if (*str == 0)
+               return 1;
+
+       if (*str == '=')
+               str++;
+
+       if (!strcmp(str, "32"))
+               va_align.flags = ALIGN_VA_32;
+       else if (!strcmp(str, "64"))
+               va_align.flags = ALIGN_VA_64;
+       else if (!strcmp(str, "off"))
+               va_align.flags = 0;
+       else if (!strcmp(str, "on"))
+               va_align.flags = ALIGN_VA_32 | ALIGN_VA_64;
+       else
+               return 0;
+
+       return 1;
+}
+__setup("align_va_addr", control_va_addr_alignment);
+
 SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
                unsigned long, prot, unsigned long, flags,
                unsigned long, fd, unsigned long, off)
@@ -92,6 +154,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        start_addr = addr;
 
 full_search:
+
+       addr = align_addr(addr, filp, 0);
+
        for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
                /* At this point:  (!vma || addr < vma->vm_end). */
                if (end - len < addr) {
@@ -117,6 +182,7 @@ full_search:
                        mm->cached_hole_size = vma->vm_start - addr;
 
                addr = vma->vm_end;
+               addr = align_addr(addr, filp, 0);
        }
 }
 
@@ -161,10 +227,13 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
        /* make sure it can fit in the remaining address space */
        if (addr > len) {
-               vma = find_vma(mm, addr-len);
-               if (!vma || addr <= vma->vm_start)
+               unsigned long tmp_addr = align_addr(addr - len, filp,
+                                                   ALIGN_TOPDOWN);
+
+               vma = find_vma(mm, tmp_addr);
+               if (!vma || tmp_addr + len <= vma->vm_start)
                        /* remember the address as a hint for next time */
-                       return mm->free_area_cache = addr-len;
+                       return mm->free_area_cache = tmp_addr;
        }
 
        if (mm->mmap_base < len)
@@ -173,6 +242,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        addr = mm->mmap_base-len;
 
        do {
+               addr = align_addr(addr, filp, ALIGN_TOPDOWN);
+
                /*
                 * Lookup failure means no vma is above this address,
                 * else if new region fits below vma->vm_start,
index 6f164bd5e14d167d417b2f86e5fc8580047ed371..6eee0828e3272bb53b84960c8e6e0e72e6423194 100644 (file)
@@ -61,10 +61,6 @@ struct x86_init_ops x86_init __initdata = {
                .banner                 = default_banner,
        },
 
-       .mapping = {
-               .pagetable_reserve              = native_pagetable_reserve,
-       },
-
        .paging = {
                .pagetable_setup_start  = native_pagetable_setup_start,
                .pagetable_setup_done   = native_pagetable_setup_done,
index 13ee258442ae2b58cb195374c02c1a213f8333ee..f63da5ef217c40deb6af93e0924246fc68f94008 100644 (file)
@@ -70,6 +70,7 @@
 #include <asm/i387.h>
 #include <asm/stackprotector.h>
 #include <asm/reboot.h>                /* for struct machine_ops */
+#include <asm/kvm_para.h>
 
 /*G:010
  * Welcome to the Guest!
@@ -455,6 +456,15 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx,
                *ax &= 0xFFFFF0FF;
                *ax |= 0x00000500;
                break;
+
+       /*
+        * This is used to detect if we're running under KVM.  We might be,
+        * but that's a Host matter, not us.  So say we're not.
+        */
+       case KVM_CPUID_SIGNATURE:
+               *bx = *cx = *dx = 0;
+               break;
+
        /*
         * 0x80000000 returns the highest Extended Function, so we futureproof
         * like we do above by limiting it to known fields.
index 0d17c8c50acd54334b6c92335dad6e4c954ca18f..f2d4c9da97b4e54bb2bc79f454002ac7283819d5 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/traps.h>                 /* dotraplinkage, ...           */
 #include <asm/pgalloc.h>               /* pgd_*(), ...                 */
 #include <asm/kmemcheck.h>             /* kmemcheck_*(), ...           */
-#include <asm/vsyscall.h>
+#include <asm/fixmap.h>                        /* VSYSCALL_START               */
 
 /*
  * Page fault error code bits:
index 30326443ab81d9189224cf0c373ded68da51332d..a90ccc44db6953132a4a56f606bc77f61e39c190 100644 (file)
@@ -28,22 +28,110 @@ int direct_gbpages
 #endif
 ;
 
-static void __init find_early_table_space(unsigned long end, int use_pse,
-                                         int use_gbpages)
+static unsigned long __init find_early_fixmap_space(void)
 {
-       unsigned long puds, pmds, ptes, tables, start = 0, good_end = end;
+       unsigned long size = 0;
+#ifdef CONFIG_X86_32
+       int kmap_begin_pmd_idx, kmap_end_pmd_idx;
+       int fixmap_begin_pmd_idx, fixmap_end_pmd_idx;
+       int btmap_begin_pmd_idx;
+
+       fixmap_begin_pmd_idx =
+               __fix_to_virt(__end_of_fixed_addresses - 1) >> PMD_SHIFT;
+       /*
+        * fixmap_end_pmd_idx is the end of the fixmap minus the PMD that
+        * has been defined in the data section by head_32.S (see
+        * initial_pg_fixmap).
+        * Note: This is similar to what early_ioremap_page_table_range_init
+        * does except that the "end" has PMD_SIZE expunged as per previous
+        * comment.
+        */
+       fixmap_end_pmd_idx = (FIXADDR_TOP - 1) >> PMD_SHIFT;
+       btmap_begin_pmd_idx = __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT;
+       kmap_begin_pmd_idx = __fix_to_virt(FIX_KMAP_END) >> PMD_SHIFT;
+       kmap_end_pmd_idx = __fix_to_virt(FIX_KMAP_BEGIN) >> PMD_SHIFT;
+
+       size = fixmap_end_pmd_idx - fixmap_begin_pmd_idx;
+       /*
+        * early_ioremap_init has already allocated a PMD at
+        * btmap_begin_pmd_idx
+        */
+       if (btmap_begin_pmd_idx < fixmap_end_pmd_idx)
+               size--;
+
+#ifdef CONFIG_HIGHMEM
+       /*
+        * see page_table_kmap_check: if the kmap spans multiple PMDs, make
+        * sure the pte pages are allocated contiguously. It might need up
+        * to two additional pte pages to replace the page declared by
+        * head_32.S and the one allocated by early_ioremap_init, if they
+        * are even partially used for the kmap.
+        */
+       if (kmap_begin_pmd_idx != kmap_end_pmd_idx) {
+               if (kmap_end_pmd_idx == fixmap_end_pmd_idx)
+                       size++;
+               if (btmap_begin_pmd_idx >= kmap_begin_pmd_idx &&
+                               btmap_begin_pmd_idx <= kmap_end_pmd_idx)
+                       size++;
+       }
+#endif
+#endif
+       return (size * PMD_SIZE + PAGE_SIZE - 1) >> PAGE_SHIFT;
+}
+
+static void __init find_early_table_space(unsigned long start,
+               unsigned long end, int use_pse, int use_gbpages)
+{
+       unsigned long pmds = 0, ptes = 0, tables = 0, good_end = end,
+                                 pud_mapped = 0, pmd_mapped = 0, size = end - start;
        phys_addr_t base;
 
-       puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-       tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
+       pud_mapped = DIV_ROUND_UP(PFN_PHYS(max_pfn_mapped),
+                       (PUD_SIZE * PTRS_PER_PUD));
+       pud_mapped *= (PUD_SIZE * PTRS_PER_PUD);
+       pmd_mapped = DIV_ROUND_UP(PFN_PHYS(max_pfn_mapped),
+                       (PMD_SIZE * PTRS_PER_PMD));
+       pmd_mapped *= (PMD_SIZE * PTRS_PER_PMD);
+
+       /*
+        * On x86_64 do not limit the size we need to cover with 4KB pages
+        * depending on the initial allocation because head_64.S always uses
+        * 2MB pages.
+        */
+#ifdef CONFIG_X86_32
+       if (start < PFN_PHYS(max_pfn_mapped)) {
+               if (PFN_PHYS(max_pfn_mapped) < end)
+                       size -= PFN_PHYS(max_pfn_mapped) - start;
+               else
+                       size = 0;
+       }
+#endif
+
+#ifndef __PAGETABLE_PUD_FOLDED
+       if (end > pud_mapped) {
+               unsigned long puds;
+               if (start < pud_mapped)
+                       puds = (end - pud_mapped + PUD_SIZE - 1) >> PUD_SHIFT;
+               else
+                       puds = (end - start + PUD_SIZE - 1) >> PUD_SHIFT;
+               tables += roundup(puds * sizeof(pud_t), PAGE_SIZE);
+       }
+#endif
 
        if (use_gbpages) {
                unsigned long extra;
 
                extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
                pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
-       } else
-               pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
+       }
+#ifndef __PAGETABLE_PMD_FOLDED
+       else if (end > pmd_mapped) {
+               if (start < pmd_mapped)
+                       pmds = (end - pmd_mapped + PMD_SIZE - 1) >> PMD_SHIFT;
+               else
+                       pmds = (end - start + PMD_SIZE - 1) >> PMD_SHIFT;
+       }
+#endif
 
        tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
 
@@ -51,23 +139,22 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
                unsigned long extra;
 
                extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT);
-#ifdef CONFIG_X86_32
-               extra += PMD_SIZE;
-#endif
                ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
        } else
-               ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
+               ptes = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+       ptes += find_early_fixmap_space();
 
        tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
 
-#ifdef CONFIG_X86_32
-       /* for fixmap */
-       tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
+       if (!tables)
+               return;
 
+#ifdef CONFIG_X86_32
        good_end = max_pfn_mapped << PAGE_SHIFT;
 #endif
 
-       base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE);
+       base = memblock_find_in_range(0x00, good_end, tables, PAGE_SIZE);
        if (base == MEMBLOCK_ERROR)
                panic("Cannot find space for the kernel page tables");
 
@@ -77,11 +164,10 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
 
        printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
                end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT);
-}
 
-void __init native_pagetable_reserve(u64 start, u64 end)
-{
-       memblock_x86_reserve_range(start, end, "PGTABLE");
+       if (pgt_buf_top > pgt_buf_start)
+               memblock_x86_reserve_range(pgt_buf_start << PAGE_SHIFT,
+                                pgt_buf_top << PAGE_SHIFT, "PGTABLE");
 }
 
 struct map_range {
@@ -261,7 +347,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
         * nodes are discovered.
         */
        if (!after_bootmem)
-               find_early_table_space(end, use_pse, use_gbpages);
+               find_early_table_space(start, end, use_pse, use_gbpages);
 
        for (i = 0; i < nr_range; i++)
                ret = kernel_physical_mapping_init(mr[i].start, mr[i].end,
@@ -275,24 +361,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
 
        __flush_tlb_all();
 
-       /*
-        * Reserve the kernel pagetable pages we used (pgt_buf_start -
-        * pgt_buf_end) and free the other ones (pgt_buf_end - pgt_buf_top)
-        * so that they can be reused for other purposes.
-        *
-        * On native it just means calling memblock_x86_reserve_range, on Xen it
-        * also means marking RW the pagetable pages that we allocated before
-        * but that haven't been used.
-        *
-        * In fact on xen we mark RO the whole range pgt_buf_start -
-        * pgt_buf_top, because we have to make sure that when
-        * init_memory_mapping reaches the pagetable pages area, it maps
-        * RO all the pagetable pages, including the ones that are beyond
-        * pgt_buf_end at that time.
-        */
-       if (!after_bootmem && pgt_buf_end > pgt_buf_start)
-               x86_init.mapping.pagetable_reserve(PFN_PHYS(pgt_buf_start),
-                               PFN_PHYS(pgt_buf_end));
+       if (pgt_buf_end != pgt_buf_top)
+               printk(KERN_DEBUG "initial kernel pagetable allocation wasted %lx"
+                               " pages\n", pgt_buf_top - pgt_buf_end);
 
        if (!after_bootmem)
                early_memtest(start, end);
index 1dab5194fd9df9f6bead4b0e09d154bd2b26e178..4b5ba85eb5c95ebb705f8ce420acbff85c052f47 100644 (file)
 #include <linux/sched.h>
 #include <asm/elf.h>
 
+struct __read_mostly va_alignment va_align = {
+       .flags = -1,
+};
+
 static unsigned int stack_maxrandom_size(void)
 {
        unsigned int max = 0;
@@ -42,7 +46,6 @@ static unsigned int stack_maxrandom_size(void)
        return max;
 }
 
-
 /*
  * Top of mmap area (just below the process stack).
  *
@@ -51,21 +54,6 @@ static unsigned int stack_maxrandom_size(void)
 #define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
 #define MAX_GAP (TASK_SIZE/6*5)
 
-/*
- * True on X86_32 or when emulating IA32 on X86_64
- */
-static int mmap_is_ia32(void)
-{
-#ifdef CONFIG_X86_32
-       return 1;
-#endif
-#ifdef CONFIG_IA32_EMULATION
-       if (test_thread_flag(TIF_IA32))
-               return 1;
-#endif
-       return 0;
-}
-
 static int mmap_is_legacy(void)
 {
        if (current->personality & ADDR_COMPAT_LAYOUT)
index 8b9940e78e2fa6da6751f115f4d8b0ce87f5b53a..7cce722667b83dd06b506d06b771a572c0843598 100644 (file)
@@ -161,13 +161,13 @@ restart:
        if (inbuf && inlen) {
                /* write data to EC */
                for (i = 0; i < inlen; i++) {
+                       pr_devel("olpc-ec:  sending cmd arg 0x%x\n", inbuf[i]);
+                       outb(inbuf[i], 0x68);
                        if (wait_on_ibf(0x6c, 0)) {
                                printk(KERN_ERR "olpc-ec:  timeout waiting for"
                                                " EC accept data!\n");
                                goto err;
                        }
-                       pr_devel("olpc-ec:  sending cmd arg 0x%x\n", inbuf[i]);
-                       outb(inbuf[i], 0x68);
                }
        }
        if (outbuf && outlen) {
index 316fbca3490e98afe758d7a4e535eaecd4482a8f..153407c35b75bda37e2b5d2675d3abb6280cc9cd 100644 (file)
@@ -89,6 +89,15 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
        addr = start + (offset << PAGE_SHIFT);
        if (addr >= end)
                addr = end;
+
+       /*
+        * page-align it here so that get_unmapped_area doesn't
+        * align it wrongfully again to the next page. addr can come in 4K
+        * unaligned here as a result of stack start randomization.
+        */
+       addr = PAGE_ALIGN(addr);
+       addr = align_addr(addr, NULL, ALIGN_VDSO);
+
        return addr;
 }
 
index 5cc821cb2e0968090501e8c6e5af36353d5e2f87..ae559fe91c250efe1f75b38bb8e8ae1dd86be28b 100644 (file)
@@ -49,11 +49,3 @@ config XEN_DEBUG_FS
        help
          Enable statistics output and various tuning options in debugfs.
          Enabling this option may incur a significant performance overhead.
-
-config XEN_DEBUG
-       bool "Enable Xen debug checks"
-       depends on XEN
-       default n
-       help
-         Enable various WARN_ON checks in the Xen MMU code.
-         Enabling this option WILL incur a significant performance overhead.
index 20a6142750644442492dabdbbd6a55aaa75244a5..6646bfef14a5efe58e4ac7309eda528814ef6f07 100644 (file)
@@ -495,41 +495,6 @@ static pte_t xen_make_pte(pteval_t pte)
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
 
-#ifdef CONFIG_XEN_DEBUG
-pte_t xen_make_pte_debug(pteval_t pte)
-{
-       phys_addr_t addr = (pte & PTE_PFN_MASK);
-       phys_addr_t other_addr;
-       bool io_page = false;
-       pte_t _pte;
-
-       if (pte & _PAGE_IOMAP)
-               io_page = true;
-
-       _pte = xen_make_pte(pte);
-
-       if (!addr)
-               return _pte;
-
-       if (io_page &&
-           (xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
-               other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT;
-               WARN_ONCE(addr != other_addr,
-                       "0x%lx is using VM_IO, but it is 0x%lx!\n",
-                       (unsigned long)addr, (unsigned long)other_addr);
-       } else {
-               pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP;
-               other_addr = (_pte.pte & PTE_PFN_MASK);
-               WARN_ONCE((addr == other_addr) && (!io_page) && (!iomap_set),
-                       "0x%lx is missing VM_IO (and wasn't fixed)!\n",
-                       (unsigned long)addr);
-       }
-
-       return _pte;
-}
-PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_debug);
-#endif
-
 static pgd_t xen_make_pgd(pgdval_t pgd)
 {
        pgd = pte_pfn_to_mfn(pgd);
@@ -1196,20 +1161,6 @@ static void __init xen_pagetable_setup_start(pgd_t *base)
 {
 }
 
-static __init void xen_mapping_pagetable_reserve(u64 start, u64 end)
-{
-       /* reserve the range used */
-       native_pagetable_reserve(start, end);
-
-       /* set as RW the rest */
-       printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n", end,
-                       PFN_PHYS(pgt_buf_top));
-       while (end < PFN_PHYS(pgt_buf_top)) {
-               make_lowmem_page_readwrite(__va(end));
-               end += PAGE_SIZE;
-       }
-}
-
 static void xen_post_allocator_init(void);
 
 static void __init xen_pagetable_setup_done(pgd_t *base)
@@ -1994,9 +1945,6 @@ void __init xen_ident_map_ISA(void)
 
 static void __init xen_post_allocator_init(void)
 {
-#ifdef CONFIG_XEN_DEBUG
-       pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug);
-#endif
        pv_mmu_ops.set_pte = xen_set_pte;
        pv_mmu_ops.set_pmd = xen_set_pmd;
        pv_mmu_ops.set_pud = xen_set_pud;
@@ -2102,7 +2050,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
 
 void __init xen_init_mmu_ops(void)
 {
-       x86_init.mapping.pagetable_reserve = xen_mapping_pagetable_reserve;
        x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start;
        x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
        pv_mmu_ops = xen_mmu_ops;
index 7be8accb0b0caf7270144d3eaba8e571f5c6b0eb..6abbedd09d85dfbdab7863edf99d7d3b205d234a 100644 (file)
@@ -132,7 +132,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    6       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
-#define TIF_FREEZE             17      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
@@ -141,7 +140,6 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_IRET              (1<<TIF_IRET)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index f717e20d961b342b16d128979ad959dad55a154a..7dde24456427467a1caf0dc7fa39275b9778f484 100644 (file)
@@ -633,7 +633,7 @@ static const struct net_device_ops iss_netdev_ops = {
        .ndo_set_mac_address    = iss_net_set_mac,
        //.ndo_do_ioctl         = iss_net_ioctl,
        .ndo_tx_timeout         = iss_net_tx_timeout,
-       .ndo_set_multicast_list = iss_net_set_multicast_list,
+       .ndo_set_rx_mode        = iss_net_set_multicast_list,
 };
 
 static int iss_net_configure(int index, char *init)
index ae27b7534ea7d14ee0c5f493e3eaf6e8f123eaa2..55c50cd34690879fb59695c9abb9b3a2eaf5dfb4 100644 (file)
@@ -407,6 +407,16 @@ config CRYPTO_SHA1
        help
          SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
+config CRYPTO_SHA1_SSSE3
+       tristate "SHA1 digest algorithm (SSSE3/AVX)"
+       depends on X86 && 64BIT
+       select CRYPTO_SHA1
+       select CRYPTO_HASH
+       help
+         SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
+         using Supplemental SSE3 (SSSE3) instructions or Advanced Vector
+         Extensions (AVX), when available.
+
 config CRYPTO_SHA256
        tristate "SHA224 and SHA256 digest algorithm"
        select CRYPTO_HASH
index e46d21ae26bc0538003cf72b42fe1a8e90eb51cd..671d4d6d14df106b3b0278364340ef3290d7a185 100644 (file)
@@ -945,7 +945,7 @@ static void __exit cryptd_exit(void)
        crypto_unregister_template(&cryptd_tmpl);
 }
 
-module_init(cryptd_init);
+subsys_initcall(cryptd_init);
 module_exit(cryptd_exit);
 
 MODULE_LICENSE("GPL");
index 00ae60eb925435efe5295a9d7315283bd258e613..42794803c480531a60cc465657741a42ea5485dc 100644 (file)
@@ -36,7 +36,7 @@ static int sha1_init(struct shash_desc *desc)
        return 0;
 }
 
-static int sha1_update(struct shash_desc *desc, const u8 *data,
+int crypto_sha1_update(struct shash_desc *desc, const u8 *data,
                        unsigned int len)
 {
        struct sha1_state *sctx = shash_desc_ctx(desc);
@@ -71,6 +71,7 @@ static int sha1_update(struct shash_desc *desc, const u8 *data,
 
        return 0;
 }
+EXPORT_SYMBOL(crypto_sha1_update);
 
 
 /* Add padding and return the message digest. */
@@ -87,10 +88,10 @@ static int sha1_final(struct shash_desc *desc, u8 *out)
        /* Pad out to 56 mod 64 */
        index = sctx->count & 0x3f;
        padlen = (index < 56) ? (56 - index) : ((64+56) - index);
-       sha1_update(desc, padding, padlen);
+       crypto_sha1_update(desc, padding, padlen);
 
        /* Append length */
-       sha1_update(desc, (const u8 *)&bits, sizeof(bits));
+       crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
 
        /* Store state in digest */
        for (i = 0; i < 5; i++)
@@ -121,7 +122,7 @@ static int sha1_import(struct shash_desc *desc, const void *in)
 static struct shash_alg alg = {
        .digestsize     =       SHA1_DIGEST_SIZE,
        .init           =       sha1_init,
-       .update         =       sha1_update,
+       .update         =       crypto_sha1_update,
        .final          =       sha1_final,
        .export         =       sha1_export,
        .import         =       sha1_import,
index f75f81ad15c962a20c0cbc1afa7ba035e9ccca8c..460e96ef07b1e339788e8a637d6db2b6291717c2 100644 (file)
@@ -73,8 +73,7 @@ acpi_status acpi_reset(void)
 
        /* Check if the reset register is supported */
 
-       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
-           !reset_reg->address) {
+       if (!reset_reg->address) {
                return_ACPI_STATUS(AE_NOT_EXIST);
        }
 
index c34aa51af4eed85a99bc9aad7720e4dd582f47a8..e3f47872ec222949d13f239fdaf9e00eb5985984 100644 (file)
@@ -13,6 +13,7 @@ config ACPI_APEI_GHES
        bool "APEI Generic Hardware Error Source"
        depends on ACPI_APEI && X86
        select ACPI_HED
+       select IRQ_WORK
        select LLIST
        select GENERIC_ALLOCATOR
        help
index 8041248fce9ba245a6eeeedf4adb4dd7a2b5ee20..61540360d5ce815f67e67250874ad357f3e328e6 100644 (file)
@@ -618,7 +618,7 @@ int apei_osc_setup(void)
        };
 
        capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
-       capbuf[OSC_SUPPORT_TYPE] = 0;
+       capbuf[OSC_SUPPORT_TYPE] = 1;
        capbuf[OSC_CONTROL_TYPE] = 0;
 
        if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))
index 2ca59dc69f7f6b034660bfdc04462230880456f9..5e820ea355703b8387cadf2b046fc869c5d034c8 100644 (file)
@@ -1165,7 +1165,7 @@ static int __init erst_init(void)
                goto err_release_erange;
 
        buf = kmalloc(erst_erange.size, GFP_KERNEL);
-       mutex_init(&erst_info.buf_mutex);
+       spin_lock_init(&erst_info.buf_lock);
        if (buf) {
                erst_info.buf = buf + sizeof(struct cper_pstore_record);
                erst_info.bufsize = erst_erange.size -
index 431ab11c8c1b6736aec984754c9f6002d3542ad8..2e69e09ff03e13a02b04bba1dec60bd9ef0c1cbf 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/dmi.h>
 #include <linux/moduleparam.h>
 #include <linux/sched.h>       /* need_resched() */
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/clockchips.h>
 #include <linux/cpuidle.h>
 #include <linux/irqflags.h>
index a6c77e8b37bde54c266cae17d620c441a896e3b9..c1d612435939a5d62abb832d1f620faeeac7dc20 100644 (file)
@@ -23,8 +23,7 @@ void acpi_reboot(void)
        /* Is the reset register supported? The spec says we should be
         * checking the bit width and bit offset, but Windows ignores
         * these fields */
-       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
-               return;
+       /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
 
        reset_value = acpi_gbl_FADT.reset_value;
 
index 449c556274c052cf4c9fd221c577b7735bcdca0f..8ab80bafe3f1604f3e05e7287ed5fe4f9ed1e6fb 100644 (file)
@@ -1062,13 +1062,12 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
        if (!id)
                return;
 
-       id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
+       id->id = kstrdup(dev_id, GFP_KERNEL);
        if (!id->id) {
                kfree(id);
                return;
        }
 
-       strcpy(id->id, dev_id);
        list_add_tail(&id->list, &device->pnp.ids);
 }
 
index ed16fbedaabd78020044996a70f4f4ad1d8879c8..c021186736e9328cdc8c5de33ea1349177613ef9 100644 (file)
@@ -2532,8 +2532,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
        return reset(link, classes, deadline);
 }
 
-static int ata_eh_followup_srst_needed(struct ata_link *link,
-                                      int rc, const unsigned int *classes)
+static int ata_eh_followup_srst_needed(struct ata_link *link, int rc)
 {
        if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
                return 0;
@@ -2726,7 +2725,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
 
                /* perform follow-up SRST if necessary */
                if (reset == hardreset &&
-                   ata_eh_followup_srst_needed(link, rc, classes)) {
+                   ata_eh_followup_srst_needed(link, rc)) {
                        reset = softreset;
 
                        if (!reset) {
index 960c725713951632869b9bc01585374ea2e5ae4d..3f4c2613b3dfa1a2f672bbb6d86383dc2e58d029 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <mach/at91sam9_smc.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #define DRV_NAME               "pata_at91"
 #define DRV_VERSION            "0.3"
index 55470f337e517b35419b98fc96778123be915293..1e9140626a8371eae9e846bb2fd9fb3a327136e6 100644 (file)
@@ -268,7 +268,7 @@ union sil24_cmd_block {
        struct sil24_atapi_block atapi;
 };
 
-static struct sil24_cerr_info {
+static const struct sil24_cerr_info {
        unsigned int err_mask, action;
        const char *desc;
 } sil24_cerr_db[] = {
@@ -1019,7 +1019,7 @@ static void sil24_error_intr(struct ata_port *ap)
 
        /* deal with command error */
        if (irq_stat & PORT_IRQ_ERROR) {
-               struct sil24_cerr_info *ci = NULL;
+               const struct sil24_cerr_info *ci = NULL;
                unsigned int err_mask = 0, action = 0;
                u32 context, cerr;
                int pmp;
index bc8729d603a74834b34e75d843cbe3b1045cad50..82c865452c7080d180ec6a453ab1efb3e988dac3 100644 (file)
@@ -1764,8 +1764,8 @@ void device_shutdown(void)
 
 #ifdef CONFIG_PRINTK
 
-static int __dev_printk(const char *level, const struct device *dev,
-                       struct va_format *vaf)
+int __dev_printk(const char *level, const struct device *dev,
+                struct va_format *vaf)
 {
        if (!dev)
                return printk("%s(NULL device *): %pV", level, vaf);
@@ -1773,6 +1773,7 @@ static int __dev_printk(const char *level, const struct device *dev,
        return printk("%s%s %s: %pV",
                      level, dev_driver_string(dev), dev_name(dev), vaf);
 }
+EXPORT_SYMBOL(__dev_printk);
 
 int dev_printk(const char *level, const struct device *dev,
               const char *fmt, ...)
index cf7a0c78805278e64f195921b3991c577691da66..65cd74832450507b9f7b1949b6ca85c648109ff1 100644 (file)
@@ -397,6 +397,7 @@ static int remove_nodes(struct device *dev,
 
 static int release_nodes(struct device *dev, struct list_head *first,
                         struct list_head *end, unsigned long flags)
+       __releases(&dev->devres_lock)
 {
        LIST_HEAD(todo);
        int cnt;
index 33e1bed68fddf771ae9b12a716114215b59b5f68..a4760e095ff51b36a58871cdf9329bf4573f6c1d 100644 (file)
@@ -376,7 +376,7 @@ int devtmpfs_mount(const char *mntdir)
        return err;
 }
 
-static __initdata DECLARE_COMPLETION(setup_done);
+static DECLARE_COMPLETION(setup_done);
 
 static int handle(const char *name, mode_t mode, struct device *dev)
 {
index 0cad9c7f6bb50f68bdb0a371e44d51530a02ec06..10334a02f8d993682a1d3b756219e299b79eda7d 100644 (file)
@@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
 
 /**
  * arch_setup_pdev_archdata - Allow manipulation of archdata before its used
- * @dev: platform device
+ * @pdev: platform device
  *
  * This is called before platform_device_add() such that any pdev_archdata may
  * be setup before the platform_notifier is called.  So if a user needs to
@@ -614,7 +614,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
                return rc;
 
        add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
-               (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
+                       pdev->name);
        return 0;
 }
 
index 2639ae79a3728af32c4d3d9c8aa8c730d426aa77..81676dd1790044b3aba8c05ad3eab0cf40dab375 100644 (file)
@@ -1,4 +1,4 @@
-obj-$(CONFIG_PM)       += sysfs.o generic_ops.o
+obj-$(CONFIG_PM)       += sysfs.o generic_ops.o common.o qos.o
 obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o
 obj-$(CONFIG_PM_RUNTIME)       += runtime.o
 obj-$(CONFIG_PM_TRACE_RTC)     += trace.o
@@ -6,4 +6,4 @@ obj-$(CONFIG_PM_OPP)    += opp.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS)       +=  domain.o
 obj-$(CONFIG_HAVE_CLK) += clock_ops.o
 
-ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
\ No newline at end of file
+ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
index a846b2f95cfbc5bfbf253f5955da6cb8cd07804f..b6a115c3d66931bcbf9f3fca6e0697a2593edda6 100644 (file)
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/pm.h>
-#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 
 #ifdef CONFIG_PM
 
-struct pm_clk_data {
-       struct list_head clock_list;
-       struct mutex lock;
-};
-
 enum pce_status {
        PCE_STATUS_NONE = 0,
        PCE_STATUS_ACQUIRED,
@@ -36,11 +31,6 @@ struct pm_clock_entry {
        enum pce_status status;
 };
 
-static struct pm_clk_data *__to_pcd(struct device *dev)
-{
-       return dev ? dev->power.subsys_data : NULL;
-}
-
 /**
  * pm_clk_add - Start using a device clock for power management.
  * @dev: Device whose clock is going to be used for power management.
@@ -51,10 +41,10 @@ static struct pm_clk_data *__to_pcd(struct device *dev)
  */
 int pm_clk_add(struct device *dev, const char *con_id)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce;
 
-       if (!pcd)
+       if (!psd)
                return -EINVAL;
 
        ce = kzalloc(sizeof(*ce), GFP_KERNEL);
@@ -73,9 +63,9 @@ int pm_clk_add(struct device *dev, const char *con_id)
                }
        }
 
-       mutex_lock(&pcd->lock);
-       list_add_tail(&ce->node, &pcd->clock_list);
-       mutex_unlock(&pcd->lock);
+       mutex_lock(&psd->lock);
+       list_add_tail(&ce->node, &psd->clock_list);
+       mutex_unlock(&psd->lock);
        return 0;
 }
 
@@ -117,15 +107,15 @@ static void __pm_clk_remove(struct pm_clock_entry *ce)
  */
 void pm_clk_remove(struct device *dev, const char *con_id)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce;
 
-       if (!pcd)
+       if (!psd)
                return;
 
-       mutex_lock(&pcd->lock);
+       mutex_lock(&psd->lock);
 
-       list_for_each_entry(ce, &pcd->clock_list, node) {
+       list_for_each_entry(ce, &psd->clock_list, node) {
                if (!con_id && !ce->con_id) {
                        __pm_clk_remove(ce);
                        break;
@@ -137,30 +127,34 @@ void pm_clk_remove(struct device *dev, const char *con_id)
                }
        }
 
-       mutex_unlock(&pcd->lock);
+       mutex_unlock(&psd->lock);
 }
 
 /**
  * pm_clk_init - Initialize a device's list of power management clocks.
  * @dev: Device to initialize the list of PM clocks for.
  *
- * Allocate a struct pm_clk_data object, initialize its lock member and
- * make the @dev's power.subsys_data field point to it.
+ * Initialize the lock and clock_list members of the device's pm_subsys_data
+ * object.
  */
-int pm_clk_init(struct device *dev)
+void pm_clk_init(struct device *dev)
 {
-       struct pm_clk_data *pcd;
-
-       pcd = kzalloc(sizeof(*pcd), GFP_KERNEL);
-       if (!pcd) {
-               dev_err(dev, "Not enough memory for PM clock data.\n");
-               return -ENOMEM;
-       }
+       struct pm_subsys_data *psd = dev_to_psd(dev);
+       if (psd)
+               INIT_LIST_HEAD(&psd->clock_list);
+}
 
-       INIT_LIST_HEAD(&pcd->clock_list);
-       mutex_init(&pcd->lock);
-       dev->power.subsys_data = pcd;
-       return 0;
+/**
+ * pm_clk_create - Create and initialize a device's list of PM clocks.
+ * @dev: Device to create and initialize the list of PM clocks for.
+ *
+ * Allocate a struct pm_subsys_data object, initialize its lock and clock_list
+ * members and make the @dev's power.subsys_data field point to it.
+ */
+int pm_clk_create(struct device *dev)
+{
+       int ret = dev_pm_get_subsys_data(dev);
+       return ret < 0 ? ret : 0;
 }
 
 /**
@@ -168,27 +162,25 @@ int pm_clk_init(struct device *dev)
  * @dev: Device to destroy the list of PM clocks for.
  *
  * Clear the @dev's power.subsys_data field, remove the list of clock entries
- * from the struct pm_clk_data object pointed to by it before and free
+ * from the struct pm_subsys_data object pointed to by it before and free
  * that object.
  */
 void pm_clk_destroy(struct device *dev)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce, *c;
 
-       if (!pcd)
+       if (!psd)
                return;
 
-       dev->power.subsys_data = NULL;
-
-       mutex_lock(&pcd->lock);
+       mutex_lock(&psd->lock);
 
-       list_for_each_entry_safe_reverse(ce, c, &pcd->clock_list, node)
+       list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node)
                __pm_clk_remove(ce);
 
-       mutex_unlock(&pcd->lock);
+       mutex_unlock(&psd->lock);
 
-       kfree(pcd);
+       dev_pm_put_subsys_data(dev);
 }
 
 #endif /* CONFIG_PM */
@@ -218,17 +210,17 @@ static void pm_clk_acquire(struct device *dev,
  */
 int pm_clk_suspend(struct device *dev)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce;
 
        dev_dbg(dev, "%s()\n", __func__);
 
-       if (!pcd)
+       if (!psd)
                return 0;
 
-       mutex_lock(&pcd->lock);
+       mutex_lock(&psd->lock);
 
-       list_for_each_entry_reverse(ce, &pcd->clock_list, node) {
+       list_for_each_entry_reverse(ce, &psd->clock_list, node) {
                if (ce->status == PCE_STATUS_NONE)
                        pm_clk_acquire(dev, ce);
 
@@ -238,7 +230,7 @@ int pm_clk_suspend(struct device *dev)
                }
        }
 
-       mutex_unlock(&pcd->lock);
+       mutex_unlock(&psd->lock);
 
        return 0;
 }
@@ -249,17 +241,17 @@ int pm_clk_suspend(struct device *dev)
  */
 int pm_clk_resume(struct device *dev)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce;
 
        dev_dbg(dev, "%s()\n", __func__);
 
-       if (!pcd)
+       if (!psd)
                return 0;
 
-       mutex_lock(&pcd->lock);
+       mutex_lock(&psd->lock);
 
-       list_for_each_entry(ce, &pcd->clock_list, node) {
+       list_for_each_entry(ce, &psd->clock_list, node) {
                if (ce->status == PCE_STATUS_NONE)
                        pm_clk_acquire(dev, ce);
 
@@ -269,7 +261,7 @@ int pm_clk_resume(struct device *dev)
                }
        }
 
-       mutex_unlock(&pcd->lock);
+       mutex_unlock(&psd->lock);
 
        return 0;
 }
@@ -307,7 +299,7 @@ static int pm_clk_notify(struct notifier_block *nb,
                if (dev->pm_domain)
                        break;
 
-               error = pm_clk_init(dev);
+               error = pm_clk_create(dev);
                if (error)
                        break;
 
@@ -342,21 +334,21 @@ static int pm_clk_notify(struct notifier_block *nb,
  */
 int pm_clk_suspend(struct device *dev)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce;
 
        dev_dbg(dev, "%s()\n", __func__);
 
        /* If there is no driver, the clocks are already disabled. */
-       if (!pcd || !dev->driver)
+       if (!psd || !dev->driver)
                return 0;
 
-       mutex_lock(&pcd->lock);
+       mutex_lock(&psd->lock);
 
-       list_for_each_entry_reverse(ce, &pcd->clock_list, node)
+       list_for_each_entry_reverse(ce, &psd->clock_list, node)
                clk_disable(ce->clk);
 
-       mutex_unlock(&pcd->lock);
+       mutex_unlock(&psd->lock);
 
        return 0;
 }
@@ -367,21 +359,21 @@ int pm_clk_suspend(struct device *dev)
  */
 int pm_clk_resume(struct device *dev)
 {
-       struct pm_clk_data *pcd = __to_pcd(dev);
+       struct pm_subsys_data *psd = dev_to_psd(dev);
        struct pm_clock_entry *ce;
 
        dev_dbg(dev, "%s()\n", __func__);
 
        /* If there is no driver, the clocks should remain disabled. */
-       if (!pcd || !dev->driver)
+       if (!psd || !dev->driver)
                return 0;
 
-       mutex_lock(&pcd->lock);
+       mutex_lock(&psd->lock);
 
-       list_for_each_entry(ce, &pcd->clock_list, node)
+       list_for_each_entry(ce, &psd->clock_list, node)
                clk_enable(ce->clk);
 
-       mutex_unlock(&pcd->lock);
+       mutex_unlock(&psd->lock);
 
        return 0;
 }
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
new file mode 100644 (file)
index 0000000..d4e359c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * drivers/base/power/common.c - Common device power management code.
+ *
+ * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pm_clock.h>
+
+/**
+ * dev_pm_get_subsys_data - Create or refcount power.subsys_data for device.
+ * @dev: Device to handle.
+ *
+ * If power.subsys_data is NULL, point it to a new object, otherwise increment
+ * its reference counter.  Return 1 if a new object has been created, otherwise
+ * return 0 or error code.
+ */
+int dev_pm_get_subsys_data(struct device *dev)
+{
+       struct pm_subsys_data *psd;
+       int ret = 0;
+
+       psd = kzalloc(sizeof(*psd), GFP_KERNEL);
+       if (!psd)
+               return -ENOMEM;
+
+       spin_lock_irq(&dev->power.lock);
+
+       if (dev->power.subsys_data) {
+               dev->power.subsys_data->refcount++;
+       } else {
+               mutex_init(&psd->lock);
+               psd->refcount = 1;
+               dev->power.subsys_data = psd;
+               pm_clk_init(dev);
+               psd = NULL;
+               ret = 1;
+       }
+
+       spin_unlock_irq(&dev->power.lock);
+
+       /* kfree() verifies that its argument is nonzero. */
+       kfree(psd);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
+
+/**
+ * dev_pm_put_subsys_data - Drop reference to power.subsys_data.
+ * @dev: Device to handle.
+ *
+ * If the reference counter of power.subsys_data is zero after dropping the
+ * reference, power.subsys_data is removed.  Return 1 if that happens or 0
+ * otherwise.
+ */
+int dev_pm_put_subsys_data(struct device *dev)
+{
+       struct pm_subsys_data *psd;
+       int ret = 0;
+
+       spin_lock_irq(&dev->power.lock);
+
+       psd = dev_to_psd(dev);
+       if (!psd) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (--psd->refcount == 0) {
+               dev->power.subsys_data = NULL;
+               kfree(psd);
+               ret = 1;
+       }
+
+ out:
+       spin_unlock_irq(&dev->power.lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
index 1c374579407c14316b35e8b9d7faff71077b18f6..339eb2d9bddab16678048c9526672b4bb4e2139b 100644 (file)
@@ -29,10 +29,20 @@ static struct generic_pm_domain *dev_to_genpd(struct device *dev)
        return pd_to_genpd(dev->pm_domain);
 }
 
-static void genpd_sd_counter_dec(struct generic_pm_domain *genpd)
+static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
 {
-       if (!WARN_ON(genpd->sd_count == 0))
-                       genpd->sd_count--;
+       bool ret = false;
+
+       if (!WARN_ON(atomic_read(&genpd->sd_count) == 0))
+               ret = !!atomic_dec_and_test(&genpd->sd_count);
+
+       return ret;
+}
+
+static void genpd_sd_counter_inc(struct generic_pm_domain *genpd)
+{
+       atomic_inc(&genpd->sd_count);
+       smp_mb__after_atomic_inc();
 }
 
 static void genpd_acquire_lock(struct generic_pm_domain *genpd)
@@ -71,60 +81,97 @@ static void genpd_set_active(struct generic_pm_domain *genpd)
 }
 
 /**
- * pm_genpd_poweron - Restore power to a given PM domain and its parents.
+ * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
  * @genpd: PM domain to power up.
  *
- * Restore power to @genpd and all of its parents so that it is possible to
+ * Restore power to @genpd and all of its masters so that it is possible to
  * resume a device belonging to it.
  */
-int pm_genpd_poweron(struct generic_pm_domain *genpd)
+int __pm_genpd_poweron(struct generic_pm_domain *genpd)
+       __releases(&genpd->lock) __acquires(&genpd->lock)
 {
-       struct generic_pm_domain *parent = genpd->parent;
+       struct gpd_link *link;
+       DEFINE_WAIT(wait);
        int ret = 0;
 
- start:
-       if (parent) {
-               genpd_acquire_lock(parent);
-               mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
-       } else {
+       /* If the domain's master is being waited for, we have to wait too. */
+       for (;;) {
+               prepare_to_wait(&genpd->status_wait_queue, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               if (genpd->status != GPD_STATE_WAIT_MASTER)
+                       break;
+               mutex_unlock(&genpd->lock);
+
+               schedule();
+
                mutex_lock(&genpd->lock);
        }
+       finish_wait(&genpd->status_wait_queue, &wait);
 
        if (genpd->status == GPD_STATE_ACTIVE
            || (genpd->prepared_count > 0 && genpd->suspend_power_off))
-               goto out;
+               return 0;
 
        if (genpd->status != GPD_STATE_POWER_OFF) {
                genpd_set_active(genpd);
-               goto out;
+               return 0;
        }
 
-       if (parent && parent->status != GPD_STATE_ACTIVE) {
+       /*
+        * The list is guaranteed not to change while the loop below is being
+        * executed, unless one of the masters' .power_on() callbacks fiddles
+        * with it.
+        */
+       list_for_each_entry(link, &genpd->slave_links, slave_node) {
+               genpd_sd_counter_inc(link->master);
+               genpd->status = GPD_STATE_WAIT_MASTER;
+
                mutex_unlock(&genpd->lock);
-               genpd_release_lock(parent);
 
-               ret = pm_genpd_poweron(parent);
-               if (ret)
-                       return ret;
+               ret = pm_genpd_poweron(link->master);
 
-               goto start;
+               mutex_lock(&genpd->lock);
+
+               /*
+                * The "wait for parent" status is guaranteed not to change
+                * while the master is powering on.
+                */
+               genpd->status = GPD_STATE_POWER_OFF;
+               wake_up_all(&genpd->status_wait_queue);
+               if (ret) {
+                       genpd_sd_counter_dec(link->master);
+                       goto err;
+               }
        }
 
        if (genpd->power_on) {
                ret = genpd->power_on(genpd);
                if (ret)
-                       goto out;
+                       goto err;
        }
 
        genpd_set_active(genpd);
-       if (parent)
-               parent->sd_count++;
 
- out:
-       mutex_unlock(&genpd->lock);
-       if (parent)
-               genpd_release_lock(parent);
+       return 0;
+
+ err:
+       list_for_each_entry_continue_reverse(link, &genpd->slave_links, slave_node)
+               genpd_sd_counter_dec(link->master);
+
+       return ret;
+}
+
+/**
+ * pm_genpd_poweron - Restore power to a given PM domain and its masters.
+ * @genpd: PM domain to power up.
+ */
+int pm_genpd_poweron(struct generic_pm_domain *genpd)
+{
+       int ret;
 
+       mutex_lock(&genpd->lock);
+       ret = __pm_genpd_poweron(genpd);
+       mutex_unlock(&genpd->lock);
        return ret;
 }
 
@@ -134,18 +181,18 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
 
 /**
  * __pm_genpd_save_device - Save the pre-suspend state of a device.
- * @dle: Device list entry of the device to save the state of.
+ * @pdd: Domain data of the device to save the state of.
  * @genpd: PM domain the device belongs to.
  */
-static int __pm_genpd_save_device(struct dev_list_entry *dle,
+static int __pm_genpd_save_device(struct pm_domain_data *pdd,
                                  struct generic_pm_domain *genpd)
        __releases(&genpd->lock) __acquires(&genpd->lock)
 {
-       struct device *dev = dle->dev;
+       struct device *dev = pdd->dev;
        struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (dle->need_restore)
+       if (pdd->need_restore)
                return 0;
 
        mutex_unlock(&genpd->lock);
@@ -163,24 +210,24 @@ static int __pm_genpd_save_device(struct dev_list_entry *dle,
        mutex_lock(&genpd->lock);
 
        if (!ret)
-               dle->need_restore = true;
+               pdd->need_restore = true;
 
        return ret;
 }
 
 /**
  * __pm_genpd_restore_device - Restore the pre-suspend state of a device.
- * @dle: Device list entry of the device to restore the state of.
+ * @pdd: Domain data of the device to restore the state of.
  * @genpd: PM domain the device belongs to.
  */
-static void __pm_genpd_restore_device(struct dev_list_entry *dle,
+static void __pm_genpd_restore_device(struct pm_domain_data *pdd,
                                      struct generic_pm_domain *genpd)
        __releases(&genpd->lock) __acquires(&genpd->lock)
 {
-       struct device *dev = dle->dev;
+       struct device *dev = pdd->dev;
        struct device_driver *drv = dev->driver;
 
-       if (!dle->need_restore)
+       if (!pdd->need_restore)
                return;
 
        mutex_unlock(&genpd->lock);
@@ -197,7 +244,7 @@ static void __pm_genpd_restore_device(struct dev_list_entry *dle,
 
        mutex_lock(&genpd->lock);
 
-       dle->need_restore = false;
+       pdd->need_restore = false;
 }
 
 /**
@@ -211,7 +258,8 @@ static void __pm_genpd_restore_device(struct dev_list_entry *dle,
  */
 static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
 {
-       return genpd->status == GPD_STATE_ACTIVE || genpd->resume_count > 0;
+       return genpd->status == GPD_STATE_WAIT_MASTER
+               || genpd->status == GPD_STATE_ACTIVE || genpd->resume_count > 0;
 }
 
 /**
@@ -238,8 +286,8 @@ void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
 static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
        __releases(&genpd->lock) __acquires(&genpd->lock)
 {
-       struct generic_pm_domain *parent;
-       struct dev_list_entry *dle;
+       struct pm_domain_data *pdd;
+       struct gpd_link *link;
        unsigned int not_suspended;
        int ret = 0;
 
@@ -247,19 +295,21 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
        /*
         * Do not try to power off the domain in the following situations:
         * (1) The domain is already in the "power off" state.
-        * (2) System suspend is in progress.
+        * (2) The domain is waiting for its master to power up.
         * (3) One of the domain's devices is being resumed right now.
+        * (4) System suspend is in progress.
         */
-       if (genpd->status == GPD_STATE_POWER_OFF || genpd->prepared_count > 0
-           || genpd->resume_count > 0)
+       if (genpd->status == GPD_STATE_POWER_OFF
+           || genpd->status == GPD_STATE_WAIT_MASTER
+           || genpd->resume_count > 0 || genpd->prepared_count > 0)
                return 0;
 
-       if (genpd->sd_count > 0)
+       if (atomic_read(&genpd->sd_count) > 0)
                return -EBUSY;
 
        not_suspended = 0;
-       list_for_each_entry(dle, &genpd->dev_list, node)
-               if (dle->dev->driver && !pm_runtime_suspended(dle->dev))
+       list_for_each_entry(pdd, &genpd->dev_list, list_node)
+               if (pdd->dev->driver && !pm_runtime_suspended(pdd->dev))
                        not_suspended++;
 
        if (not_suspended > genpd->in_progress)
@@ -282,54 +332,50 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
        genpd->status = GPD_STATE_BUSY;
        genpd->poweroff_task = current;
 
-       list_for_each_entry_reverse(dle, &genpd->dev_list, node) {
-               ret = __pm_genpd_save_device(dle, genpd);
+       list_for_each_entry_reverse(pdd, &genpd->dev_list, list_node) {
+               ret = atomic_read(&genpd->sd_count) == 0 ?
+                       __pm_genpd_save_device(pdd, genpd) : -EBUSY;
+
+               if (genpd_abort_poweroff(genpd))
+                       goto out;
+
                if (ret) {
                        genpd_set_active(genpd);
                        goto out;
                }
 
-               if (genpd_abort_poweroff(genpd))
-                       goto out;
-
                if (genpd->status == GPD_STATE_REPEAT) {
                        genpd->poweroff_task = NULL;
                        goto start;
                }
        }
 
-       parent = genpd->parent;
-       if (parent) {
-               mutex_unlock(&genpd->lock);
-
-               genpd_acquire_lock(parent);
-               mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
-
-               if (genpd_abort_poweroff(genpd)) {
-                       genpd_release_lock(parent);
+       if (genpd->power_off) {
+               if (atomic_read(&genpd->sd_count) > 0) {
+                       ret = -EBUSY;
                        goto out;
                }
-       }
 
-       if (genpd->power_off) {
+               /*
+                * If sd_count > 0 at this point, one of the subdomains hasn't
+                * managed to call pm_genpd_poweron() for the master yet after
+                * incrementing it.  In that case pm_genpd_poweron() will wait
+                * for us to drop the lock, so we can call .power_off() and let
+                * the pm_genpd_poweron() restore power for us (this shouldn't
+                * happen very often).
+                */
                ret = genpd->power_off(genpd);
                if (ret == -EBUSY) {
                        genpd_set_active(genpd);
-                       if (parent)
-                               genpd_release_lock(parent);
-
                        goto out;
                }
        }
 
        genpd->status = GPD_STATE_POWER_OFF;
 
-       if (parent) {
-               genpd_sd_counter_dec(parent);
-               if (parent->sd_count == 0)
-                       genpd_queue_power_off_work(parent);
-
-               genpd_release_lock(parent);
+       list_for_each_entry(link, &genpd->slave_links, slave_node) {
+               genpd_sd_counter_dec(link->master);
+               genpd_queue_power_off_work(link->master);
        }
 
  out:
@@ -386,24 +432,6 @@ static int pm_genpd_runtime_suspend(struct device *dev)
        return 0;
 }
 
-/**
- * __pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
- * @dev: Device to resume.
- * @genpd: PM domain the device belongs to.
- */
-static void __pm_genpd_runtime_resume(struct device *dev,
-                                     struct generic_pm_domain *genpd)
-{
-       struct dev_list_entry *dle;
-
-       list_for_each_entry(dle, &genpd->dev_list, node) {
-               if (dle->dev == dev) {
-                       __pm_genpd_restore_device(dle, genpd);
-                       break;
-               }
-       }
-}
-
 /**
  * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
  * @dev: Device to resume.
@@ -424,11 +452,12 @@ static int pm_genpd_runtime_resume(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       ret = pm_genpd_poweron(genpd);
-       if (ret)
-               return ret;
-
        mutex_lock(&genpd->lock);
+       ret = __pm_genpd_poweron(genpd);
+       if (ret) {
+               mutex_unlock(&genpd->lock);
+               return ret;
+       }
        genpd->status = GPD_STATE_BUSY;
        genpd->resume_count++;
        for (;;) {
@@ -448,7 +477,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
                mutex_lock(&genpd->lock);
        }
        finish_wait(&genpd->status_wait_queue, &wait);
-       __pm_genpd_runtime_resume(dev, genpd);
+       __pm_genpd_restore_device(&dev->power.subsys_data->domain_data, genpd);
        genpd->resume_count--;
        genpd_set_active(genpd);
        wake_up_all(&genpd->status_wait_queue);
@@ -478,8 +507,6 @@ void pm_genpd_poweroff_unused(void)
 #else
 
 static inline void genpd_power_off_work_fn(struct work_struct *work) {}
-static inline void __pm_genpd_runtime_resume(struct device *dev,
-                                            struct generic_pm_domain *genpd) {}
 
 #define pm_genpd_runtime_suspend       NULL
 #define pm_genpd_runtime_resume                NULL
@@ -489,11 +516,11 @@ static inline void __pm_genpd_runtime_resume(struct device *dev,
 #ifdef CONFIG_PM_SLEEP
 
 /**
- * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its parents.
+ * pm_genpd_sync_poweroff - Synchronously power off a PM domain and its masters.
  * @genpd: PM domain to power off, if possible.
  *
  * Check if the given PM domain can be powered off (during system suspend or
- * hibernation) and do that if so.  Also, in that case propagate to its parent.
+ * hibernation) and do that if so.  Also, in that case propagate to its masters.
  *
  * This function is only called in "noirq" stages of system power transitions,
  * so it need not acquire locks (all of the "noirq" callbacks are executed
@@ -501,21 +528,23 @@ static inline void __pm_genpd_runtime_resume(struct device *dev,
  */
 static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
 {
-       struct generic_pm_domain *parent = genpd->parent;
+       struct gpd_link *link;
 
        if (genpd->status == GPD_STATE_POWER_OFF)
                return;
 
-       if (genpd->suspended_count != genpd->device_count || genpd->sd_count > 0)
+       if (genpd->suspended_count != genpd->device_count
+           || atomic_read(&genpd->sd_count) > 0)
                return;
 
        if (genpd->power_off)
                genpd->power_off(genpd);
 
        genpd->status = GPD_STATE_POWER_OFF;
-       if (parent) {
-               genpd_sd_counter_dec(parent);
-               pm_genpd_sync_poweroff(parent);
+
+       list_for_each_entry(link, &genpd->slave_links, slave_node) {
+               genpd_sd_counter_dec(link->master);
+               pm_genpd_sync_poweroff(link->master);
        }
 }
 
@@ -1034,7 +1063,7 @@ static void pm_genpd_complete(struct device *dev)
  */
 int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
 {
-       struct dev_list_entry *dle;
+       struct pm_domain_data *pdd;
        int ret = 0;
 
        dev_dbg(dev, "%s()\n", __func__);
@@ -1054,26 +1083,20 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
                goto out;
        }
 
-       list_for_each_entry(dle, &genpd->dev_list, node)
-               if (dle->dev == dev) {
+       list_for_each_entry(pdd, &genpd->dev_list, list_node)
+               if (pdd->dev == dev) {
                        ret = -EINVAL;
                        goto out;
                }
 
-       dle = kzalloc(sizeof(*dle), GFP_KERNEL);
-       if (!dle) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       dle->dev = dev;
-       dle->need_restore = false;
-       list_add_tail(&dle->node, &genpd->dev_list);
        genpd->device_count++;
 
-       spin_lock_irq(&dev->power.lock);
        dev->pm_domain = &genpd->domain;
-       spin_unlock_irq(&dev->power.lock);
+       dev_pm_get_subsys_data(dev);
+       pdd = &dev->power.subsys_data->domain_data;
+       pdd->dev = dev;
+       pdd->need_restore = false;
+       list_add_tail(&pdd->list_node, &genpd->dev_list);
 
  out:
        genpd_release_lock(genpd);
@@ -1089,7 +1112,7 @@ int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
 int pm_genpd_remove_device(struct generic_pm_domain *genpd,
                           struct device *dev)
 {
-       struct dev_list_entry *dle;
+       struct pm_domain_data *pdd;
        int ret = -EINVAL;
 
        dev_dbg(dev, "%s()\n", __func__);
@@ -1104,17 +1127,16 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
                goto out;
        }
 
-       list_for_each_entry(dle, &genpd->dev_list, node) {
-               if (dle->dev != dev)
+       list_for_each_entry(pdd, &genpd->dev_list, list_node) {
+               if (pdd->dev != dev)
                        continue;
 
-               spin_lock_irq(&dev->power.lock);
+               list_del_init(&pdd->list_node);
+               pdd->dev = NULL;
+               dev_pm_put_subsys_data(dev);
                dev->pm_domain = NULL;
-               spin_unlock_irq(&dev->power.lock);
 
                genpd->device_count--;
-               list_del(&dle->node);
-               kfree(dle);
 
                ret = 0;
                break;
@@ -1129,48 +1151,55 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 /**
  * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
  * @genpd: Master PM domain to add the subdomain to.
- * @new_subdomain: Subdomain to be added.
+ * @subdomain: Subdomain to be added.
  */
 int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
-                          struct generic_pm_domain *new_subdomain)
+                          struct generic_pm_domain *subdomain)
 {
-       struct generic_pm_domain *subdomain;
+       struct gpd_link *link;
        int ret = 0;
 
-       if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(new_subdomain))
+       if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
                return -EINVAL;
 
  start:
        genpd_acquire_lock(genpd);
-       mutex_lock_nested(&new_subdomain->lock, SINGLE_DEPTH_NESTING);
+       mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
 
-       if (new_subdomain->status != GPD_STATE_POWER_OFF
-           && new_subdomain->status != GPD_STATE_ACTIVE) {
-               mutex_unlock(&new_subdomain->lock);
+       if (subdomain->status != GPD_STATE_POWER_OFF
+           && subdomain->status != GPD_STATE_ACTIVE) {
+               mutex_unlock(&subdomain->lock);
                genpd_release_lock(genpd);
                goto start;
        }
 
        if (genpd->status == GPD_STATE_POWER_OFF
-           &&  new_subdomain->status != GPD_STATE_POWER_OFF) {
+           &&  subdomain->status != GPD_STATE_POWER_OFF) {
                ret = -EINVAL;
                goto out;
        }
 
-       list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
-               if (subdomain == new_subdomain) {
+       list_for_each_entry(link, &genpd->slave_links, slave_node) {
+               if (link->slave == subdomain && link->master == genpd) {
                        ret = -EINVAL;
                        goto out;
                }
        }
 
-       list_add_tail(&new_subdomain->sd_node, &genpd->sd_list);
-       new_subdomain->parent = genpd;
+       link = kzalloc(sizeof(*link), GFP_KERNEL);
+       if (!link) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       link->master = genpd;
+       list_add_tail(&link->master_node, &genpd->master_links);
+       link->slave = subdomain;
+       list_add_tail(&link->slave_node, &subdomain->slave_links);
        if (subdomain->status != GPD_STATE_POWER_OFF)
-               genpd->sd_count++;
+               genpd_sd_counter_inc(genpd);
 
  out:
-       mutex_unlock(&new_subdomain->lock);
+       mutex_unlock(&subdomain->lock);
        genpd_release_lock(genpd);
 
        return ret;
@@ -1179,22 +1208,22 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 /**
  * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
  * @genpd: Master PM domain to remove the subdomain from.
- * @target: Subdomain to be removed.
+ * @subdomain: Subdomain to be removed.
  */
 int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
-                             struct generic_pm_domain *target)
+                             struct generic_pm_domain *subdomain)
 {
-       struct generic_pm_domain *subdomain;
+       struct gpd_link *link;
        int ret = -EINVAL;
 
-       if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(target))
+       if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
                return -EINVAL;
 
  start:
        genpd_acquire_lock(genpd);
 
-       list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
-               if (subdomain != target)
+       list_for_each_entry(link, &genpd->master_links, master_node) {
+               if (link->slave != subdomain)
                        continue;
 
                mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
@@ -1206,8 +1235,9 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
                        goto start;
                }
 
-               list_del(&subdomain->sd_node);
-               subdomain->parent = NULL;
+               list_del(&link->master_node);
+               list_del(&link->slave_node);
+               kfree(link);
                if (subdomain->status != GPD_STATE_POWER_OFF)
                        genpd_sd_counter_dec(genpd);
 
@@ -1234,15 +1264,14 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
        if (IS_ERR_OR_NULL(genpd))
                return;
 
-       INIT_LIST_HEAD(&genpd->sd_node);
-       genpd->parent = NULL;
+       INIT_LIST_HEAD(&genpd->master_links);
+       INIT_LIST_HEAD(&genpd->slave_links);
        INIT_LIST_HEAD(&genpd->dev_list);
-       INIT_LIST_HEAD(&genpd->sd_list);
        mutex_init(&genpd->lock);
        genpd->gov = gov;
        INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
        genpd->in_progress = 0;
-       genpd->sd_count = 0;
+       atomic_set(&genpd->sd_count, 0);
        genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
        init_waitqueue_head(&genpd->status_wait_queue);
        genpd->poweroff_task = NULL;
index a85459126bc6a5ef9cdb737140353084d0bd8c3e..ad994fb2453cfb2e9b21c24a4bae83cec47c9bb4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
 #include <linux/resume-trace.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
@@ -46,6 +47,7 @@ LIST_HEAD(dpm_prepared_list);
 LIST_HEAD(dpm_suspended_list);
 LIST_HEAD(dpm_noirq_list);
 
+struct suspend_stats suspend_stats;
 static DEFINE_MUTEX(dpm_list_mtx);
 static pm_message_t pm_transition;
 
@@ -97,6 +99,7 @@ void device_pm_add(struct device *dev)
                        dev_name(dev->parent));
        list_add_tail(&dev->power.entry, &dpm_list);
        mutex_unlock(&dpm_list_mtx);
+       dev_pm_qos_constraints_init(dev);
 }
 
 /**
@@ -107,6 +110,7 @@ void device_pm_remove(struct device *dev)
 {
        pr_debug("PM: Removing info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
+       dev_pm_qos_constraints_destroy(dev);
        complete_all(&dev->power.completion);
        mutex_lock(&dpm_list_mtx);
        list_del_init(&dev->power.entry);
@@ -464,8 +468,12 @@ void dpm_resume_noirq(pm_message_t state)
                mutex_unlock(&dpm_list_mtx);
 
                error = device_resume_noirq(dev, state);
-               if (error)
+               if (error) {
+                       suspend_stats.failed_resume_noirq++;
+                       dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
+                       dpm_save_failed_dev(dev_name(dev));
                        pm_dev_err(dev, state, " early", error);
+               }
 
                mutex_lock(&dpm_list_mtx);
                put_device(dev);
@@ -626,8 +634,12 @@ void dpm_resume(pm_message_t state)
                        mutex_unlock(&dpm_list_mtx);
 
                        error = device_resume(dev, state, false);
-                       if (error)
+                       if (error) {
+                               suspend_stats.failed_resume++;
+                               dpm_save_failed_step(SUSPEND_RESUME);
+                               dpm_save_failed_dev(dev_name(dev));
                                pm_dev_err(dev, state, "", error);
+                       }
 
                        mutex_lock(&dpm_list_mtx);
                }
@@ -802,6 +814,9 @@ int dpm_suspend_noirq(pm_message_t state)
                mutex_lock(&dpm_list_mtx);
                if (error) {
                        pm_dev_err(dev, state, " late", error);
+                       suspend_stats.failed_suspend_noirq++;
+                       dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
+                       dpm_save_failed_dev(dev_name(dev));
                        put_device(dev);
                        break;
                }
@@ -923,8 +938,10 @@ static void async_suspend(void *data, async_cookie_t cookie)
        int error;
 
        error = __device_suspend(dev, pm_transition, true);
-       if (error)
+       if (error) {
+               dpm_save_failed_dev(dev_name(dev));
                pm_dev_err(dev, pm_transition, " async", error);
+       }
 
        put_device(dev);
 }
@@ -967,6 +984,7 @@ int dpm_suspend(pm_message_t state)
                mutex_lock(&dpm_list_mtx);
                if (error) {
                        pm_dev_err(dev, state, "", error);
+                       dpm_save_failed_dev(dev_name(dev));
                        put_device(dev);
                        break;
                }
@@ -980,7 +998,10 @@ int dpm_suspend(pm_message_t state)
        async_synchronize_full();
        if (!error)
                error = async_error;
-       if (!error)
+       if (error) {
+               suspend_stats.failed_suspend++;
+               dpm_save_failed_step(SUSPEND_SUSPEND);
+       } else
                dpm_show_time(starttime, state, NULL);
        return error;
 }
@@ -1088,7 +1109,10 @@ int dpm_suspend_start(pm_message_t state)
        int error;
 
        error = dpm_prepare(state);
-       if (!error)
+       if (error) {
+               suspend_stats.failed_prepare++;
+               dpm_save_failed_step(SUSPEND_PREPARE);
+       } else
                error = dpm_suspend(state);
        return error;
 }
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
new file mode 100644 (file)
index 0000000..8d0b811
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * Devices PM QoS constraints management
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * This module exposes the interface to kernel space for specifying
+ * per-device PM QoS dependencies. It provides infrastructure for registration
+ * of:
+ *
+ * Dependents on a QoS value : register requests
+ * Watchers of QoS value : get notified when target QoS value changes
+ *
+ * This QoS design is best effort based. Dependents register their QoS needs.
+ * Watchers register to keep track of the current QoS needs of the system.
+ * Watchers can register different types of notification callbacks:
+ *  . a per-device notification callback using the dev_pm_qos_*_notifier API.
+ *    The notification chain data is stored in the per-device constraint
+ *    data struct.
+ *  . a system-wide notification callback using the dev_pm_qos_*_global_notifier
+ *    API. The notification chain data is stored in a static variable.
+ *
+ * Note about the per-device constraint data struct allocation:
+ * . The per-device constraints data struct ptr is tored into the device
+ *    dev_pm_info.
+ * . To minimize the data usage by the per-device constraints, the data struct
+ *   is only allocated at the first call to dev_pm_qos_add_request.
+ * . The data is later free'd when the device is removed from the system.
+ * . The constraints_state variable from dev_pm_info tracks the data struct
+ *    allocation state:
+ *    DEV_PM_QOS_NO_DEVICE: No device present or device removed, no data
+ *     allocated,
+ *    DEV_PM_QOS_DEVICE_PRESENT: Device present, data not allocated and will be
+ *     allocated at the first call to dev_pm_qos_add_request,
+ *    DEV_PM_QOS_ALLOCATED: Device present, data allocated. The per-device
+ *     PM QoS constraints framework is operational and constraints can be
+ *     added, updated or removed using the dev_pm_qos_* API.
+ *  . A global mutex protects the constraints users from the data being
+ *     allocated and free'd.
+ */
+
+#include <linux/pm_qos.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+
+static DEFINE_MUTEX(dev_pm_qos_mtx);
+static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers);
+
+/*
+ * apply_constraint
+ * @req: constraint request to apply
+ * @action: action to perform add/update/remove, of type enum pm_qos_req_action
+ * @value: defines the qos request
+ *
+ * Internal function to update the constraints list using the PM QoS core
+ * code and if needed call the per-device and the global notification
+ * callbacks
+ */
+static int apply_constraint(struct dev_pm_qos_request *req,
+                           enum pm_qos_req_action action, int value)
+{
+       int ret, curr_value;
+
+       ret = pm_qos_update_target(req->dev->power.constraints,
+                                  &req->node, action, value);
+
+       if (ret) {
+               /* Call the global callbacks if needed */
+               curr_value = pm_qos_read_value(req->dev->power.constraints);
+               blocking_notifier_call_chain(&dev_pm_notifiers,
+                                            (unsigned long)curr_value,
+                                            req);
+       }
+
+       return ret;
+}
+
+/*
+ * dev_pm_qos_constraints_allocate
+ * @dev: device to allocate data for
+ *
+ * Called at the first call to add_request, for constraint data allocation
+ * Must be called with the dev_pm_qos_mtx mutex held
+ */
+static int dev_pm_qos_constraints_allocate(struct device *dev)
+{
+       struct pm_qos_constraints *c;
+       struct blocking_notifier_head *n;
+
+       c = kzalloc(sizeof(*c), GFP_KERNEL);
+       if (!c)
+               return -ENOMEM;
+
+       n = kzalloc(sizeof(*n), GFP_KERNEL);
+       if (!n) {
+               kfree(c);
+               return -ENOMEM;
+       }
+       BLOCKING_INIT_NOTIFIER_HEAD(n);
+
+       dev->power.constraints = c;
+       plist_head_init(&dev->power.constraints->list);
+       dev->power.constraints->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE;
+       dev->power.constraints->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE;
+       dev->power.constraints->type = PM_QOS_MIN;
+       dev->power.constraints->notifiers = n;
+       dev->power.constraints_state = DEV_PM_QOS_ALLOCATED;
+
+       return 0;
+}
+
+/**
+ * dev_pm_qos_constraints_init
+ * @dev: target device
+ *
+ * Called from the device PM subsystem at device insertion
+ */
+void dev_pm_qos_constraints_init(struct device *dev)
+{
+       mutex_lock(&dev_pm_qos_mtx);
+       dev->power.constraints_state = DEV_PM_QOS_DEVICE_PRESENT;
+       mutex_unlock(&dev_pm_qos_mtx);
+}
+
+/**
+ * dev_pm_qos_constraints_destroy
+ * @dev: target device
+ *
+ * Called from the device PM subsystem at device removal
+ */
+void dev_pm_qos_constraints_destroy(struct device *dev)
+{
+       struct dev_pm_qos_request *req, *tmp;
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (dev->power.constraints_state == DEV_PM_QOS_ALLOCATED) {
+               /* Flush the constraints list for the device */
+               plist_for_each_entry_safe(req, tmp,
+                                         &dev->power.constraints->list,
+                                         node) {
+                       /*
+                        * Update constraints list and call the notification
+                        * callbacks if needed
+                        */
+                       apply_constraint(req, PM_QOS_REMOVE_REQ,
+                                        PM_QOS_DEFAULT_VALUE);
+                       memset(req, 0, sizeof(*req));
+               }
+
+               kfree(dev->power.constraints->notifiers);
+               kfree(dev->power.constraints);
+               dev->power.constraints = NULL;
+       }
+       dev->power.constraints_state = DEV_PM_QOS_NO_DEVICE;
+
+       mutex_unlock(&dev_pm_qos_mtx);
+}
+
+/**
+ * dev_pm_qos_add_request - inserts new qos request into the list
+ * @dev: target device for the constraint
+ * @req: pointer to a preallocated handle
+ * @value: defines the qos request
+ *
+ * This function inserts a new entry in the device constraints list of
+ * requested qos performance characteristics. It recomputes the aggregate
+ * QoS expectations of parameters and initializes the dev_pm_qos_request
+ * handle.  Caller needs to save this handle for later use in updates and
+ * removal.
+ *
+ * Returns 1 if the aggregated constraint value has changed,
+ * 0 if the aggregated constraint value has not changed,
+ * -EINVAL in case of wrong parameters, -ENODEV if the device has been
+ * removed from the system
+ */
+int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
+                          s32 value)
+{
+       int ret = 0;
+
+       if (!dev || !req) /*guard against callers passing in null */
+               return -EINVAL;
+
+       if (dev_pm_qos_request_active(req)) {
+               WARN(1, KERN_ERR "dev_pm_qos_add_request() called for already "
+                       "added request\n");
+               return -EINVAL;
+       }
+
+       mutex_lock(&dev_pm_qos_mtx);
+       req->dev = dev;
+
+       /* Return if the device has been removed */
+       if (req->dev->power.constraints_state == DEV_PM_QOS_NO_DEVICE) {
+               ret = -ENODEV;
+               goto out;
+       }
+
+       /*
+        * Allocate the constraints data on the first call to add_request,
+        * i.e. only if the data is not already allocated and if the device has
+        * not been removed
+        */
+       if (dev->power.constraints_state == DEV_PM_QOS_DEVICE_PRESENT)
+               ret = dev_pm_qos_constraints_allocate(dev);
+
+       if (!ret)
+               ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
+
+out:
+       mutex_unlock(&dev_pm_qos_mtx);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_add_request);
+
+/**
+ * dev_pm_qos_update_request - modifies an existing qos request
+ * @req : handle to list element holding a dev_pm_qos request to use
+ * @new_value: defines the qos request
+ *
+ * Updates an existing dev PM qos request along with updating the
+ * target value.
+ *
+ * Attempts are made to make this code callable on hot code paths.
+ *
+ * Returns 1 if the aggregated constraint value has changed,
+ * 0 if the aggregated constraint value has not changed,
+ * -EINVAL in case of wrong parameters, -ENODEV if the device has been
+ * removed from the system
+ */
+int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
+                             s32 new_value)
+{
+       int ret = 0;
+
+       if (!req) /*guard against callers passing in null */
+               return -EINVAL;
+
+       if (!dev_pm_qos_request_active(req)) {
+               WARN(1, KERN_ERR "dev_pm_qos_update_request() called for "
+                       "unknown object\n");
+               return -EINVAL;
+       }
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (req->dev->power.constraints_state == DEV_PM_QOS_ALLOCATED) {
+               if (new_value != req->node.prio)
+                       ret = apply_constraint(req, PM_QOS_UPDATE_REQ,
+                                              new_value);
+       } else {
+               /* Return if the device has been removed */
+               ret = -ENODEV;
+       }
+
+       mutex_unlock(&dev_pm_qos_mtx);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
+
+/**
+ * dev_pm_qos_remove_request - modifies an existing qos request
+ * @req: handle to request list element
+ *
+ * Will remove pm qos request from the list of constraints and
+ * recompute the current target value. Call this on slow code paths.
+ *
+ * Returns 1 if the aggregated constraint value has changed,
+ * 0 if the aggregated constraint value has not changed,
+ * -EINVAL in case of wrong parameters, -ENODEV if the device has been
+ * removed from the system
+ */
+int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
+{
+       int ret = 0;
+
+       if (!req) /*guard against callers passing in null */
+               return -EINVAL;
+
+       if (!dev_pm_qos_request_active(req)) {
+               WARN(1, KERN_ERR "dev_pm_qos_remove_request() called for "
+                       "unknown object\n");
+               return -EINVAL;
+       }
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (req->dev->power.constraints_state == DEV_PM_QOS_ALLOCATED) {
+               ret = apply_constraint(req, PM_QOS_REMOVE_REQ,
+                                      PM_QOS_DEFAULT_VALUE);
+               memset(req, 0, sizeof(*req));
+       } else {
+               /* Return if the device has been removed */
+               ret = -ENODEV;
+       }
+
+       mutex_unlock(&dev_pm_qos_mtx);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_remove_request);
+
+/**
+ * dev_pm_qos_add_notifier - sets notification entry for changes to target value
+ * of per-device PM QoS constraints
+ *
+ * @dev: target device for the constraint
+ * @notifier: notifier block managed by caller.
+ *
+ * Will register the notifier into a notification chain that gets called
+ * upon changes to the target value for the device.
+ */
+int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier)
+{
+       int retval = 0;
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       /* Silently return if the device has been removed */
+       if (dev->power.constraints_state != DEV_PM_QOS_ALLOCATED)
+               goto out;
+
+       retval = blocking_notifier_chain_register(
+                       dev->power.constraints->notifiers,
+                       notifier);
+
+out:
+       mutex_unlock(&dev_pm_qos_mtx);
+       return retval;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_add_notifier);
+
+/**
+ * dev_pm_qos_remove_notifier - deletes notification for changes to target value
+ * of per-device PM QoS constraints
+ *
+ * @dev: target device for the constraint
+ * @notifier: notifier block to be removed.
+ *
+ * Will remove the notifier from the notification chain that gets called
+ * upon changes to the target value.
+ */
+int dev_pm_qos_remove_notifier(struct device *dev,
+                              struct notifier_block *notifier)
+{
+       int retval = 0;
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       /* Silently return if the device has been removed */
+       if (dev->power.constraints_state != DEV_PM_QOS_ALLOCATED)
+               goto out;
+
+       retval = blocking_notifier_chain_unregister(
+                       dev->power.constraints->notifiers,
+                       notifier);
+
+out:
+       mutex_unlock(&dev_pm_qos_mtx);
+       return retval;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_remove_notifier);
+
+/**
+ * dev_pm_qos_add_global_notifier - sets notification entry for changes to
+ * target value of the PM QoS constraints for any device
+ *
+ * @notifier: notifier block managed by caller.
+ *
+ * Will register the notifier into a notification chain that gets called
+ * upon changes to the target value for any device.
+ */
+int dev_pm_qos_add_global_notifier(struct notifier_block *notifier)
+{
+       return blocking_notifier_chain_register(&dev_pm_notifiers, notifier);
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_add_global_notifier);
+
+/**
+ * dev_pm_qos_remove_global_notifier - deletes notification for changes to
+ * target value of PM QoS constraints for any device
+ *
+ * @notifier: notifier block to be removed.
+ *
+ * Will remove the notifier from the notification chain that gets called
+ * upon changes to the target value for any device.
+ */
+int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier)
+{
+       return blocking_notifier_chain_unregister(&dev_pm_notifiers, notifier);
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_remove_global_notifier);
index acb3f83b8079486e214dc23e315ca3f9f6f755c4..04e18abb50bb6710adaef42932a51ed1c602a26b 100644 (file)
@@ -732,13 +732,16 @@ EXPORT_SYMBOL_GPL(pm_schedule_suspend);
  * return immediately if it is larger than zero.  Then carry out an idle
  * notification, either synchronous or asynchronous.
  *
- * This routine may be called in atomic context if the RPM_ASYNC flag is set.
+ * This routine may be called in atomic context if the RPM_ASYNC flag is set,
+ * or if pm_runtime_irq_safe() has been called.
  */
 int __pm_runtime_idle(struct device *dev, int rpmflags)
 {
        unsigned long flags;
        int retval;
 
+       might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
+
        if (rpmflags & RPM_GET_PUT) {
                if (!atomic_dec_and_test(&dev->power.usage_count))
                        return 0;
@@ -761,13 +764,16 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle);
  * return immediately if it is larger than zero.  Then carry out a suspend,
  * either synchronous or asynchronous.
  *
- * This routine may be called in atomic context if the RPM_ASYNC flag is set.
+ * This routine may be called in atomic context if the RPM_ASYNC flag is set,
+ * or if pm_runtime_irq_safe() has been called.
  */
 int __pm_runtime_suspend(struct device *dev, int rpmflags)
 {
        unsigned long flags;
        int retval;
 
+       might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
+
        if (rpmflags & RPM_GET_PUT) {
                if (!atomic_dec_and_test(&dev->power.usage_count))
                        return 0;
@@ -789,13 +795,16 @@ EXPORT_SYMBOL_GPL(__pm_runtime_suspend);
  * If the RPM_GET_PUT flag is set, increment the device's usage count.  Then
  * carry out a resume, either synchronous or asynchronous.
  *
- * This routine may be called in atomic context if the RPM_ASYNC flag is set.
+ * This routine may be called in atomic context if the RPM_ASYNC flag is set,
+ * or if pm_runtime_irq_safe() has been called.
  */
 int __pm_runtime_resume(struct device *dev, int rpmflags)
 {
        unsigned long flags;
        int retval;
 
+       might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
+
        if (rpmflags & RPM_GET_PUT)
                atomic_inc(&dev->power.usage_count);
 
index f476f4571295c69471e1bf723efbbc77d86cf915..057c13f66a674685d228e7fb1b5bb456b9a5e703 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_REGMAP) += regmap.o
+obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
new file mode 100644 (file)
index 0000000..5ab3fef
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Register map access API internal header
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _REGMAP_INTERNAL_H
+#define _REGMAP_INTERNAL_H
+
+#include <linux/regmap.h>
+#include <linux/fs.h>
+
+struct regmap;
+
+struct regmap_format {
+       size_t buf_size;
+       size_t reg_bytes;
+       size_t val_bytes;
+       void (*format_write)(struct regmap *map,
+                            unsigned int reg, unsigned int val);
+       void (*format_reg)(void *buf, unsigned int reg);
+       void (*format_val)(void *buf, unsigned int val);
+       unsigned int (*parse_val)(void *buf);
+};
+
+struct regmap {
+       struct mutex lock;
+
+       struct device *dev; /* Device we do I/O on */
+       void *work_buf;     /* Scratch buffer used to format I/O */
+       struct regmap_format format;  /* Buffer format */
+       const struct regmap_bus *bus;
+
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *debugfs;
+#endif
+
+       unsigned int max_register;
+       bool (*writeable_reg)(struct device *dev, unsigned int reg);
+       bool (*readable_reg)(struct device *dev, unsigned int reg);
+       bool (*volatile_reg)(struct device *dev, unsigned int reg);
+       bool (*precious_reg)(struct device *dev, unsigned int reg);
+};
+
+bool regmap_writeable(struct regmap *map, unsigned int reg);
+bool regmap_readable(struct regmap *map, unsigned int reg);
+bool regmap_volatile(struct regmap *map, unsigned int reg);
+bool regmap_precious(struct regmap *map, unsigned int reg);
+
+#ifdef CONFIG_DEBUG_FS
+extern void regmap_debugfs_initcall(void);
+extern void regmap_debugfs_init(struct regmap *map);
+extern void regmap_debugfs_exit(struct regmap *map);
+#else
+void regmap_debugfs_initcall(void) { }
+void regmap_debugfs_init(struct regmap *map) { }
+void regmap_debugfs_exit(struct regmap *map) { }
+#endif
+
+#endif
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
new file mode 100644 (file)
index 0000000..7a8d675
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Register map access API - debugfs
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include "internal.h"
+
+static struct dentry *regmap_debugfs_root;
+
+/* Calculate the length of a fixed format  */
+static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size)
+{
+       snprintf(buf, buf_size, "%x", max_val);
+       return strlen(buf);
+}
+
+static int regmap_open_file(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
+                                   size_t count, loff_t *ppos)
+{
+       int reg_len, val_len, tot_len;
+       size_t buf_pos = 0;
+       loff_t p = 0;
+       ssize_t ret;
+       int i;
+       struct regmap *map = file->private_data;
+       char *buf;
+       unsigned int val;
+
+       if (*ppos < 0 || !count)
+               return -EINVAL;
+
+       buf = kmalloc(count, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Calculate the length of a fixed format  */
+       reg_len = regmap_calc_reg_len(map->max_register, buf, count);
+       val_len = 2 * map->format.val_bytes;
+       tot_len = reg_len + val_len + 3;      /* : \n */
+
+       for (i = 0; i < map->max_register; i++) {
+               if (!regmap_readable(map, i))
+                       continue;
+
+               if (regmap_precious(map, i))
+                       continue;
+
+               /* If we're in the region the user is trying to read */
+               if (p >= *ppos) {
+                       /* ...but not beyond it */
+                       if (buf_pos >= count - 1 - tot_len)
+                               break;
+
+                       /* Format the register */
+                       snprintf(buf + buf_pos, count - buf_pos, "%.*x: ",
+                                reg_len, i);
+                       buf_pos += reg_len + 2;
+
+                       /* Format the value, write all X if we can't read */
+                       ret = regmap_read(map, i, &val);
+                       if (ret == 0)
+                               snprintf(buf + buf_pos, count - buf_pos,
+                                        "%.*x", val_len, val);
+                       else
+                               memset(buf + buf_pos, 'X', val_len);
+                       buf_pos += 2 * map->format.val_bytes;
+
+                       buf[buf_pos++] = '\n';
+               }
+               p += tot_len;
+       }
+
+       ret = buf_pos;
+
+       if (copy_to_user(user_buf, buf, buf_pos)) {
+               ret = -EFAULT;
+               goto out;
+       }
+
+       *ppos += buf_pos;
+
+out:
+       kfree(buf);
+       return ret;
+}
+
+static const struct file_operations regmap_map_fops = {
+       .open = regmap_open_file,
+       .read = regmap_map_read_file,
+       .llseek = default_llseek,
+};
+
+static ssize_t regmap_access_read_file(struct file *file,
+                                      char __user *user_buf, size_t count,
+                                      loff_t *ppos)
+{
+       int reg_len, tot_len;
+       size_t buf_pos = 0;
+       loff_t p = 0;
+       ssize_t ret;
+       int i;
+       struct regmap *map = file->private_data;
+       char *buf;
+
+       if (*ppos < 0 || !count)
+               return -EINVAL;
+
+       buf = kmalloc(count, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Calculate the length of a fixed format  */
+       reg_len = regmap_calc_reg_len(map->max_register, buf, count);
+       tot_len = reg_len + 10; /* ': R W V P\n' */
+
+       for (i = 0; i < map->max_register; i++) {
+               /* Ignore registers which are neither readable nor writable */
+               if (!regmap_readable(map, i) && !regmap_writeable(map, i))
+                       continue;
+
+               /* If we're in the region the user is trying to read */
+               if (p >= *ppos) {
+                       /* ...but not beyond it */
+                       if (buf_pos >= count - 1 - tot_len)
+                               break;
+
+                       /* Format the register */
+                       snprintf(buf + buf_pos, count - buf_pos,
+                                "%.*x: %c %c %c %c\n",
+                                reg_len, i,
+                                regmap_readable(map, i) ? 'y' : 'n',
+                                regmap_writeable(map, i) ? 'y' : 'n',
+                                regmap_volatile(map, i) ? 'y' : 'n',
+                                regmap_precious(map, i) ? 'y' : 'n');
+
+                       buf_pos += tot_len;
+               }
+               p += tot_len;
+       }
+
+       ret = buf_pos;
+
+       if (copy_to_user(user_buf, buf, buf_pos)) {
+               ret = -EFAULT;
+               goto out;
+       }
+
+       *ppos += buf_pos;
+
+out:
+       kfree(buf);
+       return ret;
+}
+
+static const struct file_operations regmap_access_fops = {
+       .open = regmap_open_file,
+       .read = regmap_access_read_file,
+       .llseek = default_llseek,
+};
+
+void regmap_debugfs_init(struct regmap *map)
+{
+       map->debugfs = debugfs_create_dir(dev_name(map->dev),
+                                         regmap_debugfs_root);
+       if (!map->debugfs) {
+               dev_warn(map->dev, "Failed to create debugfs directory\n");
+               return;
+       }
+
+       if (map->max_register) {
+               debugfs_create_file("registers", 0400, map->debugfs,
+                                   map, &regmap_map_fops);
+               debugfs_create_file("access", 0400, map->debugfs,
+                                   map, &regmap_access_fops);
+       }
+}
+
+void regmap_debugfs_exit(struct regmap *map)
+{
+       debugfs_remove_recursive(map->debugfs);
+}
+
+void regmap_debugfs_initcall(void)
+{
+       regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
+       if (!regmap_debugfs_root) {
+               pr_warn("regmap: Failed to create debugfs root\n");
+               return;
+       }
+}
index c4f7a45cd2c3386a95776081eab5350bb0034017..e7d916d1b3ea2d2e31dd58355288111d728eead3 100644 (file)
@@ -90,7 +90,6 @@ static int regmap_i2c_read(struct device *dev,
 }
 
 static struct regmap_bus regmap_i2c = {
-       .type = &i2c_bus_type,
        .write = regmap_i2c_write,
        .gather_write = regmap_i2c_gather_write,
        .read = regmap_i2c_read,
index f8396945d6ed6339741ab0bd6db8dca9a985a587..fe831e3ec8821453c7ea15547f04e5d184316630 100644 (file)
@@ -48,7 +48,6 @@ static int regmap_spi_read(struct device *dev,
 }
 
 static struct regmap_bus regmap_spi = {
-       .type = &spi_bus_type,
        .write = regmap_spi_write,
        .gather_write = regmap_spi_gather_write,
        .read = regmap_spi_read,
index 0eef4da1ac61f1deb274e56fb5601cfc6275c193..fa2bd896eb208fa8a92732eb6a2accf3ee3a4732 100644 (file)
 #include <linux/mutex.h>
 #include <linux/err.h>
 
-#include <linux/regmap.h>
-
-struct regmap;
-
-struct regmap_format {
-       size_t buf_size;
-       size_t reg_bytes;
-       size_t val_bytes;
-       void (*format_write)(struct regmap *map,
-                            unsigned int reg, unsigned int val);
-       void (*format_reg)(void *buf, unsigned int reg);
-       void (*format_val)(void *buf, unsigned int val);
-       unsigned int (*parse_val)(void *buf);
-};
-
-struct regmap {
-       struct mutex lock;
-
-       struct device *dev; /* Device we do I/O on */
-       void *work_buf;     /* Scratch buffer used to format I/O */
-       struct regmap_format format;  /* Buffer format */
-       const struct regmap_bus *bus;
-};
+#define CREATE_TRACE_POINTS
+#include <trace/events/regmap.h>
+
+#include "internal.h"
+
+bool regmap_writeable(struct regmap *map, unsigned int reg)
+{
+       if (map->max_register && reg > map->max_register)
+               return false;
+
+       if (map->writeable_reg)
+               return map->writeable_reg(map->dev, reg);
+
+       return true;
+}
+
+bool regmap_readable(struct regmap *map, unsigned int reg)
+{
+       if (map->max_register && reg > map->max_register)
+               return false;
+
+       if (map->readable_reg)
+               return map->readable_reg(map->dev, reg);
+
+       return true;
+}
+
+bool regmap_volatile(struct regmap *map, unsigned int reg)
+{
+       if (map->max_register && reg > map->max_register)
+               return false;
+
+       if (map->volatile_reg)
+               return map->volatile_reg(map->dev, reg);
+
+       return true;
+}
+
+bool regmap_precious(struct regmap *map, unsigned int reg)
+{
+       if (map->max_register && reg > map->max_register)
+               return false;
+
+       if (map->precious_reg)
+               return map->precious_reg(map->dev, reg);
+
+       return false;
+}
 
 static void regmap_format_4_12_write(struct regmap *map,
                                     unsigned int reg, unsigned int val)
@@ -116,6 +141,11 @@ struct regmap *regmap_init(struct device *dev,
        map->format.val_bytes = config->val_bits / 8;
        map->dev = dev;
        map->bus = bus;
+       map->max_register = config->max_register;
+       map->writeable_reg = config->writeable_reg;
+       map->readable_reg = config->readable_reg;
+       map->volatile_reg = config->volatile_reg;
+       map->precious_reg = config->precious_reg;
 
        switch (config->reg_bits) {
        case 4:
@@ -171,6 +201,8 @@ struct regmap *regmap_init(struct device *dev,
                goto err_bus;
        }
 
+       regmap_debugfs_init(map);
+
        return map;
 
 err_bus:
@@ -187,6 +219,7 @@ EXPORT_SYMBOL_GPL(regmap_init);
  */
 void regmap_exit(struct regmap *map)
 {
+       regmap_debugfs_exit(map);
        kfree(map->work_buf);
        module_put(map->bus->owner);
        kfree(map);
@@ -199,16 +232,32 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
        void *buf;
        int ret = -ENOTSUPP;
        size_t len;
+       int i;
+
+       /* Check for unwritable registers before we start */
+       if (map->writeable_reg)
+               for (i = 0; i < val_len / map->format.val_bytes; i++)
+                       if (!map->writeable_reg(map->dev, reg + i))
+                               return -EINVAL;
 
        map->format.format_reg(map->work_buf, reg);
 
-       /* Try to do a gather write if we can */
-       if (map->bus->gather_write)
+       trace_regmap_hw_write_start(map->dev, reg,
+                                   val_len / map->format.val_bytes);
+
+       /* If we're doing a single register write we can probably just
+        * send the work_buf directly, otherwise try to do a gather
+        * write.
+        */
+       if (val == map->work_buf + map->format.reg_bytes)
+               ret = map->bus->write(map->dev, map->work_buf,
+                                     map->format.reg_bytes + val_len);
+       else if (map->bus->gather_write)
                ret = map->bus->gather_write(map->dev, map->work_buf,
                                             map->format.reg_bytes,
                                             val, val_len);
 
-       /* Otherwise fall back on linearising by hand. */
+       /* If that didn't work fall back on linearising by hand. */
        if (ret == -ENOTSUPP) {
                len = map->format.reg_bytes + val_len;
                buf = kmalloc(len, GFP_KERNEL);
@@ -222,19 +271,31 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
                kfree(buf);
        }
 
+       trace_regmap_hw_write_done(map->dev, reg,
+                                  val_len / map->format.val_bytes);
+
        return ret;
 }
 
 static int _regmap_write(struct regmap *map, unsigned int reg,
                         unsigned int val)
 {
+       int ret;
        BUG_ON(!map->format.format_write && !map->format.format_val);
 
+       trace_regmap_reg_write(map->dev, reg, val);
+
        if (map->format.format_write) {
                map->format.format_write(map, reg, val);
 
-               return map->bus->write(map->dev, map->work_buf,
-                                      map->format.buf_size);
+               trace_regmap_hw_write_start(map->dev, reg, 1);
+
+               ret = map->bus->write(map->dev, map->work_buf,
+                                     map->format.buf_size);
+
+               trace_regmap_hw_write_done(map->dev, reg, 1);
+
+               return ret;
        } else {
                map->format.format_val(map->work_buf + map->format.reg_bytes,
                                       val);
@@ -316,12 +377,16 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
        if (map->bus->read_flag_mask)
                u8[0] |= map->bus->read_flag_mask;
 
+       trace_regmap_hw_read_start(map->dev, reg,
+                                  val_len / map->format.val_bytes);
+
        ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes,
                             val, val_len);
-       if (ret != 0)
-               return ret;
 
-       return 0;
+       trace_regmap_hw_read_done(map->dev, reg,
+                                 val_len / map->format.val_bytes);
+
+       return ret;
 }
 
 static int _regmap_read(struct regmap *map, unsigned int reg,
@@ -333,8 +398,10 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
                return -EINVAL;
 
        ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes);
-       if (ret == 0)
+       if (ret == 0) {
                *val = map->format.parse_val(map->work_buf);
+               trace_regmap_reg_read(map->dev, reg, *val);
+       }
 
        return ret;
 }
@@ -453,3 +520,11 @@ out:
        return ret;
 }
 EXPORT_SYMBOL_GPL(regmap_update_bits);
+
+static int __init regmap_initcall(void)
+{
+       regmap_debugfs_initcall();
+
+       return 0;
+}
+postcore_initcall(regmap_initcall);
index ae0a02e1b808dafdf2e13edfac026f339fb68a43..c1172dafdffac1c7688155dc20a658628c6934ca 100644 (file)
@@ -33,6 +33,19 @@ config BCMA_DRIVER_PCI_HOSTMODE
        help
          PCI core hostmode operation (external PCI bus).
 
+config BCMA_HOST_SOC
+       bool
+       depends on BCMA_DRIVER_MIPS
+
+config BCMA_DRIVER_MIPS
+       bool "BCMA Broadcom MIPS core driver"
+       depends on BCMA && MIPS
+       help
+         Driver for the Broadcom MIPS core attached to Broadcom specific
+         Advanced Microcontroller Bus.
+
+         If unsure, say N
+
 config BCMA_DEBUG
        bool "BCMA debugging"
        depends on BCMA
index a2161cceafb9b3810278ee35e1a8749070c58649..82de24e5340ccc0c11e602ab2b89d93e7cfb430c 100644 (file)
@@ -2,7 +2,9 @@ bcma-y                                  += main.o scan.o core.o sprom.o
 bcma-y                                 += driver_chipcommon.o driver_chipcommon_pmu.o
 bcma-y                                 += driver_pci.o
 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)        += driver_pci_host.o
+bcma-$(CONFIG_BCMA_DRIVER_MIPS)                += driver_mips.o
 bcma-$(CONFIG_BCMA_HOST_PCI)           += host_pci.o
+bcma-$(CONFIG_BCMA_HOST_SOC)           += host_soc.o
 obj-$(CONFIG_BCMA)                     += bcma.o
 
 ccflags-$(CONFIG_BCMA_DEBUG)           := -DDEBUG
index e02ff21835c90b960722ab6419fed6039f47c828..30a3085d3354577d68e3121e4dfb77c57cc4409f 100644 (file)
@@ -15,13 +15,29 @@ struct bcma_bus;
 /* main.c */
 int bcma_bus_register(struct bcma_bus *bus);
 void bcma_bus_unregister(struct bcma_bus *bus);
+int __init bcma_bus_early_register(struct bcma_bus *bus,
+                                  struct bcma_device *core_cc,
+                                  struct bcma_device *core_mips);
 
 /* scan.c */
 int bcma_bus_scan(struct bcma_bus *bus);
+int __init bcma_bus_scan_early(struct bcma_bus *bus,
+                              struct bcma_device_id *match,
+                              struct bcma_device *core);
+void bcma_init_bus(struct bcma_bus *bus);
 
 /* sprom.c */
 int bcma_sprom_get(struct bcma_bus *bus);
 
+/* driver_chipcommon.c */
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
+
+/* driver_chipcommon_pmu.c */
+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
+
 #ifdef CONFIG_BCMA_HOST_PCI
 /* host_pci.c */
 extern int __init bcma_host_pci_init(void);
index 4a04a49cc06d8dd375efbe1d36d211e9fff3fae7..189a97b51be909be5fa5543b91141264dc35b0b1 100644 (file)
@@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
 u32 bcma_core_dma_translation(struct bcma_device *core)
 {
        switch (core->bus->hosttype) {
+       case BCMA_HOSTTYPE_SOC:
+               return 0;
        case BCMA_HOSTTYPE_PCI:
                if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
                        return BCMA_DMA_TRANSLATION_DMA64_CMT;
index 851e05bc948afea6740d5b590e26c1320654c6a8..47cce9d696306f28f8f6d9221e73b0f863df7f7e 100644 (file)
@@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
        u32 leddc_on = 10;
        u32 leddc_off = 90;
 
+       if (cc->setup_done)
+               return;
+
        if (cc->core->id.rev >= 11)
                cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
        cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
                        ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
                         (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
        }
+
+       cc->setup_done = true;
 }
 
 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
@@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
        return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
 }
+
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
+{
+       unsigned int irq;
+       u32 baud_base;
+       u32 i;
+       unsigned int ccrev = cc->core->id.rev;
+       struct bcma_serial_port *ports = cc->serial_ports;
+
+       if (ccrev >= 11 && ccrev != 15) {
+               /* Fixed ALP clock */
+               baud_base = bcma_pmu_alp_clock(cc);
+               if (ccrev >= 21) {
+                       /* Turn off UART clock before switching clocksource. */
+                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
+                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
+                                      & ~BCMA_CC_CORECTL_UARTCLKEN);
+               }
+               /* Set the override bit so we don't divide it */
+               bcma_cc_write32(cc, BCMA_CC_CORECTL,
+                              bcma_cc_read32(cc, BCMA_CC_CORECTL)
+                              | BCMA_CC_CORECTL_UARTCLK0);
+               if (ccrev >= 21) {
+                       /* Re-enable the UART clock. */
+                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
+                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
+                                      | BCMA_CC_CORECTL_UARTCLKEN);
+               }
+       } else {
+               pr_err("serial not supported on this device ccrev: 0x%x\n",
+                      ccrev);
+               return;
+       }
+
+       irq = bcma_core_mips_irq(cc->core);
+
+       /* Determine the registers of the UARTs */
+       cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
+       for (i = 0; i < cc->nr_serial_ports; i++) {
+               ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
+                               (i * 256);
+               ports[i].irq = irq;
+               ports[i].baud_base = baud_base;
+               ports[i].reg_shift = 0;
+       }
+}
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
index fcc63db0ce7542ded6428071103315370dda11cb..4bc10aa57bd425cf61cb0cb65f1e8f064b169e38 100644 (file)
 #include "bcma_private.h"
 #include <linux/bcma/bcma.h>
 
+static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
+{
+       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
+       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
+       return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
+}
+
 static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
                                        u32 offset, u32 mask, u32 set)
 {
@@ -83,6 +90,24 @@ void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
        }
 }
 
+/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
+{
+       struct bcma_bus *bus = cc->core->bus;
+       u32 val;
+
+       val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
+       if (enable) {
+               val |= BCMA_CHIPCTL_4331_EXTPA_EN;
+               if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
+                       val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
+       } else {
+               val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
+               val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
+       }
+       bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
+}
+
 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
 {
        struct bcma_bus *bus = cc->core->bus;
@@ -92,7 +117,7 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
                bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
                break;
        case 0x4331:
-               pr_err("Enabling Ext PA lines not implemented\n");
+               /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
                break;
        case 43224:
                if (bus->chipinfo.rev == 0) {
@@ -136,3 +161,129 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
        bcma_pmu_swreg_init(cc);
        bcma_pmu_workarounds(cc);
 }
+
+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
+{
+       struct bcma_bus *bus = cc->core->bus;
+
+       switch (bus->chipinfo.id) {
+       case 0x4716:
+       case 0x4748:
+       case 47162:
+       case 0x4313:
+       case 0x5357:
+       case 0x4749:
+       case 53572:
+               /* always 20Mhz */
+               return 20000 * 1000;
+       case 0x5356:
+       case 0x5300:
+               /* always 25Mhz */
+               return 25000 * 1000;
+       default:
+               pr_warn("No ALP clock specified for %04X device, "
+                       "pmu rev. %d, using default %d Hz\n",
+                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
+       }
+       return BCMA_CC_PMU_ALP_CLOCK;
+}
+
+/* Find the output of the "m" pll divider given pll controls that start with
+ * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
+ */
+static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
+{
+       u32 tmp, div, ndiv, p1, p2, fc;
+       struct bcma_bus *bus = cc->core->bus;
+
+       BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
+
+       BUG_ON(!m || m > 4);
+
+       if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
+               /* Detect failure in clock setting */
+               tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
+               if (tmp & 0x40000)
+                       return 133 * 1000000;
+       }
+
+       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
+       p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
+       p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
+
+       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
+       div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
+               BCMA_CC_PPL_MDIV_MASK;
+
+       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
+       ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
+
+       /* Do calculation in Mhz */
+       fc = bcma_pmu_alp_clock(cc) / 1000000;
+       fc = (p1 * ndiv * fc) / p2;
+
+       /* Return clock in Hertz */
+       return (fc / div) * 1000000;
+}
+
+/* query bus clock frequency for PMU-enabled chipcommon */
+u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
+{
+       struct bcma_bus *bus = cc->core->bus;
+
+       switch (bus->chipinfo.id) {
+       case 0x4716:
+       case 0x4748:
+       case 47162:
+               return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
+                                     BCMA_CC_PMU5_MAINPLL_SSB);
+       case 0x5356:
+               return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
+                                     BCMA_CC_PMU5_MAINPLL_SSB);
+       case 0x5357:
+       case 0x4749:
+               return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
+                                     BCMA_CC_PMU5_MAINPLL_SSB);
+       case 0x5300:
+               return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
+                                     BCMA_CC_PMU5_MAINPLL_SSB);
+       case 53572:
+               return 75000000;
+       default:
+               pr_warn("No backplane clock specified for %04X device, "
+                       "pmu rev. %d, using default %d Hz\n",
+                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
+       }
+       return BCMA_CC_PMU_HT_CLOCK;
+}
+
+/* query cpu clock frequency for PMU-enabled chipcommon */
+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
+{
+       struct bcma_bus *bus = cc->core->bus;
+
+       if (bus->chipinfo.id == 53572)
+               return 300000000;
+
+       if (cc->pmu.rev >= 5) {
+               u32 pll;
+               switch (bus->chipinfo.id) {
+               case 0x5356:
+                       pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
+                       break;
+               case 0x5357:
+               case 0x4749:
+                       pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
+                       break;
+               default:
+                       pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
+                       break;
+               }
+
+               /* TODO: if (bus->chipinfo.id == 0x5300)
+                 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
+               return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
+       }
+
+       return bcma_pmu_get_clockcontrol(cc);
+}
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
new file mode 100644 (file)
index 0000000..c3e9dff
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Broadcom specific AMBA
+ * Broadcom MIPS32 74K core driver
+ *
+ * Copyright 2009, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
+ * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+
+#include <linux/bcma/bcma.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/time.h>
+
+/* The 47162a0 hangs when reading MIPS DMP registers registers */
+static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
+{
+       return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
+              dev->id.id == BCMA_CORE_MIPS_74K;
+}
+
+/* The 5357b0 hangs when reading USB20H DMP registers */
+static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
+{
+       return (dev->bus->chipinfo.id == 0x5357 ||
+               dev->bus->chipinfo.id == 0x4749) &&
+              dev->bus->chipinfo.pkg == 11 &&
+              dev->id.id == BCMA_CORE_USB20_HOST;
+}
+
+static inline u32 mips_read32(struct bcma_drv_mips *mcore,
+                             u16 offset)
+{
+       return bcma_read32(mcore->core, offset);
+}
+
+static inline void mips_write32(struct bcma_drv_mips *mcore,
+                               u16 offset,
+                               u32 value)
+{
+       bcma_write32(mcore->core, offset, value);
+}
+
+static const u32 ipsflag_irq_mask[] = {
+       0,
+       BCMA_MIPS_IPSFLAG_IRQ1,
+       BCMA_MIPS_IPSFLAG_IRQ2,
+       BCMA_MIPS_IPSFLAG_IRQ3,
+       BCMA_MIPS_IPSFLAG_IRQ4,
+};
+
+static const u32 ipsflag_irq_shift[] = {
+       0,
+       BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
+       BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
+       BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
+       BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
+};
+
+static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
+{
+       u32 flag;
+
+       if (bcma_core_mips_bcm47162a0_quirk(dev))
+               return dev->core_index;
+       if (bcma_core_mips_bcm5357b0_quirk(dev))
+               return dev->core_index;
+       flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
+
+       return flag & 0x1F;
+}
+
+/* Get the MIPS IRQ assignment for a specified device.
+ * If unassigned, 0 is returned.
+ */
+unsigned int bcma_core_mips_irq(struct bcma_device *dev)
+{
+       struct bcma_device *mdev = dev->bus->drv_mips.core;
+       u32 irqflag;
+       unsigned int irq;
+
+       irqflag = bcma_core_mips_irqflag(dev);
+
+       for (irq = 1; irq <= 4; irq++)
+               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
+                   (1 << irqflag))
+                       return irq;
+
+       return 0;
+}
+EXPORT_SYMBOL(bcma_core_mips_irq);
+
+static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
+{
+       unsigned int oldirq = bcma_core_mips_irq(dev);
+       struct bcma_bus *bus = dev->bus;
+       struct bcma_device *mdev = bus->drv_mips.core;
+       u32 irqflag;
+
+       irqflag = bcma_core_mips_irqflag(dev);
+       BUG_ON(oldirq == 6);
+
+       dev->irq = irq + 2;
+
+       /* clear the old irq */
+       if (oldirq == 0)
+               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
+                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
+                           ~(1 << irqflag));
+       else
+               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
+
+       /* assign the new one */
+       if (irq == 0) {
+               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
+                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
+                           (1 << irqflag));
+       } else {
+               u32 oldirqflag = bcma_read32(mdev,
+                                            BCMA_MIPS_MIPS74K_INTMASK(irq));
+               if (oldirqflag) {
+                       struct bcma_device *core;
+
+                       /* backplane irq line is in use, find out who uses
+                        * it and set user to irq 0
+                        */
+                       list_for_each_entry_reverse(core, &bus->cores, list) {
+                               if ((1 << bcma_core_mips_irqflag(core)) ==
+                                   oldirqflag) {
+                                       bcma_core_mips_set_irq(core, 0);
+                                       break;
+                               }
+                       }
+               }
+               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
+                            1 << irqflag);
+       }
+
+       pr_info("set_irq: core 0x%04x, irq %d => %d\n",
+               dev->id.id, oldirq + 2, irq + 2);
+}
+
+static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
+{
+       int i;
+       static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
+       printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
+       for (i = 0; i <= 6; i++)
+               printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
+       printk("\n");
+}
+
+static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
+{
+       struct bcma_device *core;
+
+       list_for_each_entry_reverse(core, &bus->cores, list) {
+               bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
+       }
+}
+
+u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
+{
+       struct bcma_bus *bus = mcore->core->bus;
+
+       if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
+               return bcma_pmu_get_clockcpu(&bus->drv_cc);
+
+       pr_err("No PMU available, need this to get the cpu clock\n");
+       return 0;
+}
+EXPORT_SYMBOL(bcma_cpu_clock);
+
+static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
+{
+       struct bcma_bus *bus = mcore->core->bus;
+
+       switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
+       case BCMA_CC_FLASHT_STSER:
+       case BCMA_CC_FLASHT_ATSER:
+               pr_err("Serial flash not supported.\n");
+               break;
+       case BCMA_CC_FLASHT_PARA:
+               pr_info("found parallel flash.\n");
+               bus->drv_cc.pflash.window = 0x1c000000;
+               bus->drv_cc.pflash.window_size = 0x02000000;
+
+               if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
+                    BCMA_CC_FLASH_CFG_DS) == 0)
+                       bus->drv_cc.pflash.buswidth = 1;
+               else
+                       bus->drv_cc.pflash.buswidth = 2;
+               break;
+       default:
+               pr_err("flash not supported.\n");
+       }
+}
+
+void bcma_core_mips_init(struct bcma_drv_mips *mcore)
+{
+       struct bcma_bus *bus;
+       struct bcma_device *core;
+       bus = mcore->core->bus;
+
+       pr_info("Initializing MIPS core...\n");
+
+       if (!mcore->setup_done)
+               mcore->assigned_irqs = 1;
+
+       /* Assign IRQs to all cores on the bus */
+       list_for_each_entry_reverse(core, &bus->cores, list) {
+               int mips_irq;
+               if (core->irq)
+                       continue;
+
+               mips_irq = bcma_core_mips_irq(core);
+               if (mips_irq > 4)
+                       core->irq = 0;
+               else
+                       core->irq = mips_irq + 2;
+               if (core->irq > 5)
+                       continue;
+               switch (core->id.id) {
+               case BCMA_CORE_PCI:
+               case BCMA_CORE_PCIE:
+               case BCMA_CORE_ETHERNET:
+               case BCMA_CORE_ETHERNET_GBIT:
+               case BCMA_CORE_MAC_GBIT:
+               case BCMA_CORE_80211:
+               case BCMA_CORE_USB20_HOST:
+                       /* These devices get their own IRQ line if available,
+                        * the rest goes on IRQ0
+                        */
+                       if (mcore->assigned_irqs <= 4)
+                               bcma_core_mips_set_irq(core,
+                                                      mcore->assigned_irqs++);
+                       break;
+               }
+       }
+       pr_info("IRQ reconfiguration done\n");
+       bcma_core_mips_dump_irq(bus);
+
+       if (mcore->setup_done)
+               return;
+
+       bcma_chipco_serial_init(&bus->drv_cc);
+       bcma_core_mips_flash_detect(mcore);
+       mcore->setup_done = true;
+}
index 25f3ddf33823122433edfb6c1464598cc832acc5..81f3d0a4b856cb96b78c5492e779f1042c2788c5 100644 (file)
@@ -173,7 +173,7 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
                return false;
 
 #ifdef CONFIG_SSB_DRIVER_PCICORE
-       if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
+       if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
                return false;
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 
@@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
 
 void bcma_core_pci_init(struct bcma_drv_pci *pc)
 {
+       if (pc->setup_done)
+               return;
+
        if (bcma_core_pci_is_in_hostmode(pc)) {
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
                bcma_core_pci_hostmode_init(pc);
@@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
        } else {
                bcma_core_pci_clientmode_init(pc);
        }
+
+       pc->setup_done = true;
 }
 
 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
@@ -205,7 +210,14 @@ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
 {
        struct pci_dev *pdev = pc->core->bus->host_pci;
        u32 coremask, tmp;
-       int err;
+       int err = 0;
+
+       if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
+               /* This bcma device is not on a PCI host-bus. So the IRQs are
+                * not routed through the PCI core.
+                * So we must not enable routing through the PCI core. */
+               goto out;
+       }
 
        err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
        if (err)
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
new file mode 100644 (file)
index 0000000..3c381fb
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Broadcom specific AMBA
+ * System on Chip (SoC) Host
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include "scan.h"
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_soc.h>
+
+static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
+{
+       return readb(core->io_addr + offset);
+}
+
+static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
+{
+       return readw(core->io_addr + offset);
+}
+
+static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
+{
+       return readl(core->io_addr + offset);
+}
+
+static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
+                                u8 value)
+{
+       writeb(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
+                                u16 value)
+{
+       writew(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
+                                u32 value)
+{
+       writel(value, core->io_addr + offset);
+}
+
+#ifdef CONFIG_BCMA_BLOCKIO
+static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
+                                    size_t count, u16 offset, u8 reg_width)
+{
+       void __iomem *addr = core->io_addr + offset;
+
+       switch (reg_width) {
+       case sizeof(u8): {
+               u8 *buf = buffer;
+
+               while (count) {
+                       *buf = __raw_readb(addr);
+                       buf++;
+                       count--;
+               }
+               break;
+       }
+       case sizeof(u16): {
+               __le16 *buf = buffer;
+
+               WARN_ON(count & 1);
+               while (count) {
+                       *buf = (__force __le16)__raw_readw(addr);
+                       buf++;
+                       count -= 2;
+               }
+               break;
+       }
+       case sizeof(u32): {
+               __le32 *buf = buffer;
+
+               WARN_ON(count & 3);
+               while (count) {
+                       *buf = (__force __le32)__raw_readl(addr);
+                       buf++;
+                       count -= 4;
+               }
+               break;
+       }
+       default:
+               WARN_ON(1);
+       }
+}
+
+static void bcma_host_soc_block_write(struct bcma_device *core,
+                                     const void *buffer,
+                                     size_t count, u16 offset, u8 reg_width)
+{
+       void __iomem *addr = core->io_addr + offset;
+
+       switch (reg_width) {
+       case sizeof(u8): {
+               const u8 *buf = buffer;
+
+               while (count) {
+                       __raw_writeb(*buf, addr);
+                       buf++;
+                       count--;
+               }
+               break;
+       }
+       case sizeof(u16): {
+               const __le16 *buf = buffer;
+
+               WARN_ON(count & 1);
+               while (count) {
+                       __raw_writew((__force u16)(*buf), addr);
+                       buf++;
+                       count -= 2;
+               }
+               break;
+       }
+       case sizeof(u32): {
+               const __le32 *buf = buffer;
+
+               WARN_ON(count & 3);
+               while (count) {
+                       __raw_writel((__force u32)(*buf), addr);
+                       buf++;
+                       count -= 4;
+               }
+               break;
+       }
+       default:
+               WARN_ON(1);
+       }
+}
+#endif /* CONFIG_BCMA_BLOCKIO */
+
+static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
+{
+       return readl(core->io_wrap + offset);
+}
+
+static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
+                                 u32 value)
+{
+       writel(value, core->io_wrap + offset);
+}
+
+const struct bcma_host_ops bcma_host_soc_ops = {
+       .read8          = bcma_host_soc_read8,
+       .read16         = bcma_host_soc_read16,
+       .read32         = bcma_host_soc_read32,
+       .write8         = bcma_host_soc_write8,
+       .write16        = bcma_host_soc_write16,
+       .write32        = bcma_host_soc_write32,
+#ifdef CONFIG_BCMA_BLOCKIO
+       .block_read     = bcma_host_soc_block_read,
+       .block_write    = bcma_host_soc_block_write,
+#endif
+       .aread32        = bcma_host_soc_aread32,
+       .awrite32       = bcma_host_soc_awrite32,
+};
+
+int __init bcma_host_soc_register(struct bcma_soc *soc)
+{
+       struct bcma_bus *bus = &soc->bus;
+       int err;
+
+       /* iomap only first core. We have to read some register on this core
+        * to scan the bus.
+        */
+       bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
+       if (!bus->mmio)
+               return -ENOMEM;
+
+       /* Host specific */
+       bus->hosttype = BCMA_HOSTTYPE_SOC;
+       bus->ops = &bcma_host_soc_ops;
+
+       /* Register */
+       err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
+       if (err)
+               iounmap(bus->mmio);
+
+       return err;
+}
index 873e2e4ac55f01795a3b174b103ce0960c484bc2..8c09c3e547cd1d305050d9885a6641c9b33dcd01 100644 (file)
@@ -15,6 +15,7 @@ MODULE_LICENSE("GPL");
 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
 static int bcma_device_probe(struct device *dev);
 static int bcma_device_remove(struct device *dev);
+static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
 
 static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -49,6 +50,7 @@ static struct bus_type bcma_bus_type = {
        .match          = bcma_bus_match,
        .probe          = bcma_device_probe,
        .remove         = bcma_device_remove,
+       .uevent         = bcma_device_uevent,
        .dev_attrs      = bcma_device_attrs,
 };
 
@@ -66,6 +68,10 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
 static void bcma_release_core_dev(struct device *dev)
 {
        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+       if (core->io_addr)
+               iounmap(core->io_addr);
+       if (core->io_wrap)
+               iounmap(core->io_wrap);
        kfree(core);
 }
 
@@ -80,6 +86,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
                case BCMA_CORE_CHIPCOMMON:
                case BCMA_CORE_PCI:
                case BCMA_CORE_PCIE:
+               case BCMA_CORE_MIPS_74K:
                        continue;
                }
 
@@ -93,7 +100,10 @@ static int bcma_register_cores(struct bcma_bus *bus)
                        core->dma_dev = &bus->host_pci->dev;
                        core->irq = bus->host_pci->irq;
                        break;
-               case BCMA_HOSTTYPE_NONE:
+               case BCMA_HOSTTYPE_SOC:
+                       core->dev.dma_mask = &core->dev.coherent_dma_mask;
+                       core->dma_dev = &core->dev;
+                       break;
                case BCMA_HOSTTYPE_SDIO:
                        break;
                }
@@ -140,6 +150,13 @@ int bcma_bus_register(struct bcma_bus *bus)
                bcma_core_chipcommon_init(&bus->drv_cc);
        }
 
+       /* Init MIPS core */
+       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
+       if (core) {
+               bus->drv_mips.core = core;
+               bcma_core_mips_init(&bus->drv_mips);
+       }
+
        /* Init PCIE core */
        core = bcma_find_core(bus, BCMA_CORE_PCIE);
        if (core) {
@@ -169,6 +186,59 @@ void bcma_bus_unregister(struct bcma_bus *bus)
        bcma_unregister_cores(bus);
 }
 
+int __init bcma_bus_early_register(struct bcma_bus *bus,
+                                  struct bcma_device *core_cc,
+                                  struct bcma_device *core_mips)
+{
+       int err;
+       struct bcma_device *core;
+       struct bcma_device_id match;
+
+       bcma_init_bus(bus);
+
+       match.manuf = BCMA_MANUF_BCM;
+       match.id = BCMA_CORE_CHIPCOMMON;
+       match.class = BCMA_CL_SIM;
+       match.rev = BCMA_ANY_REV;
+
+       /* Scan for chip common core */
+       err = bcma_bus_scan_early(bus, &match, core_cc);
+       if (err) {
+               pr_err("Failed to scan for common core: %d\n", err);
+               return -1;
+       }
+
+       match.manuf = BCMA_MANUF_MIPS;
+       match.id = BCMA_CORE_MIPS_74K;
+       match.class = BCMA_CL_SIM;
+       match.rev = BCMA_ANY_REV;
+
+       /* Scan for mips core */
+       err = bcma_bus_scan_early(bus, &match, core_mips);
+       if (err) {
+               pr_err("Failed to scan for mips core: %d\n", err);
+               return -1;
+       }
+
+       /* Init CC core */
+       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
+       if (core) {
+               bus->drv_cc.core = core;
+               bcma_core_chipcommon_init(&bus->drv_cc);
+       }
+
+       /* Init MIPS core */
+       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
+       if (core) {
+               bus->drv_mips.core = core;
+               bcma_core_mips_init(&bus->drv_mips);
+       }
+
+       pr_info("Early bus registered\n");
+
+       return 0;
+}
+
 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
 {
        drv->drv.name = drv->name;
@@ -227,6 +297,16 @@ static int bcma_device_remove(struct device *dev)
        return 0;
 }
 
+static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+
+       return add_uevent_var(env,
+                             "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
+                             core->id.manuf, core->id.id,
+                             core->id.rev, core->id.class);
+}
+
 static int __init bcma_modinit(void)
 {
        int err;
index 40d7dcce8933da8491574c34cefd104106890456..0ea390f9aa9e75e3dfb2d18139eb670eca7f01f5 100644 (file)
@@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
        return addrl;
 }
 
-int bcma_bus_scan(struct bcma_bus *bus)
+static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
+                                                  u16 index)
 {
-       u32 erombase;
-       u32 __iomem *eromptr, *eromend;
+       struct bcma_device *core;
 
+       list_for_each_entry(core, &bus->cores, list) {
+               if (core->core_index == index)
+                       return core;
+       }
+       return NULL;
+}
+
+static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
+                             struct bcma_device_id *match, int core_num,
+                             struct bcma_device *core)
+{
+       s32 tmp;
+       u8 i, j;
        s32 cia, cib;
        u8 ports[2], wrappers[2];
 
+       /* get CIs */
+       cia = bcma_erom_get_ci(bus, eromptr);
+       if (cia < 0) {
+               bcma_erom_push_ent(eromptr);
+               if (bcma_erom_is_end(bus, eromptr))
+                       return -ESPIPE;
+               return -EILSEQ;
+       }
+       cib = bcma_erom_get_ci(bus, eromptr);
+       if (cib < 0)
+               return -EILSEQ;
+
+       /* parse CIs */
+       core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
+       core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
+       core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
+       ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
+       ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
+       wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
+       wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
+       core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
+
+       if (((core->id.manuf == BCMA_MANUF_ARM) &&
+            (core->id.id == 0xFFF)) ||
+           (ports[1] == 0)) {
+               bcma_erom_skip_component(bus, eromptr);
+               return -ENXIO;
+       }
+
+       /* check if component is a core at all */
+       if (wrappers[0] + wrappers[1] == 0) {
+               /* we could save addrl of the router
+               if (cid == BCMA_CORE_OOB_ROUTER)
+                */
+               bcma_erom_skip_component(bus, eromptr);
+               return -ENXIO;
+       }
+
+       if (bcma_erom_is_bridge(bus, eromptr)) {
+               bcma_erom_skip_component(bus, eromptr);
+               return -ENXIO;
+       }
+
+       if (bcma_find_core_by_index(bus, core_num)) {
+               bcma_erom_skip_component(bus, eromptr);
+               return -ENODEV;
+       }
+
+       if (match && ((match->manuf != BCMA_ANY_MANUF &&
+             match->manuf != core->id.manuf) ||
+            (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
+            (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
+            (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
+           )) {
+               bcma_erom_skip_component(bus, eromptr);
+               return -ENODEV;
+       }
+
+       /* get & parse master ports */
+       for (i = 0; i < ports[0]; i++) {
+               u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
+               if (mst_port_d < 0)
+                       return -EILSEQ;
+       }
+
+       /* get & parse slave ports */
+       for (i = 0; i < ports[1]; i++) {
+               for (j = 0; ; j++) {
+                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                               SCAN_ADDR_TYPE_SLAVE, i);
+                       if (tmp < 0) {
+                               /* no more entries for port _i_ */
+                               /* pr_debug("erom: slave port %d "
+                                * "has %d descriptors\n", i, j); */
+                               break;
+                       } else {
+                               if (i == 0 && j == 0)
+                                       core->addr = tmp;
+                       }
+               }
+       }
+
+       /* get & parse master wrappers */
+       for (i = 0; i < wrappers[0]; i++) {
+               for (j = 0; ; j++) {
+                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                               SCAN_ADDR_TYPE_MWRAP, i);
+                       if (tmp < 0) {
+                               /* no more entries for port _i_ */
+                               /* pr_debug("erom: master wrapper %d "
+                                * "has %d descriptors\n", i, j); */
+                               break;
+                       } else {
+                               if (i == 0 && j == 0)
+                                       core->wrap = tmp;
+                       }
+               }
+       }
+
+       /* get & parse slave wrappers */
+       for (i = 0; i < wrappers[1]; i++) {
+               u8 hack = (ports[1] == 1) ? 0 : 1;
+               for (j = 0; ; j++) {
+                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                               SCAN_ADDR_TYPE_SWRAP, i + hack);
+                       if (tmp < 0) {
+                               /* no more entries for port _i_ */
+                               /* pr_debug("erom: master wrapper %d "
+                                * has %d descriptors\n", i, j); */
+                               break;
+                       } else {
+                               if (wrappers[0] == 0 && !i && !j)
+                                       core->wrap = tmp;
+                       }
+               }
+       }
+       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
+               core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
+               if (!core->io_addr)
+                       return -ENOMEM;
+               core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
+               if (!core->io_wrap) {
+                       iounmap(core->io_addr);
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+}
+
+void bcma_init_bus(struct bcma_bus *bus)
+{
        s32 tmp;
-       u8 i, j;
 
-       int err;
+       if (bus->init_done)
+               return;
 
        INIT_LIST_HEAD(&bus->cores);
        bus->nr_cores = 0;
@@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
        bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
        bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
        bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+       bus->init_done = true;
+}
+
+int bcma_bus_scan(struct bcma_bus *bus)
+{
+       u32 erombase;
+       u32 __iomem *eromptr, *eromend;
+
+       int err, core_num = 0;
+
+       bcma_init_bus(bus);
 
        erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
-       eromptr = bus->mmio;
+       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
+               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
+               if (!eromptr)
+                       return -ENOMEM;
+       } else {
+               eromptr = bus->mmio;
+       }
+
        eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
 
        bcma_scan_switch_core(bus, erombase);
@@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
                INIT_LIST_HEAD(&core->list);
                core->bus = bus;
 
-               /* get CIs */
-               cia = bcma_erom_get_ci(bus, &eromptr);
-               if (cia < 0) {
-                       bcma_erom_push_ent(&eromptr);
-                       if (bcma_erom_is_end(bus, &eromptr))
-                               break;
-                       err= -EILSEQ;
-                       goto out;
-               }
-               cib = bcma_erom_get_ci(bus, &eromptr);
-               if (cib < 0) {
-                       err= -EILSEQ;
-                       goto out;
-               }
-
-               /* parse CIs */
-               core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
-               core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
-               core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
-               ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
-               ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
-               wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
-               wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
-               core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
-
-               if (((core->id.manuf == BCMA_MANUF_ARM) &&
-                    (core->id.id == 0xFFF)) ||
-                   (ports[1] == 0)) {
-                       bcma_erom_skip_component(bus, &eromptr);
+               err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
+               if (err == -ENODEV) {
+                       core_num++;
                        continue;
-               }
-
-               /* check if component is a core at all */
-               if (wrappers[0] + wrappers[1] == 0) {
-                       /* we could save addrl of the router
-                       if (cid == BCMA_CORE_OOB_ROUTER)
-                        */
-                       bcma_erom_skip_component(bus, &eromptr);
+               } else if (err == -ENXIO)
                        continue;
-               }
+               else if (err == -ESPIPE)
+                       break;
+               else if (err < 0)
+                       return err;
 
-               if (bcma_erom_is_bridge(bus, &eromptr)) {
-                       bcma_erom_skip_component(bus, &eromptr);
-                       continue;
-               }
+               core->core_index = core_num++;
+               bus->nr_cores++;
 
-               /* get & parse master ports */
-               for (i = 0; i < ports[0]; i++) {
-                       u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
-                       if (mst_port_d < 0) {
-                               err= -EILSEQ;
-                               goto out;
-                       }
-               }
+               pr_info("Core %d found: %s "
+                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
+                       core->core_index, bcma_device_name(&core->id),
+                       core->id.manuf, core->id.id, core->id.rev,
+                       core->id.class);
 
-               /* get & parse slave ports */
-               for (i = 0; i < ports[1]; i++) {
-                       for (j = 0; ; j++) {
-                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
-                                       SCAN_ADDR_TYPE_SLAVE, i);
-                               if (tmp < 0) {
-                                       /* no more entries for port _i_ */
-                                       /* pr_debug("erom: slave port %d "
-                                        * "has %d descriptors\n", i, j); */
-                                       break;
-                               } else {
-                                       if (i == 0 && j == 0)
-                                               core->addr = tmp;
-                               }
-                       }
-               }
+               list_add(&core->list, &bus->cores);
+       }
 
-               /* get & parse master wrappers */
-               for (i = 0; i < wrappers[0]; i++) {
-                       for (j = 0; ; j++) {
-                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
-                                       SCAN_ADDR_TYPE_MWRAP, i);
-                               if (tmp < 0) {
-                                       /* no more entries for port _i_ */
-                                       /* pr_debug("erom: master wrapper %d "
-                                        * "has %d descriptors\n", i, j); */
-                                       break;
-                               } else {
-                                       if (i == 0 && j == 0)
-                                               core->wrap = tmp;
-                               }
-                       }
-               }
+       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
+               iounmap(eromptr);
 
-               /* get & parse slave wrappers */
-               for (i = 0; i < wrappers[1]; i++) {
-                       u8 hack = (ports[1] == 1) ? 0 : 1;
-                       for (j = 0; ; j++) {
-                               tmp = bcma_erom_get_addr_desc(bus, &eromptr,
-                                       SCAN_ADDR_TYPE_SWRAP, i + hack);
-                               if (tmp < 0) {
-                                       /* no more entries for port _i_ */
-                                       /* pr_debug("erom: master wrapper %d "
-                                        * has %d descriptors\n", i, j); */
-                                       break;
-                               } else {
-                                       if (wrappers[0] == 0 && !i && !j)
-                                               core->wrap = tmp;
-                               }
-                       }
-               }
+       return 0;
+}
+
+int __init bcma_bus_scan_early(struct bcma_bus *bus,
+                              struct bcma_device_id *match,
+                              struct bcma_device *core)
+{
+       u32 erombase;
+       u32 __iomem *eromptr, *eromend;
+
+       int err = -ENODEV;
+       int core_num = 0;
+
+       erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
+       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
+               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
+               if (!eromptr)
+                       return -ENOMEM;
+       } else {
+               eromptr = bus->mmio;
+       }
+
+       eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
+
+       bcma_scan_switch_core(bus, erombase);
+
+       while (eromptr < eromend) {
+               memset(core, 0, sizeof(*core));
+               INIT_LIST_HEAD(&core->list);
+               core->bus = bus;
 
+               err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
+               if (err == -ENODEV) {
+                       core_num++;
+                       continue;
+               } else if (err == -ENXIO)
+                       continue;
+               else if (err == -ESPIPE)
+                       break;
+               else if (err < 0)
+                       return err;
+
+               core->core_index = core_num++;
+               bus->nr_cores++;
                pr_info("Core %d found: %s "
                        "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
-                       bus->nr_cores, bcma_device_name(&core->id),
+                       core->core_index, bcma_device_name(&core->id),
                        core->id.manuf, core->id.id, core->id.rev,
                        core->id.class);
 
-               core->core_index = bus->nr_cores++;
                list_add(&core->list, &bus->cores);
-               continue;
-out:
-               return err;
+               err = 0;
+               break;
        }
 
-       return 0;
+       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
+               iounmap(eromptr);
+
+       return err;
 }
index 8b5b7856abe3314ceeb9526811267b9f7e3a2576..166ed13ec06685667aa00fe9cf381d08a2af71ed 100644 (file)
@@ -152,6 +152,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
        if (!sprom)
                return -ENOMEM;
 
+       if (bus->chipinfo.id == 0x4331)
+               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
+
        /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
         * According to brcm80211 this applies to cards with PCIe rev >= 6
         * TODO: understand this condition and use it */
@@ -159,6 +162,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
                BCMA_CC_SPROM_PCIE6;
        bcma_sprom_read(bus, offset, sprom);
 
+       if (bus->chipinfo.id == 0x4331)
+               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
+
        err = bcma_sprom_valid(sprom);
        if (err)
                goto out;
index 8f4ef656a1af4ca435ff3ecc5e0d6079e6a1e34d..6da7edea700a274815fb4367598478197a853f4e 100644 (file)
@@ -68,6 +68,10 @@ static int cciss_tape_cmds = 6;
 module_param(cciss_tape_cmds, int, 0644);
 MODULE_PARM_DESC(cciss_tape_cmds,
        "number of commands to allocate for tape devices (default: 6)");
+static int cciss_simple_mode;
+module_param(cciss_simple_mode, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(cciss_simple_mode,
+       "Use 'simple mode' rather than 'performant mode'");
 
 static DEFINE_MUTEX(cciss_mutex);
 static struct proc_dir_entry *proc_cciss;
@@ -176,6 +180,7 @@ static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol,
                        unsigned int block_size, InquiryData_struct *inq_buff,
                                   drive_info_struct *drv);
 static void __devinit cciss_interrupt_mode(ctlr_info_t *);
+static int __devinit cciss_enter_simple_mode(struct ctlr_info *h);
 static void start_io(ctlr_info_t *h);
 static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
                        __u8 page_code, unsigned char scsi3addr[],
@@ -388,7 +393,7 @@ static void cciss_seq_show_header(struct seq_file *seq)
                h->product_name,
                (unsigned long)h->board_id,
                h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
-               h->firm_ver[3], (unsigned int)h->intr[PERF_MODE_INT],
+               h->firm_ver[3], (unsigned int)h->intr[h->intr_mode],
                h->num_luns,
                h->Qdepth, h->commands_outstanding,
                h->maxQsinceinit, h->max_outstanding, h->maxSG);
@@ -636,6 +641,18 @@ static ssize_t host_store_rescan(struct device *dev,
 }
 static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
 
+static ssize_t host_show_transport_mode(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
+{
+       struct ctlr_info *h = to_hba(dev);
+
+       return snprintf(buf, 20, "%s\n",
+               h->transMethod & CFGTBL_Trans_Performant ?
+                       "performant" : "simple");
+}
+static DEVICE_ATTR(transport_mode, S_IRUGO, host_show_transport_mode, NULL);
+
 static ssize_t dev_show_unique_id(struct device *dev,
                                 struct device_attribute *attr,
                                 char *buf)
@@ -808,6 +825,7 @@ static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
 static struct attribute *cciss_host_attrs[] = {
        &dev_attr_rescan.attr,
        &dev_attr_resettable.attr,
+       &dev_attr_transport_mode.attr,
        NULL
 };
 
@@ -3984,6 +4002,9 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
 {
        __u32 trans_support;
 
+       if (cciss_simple_mode)
+               return;
+
        dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n");
        /* Attempt to put controller into performant mode if supported */
        /* Does board support performant mode? */
@@ -4081,7 +4102,7 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *h)
 default_int_mode:
 #endif                         /* CONFIG_PCI_MSI */
        /* if we get here we're going to use the default interrupt mode */
-       h->intr[PERF_MODE_INT] = h->pdev->irq;
+       h->intr[h->intr_mode] = h->pdev->irq;
        return;
 }
 
@@ -4341,6 +4362,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
        }
        cciss_enable_scsi_prefetch(h);
        cciss_p600_dma_prefetch_quirk(h);
+       err = cciss_enter_simple_mode(h);
+       if (err)
+               goto err_out_free_res;
        cciss_put_controller_into_performant_mode(h);
        return 0;
 
@@ -4843,20 +4867,20 @@ static int cciss_request_irq(ctlr_info_t *h,
        irqreturn_t (*intxhandler)(int, void *))
 {
        if (h->msix_vector || h->msi_vector) {
-               if (!request_irq(h->intr[PERF_MODE_INT], msixhandler,
+               if (!request_irq(h->intr[h->intr_mode], msixhandler,
                                IRQF_DISABLED, h->devname, h))
                        return 0;
                dev_err(&h->pdev->dev, "Unable to get msi irq %d"
-                       " for %s\n", h->intr[PERF_MODE_INT],
+                       " for %s\n", h->intr[h->intr_mode],
                        h->devname);
                return -1;
        }
 
-       if (!request_irq(h->intr[PERF_MODE_INT], intxhandler,
+       if (!request_irq(h->intr[h->intr_mode], intxhandler,
                        IRQF_DISABLED, h->devname, h))
                return 0;
        dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
-               h->intr[PERF_MODE_INT], h->devname);
+               h->intr[h->intr_mode], h->devname);
        return -1;
 }
 
@@ -4887,7 +4911,7 @@ static void cciss_undo_allocations_after_kdump_soft_reset(ctlr_info_t *h)
 {
        int ctlr = h->ctlr;
 
-       free_irq(h->intr[PERF_MODE_INT], h);
+       free_irq(h->intr[h->intr_mode], h);
 #ifdef CONFIG_PCI_MSI
        if (h->msix_vector)
                pci_disable_msix(h->pdev);
@@ -4953,6 +4977,7 @@ reinit_after_soft_reset:
        h = hba[i];
        h->pdev = pdev;
        h->busy_initializing = 1;
+       h->intr_mode = cciss_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
        INIT_LIST_HEAD(&h->cmpQ);
        INIT_LIST_HEAD(&h->reqQ);
        mutex_init(&h->busy_shutting_down);
@@ -5009,7 +5034,7 @@ reinit_after_soft_reset:
 
        dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
               h->devname, pdev->device, pci_name(pdev),
-              h->intr[PERF_MODE_INT], dac ? "" : " not");
+              h->intr[h->intr_mode], dac ? "" : " not");
 
        if (cciss_allocate_cmd_pool(h))
                goto clean4;
@@ -5056,7 +5081,7 @@ reinit_after_soft_reset:
                spin_lock_irqsave(&h->lock, flags);
                h->access.set_intr_mask(h, CCISS_INTR_OFF);
                spin_unlock_irqrestore(&h->lock, flags);
-               free_irq(h->intr[PERF_MODE_INT], h);
+               free_irq(h->intr[h->intr_mode], h);
                rc = cciss_request_irq(h, cciss_msix_discard_completions,
                                        cciss_intx_discard_completions);
                if (rc) {
@@ -5133,7 +5158,7 @@ clean4:
        cciss_free_cmd_pool(h);
        cciss_free_scatterlists(h);
        cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
-       free_irq(h->intr[PERF_MODE_INT], h);
+       free_irq(h->intr[h->intr_mode], h);
 clean2:
        unregister_blkdev(h->major, h->devname);
 clean1:
@@ -5172,9 +5197,31 @@ static void cciss_shutdown(struct pci_dev *pdev)
        if (return_code != IO_OK)
                dev_warn(&h->pdev->dev, "Error flushing cache\n");
        h->access.set_intr_mask(h, CCISS_INTR_OFF);
-       free_irq(h->intr[PERF_MODE_INT], h);
+       free_irq(h->intr[h->intr_mode], h);
+}
+
+static int __devinit cciss_enter_simple_mode(struct ctlr_info *h)
+{
+       u32 trans_support;
+
+       trans_support = readl(&(h->cfgtable->TransportSupport));
+       if (!(trans_support & SIMPLE_MODE))
+               return -ENOTSUPP;
+
+       h->max_commands = readl(&(h->cfgtable->CmdsOutMax));
+       writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest));
+       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+       cciss_wait_for_mode_change_ack(h);
+       print_cfg_table(h);
+       if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) {
+               dev_warn(&h->pdev->dev, "unable to get board into simple mode\n");
+               return -ENODEV;
+       }
+       h->transMethod = CFGTBL_Trans_Simple;
+       return 0;
 }
 
+
 static void __devexit cciss_remove_one(struct pci_dev *pdev)
 {
        ctlr_info_t *h;
index c049548e68b7ba39d27cf7b9c216868c8fc2b18e..7fda30e4a2416195696b6a4eebd560d74fca6917 100644 (file)
@@ -92,6 +92,7 @@ struct ctlr_info
        unsigned int intr[4];
        unsigned int msix_vector;
        unsigned int msi_vector;
+       int     intr_mode;
        int     cciss_max_sectors;
        BYTE    cciss_read;
        BYTE    cciss_write;
index 15f65b5f3fc7156c50300a6ab4d8efbe8a054e0e..0b3c5663a187d3473173ebb512b7dae7f6ba9cb1 100644 (file)
@@ -260,7 +260,7 @@ static struct rbd_client *rbd_client_create(struct ceph_options *opt,
        kref_init(&rbdc->kref);
        INIT_LIST_HEAD(&rbdc->node);
 
-       rbdc->client = ceph_create_client(opt, rbdc);
+       rbdc->client = ceph_create_client(opt, rbdc, 0, 0);
        if (IS_ERR(rbdc->client))
                goto out_rbdc;
        opt = NULL; /* Now rbdc->client is responsible for opt */
index 2330a9ad5e9568c2e4e1944e76eca10f7c5cdb53..8c42986a95256f7fcd878f316f41541ad6dbb5ff 100644 (file)
@@ -561,7 +561,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                break;
        case BLKIF_OP_FLUSH_DISKCACHE:
                blkif->st_f_req++;
-               operation = WRITE_FLUSH;
+               operation = WRITE_FLUSH_FUA;
                break;
        case BLKIF_OP_WRITE_BARRIER:
        default:
@@ -572,7 +572,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
        /* Check that the number of segments is sane. */
        nseg = req->nr_segments;
-       if (unlikely(nseg == 0 && operation != WRITE_FLUSH) ||
+       if (unlikely(nseg == 0 && operation != WRITE_FLUSH_FUA) ||
            unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
                pr_debug(DRV_PFX "Bad number of segments in request (%d)\n",
                         nseg);
@@ -656,7 +656,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
        /* This will be hit if the operation was a flush. */
        if (!bio) {
-               BUG_ON(operation != WRITE_FLUSH);
+               BUG_ON(operation != WRITE_FLUSH_FUA);
 
                bio = bio_alloc(GFP_KERNEL, 0);
                if (unlikely(bio == NULL))
@@ -685,7 +685,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
        if (operation == READ)
                blkif->st_rd_sect += preq.nr_sects;
-       else if (operation == WRITE || operation == WRITE_FLUSH)
+       else if (operation == WRITE || operation == WRITE_FLUSH_FUA)
                blkif->st_wr_sect += preq.nr_sects;
 
        return 0;
index 9e40b283a4685c38820c20e0d5bb26f1d6d74be5..00c57c90e2d6c189fc2c7aecb6e16a0e45e6c535 100644 (file)
@@ -46,7 +46,7 @@
 
 #define DRV_PFX "xen-blkback:"
 #define DPRINTK(fmt, args...)                          \
-       pr_debug(DRV_PFX "(%s:%d) " fmt ".\n",  \
+       pr_debug(DRV_PFX "(%s:%d) " fmt ".\n",          \
                 __func__, __LINE__, ##args)
 
 
index 3f129b45451a0c6af0a3f1ac0c25caf112491600..9fa9d07967165fb250bfbb50b3ecbfa6d8269905 100644 (file)
@@ -35,6 +35,7 @@ static void connect(struct backend_info *);
 static int connect_ring(struct backend_info *);
 static void backend_changed(struct xenbus_watch *, const char **,
                            unsigned int);
+static void xen_vbd_sync(struct xen_vbd *vbd);
 
 struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be)
 {
@@ -232,6 +233,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif)
                free_vm_area(blkif->blk_ring_area);
                blkif->blk_rings.common.sring = NULL;
        }
+       xen_vbd_sync(&blkif->vbd);
 }
 
 void xen_blkif_free(struct xen_blkif *blkif)
@@ -332,6 +334,12 @@ static void xen_vbd_free(struct xen_vbd *vbd)
        vbd->bdev = NULL;
 }
 
+static void xen_vbd_sync(struct xen_vbd *vbd)
+{
+       if (vbd->bdev)
+               fsync_bdev(vbd->bdev);
+}
+
 static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
                          unsigned major, unsigned minor, int readonly,
                          int cdrom)
@@ -590,7 +598,7 @@ static void frontend_changed(struct xenbus_device *dev,
 
                /*
                 * Enforce precondition before potential leak point.
-                * blkif_disconnect() is idempotent.
+                * xen_blkif_disconnect() is idempotent.
                 */
                xen_blkif_disconnect(be->blkif);
 
@@ -601,17 +609,17 @@ static void frontend_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateClosing:
-               xen_blkif_disconnect(be->blkif);
                xenbus_switch_state(dev, XenbusStateClosing);
                break;
 
        case XenbusStateClosed:
+               xen_blkif_disconnect(be->blkif);
                xenbus_switch_state(dev, XenbusStateClosed);
                if (xenbus_dev_is_online(dev))
                        break;
                /* fall through if not online */
        case XenbusStateUnknown:
-               /* implies blkif_disconnect() via blkback_remove() */
+               /* implies xen_blkif_disconnect() via xen_blkbk_remove() */
                device_unregister(&dev->dev);
                break;
 
index 9ea8c2576c70e768f22ad8ea2cc423337611fb4f..67d656b1adc6894e1f57b5706c7b79d1868a0f69 100644 (file)
@@ -1148,7 +1148,7 @@ static void blkfront_connect(struct blkfront_info *info)
                return;
        }
 
-       info->feature_flush = 0;
+       info->feature_flush = REQ_FLUSH | REQ_FUA;
        info->flush_op = 0;
 
        err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
@@ -1163,7 +1163,6 @@ static void blkfront_connect(struct blkfront_info *info)
         * If there are barriers, then we use flush.
         */
        if (!err && barrier) {
-               info->feature_flush = REQ_FLUSH | REQ_FUA;
                info->flush_op = BLKIF_OP_WRITE_BARRIER;
        }
        /*
@@ -1175,10 +1174,12 @@ static void blkfront_connect(struct blkfront_info *info)
                            NULL);
 
        if (!err && flush) {
-               info->feature_flush = REQ_FLUSH;
                info->flush_op = BLKIF_OP_FLUSH_DISKCACHE;
        }
-               
+
+       if (!flush && !barrier)
+               info->feature_flush = 0;
+
        err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
        if (err) {
                xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
index a5854735bb2e7882124ad1dc2c1b9c9296c93820..db7cb8111fbe58a89f21ee6ccea50467356bd38a 100644 (file)
@@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 with sflash firmware*/
        { USB_DEVICE(0x0CF3, 0x3002) },
        { USB_DEVICE(0x13d3, 0x3304) },
+       { USB_DEVICE(0x0930, 0x0215) },
 
        /* Atheros AR9285 Malbec with sflash firmware */
        { USB_DEVICE(0x03F0, 0x311D) },
index 548d1d9e4ddad7328c2ac9d68ec7d17de949d15a..57312d44db54f4b1b61a1e47b37f77c67d7961c2 100644 (file)
@@ -473,8 +473,6 @@ static int btmrvl_service_main_thread(void *data)
 
        init_waitqueue_entry(&wait, current);
 
-       current->flags |= PF_NOFREEZE;
-
        for (;;) {
                add_wait_queue(&thread->wait_q, &wait);
 
index 91d13a9e8c657f9b838c56ecbae6608965342bc0..656287c83eab8a3d2547e06f30a8e613cc761206 100644 (file)
@@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = {
        /* Atheros 3011 with sflash firmware */
        { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
        { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
+       { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
 
        /* Atheros AR9285 Malbec with sflash firmware */
        { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
@@ -256,7 +257,9 @@ static void btusb_intr_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               if (err != -EPERM)
+               /* -EPERM: urb is being killed;
+                * -ENODEV: device got disconnected */
+               if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
@@ -341,7 +344,9 @@ static void btusb_bulk_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               if (err != -EPERM)
+               /* -EPERM: urb is being killed;
+                * -ENODEV: device got disconnected */
+               if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
@@ -431,7 +436,9 @@ static void btusb_isoc_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               if (err != -EPERM)
+               /* -EPERM: urb is being killed;
+                * -ENODEV: device got disconnected */
+               if (err != -EPERM && err != -ENODEV)
                        BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
@@ -695,8 +702,7 @@ static int btusb_send_frame(struct sk_buff *skb)
                break;
 
        case HCI_ACLDATA_PKT:
-               if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 &&
-                                               hdev->conn_hash.le_num < 1))
+               if (!data->bulk_tx_ep)
                        return -ENODEV;
 
                urb = usb_alloc_urb(0, GFP_ATOMIC);
@@ -1103,7 +1109,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
                return 0;
 
        spin_lock_irq(&data->txlock);
-       if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
+       if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
                set_bit(BTUSB_SUSPENDING, &data->flags);
                spin_unlock_irq(&data->txlock);
        } else {
index 056b289a1e89e2452613bbf875e49b28f6db9d16..3695773ce7c3565791b7c64b30c2e2806e02c444 100644 (file)
@@ -336,7 +336,8 @@ hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
        off_t j, io_pg_start;
        int io_pg_count;
 
-       if (type != 0 || mem->type != 0) {
+       if (type != mem->type ||
+               agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
                return -EINVAL;
        }
 
@@ -380,7 +381,8 @@ hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
        struct _hp_private *hp = &hp_private;
        int i, io_pg_start, io_pg_count;
 
-       if (type != 0 || mem->type != 0) {
+       if (type != mem->type ||
+               agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
                return -EINVAL;
        }
 
index a7346ab97a3c22002ffc6948321ca24b1720b8f9..2a2b8fd708c11a6d1772fd2e5b4b11502c6fdf1c 100644 (file)
@@ -300,17 +300,13 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg)
                        /*
                         * Wait for the suspend/resume to complete.  If there
                         * are pending acknowledges, we wait here for them.
+                        * wait_event_freezable() is interruptible and pending
+                        * signal can cause busy looping.  We aren't doing
+                        * anything critical, chill a bit on each iteration.
                         */
-                       freezer_do_not_count();
-
-                       wait_event(apm_suspend_waitqueue,
-                                  as->suspend_state == SUSPEND_DONE);
-
-                       /*
-                        * Since we are waiting until the suspend is done, the
-                        * try_to_freeze() in freezer_count() will not trigger
-                        */
-                       freezer_count();
+                       while (wait_event_freezable(apm_suspend_waitqueue,
+                                       as->suspend_state == SUSPEND_DONE))
+                               msleep(10);
                        break;
                case SUSPEND_ACKTO:
                        as->suspend_result = -ETIMEDOUT;
index c35a785005b08e132f23447ac31365853b5acd9c..f7c93d7be00f307db47a6657bcf8aa5d29bdb3c6 100644 (file)
@@ -932,7 +932,21 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
  */
 void get_random_bytes(void *buf, int nbytes)
 {
-       extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
+       char *p = buf;
+
+       while (nbytes) {
+               unsigned long v;
+               int chunk = min(nbytes, (int)sizeof(unsigned long));
+               
+               if (!arch_get_random_long(&v))
+                       break;
+               
+               memcpy(buf, &v, chunk);
+               p += chunk;
+               nbytes -= chunk;
+       }
+
+       extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
 }
 EXPORT_SYMBOL(get_random_bytes);
 
@@ -1318,8 +1332,13 @@ late_initcall(random_int_secret_init);
 DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
 unsigned int get_random_int(void)
 {
-       __u32 *hash = get_cpu_var(get_random_int_hash);
        unsigned int ret;
+       __u32 *hash;
+
+       if (arch_get_random_int(&ret))
+               return ret;
+
+       hash = get_cpu_var(get_random_int_hash);
 
        hash[0] += current->pid + jiffies + get_cycles();
        md5_transform(hash, random_int_secret);
index caf8012ef47ce1c69af6f07df4f62e7c5676a581..e53af7638186840d449a65de533667dbb164316c 100644 (file)
@@ -963,6 +963,9 @@ ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr,
 {
        struct tpm_chip *chip = dev_get_drvdata(dev);
 
+       if (chip->vendor.duration[TPM_LONG] == 0)
+               return 0;
+
        return sprintf(buf, "%d %d %d [%s]\n",
                       jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
                       jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
index fb68b1295373e7287aa92a577b6aa937ba7ffe09..ed99f3bf341addc4221971f445c7921e41a7a8bf 100644 (file)
@@ -1675,13 +1675,11 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
 
        multiport = false;
        portdev->config.max_nr_ports = 1;
-       if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
+       if (virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT,
+                             offsetof(struct virtio_console_config,
+                                      max_nr_ports),
+                             &portdev->config.max_nr_ports) == 0)
                multiport = true;
-               vdev->config->get(vdev, offsetof(struct virtio_console_config,
-                                                max_nr_ports),
-                                 &portdev->config.max_nr_ports,
-                                 sizeof(portdev->config.max_nr_ports));
-       }
 
        err = init_vqs(portdev);
        if (err < 0) {
index dc7c033ef587142ce080e33a2b2711a94ece1d89..32a77becc098534c2b0b77a585d48f4974538c65 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
@@ -150,13 +151,13 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
 
 static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
 {
-       int ret;
+       int k, ret;
 
        /* enable clock */
        ret = clk_enable(p->clk);
        if (ret) {
                dev_err(&p->pdev->dev, "cannot enable clock\n");
-               return ret;
+               goto err0;
        }
 
        /* make sure channel is disabled */
@@ -174,9 +175,38 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
        sh_cmt_write(p, CMCOR, 0xffffffff);
        sh_cmt_write(p, CMCNT, 0);
 
+       /*
+        * According to the sh73a0 user's manual, as CMCNT can be operated
+        * only by the RCLK (Pseudo 32 KHz), there's one restriction on
+        * modifying CMCNT register; two RCLK cycles are necessary before
+        * this register is either read or any modification of the value
+        * it holds is reflected in the LSI's actual operation.
+        *
+        * While at it, we're supposed to clear out the CMCNT as of this
+        * moment, so make sure it's processed properly here.  This will
+        * take RCLKx2 at maximum.
+        */
+       for (k = 0; k < 100; k++) {
+               if (!sh_cmt_read(p, CMCNT))
+                       break;
+               udelay(1);
+       }
+
+       if (sh_cmt_read(p, CMCNT)) {
+               dev_err(&p->pdev->dev, "cannot clear CMCNT\n");
+               ret = -ETIMEDOUT;
+               goto err1;
+       }
+
        /* enable channel */
        sh_cmt_start_stop_ch(p, 1);
        return 0;
+ err1:
+       /* stop clock */
+       clk_disable(p->clk);
+
+ err0:
+       return ret;
 }
 
 static void sh_cmt_disable(struct sh_cmt_priv *p)
index 891360edecdd218fcd200e5c1e47f28f3ff07d52..629b3ec698e2d4ac0f88f88e26f9e95e91e96150 100644 (file)
@@ -725,7 +725,7 @@ static int __init cpufreq_gov_dbs_init(void)
                dbs_tuners_ins.down_differential =
                                        MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
                /*
-                * In no_hz/micro accounting case we set the minimum frequency
+                * In nohz/micro accounting case we set the minimum frequency
                 * not depending on HZ, but fixed (very low). The deferred
                 * timer might skip some samples if idle/sleeping as needed.
                */
index 35a257dd4bb76f848762bccf5fe9e10db3248a77..4bd6815d317bb86631dc3713a7e2e3eebc7332ac 100644 (file)
 #include <asm/msr.h>
 #include <asm/tsc.h>
 
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+#endif
+
 #define EPS_BRAND_C7M  0
 #define EPS_BRAND_C7   1
 #define EPS_BRAND_EDEN 2
 
 struct eps_cpu_data {
        u32 fsb;
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+       u32 bios_limit;
+#endif
        struct cpufreq_frequency_table freq_table[];
 };
 
 static struct eps_cpu_data *eps_cpu[NR_CPUS];
 
+/* Module parameters */
+static int freq_failsafe_off;
+static int voltage_failsafe_off;
+static int set_max_voltage;
+
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+static int ignore_acpi_limit;
+
+static struct acpi_processor_performance *eps_acpi_cpu_perf;
+
+/* Minimum necessary to get acpi_processor_get_bios_limit() working */
+static int eps_acpi_init(void)
+{
+       eps_acpi_cpu_perf = kzalloc(sizeof(struct acpi_processor_performance),
+                                     GFP_KERNEL);
+       if (!eps_acpi_cpu_perf)
+               return -ENOMEM;
+
+       if (!zalloc_cpumask_var(&eps_acpi_cpu_perf->shared_cpu_map,
+                                                               GFP_KERNEL)) {
+               kfree(eps_acpi_cpu_perf);
+               eps_acpi_cpu_perf = NULL;
+               return -ENOMEM;
+       }
+
+       if (acpi_processor_register_performance(eps_acpi_cpu_perf, 0)) {
+               free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map);
+               kfree(eps_acpi_cpu_perf);
+               eps_acpi_cpu_perf = NULL;
+               return -EIO;
+       }
+       return 0;
+}
+
+static int eps_acpi_exit(struct cpufreq_policy *policy)
+{
+       if (eps_acpi_cpu_perf) {
+               acpi_processor_unregister_performance(eps_acpi_cpu_perf, 0);
+               free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map);
+               kfree(eps_acpi_cpu_perf);
+               eps_acpi_cpu_perf = NULL;
+       }
+       return 0;
+}
+#endif
 
 static unsigned int eps_get(unsigned int cpu)
 {
@@ -164,6 +217,9 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
        int k, step, voltage;
        int ret;
        int states;
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+       unsigned int limit;
+#endif
 
        if (policy->cpu != 0)
                return -ENODEV;
@@ -244,11 +300,62 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
                return -EINVAL;
        if (current_voltage > 0x1f || max_voltage > 0x1f)
                return -EINVAL;
-       if (max_voltage < min_voltage)
+       if (max_voltage < min_voltage
+           || current_voltage < min_voltage
+           || current_voltage > max_voltage)
                return -EINVAL;
 
+       /* Check for systems using underclocked CPU */
+       if (!freq_failsafe_off && max_multiplier != current_multiplier) {
+               printk(KERN_INFO "eps: Your processor is running at different "
+                       "frequency then its maximum. Aborting.\n");
+               printk(KERN_INFO "eps: You can use freq_failsafe_off option "
+                       "to disable this check.\n");
+               return -EINVAL;
+       }
+       if (!voltage_failsafe_off && max_voltage != current_voltage) {
+               printk(KERN_INFO "eps: Your processor is running at different "
+                       "voltage then its maximum. Aborting.\n");
+               printk(KERN_INFO "eps: You can use voltage_failsafe_off "
+                       "option to disable this check.\n");
+               return -EINVAL;
+       }
+
        /* Calc FSB speed */
        fsb = cpu_khz / current_multiplier;
+
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+       /* Check for ACPI processor speed limit */
+       if (!ignore_acpi_limit && !eps_acpi_init()) {
+               if (!acpi_processor_get_bios_limit(policy->cpu, &limit)) {
+                       printk(KERN_INFO "eps: ACPI limit %u.%uGHz\n",
+                               limit/1000000,
+                               (limit%1000000)/10000);
+                       eps_acpi_exit(policy);
+                       /* Check if max_multiplier is in BIOS limits */
+                       if (limit && max_multiplier * fsb > limit) {
+                               printk(KERN_INFO "eps: Aborting.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+#endif
+
+       /* Allow user to set lower maximum voltage then that reported
+        * by processor */
+       if (brand == EPS_BRAND_C7M && set_max_voltage) {
+               u32 v;
+
+               /* Change mV to something hardware can use */
+               v = (set_max_voltage - 700) / 16;
+               /* Check if voltage is within limits */
+               if (v >= min_voltage && v <= max_voltage) {
+                       printk(KERN_INFO "eps: Setting %dmV as maximum.\n",
+                               v * 16 + 700);
+                       max_voltage = v;
+               }
+       }
+
        /* Calc number of p-states supported */
        if (brand == EPS_BRAND_C7M)
                states = max_multiplier - min_multiplier + 1;
@@ -265,6 +372,9 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
 
        /* Copy basic values */
        centaur->fsb = fsb;
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+       centaur->bios_limit = limit;
+#endif
 
        /* Fill frequency and MSR value table */
        f_table = &centaur->freq_table[0];
@@ -303,17 +413,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
 static int eps_cpu_exit(struct cpufreq_policy *policy)
 {
        unsigned int cpu = policy->cpu;
-       struct eps_cpu_data *centaur;
-       u32 lo, hi;
 
-       if (eps_cpu[cpu] == NULL)
-               return -ENODEV;
-       centaur = eps_cpu[cpu];
-
-       /* Get max frequency */
-       rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-       /* Set max frequency */
-       eps_set_state(centaur, cpu, hi & 0xffff);
        /* Bye */
        cpufreq_frequency_table_put_attr(policy->cpu);
        kfree(eps_cpu[cpu]);
@@ -359,6 +459,19 @@ static void __exit eps_exit(void)
        cpufreq_unregister_driver(&eps_driver);
 }
 
+/* Allow user to overclock his machine or to change frequency to higher after
+ * unloading module */
+module_param(freq_failsafe_off, int, 0644);
+MODULE_PARM_DESC(freq_failsafe_off, "Disable current vs max frequency check");
+module_param(voltage_failsafe_off, int, 0644);
+MODULE_PARM_DESC(voltage_failsafe_off, "Disable current vs max voltage check");
+#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
+module_param(ignore_acpi_limit, int, 0644);
+MODULE_PARM_DESC(ignore_acpi_limit, "Don't check ACPI's processor speed limit");
+#endif
+module_param(set_max_voltage, int, 0644);
+MODULE_PARM_DESC(set_max_voltage, "Set maximum CPU voltage (mV) C7-M only");
+
 MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
 MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
 MODULE_LICENSE("GPL");
index b7c3a84c4cfa86cf6fe5b4fa14f2acf319d1b380..6f887573ce940e36d626c2d5917ca31073aeadfe 100644 (file)
@@ -464,6 +464,8 @@ static int exynos4_cpufreq_resume(struct cpufreq_policy *policy)
 
 static int exynos4_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
+       int ret;
+
        policy->cur = policy->min = policy->max = exynos4_getspeed(policy->cpu);
 
        cpufreq_frequency_table_get_attr(exynos4_freq_table, policy->cpu);
@@ -479,16 +481,35 @@ static int exynos4_cpufreq_cpu_init(struct cpufreq_policy *policy)
         */
        cpumask_setall(policy->cpus);
 
-       return cpufreq_frequency_table_cpuinfo(policy, exynos4_freq_table);
+       ret = cpufreq_frequency_table_cpuinfo(policy, exynos4_freq_table);
+       if (ret)
+               return ret;
+
+       cpufreq_frequency_table_get_attr(exynos4_freq_table, policy->cpu);
+
+       return 0;
 }
 
+static int exynos4_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+       cpufreq_frequency_table_put_attr(policy->cpu);
+       return 0;
+}
+
+static struct freq_attr *exynos4_cpufreq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       NULL,
+};
+
 static struct cpufreq_driver exynos4_driver = {
        .flags          = CPUFREQ_STICKY,
        .verify         = exynos4_verify_speed,
        .target         = exynos4_target,
        .get            = exynos4_getspeed,
        .init           = exynos4_cpufreq_cpu_init,
+       .exit           = exynos4_cpufreq_cpu_exit,
        .name           = "exynos4_cpufreq",
+       .attr           = exynos4_cpufreq_attr,
 #ifdef CONFIG_PM
        .suspend        = exynos4_cpufreq_suspend,
        .resume         = exynos4_cpufreq_resume,
index d4c542372886b9cc92ae732590d2404196fb6eab..0df0141100978d583c3a2bbeac17c4625429ab8a 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/cpu.h>
 #include <linux/cpuidle.h>
 #include <linux/ktime.h>
index 12c98900dcf834645f47858f1687a46dbc5857cc..f62fde21e9626edc19e2374a1fb8850b922e9410 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/moduleparam.h>
 #include <linux/jiffies.h>
 
index c47f3d09c1eeb6184420632a78e892f125c36bf8..3600f1955e4806dee41e61bef256697c6052832b 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/time.h>
 #include <linux/ktime.h>
 #include <linux/hrtimer.h>
index d0183ddb3076d1dec3b668e355e2967eb5046bc7..8944dabc0e3c79cae9e960a89cbb7b937072912a 100644 (file)
@@ -1006,9 +1006,9 @@ static int n2_do_ecb(struct ablkcipher_request *req, bool encrypt)
 
        spin_unlock_irqrestore(&qp->lock, flags);
 
+out:
        put_cpu();
 
-out:
        n2_chunk_complete(req, NULL);
        return err;
 }
@@ -1096,9 +1096,9 @@ static int n2_do_chaining(struct ablkcipher_request *req, bool encrypt)
 
        spin_unlock_irqrestore(&qp->lock, flags);
 
+out:
        put_cpu();
 
-out:
        n2_chunk_complete(req, err ? NULL : final_iv_addr);
        return err;
 }
index db33d300aa232a4dec0c4234b2ab768a5dfc7023..29b9469f83789eb42ee8c5d47ca7901d85fb70af 100644 (file)
@@ -508,10 +508,8 @@ static int __init padlock_init(void)
        int ret;
        struct cpuinfo_x86 *c = &cpu_data(0);
 
-       if (!cpu_has_xcrypt) {
-               printk(KERN_NOTICE PFX "VIA PadLock not detected.\n");
+       if (!cpu_has_xcrypt)
                return -ENODEV;
-       }
 
        if (!cpu_has_xcrypt_enabled) {
                printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
index 230b5b8cda1f9b2ff82bbd410a5f27eb026b805f..a2b553eabbdb6db38839ba1f14cc26a61edb31d2 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/rtnetlink.h>
@@ -1241,8 +1242,8 @@ static void spacc_spacc_complete(unsigned long data)
        spin_unlock_irqrestore(&engine->hw_lock, flags);
 
        list_for_each_entry_safe(req, tmp, &completed, list) {
-               req->complete(req);
                list_del(&req->list);
+               req->complete(req);
        }
 }
 
@@ -1657,10 +1658,33 @@ static struct spacc_alg l2_engine_algs[] = {
        },
 };
 
-static int __devinit spacc_probe(struct platform_device *pdev,
-                                unsigned max_ctxs, size_t cipher_pg_sz,
-                                size_t hash_pg_sz, size_t fifo_sz,
-                                struct spacc_alg *algs, size_t num_algs)
+#ifdef CONFIG_OF
+static const struct of_device_id spacc_of_id_table[] = {
+       { .compatible = "picochip,spacc-ipsec" },
+       { .compatible = "picochip,spacc-l2" },
+       {}
+};
+#else /* CONFIG_OF */
+#define spacc_of_id_table NULL
+#endif /* CONFIG_OF */
+
+static bool spacc_is_compatible(struct platform_device *pdev,
+                               const char *spacc_type)
+{
+       const struct platform_device_id *platid = platform_get_device_id(pdev);
+
+       if (platid && !strcmp(platid->name, spacc_type))
+               return true;
+
+#ifdef CONFIG_OF
+       if (of_device_is_compatible(pdev->dev.of_node, spacc_type))
+               return true;
+#endif /* CONFIG_OF */
+
+       return false;
+}
+
+static int __devinit spacc_probe(struct platform_device *pdev)
 {
        int i, err, ret = -EINVAL;
        struct resource *mem, *irq;
@@ -1669,13 +1693,25 @@ static int __devinit spacc_probe(struct platform_device *pdev,
        if (!engine)
                return -ENOMEM;
 
-       engine->max_ctxs        = max_ctxs;
-       engine->cipher_pg_sz    = cipher_pg_sz;
-       engine->hash_pg_sz      = hash_pg_sz;
-       engine->fifo_sz         = fifo_sz;
-       engine->algs            = algs;
-       engine->num_algs        = num_algs;
-       engine->name            = dev_name(&pdev->dev);
+       if (spacc_is_compatible(pdev, "picochip,spacc-ipsec")) {
+               engine->max_ctxs        = SPACC_CRYPTO_IPSEC_MAX_CTXS;
+               engine->cipher_pg_sz    = SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ;
+               engine->hash_pg_sz      = SPACC_CRYPTO_IPSEC_HASH_PG_SZ;
+               engine->fifo_sz         = SPACC_CRYPTO_IPSEC_FIFO_SZ;
+               engine->algs            = ipsec_engine_algs;
+               engine->num_algs        = ARRAY_SIZE(ipsec_engine_algs);
+       } else if (spacc_is_compatible(pdev, "picochip,spacc-l2")) {
+               engine->max_ctxs        = SPACC_CRYPTO_L2_MAX_CTXS;
+               engine->cipher_pg_sz    = SPACC_CRYPTO_L2_CIPHER_PG_SZ;
+               engine->hash_pg_sz      = SPACC_CRYPTO_L2_HASH_PG_SZ;
+               engine->fifo_sz         = SPACC_CRYPTO_L2_FIFO_SZ;
+               engine->algs            = l2_engine_algs;
+               engine->num_algs        = ARRAY_SIZE(l2_engine_algs);
+       } else {
+               return -EINVAL;
+       }
+
+       engine->name = dev_name(&pdev->dev);
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -1711,7 +1747,7 @@ static int __devinit spacc_probe(struct platform_device *pdev,
 
        spin_lock_init(&engine->hw_lock);
 
-       engine->clk = clk_get(&pdev->dev, NULL);
+       engine->clk = clk_get(&pdev->dev, "ref");
        if (IS_ERR(engine->clk)) {
                dev_info(&pdev->dev, "clk unavailable\n");
                device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh);
@@ -1800,72 +1836,33 @@ static int __devexit spacc_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int __devinit ipsec_probe(struct platform_device *pdev)
-{
-       return spacc_probe(pdev, SPACC_CRYPTO_IPSEC_MAX_CTXS,
-                          SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ,
-                          SPACC_CRYPTO_IPSEC_HASH_PG_SZ,
-                          SPACC_CRYPTO_IPSEC_FIFO_SZ, ipsec_engine_algs,
-                          ARRAY_SIZE(ipsec_engine_algs));
-}
-
-static struct platform_driver ipsec_driver = {
-       .probe          = ipsec_probe,
-       .remove         = __devexit_p(spacc_remove),
-       .driver         = {
-               .name   = "picoxcell-ipsec",
-#ifdef CONFIG_PM
-               .pm     = &spacc_pm_ops,
-#endif /* CONFIG_PM */
-       },
+static const struct platform_device_id spacc_id_table[] = {
+       { "picochip,spacc-ipsec", },
+       { "picochip,spacc-l2", },
 };
 
-static int __devinit l2_probe(struct platform_device *pdev)
-{
-       return spacc_probe(pdev, SPACC_CRYPTO_L2_MAX_CTXS,
-                          SPACC_CRYPTO_L2_CIPHER_PG_SZ,
-                          SPACC_CRYPTO_L2_HASH_PG_SZ, SPACC_CRYPTO_L2_FIFO_SZ,
-                          l2_engine_algs, ARRAY_SIZE(l2_engine_algs));
-}
-
-static struct platform_driver l2_driver = {
-       .probe          = l2_probe,
+static struct platform_driver spacc_driver = {
+       .probe          = spacc_probe,
        .remove         = __devexit_p(spacc_remove),
        .driver         = {
-               .name   = "picoxcell-l2",
+               .name   = "picochip,spacc",
 #ifdef CONFIG_PM
                .pm     = &spacc_pm_ops,
 #endif /* CONFIG_PM */
+               .of_match_table = spacc_of_id_table,
        },
+       .id_table       = spacc_id_table,
 };
 
 static int __init spacc_init(void)
 {
-       int ret = platform_driver_register(&ipsec_driver);
-       if (ret) {
-               pr_err("failed to register ipsec spacc driver");
-               goto out;
-       }
-
-       ret = platform_driver_register(&l2_driver);
-       if (ret) {
-               pr_err("failed to register l2 spacc driver");
-               goto l2_failed;
-       }
-
-       return 0;
-
-l2_failed:
-       platform_driver_unregister(&ipsec_driver);
-out:
-       return ret;
+       return platform_driver_register(&spacc_driver);
 }
 module_init(spacc_init);
 
 static void __exit spacc_exit(void)
 {
-       platform_driver_unregister(&ipsec_driver);
-       platform_driver_unregister(&l2_driver);
+       platform_driver_unregister(&spacc_driver);
 }
 module_exit(spacc_exit);
 
index 6a483eac7b3f2d971cabae0aceaf022a42866558..3b99dc62874b5640be9383a70657d593f9cc31e7 100644 (file)
@@ -107,10 +107,11 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
 {
        struct at_desc *desc, *_desc;
        struct at_desc *ret = NULL;
+       unsigned long flags;
        unsigned int i = 0;
        LIST_HEAD(tmp_list);
 
-       spin_lock_bh(&atchan->lock);
+       spin_lock_irqsave(&atchan->lock, flags);
        list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
                i++;
                if (async_tx_test_ack(&desc->txd)) {
@@ -121,7 +122,7 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
                dev_dbg(chan2dev(&atchan->chan_common),
                                "desc %p not ACKed\n", desc);
        }
-       spin_unlock_bh(&atchan->lock);
+       spin_unlock_irqrestore(&atchan->lock, flags);
        dev_vdbg(chan2dev(&atchan->chan_common),
                "scanned %u descriptors on freelist\n", i);
 
@@ -129,9 +130,9 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan)
        if (!ret) {
                ret = atc_alloc_descriptor(&atchan->chan_common, GFP_ATOMIC);
                if (ret) {
-                       spin_lock_bh(&atchan->lock);
+                       spin_lock_irqsave(&atchan->lock, flags);
                        atchan->descs_allocated++;
-                       spin_unlock_bh(&atchan->lock);
+                       spin_unlock_irqrestore(&atchan->lock, flags);
                } else {
                        dev_err(chan2dev(&atchan->chan_common),
                                        "not enough descriptors available\n");
@@ -150,8 +151,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
 {
        if (desc) {
                struct at_desc *child;
+               unsigned long flags;
 
-               spin_lock_bh(&atchan->lock);
+               spin_lock_irqsave(&atchan->lock, flags);
                list_for_each_entry(child, &desc->tx_list, desc_node)
                        dev_vdbg(chan2dev(&atchan->chan_common),
                                        "moving child desc %p to freelist\n",
@@ -160,7 +162,7 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
                dev_vdbg(chan2dev(&atchan->chan_common),
                         "moving desc %p to freelist\n", desc);
                list_add(&desc->desc_node, &atchan->free_list);
-               spin_unlock_bh(&atchan->lock);
+               spin_unlock_irqrestore(&atchan->lock, flags);
        }
 }
 
@@ -299,7 +301,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 
        /* for cyclic transfers,
         * no need to replay callback function while stopping */
-       if (!test_bit(ATC_IS_CYCLIC, &atchan->status)) {
+       if (!atc_chan_is_cyclic(atchan)) {
                dma_async_tx_callback   callback = txd->callback;
                void                    *param = txd->callback_param;
 
@@ -471,16 +473,17 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)
 static void atc_tasklet(unsigned long data)
 {
        struct at_dma_chan *atchan = (struct at_dma_chan *)data;
+       unsigned long flags;
 
-       spin_lock(&atchan->lock);
+       spin_lock_irqsave(&atchan->lock, flags);
        if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status))
                atc_handle_error(atchan);
-       else if (test_bit(ATC_IS_CYCLIC, &atchan->status))
+       else if (atc_chan_is_cyclic(atchan))
                atc_handle_cyclic(atchan);
        else
                atc_advance_work(atchan);
 
-       spin_unlock(&atchan->lock);
+       spin_unlock_irqrestore(&atchan->lock, flags);
 }
 
 static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
@@ -539,8 +542,9 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
        struct at_desc          *desc = txd_to_at_desc(tx);
        struct at_dma_chan      *atchan = to_at_dma_chan(tx->chan);
        dma_cookie_t            cookie;
+       unsigned long           flags;
 
-       spin_lock_bh(&atchan->lock);
+       spin_lock_irqsave(&atchan->lock, flags);
        cookie = atc_assign_cookie(atchan, desc);
 
        if (list_empty(&atchan->active_list)) {
@@ -554,7 +558,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
                list_add_tail(&desc->desc_node, &atchan->queue);
        }
 
-       spin_unlock_bh(&atchan->lock);
+       spin_unlock_irqrestore(&atchan->lock, flags);
 
        return cookie;
 }
@@ -927,28 +931,29 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
        struct at_dma_chan      *atchan = to_at_dma_chan(chan);
        struct at_dma           *atdma = to_at_dma(chan->device);
        int                     chan_id = atchan->chan_common.chan_id;
+       unsigned long           flags;
 
        LIST_HEAD(list);
 
        dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd);
 
        if (cmd == DMA_PAUSE) {
-               spin_lock_bh(&atchan->lock);
+               spin_lock_irqsave(&atchan->lock, flags);
 
                dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
                set_bit(ATC_IS_PAUSED, &atchan->status);
 
-               spin_unlock_bh(&atchan->lock);
+               spin_unlock_irqrestore(&atchan->lock, flags);
        } else if (cmd == DMA_RESUME) {
-               if (!test_bit(ATC_IS_PAUSED, &atchan->status))
+               if (!atc_chan_is_paused(atchan))
                        return 0;
 
-               spin_lock_bh(&atchan->lock);
+               spin_lock_irqsave(&atchan->lock, flags);
 
                dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
                clear_bit(ATC_IS_PAUSED, &atchan->status);
 
-               spin_unlock_bh(&atchan->lock);
+               spin_unlock_irqrestore(&atchan->lock, flags);
        } else if (cmd == DMA_TERMINATE_ALL) {
                struct at_desc  *desc, *_desc;
                /*
@@ -957,7 +962,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
                 * channel. We still have to poll the channel enable bit due
                 * to AHB/HSB limitations.
                 */
-               spin_lock_bh(&atchan->lock);
+               spin_lock_irqsave(&atchan->lock, flags);
 
                /* disabling channel: must also remove suspend state */
                dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
@@ -978,7 +983,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
                /* if channel dedicated to cyclic operations, free it */
                clear_bit(ATC_IS_CYCLIC, &atchan->status);
 
-               spin_unlock_bh(&atchan->lock);
+               spin_unlock_irqrestore(&atchan->lock, flags);
        } else {
                return -ENXIO;
        }
@@ -1004,9 +1009,10 @@ atc_tx_status(struct dma_chan *chan,
        struct at_dma_chan      *atchan = to_at_dma_chan(chan);
        dma_cookie_t            last_used;
        dma_cookie_t            last_complete;
+       unsigned long           flags;
        enum dma_status         ret;
 
-       spin_lock_bh(&atchan->lock);
+       spin_lock_irqsave(&atchan->lock, flags);
 
        last_complete = atchan->completed_cookie;
        last_used = chan->cookie;
@@ -1021,7 +1027,7 @@ atc_tx_status(struct dma_chan *chan,
                ret = dma_async_is_complete(cookie, last_complete, last_used);
        }
 
-       spin_unlock_bh(&atchan->lock);
+       spin_unlock_irqrestore(&atchan->lock, flags);
 
        if (ret != DMA_SUCCESS)
                dma_set_tx_state(txstate, last_complete, last_used,
@@ -1029,7 +1035,7 @@ atc_tx_status(struct dma_chan *chan,
        else
                dma_set_tx_state(txstate, last_complete, last_used, 0);
 
-       if (test_bit(ATC_IS_PAUSED, &atchan->status))
+       if (atc_chan_is_paused(atchan))
                ret = DMA_PAUSED;
 
        dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n",
@@ -1046,18 +1052,19 @@ atc_tx_status(struct dma_chan *chan,
 static void atc_issue_pending(struct dma_chan *chan)
 {
        struct at_dma_chan      *atchan = to_at_dma_chan(chan);
+       unsigned long           flags;
 
        dev_vdbg(chan2dev(chan), "issue_pending\n");
 
        /* Not needed for cyclic transfers */
-       if (test_bit(ATC_IS_CYCLIC, &atchan->status))
+       if (atc_chan_is_cyclic(atchan))
                return;
 
-       spin_lock_bh(&atchan->lock);
+       spin_lock_irqsave(&atchan->lock, flags);
        if (!atc_chan_is_enabled(atchan)) {
                atc_advance_work(atchan);
        }
-       spin_unlock_bh(&atchan->lock);
+       spin_unlock_irqrestore(&atchan->lock, flags);
 }
 
 /**
@@ -1073,6 +1080,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
        struct at_dma           *atdma = to_at_dma(chan->device);
        struct at_desc          *desc;
        struct at_dma_slave     *atslave;
+       unsigned long           flags;
        int                     i;
        u32                     cfg;
        LIST_HEAD(tmp_list);
@@ -1116,11 +1124,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
                list_add_tail(&desc->desc_node, &tmp_list);
        }
 
-       spin_lock_bh(&atchan->lock);
+       spin_lock_irqsave(&atchan->lock, flags);
        atchan->descs_allocated = i;
        list_splice(&tmp_list, &atchan->free_list);
        atchan->completed_cookie = chan->cookie = 1;
-       spin_unlock_bh(&atchan->lock);
+       spin_unlock_irqrestore(&atchan->lock, flags);
 
        /* channel parameters */
        channel_writel(atchan, CFG, cfg);
@@ -1293,15 +1301,13 @@ static int __init at_dma_probe(struct platform_device *pdev)
        if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
                atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
 
-       if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask))
+       if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
                atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
-
-       if (dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
+               /* controller can do slave DMA: can trigger cyclic transfers */
+               dma_cap_set(DMA_CYCLIC, atdma->dma_common.cap_mask);
                atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic;
-
-       if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ||
-           dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
                atdma->dma_common.device_control = atc_control;
+       }
 
        dma_writel(atdma, EN, AT_DMA_ENABLE);
 
@@ -1377,27 +1383,112 @@ static void at_dma_shutdown(struct platform_device *pdev)
        clk_disable(atdma->clk);
 }
 
+static int at_dma_prepare(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct at_dma *atdma = platform_get_drvdata(pdev);
+       struct dma_chan *chan, *_chan;
+
+       list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
+                       device_node) {
+               struct at_dma_chan *atchan = to_at_dma_chan(chan);
+               /* wait for transaction completion (except in cyclic case) */
+               if (atc_chan_is_enabled(atchan) && !atc_chan_is_cyclic(atchan))
+                       return -EAGAIN;
+       }
+       return 0;
+}
+
+static void atc_suspend_cyclic(struct at_dma_chan *atchan)
+{
+       struct dma_chan *chan = &atchan->chan_common;
+
+       /* Channel should be paused by user
+        * do it anyway even if it is not done already */
+       if (!atc_chan_is_paused(atchan)) {
+               dev_warn(chan2dev(chan),
+               "cyclic channel not paused, should be done by channel user\n");
+               atc_control(chan, DMA_PAUSE, 0);
+       }
+
+       /* now preserve additional data for cyclic operations */
+       /* next descriptor address in the cyclic list */
+       atchan->save_dscr = channel_readl(atchan, DSCR);
+
+       vdbg_dump_regs(atchan);
+}
+
 static int at_dma_suspend_noirq(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct at_dma *atdma = platform_get_drvdata(pdev);
+       struct dma_chan *chan, *_chan;
 
-       at_dma_off(platform_get_drvdata(pdev));
+       /* preserve data */
+       list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
+                       device_node) {
+               struct at_dma_chan *atchan = to_at_dma_chan(chan);
+
+               if (atc_chan_is_cyclic(atchan))
+                       atc_suspend_cyclic(atchan);
+               atchan->save_cfg = channel_readl(atchan, CFG);
+       }
+       atdma->save_imr = dma_readl(atdma, EBCIMR);
+
+       /* disable DMA controller */
+       at_dma_off(atdma);
        clk_disable(atdma->clk);
        return 0;
 }
 
+static void atc_resume_cyclic(struct at_dma_chan *atchan)
+{
+       struct at_dma   *atdma = to_at_dma(atchan->chan_common.device);
+
+       /* restore channel status for cyclic descriptors list:
+        * next descriptor in the cyclic list at the time of suspend */
+       channel_writel(atchan, SADDR, 0);
+       channel_writel(atchan, DADDR, 0);
+       channel_writel(atchan, CTRLA, 0);
+       channel_writel(atchan, CTRLB, 0);
+       channel_writel(atchan, DSCR, atchan->save_dscr);
+       dma_writel(atdma, CHER, atchan->mask);
+
+       /* channel pause status should be removed by channel user
+        * We cannot take the initiative to do it here */
+
+       vdbg_dump_regs(atchan);
+}
+
 static int at_dma_resume_noirq(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct at_dma *atdma = platform_get_drvdata(pdev);
+       struct dma_chan *chan, *_chan;
 
+       /* bring back DMA controller */
        clk_enable(atdma->clk);
        dma_writel(atdma, EN, AT_DMA_ENABLE);
+
+       /* clear any pending interrupt */
+       while (dma_readl(atdma, EBCISR))
+               cpu_relax();
+
+       /* restore saved data */
+       dma_writel(atdma, EBCIER, atdma->save_imr);
+       list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
+                       device_node) {
+               struct at_dma_chan *atchan = to_at_dma_chan(chan);
+
+               channel_writel(atchan, CFG, atchan->save_cfg);
+               if (atc_chan_is_cyclic(atchan))
+                       atc_resume_cyclic(atchan);
+       }
        return 0;
 }
 
 static const struct dev_pm_ops at_dma_dev_pm_ops = {
+       .prepare = at_dma_prepare,
        .suspend_noirq = at_dma_suspend_noirq,
        .resume_noirq = at_dma_resume_noirq,
 };
index 087dbf1dd39cc0d87416e24e093ca7841a714b3f..aa4c9aebab7cedec68a42aececeb218aaea0208b 100644 (file)
@@ -204,6 +204,9 @@ enum atc_status {
  * @status: transmit status information from irq/prep* functions
  *                to tasklet (use atomic operations)
  * @tasklet: bottom half to finish transaction work
+ * @save_cfg: configuration register that is saved on suspend/resume cycle
+ * @save_dscr: for cyclic operations, preserve next descriptor address in
+ *             the cyclic list on suspend/resume cycle
  * @lock: serializes enqueue/dequeue operations to descriptors lists
  * @completed_cookie: identifier for the most recently completed operation
  * @active_list: list of descriptors dmaengine is being running on
@@ -218,6 +221,8 @@ struct at_dma_chan {
        u8                      mask;
        unsigned long           status;
        struct tasklet_struct   tasklet;
+       u32                     save_cfg;
+       u32                     save_dscr;
 
        spinlock_t              lock;
 
@@ -248,6 +253,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
  * @chan_common: common dmaengine dma_device object members
  * @ch_regs: memory mapped register base
  * @clk: dma controller clock
+ * @save_imr: interrupt mask register that is saved on suspend/resume cycle
  * @all_chan_mask: all channels availlable in a mask
  * @dma_desc_pool: base of DMA descriptor region (DMA address)
  * @chan: channels table to store at_dma_chan structures
@@ -256,6 +262,7 @@ struct at_dma {
        struct dma_device       dma_common;
        void __iomem            *regs;
        struct clk              *clk;
+       u32                     save_imr;
 
        u8                      all_chan_mask;
 
@@ -355,6 +362,23 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
        return !!(dma_readl(atdma, CHSR) & atchan->mask);
 }
 
+/**
+ * atc_chan_is_paused - test channel pause/resume status
+ * @atchan: channel we want to test status
+ */
+static inline int atc_chan_is_paused(struct at_dma_chan *atchan)
+{
+       return test_bit(ATC_IS_PAUSED, &atchan->status);
+}
+
+/**
+ * atc_chan_is_cyclic - test if given channel has cyclic property set
+ * @atchan: channel we want to test status
+ */
+static inline int atc_chan_is_cyclic(struct at_dma_chan *atchan)
+{
+       return test_bit(ATC_IS_CYCLIC, &atchan->status);
+}
 
 /**
  * set_desc_eol - set end-of-link to descriptor so it will end transfer
index 765f5ff22304348aa629b5857a02397f93dea8ce..accc18441b1670f8c866b11b8c9250a2683e280e 100644 (file)
@@ -477,6 +477,8 @@ err_srcs:
        pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
                        thread_name, total_tests, failed_tests, ret);
 
+       /* terminate all transfers on specified channels */
+       chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
        if (iterations > 0)
                while (!kthread_should_stop()) {
                        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
@@ -499,6 +501,10 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
                list_del(&thread->node);
                kfree(thread);
        }
+
+       /* terminate all transfers on specified channels */
+       dtc->chan->device->device_control(dtc->chan, DMA_TERMINATE_ALL, 0);
+
        kfree(dtc);
 }
 
index be641cbd36fcb30c16aafaf25f279ecc0064b07a..b4588bdd98bb0f0f7dbd3ea5c570f760550ef14d 100644 (file)
@@ -130,6 +130,23 @@ struct mxs_dma_engine {
        struct mxs_dma_chan             mxs_chans[MXS_DMA_CHANNELS];
 };
 
+static inline void mxs_dma_clkgate(struct mxs_dma_chan *mxs_chan, int enable)
+{
+       struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
+       int chan_id = mxs_chan->chan.chan_id;
+       int set_clr = enable ? MXS_CLR_ADDR : MXS_SET_ADDR;
+
+       /* enable apbh channel clock */
+       if (dma_is_apbh()) {
+               if (apbh_is_old())
+                       writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
+                               mxs_dma->base + HW_APBHX_CTRL0 + set_clr);
+               else
+                       writel(1 << chan_id,
+                               mxs_dma->base + HW_APBHX_CTRL0 + set_clr);
+       }
+}
+
 static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
 {
        struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -148,38 +165,21 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
        struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
        int chan_id = mxs_chan->chan.chan_id;
 
+       /* clkgate needs to be enabled before writing other registers */
+       mxs_dma_clkgate(mxs_chan, 1);
+
        /* set cmd_addr up */
        writel(mxs_chan->ccw_phys,
                mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id));
 
-       /* enable apbh channel clock */
-       if (dma_is_apbh()) {
-               if (apbh_is_old())
-                       writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
-                               mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
-               else
-                       writel(1 << chan_id,
-                               mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
-       }
-
        /* write 1 to SEMA to kick off the channel */
        writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id));
 }
 
 static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
 {
-       struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
-       int chan_id = mxs_chan->chan.chan_id;
-
        /* disable apbh channel clock */
-       if (dma_is_apbh()) {
-               if (apbh_is_old())
-                       writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
-                               mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
-               else
-                       writel(1 << chan_id,
-                               mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
-       }
+       mxs_dma_clkgate(mxs_chan, 0);
 
        mxs_chan->status = DMA_SUCCESS;
 }
@@ -338,7 +338,10 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
        if (ret)
                goto err_clk;
 
+       /* clkgate needs to be enabled for reset to finish */
+       mxs_dma_clkgate(mxs_chan, 1);
        mxs_dma_reset_chan(mxs_chan);
+       mxs_dma_clkgate(mxs_chan, 0);
 
        dma_async_tx_descriptor_init(&mxs_chan->desc, chan);
        mxs_chan->desc.tx_submit = mxs_dma_tx_submit;
index af1a17d42bd76ad09309e9cba305e2d5e2bc8fbd..d057d6c40208e2d405d9e5b5d77be641bd46a051 100644 (file)
@@ -41,7 +41,7 @@ config EDAC_DEBUG
 
 config EDAC_DECODE_MCE
        tristate "Decode MCEs in human-readable form (only on AMD for now)"
-       depends on CPU_SUP_AMD && X86_MCE
+       depends on CPU_SUP_AMD && X86_MCE_AMD
        default y
        ---help---
          Enable this option if you want to decode Machine Check Exceptions
@@ -71,9 +71,6 @@ config EDAC_MM_EDAC
          occurred so that a particular failing memory module can be
          replaced.  If unsure, select 'Y'.
 
-config EDAC_MCE
-       bool
-
 config EDAC_AMD64
        tristate "AMD64 (Opteron, Athlon64) K8, F10h"
        depends on EDAC_MM_EDAC && AMD_NB && X86_64 && EDAC_DECODE_MCE
@@ -173,8 +170,7 @@ config EDAC_I5400
 
 config EDAC_I7CORE
        tristate "Intel i7 Core (Nehalem) processors"
-       depends on EDAC_MM_EDAC && PCI && X86
-       select EDAC_MCE
+       depends on EDAC_MM_EDAC && PCI && X86 && X86_MCE_INTEL
        help
          Support for error detection and correction the Intel
          i7 Core (Nehalem) Integrated Memory Controller that exists on
index 3e239133e29e792a54c9c2a4432806ff56535a96..b06a9b11a5f6c3e1e72fccc5a1528a33013664b4 100644 (file)
@@ -8,7 +8,6 @@
 
 obj-$(CONFIG_EDAC)                     := edac_stub.o
 obj-$(CONFIG_EDAC_MM_EDAC)             += edac_core.o
-obj-$(CONFIG_EDAC_MCE)                 += edac_mce.o
 
 edac_core-y    := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
 edac_core-y    += edac_module.o edac_device_sysfs.o
index 55b8278bb172f6feda52e225581b258b3404402a..fe90cd4a7ebc4192da2d1e354cc72e3436d6ab45 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/workqueue.h>
+#include <linux/edac.h>
 
-#define EDAC_MC_LABEL_LEN      31
 #define EDAC_DEVICE_NAME_LEN   31
 #define EDAC_ATTRIB_VALUE_LEN  15
-#define MC_PROC_NAME_MAX_LEN   7
 
 #if PAGE_SHIFT < 20
 #define PAGES_TO_MiB(pages)    ((pages) >> (20 - PAGE_SHIFT))
@@ -101,353 +100,6 @@ extern int edac_debug_level;
 
 #define edac_dev_name(dev) (dev)->dev_name
 
-/* memory devices */
-enum dev_type {
-       DEV_UNKNOWN = 0,
-       DEV_X1,
-       DEV_X2,
-       DEV_X4,
-       DEV_X8,
-       DEV_X16,
-       DEV_X32,                /* Do these parts exist? */
-       DEV_X64                 /* Do these parts exist? */
-};
-
-#define DEV_FLAG_UNKNOWN       BIT(DEV_UNKNOWN)
-#define DEV_FLAG_X1            BIT(DEV_X1)
-#define DEV_FLAG_X2            BIT(DEV_X2)
-#define DEV_FLAG_X4            BIT(DEV_X4)
-#define DEV_FLAG_X8            BIT(DEV_X8)
-#define DEV_FLAG_X16           BIT(DEV_X16)
-#define DEV_FLAG_X32           BIT(DEV_X32)
-#define DEV_FLAG_X64           BIT(DEV_X64)
-
-/* memory types */
-enum mem_type {
-       MEM_EMPTY = 0,          /* Empty csrow */
-       MEM_RESERVED,           /* Reserved csrow type */
-       MEM_UNKNOWN,            /* Unknown csrow type */
-       MEM_FPM,                /* Fast page mode */
-       MEM_EDO,                /* Extended data out */
-       MEM_BEDO,               /* Burst Extended data out */
-       MEM_SDR,                /* Single data rate SDRAM */
-       MEM_RDR,                /* Registered single data rate SDRAM */
-       MEM_DDR,                /* Double data rate SDRAM */
-       MEM_RDDR,               /* Registered Double data rate SDRAM */
-       MEM_RMBS,               /* Rambus DRAM */
-       MEM_DDR2,               /* DDR2 RAM */
-       MEM_FB_DDR2,            /* fully buffered DDR2 */
-       MEM_RDDR2,              /* Registered DDR2 RAM */
-       MEM_XDR,                /* Rambus XDR */
-       MEM_DDR3,               /* DDR3 RAM */
-       MEM_RDDR3,              /* Registered DDR3 RAM */
-};
-
-#define MEM_FLAG_EMPTY         BIT(MEM_EMPTY)
-#define MEM_FLAG_RESERVED      BIT(MEM_RESERVED)
-#define MEM_FLAG_UNKNOWN       BIT(MEM_UNKNOWN)
-#define MEM_FLAG_FPM           BIT(MEM_FPM)
-#define MEM_FLAG_EDO           BIT(MEM_EDO)
-#define MEM_FLAG_BEDO          BIT(MEM_BEDO)
-#define MEM_FLAG_SDR           BIT(MEM_SDR)
-#define MEM_FLAG_RDR           BIT(MEM_RDR)
-#define MEM_FLAG_DDR           BIT(MEM_DDR)
-#define MEM_FLAG_RDDR          BIT(MEM_RDDR)
-#define MEM_FLAG_RMBS          BIT(MEM_RMBS)
-#define MEM_FLAG_DDR2           BIT(MEM_DDR2)
-#define MEM_FLAG_FB_DDR2        BIT(MEM_FB_DDR2)
-#define MEM_FLAG_RDDR2          BIT(MEM_RDDR2)
-#define MEM_FLAG_XDR            BIT(MEM_XDR)
-#define MEM_FLAG_DDR3           BIT(MEM_DDR3)
-#define MEM_FLAG_RDDR3          BIT(MEM_RDDR3)
-
-/* chipset Error Detection and Correction capabilities and mode */
-enum edac_type {
-       EDAC_UNKNOWN = 0,       /* Unknown if ECC is available */
-       EDAC_NONE,              /* Doesn't support ECC */
-       EDAC_RESERVED,          /* Reserved ECC type */
-       EDAC_PARITY,            /* Detects parity errors */
-       EDAC_EC,                /* Error Checking - no correction */
-       EDAC_SECDED,            /* Single bit error correction, Double detection */
-       EDAC_S2ECD2ED,          /* Chipkill x2 devices - do these exist? */
-       EDAC_S4ECD4ED,          /* Chipkill x4 devices */
-       EDAC_S8ECD8ED,          /* Chipkill x8 devices */
-       EDAC_S16ECD16ED,        /* Chipkill x16 devices */
-};
-
-#define EDAC_FLAG_UNKNOWN      BIT(EDAC_UNKNOWN)
-#define EDAC_FLAG_NONE         BIT(EDAC_NONE)
-#define EDAC_FLAG_PARITY       BIT(EDAC_PARITY)
-#define EDAC_FLAG_EC           BIT(EDAC_EC)
-#define EDAC_FLAG_SECDED       BIT(EDAC_SECDED)
-#define EDAC_FLAG_S2ECD2ED     BIT(EDAC_S2ECD2ED)
-#define EDAC_FLAG_S4ECD4ED     BIT(EDAC_S4ECD4ED)
-#define EDAC_FLAG_S8ECD8ED     BIT(EDAC_S8ECD8ED)
-#define EDAC_FLAG_S16ECD16ED   BIT(EDAC_S16ECD16ED)
-
-/* scrubbing capabilities */
-enum scrub_type {
-       SCRUB_UNKNOWN = 0,      /* Unknown if scrubber is available */
-       SCRUB_NONE,             /* No scrubber */
-       SCRUB_SW_PROG,          /* SW progressive (sequential) scrubbing */
-       SCRUB_SW_SRC,           /* Software scrub only errors */
-       SCRUB_SW_PROG_SRC,      /* Progressive software scrub from an error */
-       SCRUB_SW_TUNABLE,       /* Software scrub frequency is tunable */
-       SCRUB_HW_PROG,          /* HW progressive (sequential) scrubbing */
-       SCRUB_HW_SRC,           /* Hardware scrub only errors */
-       SCRUB_HW_PROG_SRC,      /* Progressive hardware scrub from an error */
-       SCRUB_HW_TUNABLE        /* Hardware scrub frequency is tunable */
-};
-
-#define SCRUB_FLAG_SW_PROG     BIT(SCRUB_SW_PROG)
-#define SCRUB_FLAG_SW_SRC      BIT(SCRUB_SW_SRC)
-#define SCRUB_FLAG_SW_PROG_SRC BIT(SCRUB_SW_PROG_SRC)
-#define SCRUB_FLAG_SW_TUN      BIT(SCRUB_SW_SCRUB_TUNABLE)
-#define SCRUB_FLAG_HW_PROG     BIT(SCRUB_HW_PROG)
-#define SCRUB_FLAG_HW_SRC      BIT(SCRUB_HW_SRC)
-#define SCRUB_FLAG_HW_PROG_SRC BIT(SCRUB_HW_PROG_SRC)
-#define SCRUB_FLAG_HW_TUN      BIT(SCRUB_HW_TUNABLE)
-
-/* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */
-
-/* EDAC internal operation states */
-#define        OP_ALLOC                0x100
-#define OP_RUNNING_POLL                0x201
-#define OP_RUNNING_INTERRUPT   0x202
-#define OP_RUNNING_POLL_INTR   0x203
-#define OP_OFFLINE             0x300
-
-/*
- * There are several things to be aware of that aren't at all obvious:
- *
- *
- * SOCKETS, SOCKET SETS, BANKS, ROWS, CHIP-SELECT ROWS, CHANNELS, etc..
- *
- * These are some of the many terms that are thrown about that don't always
- * mean what people think they mean (Inconceivable!).  In the interest of
- * creating a common ground for discussion, terms and their definitions
- * will be established.
- *
- * Memory devices:     The individual chip on a memory stick.  These devices
- *                     commonly output 4 and 8 bits each.  Grouping several
- *                     of these in parallel provides 64 bits which is common
- *                     for a memory stick.
- *
- * Memory Stick:       A printed circuit board that aggregates multiple
- *                     memory devices in parallel.  This is the atomic
- *                     memory component that is purchaseable by Joe consumer
- *                     and loaded into a memory socket.
- *
- * Socket:             A physical connector on the motherboard that accepts
- *                     a single memory stick.
- *
- * Channel:            Set of memory devices on a memory stick that must be
- *                     grouped in parallel with one or more additional
- *                     channels from other memory sticks.  This parallel
- *                     grouping of the output from multiple channels are
- *                     necessary for the smallest granularity of memory access.
- *                     Some memory controllers are capable of single channel -
- *                     which means that memory sticks can be loaded
- *                     individually.  Other memory controllers are only
- *                     capable of dual channel - which means that memory
- *                     sticks must be loaded as pairs (see "socket set").
- *
- * Chip-select row:    All of the memory devices that are selected together.
- *                     for a single, minimum grain of memory access.
- *                     This selects all of the parallel memory devices across
- *                     all of the parallel channels.  Common chip-select rows
- *                     for single channel are 64 bits, for dual channel 128
- *                     bits.
- *
- * Single-Ranked stick:        A Single-ranked stick has 1 chip-select row of memory.
- *                     Motherboards commonly drive two chip-select pins to
- *                     a memory stick. A single-ranked stick, will occupy
- *                     only one of those rows. The other will be unused.
- *
- * Double-Ranked stick:        A double-ranked stick has two chip-select rows which
- *                     access different sets of memory devices.  The two
- *                     rows cannot be accessed concurrently.
- *
- * Double-sided stick: DEPRECATED TERM, see Double-Ranked stick.
- *                     A double-sided stick has two chip-select rows which
- *                     access different sets of memory devices.  The two
- *                     rows cannot be accessed concurrently.  "Double-sided"
- *                     is irrespective of the memory devices being mounted
- *                     on both sides of the memory stick.
- *
- * Socket set:         All of the memory sticks that are required for
- *                     a single memory access or all of the memory sticks
- *                     spanned by a chip-select row.  A single socket set
- *                     has two chip-select rows and if double-sided sticks
- *                     are used these will occupy those chip-select rows.
- *
- * Bank:               This term is avoided because it is unclear when
- *                     needing to distinguish between chip-select rows and
- *                     socket sets.
- *
- * Controller pages:
- *
- * Physical pages:
- *
- * Virtual pages:
- *
- *
- * STRUCTURE ORGANIZATION AND CHOICES
- *
- *
- *
- * PS - I enjoyed writing all that about as much as you enjoyed reading it.
- */
-
-struct channel_info {
-       int chan_idx;           /* channel index */
-       u32 ce_count;           /* Correctable Errors for this CHANNEL */
-       char label[EDAC_MC_LABEL_LEN + 1];      /* DIMM label on motherboard */
-       struct csrow_info *csrow;       /* the parent */
-};
-
-struct csrow_info {
-       unsigned long first_page;       /* first page number in dimm */
-       unsigned long last_page;        /* last page number in dimm */
-       unsigned long page_mask;        /* used for interleaving -
-                                        * 0UL for non intlv
-                                        */
-       u32 nr_pages;           /* number of pages in csrow */
-       u32 grain;              /* granularity of reported error in bytes */
-       int csrow_idx;          /* the chip-select row */
-       enum dev_type dtype;    /* memory device type */
-       u32 ue_count;           /* Uncorrectable Errors for this csrow */
-       u32 ce_count;           /* Correctable Errors for this csrow */
-       enum mem_type mtype;    /* memory csrow type */
-       enum edac_type edac_mode;       /* EDAC mode for this csrow */
-       struct mem_ctl_info *mci;       /* the parent */
-
-       struct kobject kobj;    /* sysfs kobject for this csrow */
-
-       /* channel information for this csrow */
-       u32 nr_channels;
-       struct channel_info *channels;
-};
-
-struct mcidev_sysfs_group {
-       const char *name;                               /* group name */
-       const struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */
-};
-
-struct mcidev_sysfs_group_kobj {
-       struct list_head list;          /* list for all instances within a mc */
-
-       struct kobject kobj;            /* kobj for the group */
-
-       const struct mcidev_sysfs_group *grp;   /* group description table */
-       struct mem_ctl_info *mci;       /* the parent */
-};
-
-/* mcidev_sysfs_attribute structure
- *     used for driver sysfs attributes and in mem_ctl_info
- *     sysfs top level entries
- */
-struct mcidev_sysfs_attribute {
-       /* It should use either attr or grp */
-       struct attribute attr;
-       const struct mcidev_sysfs_group *grp;   /* Points to a group of attributes */
-
-       /* Ops for show/store values at the attribute - not used on group */
-        ssize_t (*show)(struct mem_ctl_info *,char *);
-        ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
-};
-
-/* MEMORY controller information structure
- */
-struct mem_ctl_info {
-       struct list_head link;  /* for global list of mem_ctl_info structs */
-
-       struct module *owner;   /* Module owner of this control struct */
-
-       unsigned long mtype_cap;        /* memory types supported by mc */
-       unsigned long edac_ctl_cap;     /* Mem controller EDAC capabilities */
-       unsigned long edac_cap; /* configuration capabilities - this is
-                                * closely related to edac_ctl_cap.  The
-                                * difference is that the controller may be
-                                * capable of s4ecd4ed which would be listed
-                                * in edac_ctl_cap, but if channels aren't
-                                * capable of s4ecd4ed then the edac_cap would
-                                * not have that capability.
-                                */
-       unsigned long scrub_cap;        /* chipset scrub capabilities */
-       enum scrub_type scrub_mode;     /* current scrub mode */
-
-       /* Translates sdram memory scrub rate given in bytes/sec to the
-          internal representation and configures whatever else needs
-          to be configured.
-        */
-       int (*set_sdram_scrub_rate) (struct mem_ctl_info * mci, u32 bw);
-
-       /* Get the current sdram memory scrub rate from the internal
-          representation and converts it to the closest matching
-          bandwidth in bytes/sec.
-        */
-       int (*get_sdram_scrub_rate) (struct mem_ctl_info * mci);
-
-
-       /* pointer to edac checking routine */
-       void (*edac_check) (struct mem_ctl_info * mci);
-
-       /*
-        * Remaps memory pages: controller pages to physical pages.
-        * For most MC's, this will be NULL.
-        */
-       /* FIXME - why not send the phys page to begin with? */
-       unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
-                                          unsigned long page);
-       int mc_idx;
-       int nr_csrows;
-       struct csrow_info *csrows;
-       /*
-        * FIXME - what about controllers on other busses? - IDs must be
-        * unique.  dev pointer should be sufficiently unique, but
-        * BUS:SLOT.FUNC numbers may not be unique.
-        */
-       struct device *dev;
-       const char *mod_name;
-       const char *mod_ver;
-       const char *ctl_name;
-       const char *dev_name;
-       char proc_name[MC_PROC_NAME_MAX_LEN + 1];
-       void *pvt_info;
-       u32 ue_noinfo_count;    /* Uncorrectable Errors w/o info */
-       u32 ce_noinfo_count;    /* Correctable Errors w/o info */
-       u32 ue_count;           /* Total Uncorrectable Errors for this MC */
-       u32 ce_count;           /* Total Correctable Errors for this MC */
-       unsigned long start_time;       /* mci load start time (in jiffies) */
-
-       struct completion complete;
-
-       /* edac sysfs device control */
-       struct kobject edac_mci_kobj;
-
-       /* list for all grp instances within a mc */
-       struct list_head grp_kobj_list;
-
-       /* Additional top controller level attributes, but specified
-        * by the low level driver.
-        *
-        * Set by the low level driver to provide attributes at the
-        * controller level, same level as 'ue_count' and 'ce_count' above.
-        * An array of structures, NULL terminated
-        *
-        * If attributes are desired, then set to array of attributes
-        * If no attributes are desired, leave NULL
-        */
-       const struct mcidev_sysfs_attribute *mc_driver_sysfs_attributes;
-
-       /* work struct for this MC */
-       struct delayed_work work;
-
-       /* the internal state of this controller instance */
-       int op_state;
-};
-
 /*
  * The following are the structures to provide for a generic
  * or abstract 'edac_device'. This set of structures and the
diff --git a/drivers/edac/edac_mce.c b/drivers/edac/edac_mce.c
deleted file mode 100644 (file)
index 9ccdc5b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Provides edac interface to mcelog events
- *
- * This file may be distributed under the terms of the
- * GNU General Public License version 2.
- *
- * Copyright (c) 2009 by:
- *      Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * Red Hat Inc. http://www.redhat.com
- */
-
-#include <linux/module.h>
-#include <linux/edac_mce.h>
-#include <asm/mce.h>
-
-int edac_mce_enabled;
-EXPORT_SYMBOL_GPL(edac_mce_enabled);
-
-
-/*
- * Extension interface
- */
-
-static LIST_HEAD(edac_mce_list);
-static DEFINE_MUTEX(edac_mce_lock);
-
-int edac_mce_register(struct edac_mce *edac_mce)
-{
-       mutex_lock(&edac_mce_lock);
-       list_add_tail(&edac_mce->list, &edac_mce_list);
-       mutex_unlock(&edac_mce_lock);
-       return 0;
-}
-EXPORT_SYMBOL(edac_mce_register);
-
-void edac_mce_unregister(struct edac_mce *edac_mce)
-{
-       mutex_lock(&edac_mce_lock);
-       list_del(&edac_mce->list);
-       mutex_unlock(&edac_mce_lock);
-}
-EXPORT_SYMBOL(edac_mce_unregister);
-
-int edac_mce_parse(struct mce *mce)
-{
-       struct edac_mce *edac_mce;
-
-       list_for_each_entry(edac_mce, &edac_mce_list, list) {
-               if (edac_mce->check_error(edac_mce->priv, mce))
-                       return 1;
-       }
-
-       /* Nobody queued the error */
-       return 0;
-}
-EXPORT_SYMBOL_GPL(edac_mce_parse);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-MODULE_DESCRIPTION("EDAC Driver for mcelog captured errors");
index f6cf448d69b4f468160e19fc29fab0ea473f04b8..7cb68decf57db335d486920313e57f305d7e03e0 100644 (file)
 #include <linux/pci_ids.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/edac.h>
 #include <linux/mmzone.h>
-#include <linux/edac_mce.h>
 #include <linux/smp.h>
+#include <asm/mce.h>
 #include <asm/processor.h>
 
 #include "edac_core.h"
@@ -78,6 +79,8 @@ MODULE_PARM_DESC(use_pci_fixup, "Enable PCI fixup to seek for hidden devices");
        /* OFFSETS for Device 0 Function 0 */
 
 #define MC_CFG_CONTROL 0x90
+  #define MC_CFG_UNLOCK                0x02
+  #define MC_CFG_LOCK          0x00
 
        /* OFFSETS for Device 3 Function 0 */
 
@@ -98,6 +101,15 @@ MODULE_PARM_DESC(use_pci_fixup, "Enable PCI fixup to seek for hidden devices");
   #define DIMM0_COR_ERR(r)                     ((r) & 0x7fff)
 
 /* OFFSETS for Device 3 Function 2, as inicated on Xeon 5500 datasheet */
+#define MC_SSRCONTROL          0x48
+  #define SSR_MODE_DISABLE     0x00
+  #define SSR_MODE_ENABLE      0x01
+  #define SSR_MODE_MASK                0x03
+
+#define MC_SCRUB_CONTROL       0x4c
+  #define STARTSCRUB           (1 << 24)
+  #define SCRUBINTERVAL_MASK    0xffffff
+
 #define MC_COR_ECC_CNT_0       0x80
 #define MC_COR_ECC_CNT_1       0x84
 #define MC_COR_ECC_CNT_2       0x88
@@ -253,10 +265,7 @@ struct i7core_pvt {
        unsigned long   rdimm_ce_count[NUM_CHANS][MAX_DIMMS];
        int             rdimm_last_ce_count[NUM_CHANS][MAX_DIMMS];
 
-       unsigned int    is_registered;
-
-       /* mcelog glue */
-       struct edac_mce         edac_mce;
+       bool            is_registered, enable_scrub;
 
        /* Fifo double buffers */
        struct mce              mce_entry[MCE_LOG_LEN];
@@ -268,6 +277,9 @@ struct i7core_pvt {
        /* Count indicator to show errors not got */
        unsigned                mce_overrun;
 
+       /* DCLK Frequency used for computing scrub rate */
+       int                     dclk_freq;
+
        /* Struct to control EDAC polling */
        struct edac_pci_ctl_info *i7core_pci;
 };
@@ -281,8 +293,7 @@ static const struct pci_id_descr pci_dev_descr_i7core_nehalem[] = {
                /* Memory controller */
        { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR)     },
        { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD)  },
-
-               /* Exists only for RDIMM */
+                       /* Exists only for RDIMM */
        { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1  },
        { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
 
@@ -303,6 +314,16 @@ static const struct pci_id_descr pci_dev_descr_i7core_nehalem[] = {
        { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
        { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
        { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC)   },
+
+               /* Generic Non-core registers */
+       /*
+        * This is the PCI device on i7core and on Xeon 35xx (8086:2c41)
+        * On Xeon 55xx, however, it has a different id (8086:2c40). So,
+        * the probing code needs to test for the other address in case of
+        * failure of this one
+        */
+       { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE)  },
+
 };
 
 static const struct pci_id_descr pci_dev_descr_lynnfield[] = {
@@ -319,6 +340,12 @@ static const struct pci_id_descr pci_dev_descr_lynnfield[] = {
        { PCI_DESCR( 5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) },
        { PCI_DESCR( 5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) },
        { PCI_DESCR( 5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC)   },
+
+       /*
+        * This is the PCI device has an alternate address on some
+        * processors like Core i7 860
+        */
+       { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE)     },
 };
 
 static const struct pci_id_descr pci_dev_descr_i7core_westmere[] = {
@@ -346,6 +373,10 @@ static const struct pci_id_descr pci_dev_descr_i7core_westmere[] = {
        { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) },
        { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) },
        { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2)   },
+
+               /* Generic Non-core registers */
+       { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2)  },
+
 };
 
 #define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) }
@@ -731,7 +762,7 @@ static int get_dimm_config(const struct mem_ctl_info *mci)
                        debugf1("\t\t%#x\t%#x\t%#x\n",
                                (value[j] >> 27) & 0x1,
                                (value[j] >> 24) & 0x7,
-                               (value[j] && ((1 << 24) - 1)));
+                               (value[j] & ((1 << 24) - 1)));
        }
 
        return 0;
@@ -1324,6 +1355,20 @@ static int i7core_get_onedevice(struct pci_dev **prev,
        pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
                              dev_descr->dev_id, *prev);
 
+       /*
+        * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
+        * is at addr 8086:2c40, instead of 8086:2c41. So, we need
+        * to probe for the alternate address in case of failure
+        */
+       if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev)
+               pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+                                     PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev);
+
+       if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev)
+               pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+                                     PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT,
+                                     *prev);
+
        if (!pdev) {
                if (*prev) {
                        *prev = pdev;
@@ -1444,8 +1489,10 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
        struct i7core_pvt *pvt = mci->pvt_info;
        struct pci_dev *pdev;
        int i, func, slot;
+       char *family;
 
-       pvt->is_registered = 0;
+       pvt->is_registered = false;
+       pvt->enable_scrub  = false;
        for (i = 0; i < i7core_dev->n_devs; i++) {
                pdev = i7core_dev->pdev[i];
                if (!pdev)
@@ -1461,9 +1508,37 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
                        if (unlikely(func > MAX_CHAN_FUNC))
                                goto error;
                        pvt->pci_ch[slot - 4][func] = pdev;
-               } else if (!slot && !func)
+               } else if (!slot && !func) {
                        pvt->pci_noncore = pdev;
-               else
+
+                       /* Detect the processor family */
+                       switch (pdev->device) {
+                       case PCI_DEVICE_ID_INTEL_I7_NONCORE:
+                               family = "Xeon 35xx/ i7core";
+                               pvt->enable_scrub = false;
+                               break;
+                       case PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT:
+                               family = "i7-800/i5-700";
+                               pvt->enable_scrub = false;
+                               break;
+                       case PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE:
+                               family = "Xeon 34xx";
+                               pvt->enable_scrub = false;
+                               break;
+                       case PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT:
+                               family = "Xeon 55xx";
+                               pvt->enable_scrub = true;
+                               break;
+                       case PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2:
+                               family = "Xeon 56xx / i7-900";
+                               pvt->enable_scrub = true;
+                               break;
+                       default:
+                               family = "unknown";
+                               pvt->enable_scrub = false;
+                       }
+                       debugf0("Detected a processor type %s\n", family);
+               } else
                        goto error;
 
                debugf0("Associated fn %d.%d, dev = %p, socket %d\n",
@@ -1472,7 +1547,7 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
 
                if (PCI_SLOT(pdev->devfn) == 3 &&
                        PCI_FUNC(pdev->devfn) == 2)
-                       pvt->is_registered = 1;
+                       pvt->is_registered = true;
        }
 
        return 0;
@@ -1826,33 +1901,43 @@ check_ce_error:
  * WARNING: As this routine should be called at NMI time, extra care should
  * be taken to avoid deadlocks, and to be as fast as possible.
  */
-static int i7core_mce_check_error(void *priv, struct mce *mce)
+static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
+                                 void *data)
 {
-       struct mem_ctl_info *mci = priv;
-       struct i7core_pvt *pvt = mci->pvt_info;
+       struct mce *mce = (struct mce *)data;
+       struct i7core_dev *i7_dev;
+       struct mem_ctl_info *mci;
+       struct i7core_pvt *pvt;
+
+       i7_dev = get_i7core_dev(mce->socketid);
+       if (!i7_dev)
+               return NOTIFY_BAD;
+
+       mci = i7_dev->mci;
+       pvt = mci->pvt_info;
 
        /*
         * Just let mcelog handle it if the error is
         * outside the memory controller
         */
        if (((mce->status & 0xffff) >> 7) != 1)
-               return 0;
+               return NOTIFY_DONE;
 
        /* Bank 8 registers are the only ones that we know how to handle */
        if (mce->bank != 8)
-               return 0;
+               return NOTIFY_DONE;
 
 #ifdef CONFIG_SMP
        /* Only handle if it is the right mc controller */
-       if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket)
-               return 0;
+       if (mce->socketid != pvt->i7core_dev->socket)
+               return NOTIFY_DONE;
 #endif
 
        smp_rmb();
        if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) {
                smp_wmb();
                pvt->mce_overrun++;
-               return 0;
+               return NOTIFY_DONE;
        }
 
        /* Copy memory error at the ringbuffer */
@@ -1865,7 +1950,238 @@ static int i7core_mce_check_error(void *priv, struct mce *mce)
                i7core_check_error(mci);
 
        /* Advise mcelog that the errors were handled */
-       return 1;
+       return NOTIFY_STOP;
+}
+
+static struct notifier_block i7_mce_dec = {
+       .notifier_call  = i7core_mce_check_error,
+};
+
+struct memdev_dmi_entry {
+       u8 type;
+       u8 length;
+       u16 handle;
+       u16 phys_mem_array_handle;
+       u16 mem_err_info_handle;
+       u16 total_width;
+       u16 data_width;
+       u16 size;
+       u8 form;
+       u8 device_set;
+       u8 device_locator;
+       u8 bank_locator;
+       u8 memory_type;
+       u16 type_detail;
+       u16 speed;
+       u8 manufacturer;
+       u8 serial_number;
+       u8 asset_tag;
+       u8 part_number;
+       u8 attributes;
+       u32 extended_size;
+       u16 conf_mem_clk_speed;
+} __attribute__((__packed__));
+
+
+/*
+ * Decode the DRAM Clock Frequency, be paranoid, make sure that all
+ * memory devices show the same speed, and if they don't then consider
+ * all speeds to be invalid.
+ */
+static void decode_dclk(const struct dmi_header *dh, void *_dclk_freq)
+{
+       int *dclk_freq = _dclk_freq;
+       u16 dmi_mem_clk_speed;
+
+       if (*dclk_freq == -1)
+               return;
+
+       if (dh->type == DMI_ENTRY_MEM_DEVICE) {
+               struct memdev_dmi_entry *memdev_dmi_entry =
+                       (struct memdev_dmi_entry *)dh;
+               unsigned long conf_mem_clk_speed_offset =
+                       (unsigned long)&memdev_dmi_entry->conf_mem_clk_speed -
+                       (unsigned long)&memdev_dmi_entry->type;
+               unsigned long speed_offset =
+                       (unsigned long)&memdev_dmi_entry->speed -
+                       (unsigned long)&memdev_dmi_entry->type;
+
+               /* Check that a DIMM is present */
+               if (memdev_dmi_entry->size == 0)
+                       return;
+
+               /*
+                * Pick the configured speed if it's available, otherwise
+                * pick the DIMM speed, or we don't have a speed.
+                */
+               if (memdev_dmi_entry->length > conf_mem_clk_speed_offset) {
+                       dmi_mem_clk_speed =
+                               memdev_dmi_entry->conf_mem_clk_speed;
+               } else if (memdev_dmi_entry->length > speed_offset) {
+                       dmi_mem_clk_speed = memdev_dmi_entry->speed;
+               } else {
+                       *dclk_freq = -1;
+                       return;
+               }
+
+               if (*dclk_freq == 0) {
+                       /* First pass, speed was 0 */
+                       if (dmi_mem_clk_speed > 0) {
+                               /* Set speed if a valid speed is read */
+                               *dclk_freq = dmi_mem_clk_speed;
+                       } else {
+                               /* Otherwise we don't have a valid speed */
+                               *dclk_freq = -1;
+                       }
+               } else if (*dclk_freq > 0 &&
+                          *dclk_freq != dmi_mem_clk_speed) {
+                       /*
+                        * If we have a speed, check that all DIMMS are the same
+                        * speed, otherwise set the speed as invalid.
+                        */
+                       *dclk_freq = -1;
+               }
+       }
+}
+
+/*
+ * The default DCLK frequency is used as a fallback if we
+ * fail to find anything reliable in the DMI. The value
+ * is taken straight from the datasheet.
+ */
+#define DEFAULT_DCLK_FREQ 800
+
+static int get_dclk_freq(void)
+{
+       int dclk_freq = 0;
+
+       dmi_walk(decode_dclk, (void *)&dclk_freq);
+
+       if (dclk_freq < 1)
+               return DEFAULT_DCLK_FREQ;
+
+       return dclk_freq;
+}
+
+/*
+ * set_sdram_scrub_rate                This routine sets byte/sec bandwidth scrub rate
+ *                             to hardware according to SCRUBINTERVAL formula
+ *                             found in datasheet.
+ */
+static int set_sdram_scrub_rate(struct mem_ctl_info *mci, u32 new_bw)
+{
+       struct i7core_pvt *pvt = mci->pvt_info;
+       struct pci_dev *pdev;
+       u32 dw_scrub;
+       u32 dw_ssr;
+
+       /* Get data from the MC register, function 2 */
+       pdev = pvt->pci_mcr[2];
+       if (!pdev)
+               return -ENODEV;
+
+       pci_read_config_dword(pdev, MC_SCRUB_CONTROL, &dw_scrub);
+
+       if (new_bw == 0) {
+               /* Prepare to disable petrol scrub */
+               dw_scrub &= ~STARTSCRUB;
+               /* Stop the patrol scrub engine */
+               write_and_test(pdev, MC_SCRUB_CONTROL,
+                              dw_scrub & ~SCRUBINTERVAL_MASK);
+
+               /* Get current status of scrub rate and set bit to disable */
+               pci_read_config_dword(pdev, MC_SSRCONTROL, &dw_ssr);
+               dw_ssr &= ~SSR_MODE_MASK;
+               dw_ssr |= SSR_MODE_DISABLE;
+       } else {
+               const int cache_line_size = 64;
+               const u32 freq_dclk_mhz = pvt->dclk_freq;
+               unsigned long long scrub_interval;
+               /*
+                * Translate the desired scrub rate to a register value and
+                * program the corresponding register value.
+                */
+               scrub_interval = (unsigned long long)freq_dclk_mhz *
+                       cache_line_size * 1000000 / new_bw;
+
+               if (!scrub_interval || scrub_interval > SCRUBINTERVAL_MASK)
+                       return -EINVAL;
+
+               dw_scrub = SCRUBINTERVAL_MASK & scrub_interval;
+
+               /* Start the patrol scrub engine */
+               pci_write_config_dword(pdev, MC_SCRUB_CONTROL,
+                                      STARTSCRUB | dw_scrub);
+
+               /* Get current status of scrub rate and set bit to enable */
+               pci_read_config_dword(pdev, MC_SSRCONTROL, &dw_ssr);
+               dw_ssr &= ~SSR_MODE_MASK;
+               dw_ssr |= SSR_MODE_ENABLE;
+       }
+       /* Disable or enable scrubbing */
+       pci_write_config_dword(pdev, MC_SSRCONTROL, dw_ssr);
+
+       return new_bw;
+}
+
+/*
+ * get_sdram_scrub_rate                This routine convert current scrub rate value
+ *                             into byte/sec bandwidth accourding to
+ *                             SCRUBINTERVAL formula found in datasheet.
+ */
+static int get_sdram_scrub_rate(struct mem_ctl_info *mci)
+{
+       struct i7core_pvt *pvt = mci->pvt_info;
+       struct pci_dev *pdev;
+       const u32 cache_line_size = 64;
+       const u32 freq_dclk_mhz = pvt->dclk_freq;
+       unsigned long long scrub_rate;
+       u32 scrubval;
+
+       /* Get data from the MC register, function 2 */
+       pdev = pvt->pci_mcr[2];
+       if (!pdev)
+               return -ENODEV;
+
+       /* Get current scrub control data */
+       pci_read_config_dword(pdev, MC_SCRUB_CONTROL, &scrubval);
+
+       /* Mask highest 8-bits to 0 */
+       scrubval &=  SCRUBINTERVAL_MASK;
+       if (!scrubval)
+               return 0;
+
+       /* Calculate scrub rate value into byte/sec bandwidth */
+       scrub_rate =  (unsigned long long)freq_dclk_mhz *
+               1000000 * cache_line_size / scrubval;
+       return (int)scrub_rate;
+}
+
+static void enable_sdram_scrub_setting(struct mem_ctl_info *mci)
+{
+       struct i7core_pvt *pvt = mci->pvt_info;
+       u32 pci_lock;
+
+       /* Unlock writes to pci registers */
+       pci_read_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, &pci_lock);
+       pci_lock &= ~0x3;
+       pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL,
+                              pci_lock | MC_CFG_UNLOCK);
+
+       mci->set_sdram_scrub_rate = set_sdram_scrub_rate;
+       mci->get_sdram_scrub_rate = get_sdram_scrub_rate;
+}
+
+static void disable_sdram_scrub_setting(struct mem_ctl_info *mci)
+{
+       struct i7core_pvt *pvt = mci->pvt_info;
+       u32 pci_lock;
+
+       /* Lock writes to pci registers */
+       pci_read_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, &pci_lock);
+       pci_lock &= ~0x3;
+       pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL,
+                              pci_lock | MC_CFG_LOCK);
 }
 
 static void i7core_pci_ctl_create(struct i7core_pvt *pvt)
@@ -1874,7 +2190,8 @@ static void i7core_pci_ctl_create(struct i7core_pvt *pvt)
                                                &pvt->i7core_dev->pdev[0]->dev,
                                                EDAC_MOD_STR);
        if (unlikely(!pvt->i7core_pci))
-               pr_warn("Unable to setup PCI error report via EDAC\n");
+               i7core_printk(KERN_WARNING,
+                             "Unable to setup PCI error report via EDAC\n");
 }
 
 static void i7core_pci_ctl_release(struct i7core_pvt *pvt)
@@ -1906,8 +2223,11 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev)
        debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
                __func__, mci, &i7core_dev->pdev[0]->dev);
 
-       /* Disable MCE NMI handler */
-       edac_mce_unregister(&pvt->edac_mce);
+       /* Disable scrubrate setting */
+       if (pvt->enable_scrub)
+               disable_sdram_scrub_setting(mci);
+
+       atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &i7_mce_dec);
 
        /* Disable EDAC polling */
        i7core_pci_ctl_release(pvt);
@@ -1979,6 +2299,10 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
        /* Set the function pointer to an actual operation function */
        mci->edac_check = i7core_check_error;
 
+       /* Enable scrubrate setting */
+       if (pvt->enable_scrub)
+               enable_sdram_scrub_setting(mci);
+
        /* add this new MC control structure to EDAC's list of MCs */
        if (unlikely(edac_mc_add_mc(mci))) {
                debugf0("MC: " __FILE__
@@ -2002,21 +2326,13 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
        /* allocating generic PCI control info */
        i7core_pci_ctl_create(pvt);
 
-       /* Registers on edac_mce in order to receive memory errors */
-       pvt->edac_mce.priv = mci;
-       pvt->edac_mce.check_error = i7core_mce_check_error;
-       rc = edac_mce_register(&pvt->edac_mce);
-       if (unlikely(rc < 0)) {
-               debugf0("MC: " __FILE__
-                       ": %s(): failed edac_mce_register()\n", __func__);
-               goto fail1;
-       }
+       /* DCLK for scrub rate setting */
+       pvt->dclk_freq = get_dclk_freq();
+
+       atomic_notifier_chain_register(&x86_mce_decoder_chain, &i7_mce_dec);
 
        return 0;
 
-fail1:
-       i7core_pci_ctl_release(pvt);
-       edac_mc_del_mc(mci->dev);
 fail0:
        kfree(mci->ctl_name);
        edac_mc_free(mci);
@@ -2035,7 +2351,7 @@ fail0:
 static int __devinit i7core_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *id)
 {
-       int rc;
+       int rc, count = 0;
        struct i7core_dev *i7core_dev;
 
        /* get the pci devices we want to reserve for our use */
@@ -2055,12 +2371,28 @@ static int __devinit i7core_probe(struct pci_dev *pdev,
                goto fail0;
 
        list_for_each_entry(i7core_dev, &i7core_edac_list, list) {
+               count++;
                rc = i7core_register_mci(i7core_dev);
                if (unlikely(rc < 0))
                        goto fail1;
        }
 
-       i7core_printk(KERN_INFO, "Driver loaded.\n");
+       /*
+        * Nehalem-EX uses a different memory controller. However, as the
+        * memory controller is not visible on some Nehalem/Nehalem-EP, we
+        * need to indirectly probe via a X58 PCI device. The same devices
+        * are found on (some) Nehalem-EX. So, on those machines, the
+        * probe routine needs to return -ENODEV, as the actual Memory
+        * Controller registers won't be detected.
+        */
+       if (!count) {
+               rc = -ENODEV;
+               goto fail1;
+       }
+
+       i7core_printk(KERN_INFO,
+                     "Driver loaded, %d memory controller(s) found.\n",
+                     count);
 
        mutex_unlock(&i7core_edac_lock);
        return 0;
index 795cfbc0bf50ff39b3f3911b6596d3353f90d4ef..5bfe6997d9ff73207d6497f3bc15ffc15f9f5795 100644 (file)
@@ -769,8 +769,8 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
        if (amd_filter_mce(m))
                return NOTIFY_STOP;
 
-       pr_emerg(HW_ERR "MC%d_STATUS[%s|%s|%s|%s|%s",
-               m->bank,
+       pr_emerg(HW_ERR "CPU:%d MC%d_STATUS[%s|%s|%s|%s|%s",
+               m->extcpu, m->bank,
                ((m->status & MCI_STATUS_OVER)  ? "Over"  : "-"),
                ((m->status & MCI_STATUS_UC)    ? "UE"    : "CE"),
                ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
index 0de7d8770891e5421a52f7a8732b66e09dd13423..38400963e245f93b74beb056f7e5fa10f2209680 100644 (file)
@@ -205,7 +205,7 @@ static struct platform_driver ppc4xx_edac_driver = {
        .remove                 = ppc4xx_edac_remove,
        .driver = {
                .owner = THIS_MODULE,
-               .name = PPC4XX_EDAC_MODULE_NAME
+               .name = PPC4XX_EDAC_MODULE_NAME,
                .of_match_table = ppc4xx_edac_match,
        },
 };
index 41841a3e3f99c9acd4c4fc72c972626d8dffdcee..17cef864506a7b6778b109dd0d0b570514eab6eb 100644 (file)
@@ -1198,6 +1198,10 @@ static int sbp2_remove(struct device *dev)
 {
        struct fw_unit *unit = fw_unit(dev);
        struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
+       struct sbp2_logical_unit *lu;
+
+       list_for_each_entry(lu, &tgt->lu_list, link)
+               cancel_delayed_work_sync(&lu->work);
 
        sbp2_target_put(tgt);
        return 0;
index eb80b549ed8d17dc0d46a0d6d85a9ccbee0a25d0..be8bcb035e2a31752ef2e2ddb4361dab5a919a5b 100644 (file)
@@ -978,7 +978,7 @@ int register_efivars(struct efivars *efivars,
        if (efivars->efi_pstore_info.buf) {
                efivars->efi_pstore_info.bufsize = 1024;
                efivars->efi_pstore_info.data = efivars;
-               mutex_init(&efivars->efi_pstore_info.buf_mutex);
+               spin_lock_init(&efivars->efi_pstore_info.buf_lock);
                pstore_register(&efivars->efi_pstore_info);
        }
 
index 68810fd1a59d057da2625e57efd55313523eeadd..aa83de9db1b91ce380ed86ca9e6f4a421491095a 100644 (file)
@@ -420,7 +420,7 @@ static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
 
 static efi_status_t gsmi_set_variable(efi_char16_t *name,
                                      efi_guid_t *vendor,
-                                     unsigned long attr,
+                                     u32 attr,
                                      unsigned long data_size,
                                      void *data)
 {
index 9588948c96f08b2e8487b6333d7151fd1e914267..84bc7389e367a1625cf1069d7d64a2ac09dee491 100644 (file)
@@ -14,11 +14,14 @@ obj-$(CONFIG_GPIO_ADP5588)  += gpio-adp5588.o
 obj-$(CONFIG_GPIO_BT8XX)       += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CS5535)      += gpio-cs5535.o
 obj-$(CONFIG_GPIO_DA9052)      += gpio-da9052.o
+obj-$(CONFIG_ARCH_DAVINCI)     += gpio-davinci.o
 obj-$(CONFIG_GPIO_EP93XX)      += gpio-ep93xx.o
 obj-$(CONFIG_GPIO_EXYNOS4)     += gpio-exynos4.o
 obj-$(CONFIG_GPIO_IT8761E)     += gpio-it8761e.o
 obj-$(CONFIG_GPIO_JANZ_TTL)    += gpio-janz-ttl.o
+obj-$(CONFIG_MACH_KS8695)      += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)    += gpio-langwell.o
+obj-$(CONFIG_ARCH_LPC32XX)     += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_MAX730X)     += gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300)     += gpio-max7300.o
 obj-$(CONFIG_GPIO_MAX7301)     += gpio-max7301.o
@@ -42,13 +45,14 @@ obj-$(CONFIG_GPIO_RDC321X)  += gpio-rdc321x.o
 obj-$(CONFIG_GPIO_PLAT_SAMSUNG)        += gpio-plat-samsung.o
 obj-$(CONFIG_GPIO_S5PC100)     += gpio-s5pc100.o
 obj-$(CONFIG_GPIO_S5PV210)     += gpio-s5pv210.o
-
+obj-$(CONFIG_ARCH_SA1100)      += gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)         += gpio-sch.o
 obj-$(CONFIG_GPIO_STMPE)       += gpio-stmpe.o
 obj-$(CONFIG_GPIO_SX150X)      += gpio-sx150x.o
 obj-$(CONFIG_GPIO_TC3589X)     += gpio-tc3589x.o
 obj-$(CONFIG_ARCH_TEGRA)       += gpio-tegra.o
 obj-$(CONFIG_GPIO_TIMBERDALE)  += gpio-timberdale.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
 obj-$(CONFIG_GPIO_TPS65910)    += gpio-tps65910.o
 obj-$(CONFIG_GPIO_TPS65912)    += gpio-tps65912.o
 obj-$(CONFIG_GPIO_TWL4030)     += gpio-twl4030.o
similarity index 99%
rename from arch/arm/mach-davinci/gpio.c
rename to drivers/gpio/gpio-davinci.c
index cafbe13a82a5c5bc56e24bf60fd37fae1d324c4c..a8066e8edadeadcc918c6de59cb3bdbfc2078027 100644 (file)
@@ -9,15 +9,13 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-
+#include <linux/gpio.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
 
-#include <mach/gpio.h>
-
 #include <asm/mach/irq.h>
 
 struct davinci_gpio_regs {
index 72fb9c665320804b43c7e9bff8bcd663fdc2ba74..fbd6a606677799645d463ce1b0d77684b25ddaa6 100644 (file)
@@ -307,6 +307,21 @@ static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
        return 0;
 }
 
+/*
+ * Map GPIO A0..A7  (0..7)  to irq 64..71,
+ *          B0..B7  (7..15) to irq 72..79, and
+ *          F0..F7 (16..24) to irq 80..87.
+ */
+static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       int gpio = chip->base + offset;
+
+       if (gpio > EP93XX_GPIO_LINE_MAX_IRQ)
+               return -EINVAL;
+
+       return 64 + gpio;
+}
+
 static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
        void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
 {
@@ -321,8 +336,10 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
        bgc->gc.label = bank->label;
        bgc->gc.base = bank->base;
 
-       if (bank->has_debounce)
+       if (bank->has_debounce) {
                bgc->gc.set_debounce = ep93xx_gpio_set_debounce;
+               bgc->gc.to_irq = ep93xx_gpio_to_irq;
+       }
 
        return gpiochip_add(&bgc->gc);
 }
similarity index 99%
rename from arch/arm/mach-ks8695/gpio.c
rename to drivers/gpio/gpio-ks8695.c
index 31e456508a6f4d83adbf06d256216a717dd1b96c..a3ac66ea364b8cce3f624b9000d4e5c53e906c1b 100644 (file)
@@ -18,7 +18,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
@@ -31,7 +31,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/regs-gpio.h>
-#include <mach/gpio.h>
+#include <mach/gpio-ks8695.h>
 
 /*
  * Configure a GPIO line for either GPIO function, or its internal
similarity index 99%
rename from arch/arm/mach-lpc32xx/gpiolib.c
rename to drivers/gpio/gpio-lpc32xx.c
index 69061ea8997afee70dafdd260c37b1ba49851559..5b6948081f8fb3d953d5f95703ed6dac95f9e23d 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include "common.h"
+#include <mach/gpio-lpc32xx.h>
 
 #define LPC32XX_GPIO_P3_INP_STATE              _GPREG(0x000)
 #define LPC32XX_GPIO_P3_OUTP_SET               _GPREG(0x004)
index 2c212c732d76e5e0996fb90a354f33e383ab7297..740caed2b278bc4defd03dccb5444885ec6804d2 100644 (file)
@@ -27,8 +27,9 @@
 #include <asm/mach/irq.h>
 
 #include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
 #include <mach/hardware.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 /*
  * The GPIO module in the Nomadik family of Systems-on-Chip is an
index 0599854e22171449ed214366140313b4ac38e152..9c27244fd680ecf06e9e3309e983a8810c83baae 100644 (file)
@@ -25,7 +25,7 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <asm/mach/irq.h>
 
 struct gpio_bank {
similarity index 96%
rename from arch/arm/mach-sa1100/gpio.c
rename to drivers/gpio/gpio-sa1100.c
index 0d3829a8c2c1df94cd2e8ceb3ef8aa751291a336..b6c1f6d80649a93145daef13d6fcfd042fe20e47 100644 (file)
@@ -7,13 +7,11 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
 
-#include <asm/gpio.h>
 #include <mach/hardware.h>
-#include "generic.h"
 
 static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
index 53e8255cb0bac91dd5562a0c15336257229d015a..92f2b8c06de11e4953de02e38245c5c144eff13b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <mach/gpio-u300.h>
 
 /* Reference to GPIO block clock */
 static struct clk *clk;
index 7f65940f918f9a093002eb68e5b2c2f22722a486..4f0c1ecac72e07ed1138cf8fe59d67e4472050f7 100644 (file)
@@ -466,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
                    (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
                        return true;
        }
+       /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100
+        * (RS690M) sends data to i2c bus for a HDMI connector that
+        * is not implemented */
+       if ((dev->pdev->device == 0x791f) &&
+           (dev->pdev->subsystem_vendor == 0x1179) &&
+           (dev->pdev->subsystem_device == 0xff68)) {
+               if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
+                   (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
+                       return true;
+       }
 
        /* Default: no EDID header probe required for DDC probing */
        return false;
index a3b011b494650fcd2786f0db4be6da79952c3491..b51e15725c6e45321b088664749a48101e79be28 100644 (file)
@@ -301,6 +301,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64
                mc->mc_vram_size = mc->aper_size;
        }
        mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
+       if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size)
+               mc->real_vram_size = radeon_vram_limit;
        dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
                        mc->mc_vram_size >> 20, mc->vram_start,
                        mc->vram_end, mc->real_vram_size >> 20);
index dee4a0c1b4b2f9e473cc59f1766ffb0e2121ba5f..602fa3541c454f8ac2c058cb5832520fad95612f 100644 (file)
@@ -40,10 +40,14 @@ void radeon_test_moves(struct radeon_device *rdev)
        size = 1024 * 1024;
 
        /* Number of tests =
-        * (Total GTT - IB pool - writeback page - ring buffer) / test size
+        * (Total GTT - IB pool - writeback page - ring buffers) / test size
         */
-       n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE -
-            rdev->cp.ring_size)) / size;
+       n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - rdev->cp.ring_size;
+       if (rdev->wb.wb_obj)
+               n -= RADEON_GPU_PAGE_SIZE;
+       if (rdev->ih.ring_obj)
+               n -= rdev->ih.ring_size;
+       n /= size;
 
        gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
        if (!gtt_obj) {
@@ -132,9 +136,15 @@ void radeon_test_moves(struct radeon_device *rdev)
                     gtt_start++, vram_start++) {
                        if (*vram_start != gtt_start) {
                                DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
-                                         "expected 0x%p (GTT map 0x%p-0x%p)\n",
-                                         i, *vram_start, gtt_start, gtt_map,
-                                         gtt_end);
+                                         "expected 0x%p (GTT/VRAM offset "
+                                         "0x%16llx/0x%16llx)\n",
+                                         i, *vram_start, gtt_start,
+                                         (unsigned long long)
+                                         (gtt_addr - rdev->mc.gtt_start +
+                                          (void*)gtt_start - gtt_map),
+                                         (unsigned long long)
+                                         (vram_addr - rdev->mc.vram_start +
+                                          (void*)gtt_start - gtt_map));
                                radeon_bo_kunmap(vram_obj);
                                goto out_cleanup;
                        }
@@ -175,9 +185,15 @@ void radeon_test_moves(struct radeon_device *rdev)
                     gtt_start++, vram_start++) {
                        if (*gtt_start != vram_start) {
                                DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
-                                         "expected 0x%p (VRAM map 0x%p-0x%p)\n",
-                                         i, *gtt_start, vram_start, vram_map,
-                                         vram_end);
+                                         "expected 0x%p (VRAM/GTT offset "
+                                         "0x%16llx/0x%16llx)\n",
+                                         i, *gtt_start, vram_start,
+                                         (unsigned long long)
+                                         (vram_addr - rdev->mc.vram_start +
+                                          (void*)vram_start - vram_map),
+                                         (unsigned long long)
+                                         (gtt_addr - rdev->mc.gtt_start +
+                                          (void*)vram_start - vram_map));
                                radeon_bo_kunmap(gtt_obj[i]);
                                goto out_cleanup;
                        }
index 60125ddba1e93551c41376a3e10e27a72519271e..9b86fb0e4122037056a3d5075ae5a5d1c8663874 100644 (file)
@@ -450,6 +450,29 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_
                        return -EINVAL;
                mem->bus.base = rdev->mc.aper_base;
                mem->bus.is_iomem = true;
+#ifdef __alpha__
+               /*
+                * Alpha: use bus.addr to hold the ioremap() return,
+                * so we can modify bus.base below.
+                */
+               if (mem->placement & TTM_PL_FLAG_WC)
+                       mem->bus.addr =
+                               ioremap_wc(mem->bus.base + mem->bus.offset,
+                                          mem->bus.size);
+               else
+                       mem->bus.addr =
+                               ioremap_nocache(mem->bus.base + mem->bus.offset,
+                                               mem->bus.size);
+
+               /*
+                * Alpha: Use just the bus offset plus
+                * the hose/domain memory base for bus.base.
+                * It then can be used to build PTEs for VRAM
+                * access, as done in ttm_bo_vm_fault().
+                */
+               mem->bus.base = (mem->bus.base & 0x0ffffffffUL) +
+                       rdev->ddev->hose->dense_mem_base;
+#endif
                break;
        default:
                return -EINVAL;
index 56619f64b6bfa004c9b1900ac3dd36328593a6cf..a4d38d85909a0254e23fa3a1f0b607814329bf60 100644 (file)
@@ -353,8 +353,10 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
 
                ret = ttm_tt_set_user(bo->ttm, current,
                                      bo->buffer_start, bo->num_pages);
-               if (unlikely(ret != 0))
+               if (unlikely(ret != 0)) {
                        ttm_tt_destroy(bo->ttm);
+                       bo->ttm = NULL;
+               }
                break;
        default:
                printk(KERN_ERR TTM_PFX "Illegal buffer object type\n");
@@ -390,10 +392,12 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
         * Create and bind a ttm if required.
         */
 
-       if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) {
-               ret = ttm_bo_add_ttm(bo, false);
-               if (ret)
-                       goto out_err;
+       if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
+               if (bo->ttm == NULL) {
+                       ret = ttm_bo_add_ttm(bo, false);
+                       if (ret)
+                               goto out_err;
+               }
 
                ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
                if (ret)
index 77dbf408c0d01d86e2fe27a5d3cbc836d17ab46c..ae3c6f5dd2b71acee36f863deafc3896a874010e 100644 (file)
@@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
                if (ret)
                        return ret;
 
-               ttm_bo_free_old_node(bo);
                if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
                    (bo->ttm != NULL)) {
                        ttm_tt_unbind(bo->ttm);
                        ttm_tt_destroy(bo->ttm);
                        bo->ttm = NULL;
                }
+               ttm_bo_free_old_node(bo);
        } else {
                /**
                 * This should help pipeline ordinary buffer moves.
index 306b15f39c9c12a8e717699c0d1c25fe396aa714..2703c9cc98f581f23843c2192bb784e677863a14 100644 (file)
@@ -69,7 +69,7 @@ config HID_ACRUX
        Say Y here if you want to enable support for ACRUX game controllers.
 
 config HID_ACRUX_FF
-       tristate "ACRUX force feedback support"
+       bool "ACRUX force feedback support"
        depends on HID_ACRUX
        select INPUT_FF_MEMLESS
        ---help---
@@ -278,13 +278,21 @@ config LOGIG940_FF
          Say Y here if you want to enable force feedback support for Logitech
          Flight System G940 devices.
 
-config LOGIWII_FF
-       bool "Logitech Speed Force Wireless force feedback support"
+config LOGIWHEELS_FF
+       bool "Logitech wheels configuration and force feedback support"
        depends on HID_LOGITECH
        select INPUT_FF_MEMLESS
+       default LOGITECH_FF
        help
-         Say Y here if you want to enable force feedback support for Logitech
-         Speed Force Wireless (Wii) devices.
+         Say Y here if you want to enable force feedback and range setting
+         support for following Logitech wheels:
+         - Logitech Driving Force
+         - Logitech Driving Force Pro
+         - Logitech Driving Force GT
+         - Logitech G25
+         - Logitech G27
+         - Logitech MOMO/MOMO 2
+         - Logitech Formula Force EX
 
 config HID_MAGICMOUSE
        tristate "Apple MagicMouse multi-touch support"
@@ -328,6 +336,7 @@ config HID_MULTITOUCH
          - Hanvon dual touch panels
          - Ilitek dual touch panels
          - IrTouch Infrared USB panels
+         - LG Display panels (Dell ST2220Tc)
          - Lumio CrystalTouch panels
          - MosArt dual-touch panels
          - PenMount dual touch panels
index 0a0a38e9fd28477d1bae9a2a778bcf889d4289ba..77c9e5d7ff97186802a643fedd8017d1006d90cd 100644 (file)
@@ -21,7 +21,7 @@ endif
 ifdef CONFIG_LOGIG940_FF
        hid-logitech-y  += hid-lg3ff.o
 endif
-ifdef CONFIG_LOGIWII_FF
+ifdef CONFIG_LOGIWHEELS_FF
        hid-logitech-y  += hid-lg4ff.o
 endif
 
index b85744fe846477221ad02221f78bb397c603f54d..8bfd87b59c47b62c64a66473e834971426d7889e 100644 (file)
@@ -183,6 +183,9 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
                                hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
                        table = macbookair_fn_keys;
+               else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI &&
+                               hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS)
+                       table = macbookair_fn_keys;
                else if (hid->product < 0x21d || hid->product >= 0x300)
                        table = powerbook_fn_keys;
                else
@@ -487,6 +490,12 @@ static const struct hid_device_id apple_devices[] = {
                .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
                .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
+               .driver_data = APPLE_HAS_FN },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
+               .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
index 121514149e0b4fd5f5332b8dee252436b8c784f7..3bdb4500f95eea6bc7f8b901cc460d3d881ae2b5 100644 (file)
@@ -6,7 +6,7 @@
  * Xbox 360 controller.
  *
  * 1a34:0802 "ACRUX USB GAMEPAD 8116"
- *  - tested with a EXEQ EQ-PCU-02090 game controller.
+ *  - tested with an EXEQ EQ-PCU-02090 game controller.
  *
  * Copyright (c) 2010 Sergei Kolzun <x0r@dv-life.ru>
  */
@@ -45,7 +45,10 @@ static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct axff_device *axff = data;
+       struct hid_report *report = axff->report;
+       int field_count = 0;
        int left, right;
+       int i, j;
 
        left = effect->u.rumble.strong_magnitude;
        right = effect->u.rumble.weak_magnitude;
@@ -55,10 +58,14 @@ static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect
        left = left * 0xff / 0xffff;
        right = right * 0xff / 0xffff;
 
-       axff->report->field[0]->value[0] = left;
-       axff->report->field[1]->value[0] = right;
-       axff->report->field[2]->value[0] = left;
-       axff->report->field[3]->value[0] = right;
+       for (i = 0; i < report->maxfield; i++) {
+               for (j = 0; j < report->field[i]->report_count; j++) {
+                       report->field[i]->value[j] =
+                               field_count % 2 ? right : left;
+                       field_count++;
+               }
+       }
+
        dbg_hid("running with 0x%02x 0x%02x", left, right);
        usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
 
@@ -72,6 +79,8 @@ static int axff_init(struct hid_device *hid)
        struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
        struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list;
        struct input_dev *dev = hidinput->input;
+       int field_count = 0;
+       int i, j;
        int error;
 
        if (list_empty(report_list)) {
@@ -80,9 +89,16 @@ static int axff_init(struct hid_device *hid)
        }
 
        report = list_first_entry(report_list, struct hid_report, list);
+       for (i = 0; i < report->maxfield; i++) {
+               for (j = 0; j < report->field[i]->report_count; j++) {
+                       report->field[i]->value[j] = 0x00;
+                       field_count++;
+               }
+       }
 
-       if (report->maxfield < 4) {
-               hid_err(hid, "no fields in the report: %d\n", report->maxfield);
+       if (field_count < 4) {
+               hid_err(hid, "not enough fields in the report: %d\n",
+                       field_count);
                return -ENODEV;
        }
 
@@ -97,13 +113,9 @@ static int axff_init(struct hid_device *hid)
                goto err_free_mem;
 
        axff->report = report;
-       axff->report->field[0]->value[0] = 0x00;
-       axff->report->field[1]->value[0] = 0x00;
-       axff->report->field[2]->value[0] = 0x00;
-       axff->report->field[3]->value[0] = 0x00;
        usbhid_submit_report(hid, axff->report, USB_DIR_OUT);
 
-       hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun<x0r@dv-life.ru>\n");
+       hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun <x0r@dv-life.ru>\n");
 
        return 0;
 
index 1a5cf0c9cfcade20b35386e183f36a69155f5a7a..582be00a44225d78f9b55d3b7381ba13d7a94fc4 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/wait.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
+#include <linux/semaphore.h>
 
 #include <linux/hid.h>
 #include <linux/hiddev.h>
@@ -1085,16 +1086,25 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
        struct hid_report *report;
        char *buf;
        unsigned int i;
-       int ret;
+       int ret = 0;
 
-       if (!hid || !hid->driver)
+       if (!hid)
                return -ENODEV;
+
+       if (down_trylock(&hid->driver_lock))
+               return -EBUSY;
+
+       if (!hid->driver) {
+               ret = -ENODEV;
+               goto unlock;
+       }
        report_enum = hid->report_enum + type;
        hdrv = hid->driver;
 
        if (!size) {
                dbg_hid("empty report\n");
-               return -1;
+               ret = -1;
+               goto unlock;
        }
 
        buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
@@ -1118,18 +1128,24 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
 nomem:
        report = hid_get_report(report_enum, data);
 
-       if (!report)
-               return -1;
+       if (!report) {
+               ret = -1;
+               goto unlock;
+       }
 
        if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
                ret = hdrv->raw_event(hid, report, data, size);
-               if (ret != 0)
-                       return ret < 0 ? ret : 0;
+               if (ret != 0) {
+                       ret = ret < 0 ? ret : 0;
+                       goto unlock;
+               }
        }
 
        hid_report_raw_event(hid, type, data, size, interrupt);
 
-       return 0;
+unlock:
+       up(&hid->driver_lock);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(hid_input_report);
 
@@ -1340,6 +1356,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
@@ -1396,6 +1415,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
@@ -1498,6 +1518,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
@@ -1617,6 +1638,9 @@ static int hid_device_probe(struct device *dev)
        const struct hid_device_id *id;
        int ret = 0;
 
+       if (down_interruptible(&hdev->driver_lock))
+               return -EINTR;
+
        if (!hdev->driver) {
                id = hid_match_device(hdev, hdrv);
                if (id == NULL)
@@ -1633,14 +1657,20 @@ static int hid_device_probe(struct device *dev)
                if (ret)
                        hdev->driver = NULL;
        }
+
+       up(&hdev->driver_lock);
        return ret;
 }
 
 static int hid_device_remove(struct device *dev)
 {
        struct hid_device *hdev = container_of(dev, struct hid_device, dev);
-       struct hid_driver *hdrv = hdev->driver;
+       struct hid_driver *hdrv;
+
+       if (down_interruptible(&hdev->driver_lock))
+               return -EINTR;
 
+       hdrv = hdev->driver;
        if (hdrv) {
                if (hdrv->remove)
                        hdrv->remove(hdev);
@@ -1649,6 +1679,7 @@ static int hid_device_remove(struct device *dev)
                hdev->driver = NULL;
        }
 
+       up(&hdev->driver_lock);
        return 0;
 }
 
@@ -1996,6 +2027,7 @@ struct hid_device *hid_allocate_device(void)
 
        init_waitqueue_head(&hdev->debug_wait);
        INIT_LIST_HEAD(&hdev->debug_list);
+       sema_init(&hdev->driver_lock, 1);
 
        return hdev;
 err:
index bae48745bb4281da2d77ee429882fa52093e60e2..9a243ca96e6db8fbb754b34e16e8c508ee289eab 100644 (file)
@@ -450,6 +450,11 @@ void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
                seq_printf(f, "Logical(");
                hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
        }
+       if (field->application) {
+               tab(n, f);
+               seq_printf(f, "Application(");
+               hid_resolv_usage(field->application, f); seq_printf(f, ")\n");
+       }
        tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
        for (j = 0; j < field->maxusage; j++) {
                tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
index db63ccf21cc867b3d6392c994d241ba7f0585a85..171ea8e810df6c6f9cd65a300e69e6b962abf2b3 100644 (file)
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI   0x0245
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO    0x0246
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS    0x0247
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI   0x024c
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO    0x024d
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS    0x024e
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI  0x0239
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO   0x023a
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS   0x023b
 #define USB_DEVICE_ID_LD_HYBRID                0x2090
 #define USB_DEVICE_ID_LD_HEATCONTROL   0x20A0
 
+#define USB_VENDOR_ID_LG               0x1fd2
+#define USB_DEVICE_ID_LG_MULTITOUCH    0x0064
+
 #define USB_VENDOR_ID_LOGITECH         0x046d
 #define USB_DEVICE_ID_LOGITECH_RECEIVER        0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL      0xc295
 #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL       0xc298
 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL       0xc299
+#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL      0xc29a
 #define USB_DEVICE_ID_LOGITECH_G27_WHEEL       0xc29b
 #define USB_DEVICE_ID_LOGITECH_WII_WHEEL       0xc29c
 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD       0xc30a
index a7f916e8fc3256bc6fcbdc68210bc8e92e1630db..e7a7bd1eb34a55c9f200d92d983148ea6e317a70 100644 (file)
@@ -363,7 +363,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       if (quirks & (LG_FF | LG_FF2 | LG_FF3))
+       if (quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
                connect_mask &= ~HID_CONNECT_FF;
 
        ret = hid_hw_start(hdev, connect_mask);
@@ -372,7 +372,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
                goto err_free;
        }
 
-       if (quirks & LG_FF4) {
+       /* Setup wireless link with Logitech Wii wheel */
+       if(hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
                unsigned char buf[] = { 0x00, 0xAF,  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
                ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
@@ -405,6 +406,15 @@ err_free:
        return ret;
 }
 
+static void lg_remove(struct hid_device *hdev)
+{
+       unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+       if(quirks & LG_FF4)
+               lg4ff_deinit(hdev);
+
+       hid_hw_stop(hdev);
+}
+
 static const struct hid_device_id lg_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
                .driver_data = LG_RDESC | LG_WIRELESS },
@@ -431,7 +441,7 @@ static const struct hid_device_id lg_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D),
                .driver_data = LG_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
-               .driver_data = LG_NOGET | LG_FF },
+               .driver_data = LG_NOGET | LG_FF4 },
 
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
                .driver_data = LG_FF2 },
@@ -444,15 +454,17 @@ static const struct hid_device_id lg_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO),
                .driver_data = LG_FF },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL),
-               .driver_data = LG_FF },
+               .driver_data = LG_FF4 },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
-               .driver_data = LG_FF },
+               .driver_data = LG_FF4 },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
-               .driver_data = LG_FF },
+               .driver_data = LG_FF4 },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
+               .driver_data = LG_FF4 },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
-               .driver_data = LG_FF },
+               .driver_data = LG_FF4 },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
-               .driver_data = LG_NOGET | LG_FF },
+               .driver_data = LG_NOGET | LG_FF4 },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
                .driver_data = LG_FF4 },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
@@ -478,6 +490,7 @@ static struct hid_driver lg_driver = {
        .input_mapped = lg_input_mapped,
        .event = lg_event,
        .probe = lg_probe,
+       .remove = lg_remove,
 };
 
 static int __init lg_init(void)
index b0100ba2ae0b2f8b16b4f84b64e2f40fea7f40b6..4b097286dc789ab009b1df11630954d0f4d9631f 100644 (file)
@@ -19,10 +19,12 @@ int lg3ff_init(struct hid_device *hdev);
 static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
 #endif
 
-#ifdef CONFIG_LOGIWII_FF
+#ifdef CONFIG_LOGIWHEELS_FF
 int lg4ff_init(struct hid_device *hdev);
+int lg4ff_deinit(struct hid_device *hdev);
 #else
 static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
+static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; }
 #endif
 
 #endif
index fa550c8e1d1bc639bd3e9c34a299903391bca44a..dc38c2d89df1eb2614fa87efac3cdcaffda6c761 100644 (file)
 
 #include "usbhid/usbhid.h"
 #include "hid-lg.h"
+#include "hid-ids.h"
 
-struct lg4ff_device {
-       struct hid_report *report;
+#define DFGT_REV_MAJ 0x13
+#define DFGT_REV_MIN 0x22
+#define DFP_REV_MAJ 0x11
+#define DFP_REV_MIN 0x06
+#define FFEX_REV_MAJ 0x21
+#define FFEX_REV_MIN 0x00
+#define G25_REV_MAJ 0x12
+#define G25_REV_MIN 0x22
+#define G27_REV_MAJ 0x12
+#define G27_REV_MIN 0x38
+
+#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev)
+
+static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
+static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range);
+static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+
+static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
+
+static bool list_inited;
+
+struct lg4ff_device_entry {
+       char  *device_id;       /* Use name in respective kobject structure's address as the ID */
+       __u16 range;
+       __u16 min_range;
+       __u16 max_range;
+       __u8  leds;
+       struct list_head list;
+       void (*set_range)(struct hid_device *hid, u16 range);
 };
 
-static const signed short ff4_wheel_ac[] = {
+static struct lg4ff_device_entry device_list;
+
+static const signed short lg4ff_wheel_effects[] = {
        FF_CONSTANT,
        FF_AUTOCENTER,
        -1
 };
 
-static int hid_lg4ff_play(struct input_dev *dev, void *data,
-                        struct ff_effect *effect)
+struct lg4ff_wheel {
+       const __u32 product_id;
+       const signed short *ff_effects;
+       const __u16 min_range;
+       const __u16 max_range;
+       void (*set_range)(struct hid_device *hid, u16 range);
+};
+
+static const struct lg4ff_wheel lg4ff_devices[] = {
+       {USB_DEVICE_ID_LOGITECH_WHEEL,       lg4ff_wheel_effects, 40, 270, NULL},
+       {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL,  lg4ff_wheel_effects, 40, 270, NULL},
+       {USB_DEVICE_ID_LOGITECH_DFP_WHEEL,   lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_dfp},
+       {USB_DEVICE_ID_LOGITECH_G25_WHEEL,   lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_g25},
+       {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL,  lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_g25},
+       {USB_DEVICE_ID_LOGITECH_G27_WHEEL,   lg4ff_wheel_effects, 40, 900, hid_lg4ff_set_range_g25},
+       {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
+       {USB_DEVICE_ID_LOGITECH_WII_WHEEL,   lg4ff_wheel_effects, 40, 270, NULL}
+};
+
+struct lg4ff_native_cmd {
+       const __u8 cmd_num;     /* Number of commands to send */
+       const __u8 cmd[];
+};
+
+struct lg4ff_usb_revision {
+       const __u16 rev_maj;
+       const __u16 rev_min;
+       const struct lg4ff_native_cmd *command;
+};
+
+static const struct lg4ff_native_cmd native_dfp = {
+       1,
+       {0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static const struct lg4ff_native_cmd native_dfgt = {
+       2,
+       {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,      /* 1st command */
+        0xf8, 0x09, 0x03, 0x01, 0x00, 0x00, 0x00}      /* 2nd command */
+};
+
+static const struct lg4ff_native_cmd native_g25 = {
+       1,
+       {0xf8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static const struct lg4ff_native_cmd native_g27 = {
+       2,
+       {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,      /* 1st command */
+        0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00}      /* 2nd command */
+};
+
+static const struct lg4ff_usb_revision lg4ff_revs[] = {
+       {DFGT_REV_MAJ, DFGT_REV_MIN, &native_dfgt},     /* Driving Force GT */
+       {DFP_REV_MAJ,  DFP_REV_MIN,  &native_dfp},      /* Driving Force Pro */
+       {G25_REV_MAJ,  G25_REV_MIN,  &native_g25},      /* G25 */
+       {G27_REV_MAJ,  G27_REV_MIN,  &native_g27},      /* G27 */
+};
+
+static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
@@ -55,13 +144,12 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data,
                x = effect->u.ramp.start_level + 0x80;  /* 0x80 is no force */
                CLAMP(x);
                report->field[0]->value[0] = 0x11;      /* Slot 1 */
-               report->field[0]->value[1] = 0x10;
+               report->field[0]->value[1] = 0x08;
                report->field[0]->value[2] = x;
-               report->field[0]->value[3] = 0x00;
+               report->field[0]->value[3] = 0x80;
                report->field[0]->value[4] = 0x00;
-               report->field[0]->value[5] = 0x08;
+               report->field[0]->value[5] = 0x00;
                report->field[0]->value[6] = 0x00;
-               dbg_hid("Autocenter, x=0x%02X\n", x);
 
                usbhid_submit_report(hid, report, USB_DIR_OUT);
                break;
@@ -69,24 +157,184 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data,
        return 0;
 }
 
-static void hid_lg4ff_set_autocenter(struct input_dev *dev, u16 magnitude)
+/* Sends default autocentering command compatible with
+ * all wheels except Formula Force EX */
+static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitude)
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
        struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
-       __s32 *value = report->field[0]->value;
 
-       *value++ = 0xfe;
-       *value++ = 0x0d;
-       *value++ = 0x07;
-       *value++ = 0x07;
-       *value++ = (magnitude >> 8) & 0xff;
-       *value++ = 0x00;
-       *value = 0x00;
+       report->field[0]->value[0] = 0xfe;
+       report->field[0]->value[1] = 0x0d;
+       report->field[0]->value[2] = magnitude >> 13;
+       report->field[0]->value[3] = magnitude >> 13;
+       report->field[0]->value[4] = magnitude >> 8;
+       report->field[0]->value[5] = 0x00;
+       report->field[0]->value[6] = 0x00;
+
+       usbhid_submit_report(hid, report, USB_DIR_OUT);
+}
+
+/* Sends autocentering command compatible with Formula Force EX */
+static void hid_lg4ff_set_autocenter_ffex(struct input_dev *dev, u16 magnitude)
+{
+       struct hid_device *hid = input_get_drvdata(dev);
+       struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+       magnitude = magnitude * 90 / 65535;
+       
+
+       report->field[0]->value[0] = 0xfe;
+       report->field[0]->value[1] = 0x03;
+       report->field[0]->value[2] = magnitude >> 14;
+       report->field[0]->value[3] = magnitude >> 14;
+       report->field[0]->value[4] = magnitude;
+       report->field[0]->value[5] = 0x00;
+       report->field[0]->value[6] = 0x00;
+
+       usbhid_submit_report(hid, report, USB_DIR_OUT);
+}
+
+/* Sends command to set range compatible with G25/G27/Driving Force GT */
+static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range)
+{
+       struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+       dbg_hid("G25/G27/DFGT: setting range to %u\n", range);
+
+       report->field[0]->value[0] = 0xf8;
+       report->field[0]->value[1] = 0x81;
+       report->field[0]->value[2] = range & 0x00ff;
+       report->field[0]->value[3] = (range & 0xff00) >> 8;
+       report->field[0]->value[4] = 0x00;
+       report->field[0]->value[5] = 0x00;
+       report->field[0]->value[6] = 0x00;
+
+       usbhid_submit_report(hid, report, USB_DIR_OUT);
+}
+
+/* Sends commands to set range compatible with Driving Force Pro wheel */
+static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range)
+{
+       struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+       int start_left, start_right, full_range;
+       dbg_hid("Driving Force Pro: setting range to %u\n", range);
+
+       /* Prepare "coarse" limit command */
+       report->field[0]->value[0] = 0xf8;
+       report->field[0]->value[1] = 0x00;      /* Set later */
+       report->field[0]->value[2] = 0x00;
+       report->field[0]->value[3] = 0x00;
+       report->field[0]->value[4] = 0x00;
+       report->field[0]->value[5] = 0x00;
+       report->field[0]->value[6] = 0x00;
+
+       if (range > 200) {
+               report->field[0]->value[1] = 0x03;
+               full_range = 900;
+       } else {
+               report->field[0]->value[1] = 0x02;
+               full_range = 200;
+       }
+       usbhid_submit_report(hid, report, USB_DIR_OUT);
+
+       /* Prepare "fine" limit command */
+       report->field[0]->value[0] = 0x81;
+       report->field[0]->value[1] = 0x0b;
+       report->field[0]->value[2] = 0x00;
+       report->field[0]->value[3] = 0x00;
+       report->field[0]->value[4] = 0x00;
+       report->field[0]->value[5] = 0x00;
+       report->field[0]->value[6] = 0x00;
+
+       if (range == 200 || range == 900) {     /* Do not apply any fine limit */
+               usbhid_submit_report(hid, report, USB_DIR_OUT);
+               return;
+       }
+
+       /* Construct fine limit command */
+       start_left = (((full_range - range + 1) * 2047) / full_range);
+       start_right = 0xfff - start_left;
+
+       report->field[0]->value[2] = start_left >> 4;
+       report->field[0]->value[3] = start_right >> 4;
+       report->field[0]->value[4] = 0xff;
+       report->field[0]->value[5] = (start_right & 0xe) << 4 | (start_left & 0xe);
+       report->field[0]->value[6] = 0xff;
 
        usbhid_submit_report(hid, report, USB_DIR_OUT);
 }
 
+static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd)
+{
+       struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
+       __u8 i, j;
+
+       j = 0;
+       while (j < 7*cmd->cmd_num) {
+               for (i = 0; i < 7; i++)
+                       report->field[0]->value[i] = cmd->cmd[j++];
+
+               usbhid_submit_report(hid, report, USB_DIR_OUT);
+       }
+}
+
+/* Read current range and display it in terminal */
+static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct lg4ff_device_entry *entry = 0;
+       struct list_head *h;
+       struct hid_device *hid = to_hid_device(dev);
+       size_t count;
+
+       list_for_each(h, &device_list.list) {
+               entry = list_entry(h, struct lg4ff_device_entry, list);
+               if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
+                       break;
+       }
+       if (h == &device_list.list) {
+               dbg_hid("Device not found!");
+               return 0;
+       }
+
+       count = scnprintf(buf, PAGE_SIZE, "%u\n", entry->range);
+       return count;
+}
+
+/* Set range to user specified value, call appropriate function
+ * according to the type of the wheel */
+static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct lg4ff_device_entry *entry = 0;
+       struct list_head *h;
+       struct hid_device *hid = to_hid_device(dev);
+       __u16 range = simple_strtoul(buf, NULL, 10);
+
+       list_for_each(h, &device_list.list) {
+               entry = list_entry(h, struct lg4ff_device_entry, list);
+               if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
+                       break;
+       }
+       if (h == &device_list.list) {
+               dbg_hid("Device not found!");
+               return count;
+       }
+
+       if (range == 0)
+               range = entry->max_range;
+
+       /* Check if the wheel supports range setting
+        * and that the range is within limits for the wheel */
+       if (entry->set_range != NULL && range >= entry->min_range && range <= entry->max_range) {
+               entry->set_range(hid, range);
+               entry->range = range;
+       }
+
+       return count;
+}
 
 int lg4ff_init(struct hid_device *hid)
 {
@@ -95,9 +343,10 @@ int lg4ff_init(struct hid_device *hid)
        struct input_dev *dev = hidinput->input;
        struct hid_report *report;
        struct hid_field *field;
-       const signed short *ff_bits = ff4_wheel_ac;
-       int error;
-       int i;
+       struct lg4ff_device_entry *entry;
+       struct usb_device_descriptor *udesc;
+       int error, i, j;
+       __u16 bcdDevice, rev_maj, rev_min;
 
        /* Find the report to use */
        if (list_empty(report_list)) {
@@ -118,18 +367,122 @@ int lg4ff_init(struct hid_device *hid)
                return -1;
        }
 
-       for (i = 0; ff_bits[i] >= 0; i++)
-               set_bit(ff_bits[i], dev->ffbit);
+       /* Check what wheel has been connected */
+       for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) {
+               if (hid->product == lg4ff_devices[i].product_id) {
+                       dbg_hid("Found compatible device, product ID %04X\n", lg4ff_devices[i].product_id);
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(lg4ff_devices)) {
+               hid_err(hid, "Device is not supported by lg4ff driver. If you think it should be, consider reporting a bug to"
+                            "LKML, Simon Wood <simon@mungewell.org> or Michal Maly <madcatxster@gmail.com>\n");
+               return -1;
+       }
+
+       /* Attempt to switch wheel to native mode when applicable */
+       udesc = &(hid_to_usb_dev(hid)->descriptor);
+       if (!udesc) {
+               hid_err(hid, "NULL USB device descriptor\n");
+               return -1;
+       }
+       bcdDevice = le16_to_cpu(udesc->bcdDevice);
+       rev_maj = bcdDevice >> 8;
+       rev_min = bcdDevice & 0xff;
+
+       if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_WHEEL) {
+               dbg_hid("Generic wheel detected, can it do native?\n");
+               dbg_hid("USB revision: %2x.%02x\n", rev_maj, rev_min);
+
+               for (j = 0; j < ARRAY_SIZE(lg4ff_revs); j++) {
+                       if (lg4ff_revs[j].rev_maj == rev_maj && lg4ff_revs[j].rev_min == rev_min) {
+                               hid_lg4ff_switch_native(hid, lg4ff_revs[j].command);
+                               hid_info(hid, "Switched to native mode\n");
+                       }
+               }
+       }
+
+       /* Set supported force feedback capabilities */
+       for (j = 0; lg4ff_devices[i].ff_effects[j] >= 0; j++)
+               set_bit(lg4ff_devices[i].ff_effects[j], dev->ffbit);
 
        error = input_ff_create_memless(dev, NULL, hid_lg4ff_play);
 
        if (error)
                return error;
 
-       if (test_bit(FF_AUTOCENTER, dev->ffbit))
-               dev->ff->set_autocenter = hid_lg4ff_set_autocenter;
+       /* Check if autocentering is available and
+        * set the centering force to zero by default */
+       if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
+               if(rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN)  /* Formula Force EX expects different autocentering command */
+                       dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
+               else
+                       dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
+
+               dev->ff->set_autocenter(dev, 0);
+       }
+
+               /* Initialize device_list if this is the first device to handle by lg4ff */
+       if (!list_inited) {
+               INIT_LIST_HEAD(&device_list.list);
+               list_inited = 1;
+       }
+
+       /* Add the device to device_list */
+       entry = (struct lg4ff_device_entry *)kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL);
+       if (!entry) {
+               hid_err(hid, "Cannot add device, insufficient memory.\n");
+               return -ENOMEM;
+       }
+       entry->device_id = (char *)kzalloc(strlen((&hid->dev)->kobj.name) + 1, GFP_KERNEL);
+       if (!entry->device_id) {
+               hid_err(hid, "Cannot set device_id, insufficient memory.\n");
+               return -ENOMEM;
+       }
+       strcpy(entry->device_id, (&hid->dev)->kobj.name);
+       entry->min_range = lg4ff_devices[i].min_range;
+       entry->max_range = lg4ff_devices[i].max_range;
+       entry->set_range = lg4ff_devices[i].set_range;
+       list_add(&entry->list, &device_list.list);
+
+       /* Create sysfs interface */
+       error = device_create_file(&hid->dev, &dev_attr_range);
+       if (error)
+               return error;
+       dbg_hid("sysfs interface created\n");
+
+       /* Set the maximum range to start with */
+       entry->range = entry->max_range;
+       if (entry->set_range != NULL)
+               entry->set_range(hid, entry->range);
 
        hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood <simon@mungewell.org>\n");
        return 0;
 }
 
+int lg4ff_deinit(struct hid_device *hid)
+{
+       bool found = 0;
+       struct lg4ff_device_entry *entry;
+       struct list_head *h, *g;
+       list_for_each_safe(h, g, &device_list.list) {
+               entry = list_entry(h, struct lg4ff_device_entry, list);
+               if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) {
+                       list_del(h);
+                       kfree(entry->device_id);
+                       kfree(entry);
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (!found) {
+               dbg_hid("Device entry not found!\n");
+               return -1;
+       }
+
+       device_remove_file(&hid->dev, &dev_attr_range);
+       dbg_hid("Device successfully unregistered\n");
+       return 0;
+}
index 088f85049290164a92167dbdda3ef6480f1a3f5e..27bc54f92f4484d7efc0ef687d70082c725b337f 100644 (file)
@@ -58,12 +58,6 @@ static const signed short ff_joystick_ac[] = {
        -1
 };
 
-static const signed short ff_wheel[] = {
-       FF_CONSTANT,
-       FF_AUTOCENTER,
-       -1
-};
-
 static const struct dev_type devices[] = {
        { 0x046d, 0xc211, ff_rumble },
        { 0x046d, 0xc219, ff_rumble },
@@ -71,14 +65,7 @@ static const struct dev_type devices[] = {
        { 0x046d, 0xc286, ff_joystick_ac },
        { 0x046d, 0xc287, ff_joystick_ac },
        { 0x046d, 0xc293, ff_joystick },
-       { 0x046d, 0xc294, ff_wheel },
-       { 0x046d, 0xc298, ff_wheel },
-       { 0x046d, 0xc299, ff_wheel },
-       { 0x046d, 0xc29b, ff_wheel },
        { 0x046d, 0xc295, ff_joystick },
-       { 0x046d, 0xc298, ff_wheel },
-       { 0x046d, 0xc299, ff_wheel },
-       { 0x046d, 0xca03, ff_wheel },
 };
 
 static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
index 0ec91c18a4216a52a4a3c7d85292a22f61a6e828..b5bdab3299bcc6fdac44631c77fe8ca5c85028df 100644 (file)
@@ -81,6 +81,28 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define NO_TOUCHES -1
 #define SINGLE_TOUCH_UP -2
 
+/* Touch surface information. Dimension is in hundredths of a mm, min and max
+ * are in units. */
+#define MOUSE_DIMENSION_X (float)9056
+#define MOUSE_MIN_X -1100
+#define MOUSE_MAX_X 1258
+#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100))
+#define MOUSE_DIMENSION_Y (float)5152
+#define MOUSE_MIN_Y -1589
+#define MOUSE_MAX_Y 2047
+#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100))
+
+#define TRACKPAD_DIMENSION_X (float)13000
+#define TRACKPAD_MIN_X -2909
+#define TRACKPAD_MAX_X 3167
+#define TRACKPAD_RES_X \
+       ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100))
+#define TRACKPAD_DIMENSION_Y (float)11000
+#define TRACKPAD_MIN_Y -2456
+#define TRACKPAD_MAX_Y 2565
+#define TRACKPAD_RES_Y \
+       ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
+
 /**
  * struct magicmouse_sc - Tracks Magic Mouse-specific data.
  * @input: Input device through which we report events.
@@ -406,17 +428,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
                 * inverse of the reported Y.
                 */
                if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
-                       input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
-                               1358, 4, 0);
-                       input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
-                               2047, 4, 0);
+                       input_set_abs_params(input, ABS_MT_POSITION_X,
+                               MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
+                       input_set_abs_params(input, ABS_MT_POSITION_Y,
+                               MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
+
+                       input_abs_set_res(input, ABS_MT_POSITION_X,
+                               MOUSE_RES_X);
+                       input_abs_set_res(input, ABS_MT_POSITION_Y,
+                               MOUSE_RES_Y);
                } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
-                       input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
-                       input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
-                       input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
-                               3167, 4, 0);
-                       input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
-                               2565, 4, 0);
+                       input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
+                               TRACKPAD_MAX_X, 4, 0);
+                       input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
+                               TRACKPAD_MAX_Y, 4, 0);
+                       input_set_abs_params(input, ABS_MT_POSITION_X,
+                               TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
+                       input_set_abs_params(input, ABS_MT_POSITION_Y,
+                               TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
+
+                       input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
+                       input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
+                       input_abs_set_res(input, ABS_MT_POSITION_X,
+                               TRACKPAD_RES_X);
+                       input_abs_set_res(input, ABS_MT_POSITION_Y,
+                               TRACKPAD_RES_Y);
                }
 
                input_set_events_per_packet(input, 60);
index 58d0e7aaf088ace83e03aa2ec3975e6b6fcae16f..b03a0b0e9b6349136abf6f6132fc85fce2088588 100644 (file)
@@ -213,6 +213,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
        struct mt_class *cls = td->mtclass;
        __s32 quirks = cls->quirks;
 
+       /* Only map fields from TouchScreen or TouchPad collections.
+         * We need to ignore fields that belong to other collections
+         * such as Mouse that might have the same GenericDesktop usages. */
+       if (field->application == HID_DG_TOUCHSCREEN)
+               set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
+       else if (field->application == HID_DG_TOUCHPAD)
+               set_bit(INPUT_PROP_POINTER, hi->input->propbit);
+       else
+               return 0;
+
        switch (usage->hid & HID_USAGE_PAGE) {
 
        case HID_UP_GENDESK:
@@ -672,6 +682,11 @@ static const struct hid_device_id mt_devices[] = {
                HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
                        USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
 
+       /* LG Display panels */
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_LG,
+                       USB_DEVICE_ID_LG_MULTITOUCH) },
+
        /* Lumio panels */
        { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
                HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
index 9d8710f8bc79c5df225af6fa358de67aa0e234a2..1782693819f37346390704739bc3a3183c5833ef 100644 (file)
@@ -2409,7 +2409,7 @@ static int picolcd_raw_event(struct hid_device *hdev,
 #ifdef CONFIG_PM
 static int picolcd_suspend(struct hid_device *hdev, pm_message_t message)
 {
-       if (message.event & PM_EVENT_AUTO)
+       if (PMSG_IS_AUTO(message))
                return 0;
 
        picolcd_suspend_backlight(hid_get_drvdata(hdev));
index 158b389d0fb796156a7f0a8e6ec368cd91c8f875..f779009104eb93f79b29c94d8eef84561d1e468a 100644 (file)
@@ -816,7 +816,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
        if (pm == NULL) {
                hid_err(hdev, "can't alloc descriptor\n");
                ret = -ENOMEM;
-               goto err_free;
+               goto err_free_pk;
        }
 
        pm->pk = pk;
@@ -849,10 +849,10 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
 err_stop:
        hid_hw_stop(hdev);
 err_free:
-       if (pm != NULL)
-               kfree(pm);
-
+       kfree(pm);
+err_free_pk:
        kfree(pk);
+
        return ret;
 }
 
index 16f7cafc9695b64377b07c5cca95c5bcea52824d..810425f2df589091d20f152316d0f26d77f0e87a 100644 (file)
@@ -65,8 +65,7 @@ static int sjoyff_init(struct hid_device *hid)
 {
        struct sjoyff_device *sjoyff;
        struct hid_report *report;
-       struct hid_input *hidinput = list_entry(hid->inputs.next,
-                                               struct hid_input, list);
+       struct hid_input *hidinput;
        struct list_head *report_list =
                        &hid->report_enum[HID_OUTPUT_REPORT].report_list;
        struct list_head *report_ptr = report_list;
@@ -78,43 +77,45 @@ static int sjoyff_init(struct hid_device *hid)
                return -ENODEV;
        }
 
-       report_ptr = report_ptr->next;
+       list_for_each_entry(hidinput, &hid->inputs, list) {
+               report_ptr = report_ptr->next;
 
-       if (report_ptr == report_list) {
-               hid_err(hid, "required output report is missing\n");
-               return -ENODEV;
-       }
+               if (report_ptr == report_list) {
+                       hid_err(hid, "required output report is missing\n");
+                       return -ENODEV;
+               }
 
-       report = list_entry(report_ptr, struct hid_report, list);
-       if (report->maxfield < 1) {
-               hid_err(hid, "no fields in the report\n");
-               return -ENODEV;
-       }
+               report = list_entry(report_ptr, struct hid_report, list);
+               if (report->maxfield < 1) {
+                       hid_err(hid, "no fields in the report\n");
+                       return -ENODEV;
+               }
 
-       if (report->field[0]->report_count < 3) {
-               hid_err(hid, "not enough values in the field\n");
-               return -ENODEV;
-       }
+               if (report->field[0]->report_count < 3) {
+                       hid_err(hid, "not enough values in the field\n");
+                       return -ENODEV;
+               }
 
-       sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL);
-       if (!sjoyff)
-               return -ENOMEM;
+               sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL);
+               if (!sjoyff)
+                       return -ENOMEM;
 
-       dev = hidinput->input;
+               dev = hidinput->input;
 
-       set_bit(FF_RUMBLE, dev->ffbit);
+               set_bit(FF_RUMBLE, dev->ffbit);
 
-       error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
-       if (error) {
-               kfree(sjoyff);
-               return error;
-       }
+               error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
+               if (error) {
+                       kfree(sjoyff);
+                       return error;
+               }
 
-       sjoyff->report = report;
-       sjoyff->report->field[0]->value[0] = 0x01;
-       sjoyff->report->field[0]->value[1] = 0x00;
-       sjoyff->report->field[0]->value[2] = 0x00;
-       usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
+               sjoyff->report = report;
+               sjoyff->report->field[0]->value[0] = 0x01;
+               sjoyff->report->field[0]->value[1] = 0x00;
+               sjoyff->report->field[0]->value[2] = 0x00;
+               usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
+       }
 
        hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
 
@@ -131,6 +132,8 @@ static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
        int ret;
 
+       hdev->quirks |= id->driver_data;
+
        ret = hid_parse(hdev);
        if (ret) {
                hid_err(hdev, "parse failed\n");
@@ -152,6 +155,9 @@ err:
 
 static const struct hid_device_id sjoy_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD),
+               .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
+                              HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { }
 };
 MODULE_DEVICE_TABLE(hid, sjoy_devices);
index e90371508fd2bf7a205cc56e31d47f1eda1a084e..1ad85f2257b4b46d4c48cd49f883fa95634c17e7 100644 (file)
@@ -201,9 +201,7 @@ static void zc_remove(struct hid_device *hdev)
        struct zc_device *zc = hid_get_drvdata(hdev);
 
        hid_hw_stop(hdev);
-
-       if (NULL != zc)
-               kfree(zc);
+       kfree(zc);
 }
 
 static const struct hid_device_id zc_devices[] = {
index ad978f5748d3211e4eeb14992806a5a912682040..a9fa294ee7d361b0885954099c5c451543024873 100644 (file)
@@ -1332,7 +1332,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
        struct usbhid_device *usbhid = hid->driver_data;
        int status;
 
-       if (message.event & PM_EVENT_AUTO) {
+       if (PMSG_IS_AUTO(message)) {
                spin_lock_irq(&usbhid->lock);   /* Sync with error handler */
                if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
                    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
@@ -1367,7 +1367,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
                        return -EIO;
        }
 
-       if (!ignoreled && (message.event & PM_EVENT_AUTO)) {
+       if (!ignoreled && PMSG_IS_AUTO(message)) {
                spin_lock_irq(&usbhid->lock);
                if (test_bit(HID_LED_ON, &usbhid->iofl)) {
                        spin_unlock_irq(&usbhid->lock);
@@ -1380,8 +1380,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
        hid_cancel_delayed_stuff(usbhid);
        hid_cease_io(usbhid);
 
-       if ((message.event & PM_EVENT_AUTO) &&
-                       test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+       if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
                /* lost race against keypresses */
                status = hid_start_in(hid);
                if (status < 0)
index 621959d5cc42c6b6798328fe32ce32072fa8669a..df618a3f951cc6e01a78dcdda48c59545e477593 100644 (file)
@@ -79,7 +79,6 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
-       { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
 
        { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
index 0b62c3c6b7cefc2e603cdf2ed9a7972434e1e443..63c9480a74e11657c80d496b12168a9b7e48c0c5 100644 (file)
@@ -315,6 +315,7 @@ config SENSORS_I5K_AMB
 
 config SENSORS_F71805F
        tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG"
+       depends on !PPC
        help
          If you say yes here you get support for hardware monitoring
          features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG
@@ -325,6 +326,7 @@ config SENSORS_F71805F
 
 config SENSORS_F71882FG
        tristate "Fintek F71882FG and compatibles"
+       depends on !PPC
        help
          If you say yes here you get support for hardware monitoring
          features of many Fintek Super-I/O (LPC) chips. The currently
@@ -448,6 +450,7 @@ config SENSORS_IBMPEX
 
 config SENSORS_IT87
        tristate "ITE IT87xx and compatibles"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get support for ITE IT8705F, IT8712F,
@@ -803,6 +806,7 @@ config SENSORS_NTC_THERMISTOR
 
 config SENSORS_PC87360
        tristate "National Semiconductor PC87360 family"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get access to the hardware monitoring
@@ -816,6 +820,7 @@ config SENSORS_PC87360
 
 config SENSORS_PC87427
        tristate "National Semiconductor PC87427"
+       depends on !PPC
        help
          If you say yes here you get access to the hardware monitoring
          functions of the National Semiconductor PC87427 Super-I/O chip.
@@ -907,7 +912,7 @@ config SENSORS_SMM665
 
 config SENSORS_DME1737
        tristate "SMSC DME1737, SCH311x and compatibles"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C && EXPERIMENTAL && !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the hardware monitoring
@@ -949,6 +954,7 @@ config SENSORS_EMC6W201
 
 config SENSORS_SMSC47M1
        tristate "SMSC LPC47M10x and compatibles"
+       depends on !PPC
        help
          If you say yes here you get support for the integrated fan
          monitoring and control capabilities of the SMSC LPC47B27x,
@@ -982,7 +988,7 @@ config SENSORS_SMSC47M192
 
 config SENSORS_SMSC47B397
        tristate "SMSC LPC47B397-NC"
-       depends on EXPERIMENTAL
+       depends on EXPERIMENTAL && !PPC
        help
          If you say yes here you get support for the SMSC LPC47B397-NC
          sensor chip.
@@ -996,6 +1002,7 @@ config SENSORS_SCH56XX_COMMON
 
 config SENSORS_SCH5627
        tristate "SMSC SCH5627"
+       depends on !PPC
        select SENSORS_SCH56XX_COMMON
        help
          If you say yes here you get support for the hardware monitoring
@@ -1006,6 +1013,7 @@ config SENSORS_SCH5627
 
 config SENSORS_SCH5636
        tristate "SMSC SCH5636"
+       depends on !PPC
        select SENSORS_SCH56XX_COMMON
        help
          SMSC SCH5636 Super I/O chips include an embedded microcontroller for
@@ -1129,6 +1137,7 @@ config SENSORS_VIA686A
 
 config SENSORS_VT1211
        tristate "VIA VT1211"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here then you get support for hardware monitoring
@@ -1241,6 +1250,7 @@ config SENSORS_W83L786NG
 
 config SENSORS_W83627HF
        tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the Winbond W836X7 series
@@ -1252,6 +1262,7 @@ config SENSORS_W83627HF
 
 config SENSORS_W83627EHF
        tristate "Winbond W83627EHF/EHG/DHG, W83667HG, NCT6775F, NCT6776F"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the hardware
index c316294c48b47ba848f5844270e0394d13e2be87..c6d59b1788d7d835b901297a93fdf8dcb737504f 100644 (file)
@@ -148,8 +148,9 @@ struct aem_data {
        int                     id;
        struct aem_ipmi_data    ipmi;
 
-       /* Function to update sensors */
+       /* Function and buffer to update sensors */
        void (*update)(struct aem_data *data);
+       struct aem_read_sensor_resp *rs_resp;
 
        /*
         * AEM 1.x sensors:
@@ -246,8 +247,6 @@ static void aem_bmc_gone(int iface);
 static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
 
 static void aem_remove_sensors(struct aem_data *data);
-static int aem_init_aem1(struct aem_ipmi_data *probe);
-static int aem_init_aem2(struct aem_ipmi_data *probe);
 static int aem1_find_sensors(struct aem_data *data);
 static int aem2_find_sensors(struct aem_data *data);
 static void update_aem1_sensors(struct aem_data *data);
@@ -390,13 +389,14 @@ static void aem_idr_put(int id)
 
 /* Sensor support functions */
 
-/* Read a sensor value */
+/* Read a sensor value; must be called with data->lock held */
 static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
                           void *buf, size_t size)
 {
        int rs_size, res;
        struct aem_read_sensor_req rs_req;
-       struct aem_read_sensor_resp *rs_resp;
+       /* Use preallocated rx buffer */
+       struct aem_read_sensor_resp *rs_resp = data->rs_resp;
        struct aem_ipmi_data *ipmi = &data->ipmi;
 
        /* AEM registers are 1, 2, 4 or 8 bytes */
@@ -422,10 +422,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
        ipmi->tx_message.data_len = sizeof(rs_req);
 
        rs_size = sizeof(*rs_resp) + size;
-       rs_resp = kzalloc(rs_size, GFP_KERNEL);
-       if (!rs_resp)
-               return -ENOMEM;
-
        ipmi->rx_msg_data = rs_resp;
        ipmi->rx_msg_len = rs_size;
 
@@ -468,7 +464,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
        res = 0;
 
 out:
-       kfree(rs_resp);
        return res;
 }
 
@@ -526,6 +521,7 @@ static void aem_delete(struct aem_data *data)
 {
        list_del(&data->list);
        aem_remove_sensors(data);
+       kfree(data->rs_resp);
        hwmon_device_unregister(data->hwmon_dev);
        ipmi_destroy_user(data->ipmi.user);
        platform_set_drvdata(data->pdev, NULL);
@@ -602,24 +598,31 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
        platform_set_drvdata(data->pdev, data);
 
        /* Set up IPMI interface */
-       if (aem_init_ipmi_data(&data->ipmi, probe->interface,
-                              probe->bmc_device))
+       res = aem_init_ipmi_data(&data->ipmi, probe->interface,
+                                probe->bmc_device);
+       if (res)
                goto ipmi_err;
 
        /* Register with hwmon */
        data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
-
        if (IS_ERR(data->hwmon_dev)) {
                dev_err(&data->pdev->dev, "Unable to register hwmon "
                        "device for IPMI interface %d\n",
                        probe->interface);
+               res = PTR_ERR(data->hwmon_dev);
                goto hwmon_reg_err;
        }
 
        data->update = update_aem1_sensors;
+       data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
+       if (!data->rs_resp) {
+               res = -ENOMEM;
+               goto alloc_resp_err;
+       }
 
        /* Find sensors */
-       if (aem1_find_sensors(data))
+       res = aem1_find_sensors(data);
+       if (res)
                goto sensor_err;
 
        /* Add to our list of AEM devices */
@@ -631,6 +634,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
        return 0;
 
 sensor_err:
+       kfree(data->rs_resp);
+alloc_resp_err:
        hwmon_device_unregister(data->hwmon_dev);
 hwmon_reg_err:
        ipmi_destroy_user(data->ipmi.user);
@@ -646,7 +651,7 @@ id_err:
 }
 
 /* Find and initialize all AEM1 instances */
-static int aem_init_aem1(struct aem_ipmi_data *probe)
+static void aem_init_aem1(struct aem_ipmi_data *probe)
 {
        int num, i, err;
 
@@ -657,11 +662,8 @@ static int aem_init_aem1(struct aem_ipmi_data *probe)
                        dev_err(probe->bmc_device,
                                "Error %d initializing AEM1 0x%X\n",
                                err, i);
-                       return err;
                }
        }
-
-       return 0;
 }
 
 /* Probe functions for AEM2 devices */
@@ -735,24 +737,31 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
        platform_set_drvdata(data->pdev, data);
 
        /* Set up IPMI interface */
-       if (aem_init_ipmi_data(&data->ipmi, probe->interface,
-                              probe->bmc_device))
+       res = aem_init_ipmi_data(&data->ipmi, probe->interface,
+                                probe->bmc_device);
+       if (res)
                goto ipmi_err;
 
        /* Register with hwmon */
        data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
-
        if (IS_ERR(data->hwmon_dev)) {
                dev_err(&data->pdev->dev, "Unable to register hwmon "
                        "device for IPMI interface %d\n",
                        probe->interface);
+               res = PTR_ERR(data->hwmon_dev);
                goto hwmon_reg_err;
        }
 
        data->update = update_aem2_sensors;
+       data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
+       if (!data->rs_resp) {
+               res = -ENOMEM;
+               goto alloc_resp_err;
+       }
 
        /* Find sensors */
-       if (aem2_find_sensors(data))
+       res = aem2_find_sensors(data);
+       if (res)
                goto sensor_err;
 
        /* Add to our list of AEM devices */
@@ -764,6 +773,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
        return 0;
 
 sensor_err:
+       kfree(data->rs_resp);
+alloc_resp_err:
        hwmon_device_unregister(data->hwmon_dev);
 hwmon_reg_err:
        ipmi_destroy_user(data->ipmi.user);
@@ -779,7 +790,7 @@ id_err:
 }
 
 /* Find and initialize all AEM2 instances */
-static int aem_init_aem2(struct aem_ipmi_data *probe)
+static void aem_init_aem2(struct aem_ipmi_data *probe)
 {
        struct aem_find_instance_resp fi_resp;
        int err;
@@ -798,12 +809,9 @@ static int aem_init_aem2(struct aem_ipmi_data *probe)
                        dev_err(probe->bmc_device,
                                "Error %d initializing AEM2 0x%X\n",
                                err, fi_resp.module_handle);
-                       return err;
                }
                i++;
        }
-
-       return 0;
 }
 
 /* Probe a BMC for AEM firmware instances */
index d7926f4336b5f5b8d712e6e74c6118f8e2a24d13..eab11615dced6b54e71996bfd4df60c159bbe570 100644 (file)
@@ -211,8 +211,7 @@ static int lookup_comp(struct ntc_data *data,
        if (data->comp[mid].ohm <= ohm) {
                *i_low = mid;
                *i_high = mid - 1;
-       }
-       if (data->comp[mid].ohm > ohm) {
+       } else {
                *i_low = mid + 1;
                *i_high = mid;
        }
index f2b377c56a3acda506e1efb21837bfa7138879de..eca61b3a58e74d9eab7536ac62f17f994cb2f452 100644 (file)
@@ -197,6 +197,9 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0, 0x152, 0x252, 0 };
 #define W83627EHF_REG_ALARM2           0x45A
 #define W83627EHF_REG_ALARM3           0x45B
 
+#define W83627EHF_REG_CASEOPEN_DET     0x42 /* SMI STATUS #2 */
+#define W83627EHF_REG_CASEOPEN_CLR     0x46 /* SMI MASK #3 */
+
 /* SmartFan registers */
 #define W83627EHF_REG_FAN_STEPUP_TIME 0x0f
 #define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e
@@ -468,6 +471,7 @@ struct w83627ehf_data {
        s16 temp_max[9];
        s16 temp_max_hyst[9];
        u32 alarms;
+       u8 caseopen;
 
        u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
        u8 pwm_enable[4]; /* 1->manual
@@ -873,6 +877,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
                               (w83627ehf_read_value(data,
                                        W83627EHF_REG_ALARM3) << 16);
 
+               data->caseopen = w83627ehf_read_value(data,
+                                               W83627EHF_REG_CASEOPEN_DET);
+
                data->last_updated = jiffies;
                data->valid = 1;
        }
@@ -1654,6 +1661,48 @@ show_vid(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
 
+
+/* Case open detection */
+
+static ssize_t
+show_caseopen(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct w83627ehf_data *data = w83627ehf_update_device(dev);
+
+       return sprintf(buf, "%d\n",
+               !!(data->caseopen & to_sensor_dev_attr_2(attr)->index));
+}
+
+static ssize_t
+clear_caseopen(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct w83627ehf_data *data = dev_get_drvdata(dev);
+       unsigned long val;
+       u16 reg, mask;
+
+       if (strict_strtoul(buf, 10, &val) || val != 0)
+               return -EINVAL;
+
+       mask = to_sensor_dev_attr_2(attr)->nr;
+
+       mutex_lock(&data->update_lock);
+       reg = w83627ehf_read_value(data, W83627EHF_REG_CASEOPEN_CLR);
+       w83627ehf_write_value(data, W83627EHF_REG_CASEOPEN_CLR, reg | mask);
+       w83627ehf_write_value(data, W83627EHF_REG_CASEOPEN_CLR, reg & ~mask);
+       data->valid = 0;        /* Force cache refresh */
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+static struct sensor_device_attribute_2 sda_caseopen[] = {
+       SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_caseopen,
+                       clear_caseopen, 0x80, 0x10),
+       SENSOR_ATTR_2(intrusion1_alarm, S_IWUSR | S_IRUGO, show_caseopen,
+                       clear_caseopen, 0x40, 0x40),
+};
+
 /*
  * Driver and device management
  */
@@ -1710,6 +1759,9 @@ static void w83627ehf_device_remove_files(struct device *dev)
                device_remove_file(dev, &sda_temp_type[i].dev_attr);
        }
 
+       device_remove_file(dev, &sda_caseopen[0].dev_attr);
+       device_remove_file(dev, &sda_caseopen[1].dev_attr);
+
        device_remove_file(dev, &dev_attr_name);
        device_remove_file(dev, &dev_attr_cpu0_vid);
 }
@@ -2261,6 +2313,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                        goto exit_remove;
        }
 
+       err = device_create_file(dev, &sda_caseopen[0].dev_attr);
+       if (err)
+               goto exit_remove;
+
+       if (sio_data->kind == nct6776) {
+               err = device_create_file(dev, &sda_caseopen[1].dev_attr);
+               if (err)
+                       goto exit_remove;
+       }
+
        err = device_create_file(dev, &dev_attr_name);
        if (err)
                goto exit_remove;
index 646068e5100bac8c6e3e9840bd0ac53596e4728a..d1fc5cf9aa4db1cf0aec15b5badb584db3ab962f 100644 (file)
@@ -789,7 +789,7 @@ config I2C_ACORN
 
 config I2C_ELEKTOR
        tristate "Elektor ISA card"
-       depends on ISA && BROKEN_ON_SMP
+       depends on ISA && HAS_IOPORT && BROKEN_ON_SMP
        select I2C_ALGOPCF
        help
          This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
index 5d8aed5ec21bb85863743e4855d450403074cf64..c01e9519f6c15ee5df4e8cb32ae44ae234f57482 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/slab.h>
 
 #include <mach/hardware.h>     /* Pick up IXP2000-specific bits */
-#include <mach/gpio.h>
+#include <mach/gpio-ixp2000.h>
 
 static inline int ixp2000_scl_pin(void *data)
 {
index 000a78e5246c5c1d9f510fcfbbfc9cf35700137a..6dede8f366c59417b3283cc03b220f6b5c58c97b 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/platform_device.h>
 
 #include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <mach/at91sam9_smc.h>
 
 #define DRV_NAME "at91_ide"
index 621619c794e5aaed29e56f685e7007e5c57b2e04..2761364185af203d1dad8174d450bb44d3d0260b 100644 (file)
@@ -1,4 +1,4 @@
-ccflags-y := -Idrivers/net/cxgb3
+ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb3
 
 obj-$(CONFIG_INFINIBAND_CXGB3) += iw_cxgb3.o
 
index cd20b1342aec18e7b017a98678607a9fa26c661d..46b878ca2c3b4863abc6849d8a0519a8d9050616 100644 (file)
@@ -1,4 +1,4 @@
-ccflags-y := -Idrivers/net/cxgb4
+ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4
 
 obj-$(CONFIG_INFINIBAND_CXGB4) += iw_cxgb4.o
 
index bd995b2b50d8da143d721aa4d04683844fda410a..24ab11a9ad1e1653771bd86329786de9f8b0ce82 100644 (file)
@@ -1,6 +1,7 @@
 config MLX4_INFINIBAND
        tristate "Mellanox ConnectX HCA support"
-       depends on NETDEVICES && NETDEV_10000 && PCI
+       depends on NETDEVICES && ETHERNET && PCI
+       select NET_VENDOR_MELLANOX
        select MLX4_CORE
        ---help---
          This driver provides low-level InfiniBand support for
index 9d7ffebff213f4f5f705d62bea366979d64a229c..66e12298d91702255cd7cee190e765836b9eb4c8 100644 (file)
@@ -1638,7 +1638,7 @@ static const struct net_device_ops nes_netdev_ops = {
        .ndo_get_stats          = nes_netdev_get_stats,
        .ndo_tx_timeout         = nes_netdev_tx_timeout,
        .ndo_set_mac_address    = nes_netdev_set_mac_address,
-       .ndo_set_multicast_list = nes_netdev_set_multicast_list,
+       .ndo_set_rx_mode        = nes_netdev_set_multicast_list,
        .ndo_change_mtu         = nes_netdev_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_fix_features       = nes_fix_features,
index fe89c4660d555fc821b8908c28a92ec208ca3070..7567b60002309a19a2d0a4cc13da855a46042be4 100644 (file)
@@ -998,7 +998,7 @@ static const struct net_device_ops ipoib_netdev_ops = {
        .ndo_fix_features        = ipoib_fix_features,
        .ndo_start_xmit          = ipoib_start_xmit,
        .ndo_tx_timeout          = ipoib_timeout,
-       .ndo_set_multicast_list  = ipoib_set_mcast_list,
+       .ndo_set_rx_mode         = ipoib_set_mcast_list,
        .ndo_neigh_setup         = ipoib_neigh_setup_dev,
 };
 
index b1aabde87523176f17ce0896e98403d4fda6f0a1..b253973881b82f69e7eaaa82c73cdc07fe843f22 100644 (file)
@@ -49,8 +49,10 @@ static int input_open_polled_device(struct input_dev *input)
                dev->open(dev);
 
        /* Only start polling if polling is enabled */
-       if (dev->poll_interval > 0)
-               queue_delayed_work(system_freezable_wq, &dev->work, 0);
+       if (dev->poll_interval > 0) {
+               dev->poll(dev);
+               input_polldev_queue_work(dev);
+       }
 
        return 0;
 }
index 9882971827e6325bd7a424ef83b13b5679cec8d1..358cd7ee905b7ff4f9a7498e277341037437bf19 100644 (file)
@@ -139,7 +139,7 @@ struct analog_port {
 #include <linux/i8253.h>
 
 #define GET_TIME(x)    do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0)
-#define DELTA(x,y)     (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0)))
+#define DELTA(x,y)     (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? PIT_TICK_RATE / HZ : 0)))
 #define TIME_NAME      (cpu_has_tsc?"TSC":"PIT")
 static unsigned int get_time_pit(void)
 {
index c8242dd190d0c920f64ff105903fd76c2e5a6be1..aa17e024d80329acffd48223b554d5f2528f513a 100644 (file)
@@ -20,6 +20,7 @@
  * flag.
  */
 
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
index 33d0bdc837c099a486e2bffc95dbe0fb6a8ee7c4..323bcdfff2484b6d3ddf22fddcb343216c879ee6 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/mutex.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/keypad.h>
 #include <plat/menelaus.h>
 #include <asm/irq.h>
index f270447ba9519cb9497eea8a02d9869eef58ba4b..a5a77915c65003fb30eb058765945353f11d6298 100644 (file)
@@ -702,7 +702,7 @@ err_iounmap:
 err_free_mem_region:
        release_mem_region(res->start, resource_size(res));
 err_free_mem:
-       input_free_device(kbc->idev);
+       input_free_device(input_dev);
        kfree(kbc);
 
        return err;
index c9104bb4db060061f4bc4dbdc6068dbfd7eeafa3..a1aa35a053b732a7496ab23c0740ddac42e840b2 100644 (file)
@@ -62,6 +62,17 @@ config INPUT_AD714X_SPI
          To compile this driver as a module, choose M here: the
          module will be called ad714x-spi.
 
+config INPUT_BMA150
+       tristate "BMA150/SMB380 acceleration sensor support"
+       depends on I2C
+       select INPUT_POLLDEV
+       help
+         Say Y here if you have Bosch Sensortec's BMA150 or SMB380
+         acceleration sensor hooked to an I2C bus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called bma150.
+
 config INPUT_PCSPKR
        tristate "PC Speaker support"
        depends on PCSPKR_PLATFORM
@@ -74,6 +85,29 @@ config INPUT_PCSPKR
          To compile this driver as a module, choose M here: the
          module will be called pcspkr.
 
+config INPUT_PM8XXX_VIBRATOR
+       tristate "Qualcomm PM8XXX vibrator support"
+       depends on MFD_PM8XXX
+       select INPUT_FF_MEMLESS
+       help
+         This option enables device driver support for the vibrator
+         on Qualcomm PM8xxx chip. This driver supports ff-memless interface
+         from input framework.
+
+         To compile this driver as module, choose M here: the
+         module will be called pm8xxx-vibrator.
+
+config INPUT_PMIC8XXX_PWRKEY
+       tristate "PMIC8XXX power key support"
+       depends on MFD_PM8XXX
+       help
+         Say Y here if you want support for the PMIC8XXX power key.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called pmic8xxx-pwrkey.
+
 config INPUT_SPARCSPKR
        tristate "SPARC Speaker support"
        depends on PCI && SPARC64
@@ -379,17 +413,6 @@ config INPUT_PWM_BEEPER
          To compile this driver as a module, choose M here: the module will be
          called pwm-beeper.
 
-config INPUT_PMIC8XXX_PWRKEY
-       tristate "PMIC8XXX power key support"
-       depends on MFD_PM8XXX
-       help
-         Say Y here if you want support for the PMIC8XXX power key.
-
-         If unsure, say N.
-
-         To compile this driver as a module, choose M here: the
-         module will be called pmic8xxx-pwrkey.
-
 config INPUT_GPIO_ROTARY_ENCODER
        tristate "Rotary encoders connected to GPIO pins"
        depends on GPIOLIB && GENERIC_GPIO
index 299ad5edba846e18c57aebf2c6b9dddb78df943a..53a8d0faad52fcebec83d70056ddc7ffd592a264 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE)                += ati_remote.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)                += ati_remote2.o
 obj-$(CONFIG_INPUT_ATLAS_BTNS)         += atlas_btns.o
 obj-$(CONFIG_INPUT_BFIN_ROTARY)                += bfin_rotary.o
+obj-$(CONFIG_INPUT_BMA150)             += bma150.o
 obj-$(CONFIG_INPUT_CM109)              += cm109.o
 obj-$(CONFIG_INPUT_CMA3000)            += cma3000_d0x.o
 obj-$(CONFIG_INPUT_CMA3000_I2C)                += cma3000_d0x_i2c.o
@@ -34,9 +35,10 @@ obj-$(CONFIG_INPUT_PCAP)             += pcap_keys.o
 obj-$(CONFIG_INPUT_PCF50633_PMU)       += pcf50633-input.o
 obj-$(CONFIG_INPUT_PCF8574)            += pcf8574_keypad.o
 obj-$(CONFIG_INPUT_PCSPKR)             += pcspkr.o
+obj-$(CONFIG_INPUT_PM8XXX_VIBRATOR)    += pm8xxx-vibrator.o
+obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY)    += pmic8xxx-pwrkey.o
 obj-$(CONFIG_INPUT_POWERMATE)          += powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)         += pwm-beeper.o
-obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY)    += pmic8xxx-pwrkey.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)       += rb532_button.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)        += rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)           += sgi_btns.o
index e21deb1baa8abfb193d46702023540e2d09a41ca..025417d74ca29c37ffa8393878aae2f257892427 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * AD714X CapTouch Programmable Controller driver (I2C bus)
  *
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -27,54 +27,49 @@ static int ad714x_i2c_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
 
-static int ad714x_i2c_write(struct device *dev, unsigned short reg,
-                               unsigned short data)
+static int ad714x_i2c_write(struct ad714x_chip *chip,
+                           unsigned short reg, unsigned short data)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       int ret = 0;
-       u8 *_reg = (u8 *)&reg;
-       u8 *_data = (u8 *)&data;
-
-       u8 tx[4] = {
-               _reg[1],
-               _reg[0],
-               _data[1],
-               _data[0]
-       };
-
-       ret = i2c_master_send(client, tx, 4);
-       if (ret < 0)
-               dev_err(&client->dev, "I2C write error\n");
-
-       return ret;
+       struct i2c_client *client = to_i2c_client(chip->dev);
+       int error;
+
+       chip->xfer_buf[0] = cpu_to_be16(reg);
+       chip->xfer_buf[1] = cpu_to_be16(data);
+
+       error = i2c_master_send(client, (u8 *)chip->xfer_buf,
+                               2 * sizeof(*chip->xfer_buf));
+       if (unlikely(error < 0)) {
+               dev_err(&client->dev, "I2C write error: %d\n", error);
+               return error;
+       }
+
+       return 0;
 }
 
-static int ad714x_i2c_read(struct device *dev, unsigned short reg,
-                               unsigned short *data)
+static int ad714x_i2c_read(struct ad714x_chip *chip,
+                          unsigned short reg, unsigned short *data, size_t len)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       int ret = 0;
-       u8 *_reg = (u8 *)&reg;
-       u8 *_data = (u8 *)data;
-
-       u8 tx[2] = {
-               _reg[1],
-               _reg[0]
-       };
-       u8 rx[2];
-
-       ret = i2c_master_send(client, tx, 2);
-       if (ret >= 0)
-               ret = i2c_master_recv(client, rx, 2);
-
-       if (unlikely(ret < 0)) {
-               dev_err(&client->dev, "I2C read error\n");
-       } else {
-               _data[0] = rx[1];
-               _data[1] = rx[0];
+       struct i2c_client *client = to_i2c_client(chip->dev);
+       int i;
+       int error;
+
+       chip->xfer_buf[0] = cpu_to_be16(reg);
+
+       error = i2c_master_send(client, (u8 *)chip->xfer_buf,
+                               sizeof(*chip->xfer_buf));
+       if (error >= 0)
+               error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
+                                       len * sizeof(*chip->xfer_buf));
+
+       if (unlikely(error < 0)) {
+               dev_err(&client->dev, "I2C read error: %d\n", error);
+               return error;
        }
 
-       return ret;
+       for (i = 0; i < len; i++)
+               data[i] = be16_to_cpu(chip->xfer_buf[i]);
+
+       return 0;
 }
 
 static int __devinit ad714x_i2c_probe(struct i2c_client *client,
index 4120dd5493059126b272256b47eba121044e396d..875b50811361cef62ca8e1e1b009b120121bfe66 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * AD714X CapTouch Programmable Controller driver (SPI bus)
  *
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/input.h>       /* BUS_I2C */
+#include <linux/input.h>       /* BUS_SPI */
 #include <linux/module.h>
 #include <linux/spi/spi.h>
 #include <linux/pm.h>
@@ -30,30 +30,68 @@ static int ad714x_spi_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
 
-static int ad714x_spi_read(struct device *dev, unsigned short reg,
-               unsigned short *data)
+static int ad714x_spi_read(struct ad714x_chip *chip,
+                          unsigned short reg, unsigned short *data, size_t len)
 {
-       struct spi_device *spi = to_spi_device(dev);
-       unsigned short tx = AD714x_SPI_CMD_PREFIX | AD714x_SPI_READ | reg;
+       struct spi_device *spi = to_spi_device(chip->dev);
+       struct spi_message message;
+       struct spi_transfer xfer[2];
+       int i;
+       int error;
+
+       spi_message_init(&message);
+       memset(xfer, 0, sizeof(xfer));
+
+       chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
+                                       AD714x_SPI_READ | reg);
+       xfer[0].tx_buf = &chip->xfer_buf[0];
+       xfer[0].len = sizeof(chip->xfer_buf[0]);
+       spi_message_add_tail(&xfer[0], &message);
+
+       xfer[1].rx_buf = &chip->xfer_buf[1];
+       xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
+       spi_message_add_tail(&xfer[1], &message);
+
+       error = spi_sync(spi, &message);
+       if (unlikely(error)) {
+               dev_err(chip->dev, "SPI read error: %d\n", error);
+               return error;
+       }
+
+       for (i = 0; i < len; i++)
+               data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
 
-       return spi_write_then_read(spi, (u8 *)&tx, 2, (u8 *)data, 2);
+       return 0;
 }
 
-static int ad714x_spi_write(struct device *dev, unsigned short reg,
-               unsigned short data)
+static int ad714x_spi_write(struct ad714x_chip *chip,
+                           unsigned short reg, unsigned short data)
 {
-       struct spi_device *spi = to_spi_device(dev);
-       unsigned short tx[2] = {
-               AD714x_SPI_CMD_PREFIX | reg,
-               data
-       };
+       struct spi_device *spi = to_spi_device(chip->dev);
+       int error;
+
+       chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
+       chip->xfer_buf[1] = cpu_to_be16(data);
+
+       error = spi_write(spi, (u8 *)chip->xfer_buf,
+                         2 * sizeof(*chip->xfer_buf));
+       if (unlikely(error)) {
+               dev_err(chip->dev, "SPI write error: %d\n", error);
+               return error;
+       }
 
-       return spi_write(spi, (u8 *)tx, 4);
+       return 0;
 }
 
 static int __devinit ad714x_spi_probe(struct spi_device *spi)
 {
        struct ad714x_chip *chip;
+       int err;
+
+       spi->bits_per_word = 8;
+       err = spi_setup(spi);
+       if (err < 0)
+               return err;
 
        chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq,
                            ad714x_spi_read, ad714x_spi_write);
index c3a62c42cd28838a64fa4cb432d2ac4e430a0fc0..ca42c7d2a3c79ab247163eafd7e4d4112b6ee097 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
  *
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -59,7 +59,6 @@
 #define STAGE11_AMBIENT                0x27D
 
 #define PER_STAGE_REG_NUM      36
-#define STAGE_NUM              12
 #define STAGE_CFGREG_NUM       8
 #define SYS_CFGREG_NUM         8
 
@@ -124,27 +123,6 @@ struct ad714x_driver_data {
  * information to integrate all things which will be private data
  * of spi/i2c device
  */
-struct ad714x_chip {
-       unsigned short h_state;
-       unsigned short l_state;
-       unsigned short c_state;
-       unsigned short adc_reg[STAGE_NUM];
-       unsigned short amb_reg[STAGE_NUM];
-       unsigned short sensor_val[STAGE_NUM];
-
-       struct ad714x_platform_data *hw;
-       struct ad714x_driver_data *sw;
-
-       int irq;
-       struct device *dev;
-       ad714x_read_t read;
-       ad714x_write_t write;
-
-       struct mutex mutex;
-
-       unsigned product;
-       unsigned version;
-};
 
 static void ad714x_use_com_int(struct ad714x_chip *ad714x,
                                int start_stage, int end_stage)
@@ -154,13 +132,13 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
 
        mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
 
-       ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
+       ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
        data |= 1 << end_stage;
-       ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
+       ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
 
-       ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
+       ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
        data &= ~mask;
-       ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
+       ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
 }
 
 static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
@@ -171,13 +149,13 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
 
        mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
 
-       ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
+       ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
        data &= ~(1 << end_stage);
-       ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
+       ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
 
-       ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
+       ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
        data |= mask;
-       ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
+       ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
 }
 
 static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
@@ -273,15 +251,16 @@ static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
        struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
        int i;
 
+       ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
+                       &ad714x->adc_reg[hw->start_stage],
+                       hw->end_stage - hw->start_stage + 1);
+
        for (i = hw->start_stage; i <= hw->end_stage; i++) {
-               ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
-                       &ad714x->adc_reg[i]);
-               ad714x->read(ad714x->dev,
-                               STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
-                               &ad714x->amb_reg[i]);
-
-               ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] -
-                               ad714x->amb_reg[i]);
+               ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
+                               &ad714x->amb_reg[i], 1);
+
+               ad714x->sensor_val[i] =
+                       abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
        }
 }
 
@@ -444,15 +423,16 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
        struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
        int i;
 
+       ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
+                       &ad714x->adc_reg[hw->start_stage],
+                       hw->end_stage - hw->start_stage + 1);
+
        for (i = hw->start_stage; i <= hw->end_stage; i++) {
-               ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
-                       &ad714x->adc_reg[i]);
-               ad714x->read(ad714x->dev,
-                               STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
-                               &ad714x->amb_reg[i]);
+               ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
+                               &ad714x->amb_reg[i], 1);
                if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
-                       ad714x->sensor_val[i] = ad714x->adc_reg[i] -
-                               ad714x->amb_reg[i];
+                       ad714x->sensor_val[i] =
+                               ad714x->adc_reg[i] - ad714x->amb_reg[i];
                else
                        ad714x->sensor_val[i] = 0;
        }
@@ -597,15 +577,16 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
        struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
        int i;
 
+       ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
+                       &ad714x->adc_reg[hw->x_start_stage],
+                       hw->x_end_stage - hw->x_start_stage + 1);
+
        for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
-               ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
-                               &ad714x->adc_reg[i]);
-               ad714x->read(ad714x->dev,
-                               STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
-                               &ad714x->amb_reg[i]);
+               ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
+                               &ad714x->amb_reg[i], 1);
                if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
-                       ad714x->sensor_val[i] = ad714x->adc_reg[i] -
-                               ad714x->amb_reg[i];
+                       ad714x->sensor_val[i] =
+                               ad714x->adc_reg[i] - ad714x->amb_reg[i];
                else
                        ad714x->sensor_val[i] = 0;
        }
@@ -891,7 +872,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
 {
        unsigned short data;
 
-       ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data);
+       ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
        switch (data & 0xFFF0) {
        case AD7142_PARTID:
                ad714x->product = 0x7142;
@@ -940,23 +921,20 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
        for (i = 0; i < STAGE_NUM; i++) {
                reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
                for (j = 0; j < STAGE_CFGREG_NUM; j++)
-                       ad714x->write(ad714x->dev, reg_base + j,
+                       ad714x->write(ad714x, reg_base + j,
                                        ad714x->hw->stage_cfg_reg[i][j]);
        }
 
        for (i = 0; i < SYS_CFGREG_NUM; i++)
-               ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i,
+               ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
                        ad714x->hw->sys_cfg_reg[i]);
        for (i = 0; i < SYS_CFGREG_NUM; i++)
-               ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i,
-                       &data);
+               ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
 
-       ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF);
+       ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
 
        /* clear all interrupts */
-       ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
-       ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
-       ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
+       ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
 }
 
 static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
@@ -966,9 +944,7 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
 
        mutex_lock(&ad714x->mutex);
 
-       ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
-       ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
-       ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
+       ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
 
        for (i = 0; i < ad714x->hw->button_num; i++)
                ad714x_button_state_machine(ad714x, i);
@@ -1245,7 +1221,7 @@ int ad714x_disable(struct ad714x_chip *ad714x)
        mutex_lock(&ad714x->mutex);
 
        data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
-       ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data);
+       ad714x->write(ad714x, AD714X_PWR_CTRL, data);
 
        mutex_unlock(&ad714x->mutex);
 
@@ -1255,24 +1231,20 @@ EXPORT_SYMBOL(ad714x_disable);
 
 int ad714x_enable(struct ad714x_chip *ad714x)
 {
-       unsigned short data;
-
        dev_dbg(ad714x->dev, "%s enter\n", __func__);
 
        mutex_lock(&ad714x->mutex);
 
        /* resume to non-shutdown mode */
 
-       ad714x->write(ad714x->dev, AD714X_PWR_CTRL,
+       ad714x->write(ad714x, AD714X_PWR_CTRL,
                        ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
 
        /* make sure the interrupt output line is not low level after resume,
         * otherwise we will get no chance to enter falling-edge irq again
         */
 
-       ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
-       ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
-       ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
+       ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
 
        mutex_unlock(&ad714x->mutex);
 
index 45c54fb13f0755007e689d9b549b615d71b4a104..3c85455aa66d23329d3605fb367d400d320e4976 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * AD714X CapTouch Programmable Controller driver (bus interfaces)
  *
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
 
 #include <linux/types.h>
 
+#define STAGE_NUM              12
+
 struct device;
+struct ad714x_platform_data;
+struct ad714x_driver_data;
 struct ad714x_chip;
 
-typedef int (*ad714x_read_t)(struct device *, unsigned short, unsigned short *);
-typedef int (*ad714x_write_t)(struct device *, unsigned short, unsigned short);
+typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *, size_t);
+typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short);
+
+struct ad714x_chip {
+       unsigned short l_state;
+       unsigned short h_state;
+       unsigned short c_state;
+       unsigned short adc_reg[STAGE_NUM];
+       unsigned short amb_reg[STAGE_NUM];
+       unsigned short sensor_val[STAGE_NUM];
+
+       struct ad714x_platform_data *hw;
+       struct ad714x_driver_data *sw;
+
+       int irq;
+       struct device *dev;
+       ad714x_read_t read;
+       ad714x_write_t write;
+
+       struct mutex mutex;
+
+       unsigned product;
+       unsigned version;
+
+       __be16 xfer_buf[16] ____cacheline_aligned;
+
+};
 
 int ad714x_disable(struct ad714x_chip *ad714x);
 int ad714x_enable(struct ad714x_chip *ad714x);
diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c
new file mode 100644 (file)
index 0000000..8f55b54
--- /dev/null
@@ -0,0 +1,691 @@
+/*
+ * Copyright (c) 2011 Bosch Sensortec GmbH
+ * Copyright (c) 2011 Unixphere
+ *
+ * This driver adds support for Bosch Sensortec's digital acceleration
+ * sensors BMA150 and SMB380.
+ * The SMB380 is fully compatible with BMA150 and only differs in packaging.
+ *
+ * The datasheet for the BMA150 chip can be found here:
+ * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMA150-DS000-07.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input-polldev.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/bma150.h>
+
+#define ABSMAX_ACC_VAL         0x01FF
+#define ABSMIN_ACC_VAL         -(ABSMAX_ACC_VAL)
+
+/* Each axis is represented by a 2-byte data word */
+#define BMA150_XYZ_DATA_SIZE   6
+
+/* Input poll interval in milliseconds */
+#define BMA150_POLL_INTERVAL   10
+#define BMA150_POLL_MAX                200
+#define BMA150_POLL_MIN                0
+
+#define BMA150_BW_25HZ         0
+#define BMA150_BW_50HZ         1
+#define BMA150_BW_100HZ                2
+#define BMA150_BW_190HZ                3
+#define BMA150_BW_375HZ                4
+#define BMA150_BW_750HZ                5
+#define BMA150_BW_1500HZ       6
+
+#define BMA150_RANGE_2G                0
+#define BMA150_RANGE_4G                1
+#define BMA150_RANGE_8G                2
+
+#define BMA150_MODE_NORMAL     0
+#define BMA150_MODE_SLEEP      2
+#define BMA150_MODE_WAKE_UP    3
+
+/* Data register addresses */
+#define BMA150_DATA_0_REG      0x00
+#define BMA150_DATA_1_REG      0x01
+#define BMA150_DATA_2_REG      0x02
+
+/* Control register addresses */
+#define BMA150_CTRL_0_REG      0x0A
+#define BMA150_CTRL_1_REG      0x0B
+#define BMA150_CTRL_2_REG      0x14
+#define BMA150_CTRL_3_REG      0x15
+
+/* Configuration/Setting register addresses */
+#define BMA150_CFG_0_REG       0x0C
+#define BMA150_CFG_1_REG       0x0D
+#define BMA150_CFG_2_REG       0x0E
+#define BMA150_CFG_3_REG       0x0F
+#define BMA150_CFG_4_REG       0x10
+#define BMA150_CFG_5_REG       0x11
+
+#define BMA150_CHIP_ID         2
+#define BMA150_CHIP_ID_REG     BMA150_DATA_0_REG
+
+#define BMA150_ACC_X_LSB_REG   BMA150_DATA_2_REG
+
+#define BMA150_SLEEP_POS       0
+#define BMA150_SLEEP_MSK       0x01
+#define BMA150_SLEEP_REG       BMA150_CTRL_0_REG
+
+#define BMA150_BANDWIDTH_POS   0
+#define BMA150_BANDWIDTH_MSK   0x07
+#define BMA150_BANDWIDTH_REG   BMA150_CTRL_2_REG
+
+#define BMA150_RANGE_POS       3
+#define BMA150_RANGE_MSK       0x18
+#define BMA150_RANGE_REG       BMA150_CTRL_2_REG
+
+#define BMA150_WAKE_UP_POS     0
+#define BMA150_WAKE_UP_MSK     0x01
+#define BMA150_WAKE_UP_REG     BMA150_CTRL_3_REG
+
+#define BMA150_SW_RES_POS      1
+#define BMA150_SW_RES_MSK      0x02
+#define BMA150_SW_RES_REG      BMA150_CTRL_0_REG
+
+/* Any-motion interrupt register fields */
+#define BMA150_ANY_MOTION_EN_POS       6
+#define BMA150_ANY_MOTION_EN_MSK       0x40
+#define BMA150_ANY_MOTION_EN_REG       BMA150_CTRL_1_REG
+
+#define BMA150_ANY_MOTION_DUR_POS      6
+#define BMA150_ANY_MOTION_DUR_MSK      0xC0
+#define BMA150_ANY_MOTION_DUR_REG      BMA150_CFG_5_REG
+
+#define BMA150_ANY_MOTION_THRES_REG    BMA150_CFG_4_REG
+
+/* Advanced interrupt register fields */
+#define BMA150_ADV_INT_EN_POS          6
+#define BMA150_ADV_INT_EN_MSK          0x40
+#define BMA150_ADV_INT_EN_REG          BMA150_CTRL_3_REG
+
+/* High-G interrupt register fields */
+#define BMA150_HIGH_G_EN_POS           1
+#define BMA150_HIGH_G_EN_MSK           0x02
+#define BMA150_HIGH_G_EN_REG           BMA150_CTRL_1_REG
+
+#define BMA150_HIGH_G_HYST_POS         3
+#define BMA150_HIGH_G_HYST_MSK         0x38
+#define BMA150_HIGH_G_HYST_REG         BMA150_CFG_5_REG
+
+#define BMA150_HIGH_G_DUR_REG          BMA150_CFG_3_REG
+#define BMA150_HIGH_G_THRES_REG                BMA150_CFG_2_REG
+
+/* Low-G interrupt register fields */
+#define BMA150_LOW_G_EN_POS            0
+#define BMA150_LOW_G_EN_MSK            0x01
+#define BMA150_LOW_G_EN_REG            BMA150_CTRL_1_REG
+
+#define BMA150_LOW_G_HYST_POS          0
+#define BMA150_LOW_G_HYST_MSK          0x07
+#define BMA150_LOW_G_HYST_REG          BMA150_CFG_5_REG
+
+#define BMA150_LOW_G_DUR_REG           BMA150_CFG_1_REG
+#define BMA150_LOW_G_THRES_REG         BMA150_CFG_0_REG
+
+struct bma150_data {
+       struct i2c_client *client;
+       struct input_polled_dev *input_polled;
+       struct input_dev *input;
+       u8 mode;
+};
+
+/*
+ * The settings for the given range, bandwidth and interrupt features
+ * are stated and verified by Bosch Sensortec where they are configured
+ * to provide a generic sensitivity performance.
+ */
+static struct bma150_cfg default_cfg __devinitdata = {
+       .any_motion_int = 1,
+       .hg_int = 1,
+       .lg_int = 1,
+       .any_motion_dur = 0,
+       .any_motion_thres = 0,
+       .hg_hyst = 0,
+       .hg_dur = 150,
+       .hg_thres = 160,
+       .lg_hyst = 0,
+       .lg_dur = 150,
+       .lg_thres = 20,
+       .range = BMA150_RANGE_2G,
+       .bandwidth = BMA150_BW_50HZ
+};
+
+static int bma150_write_byte(struct i2c_client *client, u8 reg, u8 val)
+{
+       s32 ret;
+
+       /* As per specification, disable irq in between register writes */
+       if (client->irq)
+               disable_irq_nosync(client->irq);
+
+       ret = i2c_smbus_write_byte_data(client, reg, val);
+
+       if (client->irq)
+               enable_irq(client->irq);
+
+       return ret;
+}
+
+static int bma150_set_reg_bits(struct i2c_client *client,
+                                       int val, int shift, u8 mask, u8 reg)
+{
+       int data;
+
+       data = i2c_smbus_read_byte_data(client, reg);
+       if (data < 0)
+               return data;
+
+       data = (data & ~mask) | ((val << shift) & mask);
+       return bma150_write_byte(client, reg, data);
+}
+
+static int bma150_set_mode(struct bma150_data *bma150, u8 mode)
+{
+       int error;
+
+       error = bma150_set_reg_bits(bma150->client, mode, BMA150_WAKE_UP_POS,
+                               BMA150_WAKE_UP_MSK, BMA150_WAKE_UP_REG);
+       if (error)
+               return error;
+
+       error = bma150_set_reg_bits(bma150->client, mode, BMA150_SLEEP_POS,
+                               BMA150_SLEEP_MSK, BMA150_SLEEP_REG);
+       if (error)
+               return error;
+
+       if (mode == BMA150_MODE_NORMAL)
+               msleep(2);
+
+       bma150->mode = mode;
+       return 0;
+}
+
+static int __devinit bma150_soft_reset(struct bma150_data *bma150)
+{
+       int error;
+
+       error = bma150_set_reg_bits(bma150->client, 1, BMA150_SW_RES_POS,
+                               BMA150_SW_RES_MSK, BMA150_SW_RES_REG);
+       if (error)
+               return error;
+
+       msleep(2);
+       return 0;
+}
+
+static int __devinit bma150_set_range(struct bma150_data *bma150, u8 range)
+{
+       return bma150_set_reg_bits(bma150->client, range, BMA150_RANGE_POS,
+                               BMA150_RANGE_MSK, BMA150_RANGE_REG);
+}
+
+static int __devinit bma150_set_bandwidth(struct bma150_data *bma150, u8 bw)
+{
+       return bma150_set_reg_bits(bma150->client, bw, BMA150_BANDWIDTH_POS,
+                               BMA150_BANDWIDTH_MSK, BMA150_BANDWIDTH_REG);
+}
+
+static int __devinit bma150_set_low_g_interrupt(struct bma150_data *bma150,
+                                       u8 enable, u8 hyst, u8 dur, u8 thres)
+{
+       int error;
+
+       error = bma150_set_reg_bits(bma150->client, hyst,
+                               BMA150_LOW_G_HYST_POS, BMA150_LOW_G_HYST_MSK,
+                               BMA150_LOW_G_HYST_REG);
+       if (error)
+               return error;
+
+       error = bma150_write_byte(bma150->client, BMA150_LOW_G_DUR_REG, dur);
+       if (error)
+               return error;
+
+       error = bma150_write_byte(bma150->client, BMA150_LOW_G_THRES_REG, thres);
+       if (error)
+               return error;
+
+       return bma150_set_reg_bits(bma150->client, !!enable,
+                               BMA150_LOW_G_EN_POS, BMA150_LOW_G_EN_MSK,
+                               BMA150_LOW_G_EN_REG);
+}
+
+static int __devinit bma150_set_high_g_interrupt(struct bma150_data *bma150,
+                                       u8 enable, u8 hyst, u8 dur, u8 thres)
+{
+       int error;
+
+       error = bma150_set_reg_bits(bma150->client, hyst,
+                               BMA150_HIGH_G_HYST_POS, BMA150_HIGH_G_HYST_MSK,
+                               BMA150_HIGH_G_HYST_REG);
+       if (error)
+               return error;
+
+       error = bma150_write_byte(bma150->client,
+                               BMA150_HIGH_G_DUR_REG, dur);
+       if (error)
+               return error;
+
+       error = bma150_write_byte(bma150->client,
+                               BMA150_HIGH_G_THRES_REG, thres);
+       if (error)
+               return error;
+
+       return bma150_set_reg_bits(bma150->client, !!enable,
+                               BMA150_HIGH_G_EN_POS, BMA150_HIGH_G_EN_MSK,
+                               BMA150_HIGH_G_EN_REG);
+}
+
+
+static int __devinit bma150_set_any_motion_interrupt(struct bma150_data *bma150,
+                                               u8 enable, u8 dur, u8 thres)
+{
+       int error;
+
+       error = bma150_set_reg_bits(bma150->client, dur,
+                               BMA150_ANY_MOTION_DUR_POS,
+                               BMA150_ANY_MOTION_DUR_MSK,
+                               BMA150_ANY_MOTION_DUR_REG);
+       if (error)
+               return error;
+
+       error = bma150_write_byte(bma150->client,
+                               BMA150_ANY_MOTION_THRES_REG, thres);
+       if (error)
+               return error;
+
+       error = bma150_set_reg_bits(bma150->client, !!enable,
+                               BMA150_ADV_INT_EN_POS, BMA150_ADV_INT_EN_MSK,
+                               BMA150_ADV_INT_EN_REG);
+       if (error)
+               return error;
+
+       return bma150_set_reg_bits(bma150->client, !!enable,
+                               BMA150_ANY_MOTION_EN_POS,
+                               BMA150_ANY_MOTION_EN_MSK,
+                               BMA150_ANY_MOTION_EN_REG);
+}
+
+static void bma150_report_xyz(struct bma150_data *bma150)
+{
+       u8 data[BMA150_XYZ_DATA_SIZE];
+       s16 x, y, z;
+       s32 ret;
+
+       ret = i2c_smbus_read_i2c_block_data(bma150->client,
+                       BMA150_ACC_X_LSB_REG, BMA150_XYZ_DATA_SIZE, data);
+       if (ret != BMA150_XYZ_DATA_SIZE)
+               return;
+
+       x = ((0xc0 & data[0]) >> 6) | (data[1] << 2);
+       y = ((0xc0 & data[2]) >> 6) | (data[3] << 2);
+       z = ((0xc0 & data[4]) >> 6) | (data[5] << 2);
+
+       /* sign extension */
+       x = (s16) (x << 6) >> 6;
+       y = (s16) (y << 6) >> 6;
+       z = (s16) (z << 6) >> 6;
+
+       input_report_abs(bma150->input, ABS_X, x);
+       input_report_abs(bma150->input, ABS_Y, y);
+       input_report_abs(bma150->input, ABS_Z, z);
+       input_sync(bma150->input);
+}
+
+static irqreturn_t bma150_irq_thread(int irq, void *dev)
+{
+       bma150_report_xyz(dev);
+
+       return IRQ_HANDLED;
+}
+
+static void bma150_poll(struct input_polled_dev *dev)
+{
+       bma150_report_xyz(dev->private);
+}
+
+static int bma150_open(struct bma150_data *bma150)
+{
+       int error;
+
+       error = pm_runtime_get_sync(&bma150->client->dev);
+       if (error && error != -ENOSYS)
+               return error;
+
+       /*
+        * See if runtime PM woke up the device. If runtime PM
+        * is disabled we need to do it ourselves.
+        */
+       if (bma150->mode != BMA150_MODE_NORMAL) {
+               error = bma150_set_mode(bma150, BMA150_MODE_NORMAL);
+               if (error)
+                       return error;
+       }
+
+       return 0;
+}
+
+static void bma150_close(struct bma150_data *bma150)
+{
+       pm_runtime_put_sync(&bma150->client->dev);
+
+       if (bma150->mode != BMA150_MODE_SLEEP)
+               bma150_set_mode(bma150, BMA150_MODE_SLEEP);
+}
+
+static int bma150_irq_open(struct input_dev *input)
+{
+       struct bma150_data *bma150 = input_get_drvdata(input);
+
+       return bma150_open(bma150);
+}
+
+static void bma150_irq_close(struct input_dev *input)
+{
+       struct bma150_data *bma150 = input_get_drvdata(input);
+
+       bma150_close(bma150);
+}
+
+static void bma150_poll_open(struct input_polled_dev *ipoll_dev)
+{
+       struct bma150_data *bma150 = ipoll_dev->private;
+
+       bma150_open(bma150);
+}
+
+static void bma150_poll_close(struct input_polled_dev *ipoll_dev)
+{
+       struct bma150_data *bma150 = ipoll_dev->private;
+
+       bma150_close(bma150);
+}
+
+static int __devinit bma150_initialize(struct bma150_data *bma150,
+                                      const struct bma150_cfg *cfg)
+{
+       int error;
+
+       error = bma150_soft_reset(bma150);
+       if (error)
+               return error;
+
+       error = bma150_set_bandwidth(bma150, cfg->bandwidth);
+       if (error)
+               return error;
+
+       error = bma150_set_range(bma150, cfg->range);
+       if (error)
+               return error;
+
+       if (bma150->client->irq) {
+               error = bma150_set_any_motion_interrupt(bma150,
+                                       cfg->any_motion_int,
+                                       cfg->any_motion_dur,
+                                       cfg->any_motion_thres);
+               if (error)
+                       return error;
+
+               error = bma150_set_high_g_interrupt(bma150,
+                                       cfg->hg_int, cfg->hg_hyst,
+                                       cfg->hg_dur, cfg->hg_thres);
+               if (error)
+                       return error;
+
+               error = bma150_set_low_g_interrupt(bma150,
+                                       cfg->lg_int, cfg->lg_hyst,
+                                       cfg->lg_dur, cfg->lg_thres);
+               if (error)
+                       return error;
+       }
+
+       return bma150_set_mode(bma150, BMA150_MODE_SLEEP);
+}
+
+static void __devinit bma150_init_input_device(struct bma150_data *bma150,
+                                               struct input_dev *idev)
+{
+       idev->name = BMA150_DRIVER;
+       idev->phys = BMA150_DRIVER "/input0";
+       idev->id.bustype = BUS_I2C;
+       idev->dev.parent = &bma150->client->dev;
+
+       idev->evbit[0] = BIT_MASK(EV_ABS);
+       input_set_abs_params(idev, ABS_X, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
+       input_set_abs_params(idev, ABS_Y, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
+       input_set_abs_params(idev, ABS_Z, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
+}
+
+static int __devinit bma150_register_input_device(struct bma150_data *bma150)
+{
+       struct input_dev *idev;
+       int error;
+
+       idev = input_allocate_device();
+       if (!idev)
+               return -ENOMEM;
+
+       bma150_init_input_device(bma150, idev);
+
+       idev->open = bma150_irq_open;
+       idev->close = bma150_irq_close;
+       input_set_drvdata(idev, bma150);
+
+       error = input_register_device(idev);
+       if (error) {
+               input_free_device(idev);
+               return error;
+       }
+
+       bma150->input = idev;
+       return 0;
+}
+
+static int __devinit bma150_register_polled_device(struct bma150_data *bma150)
+{
+       struct input_polled_dev *ipoll_dev;
+       int error;
+
+       ipoll_dev = input_allocate_polled_device();
+       if (!ipoll_dev)
+               return -ENOMEM;
+
+       ipoll_dev->private = bma150;
+       ipoll_dev->open = bma150_poll_open;
+       ipoll_dev->close = bma150_poll_close;
+       ipoll_dev->poll = bma150_poll;
+       ipoll_dev->poll_interval = BMA150_POLL_INTERVAL;
+       ipoll_dev->poll_interval_min = BMA150_POLL_MIN;
+       ipoll_dev->poll_interval_max = BMA150_POLL_MAX;
+
+       bma150_init_input_device(bma150, ipoll_dev->input);
+
+       error = input_register_polled_device(ipoll_dev);
+       if (error) {
+               input_free_polled_device(ipoll_dev);
+               return error;
+       }
+
+       bma150->input_polled = ipoll_dev;
+       bma150->input = ipoll_dev->input;
+
+       return 0;
+}
+
+static int __devinit bma150_probe(struct i2c_client *client,
+                                 const struct i2c_device_id *id)
+{
+       const struct bma150_platform_data *pdata = client->dev.platform_data;
+       const struct bma150_cfg *cfg;
+       struct bma150_data *bma150;
+       int chip_id;
+       int error;
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               dev_err(&client->dev, "i2c_check_functionality error\n");
+               return -EIO;
+       }
+
+       chip_id = i2c_smbus_read_byte_data(client, BMA150_CHIP_ID_REG);
+       if (chip_id != BMA150_CHIP_ID) {
+               dev_err(&client->dev, "BMA150 chip id error: %d\n", chip_id);
+               return -EINVAL;
+       }
+
+       bma150 = kzalloc(sizeof(struct bma150_data), GFP_KERNEL);
+       if (!bma150)
+               return -ENOMEM;
+
+       bma150->client = client;
+
+       if (pdata) {
+               if (pdata->irq_gpio_cfg) {
+                       error = pdata->irq_gpio_cfg();
+                       if (error) {
+                               dev_err(&client->dev,
+                                       "IRQ GPIO conf. error %d, error %d\n",
+                                       client->irq, error);
+                               goto err_free_mem;
+                       }
+               }
+               cfg = &pdata->cfg;
+       } else {
+               cfg = &default_cfg;
+       }
+
+       error = bma150_initialize(bma150, cfg);
+       if (error)
+               goto err_free_mem;
+
+       if (client->irq > 0) {
+               error = bma150_register_input_device(bma150);
+               if (error)
+                       goto err_free_mem;
+
+               error = request_threaded_irq(client->irq,
+                                       NULL, bma150_irq_thread,
+                                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                                       BMA150_DRIVER, bma150);
+               if (error) {
+                       dev_err(&client->dev,
+                               "irq request failed %d, error %d\n",
+                               client->irq, error);
+                       input_unregister_device(bma150->input);
+                       goto err_free_mem;
+               }
+       } else {
+               error = bma150_register_polled_device(bma150);
+               if (error)
+                       goto err_free_mem;
+       }
+
+       i2c_set_clientdata(client, bma150);
+
+       pm_runtime_enable(&client->dev);
+
+       return 0;
+
+err_free_mem:
+       kfree(bma150);
+       return error;
+}
+
+static int __devexit bma150_remove(struct i2c_client *client)
+{
+       struct bma150_data *bma150 = i2c_get_clientdata(client);
+
+       pm_runtime_disable(&client->dev);
+
+       if (client->irq > 0) {
+               free_irq(client->irq, bma150);
+               input_unregister_device(bma150->input);
+       } else {
+               input_unregister_polled_device(bma150->input_polled);
+               input_free_polled_device(bma150->input_polled);
+       }
+
+       kfree(bma150);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int bma150_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct bma150_data *bma150 = i2c_get_clientdata(client);
+
+       return bma150_set_mode(bma150, BMA150_MODE_SLEEP);
+}
+
+static int bma150_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct bma150_data *bma150 = i2c_get_clientdata(client);
+
+       return bma150_set_mode(bma150, BMA150_MODE_NORMAL);
+}
+#endif
+
+static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
+
+static const struct i2c_device_id bma150_id[] = {
+       { "bma150", 0 },
+       { "smb380", 0 },
+       { "bma023", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, bma150_id);
+
+static struct i2c_driver bma150_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = BMA150_DRIVER,
+               .pm     = &bma150_pm,
+       },
+       .class          = I2C_CLASS_HWMON,
+       .id_table       = bma150_id,
+       .probe          = bma150_probe,
+       .remove         = __devexit_p(bma150_remove),
+};
+
+static int __init BMA150_init(void)
+{
+       return i2c_add_driver(&bma150_driver);
+}
+
+static void __exit BMA150_exit(void)
+{
+       i2c_del_driver(&bma150_driver);
+}
+
+MODULE_AUTHOR("Albert Zhang <xu.zhang@bosch-sensortec.com>");
+MODULE_DESCRIPTION("BMA150 driver");
+MODULE_LICENSE("GPL");
+
+module_init(BMA150_init);
+module_exit(BMA150_exit);
index 6c76cf79299143ce16542af8e734e49e4a21bf12..0794778295fc60619311eb619c5eee2a7a97ef07 100644 (file)
@@ -234,7 +234,7 @@ static const struct of_device_id mma8450_dt_ids[] = {
        { .compatible = "fsl,mma8450", },
        { /* sentinel */ }
 };
-MODULE_DEVICE_TABLE(i2c, mma8450_dt_ids);
+MODULE_DEVICE_TABLE(of, mma8450_dt_ids);
 
 static struct i2c_driver mma8450_driver = {
        .driver = {
index b95fac15b2ea46ec40af163359a71bfb033ecef2..f71dc728da58adcad257da28f053b98fc29fa3fa 100644 (file)
@@ -282,7 +282,7 @@ err_free_irq:
 err_pm_set_suspended:
        pm_runtime_set_suspended(&client->dev);
 err_free_mem:
-       input_unregister_device(idev);
+       input_free_device(idev);
        kfree(sensor);
        return error;
 }
diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c
new file mode 100644 (file)
index 0000000..4319293
--- /dev/null
@@ -0,0 +1,296 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+
+#define VIB_DRV                        0x4A
+
+#define VIB_DRV_SEL_MASK       0xf8
+#define VIB_DRV_SEL_SHIFT      0x03
+#define VIB_DRV_EN_MANUAL_MASK 0xfc
+
+#define VIB_MAX_LEVEL_mV       (3100)
+#define VIB_MIN_LEVEL_mV       (1200)
+#define VIB_MAX_LEVELS         (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
+
+#define MAX_FF_SPEED           0xff
+
+/**
+ * struct pm8xxx_vib - structure to hold vibrator data
+ * @vib_input_dev: input device supporting force feedback
+ * @work: work structure to set the vibration parameters
+ * @dev: device supporting force feedback
+ * @speed: speed of vibration set from userland
+ * @active: state of vibrator
+ * @level: level of vibration to set in the chip
+ * @reg_vib_drv: VIB_DRV register value
+ */
+struct pm8xxx_vib {
+       struct input_dev *vib_input_dev;
+       struct work_struct work;
+       struct device *dev;
+       int speed;
+       int level;
+       bool active;
+       u8  reg_vib_drv;
+};
+
+/**
+ * pm8xxx_vib_read_u8 - helper to read a byte from pmic chip
+ * @vib: pointer to vibrator structure
+ * @data: placeholder for data to be read
+ * @reg: register address
+ */
+static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
+                                u8 *data, u16 reg)
+{
+       int rc;
+
+       rc = pm8xxx_readb(vib->dev->parent, reg, data);
+       if (rc < 0)
+               dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n",
+                               reg, rc);
+       return rc;
+}
+
+/**
+ * pm8xxx_vib_write_u8 - helper to write a byte to pmic chip
+ * @vib: pointer to vibrator structure
+ * @data: data to write
+ * @reg: register address
+ */
+static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
+                                u8 data, u16 reg)
+{
+       int rc;
+
+       rc = pm8xxx_writeb(vib->dev->parent, reg, data);
+       if (rc < 0)
+               dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n",
+                               reg, rc);
+       return rc;
+}
+
+/**
+ * pm8xxx_vib_set - handler to start/stop vibration
+ * @vib: pointer to vibrator structure
+ * @on: state to set
+ */
+static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
+{
+       int rc;
+       u8 val = vib->reg_vib_drv;
+
+       if (on)
+               val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
+       else
+               val &= ~VIB_DRV_SEL_MASK;
+
+       rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
+       if (rc < 0)
+               return rc;
+
+       vib->reg_vib_drv = val;
+       return 0;
+}
+
+/**
+ * pm8xxx_work_handler - worker to set vibration level
+ * @work: pointer to work_struct
+ */
+static void pm8xxx_work_handler(struct work_struct *work)
+{
+       struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
+       int rc;
+       u8 val;
+
+       rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
+       if (rc < 0)
+               return;
+
+       /*
+        * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
+        * scale the level to fit into these ranges.
+        */
+       if (vib->speed) {
+               vib->active = true;
+               vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
+                                               VIB_MIN_LEVEL_mV;
+               vib->level /= 100;
+       } else {
+               vib->active = false;
+               vib->level = VIB_MIN_LEVEL_mV / 100;
+       }
+
+       pm8xxx_vib_set(vib, vib->active);
+}
+
+/**
+ * pm8xxx_vib_close - callback of input close callback
+ * @dev: input device pointer
+ *
+ * Turns off the vibrator.
+ */
+static void pm8xxx_vib_close(struct input_dev *dev)
+{
+       struct pm8xxx_vib *vib = input_get_drvdata(dev);
+
+       cancel_work_sync(&vib->work);
+       if (vib->active)
+               pm8xxx_vib_set(vib, false);
+}
+
+/**
+ * pm8xxx_vib_play_effect - function to handle vib effects.
+ * @dev: input device pointer
+ * @data: data of effect
+ * @effect: effect to play
+ *
+ * Currently this driver supports only rumble effects.
+ */
+static int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
+                                 struct ff_effect *effect)
+{
+       struct pm8xxx_vib *vib = input_get_drvdata(dev);
+
+       vib->speed = effect->u.rumble.strong_magnitude >> 8;
+       if (!vib->speed)
+               vib->speed = effect->u.rumble.weak_magnitude >> 9;
+
+       schedule_work(&vib->work);
+
+       return 0;
+}
+
+static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)
+
+{
+       struct pm8xxx_vib *vib;
+       struct input_dev *input_dev;
+       int error;
+       u8 val;
+
+       vib = kzalloc(sizeof(*vib), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!vib || !input_dev) {
+               dev_err(&pdev->dev, "couldn't allocate memory\n");
+               error = -ENOMEM;
+               goto err_free_mem;
+       }
+
+       INIT_WORK(&vib->work, pm8xxx_work_handler);
+       vib->dev = &pdev->dev;
+       vib->vib_input_dev = input_dev;
+
+       /* operate in manual mode */
+       error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
+       if (error < 0)
+               goto err_free_mem;
+       val &= ~VIB_DRV_EN_MANUAL_MASK;
+       error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
+       if (error < 0)
+               goto err_free_mem;
+
+       vib->reg_vib_drv = val;
+
+       input_dev->name = "pm8xxx_vib_ffmemless";
+       input_dev->id.version = 1;
+       input_dev->dev.parent = &pdev->dev;
+       input_dev->close = pm8xxx_vib_close;
+       input_set_drvdata(input_dev, vib);
+       input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
+
+       error = input_ff_create_memless(input_dev, NULL,
+                                       pm8xxx_vib_play_effect);
+       if (error) {
+               dev_err(&pdev->dev,
+                       "couldn't register vibrator as FF device\n");
+               goto err_free_mem;
+       }
+
+       error = input_register_device(input_dev);
+       if (error) {
+               dev_err(&pdev->dev, "couldn't register input device\n");
+               goto err_destroy_memless;
+       }
+
+       platform_set_drvdata(pdev, vib);
+       return 0;
+
+err_destroy_memless:
+       input_ff_destroy(input_dev);
+err_free_mem:
+       input_free_device(input_dev);
+       kfree(vib);
+
+       return error;
+}
+
+static int __devexit pm8xxx_vib_remove(struct platform_device *pdev)
+{
+       struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
+
+       input_unregister_device(vib->vib_input_dev);
+       kfree(vib);
+
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pm8xxx_vib_suspend(struct device *dev)
+{
+       struct pm8xxx_vib *vib = dev_get_drvdata(dev);
+
+       /* Turn off the vibrator */
+       pm8xxx_vib_set(vib, false);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
+
+static struct platform_driver pm8xxx_vib_driver = {
+       .probe          = pm8xxx_vib_probe,
+       .remove         = __devexit_p(pm8xxx_vib_remove),
+       .driver         = {
+               .name   = "pm8xxx-vib",
+               .owner  = THIS_MODULE,
+               .pm     = &pm8xxx_vib_pm_ops,
+       },
+};
+
+static int __init pm8xxx_vib_init(void)
+{
+       return platform_driver_register(&pm8xxx_vib_driver);
+}
+module_init(pm8xxx_vib_init);
+
+static void __exit pm8xxx_vib_exit(void)
+{
+       platform_driver_unregister(&pm8xxx_vib_driver);
+}
+module_exit(pm8xxx_vib_exit);
+
+MODULE_ALIAS("platform:pm8xxx_vib");
+MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Amy Maloche <amaloche@codeaurora.org>");
index 3126983c004a96860d4b042295eec0cce7b09ef1..da280189ef07c573e0a2aa05971eb3f8bbba7f64 100644 (file)
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI   0x0245
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO    0x0246
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS    0x0247
+/* MacbookAir4,2 (unibody, July 2011) */
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI   0x024c
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO    0x024d
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS    0x024e
+/* Macbook8,2 (unibody) */
+#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI  0x0252
+#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO   0x0253
+#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS   0x0254
 
 #define BCM5974_DEVICE(prod) {                                 \
        .match_flags = (USB_DEVICE_ID_MATCH_DEVICE |            \
@@ -104,6 +112,14 @@ static const struct usb_device_id bcm5974_table[] = {
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
+       /* MacbookAir4,2 */
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
+       /* MacbookPro8,2 */
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
        /* Terminating entry */
        {}
 };
@@ -294,6 +310,30 @@ static const struct bcm5974_config bcm5974_config_table[] = {
                { DIM_X, DIM_X / SN_COORD, -4415, 5050 },
                { DIM_Y, DIM_Y / SN_COORD, -55, 6680 }
        },
+       {
+               USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI,
+               USB_DEVICE_ID_APPLE_WELLSPRING6_ISO,
+               USB_DEVICE_ID_APPLE_WELLSPRING6_JIS,
+               HAS_INTEGRATED_BUTTON,
+               0x84, sizeof(struct bt_data),
+               0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+               { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
+               { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
+               { DIM_X, DIM_X / SN_COORD, -4620, 5140 },
+               { DIM_Y, DIM_Y / SN_COORD, -150, 6600 }
+       },
+       {
+               USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI,
+               USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO,
+               USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS,
+               HAS_INTEGRATED_BUTTON,
+               0x84, sizeof(struct bt_data),
+               0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+               { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
+               { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
+               { DIM_X, DIM_X / SN_COORD, -4750, 5280 },
+               { DIM_Y, DIM_Y / SN_COORD, -150, 6730 }
+       },
        {}
 };
 
index 449c0a46dbac51ba881ba49b8cfff1c3861dfee7..d27c9d91630b8d4fbe676e83353d5ee71d71c771 100644 (file)
@@ -49,6 +49,7 @@ struct hid_descriptor {
 #define USB_REQ_GET_REPORT     0x01
 #define USB_REQ_SET_REPORT     0x09
 #define WAC_HID_FEATURE_REPORT 0x03
+#define WAC_MSG_RETRIES                5
 
 static int usb_get_report(struct usb_interface *intf, unsigned char type,
                                unsigned char id, void *buf, int size)
@@ -165,7 +166,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                        report,
                        hid_desc->wDescriptorLength,
                        5000); /* 5 secs */
-       } while (result < 0 && limit++ < 5);
+       } while (result < 0 && limit++ < WAC_MSG_RETRIES);
 
        /* No need to parse the Descriptor. It isn't an error though */
        if (result < 0)
@@ -319,24 +320,26 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
        int limit = 0, report_id = 2;
        int error = -ENOMEM;
 
-       rep_data = kmalloc(2, GFP_KERNEL);
+       rep_data = kmalloc(4, GFP_KERNEL);
        if (!rep_data)
                return error;
 
-       /* ask to report tablet data if it is 2FGT Tablet PC or
+       /* ask to report tablet data if it is MT Tablet PC or
         * not a Tablet PC */
        if (features->type == TABLETPC2FG) {
                do {
                        rep_data[0] = 3;
                        rep_data[1] = 4;
+                       rep_data[2] = 0;
+                       rep_data[3] = 0;
                        report_id = 3;
                        error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
-                               report_id, rep_data, 2);
+                               report_id, rep_data, 4);
                        if (error >= 0)
                                error = usb_get_report(intf,
                                        WAC_HID_FEATURE_REPORT, report_id,
-                                       rep_data, 3);
-               } while ((error < 0 || rep_data[1] != 4) && limit++ < 5);
+                                       rep_data, 4);
+               } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
        } else if (features->type != TABLETPC) {
                do {
                        rep_data[0] = 2;
@@ -347,7 +350,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
                                error = usb_get_report(intf,
                                        WAC_HID_FEATURE_REPORT, report_id,
                                        rep_data, 2);
-               } while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
+               } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES);
        }
 
        kfree(rep_data);
index 03ebcc8b24b59bc1ec5efa8f2d5d5465c53e3e56..c1c2f7b28d89ba1c2eae80a354a2bef156c5dbdf 100644 (file)
@@ -1460,6 +1460,9 @@ static const struct wacom_features wacom_features_0xD3 =
 static const struct wacom_features wacom_features_0xD4 =
        { "Wacom Bamboo Pen",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
          63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0xD5 =
+       { "Wacom Bamboo Pen 6x8",     WACOM_PKGLEN_BBFUN, 21648, 13530, 1023,
+         63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0xD6 =
        { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN,   14720,  9200, 1023,
          63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -1564,6 +1567,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xD2) },
        { USB_DEVICE_WACOM(0xD3) },
        { USB_DEVICE_WACOM(0xD4) },
+       { USB_DEVICE_WACOM(0xD5) },
        { USB_DEVICE_WACOM(0xD6) },
        { USB_DEVICE_WACOM(0xD7) },
        { USB_DEVICE_WACOM(0xD8) },
index ae00604a6a81d8c1cf37d65823d14eb728e36e3a..f5d66859f2322b362b4f2e3c747f62db8b20fe5d 100644 (file)
@@ -244,6 +244,7 @@ struct mxt_finger {
        int x;
        int y;
        int area;
+       int pressure;
 };
 
 /* Each client has this additional data */
@@ -536,6 +537,8 @@ static void mxt_input_report(struct mxt_data *data, int single_id)
                                        finger[id].x);
                        input_report_abs(input_dev, ABS_MT_POSITION_Y,
                                        finger[id].y);
+                       input_report_abs(input_dev, ABS_MT_PRESSURE,
+                                       finger[id].pressure);
                } else {
                        finger[id].status = 0;
                }
@@ -546,6 +549,8 @@ static void mxt_input_report(struct mxt_data *data, int single_id)
        if (status != MXT_RELEASE) {
                input_report_abs(input_dev, ABS_X, finger[single_id].x);
                input_report_abs(input_dev, ABS_Y, finger[single_id].y);
+               input_report_abs(input_dev,
+                                ABS_PRESSURE, finger[single_id].pressure);
        }
 
        input_sync(input_dev);
@@ -560,6 +565,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
        int x;
        int y;
        int area;
+       int pressure;
 
        /* Check the touch is present on the screen */
        if (!(status & MXT_DETECT)) {
@@ -584,6 +590,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
                y = y >> 2;
 
        area = message->message[4];
+       pressure = message->message[5];
 
        dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
                status & MXT_MOVE ? "moved" : "pressed",
@@ -594,6 +601,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
        finger[id].x = x;
        finger[id].y = y;
        finger[id].area = area;
+       finger[id].pressure = pressure;
 
        mxt_input_report(data, id);
 }
@@ -1116,6 +1124,8 @@ static int __devinit mxt_probe(struct i2c_client *client,
                             0, data->max_x, 0, 0);
        input_set_abs_params(input_dev, ABS_Y,
                             0, data->max_y, 0, 0);
+       input_set_abs_params(input_dev, ABS_PRESSURE,
+                            0, 255, 0, 0);
 
        /* For multi touch */
        input_mt_init_slots(input_dev, MXT_MAX_FINGER);
@@ -1125,6 +1135,8 @@ static int __devinit mxt_probe(struct i2c_client *client,
                             0, data->max_x, 0, 0);
        input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
                             0, data->max_y, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_PRESSURE,
+                            0, 255, 0, 0);
 
        input_set_drvdata(input_dev, data);
        i2c_set_clientdata(client, data);
index 4f2713d92791352c1fddd806b2252af69ed24fb6..4627fe55b4011b8f40809938f1fc497672c14b5e 100644 (file)
@@ -9,7 +9,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  */
 
 /*
index 089b0a0f3d8c3f51174bb9e31c5326c61e66d679..0e8f63e5b36ffbd3ee99e1a751dff2d4400e06e7 100644 (file)
@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/errno.h>
index 22f847c890c9bfc23fb5a2f5d7b7658d5551773e..fbd5d88ccd8f3fc07ef18777f05bbf8fede75994 100644 (file)
@@ -107,9 +107,10 @@ static int __devinit asic3_led_probe(struct platform_device *pdev)
        }
 
        led->cdev->name = led->name;
-       led->cdev->default_trigger = led->default_trigger;
+       led->cdev->flags = LED_CORE_SUSPENDRESUME;
        led->cdev->brightness_set = brightness_set;
        led->cdev->blink_set = blink_set;
+       led->cdev->default_trigger = led->default_trigger;
 
        ret = led_classdev_register(&pdev->dev, led->cdev);
        if (ret < 0)
@@ -136,12 +137,44 @@ static int __devexit asic3_led_remove(struct platform_device *pdev)
        return mfd_cell_disable(pdev);
 }
 
+static int asic3_led_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       const struct mfd_cell *cell = mfd_get_cell(pdev);
+       int ret;
+
+       ret = 0;
+       if (cell->suspend)
+               ret = (*cell->suspend)(pdev);
+
+       return ret;
+}
+
+static int asic3_led_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       const struct mfd_cell *cell = mfd_get_cell(pdev);
+       int ret;
+
+       ret = 0;
+       if (cell->resume)
+               ret = (*cell->resume)(pdev);
+
+       return ret;
+}
+
+static const struct dev_pm_ops asic3_led_pm_ops = {
+       .suspend        = asic3_led_suspend,
+       .resume         = asic3_led_resume,
+};
+
 static struct platform_driver asic3_led_driver = {
        .probe          = asic3_led_probe,
        .remove         = __devexit_p(asic3_led_remove),
        .driver         = {
                .name   = "leds-asic3",
                .owner  = THIS_MODULE,
+               .pm     = &asic3_led_pm_ops,
        },
 };
 
index 2535933c49f83cb9fa8b7488caddf6a20dd8db09..5c13e93898f91f8502c911642fa91075aefcbf79 100644 (file)
@@ -313,7 +313,7 @@ static int __init init(void)
        int err;
 
        /* Lguest can't run under Xen, VMI or itself.  It does Tricky Stuff. */
-       if (paravirt_enabled()) {
+       if (get_kernel_rpl() != 0) {
                printk("lguest is afraid of being a guest\n");
                return -EPERM;
        }
index f75a66e7d312a8e1efed3d2db37ba1c554785e94..0516a446c113fa34f8933665bffa3e2bff6eea8f 100644 (file)
@@ -208,6 +208,8 @@ config DM_DEBUG
 
          If unsure, say N.
 
+source "drivers/md/persistent-data/Kconfig"
+
 config DM_CRYPT
        tristate "Crypt target support"
        depends on BLK_DEV_DM
@@ -233,6 +235,13 @@ config DM_SNAPSHOT
        ---help---
          Allow volume managers to take writable snapshots of a device.
 
+config DM_THIN_PROVISIONING
+       tristate "Thin provisioning target (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       select DM_PERSISTENT_DATA
+       ---help---
+         Provides thin provisioning and snapshots that share a data store.
+
 config DM_MIRROR
        tristate "Mirror target"
        depends on BLK_DEV_DM
index 448838b1f92a492e30c0c8b86f2ffb014a5e27cf..e5b47d0f79ec075b9be781bb5a932b0e7925120e 100644 (file)
@@ -10,6 +10,7 @@ dm-snapshot-y += dm-snap.o dm-exception-store.o dm-snap-transient.o \
 dm-mirror-y    += dm-raid1.o
 dm-log-userspace-y \
                += dm-log-userspace-base.o dm-log-userspace-transfer.o
+dm-thin-pool-y += dm-thin.o dm-thin-metadata.o
 md-mod-y       += md.o bitmap.o
 raid456-y      += raid5.o
 
@@ -34,10 +35,12 @@ obj-$(CONFIG_DM_MULTIPATH)  += dm-multipath.o dm-round-robin.o
 obj-$(CONFIG_DM_MULTIPATH_QL)  += dm-queue-length.o
 obj-$(CONFIG_DM_MULTIPATH_ST)  += dm-service-time.o
 obj-$(CONFIG_DM_SNAPSHOT)      += dm-snapshot.o
+obj-$(CONFIG_DM_PERSISTENT_DATA)       += persistent-data/
 obj-$(CONFIG_DM_MIRROR)                += dm-mirror.o dm-log.o dm-region-hash.o
 obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o
 obj-$(CONFIG_DM_ZERO)          += dm-zero.o
 obj-$(CONFIG_DM_RAID)  += dm-raid.o
+obj-$(CONFIG_DM_THIN_PROVISIONING)     += dm-thin-pool.o
 
 ifeq ($(CONFIG_DM_UEVENT),y)
 dm-mod-objs                    += dm-uevent.o
index 49da55c1528aa01137a61c98d6033c9b84dc2e05..a9c709f193dc85a23523033174198a3784a75fc9 100644 (file)
@@ -1698,6 +1698,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
        ti->num_flush_requests = 1;
+       ti->discard_zeroes_data_unsupported = 1;
        return 0;
 
 bad:
index 89f73ca22cfa112e7c215f9ab5c846de80dd5da4..f84c08029b2154f6362220a5149a337622a23564 100644 (file)
@@ -81,8 +81,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
                 * corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>
                 */
                if (!strcasecmp(arg_name, "corrupt_bio_byte")) {
-                       if (!argc)
+                       if (!argc) {
                                ti->error = "Feature corrupt_bio_byte requires parameters";
+                               return -EINVAL;
+                       }
 
                        r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error);
                        if (r)
index f82147029636d87b30e990daa230dfb17ca69c50..d3c1ab86fde37a55c736a76e22805a68434a37a0 100644 (file)
@@ -66,6 +66,8 @@ struct dm_kcopyd_client {
        struct list_head pages_jobs;
 };
 
+static struct page_list zero_page_list;
+
 static void wake(struct dm_kcopyd_client *kc)
 {
        queue_work(kc->kcopyd_wq, &kc->kcopyd_work);
@@ -254,6 +256,9 @@ int __init dm_kcopyd_init(void)
        if (!_job_cache)
                return -ENOMEM;
 
+       zero_page_list.next = &zero_page_list;
+       zero_page_list.page = ZERO_PAGE(0);
+
        return 0;
 }
 
@@ -322,7 +327,7 @@ static int run_complete_job(struct kcopyd_job *job)
        dm_kcopyd_notify_fn fn = job->fn;
        struct dm_kcopyd_client *kc = job->kc;
 
-       if (job->pages)
+       if (job->pages && job->pages != &zero_page_list)
                kcopyd_put_pages(kc, job->pages);
        /*
         * If this is the master job, the sub jobs have already
@@ -484,6 +489,8 @@ static void dispatch_job(struct kcopyd_job *job)
        atomic_inc(&kc->nr_jobs);
        if (unlikely(!job->source.count))
                push(&kc->complete_jobs, job);
+       else if (job->pages == &zero_page_list)
+               push(&kc->io_jobs, job);
        else
                push(&kc->pages_jobs, job);
        wake(kc);
@@ -592,14 +599,20 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
        job->flags = flags;
        job->read_err = 0;
        job->write_err = 0;
-       job->rw = READ;
-
-       job->source = *from;
 
        job->num_dests = num_dests;
        memcpy(&job->dests, dests, sizeof(*dests) * num_dests);
 
-       job->pages = NULL;
+       if (from) {
+               job->source = *from;
+               job->pages = NULL;
+               job->rw = READ;
+       } else {
+               memset(&job->source, 0, sizeof job->source);
+               job->source.count = job->dests[0].count;
+               job->pages = &zero_page_list;
+               job->rw = WRITE;
+       }
 
        job->fn = fn;
        job->context = context;
@@ -648,6 +661,14 @@ void dm_kcopyd_do_callback(void *j, int read_err, unsigned long write_err)
 }
 EXPORT_SYMBOL(dm_kcopyd_do_callback);
 
+int dm_kcopyd_zero(struct dm_kcopyd_client *kc,
+                  unsigned num_dests, struct dm_io_region *dests,
+                  unsigned flags, dm_kcopyd_notify_fn fn, void *context)
+{
+       return dm_kcopyd_copy(kc, NULL, num_dests, dests, flags, fn, context);
+}
+EXPORT_SYMBOL(dm_kcopyd_zero);
+
 /*
  * Cancels a kcopyd job, eg. someone might be deactivating a
  * mirror.
index a002dd85db1e674e2efbc188a531f001c2d0716b..86df8b2cf927a07caa30258bc54c8ec7a0c0a694 100644 (file)
@@ -449,7 +449,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
                                rs->ti->error = "write_mostly option is only valid for RAID1";
                                return -EINVAL;
                        }
-                       if (value > rs->md.raid_disks) {
+                       if (value >= rs->md.raid_disks) {
                                rs->ti->error = "Invalid write_mostly drive index given";
                                return -EINVAL;
                        }
index 986b8754bb0813c59fb22a0feae7083740378f72..1594562d59167ebd7a4943522da53b152e8d7194 100644 (file)
@@ -55,6 +55,7 @@ struct dm_table {
        struct dm_target *targets;
 
        unsigned integrity_supported:1;
+       unsigned singleton:1;
 
        /*
         * Indicates the rw permissions for the new logical
@@ -740,6 +741,12 @@ int dm_table_add_target(struct dm_table *t, const char *type,
        char **argv;
        struct dm_target *tgt;
 
+       if (t->singleton) {
+               DMERR("%s: target type %s must appear alone in table",
+                     dm_device_name(t->md), t->targets->type->name);
+               return -EINVAL;
+       }
+
        if ((r = check_space(t)))
                return r;
 
@@ -758,6 +765,21 @@ int dm_table_add_target(struct dm_table *t, const char *type,
                return -EINVAL;
        }
 
+       if (dm_target_needs_singleton(tgt->type)) {
+               if (t->num_targets) {
+                       DMERR("%s: target type %s must appear alone in table",
+                             dm_device_name(t->md), type);
+                       return -EINVAL;
+               }
+               t->singleton = 1;
+       }
+
+       if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) {
+               DMERR("%s: target type %s may not be included in read-only tables",
+                     dm_device_name(t->md), type);
+               return -EINVAL;
+       }
+
        tgt->table = t;
        tgt->begin = start;
        tgt->len = len;
@@ -1238,14 +1260,15 @@ static void dm_table_set_integrity(struct dm_table *t)
                return;
 
        template_disk = dm_table_get_integrity_disk(t, true);
-       if (!template_disk &&
-           blk_integrity_is_initialized(dm_disk(t->md))) {
+       if (template_disk)
+               blk_integrity_register(dm_disk(t->md),
+                                      blk_get_integrity(template_disk));
+       else if (blk_integrity_is_initialized(dm_disk(t->md)))
                DMWARN("%s: device no longer has a valid integrity profile",
                       dm_device_name(t->md));
-               return;
-       }
-       blk_integrity_register(dm_disk(t->md),
-                              blk_get_integrity(template_disk));
+       else
+               DMWARN("%s: unable to establish an integrity profile",
+                      dm_device_name(t->md));
 }
 
 static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev,
@@ -1282,6 +1305,47 @@ static bool dm_table_supports_flush(struct dm_table *t, unsigned flush)
        return 0;
 }
 
+static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev,
+                           sector_t start, sector_t len, void *data)
+{
+       struct request_queue *q = bdev_get_queue(dev->bdev);
+
+       return q && blk_queue_nonrot(q);
+}
+
+static bool dm_table_is_nonrot(struct dm_table *t)
+{
+       struct dm_target *ti;
+       unsigned i = 0;
+
+       /* Ensure that all underlying device are non-rotational. */
+       while (i < dm_table_get_num_targets(t)) {
+               ti = dm_table_get_target(t, i++);
+
+               if (!ti->type->iterate_devices ||
+                   !ti->type->iterate_devices(ti, device_is_nonrot, NULL))
+                       return 0;
+       }
+
+       return 1;
+}
+
+static bool dm_table_discard_zeroes_data(struct dm_table *t)
+{
+       struct dm_target *ti;
+       unsigned i = 0;
+
+       /* Ensure that all targets supports discard_zeroes_data. */
+       while (i < dm_table_get_num_targets(t)) {
+               ti = dm_table_get_target(t, i++);
+
+               if (ti->discard_zeroes_data_unsupported)
+                       return 0;
+       }
+
+       return 1;
+}
+
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
                               struct queue_limits *limits)
 {
@@ -1304,6 +1368,14 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
        }
        blk_queue_flush(q, flush);
 
+       if (dm_table_is_nonrot(t))
+               queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+       else
+               queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
+
+       if (!dm_table_discard_zeroes_data(t))
+               q->limits.discard_zeroes_data = 0;
+
        dm_table_set_integrity(t);
 
        /*
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
new file mode 100644 (file)
index 0000000..b7feada
--- /dev/null
@@ -0,0 +1,1406 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-thin-metadata.h"
+#include "persistent-data/dm-btree.h"
+#include "persistent-data/dm-space-map.h"
+#include "persistent-data/dm-space-map-disk.h"
+#include "persistent-data/dm-transaction-manager.h"
+
+#include <linux/list.h>
+#include <linux/device-mapper.h>
+#include <linux/workqueue.h>
+
+/*--------------------------------------------------------------------------
+ * As far as the metadata goes, there is:
+ *
+ * - A superblock in block zero, taking up fewer than 512 bytes for
+ *   atomic writes.
+ *
+ * - A space map managing the metadata blocks.
+ *
+ * - A space map managing the data blocks.
+ *
+ * - A btree mapping our internal thin dev ids onto struct disk_device_details.
+ *
+ * - A hierarchical btree, with 2 levels which effectively maps (thin
+ *   dev id, virtual block) -> block_time.  Block time is a 64-bit
+ *   field holding the time in the low 24 bits, and block in the top 48
+ *   bits.
+ *
+ * BTrees consist solely of btree_nodes, that fill a block.  Some are
+ * internal nodes, as such their values are a __le64 pointing to other
+ * nodes.  Leaf nodes can store data of any reasonable size (ie. much
+ * smaller than the block size).  The nodes consist of the header,
+ * followed by an array of keys, followed by an array of values.  We have
+ * to binary search on the keys so they're all held together to help the
+ * cpu cache.
+ *
+ * Space maps have 2 btrees:
+ *
+ * - One maps a uint64_t onto a struct index_entry.  Which points to a
+ *   bitmap block, and has some details about how many free entries there
+ *   are etc.
+ *
+ * - The bitmap blocks have a header (for the checksum).  Then the rest
+ *   of the block is pairs of bits.  With the meaning being:
+ *
+ *   0 - ref count is 0
+ *   1 - ref count is 1
+ *   2 - ref count is 2
+ *   3 - ref count is higher than 2
+ *
+ * - If the count is higher than 2 then the ref count is entered in a
+ *   second btree that directly maps the block_address to a uint32_t ref
+ *   count.
+ *
+ * The space map metadata variant doesn't have a bitmaps btree.  Instead
+ * it has one single blocks worth of index_entries.  This avoids
+ * recursive issues with the bitmap btree needing to allocate space in
+ * order to insert.  With a small data block size such as 64k the
+ * metadata support data devices that are hundreds of terrabytes.
+ *
+ * The space maps allocate space linearly from front to back.  Space that
+ * is freed in a transaction is never recycled within that transaction.
+ * To try and avoid fragmenting _free_ space the allocator always goes
+ * back and fills in gaps.
+ *
+ * All metadata io is in THIN_METADATA_BLOCK_SIZE sized/aligned chunks
+ * from the block manager.
+ *--------------------------------------------------------------------------*/
+
+#define DM_MSG_PREFIX   "thin metadata"
+
+#define THIN_SUPERBLOCK_MAGIC 27022010
+#define THIN_SUPERBLOCK_LOCATION 0
+#define THIN_VERSION 1
+#define THIN_METADATA_BLOCK_SIZE 4096
+#define THIN_METADATA_CACHE_SIZE 64
+#define SECTOR_TO_BLOCK_SHIFT 3
+
+/* This should be plenty */
+#define SPACE_MAP_ROOT_SIZE 128
+
+/*
+ * Little endian on-disk superblock and device details.
+ */
+struct thin_disk_superblock {
+       __le32 csum;    /* Checksum of superblock except for this field. */
+       __le32 flags;
+       __le64 blocknr; /* This block number, dm_block_t. */
+
+       __u8 uuid[16];
+       __le64 magic;
+       __le32 version;
+       __le32 time;
+
+       __le64 trans_id;
+
+       /*
+        * Root held by userspace transactions.
+        */
+       __le64 held_root;
+
+       __u8 data_space_map_root[SPACE_MAP_ROOT_SIZE];
+       __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
+
+       /*
+        * 2-level btree mapping (dev_id, (dev block, time)) -> data block
+        */
+       __le64 data_mapping_root;
+
+       /*
+        * Device detail root mapping dev_id -> device_details
+        */
+       __le64 device_details_root;
+
+       __le32 data_block_size;         /* In 512-byte sectors. */
+
+       __le32 metadata_block_size;     /* In 512-byte sectors. */
+       __le64 metadata_nr_blocks;
+
+       __le32 compat_flags;
+       __le32 compat_ro_flags;
+       __le32 incompat_flags;
+} __packed;
+
+struct disk_device_details {
+       __le64 mapped_blocks;
+       __le64 transaction_id;          /* When created. */
+       __le32 creation_time;
+       __le32 snapshotted_time;
+} __packed;
+
+struct dm_pool_metadata {
+       struct hlist_node hash;
+
+       struct block_device *bdev;
+       struct dm_block_manager *bm;
+       struct dm_space_map *metadata_sm;
+       struct dm_space_map *data_sm;
+       struct dm_transaction_manager *tm;
+       struct dm_transaction_manager *nb_tm;
+
+       /*
+        * Two-level btree.
+        * First level holds thin_dev_t.
+        * Second level holds mappings.
+        */
+       struct dm_btree_info info;
+
+       /*
+        * Non-blocking version of the above.
+        */
+       struct dm_btree_info nb_info;
+
+       /*
+        * Just the top level for deleting whole devices.
+        */
+       struct dm_btree_info tl_info;
+
+       /*
+        * Just the bottom level for creating new devices.
+        */
+       struct dm_btree_info bl_info;
+
+       /*
+        * Describes the device details btree.
+        */
+       struct dm_btree_info details_info;
+
+       struct rw_semaphore root_lock;
+       uint32_t time;
+       int need_commit;
+       struct dm_block *sblock;
+       dm_block_t root;
+       dm_block_t details_root;
+       struct list_head thin_devices;
+       uint64_t trans_id;
+       unsigned long flags;
+       sector_t data_block_size;
+};
+
+struct dm_thin_device {
+       struct list_head list;
+       struct dm_pool_metadata *pmd;
+       dm_thin_id id;
+
+       int open_count;
+       int changed;
+       uint64_t mapped_blocks;
+       uint64_t transaction_id;
+       uint32_t creation_time;
+       uint32_t snapshotted_time;
+};
+
+/*----------------------------------------------------------------
+ * superblock validator
+ *--------------------------------------------------------------*/
+
+static void sb_prepare_for_write(struct dm_block_validator *v,
+                                struct dm_block *b,
+                                size_t block_size)
+{
+       struct thin_disk_superblock *disk_super = dm_block_data(b);
+
+       disk_super->blocknr = cpu_to_le64(dm_block_location(b));
+       disk_super->csum = cpu_to_le32(dm_block_csum_data(&disk_super->flags, sizeof(*disk_super) - sizeof(__le32)));
+}
+
+static int sb_check(struct dm_block_validator *v,
+                   struct dm_block *b,
+                   size_t block_size)
+{
+       struct thin_disk_superblock *disk_super = dm_block_data(b);
+       __le32 csum_le;
+
+       if (dm_block_location(b) != le64_to_cpu(disk_super->blocknr)) {
+               DMERR("sb_check failed: blocknr %llu: "
+                     "wanted %llu", le64_to_cpu(disk_super->blocknr),
+                     (unsigned long long)dm_block_location(b));
+               return -ENOTBLK;
+       }
+
+       if (le64_to_cpu(disk_super->magic) != THIN_SUPERBLOCK_MAGIC) {
+               DMERR("sb_check failed: magic %llu: "
+                     "wanted %llu", le64_to_cpu(disk_super->magic),
+                     (unsigned long long)THIN_SUPERBLOCK_MAGIC);
+               return -EILSEQ;
+       }
+
+       csum_le = cpu_to_le32(dm_block_csum_data(&disk_super->flags, sizeof(*disk_super) - sizeof(__le32)));
+       if (csum_le != disk_super->csum) {
+               DMERR("sb_check failed: csum %u: wanted %u",
+                     le32_to_cpu(csum_le), le32_to_cpu(disk_super->csum));
+               return -EILSEQ;
+       }
+
+       return 0;
+}
+
+static struct dm_block_validator sb_validator = {
+       .name = "superblock",
+       .prepare_for_write = sb_prepare_for_write,
+       .check = sb_check
+};
+
+/*----------------------------------------------------------------
+ * Methods for the btree value types
+ *--------------------------------------------------------------*/
+
+static uint64_t pack_block_time(dm_block_t b, uint32_t t)
+{
+       return (b << 24) | t;
+}
+
+static void unpack_block_time(uint64_t v, dm_block_t *b, uint32_t *t)
+{
+       *b = v >> 24;
+       *t = v & ((1 << 24) - 1);
+}
+
+static void data_block_inc(void *context, void *value_le)
+{
+       struct dm_space_map *sm = context;
+       __le64 v_le;
+       uint64_t b;
+       uint32_t t;
+
+       memcpy(&v_le, value_le, sizeof(v_le));
+       unpack_block_time(le64_to_cpu(v_le), &b, &t);
+       dm_sm_inc_block(sm, b);
+}
+
+static void data_block_dec(void *context, void *value_le)
+{
+       struct dm_space_map *sm = context;
+       __le64 v_le;
+       uint64_t b;
+       uint32_t t;
+
+       memcpy(&v_le, value_le, sizeof(v_le));
+       unpack_block_time(le64_to_cpu(v_le), &b, &t);
+       dm_sm_dec_block(sm, b);
+}
+
+static int data_block_equal(void *context, void *value1_le, void *value2_le)
+{
+       __le64 v1_le, v2_le;
+       uint64_t b1, b2;
+       uint32_t t;
+
+       memcpy(&v1_le, value1_le, sizeof(v1_le));
+       memcpy(&v2_le, value2_le, sizeof(v2_le));
+       unpack_block_time(le64_to_cpu(v1_le), &b1, &t);
+       unpack_block_time(le64_to_cpu(v2_le), &b2, &t);
+
+       return b1 == b2;
+}
+
+static void subtree_inc(void *context, void *value)
+{
+       struct dm_btree_info *info = context;
+       __le64 root_le;
+       uint64_t root;
+
+       memcpy(&root_le, value, sizeof(root_le));
+       root = le64_to_cpu(root_le);
+       dm_tm_inc(info->tm, root);
+}
+
+static void subtree_dec(void *context, void *value)
+{
+       struct dm_btree_info *info = context;
+       __le64 root_le;
+       uint64_t root;
+
+       memcpy(&root_le, value, sizeof(root_le));
+       root = le64_to_cpu(root_le);
+       if (dm_btree_destroy(info, root))
+               DMERR("btree delete failed\n");
+}
+
+static int subtree_equal(void *context, void *value1_le, void *value2_le)
+{
+       __le64 v1_le, v2_le;
+       memcpy(&v1_le, value1_le, sizeof(v1_le));
+       memcpy(&v2_le, value2_le, sizeof(v2_le));
+
+       return v1_le == v2_le;
+}
+
+/*----------------------------------------------------------------*/
+
+static int superblock_all_zeroes(struct dm_block_manager *bm, int *result)
+{
+       int r;
+       unsigned i;
+       struct dm_block *b;
+       __le64 *data_le, zero = cpu_to_le64(0);
+       unsigned block_size = dm_bm_block_size(bm) / sizeof(__le64);
+
+       /*
+        * We can't use a validator here - it may be all zeroes.
+        */
+       r = dm_bm_read_lock(bm, THIN_SUPERBLOCK_LOCATION, NULL, &b);
+       if (r)
+               return r;
+
+       data_le = dm_block_data(b);
+       *result = 1;
+       for (i = 0; i < block_size; i++) {
+               if (data_le[i] != zero) {
+                       *result = 0;
+                       break;
+               }
+       }
+
+       return dm_bm_unlock(b);
+}
+
+static struct dm_pool_metadata *alloc_pmd(struct dm_block_manager *bm,
+                                         dm_block_t nr_blocks, int create)
+{
+       int r;
+       struct dm_space_map *sm, *data_sm;
+       struct dm_transaction_manager *tm;
+       struct dm_pool_metadata *pmd = NULL;
+       struct dm_block *sblock;
+
+       if (create) {
+               r = dm_tm_create_with_sm(bm, THIN_SUPERBLOCK_LOCATION,
+                                        &sb_validator, &tm, &sm, &sblock);
+               if (r < 0) {
+                       DMERR("tm_create_with_sm failed");
+                       return ERR_PTR(r);
+               }
+
+               data_sm = dm_sm_disk_create(tm, nr_blocks);
+               if (IS_ERR(data_sm)) {
+                       DMERR("sm_disk_create failed");
+                       r = PTR_ERR(data_sm);
+                       goto bad;
+               }
+
+               r = dm_tm_pre_commit(tm);
+               if (r < 0) {
+                       DMERR("couldn't pre commit");
+                       goto bad_data_sm;
+               }
+
+               r = dm_tm_commit(tm, sblock);
+               if (r < 0) {
+                       DMERR("couldn't commit");
+                       goto bad_data_sm;
+               }
+       } else {
+               struct thin_disk_superblock *disk_super = NULL;
+               size_t space_map_root_offset =
+                       offsetof(struct thin_disk_superblock, metadata_space_map_root);
+
+               r = dm_tm_open_with_sm(bm, THIN_SUPERBLOCK_LOCATION,
+                                      &sb_validator, space_map_root_offset,
+                                      SPACE_MAP_ROOT_SIZE, &tm, &sm, &sblock);
+               if (r < 0) {
+                       DMERR("tm_open_with_sm failed");
+                       return ERR_PTR(r);
+               }
+
+               disk_super = dm_block_data(sblock);
+               data_sm = dm_sm_disk_open(tm, disk_super->data_space_map_root,
+                                         sizeof(disk_super->data_space_map_root));
+               if (IS_ERR(data_sm)) {
+                       DMERR("sm_disk_open failed");
+                       r = PTR_ERR(data_sm);
+                       goto bad;
+               }
+
+               dm_tm_unlock(tm, sblock);
+       }
+
+       pmd = kmalloc(sizeof(*pmd), GFP_KERNEL);
+       if (!pmd) {
+               DMERR("could not allocate metadata struct");
+               r = -ENOMEM;
+               goto bad_data_sm;
+       }
+
+       pmd->bm = bm;
+       pmd->metadata_sm = sm;
+       pmd->data_sm = data_sm;
+       pmd->tm = tm;
+       pmd->nb_tm = dm_tm_create_non_blocking_clone(tm);
+       if (!pmd->nb_tm) {
+               DMERR("could not create clone tm");
+               r = -ENOMEM;
+               goto bad_pmd;
+       }
+
+       pmd->sblock = NULL;
+
+       pmd->info.tm = tm;
+       pmd->info.levels = 2;
+       pmd->info.value_type.context = pmd->data_sm;
+       pmd->info.value_type.size = sizeof(__le64);
+       pmd->info.value_type.inc = data_block_inc;
+       pmd->info.value_type.dec = data_block_dec;
+       pmd->info.value_type.equal = data_block_equal;
+
+       memcpy(&pmd->nb_info, &pmd->info, sizeof(pmd->nb_info));
+       pmd->nb_info.tm = pmd->nb_tm;
+
+       pmd->tl_info.tm = tm;
+       pmd->tl_info.levels = 1;
+       pmd->tl_info.value_type.context = &pmd->info;
+       pmd->tl_info.value_type.size = sizeof(__le64);
+       pmd->tl_info.value_type.inc = subtree_inc;
+       pmd->tl_info.value_type.dec = subtree_dec;
+       pmd->tl_info.value_type.equal = subtree_equal;
+
+       pmd->bl_info.tm = tm;
+       pmd->bl_info.levels = 1;
+       pmd->bl_info.value_type.context = pmd->data_sm;
+       pmd->bl_info.value_type.size = sizeof(__le64);
+       pmd->bl_info.value_type.inc = data_block_inc;
+       pmd->bl_info.value_type.dec = data_block_dec;
+       pmd->bl_info.value_type.equal = data_block_equal;
+
+       pmd->details_info.tm = tm;
+       pmd->details_info.levels = 1;
+       pmd->details_info.value_type.context = NULL;
+       pmd->details_info.value_type.size = sizeof(struct disk_device_details);
+       pmd->details_info.value_type.inc = NULL;
+       pmd->details_info.value_type.dec = NULL;
+       pmd->details_info.value_type.equal = NULL;
+
+       pmd->root = 0;
+
+       init_rwsem(&pmd->root_lock);
+       pmd->time = 0;
+       pmd->need_commit = 0;
+       pmd->details_root = 0;
+       INIT_LIST_HEAD(&pmd->thin_devices);
+
+       return pmd;
+
+bad_pmd:
+       kfree(pmd);
+bad_data_sm:
+       dm_sm_destroy(data_sm);
+bad:
+       dm_tm_destroy(tm);
+       dm_sm_destroy(sm);
+
+       return ERR_PTR(r);
+}
+
+static int __begin_transaction(struct dm_pool_metadata *pmd)
+{
+       int r;
+       u32 features;
+       struct thin_disk_superblock *disk_super;
+
+       /*
+        * __maybe_commit_transaction() resets these
+        */
+       WARN_ON(pmd->sblock);
+       WARN_ON(pmd->need_commit);
+
+       /*
+        * superblock is unlocked via dm_tm_commit()
+        */
+       r = dm_bm_write_lock(pmd->bm, THIN_SUPERBLOCK_LOCATION,
+                            &sb_validator, &pmd->sblock);
+       if (r)
+               return r;
+
+       disk_super = dm_block_data(pmd->sblock);
+       pmd->time = le32_to_cpu(disk_super->time);
+       pmd->root = le64_to_cpu(disk_super->data_mapping_root);
+       pmd->details_root = le64_to_cpu(disk_super->device_details_root);
+       pmd->trans_id = le64_to_cpu(disk_super->trans_id);
+       pmd->flags = le32_to_cpu(disk_super->flags);
+       pmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
+
+       features = le32_to_cpu(disk_super->incompat_flags) & ~THIN_FEATURE_INCOMPAT_SUPP;
+       if (features) {
+               DMERR("could not access metadata due to "
+                     "unsupported optional features (%lx).",
+                     (unsigned long)features);
+               return -EINVAL;
+       }
+
+       /*
+        * Check for read-only metadata to skip the following RDWR checks.
+        */
+       if (get_disk_ro(pmd->bdev->bd_disk))
+               return 0;
+
+       features = le32_to_cpu(disk_super->compat_ro_flags) & ~THIN_FEATURE_COMPAT_RO_SUPP;
+       if (features) {
+               DMERR("could not access metadata RDWR due to "
+                     "unsupported optional features (%lx).",
+                     (unsigned long)features);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int __write_changed_details(struct dm_pool_metadata *pmd)
+{
+       int r;
+       struct dm_thin_device *td, *tmp;
+       struct disk_device_details details;
+       uint64_t key;
+
+       list_for_each_entry_safe(td, tmp, &pmd->thin_devices, list) {
+               if (!td->changed)
+                       continue;
+
+               key = td->id;
+
+               details.mapped_blocks = cpu_to_le64(td->mapped_blocks);
+               details.transaction_id = cpu_to_le64(td->transaction_id);
+               details.creation_time = cpu_to_le32(td->creation_time);
+               details.snapshotted_time = cpu_to_le32(td->snapshotted_time);
+               __dm_bless_for_disk(&details);
+
+               r = dm_btree_insert(&pmd->details_info, pmd->details_root,
+                                   &key, &details, &pmd->details_root);
+               if (r)
+                       return r;
+
+               if (td->open_count)
+                       td->changed = 0;
+               else {
+                       list_del(&td->list);
+                       kfree(td);
+               }
+
+               pmd->need_commit = 1;
+       }
+
+       return 0;
+}
+
+/*
+ * If there is data waiting to be committed, commit it.
+ * Returns 1 if commit took place, 0 if not, or < 0 on error.
+ */
+static int __maybe_commit_transaction(struct dm_pool_metadata *pmd)
+{
+       /*
+        * FIXME: Associated pool should be made read-only on failure.
+        */
+       int r;
+       size_t len;
+       struct thin_disk_superblock *disk_super;
+
+       /*
+        * thin_disk_superblock is assumed not to exceed a 512-byte sector.
+        */
+       BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512);
+
+       r = __write_changed_details(pmd);
+       if (r < 0)
+               goto out;
+
+       if (!pmd->need_commit)
+               goto out;
+
+       r = dm_tm_pre_commit(pmd->tm);
+       if (r < 0)
+               goto out;
+
+       r = dm_sm_root_size(pmd->metadata_sm, &len);
+       if (r < 0)
+               goto out;
+
+       disk_super = dm_block_data(pmd->sblock);
+       disk_super->time = cpu_to_le32(pmd->time);
+       disk_super->data_mapping_root = cpu_to_le64(pmd->root);
+       disk_super->device_details_root = cpu_to_le64(pmd->details_root);
+       disk_super->trans_id = cpu_to_le64(pmd->trans_id);
+       disk_super->flags = cpu_to_le32(pmd->flags);
+
+       r = dm_sm_copy_root(pmd->metadata_sm, &disk_super->metadata_space_map_root, len);
+       if (r < 0)
+               goto out;
+
+       r = dm_sm_copy_root(pmd->data_sm, &disk_super->data_space_map_root, len);
+       if (r < 0)
+               goto out;
+
+       r = dm_tm_commit(pmd->tm, pmd->sblock);
+       if (!r) {
+               r = 1;
+               pmd->sblock = NULL;
+               pmd->need_commit = 0;
+       }
+
+out:
+       return r;
+}
+
+int dm_pool_commit_metadata(struct dm_pool_metadata *pmd)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+
+       r = __maybe_commit_transaction(pmd);
+       if (r <= 0)
+               goto out;
+
+       /*
+        * Open the next transaction.
+        */
+       r = __begin_transaction(pmd);
+
+out:
+       up_write(&pmd->root_lock);
+       return r;
+}
+
+struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
+                                              sector_t data_block_size)
+{
+       int r;
+       struct thin_disk_superblock *disk_super;
+       struct dm_pool_metadata *pmd;
+       sector_t bdev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
+       struct dm_block_manager *bm;
+       int create;
+
+       bm = dm_block_manager_create(bdev, THIN_METADATA_BLOCK_SIZE,
+                                    THIN_METADATA_CACHE_SIZE, 6);
+       if (!bm) {
+               DMERR("could not create block manager");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       r = superblock_all_zeroes(bm, &create);
+       if (r) {
+               dm_block_manager_destroy(bm);
+               return ERR_PTR(r);
+       }
+
+       pmd = alloc_pmd(bm, 0, create);
+       if (IS_ERR(pmd)) {
+               dm_block_manager_destroy(bm);
+               return pmd;
+       }
+       pmd->bdev = bdev;
+
+       if (!create) {
+               r = __begin_transaction(pmd);
+               if (r < 0)
+                       goto bad;
+               return pmd;
+       }
+
+       /*
+        * Create.
+        */
+       if (!pmd->sblock) {
+               r = __begin_transaction(pmd);
+               if (r < 0)
+                       goto bad;
+       }
+
+       disk_super = dm_block_data(pmd->sblock);
+       disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC);
+       disk_super->version = cpu_to_le32(THIN_VERSION);
+       disk_super->time = 0;
+       disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
+       disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT);
+       disk_super->data_block_size = cpu_to_le32(data_block_size);
+
+       r = dm_btree_create(&pmd->info, &pmd->root);
+       if (r < 0)
+               goto bad;
+
+       r = dm_btree_create(&pmd->details_info, &pmd->details_root);
+       if (r < 0) {
+               DMERR("couldn't create devices root");
+               goto bad;
+       }
+
+       pmd->flags = 0;
+       pmd->need_commit = 1;
+       r = dm_pool_commit_metadata(pmd);
+       if (r < 0) {
+               DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
+                     __func__, r);
+               goto bad;
+       }
+
+       return pmd;
+
+bad:
+       if (dm_pool_metadata_close(pmd) < 0)
+               DMWARN("%s: dm_pool_metadata_close() failed.", __func__);
+       return ERR_PTR(r);
+}
+
+int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
+{
+       int r;
+       unsigned open_devices = 0;
+       struct dm_thin_device *td, *tmp;
+
+       down_read(&pmd->root_lock);
+       list_for_each_entry_safe(td, tmp, &pmd->thin_devices, list) {
+               if (td->open_count)
+                       open_devices++;
+               else {
+                       list_del(&td->list);
+                       kfree(td);
+               }
+       }
+       up_read(&pmd->root_lock);
+
+       if (open_devices) {
+               DMERR("attempt to close pmd when %u device(s) are still open",
+                      open_devices);
+               return -EBUSY;
+       }
+
+       if (pmd->sblock) {
+               r = __maybe_commit_transaction(pmd);
+               if (r < 0)
+                       DMWARN("%s: __maybe_commit_transaction() failed, error = %d",
+                              __func__, r);
+               if (pmd->sblock)
+                       dm_tm_unlock(pmd->tm, pmd->sblock);
+       }
+
+       dm_tm_destroy(pmd->tm);
+       dm_tm_destroy(pmd->nb_tm);
+       dm_block_manager_destroy(pmd->bm);
+       dm_sm_destroy(pmd->metadata_sm);
+       dm_sm_destroy(pmd->data_sm);
+       kfree(pmd);
+
+       return 0;
+}
+
+int dm_pool_rebind_metadata_device(struct dm_pool_metadata *pmd,
+                                        struct block_device *bdev)
+{
+       return dm_bm_rebind_block_device(pmd->bm, bdev);
+}
+
+static int __open_device(struct dm_pool_metadata *pmd,
+                        dm_thin_id dev, int create,
+                        struct dm_thin_device **td)
+{
+       int r, changed = 0;
+       struct dm_thin_device *td2;
+       uint64_t key = dev;
+       struct disk_device_details details_le;
+
+       /*
+        * If the device is already open, just increment its open_count.
+        */
+       list_for_each_entry(td2, &pmd->thin_devices, list)
+               if (td2->id == dev) {
+                       td2->open_count++;
+                       *td = td2;
+                       return 0;
+               }
+
+       /*
+        * Check the device exists.
+        */
+       r = dm_btree_lookup(&pmd->details_info, pmd->details_root,
+                           &key, &details_le);
+       if (r) {
+               if (r != -ENODATA || !create)
+                       return r;
+
+               /*
+                * New device.
+                */
+               changed = 1;
+               details_le.mapped_blocks = 0;
+               details_le.transaction_id = cpu_to_le64(pmd->trans_id);
+               details_le.creation_time = cpu_to_le32(pmd->time);
+               details_le.snapshotted_time = cpu_to_le32(pmd->time);
+       }
+
+       *td = kmalloc(sizeof(**td), GFP_NOIO);
+       if (!*td)
+               return -ENOMEM;
+
+       (*td)->pmd = pmd;
+       (*td)->id = dev;
+       (*td)->open_count = 1;
+       (*td)->changed = changed;
+       (*td)->mapped_blocks = le64_to_cpu(details_le.mapped_blocks);
+       (*td)->transaction_id = le64_to_cpu(details_le.transaction_id);
+       (*td)->creation_time = le32_to_cpu(details_le.creation_time);
+       (*td)->snapshotted_time = le32_to_cpu(details_le.snapshotted_time);
+
+       list_add(&(*td)->list, &pmd->thin_devices);
+
+       return 0;
+}
+
+static void __close_device(struct dm_thin_device *td)
+{
+       --td->open_count;
+}
+
+static int __create_thin(struct dm_pool_metadata *pmd,
+                        dm_thin_id dev)
+{
+       int r;
+       dm_block_t dev_root;
+       uint64_t key = dev;
+       struct disk_device_details details_le;
+       struct dm_thin_device *td;
+       __le64 value;
+
+       r = dm_btree_lookup(&pmd->details_info, pmd->details_root,
+                           &key, &details_le);
+       if (!r)
+               return -EEXIST;
+
+       /*
+        * Create an empty btree for the mappings.
+        */
+       r = dm_btree_create(&pmd->bl_info, &dev_root);
+       if (r)
+               return r;
+
+       /*
+        * Insert it into the main mapping tree.
+        */
+       value = cpu_to_le64(dev_root);
+       __dm_bless_for_disk(&value);
+       r = dm_btree_insert(&pmd->tl_info, pmd->root, &key, &value, &pmd->root);
+       if (r) {
+               dm_btree_destroy(&pmd->bl_info, dev_root);
+               return r;
+       }
+
+       r = __open_device(pmd, dev, 1, &td);
+       if (r) {
+               __close_device(td);
+               dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
+               dm_btree_destroy(&pmd->bl_info, dev_root);
+               return r;
+       }
+       td->changed = 1;
+       __close_device(td);
+
+       return r;
+}
+
+int dm_pool_create_thin(struct dm_pool_metadata *pmd, dm_thin_id dev)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+       r = __create_thin(pmd, dev);
+       up_write(&pmd->root_lock);
+
+       return r;
+}
+
+static int __set_snapshot_details(struct dm_pool_metadata *pmd,
+                                 struct dm_thin_device *snap,
+                                 dm_thin_id origin, uint32_t time)
+{
+       int r;
+       struct dm_thin_device *td;
+
+       r = __open_device(pmd, origin, 0, &td);
+       if (r)
+               return r;
+
+       td->changed = 1;
+       td->snapshotted_time = time;
+
+       snap->mapped_blocks = td->mapped_blocks;
+       snap->snapshotted_time = time;
+       __close_device(td);
+
+       return 0;
+}
+
+static int __create_snap(struct dm_pool_metadata *pmd,
+                        dm_thin_id dev, dm_thin_id origin)
+{
+       int r;
+       dm_block_t origin_root, snap_root;
+       uint64_t key = origin, dev_key = dev;
+       struct dm_thin_device *td;
+       struct disk_device_details details_le;
+       __le64 value;
+
+       /* check this device is unused */
+       r = dm_btree_lookup(&pmd->details_info, pmd->details_root,
+                           &dev_key, &details_le);
+       if (!r)
+               return -EEXIST;
+
+       /* find the mapping tree for the origin */
+       r = dm_btree_lookup(&pmd->tl_info, pmd->root, &key, &value);
+       if (r)
+               return r;
+       origin_root = le64_to_cpu(value);
+
+       /* clone the origin */
+       r = dm_btree_clone(&pmd->bl_info, origin_root, &snap_root);
+       if (r)
+               return r;
+
+       /* insert into the main mapping tree */
+       value = cpu_to_le64(snap_root);
+       __dm_bless_for_disk(&value);
+       key = dev;
+       r = dm_btree_insert(&pmd->tl_info, pmd->root, &key, &value, &pmd->root);
+       if (r) {
+               dm_btree_destroy(&pmd->bl_info, snap_root);
+               return r;
+       }
+
+       pmd->time++;
+
+       r = __open_device(pmd, dev, 1, &td);
+       if (r)
+               goto bad;
+
+       r = __set_snapshot_details(pmd, td, origin, pmd->time);
+       if (r)
+               goto bad;
+
+       __close_device(td);
+       return 0;
+
+bad:
+       __close_device(td);
+       dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
+       dm_btree_remove(&pmd->details_info, pmd->details_root,
+                       &key, &pmd->details_root);
+       return r;
+}
+
+int dm_pool_create_snap(struct dm_pool_metadata *pmd,
+                                dm_thin_id dev,
+                                dm_thin_id origin)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+       r = __create_snap(pmd, dev, origin);
+       up_write(&pmd->root_lock);
+
+       return r;
+}
+
+static int __delete_device(struct dm_pool_metadata *pmd, dm_thin_id dev)
+{
+       int r;
+       uint64_t key = dev;
+       struct dm_thin_device *td;
+
+       /* TODO: failure should mark the transaction invalid */
+       r = __open_device(pmd, dev, 0, &td);
+       if (r)
+               return r;
+
+       if (td->open_count > 1) {
+               __close_device(td);
+               return -EBUSY;
+       }
+
+       list_del(&td->list);
+       kfree(td);
+       r = dm_btree_remove(&pmd->details_info, pmd->details_root,
+                           &key, &pmd->details_root);
+       if (r)
+               return r;
+
+       r = dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
+       if (r)
+               return r;
+
+       pmd->need_commit = 1;
+
+       return 0;
+}
+
+int dm_pool_delete_thin_device(struct dm_pool_metadata *pmd,
+                              dm_thin_id dev)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+       r = __delete_device(pmd, dev);
+       up_write(&pmd->root_lock);
+
+       return r;
+}
+
+static int __trim_thin_dev(struct dm_thin_device *td, sector_t new_size)
+{
+       struct dm_pool_metadata *pmd = td->pmd;
+       /* FIXME: convert new size to blocks */
+       uint64_t key[2] = { td->id, new_size - 1 };
+
+       td->changed = 1;
+
+       /*
+        * We need to truncate all the extraneous mappings.
+        *
+        * FIXME: We have to be careful to do this atomically.
+        * Perhaps clone the bottom layer first so we can revert?
+        */
+       return dm_btree_delete_gt(&pmd->info, pmd->root, key, &pmd->root);
+}
+
+// FIXME Incomplete implementation. Finish or remove it before final submission.
+int dm_pool_trim_thin_device(struct dm_pool_metadata *pmd, dm_thin_id dev,
+                            sector_t new_size)
+{
+       int r;
+       struct dm_thin_device *td;
+
+       down_write(&pmd->root_lock);
+       r = __open_device(pmd, dev, 1, &td);
+       if (r)
+               DMERR("couldn't open virtual device");
+       else {
+               r = __trim_thin_dev(td, new_size);
+               __close_device(td);
+       }
+
+       /* FIXME: update mapped_blocks */
+
+       up_write(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_set_metadata_transaction_id(struct dm_pool_metadata *pmd,
+                                       uint64_t current_id,
+                                       uint64_t new_id)
+{
+       down_write(&pmd->root_lock);
+       if (pmd->trans_id != current_id) {
+               up_write(&pmd->root_lock);
+               DMERR("mismatched transaction id");
+               return -EINVAL;
+       }
+
+       pmd->trans_id = new_id;
+       pmd->need_commit = 1;
+       up_write(&pmd->root_lock);
+
+       return 0;
+}
+
+int dm_pool_get_metadata_transaction_id(struct dm_pool_metadata *pmd,
+                                       uint64_t *result)
+{
+       down_read(&pmd->root_lock);
+       *result = pmd->trans_id;
+       up_read(&pmd->root_lock);
+
+       return 0;
+}
+
+int dm_pool_get_held_metadata_root(struct dm_pool_metadata *pmd,
+                                  dm_block_t *result)
+{
+       struct thin_disk_superblock *disk_super;
+
+       down_read(&pmd->root_lock);
+       disk_super = dm_block_data(pmd->sblock);
+       *result = le64_to_cpu(disk_super->held_root);
+       up_read(&pmd->root_lock);
+
+       return 0;
+}
+
+int dm_pool_open_thin_device(struct dm_pool_metadata *pmd, dm_thin_id dev,
+                            struct dm_thin_device **td)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+       r = __open_device(pmd, dev, 0, td);
+       up_write(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_close_thin_device(struct dm_thin_device *td)
+{
+       down_write(&td->pmd->root_lock);
+       __close_device(td);
+       up_write(&td->pmd->root_lock);
+
+       return 0;
+}
+
+dm_thin_id dm_thin_dev_id(struct dm_thin_device *td)
+{
+       return td->id;
+}
+
+static int __snapshotted_since(struct dm_thin_device *td, uint32_t time)
+{
+       return td->snapshotted_time > time;
+}
+
+int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block,
+                      int can_block, struct dm_thin_lookup_result *result)
+{
+       int r;
+       uint64_t block_time = 0;
+       __le64 value;
+       struct dm_pool_metadata *pmd = td->pmd;
+       dm_block_t keys[2] = { td->id, block };
+
+       if (can_block) {
+               down_read(&pmd->root_lock);
+               r = dm_btree_lookup(&pmd->info, pmd->root, keys, &value);
+               if (!r)
+                       block_time = le64_to_cpu(value);
+               up_read(&pmd->root_lock);
+
+       } else if (down_read_trylock(&pmd->root_lock)) {
+               r = dm_btree_lookup(&pmd->nb_info, pmd->root, keys, &value);
+               if (!r)
+                       block_time = le64_to_cpu(value);
+               up_read(&pmd->root_lock);
+
+       } else
+               return -EWOULDBLOCK;
+
+       if (!r) {
+               dm_block_t exception_block;
+               uint32_t exception_time;
+               unpack_block_time(block_time, &exception_block,
+                                 &exception_time);
+               result->block = exception_block;
+               result->shared = __snapshotted_since(td, exception_time);
+       }
+
+       return r;
+}
+
+static int __insert(struct dm_thin_device *td, dm_block_t block,
+                   dm_block_t data_block)
+{
+       int r, inserted;
+       __le64 value;
+       struct dm_pool_metadata *pmd = td->pmd;
+       dm_block_t keys[2] = { td->id, block };
+
+       pmd->need_commit = 1;
+       value = cpu_to_le64(pack_block_time(data_block, pmd->time));
+       __dm_bless_for_disk(&value);
+
+       r = dm_btree_insert_notify(&pmd->info, pmd->root, keys, &value,
+                                  &pmd->root, &inserted);
+       if (r)
+               return r;
+
+       if (inserted) {
+               td->mapped_blocks++;
+               td->changed = 1;
+       }
+
+       return 0;
+}
+
+int dm_thin_insert_block(struct dm_thin_device *td, dm_block_t block,
+                        dm_block_t data_block)
+{
+       int r;
+
+       down_write(&td->pmd->root_lock);
+       r = __insert(td, block, data_block);
+       up_write(&td->pmd->root_lock);
+
+       return r;
+}
+
+static int __remove(struct dm_thin_device *td, dm_block_t block)
+{
+       int r;
+       struct dm_pool_metadata *pmd = td->pmd;
+       dm_block_t keys[2] = { td->id, block };
+
+       r = dm_btree_remove(&pmd->info, pmd->root, keys, &pmd->root);
+       if (r)
+               return r;
+
+       pmd->need_commit = 1;
+
+       return 0;
+}
+
+int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block)
+{
+       int r;
+
+       down_write(&td->pmd->root_lock);
+       r = __remove(td, block);
+       up_write(&td->pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_alloc_data_block(struct dm_pool_metadata *pmd, dm_block_t *result)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+
+       r = dm_sm_new_block(pmd->data_sm, result);
+       pmd->need_commit = 1;
+
+       up_write(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_get_free_block_count(struct dm_pool_metadata *pmd, dm_block_t *result)
+{
+       int r;
+
+       down_read(&pmd->root_lock);
+       r = dm_sm_get_nr_free(pmd->data_sm, result);
+       up_read(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_get_free_metadata_block_count(struct dm_pool_metadata *pmd,
+                                         dm_block_t *result)
+{
+       int r;
+
+       down_read(&pmd->root_lock);
+       r = dm_sm_get_nr_free(pmd->metadata_sm, result);
+       up_read(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_get_metadata_dev_size(struct dm_pool_metadata *pmd,
+                                 dm_block_t *result)
+{
+       int r;
+
+       down_read(&pmd->root_lock);
+       r = dm_sm_get_nr_blocks(pmd->metadata_sm, result);
+       up_read(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_pool_get_data_block_size(struct dm_pool_metadata *pmd, sector_t *result)
+{
+       down_read(&pmd->root_lock);
+       *result = pmd->data_block_size;
+       up_read(&pmd->root_lock);
+
+       return 0;
+}
+
+int dm_pool_get_data_dev_size(struct dm_pool_metadata *pmd, dm_block_t *result)
+{
+       int r;
+
+       down_read(&pmd->root_lock);
+       r = dm_sm_get_nr_blocks(pmd->data_sm, result);
+       up_read(&pmd->root_lock);
+
+       return r;
+}
+
+int dm_thin_get_mapped_count(struct dm_thin_device *td, dm_block_t *result)
+{
+       struct dm_pool_metadata *pmd = td->pmd;
+
+       down_read(&pmd->root_lock);
+       *result = td->mapped_blocks;
+       up_read(&pmd->root_lock);
+
+       return 0;
+}
+
+static int __highest_block(struct dm_thin_device *td, dm_block_t *result)
+{
+       int r;
+       __le64 value_le;
+       dm_block_t thin_root;
+       struct dm_pool_metadata *pmd = td->pmd;
+
+       r = dm_btree_lookup(&pmd->tl_info, pmd->root, &td->id, &value_le);
+       if (r)
+               return r;
+
+       thin_root = le64_to_cpu(value_le);
+
+       return dm_btree_find_highest_key(&pmd->bl_info, thin_root, result);
+}
+
+int dm_thin_get_highest_mapped_block(struct dm_thin_device *td,
+                                    dm_block_t *result)
+{
+       int r;
+       struct dm_pool_metadata *pmd = td->pmd;
+
+       down_read(&pmd->root_lock);
+       r = __highest_block(td, result);
+       up_read(&pmd->root_lock);
+
+       return r;
+}
+
+static int __resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_count)
+{
+       int r;
+       dm_block_t old_count;
+
+       r = dm_sm_get_nr_blocks(pmd->data_sm, &old_count);
+       if (r)
+               return r;
+
+       if (new_count == old_count)
+               return 0;
+
+       if (new_count < old_count) {
+               DMERR("cannot reduce size of data device");
+               return -EINVAL;
+       }
+
+       r = dm_sm_extend(pmd->data_sm, new_count - old_count);
+       if (!r)
+               pmd->need_commit = 1;
+
+       return r;
+}
+
+int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_count)
+{
+       int r;
+
+       down_write(&pmd->root_lock);
+       r = __resize_data_dev(pmd, new_count);
+       up_write(&pmd->root_lock);
+
+       return r;
+}
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h
new file mode 100644 (file)
index 0000000..7eb7296
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_THIN_METADATA_H
+#define DM_THIN_METADATA_H
+
+#include "persistent-data/dm-block-manager.h"
+
+/*----------------------------------------------------------------*/
+
+struct dm_pool_metadata;
+struct dm_thin_device;
+
+/*
+ * Device identifier
+ */
+typedef uint64_t dm_thin_id;
+
+/*
+ * Reopens or creates a new, empty metadata volume.
+ */
+struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
+                                              sector_t data_block_size);
+
+int dm_pool_metadata_close(struct dm_pool_metadata *pmd);
+
+/*
+ * This does not currently resize the metadata device, but should eventually.
+ */
+int dm_pool_rebind_metadata_device(struct dm_pool_metadata *pmd,
+                                  struct block_device *bdev);
+
+/*
+ * Compat feature flags.  Any incompat flags beyond the ones
+ * specified below will prevent use of the thin metadata.
+ */
+#define THIN_FEATURE_COMPAT_SUPP         0UL
+#define THIN_FEATURE_COMPAT_RO_SUPP      0UL
+#define THIN_FEATURE_INCOMPAT_SUPP       0UL
+
+/*
+ * Device creation/deletion.
+ */
+int dm_pool_create_thin(struct dm_pool_metadata *pmd, dm_thin_id dev);
+
+/*
+ * An internal snapshot.
+ *
+ * You can only snapshot a quiesced origin i.e. one that is either
+ * suspended or not instanced at all.
+ */
+int dm_pool_create_snap(struct dm_pool_metadata *pmd, dm_thin_id dev,
+                       dm_thin_id origin);
+
+/*
+ * Deletes a virtual device from the metadata.  It _is_ safe to call this
+ * when that device is open.  Operations on that device will just start
+ * failing.  You still need to call close() on the device.
+ */
+int dm_pool_delete_thin_device(struct dm_pool_metadata *pmd,
+                              dm_thin_id dev);
+
+/*
+ * Thin devices don't have a size, however they do keep track of the
+ * highest mapped block.  This trimming function allows the user to remove
+ * mappings above a certain virtual block.
+ */
+int dm_pool_trim_thin_device(struct dm_pool_metadata *pmd, dm_thin_id dev,
+                            sector_t new_size);
+
+/*
+ * Commits _all_ metadata changes: device creation, deletion, mapping
+ * updates.
+ */
+int dm_pool_commit_metadata(struct dm_pool_metadata *pmd);
+
+/*
+ * Set/get userspace transaction id.
+ */
+int dm_pool_set_metadata_transaction_id(struct dm_pool_metadata *pmd,
+                                       uint64_t current_id,
+                                       uint64_t new_id);
+
+int dm_pool_get_metadata_transaction_id(struct dm_pool_metadata *pmd,
+                                       uint64_t *result);
+
+/*
+ * Hold/get root for userspace transaction.
+ */
+int dm_pool_hold_metadata_root(struct dm_pool_metadata *pmd);
+
+int dm_pool_get_held_metadata_root(struct dm_pool_metadata *pmd,
+                                  dm_block_t *result);
+
+/*
+ * Actions on a single virtual device.
+ */
+
+/*
+ * Opening the same device more than once will fail with -EBUSY.
+ */
+int dm_pool_open_thin_device(struct dm_pool_metadata *pmd, dm_thin_id dev,
+                            struct dm_thin_device **td);
+
+int dm_pool_close_thin_device(struct dm_thin_device *td);
+
+dm_thin_id dm_thin_dev_id(struct dm_thin_device *td);
+
+struct dm_thin_lookup_result {
+       dm_block_t block;
+       int shared;
+};
+
+/*
+ * Returns:
+ *   -EWOULDBLOCK iff @can_block is set and would block.
+ *   -ENODATA iff that mapping is not present.
+ *   0 success
+ */
+int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block,
+                      int can_block, struct dm_thin_lookup_result *result);
+
+/*
+ * Obtain an unused block.
+ */
+int dm_pool_alloc_data_block(struct dm_pool_metadata *pmd, dm_block_t *result);
+
+/*
+ * Insert or remove block.
+ */
+int dm_thin_insert_block(struct dm_thin_device *td, dm_block_t block,
+                        dm_block_t data_block);
+
+int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block);
+
+/*
+ * Queries.
+ */
+int dm_thin_get_highest_mapped_block(struct dm_thin_device *td,
+                                    dm_block_t *highest_mapped);
+
+int dm_thin_get_mapped_count(struct dm_thin_device *td, dm_block_t *result);
+
+int dm_pool_get_free_block_count(struct dm_pool_metadata *pmd,
+                                dm_block_t *result);
+
+int dm_pool_get_free_metadata_block_count(struct dm_pool_metadata *pmd,
+                                         dm_block_t *result);
+
+int dm_pool_get_metadata_dev_size(struct dm_pool_metadata *pmd,
+                                 dm_block_t *result);
+
+int dm_pool_get_data_block_size(struct dm_pool_metadata *pmd, sector_t *result);
+
+int dm_pool_get_data_dev_size(struct dm_pool_metadata *pmd, dm_block_t *result);
+
+/*
+ * Returns -ENOSPC if the new size is too small and already allocated
+ * blocks would be lost.
+ */
+int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_size);
+
+/*----------------------------------------------------------------*/
+
+#endif
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
new file mode 100644 (file)
index 0000000..96d9246
--- /dev/null
@@ -0,0 +1,2280 @@
+/*
+ * Copyright (C) 2011 Red Hat UK.  All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-thin-metadata.h"
+
+#include <linux/device-mapper.h>
+#include <linux/dm-io.h>
+#include <linux/dm-kcopyd.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define        DM_MSG_PREFIX   "thin"
+
+/*
+ * Tunable constants
+ */
+#define ENDIO_HOOK_POOL_SIZE 10240
+#define DEFERRED_SET_SIZE 64
+#define MAPPING_POOL_SIZE 1024
+#define PRISON_CELLS 1024
+
+/*
+ * The block size of the device holding pool data must be
+ * between 64KB and 1GB.
+ */
+#define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (64 * 1024 >> SECTOR_SHIFT)
+#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
+
+#define METADATA_DEV_MAX_SECTORS (255 * (1 << 14) * 8)
+
+/*
+ * Device id is restricted to 24 bits.
+ */
+#define MAX_DEV_ID ((1 << 24) - 1)
+
+/*
+ * How do we handle breaking sharing of data blocks?
+ * =================================================
+ *
+ * We use a standard copy-on-write btree to store the mappings for the
+ * devices (note I'm talking about copy-on-write of the metadata here, not
+ * the data).  When you take an internal snapshot you clone the root node
+ * of the origin btree.  After this there is no concept of an origin or a
+ * snapshot.  They are just two device trees that happen to point to the
+ * same data blocks.
+ *
+ * When we get a write in we decide if it's to a shared data block using
+ * some timestamp magic.  If it is, we have to break sharing.
+ *
+ * Let's say we write to a shared block in what was the origin.  The
+ * steps are:
+ *
+ * i) plug io further to this physical block. (see bio_prison code).
+ *
+ * ii) quiesce any read io to that shared data block.  Obviously
+ * including all devices that share this block.  (see deferred_set code)
+ *
+ * iii) copy the data block to a newly allocate block.  This step can be
+ * missed out if the io covers the block. (schedule_copy).
+ *
+ * iv) insert the new mapping into the origin's btree
+ * (process_prepared_mappings).  This act of inserting breaks some
+ * sharing of btree nodes between the two devices.  Breaking sharing only
+ * effects the btree of that specific device.  Btrees for the other
+ * devices that share the block never change.  The btree for the origin
+ * device as it was after the last commit is untouched, ie. we're using
+ * persistent data structures in the functional programming sense.
+ *
+ * v) unplug io to this physical block, including the io that triggered
+ * the breaking of sharing.
+ *
+ * Steps (ii) and (iii) occur in parallel.
+ *
+ * The metadata _doesn't_ need to be committed before the io continues.  We
+ * get away with this because the io is always written to a _new_ block.
+ * If there's a crash, then:
+ *
+ * - The origin mapping will point to the old origin block (the shared
+ * one).  This will contain the data as it was before the io that triggered
+ * the breaking of sharing came in.
+ *
+ * - The snap mapping still points to the old block.  As it would after
+ * the commit.
+ *
+ * The downside of this scheme is the timestamp magic isn't perfect, and
+ * will continue to think that data block in the snapshot device is shared
+ * even after the write to the origin has broken sharing.  I suspect data
+ * blocks will typically be shared by many different devices, so we're
+ * breaking sharing n + 1 times, rather than n, where n is the number of
+ * devices that reference this data block.  At the moment I think the
+ * benefits far, far outweigh the disadvantages.
+ */
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Sometimes we can't deal with a bio straight away.  We put them in prison
+ * where they can't cause any mischief.  Bios are put in a cell identified
+ * by a key, multiple bios can be in the same cell.  When the cell is
+ * subsequently unlocked the bios become available.
+ */
+struct bio_prison;
+
+struct cell_key {
+       int virtual;
+       dm_thin_id dev;
+       dm_block_t block;
+};
+
+struct cell {
+       struct hlist_node list;
+       struct bio_prison *prison;
+       struct cell_key key;
+       unsigned count;
+       struct bio_list bios;
+};
+
+struct bio_prison {
+       spinlock_t lock;
+       mempool_t *cell_pool;
+
+       unsigned nr_buckets;
+       unsigned hash_mask;
+       struct hlist_head *cells;
+};
+
+static uint32_t calc_nr_buckets(unsigned nr_cells)
+{
+       uint32_t n = 128;
+
+       nr_cells /= 4;
+       nr_cells = min(nr_cells, 8192u);
+
+       while (n < nr_cells)
+               n <<= 1;
+
+       return n;
+}
+
+/*
+ * @nr_cells should be the number of cells you want in use _concurrently_.
+ * Don't confuse it with the number of distinct keys.
+ */
+static struct bio_prison *prison_create(unsigned nr_cells)
+{
+       unsigned i;
+       uint32_t nr_buckets = calc_nr_buckets(nr_cells);
+       size_t len = sizeof(struct bio_prison) +
+               (sizeof(struct hlist_head) * nr_buckets);
+       struct bio_prison *prison = kmalloc(len, GFP_KERNEL);
+
+       if (!prison)
+               return NULL;
+
+       spin_lock_init(&prison->lock);
+       prison->cell_pool = mempool_create_kmalloc_pool(nr_cells,
+                                                       sizeof(struct cell));
+       if (!prison->cell_pool) {
+               kfree(prison);
+               return NULL;
+       }
+
+       prison->nr_buckets = nr_buckets;
+       prison->hash_mask = nr_buckets - 1;
+       prison->cells = (struct hlist_head *) (prison + 1);
+       for (i = 0; i < nr_buckets; i++)
+               INIT_HLIST_HEAD(prison->cells + i);
+
+       return prison;
+}
+
+static void prison_destroy(struct bio_prison *prison)
+{
+       mempool_destroy(prison->cell_pool);
+       kfree(prison);
+}
+
+static uint32_t hash_key(struct bio_prison *prison, struct cell_key *key)
+{
+       const unsigned long BIG_PRIME = 4294967291UL;
+       uint64_t hash = key->block * BIG_PRIME;
+
+       return (uint32_t) (hash & prison->hash_mask);
+}
+
+static int keys_equal(struct cell_key *lhs, struct cell_key *rhs)
+{
+              return (lhs->virtual == rhs->virtual) &&
+                      (lhs->dev == rhs->dev) &&
+                      (lhs->block == rhs->block);
+}
+
+static struct cell *__search_bucket(struct hlist_head *bucket,
+                                   struct cell_key *key)
+{
+       struct cell *cell;
+       struct hlist_node *tmp;
+
+       hlist_for_each_entry(cell, tmp, bucket, list)
+               if (keys_equal(&cell->key, key))
+                       return cell;
+
+       return NULL;
+}
+
+/*
+ * This may block if a new cell needs allocating.  You must ensure that
+ * cells will be unlocked even if the calling thread is blocked.
+ *
+ * Returns the number of entries in the cell prior to the new addition
+ * or < 0 on failure.
+ */
+static int bio_detain(struct bio_prison *prison, struct cell_key *key,
+                     struct bio *inmate, struct cell **ref)
+{
+       int r;
+       unsigned long flags;
+       uint32_t hash = hash_key(prison, key);
+       struct cell *uninitialized_var(cell), *cell2 = NULL;
+
+       BUG_ON(hash > prison->nr_buckets);
+
+       spin_lock_irqsave(&prison->lock, flags);
+       cell = __search_bucket(prison->cells + hash, key);
+
+       if (!cell) {
+               /*
+                * Allocate a new cell
+                */
+               spin_unlock_irqrestore(&prison->lock, flags);
+               cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
+               spin_lock_irqsave(&prison->lock, flags);
+
+               /*
+                * We've been unlocked, so we have to double check that
+                * nobody else has inserted this cell in the meantime.
+                */
+               cell = __search_bucket(prison->cells + hash, key);
+
+               if (!cell) {
+                       cell = cell2;
+                       cell2 = NULL;
+
+                       cell->prison = prison;
+                       memcpy(&cell->key, key, sizeof(cell->key));
+                       cell->count = 0;
+                       bio_list_init(&cell->bios);
+                       hlist_add_head(&cell->list, prison->cells + hash);
+               }
+       }
+
+       r = cell->count++;
+       bio_list_add(&cell->bios, inmate);
+       spin_unlock_irqrestore(&prison->lock, flags);
+
+       if (cell2)
+               mempool_free(cell2, prison->cell_pool);
+
+       *ref = cell;
+
+       return r;
+}
+
+/*
+ * @inmates must have been initialised prior to this call
+ */
+static void __cell_release(struct cell *cell, struct bio_list *inmates)
+{
+       struct bio_prison *prison = cell->prison;
+
+       hlist_del(&cell->list);
+
+       if (inmates)
+               bio_list_merge(inmates, &cell->bios);
+
+       mempool_free(cell, prison->cell_pool);
+}
+
+static void cell_release(struct cell *cell, struct bio_list *bios)
+{
+       unsigned long flags;
+       struct bio_prison *prison = cell->prison;
+
+       spin_lock_irqsave(&prison->lock, flags);
+       __cell_release(cell, bios);
+       spin_unlock_irqrestore(&prison->lock, flags);
+}
+
+/*
+ * There are a couple of places where we put a bio into a cell briefly
+ * before taking it out again.  In these situations we know that no other
+ * bio may be in the cell.  This function releases the cell, and also does
+ * a sanity check.
+ */
+static void cell_release_singleton(struct cell *cell, struct bio *bio)
+{
+       struct bio_prison *prison = cell->prison;
+       struct bio_list bios;
+       struct bio *b;
+       unsigned long flags;
+
+       bio_list_init(&bios);
+
+       spin_lock_irqsave(&prison->lock, flags);
+       __cell_release(cell, &bios);
+       spin_unlock_irqrestore(&prison->lock, flags);
+
+       b = bio_list_pop(&bios);
+       BUG_ON(b != bio);
+       BUG_ON(!bio_list_empty(&bios));
+}
+
+static void cell_error(struct cell *cell)
+{
+       struct bio_prison *prison = cell->prison;
+       struct bio_list bios;
+       struct bio *bio;
+       unsigned long flags;
+
+       bio_list_init(&bios);
+
+       spin_lock_irqsave(&prison->lock, flags);
+       __cell_release(cell, &bios);
+       spin_unlock_irqrestore(&prison->lock, flags);
+
+       while ((bio = bio_list_pop(&bios)))
+               bio_io_error(bio);
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * We use the deferred set to keep track of pending reads to shared blocks.
+ * We do this to ensure the new mapping caused by a write isn't performed
+ * until these prior reads have completed.  Otherwise the insertion of the
+ * new mapping could free the old block that the read bios are mapped to.
+ */
+
+struct deferred_set;
+struct deferred_entry {
+       struct deferred_set *ds;
+       unsigned count;
+       struct list_head work_items;
+};
+
+struct deferred_set {
+       spinlock_t lock;
+       unsigned current_entry;
+       unsigned sweeper;
+       struct deferred_entry entries[DEFERRED_SET_SIZE];
+};
+
+static void ds_init(struct deferred_set *ds)
+{
+       int i;
+
+       spin_lock_init(&ds->lock);
+       ds->current_entry = 0;
+       ds->sweeper = 0;
+       for (i = 0; i < DEFERRED_SET_SIZE; i++) {
+               ds->entries[i].ds = ds;
+               ds->entries[i].count = 0;
+               INIT_LIST_HEAD(&ds->entries[i].work_items);
+       }
+}
+
+static struct deferred_entry *ds_inc(struct deferred_set *ds)
+{
+       unsigned long flags;
+       struct deferred_entry *entry;
+
+       spin_lock_irqsave(&ds->lock, flags);
+       entry = ds->entries + ds->current_entry;
+       entry->count++;
+       spin_unlock_irqrestore(&ds->lock, flags);
+
+       return entry;
+}
+
+static unsigned ds_next(unsigned index)
+{
+       return (index + 1) % DEFERRED_SET_SIZE;
+}
+
+static void __sweep(struct deferred_set *ds, struct list_head *head)
+{
+       while ((ds->sweeper != ds->current_entry) &&
+              !ds->entries[ds->sweeper].count) {
+               list_splice_init(&ds->entries[ds->sweeper].work_items, head);
+               ds->sweeper = ds_next(ds->sweeper);
+       }
+
+       if ((ds->sweeper == ds->current_entry) && !ds->entries[ds->sweeper].count)
+               list_splice_init(&ds->entries[ds->sweeper].work_items, head);
+}
+
+static void ds_dec(struct deferred_entry *entry, struct list_head *head)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&entry->ds->lock, flags);
+       BUG_ON(!entry->count);
+       --entry->count;
+       __sweep(entry->ds, head);
+       spin_unlock_irqrestore(&entry->ds->lock, flags);
+}
+
+/*
+ * Returns 1 if deferred or 0 if no pending items to delay job.
+ */
+static int ds_add_work(struct deferred_set *ds, struct list_head *work)
+{
+       int r = 1;
+       unsigned long flags;
+       unsigned next_entry;
+
+       spin_lock_irqsave(&ds->lock, flags);
+       if ((ds->sweeper == ds->current_entry) &&
+           !ds->entries[ds->current_entry].count)
+               r = 0;
+       else {
+               list_add(work, &ds->entries[ds->current_entry].work_items);
+               next_entry = ds_next(ds->current_entry);
+               if (!ds->entries[next_entry].count)
+                       ds->current_entry = next_entry;
+       }
+       spin_unlock_irqrestore(&ds->lock, flags);
+
+       return r;
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Key building.
+ */
+static void build_data_key(struct dm_thin_device *td,
+                          dm_block_t b, struct cell_key *key)
+{
+       key->virtual = 0;
+       key->dev = dm_thin_dev_id(td);
+       key->block = b;
+}
+
+static void build_virtual_key(struct dm_thin_device *td, dm_block_t b,
+                             struct cell_key *key)
+{
+       key->virtual = 1;
+       key->dev = dm_thin_dev_id(td);
+       key->block = b;
+}
+
+/*----------------------------------------------------------------*/
+
+struct new_mapping;
+
+/*
+ * A pool device ties together a metadata device and a data device.  It
+ * also provides the interface for creating and destroying internal
+ * devices.
+ */
+struct pool {
+       struct list_head list;
+       struct dm_target *ti;   /* Only set if a pool target is bound */
+
+       struct mapped_device *pool_md;
+       struct dm_pool_metadata *pmd;
+
+       uint32_t sectors_per_block;
+       unsigned block_shift;
+       dm_block_t offset_mask;
+       dm_block_t low_water_mark;
+       unsigned zero_new_blocks:1;
+
+       struct bio_prison *prison;
+       struct dm_kcopyd_client *copier;
+
+       struct workqueue_struct *wq;
+       struct work_struct worker;
+
+       spinlock_t lock;
+       struct bio_list deferred_bios;
+       struct list_head prepared_mappings;
+
+       int low_water_triggered;        /* A dm event has been sent */
+       struct bio_list retry_on_resume_list;
+
+       struct deferred_set ds; /* FIXME: move to thin_c */
+
+       struct new_mapping *next_mapping;
+
+       mempool_t *mapping_pool;
+       mempool_t *endio_hook_pool;
+
+       atomic_t ref_count;
+};
+
+/*
+ * Target context for a pool.
+ */
+struct pool_c {
+       struct dm_target *ti;
+       struct pool *pool;
+       struct dm_dev *data_dev;
+       struct dm_dev *metadata_dev;
+       struct dm_target_callbacks callbacks;
+
+       sector_t low_water_mark;
+       unsigned zero_new_blocks:1;
+};
+
+/*
+ * Target context for a thin.
+ */
+struct thin_c {
+       struct dm_dev *pool_dev;
+       dm_thin_id dev_id;
+
+       struct pool *pool;
+       struct dm_thin_device *td;
+};
+
+/*----------------------------------------------------------------*/
+
+/*
+ * A global list that uses a struct mapped_device as a key.
+ */
+static struct dm_thin_pool_table {
+       spinlock_t lock;
+       struct list_head pools;
+} dm_thin_pool_table;
+
+static void pool_table_init(void)
+{
+       spin_lock_init(&dm_thin_pool_table.lock);
+
+       INIT_LIST_HEAD(&dm_thin_pool_table.pools);
+}
+
+static void pool_table_insert(struct pool *pool)
+{
+       spin_lock(&dm_thin_pool_table.lock);
+       list_add(&pool->list, &dm_thin_pool_table.pools);
+       spin_unlock(&dm_thin_pool_table.lock);
+}
+
+static void pool_table_remove(struct pool *pool)
+{
+       spin_lock(&dm_thin_pool_table.lock);
+       list_del(&pool->list);
+       spin_unlock(&dm_thin_pool_table.lock);
+}
+
+static struct pool *pool_table_lookup(struct mapped_device *md)
+{
+       struct pool *pool = NULL, *tmp;
+
+       spin_lock(&dm_thin_pool_table.lock);
+       list_for_each_entry(tmp, &dm_thin_pool_table.pools, list)
+               if (tmp->pool_md == md) {
+                       pool = tmp;
+                       break;
+               }
+       spin_unlock(&dm_thin_pool_table.lock);
+
+       return pool;
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * This section of code contains the logic for processing a thin device's IO.
+ * Much of the code depends on pool object resources (lists, workqueues, etc)
+ * but most is exclusively called from the thin target rather than the thin-pool
+ * target.
+ */
+
+static dm_block_t get_bio_block(struct thin_c *tc, struct bio *bio)
+{
+       return bio->bi_sector >> tc->pool->block_shift;
+}
+
+static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
+{
+       struct pool *pool = tc->pool;
+
+       bio->bi_bdev = tc->pool_dev->bdev;
+       bio->bi_sector = (block << pool->block_shift) +
+               (bio->bi_sector & pool->offset_mask);
+}
+
+static void remap_and_issue(struct thin_c *tc, struct bio *bio,
+                           dm_block_t block)
+{
+       if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
+               int r = dm_pool_commit_metadata(tc->pool->pmd);
+               if (r) {
+                       DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
+                             __func__, r);
+                       bio_io_error(bio);
+                       return;
+               }
+       }
+
+       remap(tc, bio, block);
+       generic_make_request(bio);
+}
+
+/*
+ * wake_worker() is used by thin_defer_bio and pool_preresume to continue
+ * deferred IO processing after pool resume.
+ */
+static void wake_worker(struct pool *pool)
+{
+       queue_work(pool->wq, &pool->worker);
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Bio endio functions.
+ */
+
+struct endio_hook {
+       struct thin_c *tc;
+       bio_end_io_t *saved_bi_end_io;
+       struct deferred_entry *entry;
+};
+
+struct new_mapping {
+       struct list_head list;
+
+       int prepared;
+
+       struct thin_c *tc;
+       dm_block_t virt_block;
+       dm_block_t data_block;
+       struct cell *cell;
+       int err;
+
+       /*
+        * If the bio covers the whole area of a block then we can avoid
+        * zeroing or copying.  Instead this bio is hooked.  The bio will
+        * still be in the cell, so care has to be taken to avoid issuing
+        * the bio twice.
+        */
+       struct bio *bio;
+       bio_end_io_t *saved_bi_end_io;
+};
+
+static void __maybe_add_mapping(struct new_mapping *m)
+{
+       struct pool *pool = m->tc->pool;
+
+       if (list_empty(&m->list) && m->prepared) {
+               list_add(&m->list, &pool->prepared_mappings);
+               wake_worker(pool);
+       }
+}
+
+static void copy_complete(int read_err, unsigned long write_err, void *context)
+{
+       unsigned long flags;
+       struct new_mapping *m = context;
+       struct pool *pool = m->tc->pool;
+
+       m->err = read_err || write_err ? -EIO : 0;
+
+       spin_lock_irqsave(&pool->lock, flags);
+       m->prepared = 1;
+       __maybe_add_mapping(m);
+       spin_unlock_irqrestore(&pool->lock, flags);
+}
+
+static void overwrite_endio(struct bio *bio, int err)
+{
+       unsigned long flags;
+       struct new_mapping *m = dm_get_mapinfo(bio)->ptr;
+       struct pool *pool = m->tc->pool;
+
+       m->err = err;
+
+       spin_lock_irqsave(&pool->lock, flags);
+       m->prepared = 1;
+       __maybe_add_mapping(m);
+       spin_unlock_irqrestore(&pool->lock, flags);
+}
+
+static void shared_read_endio(struct bio *bio, int err)
+{
+       struct list_head mappings;
+       struct new_mapping *m, *tmp;
+       struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+       unsigned long flags;
+       struct pool *pool = h->tc->pool;
+
+       bio->bi_end_io = h->saved_bi_end_io;
+       bio_endio(bio, err);
+
+       INIT_LIST_HEAD(&mappings);
+       ds_dec(h->entry, &mappings);
+
+       spin_lock_irqsave(&pool->lock, flags);
+       list_for_each_entry_safe(m, tmp, &mappings, list) {
+               list_del(&m->list);
+               INIT_LIST_HEAD(&m->list);
+               __maybe_add_mapping(m);
+       }
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       mempool_free(h, pool->endio_hook_pool);
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Workqueue.
+ */
+
+/*
+ * Prepared mapping jobs.
+ */
+
+/*
+ * This sends the bios in the cell back to the deferred_bios list.
+ */
+static void cell_defer(struct thin_c *tc, struct cell *cell,
+                      dm_block_t data_block)
+{
+       struct pool *pool = tc->pool;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pool->lock, flags);
+       cell_release(cell, &pool->deferred_bios);
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       wake_worker(pool);
+}
+
+/*
+ * As above, but ignoring @exception (a write bio that covers
+ * the block) because it has already been processed.
+ */
+static void cell_defer_except(struct thin_c *tc, struct cell *cell,
+                             struct bio *exception)
+{
+       struct bio_list bios;
+       struct bio *bio;
+       struct pool *pool = tc->pool;
+       unsigned long flags;
+
+       bio_list_init(&bios);
+       cell_release(cell, &bios);
+
+       spin_lock_irqsave(&pool->lock, flags);
+       while ((bio = bio_list_pop(&bios)))
+               if (bio != exception)
+                       bio_list_add(&pool->deferred_bios, bio);
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       wake_worker(pool);
+}
+
+static void process_prepared_mapping(struct new_mapping *m)
+{
+       struct thin_c *tc = m->tc;
+       struct bio *bio;
+       int r;
+
+       bio = m->bio;
+       if (bio)
+               bio->bi_end_io = m->saved_bi_end_io;
+
+       if (m->err) {
+               cell_error(m->cell);
+               return;
+       }
+
+       /*
+        * Commit the prepared block into the mapping btree.
+        * Any I/O for this block arriving after this point will get
+        * remapped to it directly.
+        */
+       r = dm_thin_insert_block(tc->td, m->virt_block, m->data_block);
+       if (r) {
+               DMERR("dm_thin_insert_block() failed");
+               cell_error(m->cell);
+               return;
+       }
+
+       /*
+        * Release any bios held while the block was being provisioned.
+        * If we are processing a write bio that completely covers the block,
+        * we already processed it so can ignore it now when processing
+        * the bios in the cell.
+        */
+       if (bio) {
+               cell_defer_except(tc, m->cell, bio);
+               bio_endio(bio, 0);
+       } else
+               cell_defer(tc, m->cell, m->data_block);
+
+       mempool_free(m, tc->pool->mapping_pool);
+}
+
+static void process_prepared_mappings(struct pool *pool)
+{
+       unsigned long flags;
+       struct list_head maps;
+       struct new_mapping *m;
+
+       INIT_LIST_HEAD(&maps);
+       spin_lock_irqsave(&pool->lock, flags);
+       list_splice_init(&pool->prepared_mappings, &maps);
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       list_for_each_entry(m, &maps, list)
+               process_prepared_mapping(m);
+}
+
+/*
+ * Deferred bio jobs.
+ */
+static int io_overwrites_block(struct pool *pool, struct bio *bio)
+{
+       return ((bio_data_dir(bio) == WRITE) &&
+               (bio->bi_sector & pool->offset_mask) == 0) &&
+               (bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT));
+}
+
+static void save_and_set_endio(struct bio *bio, bio_end_io_t **save,
+                              bio_end_io_t *fn)
+{
+       *save = bio->bi_end_io;
+       bio->bi_end_io = fn;
+}
+
+static int ensure_next_mapping(struct pool *pool)
+{
+       if (pool->next_mapping)
+               return 0;
+
+       pool->next_mapping = mempool_alloc(pool->mapping_pool, GFP_ATOMIC);
+
+       return pool->next_mapping ? 0 : -ENOMEM;
+}
+
+static struct new_mapping *get_next_mapping(struct pool *pool)
+{
+       struct new_mapping *r = pool->next_mapping;
+
+       BUG_ON(!pool->next_mapping);
+
+       pool->next_mapping = NULL;
+
+       return r;
+}
+
+static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
+                         dm_block_t data_origin, dm_block_t data_dest,
+                         struct cell *cell, struct bio *bio)
+{
+       int r;
+       struct pool *pool = tc->pool;
+       struct new_mapping *m = get_next_mapping(pool);
+
+       INIT_LIST_HEAD(&m->list);
+       m->prepared = 0;
+       m->tc = tc;
+       m->virt_block = virt_block;
+       m->data_block = data_dest;
+       m->cell = cell;
+       m->err = 0;
+       m->bio = NULL;
+
+       ds_add_work(&pool->ds, &m->list);
+
+       /*
+        * IO to pool_dev remaps to the pool target's data_dev.
+        *
+        * If the whole block of data is being overwritten, we can issue the
+        * bio immediately. Otherwise we use kcopyd to clone the data first.
+        */
+       if (io_overwrites_block(pool, bio)) {
+               m->bio = bio;
+               save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
+               dm_get_mapinfo(bio)->ptr = m;
+               remap_and_issue(tc, bio, data_dest);
+       } else {
+               struct dm_io_region from, to;
+
+               from.bdev = tc->pool_dev->bdev;
+               from.sector = data_origin * pool->sectors_per_block;
+               from.count = pool->sectors_per_block;
+
+               to.bdev = tc->pool_dev->bdev;
+               to.sector = data_dest * pool->sectors_per_block;
+               to.count = pool->sectors_per_block;
+
+               r = dm_kcopyd_copy(pool->copier, &from, 1, &to,
+                                  0, copy_complete, m);
+               if (r < 0) {
+                       mempool_free(m, pool->mapping_pool);
+                       DMERR("dm_kcopyd_copy() failed");
+                       cell_error(cell);
+               }
+       }
+}
+
+static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
+                         dm_block_t data_block, struct cell *cell,
+                         struct bio *bio)
+{
+       struct pool *pool = tc->pool;
+       struct new_mapping *m = get_next_mapping(pool);
+
+       INIT_LIST_HEAD(&m->list);
+       m->prepared = 0;
+       m->tc = tc;
+       m->virt_block = virt_block;
+       m->data_block = data_block;
+       m->cell = cell;
+       m->err = 0;
+       m->bio = NULL;
+
+       /*
+        * If the whole block of data is being overwritten or we are not
+        * zeroing pre-existing data, we can issue the bio immediately.
+        * Otherwise we use kcopyd to zero the data first.
+        */
+       if (!pool->zero_new_blocks)
+               process_prepared_mapping(m);
+       else if (io_overwrites_block(pool, bio)) {
+               m->bio = bio;
+               save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
+               dm_get_mapinfo(bio)->ptr = m;
+               remap_and_issue(tc, bio, data_block);
+       } else {
+               int r;
+               struct dm_io_region to;
+
+               to.bdev = tc->pool_dev->bdev;
+               to.sector = data_block * pool->sectors_per_block;
+               to.count = pool->sectors_per_block;
+
+               r = dm_kcopyd_zero(pool->copier, 1, &to, 0, copy_complete, m);
+               if (r < 0) {
+                       mempool_free(m, pool->mapping_pool);
+                       DMERR("dm_kcopyd_zero() failed");
+                       cell_error(cell);
+               }
+       }
+}
+
+/*
+ * If we have run out of space, queue bios until the device is
+ * resumed, presumably after having been reloaded with more space.
+ */
+static void retry_when_resumed(struct bio *bio)
+{
+       struct thin_c *tc = dm_get_mapinfo(bio)->ptr;
+       struct pool *pool = tc->pool;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pool->lock, flags);
+       bio_list_add(&pool->retry_on_resume_list, bio);
+       spin_unlock_irqrestore(&pool->lock, flags);
+}
+
+static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
+{
+       int r;
+       dm_block_t free_blocks;
+       unsigned long flags;
+       struct pool *pool = tc->pool;
+
+       r = dm_pool_get_free_block_count(pool->pmd, &free_blocks);
+       if (r)
+               return r;
+
+       if (free_blocks <= pool->low_water_mark && !pool->low_water_triggered) {
+               spin_lock_irqsave(&pool->lock, flags);
+               pool->low_water_triggered = 1;
+               spin_unlock_irqrestore(&pool->lock, flags);
+               dm_table_event(pool->ti->table);
+       }
+
+       r = dm_pool_alloc_data_block(pool->pmd, result);
+       if (r)
+               return r;
+
+       return 0;
+}
+
+static void no_space(struct cell *cell)
+{
+       struct bio *bio;
+       struct bio_list bios;
+
+       bio_list_init(&bios);
+       cell_release(cell, &bios);
+
+       while ((bio = bio_list_pop(&bios)))
+               retry_when_resumed(bio);
+}
+
+static void break_sharing(struct thin_c *tc, struct bio *bio, dm_block_t block,
+                         struct cell_key *key,
+                         struct dm_thin_lookup_result *lookup_result,
+                         struct cell *cell)
+{
+       int r;
+       dm_block_t data_block;
+
+       r = alloc_data_block(tc, &data_block);
+       switch (r) {
+       case 0:
+               schedule_copy(tc, block, lookup_result->block,
+                             data_block, cell, bio);
+               break;
+
+       case -ENOSPC:
+               no_space(cell);
+               break;
+
+       default:
+               DMERR("%s: alloc_data_block() failed, error = %d", __func__, r);
+               cell_error(cell);
+               break;
+       }
+}
+
+static void process_shared_bio(struct thin_c *tc, struct bio *bio,
+                              dm_block_t block,
+                              struct dm_thin_lookup_result *lookup_result)
+{
+       struct cell *cell;
+       struct cell_key key;
+       struct pool *pool = tc->pool;
+
+       /*
+        * If cell is already occupied, then sharing is already in the process
+        * of being broken so we have nothing further to do here.
+        */
+       build_data_key(tc->td, lookup_result->block, &key);
+       if (bio_detain(pool->prison, &key, bio, &cell))
+               return;
+
+       if (bio_data_dir(bio) == WRITE)
+               break_sharing(tc, bio, block, &key, lookup_result, cell);
+       else {
+               struct endio_hook *h;
+               h = mempool_alloc(pool->endio_hook_pool, GFP_NOIO);
+
+               h->tc = tc;
+               h->entry = ds_inc(&pool->ds);
+               save_and_set_endio(bio, &h->saved_bi_end_io, shared_read_endio);
+               dm_get_mapinfo(bio)->ptr = h;
+
+               cell_release_singleton(cell, bio);
+               remap_and_issue(tc, bio, lookup_result->block);
+       }
+}
+
+static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block,
+                           struct cell *cell)
+{
+       int r;
+       dm_block_t data_block;
+
+       /*
+        * Remap empty bios (flushes) immediately, without provisioning.
+        */
+       if (!bio->bi_size) {
+               cell_release_singleton(cell, bio);
+               remap_and_issue(tc, bio, 0);
+               return;
+       }
+
+       /*
+        * Fill read bios with zeroes and complete them immediately.
+        */
+       if (bio_data_dir(bio) == READ) {
+               zero_fill_bio(bio);
+               cell_release_singleton(cell, bio);
+               bio_endio(bio, 0);
+               return;
+       }
+
+       r = alloc_data_block(tc, &data_block);
+       switch (r) {
+       case 0:
+               schedule_zero(tc, block, data_block, cell, bio);
+               break;
+
+       case -ENOSPC:
+               no_space(cell);
+               break;
+
+       default:
+               DMERR("%s: alloc_data_block() failed, error = %d", __func__, r);
+               cell_error(cell);
+               break;
+       }
+}
+
+static void process_bio(struct thin_c *tc, struct bio *bio)
+{
+       int r;
+       dm_block_t block = get_bio_block(tc, bio);
+       struct cell *cell;
+       struct cell_key key;
+       struct dm_thin_lookup_result lookup_result;
+
+       /*
+        * If cell is already occupied, then the block is already
+        * being provisioned so we have nothing further to do here.
+        */
+       build_virtual_key(tc->td, block, &key);
+       if (bio_detain(tc->pool->prison, &key, bio, &cell))
+               return;
+
+       r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
+       switch (r) {
+       case 0:
+               /*
+                * We can release this cell now.  This thread is the only
+                * one that puts bios into a cell, and we know there were
+                * no preceding bios.
+                */
+               cell_release_singleton(cell, bio);
+
+               if (lookup_result.shared)
+                       process_shared_bio(tc, bio, block, &lookup_result);
+               else
+                       remap_and_issue(tc, bio, lookup_result.block);
+               break;
+
+       case -ENODATA:
+               provision_block(tc, bio, block, cell);
+               break;
+
+       default:
+               DMERR("dm_thin_find_block() failed, error = %d", r);
+               bio_io_error(bio);
+               break;
+       }
+}
+
+static void process_deferred_bios(struct pool *pool)
+{
+       unsigned long flags;
+       struct bio *bio;
+       struct bio_list bios;
+
+       bio_list_init(&bios);
+
+       spin_lock_irqsave(&pool->lock, flags);
+       bio_list_merge(&bios, &pool->deferred_bios);
+       bio_list_init(&pool->deferred_bios);
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       while ((bio = bio_list_pop(&bios))) {
+               struct thin_c *tc = dm_get_mapinfo(bio)->ptr;
+
+               /*
+                * If we've got no free new_mapping structs, and processing this bio
+                * might require one, we pause until there are some prepared mappings to
+                * process.
+                */
+               if (ensure_next_mapping(pool)) {
+                       spin_lock_irqsave(&pool->lock, flags);
+                       bio_list_merge(&pool->deferred_bios, &bios);
+                       spin_unlock_irqrestore(&pool->lock, flags);
+
+                       return;
+               }
+
+               process_bio(tc, bio);
+       }
+}
+
+static void do_worker(struct work_struct *ws)
+{
+       struct pool *pool = container_of(ws, struct pool, worker);
+
+       process_prepared_mappings(pool);
+       process_deferred_bios(pool);
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Mapping functions.
+ */
+
+/*
+ * Called only while mapping a thin bio to hand it over to the workqueue.
+ */
+static void thin_defer_bio(struct thin_c *tc, struct bio *bio)
+{
+       unsigned long flags;
+       struct pool *pool = tc->pool;
+
+       spin_lock_irqsave(&pool->lock, flags);
+       bio_list_add(&pool->deferred_bios, bio);
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       wake_worker(pool);
+}
+
+/*
+ * Non-blocking function designed to be called from the target's map
+ * function.
+ */
+static int thin_bio_map(struct dm_target *ti, struct bio *bio,
+                       union map_info *map_context)
+{
+       int r;
+       struct thin_c *tc = ti->private;
+       dm_block_t block = get_bio_block(tc, bio);
+       struct dm_thin_device *td = tc->td;
+       struct dm_thin_lookup_result result;
+
+       /*
+        * Save the thin context for easy access from the deferred bio later.
+        */
+       map_context->ptr = tc;
+
+       if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
+               thin_defer_bio(tc, bio);
+               return DM_MAPIO_SUBMITTED;
+       }
+
+       r = dm_thin_find_block(td, block, 0, &result);
+
+       /*
+        * Note that we defer readahead too.
+        */
+       switch (r) {
+       case 0:
+               if (unlikely(result.shared)) {
+                       /*
+                        * We have a race condition here between the
+                        * result.shared value returned by the lookup and
+                        * snapshot creation, which may cause new
+                        * sharing.
+                        *
+                        * To avoid this always quiesce the origin before
+                        * taking the snap.  You want to do this anyway to
+                        * ensure a consistent application view
+                        * (i.e. lockfs).
+                        *
+                        * More distant ancestors are irrelevant: the
+                        * shared flag will be set in their case.
+                        */
+                       thin_defer_bio(tc, bio);
+                       r = DM_MAPIO_SUBMITTED;
+               } else {
+                       remap(tc, bio, result.block);
+                       r = DM_MAPIO_REMAPPED;
+               }
+               break;
+
+       case -ENODATA:
+               /*
+                * In future, the failed dm_thin_find_block above could
+                * provide the hint to load the metadata into cache.
+                */
+       case -EWOULDBLOCK:
+               thin_defer_bio(tc, bio);
+               r = DM_MAPIO_SUBMITTED;
+               break;
+       }
+
+       return r;
+}
+
+static int pool_map(struct dm_target *ti, struct bio *bio,
+                   union map_info *map_context)
+{
+       int r;
+       struct pool_c *pt = ti->private;
+       struct pool *pool = pt->pool;
+       unsigned long flags;
+
+       /*
+        * As this is a singleton target, ti->begin is always zero.
+        */
+       spin_lock_irqsave(&pool->lock, flags);
+       bio->bi_bdev = pt->data_dev->bdev;
+       r = DM_MAPIO_REMAPPED;
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       return r;
+}
+
+/*----------------------------------------------------------------
+ * Binding of control targets to a pool object
+ *--------------------------------------------------------------*/
+/* FIXME: add locking */
+static int bind_control_target(struct pool *pool, struct dm_target *ti)
+{
+       struct pool_c *pt = ti->private;
+
+       pool->ti = ti;
+       pool->low_water_mark = dm_sector_div_up(pt->low_water_mark,
+                                               pool->sectors_per_block);
+       pool->zero_new_blocks = pt->zero_new_blocks;
+       dm_pool_rebind_metadata_device(pool->pmd, pt->metadata_dev->bdev);
+
+       return 0;
+}
+
+static void unbind_control_target(struct pool *pool, struct dm_target *ti)
+{
+       if (pool->ti == ti)
+               pool->ti = NULL;
+}
+
+/*----------------------------------------------------------------
+ * Pool creation
+ *--------------------------------------------------------------*/
+static void pool_destroy(struct pool *pool)
+{
+       if (dm_pool_metadata_close(pool->pmd) < 0)
+               DMWARN("%s: dm_pool_metadata_close() failed.", __func__);
+
+       prison_destroy(pool->prison);
+       dm_kcopyd_client_destroy(pool->copier);
+
+       if (pool->wq)
+               destroy_workqueue(pool->wq);
+
+       if (pool->next_mapping)
+               mempool_free(pool->next_mapping, pool->mapping_pool);
+
+       mempool_destroy(pool->mapping_pool);
+       mempool_destroy(pool->endio_hook_pool);
+       kfree(pool);
+}
+
+static struct pool *pool_create(struct block_device *metadata_dev,
+                               unsigned long block_size, char **error)
+{
+       int r;
+       void *err_p;
+       struct pool *pool;
+       struct dm_pool_metadata *pmd;
+
+       pmd = dm_pool_metadata_open(metadata_dev, block_size);
+       if (IS_ERR(pmd)) {
+               *error = "Error creating metadata object";
+               return (struct pool *)pmd;
+       }
+
+       pool = kmalloc(sizeof(*pool), GFP_KERNEL);
+       if (!pool) {
+               *error = "Error allocating memory for pool";
+               err_p = ERR_PTR(-ENOMEM);
+               goto bad_pool;
+       }
+
+       pool->pmd = pmd;
+       pool->sectors_per_block = block_size;
+       pool->block_shift = ffs(block_size) - 1;
+       pool->offset_mask = block_size - 1;
+       pool->low_water_mark = 0;
+       pool->zero_new_blocks = 1;
+       pool->prison = prison_create(PRISON_CELLS);
+       if (!pool->prison) {
+               *error = "Error creating pool's bio prison";
+               err_p = ERR_PTR(-ENOMEM);
+               goto bad_prison;
+       }
+
+       pool->copier = dm_kcopyd_client_create();
+       if (IS_ERR(pool->copier)) {
+               r = PTR_ERR(pool->copier);
+               *error = "Error creating pool's kcopyd client";
+               err_p = ERR_PTR(r);
+               goto bad_kcopyd_client;
+       }
+
+       /*
+        * Create singlethreaded workqueue that will service all devices
+        * that use this metadata.
+        */
+       pool->wq = alloc_ordered_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM);
+       if (!pool->wq) {
+               *error = "Error creating pool's workqueue";
+               err_p = ERR_PTR(-ENOMEM);
+               goto bad_wq;
+       }
+
+       INIT_WORK(&pool->worker, do_worker);
+       spin_lock_init(&pool->lock);
+       bio_list_init(&pool->deferred_bios);
+       INIT_LIST_HEAD(&pool->prepared_mappings);
+       pool->low_water_triggered = 0;
+       bio_list_init(&pool->retry_on_resume_list);
+       ds_init(&pool->ds);
+
+       pool->next_mapping = NULL;
+       pool->mapping_pool =
+               mempool_create_kmalloc_pool(MAPPING_POOL_SIZE, sizeof(struct new_mapping));
+       if (!pool->mapping_pool) {
+               *error = "Error creating pool's mapping mempool";
+               err_p = ERR_PTR(-ENOMEM);
+               goto bad_mapping_pool;
+       }
+
+       pool->endio_hook_pool =
+               mempool_create_kmalloc_pool(ENDIO_HOOK_POOL_SIZE, sizeof(struct endio_hook));
+       if (!pool->endio_hook_pool) {
+               *error = "Error creating pool's endio_hook mempool";
+               err_p = ERR_PTR(-ENOMEM);
+               goto bad_endio_hook_pool;
+       }
+       atomic_set(&pool->ref_count, 1);
+
+       return pool;
+
+bad_endio_hook_pool:
+       mempool_destroy(pool->mapping_pool);
+bad_mapping_pool:
+       destroy_workqueue(pool->wq);
+bad_wq:
+       dm_kcopyd_client_destroy(pool->copier);
+bad_kcopyd_client:
+       prison_destroy(pool->prison);
+bad_prison:
+       kfree(pool);
+bad_pool:
+       if (dm_pool_metadata_close(pmd))
+               DMWARN("%s: dm_pool_metadata_close() failed.", __func__);
+
+       return err_p;
+}
+
+static void pool_inc(struct pool *pool)
+{
+       atomic_inc(&pool->ref_count);
+}
+
+static void pool_dec(struct pool *pool)
+{
+       if (atomic_dec_and_test(&pool->ref_count))
+               pool_destroy(pool);
+}
+
+static struct pool *pool_find(struct mapped_device *pool_md,
+                             struct block_device *metadata_dev,
+                             unsigned long block_size,
+                             char **error)
+{
+       struct pool *pool;
+
+       pool = pool_table_lookup(pool_md);
+       if (pool)
+               pool_inc(pool);
+       else
+               pool = pool_create(metadata_dev, block_size, error);
+
+       return pool;
+}
+
+/*----------------------------------------------------------------
+ * Pool target methods
+ *--------------------------------------------------------------*/
+struct pool_features {
+       unsigned zero_new_blocks:1;
+};
+
+static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
+                              struct dm_target *ti)
+{
+       int r;
+       unsigned argc;
+       const char *arg_name;
+
+       static struct dm_arg _args[] = {
+               {0, 1, "Invalid number of pool feature arguments"},
+       };
+
+       /*
+        * No feature arguments supplied.
+        */
+       if (!as->argc)
+               return 0;
+
+       r = dm_read_arg_group(_args, as, &argc, &ti->error);
+       if (r)
+               return -EINVAL;
+
+       while (argc && !r) {
+               arg_name = dm_shift_arg(as);
+               argc--;
+
+               if (!strcasecmp(arg_name, "skip_block_zeroing")) {
+                       pf->zero_new_blocks = 0;
+                       continue;
+               }
+
+               ti->error = "Unrecognised pool feature requested";
+               r = -EINVAL;
+       }
+
+       return r;
+}
+
+static int pool_is_congested(struct dm_target_callbacks *cb, int bdi_bits)
+{
+       int r;
+       unsigned long flags;
+       struct pool_c *pt = container_of(cb, struct pool_c, callbacks);
+
+       spin_lock_irqsave(&pt->pool->lock, flags);
+       r = !bio_list_empty(&pt->pool->retry_on_resume_list);
+       spin_unlock_irqrestore(&pt->pool->lock, flags);
+
+       if (!r) {
+               struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
+               r = bdi_congested(&q->backing_dev_info, bdi_bits);
+       }
+
+       return r;
+}
+
+/*
+ * thin-pool <metadata dev> <data dev>
+ *           <data block size (sectors)>
+ *           <low water mark (sectors)>
+ *           [<#feature args> [<arg>]*]
+ *
+ * Optional feature arguments are:
+ *           skip_block_zeroing: skips the zeroing of newly-provisioned blocks.
+ */
+static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
+{
+       int r;
+       struct pool_c *pt;
+       struct pool *pool;
+       struct pool_features pf;
+       struct dm_arg_set as;
+       struct dm_dev *data_dev;
+       unsigned long block_size;
+       dm_block_t low_water;
+       struct dm_dev *metadata_dev;
+       sector_t metadata_dev_size;
+
+       if (argc < 4) {
+               ti->error = "Invalid argument count";
+               return -EINVAL;
+       }
+       as.argc = argc;
+       as.argv = argv;
+
+       r = dm_get_device(ti, argv[0], FMODE_READ | FMODE_WRITE, &metadata_dev);
+       if (r) {
+               ti->error = "Error opening metadata block device";
+               return r;
+       }
+
+       metadata_dev_size = i_size_read(metadata_dev->bdev->bd_inode) >> SECTOR_SHIFT;
+       if (metadata_dev_size > METADATA_DEV_MAX_SECTORS) {
+               ti->error = "Metadata device is too large";
+               r = -EINVAL;
+               goto out_metadata;
+       }
+
+       r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev);
+       if (r) {
+               ti->error = "Error getting data device";
+               goto out_metadata;
+       }
+
+       if (kstrtoul(argv[2], 10, &block_size) || !block_size ||
+           block_size < DATA_DEV_BLOCK_SIZE_MIN_SECTORS ||
+           block_size > DATA_DEV_BLOCK_SIZE_MAX_SECTORS ||
+           !is_power_of_2(block_size)) {
+               ti->error = "Invalid block size";
+               r = -EINVAL;
+               goto out;
+       }
+
+       if (kstrtoull(argv[3], 10, (unsigned long long *)&low_water) ||
+           !low_water) {
+               ti->error = "Invalid low water mark";
+               r = -EINVAL;
+               goto out;
+       }
+
+       /*
+        * Set default pool features.
+        */
+       memset(&pf, 0, sizeof(pf));
+       pf.zero_new_blocks = 1;
+
+       dm_consume_args(&as, 4);
+       r = parse_pool_features(&as, &pf, ti);
+       if (r)
+               goto out;
+
+       pool = pool_find(dm_table_get_md(ti->table), metadata_dev->bdev,
+                        block_size, &ti->error);
+       if (IS_ERR(pool)) {
+               r = PTR_ERR(pool);
+               goto out;
+       }
+
+       pt = kzalloc(sizeof(*pt), GFP_KERNEL);
+       if (!pt) {
+               pool_destroy(pool);
+               r = -ENOMEM;
+               goto out;
+       }
+       pt->pool = pool;
+       pt->ti = ti;
+       pt->metadata_dev = metadata_dev;
+       pt->data_dev = data_dev;
+       pt->low_water_mark = low_water;
+       pt->zero_new_blocks = pf.zero_new_blocks;
+       ti->num_flush_requests = 1;
+       ti->num_discard_requests = 0;
+       ti->discards_supported = 0;
+       ti->private = pt;
+
+       pt->callbacks.congested_fn = pool_is_congested;
+       dm_table_add_target_callbacks(ti->table, &pt->callbacks);
+
+       return 0;
+
+out:
+       dm_put_device(ti, data_dev);
+out_metadata:
+       dm_put_device(ti, metadata_dev);
+
+       return r;
+}
+
+static void pool_dtr(struct dm_target *ti)
+{
+       struct pool_c *pt = ti->private;
+
+       unbind_control_target(pt->pool, ti);
+       pool_dec(pt->pool);
+
+       dm_put_device(ti, pt->metadata_dev);
+       dm_put_device(ti, pt->data_dev);
+
+       kfree(pt);
+}
+
+static void __requeue_bios(struct pool *pool)
+{
+       bio_list_merge(&pool->deferred_bios, &pool->retry_on_resume_list);
+       bio_list_init(&pool->retry_on_resume_list);
+}
+
+/*
+ * Retrieves the number of blocks of the data device from
+ * the superblock and compares it to the actual device size,
+ * thus resizing the data device in case it has grown.
+ *
+ * This both copes with opening preallocated data devices in the ctr
+ * being followed by a resume
+ * -and-
+ * calling the resume method individually after userspace has
+ * grown the data device in reaction to a table event.
+ */
+static int pool_preresume(struct dm_target *ti)
+{
+       int r;
+       struct pool_c *pt = ti->private;
+       struct pool *pool = pt->pool;
+       dm_block_t data_size, sb_data_size;
+       unsigned long flags;
+
+       /*
+        * Take control of the pool object.
+        */
+       r = bind_control_target(pool, ti);
+       if (r)
+               return r;
+
+       data_size = ti->len >> pool->block_shift;
+       r = dm_pool_get_data_dev_size(pool->pmd, &sb_data_size);
+       if (r) {
+               DMERR("failed to retrieve data device size");
+               return r;
+       }
+
+       if (data_size < sb_data_size) {
+               DMERR("pool target too small, is %llu blocks (expected %llu)",
+                     data_size, sb_data_size);
+               return -EINVAL;
+
+       } else if (data_size > sb_data_size) {
+               r = dm_pool_resize_data_dev(pool->pmd, data_size);
+               if (r) {
+                       DMERR("failed to resize data device");
+                       return r;
+               }
+
+               r = dm_pool_commit_metadata(pool->pmd);
+               if (r) {
+                       DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
+                             __func__, r);
+                       return r;
+               }
+       }
+
+       spin_lock_irqsave(&pool->lock, flags);
+       pool->low_water_triggered = 0;
+       __requeue_bios(pool);
+       spin_unlock_irqrestore(&pool->lock, flags);
+
+       wake_worker(pool);
+
+       /*
+        * The pool object is only present if the pool is active.
+        */
+       pool->pool_md = dm_table_get_md(ti->table);
+       pool_table_insert(pool);
+
+       return 0;
+}
+
+static void pool_postsuspend(struct dm_target *ti)
+{
+       int r;
+       struct pool_c *pt = ti->private;
+       struct pool *pool = pt->pool;
+
+       flush_workqueue(pool->wq);
+
+       r = dm_pool_commit_metadata(pool->pmd);
+       if (r) {
+               DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
+                     __func__, r);
+               /* FIXME: invalidate device? error the next FUA or FLUSH bio ?*/
+       }
+
+       pool_table_remove(pool);
+       pool->pool_md = NULL;
+}
+
+static int check_arg_count(unsigned argc, unsigned args_required)
+{
+       if (argc != args_required) {
+               DMWARN("Message received with %u arguments instead of %u.",
+                      argc, args_required);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int read_dev_id(char *arg, dm_thin_id *dev_id, int warning)
+{
+       if (!kstrtoull(arg, 10, (unsigned long long *)dev_id) &&
+           *dev_id <= MAX_DEV_ID)
+               return 0;
+
+       if (warning)
+               DMWARN("Message received with invalid device id: %s", arg);
+
+       return -EINVAL;
+}
+
+static int process_create_thin_mesg(unsigned argc, char **argv, struct pool *pool)
+{
+       dm_thin_id dev_id;
+       int r;
+
+       r = check_arg_count(argc, 2);
+       if (r)
+               return r;
+
+       r = read_dev_id(argv[1], &dev_id, 1);
+       if (r)
+               return r;
+
+       r = dm_pool_create_thin(pool->pmd, dev_id);
+       if (r) {
+               DMWARN("Creation of new thinly-provisioned device with id %s failed.",
+                      argv[1]);
+               return r;
+       }
+
+       return 0;
+}
+
+static int process_create_snap_mesg(unsigned argc, char **argv, struct pool *pool)
+{
+       dm_thin_id dev_id;
+       dm_thin_id origin_dev_id;
+       int r;
+
+       r = check_arg_count(argc, 3);
+       if (r)
+               return r;
+
+       r = read_dev_id(argv[1], &dev_id, 1);
+       if (r)
+               return r;
+
+       r = read_dev_id(argv[2], &origin_dev_id, 1);
+       if (r)
+               return r;
+
+       r = dm_pool_create_snap(pool->pmd, dev_id, origin_dev_id);
+       if (r) {
+               DMWARN("Creation of new snapshot %s of device %s failed.",
+                      argv[1], argv[2]);
+               return r;
+       }
+
+       return 0;
+}
+
+static int process_delete_mesg(unsigned argc, char **argv, struct pool *pool)
+{
+       dm_thin_id dev_id;
+       int r;
+
+       r = check_arg_count(argc, 2);
+       if (r)
+               return r;
+
+       r = read_dev_id(argv[1], &dev_id, 1);
+       if (r)
+               return r;
+
+       r = dm_pool_delete_thin_device(pool->pmd, dev_id);
+       if (r)
+               DMWARN("Deletion of thin device %s failed.", argv[1]);
+
+       return r;
+}
+
+static int process_trim_mesg(unsigned argc, char **argv, struct pool *pool)
+{
+       dm_thin_id dev_id;
+       sector_t new_size;
+       int r;
+
+       r = check_arg_count(argc, 3);
+       if (r)
+               return r;
+
+       r = read_dev_id(argv[1], &dev_id, 1);
+       if (r)
+               return r;
+
+       if (kstrtoull(argv[2], 10, (unsigned long long *)&new_size)) {
+               DMWARN("trim device %s: Invalid new size: %s sectors.",
+                      argv[1], argv[2]);
+               return -EINVAL;
+       }
+
+       r = dm_pool_trim_thin_device(pool->pmd, dev_id,
+                       dm_sector_div_up(new_size, pool->sectors_per_block));
+       if (r)
+               DMWARN("Attempt to trim thin device %s failed.", argv[1]);
+
+       return r;
+}
+
+static int process_set_transaction_id_mesg(unsigned argc, char **argv, struct pool *pool)
+{
+       dm_thin_id old_id, new_id;
+       int r;
+
+       r = check_arg_count(argc, 3);
+       if (r)
+               return r;
+
+       if (kstrtoull(argv[1], 10, (unsigned long long *)&old_id)) {
+               DMWARN("set_transaction_id message: Unrecognised id %s.", argv[1]);
+               return -EINVAL;
+       }
+
+       if (kstrtoull(argv[2], 10, (unsigned long long *)&new_id)) {
+               DMWARN("set_transaction_id message: Unrecognised new id %s.", argv[2]);
+               return -EINVAL;
+       }
+
+       r = dm_pool_set_metadata_transaction_id(pool->pmd, old_id, new_id);
+       if (r) {
+               DMWARN("Failed to change transaction id from %s to %s.",
+                      argv[1], argv[2]);
+               return r;
+       }
+
+       return 0;
+}
+
+/*
+ * Messages supported:
+ *   create_thin       <dev_id>
+ *   create_snap       <dev_id> <origin_id>
+ *   delete            <dev_id>
+ *   trim              <dev_id> <new_size_in_sectors>
+ *   set_transaction_id <current_trans_id> <new_trans_id>
+ */
+static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+       int r = -EINVAL;
+       struct pool_c *pt = ti->private;
+       struct pool *pool = pt->pool;
+
+       if (!strcasecmp(argv[0], "create_thin"))
+               r = process_create_thin_mesg(argc, argv, pool);
+
+       else if (!strcasecmp(argv[0], "create_snap"))
+               r = process_create_snap_mesg(argc, argv, pool);
+
+       else if (!strcasecmp(argv[0], "delete"))
+               r = process_delete_mesg(argc, argv, pool);
+
+       else if (!strcasecmp(argv[0], "trim"))
+               r = process_trim_mesg(argc, argv, pool);
+
+       else if (!strcasecmp(argv[0], "set_transaction_id"))
+               r = process_set_transaction_id_mesg(argc, argv, pool);
+
+       else
+               DMWARN("Unrecognised thin pool target message received: %s", argv[0]);
+
+       if (!r) {
+               r = dm_pool_commit_metadata(pool->pmd);
+               if (r)
+                       DMERR("%s message: dm_pool_commit_metadata() failed, error = %d",
+                             argv[0], r);
+       }
+
+       return r;
+}
+
+/*
+ * Status line is:
+ *    <transaction id> <used metadata sectors>/<total metadata sectors>
+ *    <used data sectors>/<total data sectors> <held metadata root>
+ */
+static int pool_status(struct dm_target *ti, status_type_t type,
+                      char *result, unsigned maxlen)
+{
+       int r;
+       unsigned sz = 0;
+       uint64_t transaction_id;
+       dm_block_t nr_free_blocks_data;
+       dm_block_t nr_free_blocks_metadata;
+       dm_block_t nr_blocks_data;
+       dm_block_t nr_blocks_metadata;
+       dm_block_t held_root;
+       char buf[BDEVNAME_SIZE];
+       char buf2[BDEVNAME_SIZE];
+       struct pool_c *pt = ti->private;
+       struct pool *pool = pt->pool;
+
+       switch (type) {
+       case STATUSTYPE_INFO:
+               r = dm_pool_get_metadata_transaction_id(pool->pmd,
+                                                       &transaction_id);
+               if (r)
+                       return r;
+
+               r = dm_pool_get_free_metadata_block_count(pool->pmd,
+                                                         &nr_free_blocks_metadata);
+               if (r)
+                       return r;
+
+               r = dm_pool_get_metadata_dev_size(pool->pmd, &nr_blocks_metadata);
+               if (r)
+                       return r;
+
+               r = dm_pool_get_free_block_count(pool->pmd,
+                                                &nr_free_blocks_data);
+               if (r)
+                       return r;
+
+               r = dm_pool_get_data_dev_size(pool->pmd, &nr_blocks_data);
+               if (r)
+                       return r;
+
+               r = dm_pool_get_held_metadata_root(pool->pmd, &held_root);
+               if (r)
+                       return r;
+
+               DMEMIT("%llu %llu/%llu %llu/%llu", (unsigned long long)transaction_id,
+                      (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata) *
+                                          pool->sectors_per_block,
+                      (unsigned long long)nr_blocks_metadata * pool->sectors_per_block,
+                      (unsigned long long)(nr_blocks_data - nr_free_blocks_data) *
+                                          pool->sectors_per_block,
+                      (unsigned long long)nr_blocks_data * pool->sectors_per_block);
+
+               if (held_root)
+                       DMEMIT("%llu", held_root);
+               else
+                       DMEMIT("-");
+
+               break;
+
+       case STATUSTYPE_TABLE:
+               DMEMIT("%s %s %lu %llu ",
+                      format_dev_t(buf, pt->metadata_dev->bdev->bd_dev),
+                      format_dev_t(buf2, pt->data_dev->bdev->bd_dev),
+                      (unsigned long)pool->sectors_per_block,
+                      (unsigned long long)pt->low_water_mark);
+
+               DMEMIT("%u ", !pool->zero_new_blocks);
+
+               if (!pool->zero_new_blocks)
+                       DMEMIT("skip_block_zeroing ");
+               break;
+       }
+
+       return 0;
+}
+
+static int pool_iterate_devices(struct dm_target *ti,
+                               iterate_devices_callout_fn fn, void *data)
+{
+       struct pool_c *pt = ti->private;
+
+       return fn(ti, pt->data_dev, 0, ti->len, data);
+}
+
+static int pool_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+                     struct bio_vec *biovec, int max_size)
+{
+       struct pool_c *pt = ti->private;
+       struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
+
+       if (!q->merge_bvec_fn)
+               return max_size;
+
+       bvm->bi_bdev = pt->data_dev->bdev;
+
+       return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
+}
+
+static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
+{
+       struct pool_c *pt = ti->private;
+       struct pool *pool = pt->pool;
+
+       blk_limits_io_min(limits, 0);
+       blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
+}
+
+static struct target_type pool_target = {
+       .name = "thin-pool",
+       .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE,
+       .version = {1, 0, 0},
+       .module = THIS_MODULE,
+       .ctr = pool_ctr,
+       .dtr = pool_dtr,
+       .map = pool_map,
+       .postsuspend = pool_postsuspend,
+       .preresume = pool_preresume,
+       .message = pool_message,
+       .status = pool_status,
+       .merge = pool_merge,
+       .iterate_devices = pool_iterate_devices,
+       .io_hints = pool_io_hints,
+};
+
+/*----------------------------------------------------------------*/
+
+static void thin_dtr(struct dm_target *ti)
+{
+       struct thin_c *tc = ti->private;
+
+       pool_dec(tc->pool);
+       dm_pool_close_thin_device(tc->td);
+       dm_put_device(ti, tc->pool_dev);
+       kfree(tc);
+}
+
+/*
+ * Thin target parameters:
+ *
+ * <pool_dev> <dev_id>
+ *
+ * pool_dev: the path to the pool (eg, /dev/mapper/my_pool)
+ * dev_id: the internal device identifier
+ */
+static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
+{
+       int r;
+       struct thin_c *tc;
+       struct dm_dev *pool_dev;
+       struct mapped_device *pool_md;
+
+       if (argc != 2) {
+               ti->error = "Invalid argument count";
+               return -EINVAL;
+       }
+
+       tc = ti->private = kzalloc(sizeof(*tc), GFP_KERNEL);
+       if (!tc) {
+               ti->error = "Out of memory";
+               return -ENOMEM;
+       }
+
+       r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &pool_dev);
+       if (r) {
+               ti->error = "Error opening pool device";
+               goto bad_pool_dev;
+       }
+       tc->pool_dev = pool_dev;
+
+       if (read_dev_id(argv[1], (unsigned long long *)&tc->dev_id, 0)) {
+               ti->error = "Invalid device id";
+               r = -EINVAL;
+               goto bad_common;
+       }
+
+       pool_md = dm_get_md(tc->pool_dev->bdev->bd_dev);
+       if (!pool_md) {
+               ti->error = "Couldn't get pool mapped device";
+               r = -EINVAL;
+               goto bad_common;
+       }
+
+       tc->pool = pool_table_lookup(pool_md);
+       if (!tc->pool) {
+               ti->error = "Couldn't find pool object";
+               r = -EINVAL;
+               goto bad_pool_lookup;
+       }
+       pool_inc(tc->pool);
+
+       r = dm_pool_open_thin_device(tc->pool->pmd, tc->dev_id, &tc->td);
+       if (r) {
+               ti->error = "Couldn't open thin internal device";
+               goto bad_thin_open;
+       }
+
+       ti->split_io = tc->pool->sectors_per_block;
+       ti->num_flush_requests = 1;
+       ti->num_discard_requests = 0;
+       ti->discards_supported = 0;
+
+       dm_put(pool_md);
+
+       return 0;
+
+bad_thin_open:
+       pool_dec(tc->pool);
+bad_pool_lookup:
+       dm_put(pool_md);
+bad_common:
+       dm_put_device(ti, tc->pool_dev);
+bad_pool_dev:
+       kfree(tc);
+
+       return r;
+}
+
+static int thin_map(struct dm_target *ti, struct bio *bio,
+                   union map_info *map_context)
+{
+       bio->bi_sector -= ti->begin;
+
+       return thin_bio_map(ti, bio, map_context);
+}
+
+/*
+ * <nr mapped sectors> <highest mapped sector>
+ */
+static int thin_status(struct dm_target *ti, status_type_t type,
+                      char *result, unsigned maxlen)
+{
+       int r;
+       ssize_t sz = 0;
+       dm_block_t mapped, highest;
+       char buf[BDEVNAME_SIZE];
+       struct thin_c *tc = ti->private;
+
+       if (!tc->td)
+               DMEMIT("-");
+       else {
+               switch (type) {
+               case STATUSTYPE_INFO:
+                       r = dm_thin_get_mapped_count(tc->td, &mapped);
+                       if (r)
+                               return r;
+
+                       r = dm_thin_get_highest_mapped_block(tc->td, &highest);
+                       if (r < 0)
+                               return r;
+
+                       DMEMIT("%llu ", mapped * tc->pool->sectors_per_block);
+                       if (r)
+                               DMEMIT("%llu", ((highest + 1) *
+                                               tc->pool->sectors_per_block) - 1);
+                       else
+                               DMEMIT("-");
+                       break;
+
+               case STATUSTYPE_TABLE:
+                       DMEMIT("%s %lu",
+                              format_dev_t(buf, tc->pool_dev->bdev->bd_dev),
+                              (unsigned long) tc->dev_id);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int thin_iterate_devices(struct dm_target *ti,
+                               iterate_devices_callout_fn fn, void *data)
+{
+       struct thin_c *tc = ti->private;
+
+       return fn(ti, tc->pool_dev, 0, tc->pool->sectors_per_block, data);
+}
+
+static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
+{
+       struct thin_c *tc = ti->private;
+
+       blk_limits_io_min(limits, 0);
+       blk_limits_io_opt(limits, tc->pool->sectors_per_block << SECTOR_SHIFT);
+}
+
+static struct target_type thin_target = {
+       .name = "thin",
+       .version = {1, 0, 0},
+       .module = THIS_MODULE,
+       .ctr = thin_ctr,
+       .dtr = thin_dtr,
+       .map = thin_map,
+       .status = thin_status,
+       .iterate_devices = thin_iterate_devices,
+       .io_hints = thin_io_hints,
+};
+
+/*----------------------------------------------------------------*/
+
+static int __init dm_thin_init(void)
+{
+       int r;
+
+       pool_table_init();
+
+       r = dm_register_target(&thin_target);
+       if (r)
+               return r;
+
+       r = dm_register_target(&pool_target);
+       if (r)
+               dm_unregister_target(&thin_target);
+
+       return r;
+}
+
+static void dm_thin_exit(void)
+{
+       dm_unregister_target(&thin_target);
+       dm_unregister_target(&pool_target);
+}
+
+module_init(dm_thin_init);
+module_exit(dm_thin_exit);
+
+MODULE_DESCRIPTION(DM_NAME "device-mapper thin provisioning target");
+MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
index 52b39f335bb38549045f46eae8cad3714c867c5d..049421038e8c870a2f6ba986f2ac87a2276301b8 100644 (file)
 
 #define DM_MSG_PREFIX "core"
 
+#ifdef CONFIG_PRINTK
+/*
+ * ratelimit state to be used in DMXXX_LIMIT().
+ */
+DEFINE_RATELIMIT_STATE(dm_ratelimit_state,
+                      DEFAULT_RATELIMIT_INTERVAL,
+                      DEFAULT_RATELIMIT_BURST);
+EXPORT_SYMBOL(dm_ratelimit_state);
+#endif
+
 /*
  * Cookies are numeric values sent with CHANGE and REMOVE
  * uevents while resuming, removing or renaming the device.
@@ -2231,6 +2241,7 @@ struct mapped_device *dm_get_md(dev_t dev)
 
        return md;
 }
+EXPORT_SYMBOL_GPL(dm_get_md);
 
 void *dm_get_mdptr(struct mapped_device *md)
 {
@@ -2316,7 +2327,6 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
        while (1) {
                set_current_state(interruptible);
 
-               smp_mb();
                if (!md_in_flight(md))
                        break;
 
index 8e221a20f5d98b362e8f49660454add87a5e3b38..9a880239219db5f1e08f2f176ffa0605f0ff22e5 100644 (file)
@@ -1738,6 +1738,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        sb->level = cpu_to_le32(mddev->level);
        sb->layout = cpu_to_le32(mddev->layout);
 
+       if (test_bit(WriteMostly, &rdev->flags))
+               sb->devflags |= WriteMostly1;
+       else
+               sb->devflags &= ~WriteMostly1;
+
        if (mddev->bitmap && mddev->bitmap_info.file == NULL) {
                sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset);
                sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
@@ -2561,7 +2566,10 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
        int err = -EINVAL;
        if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
                md_error(rdev->mddev, rdev);
-               err = 0;
+               if (test_bit(Faulty, &rdev->flags))
+                       err = 0;
+               else
+                       err = -EBUSY;
        } else if (cmd_match(buf, "remove")) {
                if (rdev->raid_disk >= 0)
                        err = -EBUSY;
@@ -5983,6 +5991,8 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev)
                return -ENODEV;
 
        md_error(mddev, rdev);
+       if (!test_bit(Faulty, &rdev->flags))
+               return -EBUSY;
        return 0;
 }
 
diff --git a/drivers/md/persistent-data/Kconfig b/drivers/md/persistent-data/Kconfig
new file mode 100644 (file)
index 0000000..e2bef2d
--- /dev/null
@@ -0,0 +1,7 @@
+config DM_PERSISTENT_DATA
+       tristate "Persistent data library (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       select LIBCRC32C
+       ---help---
+        Library providing immutable on-disk data structure support for
+        device-mapper targets such as the thin provisioning target.
diff --git a/drivers/md/persistent-data/Makefile b/drivers/md/persistent-data/Makefile
new file mode 100644 (file)
index 0000000..55c44bf
--- /dev/null
@@ -0,0 +1,9 @@
+obj-$(CONFIG_DM_PERSISTENT_DATA) += dm-persistent-data.o
+dm-persistent-data-objs := \
+       dm-block-manager.o \
+       dm-space-map-disk.o \
+       dm-space-map-metadata.o \
+       dm-transaction-manager.o \
+       dm-btree.o \
+       dm-btree-remove.o \
+       dm-btree-spine.o
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c
new file mode 100644 (file)
index 0000000..43b1235
--- /dev/null
@@ -0,0 +1,998 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+#include "dm-block-manager.h"
+#include "dm-persistent-data-internal.h"
+
+#include <linux/dm-io.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/device-mapper.h>
+
+#define DM_MSG_PREFIX "block manager"
+
+/*----------------------------------------------------------------*/
+
+#define SECTOR_SIZE (1 << SECTOR_SHIFT)
+#define MAX_CACHE_SIZE 16U
+
+enum dm_block_state {
+       BS_EMPTY,
+       BS_CLEAN,
+       BS_READING,
+       BS_WRITING,
+       BS_READ_LOCKED,
+       BS_READ_LOCKED_DIRTY,   /* Block was dirty before it was read locked. */
+       BS_WRITE_LOCKED,
+       BS_DIRTY,
+       BS_ERROR
+};
+
+struct dm_block {
+       struct list_head list;
+       struct hlist_node hlist;
+
+       dm_block_t where;
+       struct dm_block_validator *validator;
+       void *data;
+       wait_queue_head_t io_q;
+       unsigned read_lock_count;
+       unsigned write_lock_pending;
+       enum dm_block_state state;
+
+       /*
+        * Extra flags like REQ_FLUSH and REQ_FUA can be set here.  This is
+        * mainly as to avoid a race condition in flush_and_unlock() where
+        * the newly-unlocked superblock may have been submitted for a
+        * write before the write_all_dirty() call is made.
+        */
+       int io_flags;
+
+       /*
+        * Sadly we need an up pointer so we can get to the bm on io
+        * completion.
+        */
+       struct dm_block_manager *bm;
+};
+
+struct dm_block_manager {
+       struct block_device *bdev;
+       unsigned cache_size;
+       unsigned max_held_per_thread;
+       unsigned block_size;    /* In bytes */
+       dm_block_t nr_blocks;
+
+       /*
+        * This will trigger every time an io completes.
+        */
+       wait_queue_head_t io_q;
+
+       struct dm_io_client *io;
+
+       /*
+        * Protects all the lists and the hash table.
+        */
+       spinlock_t lock;
+
+       unsigned error_count;
+       unsigned available_count;
+       unsigned reading_count;
+       unsigned writing_count;
+
+       struct list_head empty_list;    /* No block assigned */
+       struct list_head clean_list;    /* Unlocked and clean */
+       struct list_head dirty_list;    /* Unlocked and dirty */
+       struct list_head error_list;
+
+       char buffer_cache_name[32];
+       struct kmem_cache *buffer_cache; /* The buffers that store the raw data */
+
+       /*
+        * Hash table of cached blocks, holds everything that isn't in the
+        * BS_EMPTY state.
+        */
+       unsigned hash_size;
+       unsigned hash_mask;
+
+       struct hlist_head buckets[0];   /* Must be last member of struct. */
+};
+
+dm_block_t dm_block_location(struct dm_block *b)
+{
+       return b->where;
+}
+EXPORT_SYMBOL_GPL(dm_block_location);
+
+void *dm_block_data(struct dm_block *b)
+{
+       return b->data;
+}
+EXPORT_SYMBOL_GPL(dm_block_data);
+
+/*----------------------------------------------------------------
+ * Hash table
+ *--------------------------------------------------------------*/
+static struct dm_block *__find_block(struct dm_block_manager *bm, dm_block_t b)
+{
+       unsigned bucket = dm_hash_block(b, bm->hash_mask);
+       struct dm_block *blk;
+       struct hlist_node *n;
+
+       hlist_for_each_entry(blk, n, bm->buckets + bucket, hlist)
+               if (blk->where == b)
+                       return blk;
+
+       return NULL;
+}
+
+static void __insert_block(struct dm_block_manager *bm, struct dm_block *b)
+{
+       unsigned bucket = dm_hash_block(b->where, bm->hash_mask);
+
+       hlist_add_head(&b->hlist, bm->buckets + bucket);
+}
+
+/*----------------------------------------------------------------
+ * Block state:
+ * __transition() handles transition of a block between different states.
+ * Study this to understand the state machine.
+ *
+ * Alternatively install graphviz and run:
+ *     grep DOT dm-block-manager.c | grep -v ' ' |
+ *      sed -e 's/.*DOT: //' -e 's/\*\///' |
+ *      dot -Tps -o states.ps
+ *
+ * Assumes bm->lock is held.
+ *--------------------------------------------------------------*/
+static void __transition(struct dm_block *b, enum dm_block_state new_state)
+{
+       /* DOT: digraph BlockStates { */
+       struct dm_block_manager *bm = b->bm;
+
+       switch (new_state) {
+       case BS_EMPTY:
+               /* DOT: error -> empty */
+               /* DOT: clean -> empty */
+               BUG_ON(!((b->state == BS_ERROR) ||
+                        (b->state == BS_CLEAN)));
+               hlist_del(&b->hlist);
+               list_move(&b->list, &bm->empty_list);
+               b->write_lock_pending = 0;
+               b->read_lock_count = 0;
+               b->io_flags = 0;
+               b->validator = NULL;
+
+               if (b->state == BS_ERROR) {
+                       bm->error_count--;
+                       bm->available_count++;
+               }
+               break;
+
+       case BS_CLEAN:
+               /* DOT: reading -> clean */
+               /* DOT: writing -> clean */
+               /* DOT: read_locked -> clean */
+               BUG_ON(!((b->state == BS_READING) ||
+                        (b->state == BS_WRITING) ||
+                        (b->state == BS_READ_LOCKED)));
+               switch (b->state) {
+               case BS_READING:
+                       BUG_ON(!bm->reading_count);
+                       bm->reading_count--;
+                       break;
+
+               case BS_WRITING:
+                       BUG_ON(!bm->writing_count);
+                       bm->writing_count--;
+                       b->io_flags = 0;
+                       break;
+
+               default:
+                       break;
+               }
+               list_add_tail(&b->list, &bm->clean_list);
+               bm->available_count++;
+               break;
+
+       case BS_READING:
+               /* DOT: empty -> reading */
+               BUG_ON(!(b->state == BS_EMPTY));
+               __insert_block(bm, b);
+               list_del(&b->list);
+               bm->available_count--;
+               bm->reading_count++;
+               break;
+
+       case BS_WRITING:
+               /* DOT: dirty -> writing */
+               BUG_ON(!(b->state == BS_DIRTY));
+               list_del(&b->list);
+               bm->writing_count++;
+               break;
+
+       case BS_READ_LOCKED:
+               /* DOT: clean -> read_locked */
+               BUG_ON(!(b->state == BS_CLEAN));
+               list_del(&b->list);
+               bm->available_count--;
+               break;
+
+       case BS_READ_LOCKED_DIRTY:
+               /* DOT: dirty -> read_locked_dirty */
+               BUG_ON(!((b->state == BS_DIRTY)));
+               list_del(&b->list);
+               break;
+
+       case BS_WRITE_LOCKED:
+               /* DOT: dirty -> write_locked */
+               /* DOT: clean -> write_locked */
+               BUG_ON(!((b->state == BS_DIRTY) ||
+                        (b->state == BS_CLEAN)));
+               list_del(&b->list);
+
+               if (b->state == BS_CLEAN)
+                       bm->available_count--;
+               break;
+
+       case BS_DIRTY:
+               /* DOT: write_locked -> dirty */
+               /* DOT: read_locked_dirty -> dirty */
+               BUG_ON(!((b->state == BS_WRITE_LOCKED) ||
+                        (b->state == BS_READ_LOCKED_DIRTY)));
+               list_add_tail(&b->list, &bm->dirty_list);
+               break;
+
+       case BS_ERROR:
+               /* DOT: writing -> error */
+               /* DOT: reading -> error */
+               BUG_ON(!((b->state == BS_WRITING) ||
+                        (b->state == BS_READING)));
+               bm->error_count++;
+               list_add_tail(&b->list, &bm->error_list);
+               break;
+       }
+
+       b->state = new_state;
+       /* DOT: } */
+}
+
+/*----------------------------------------------------------------
+ * Low-level io.
+ *--------------------------------------------------------------*/
+typedef void (completion_fn)(unsigned long error, struct dm_block *b);
+
+static void submit_io(struct dm_block *b, int rw,
+                     completion_fn fn)
+{
+       struct dm_block_manager *bm = b->bm;
+       struct dm_io_request req;
+       struct dm_io_region region;
+       unsigned sectors_per_block = bm->block_size >> SECTOR_SHIFT;
+
+       region.bdev = bm->bdev;
+       region.sector = b->where * sectors_per_block;
+       region.count = sectors_per_block;
+
+       req.bi_rw = rw;
+       req.mem.type = DM_IO_KMEM;
+       req.mem.offset = 0;
+       req.mem.ptr.addr = b->data;
+       req.notify.fn = (void (*)(unsigned long, void *)) fn;
+       req.notify.context = b;
+       req.client = bm->io;
+
+       if (dm_io(&req, 1, &region, NULL) < 0)
+               fn(1, b);
+}
+
+/*----------------------------------------------------------------
+ * High-level io.
+ *--------------------------------------------------------------*/
+static void __complete_io(unsigned long error, struct dm_block *b)
+{
+       struct dm_block_manager *bm = b->bm;
+
+       if (error) {
+               DMERR("io error = %lu, block = %llu",
+                     error , (unsigned long long)b->where);
+               __transition(b, BS_ERROR);
+       } else
+               __transition(b, BS_CLEAN);
+
+       wake_up(&b->io_q);
+       wake_up(&bm->io_q);
+}
+
+static void complete_io(unsigned long error, struct dm_block *b)
+{
+       struct dm_block_manager *bm = b->bm;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bm->lock, flags);
+       __complete_io(error, b);
+       spin_unlock_irqrestore(&bm->lock, flags);
+}
+
+static void read_block(struct dm_block *b)
+{
+       submit_io(b, READ, complete_io);
+}
+
+static void write_block(struct dm_block *b)
+{
+       if (b->validator)
+               b->validator->prepare_for_write(b->validator, b,
+                                               b->bm->block_size);
+
+       submit_io(b, WRITE | b->io_flags, complete_io);
+}
+
+static void write_dirty(struct dm_block_manager *bm, unsigned count)
+{
+       struct dm_block *b, *tmp;
+       struct list_head dirty;
+       unsigned long flags;
+
+       /*
+        * Grab the first @count entries from the dirty list
+        */
+       INIT_LIST_HEAD(&dirty);
+       spin_lock_irqsave(&bm->lock, flags);
+       list_for_each_entry_safe(b, tmp, &bm->dirty_list, list) {
+               if (!count--)
+                       break;
+               __transition(b, BS_WRITING);
+               list_add_tail(&b->list, &dirty);
+       }
+       spin_unlock_irqrestore(&bm->lock, flags);
+
+       list_for_each_entry_safe(b, tmp, &dirty, list) {
+               list_del(&b->list);
+               write_block(b);
+       }
+}
+
+static void write_all_dirty(struct dm_block_manager *bm)
+{
+       write_dirty(bm, bm->cache_size);
+}
+
+static void __clear_errors(struct dm_block_manager *bm)
+{
+       struct dm_block *b, *tmp;
+       list_for_each_entry_safe(b, tmp, &bm->error_list, list)
+               __transition(b, BS_EMPTY);
+}
+
+/*----------------------------------------------------------------
+ * Waiting
+ *--------------------------------------------------------------*/
+#ifdef __CHECKER__
+#  define __retains(x) __attribute__((context(x, 1, 1)))
+#else
+#  define __retains(x)
+#endif
+
+#define __wait_block(wq, lock, flags, sched_fn, condition)     \
+do {                                                           \
+       DEFINE_WAIT(wait);                                      \
+       add_wait_queue(wq, &wait);                              \
+                                                               \
+       for (;;) {                                              \
+               prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); \
+               if (condition)                                  \
+                       break;                                  \
+                                                               \
+               spin_unlock_irqrestore(lock, flags);            \
+               sched_fn();                                     \
+               spin_lock_irqsave(lock, flags);                 \
+       }                                                       \
+                                                               \
+       finish_wait(wq, &wait);                                 \
+} while (0)
+
+static void __wait_io(struct dm_block *b, unsigned long *flags)
+       __retains(&b->bm->lock)
+{
+       __wait_block(&b->io_q, &b->bm->lock, *flags, io_schedule,
+                    ((b->state != BS_READING) && (b->state != BS_WRITING)));
+}
+
+static void __wait_unlocked(struct dm_block *b, unsigned long *flags)
+       __retains(&b->bm->lock)
+{
+       __wait_block(&b->io_q, &b->bm->lock, *flags, schedule,
+                    ((b->state == BS_CLEAN) || (b->state == BS_DIRTY)));
+}
+
+static void __wait_read_lockable(struct dm_block *b, unsigned long *flags)
+       __retains(&b->bm->lock)
+{
+       __wait_block(&b->io_q, &b->bm->lock, *flags, schedule,
+                    (!b->write_lock_pending && (b->state == BS_CLEAN ||
+                                                b->state == BS_DIRTY ||
+                                                b->state == BS_READ_LOCKED)));
+}
+
+static void __wait_all_writes(struct dm_block_manager *bm, unsigned long *flags)
+       __retains(&bm->lock)
+{
+       __wait_block(&bm->io_q, &bm->lock, *flags, io_schedule,
+                    !bm->writing_count);
+}
+
+static void __wait_all_io(struct dm_block_manager *bm, unsigned long *flags)
+       __retains(&bm->lock)
+{
+       __wait_block(&bm->io_q, &bm->lock, *flags, io_schedule,
+                    !bm->writing_count && !bm->reading_count);
+}
+
+static void __wait_clean(struct dm_block_manager *bm, unsigned long *flags)
+       __retains(&bm->lock)
+{
+       __wait_block(&bm->io_q, &bm->lock, *flags, io_schedule,
+                    (!list_empty(&bm->clean_list) ||
+                     (!bm->writing_count)));
+}
+
+/*----------------------------------------------------------------
+ * Finding a free block to recycle
+ *--------------------------------------------------------------*/
+static int __recycle_block(struct dm_block_manager *bm, dm_block_t where,
+                          int need_read, struct dm_block_validator *v,
+                          unsigned long flags,
+                          struct dm_block **result)
+       __retains(&bm->lock)
+{
+       int r = 0;
+       struct dm_block *b;
+       unsigned long available;
+
+       /*
+        * Wait for a block to appear on the empty or clean lists.
+        */
+retry:
+       while (1) {
+               /*
+                * The calling thread may hold some locks on blocks, and
+                * the rest be errored.  In which case we're never going to
+                * succeed here.
+                */
+               if (bm->error_count == bm->cache_size - bm->max_held_per_thread)
+                       return -ENOMEM;
+
+               /*
+                * Once we can lock and do io concurrently then we should
+                * probably flush at bm->cache_size / 2 and write _all_
+                * dirty blocks.
+                */
+               available = bm->available_count + bm->writing_count;
+               if (available < bm->cache_size / 4) {
+                       spin_unlock_irqrestore(&bm->lock, flags);
+                       write_dirty(bm, bm->cache_size / 4);
+                       spin_lock_irqsave(&bm->lock, flags);
+               }
+
+               if (!list_empty(&bm->empty_list)) {
+                       b = list_first_entry(&bm->empty_list, struct dm_block, list);
+                       break;
+
+               } else if (!list_empty(&bm->clean_list)) {
+                       b = list_first_entry(&bm->clean_list, struct dm_block, list);
+                       __transition(b, BS_EMPTY);
+                       break;
+               }
+
+               __wait_clean(bm, &flags);
+       }
+
+       b->where = where;
+       __transition(b, BS_READING);
+
+       if (!need_read) {
+               memset(b->data, 0, bm->block_size);
+               b->validator = v;
+               __transition(b, BS_CLEAN);
+       } else {
+               spin_unlock_irqrestore(&bm->lock, flags);
+               read_block(b);
+               spin_lock_irqsave(&bm->lock, flags);
+               __wait_io(b, &flags);
+
+               /*
+                * Has b been recycled whilst we were unlocked?
+                */
+               if (b->where != where)
+                       goto retry;
+
+               /*
+                * Did the io succeed?
+                */
+               if (b->state == BS_ERROR) {
+                       /*
+                        * Since this is a read that has failed we can clear the error
+                        * immediately.  Failed writes are revealed during a commit.
+                        */
+                       __transition(b, BS_EMPTY);
+                       r = -EIO;
+               } else {
+                       /*
+                        * We set the validator late, since there's a
+                        * window while we're waiting for the read where
+                        * someone could have set a different one.
+                        */
+                       b->validator = v;
+                       if (b->validator) {
+                               r = b->validator->check(b->validator, b, bm->block_size);
+                               if (r) {
+                                       DMERR("%s validator check failed for block %llu",
+                                             b->validator->name, (unsigned long long)b->where);
+                                       __transition(b, BS_EMPTY);
+                               }
+                       }
+               }
+       }
+
+       if (!r)
+               *result = b;
+
+       return r;
+}
+
+/*----------------------------------------------------------------
+ * Low level block management
+ *--------------------------------------------------------------*/
+
+static struct kmem_cache *dm_block_cache;  /* struct dm_block */
+
+static struct dm_block *alloc_block(struct dm_block_manager *bm)
+{
+       struct dm_block *b = kmem_cache_alloc(dm_block_cache, GFP_KERNEL);
+
+       if (!b)
+               return NULL;
+
+       INIT_LIST_HEAD(&b->list);
+       INIT_HLIST_NODE(&b->hlist);
+
+       b->data = kmem_cache_alloc(bm->buffer_cache, GFP_KERNEL);
+       if (!b->data) {
+               kmem_cache_free(dm_block_cache, b);
+               return NULL;
+       }
+
+       b->validator = NULL;
+       b->state = BS_EMPTY;
+       init_waitqueue_head(&b->io_q);
+       b->read_lock_count = 0;
+       b->write_lock_pending = 0;
+       b->io_flags = 0;
+       b->bm = bm;
+
+       return b;
+}
+
+static void free_block(struct dm_block *b)
+{
+       kmem_cache_free(b->bm->buffer_cache, b->data);
+       kmem_cache_free(dm_block_cache, b);
+}
+
+static int populate_bm(struct dm_block_manager *bm, unsigned count)
+{
+       int i;
+       LIST_HEAD(bs);
+
+       for (i = 0; i < count; i++) {
+               struct dm_block *b = alloc_block(bm);
+               if (!b) {
+                       struct dm_block *tmp;
+                       list_for_each_entry_safe(b, tmp, &bs, list)
+                               free_block(b);
+                       return -ENOMEM;
+               }
+
+               list_add(&b->list, &bs);
+       }
+
+       list_replace(&bs, &bm->empty_list);
+       bm->available_count = count;
+
+       return 0;
+}
+
+/*----------------------------------------------------------------
+ * Public interface
+ *--------------------------------------------------------------*/
+static unsigned calc_hash_size(unsigned cache_size)
+{
+       unsigned r = 32;        /* Minimum size is 16 */
+
+       while (r < cache_size)
+               r <<= 1;
+
+       return r >> 1;
+}
+
+struct dm_block_manager *dm_block_manager_create(struct block_device *bdev,
+                                                unsigned block_size,
+                                                unsigned cache_size,
+                                                unsigned max_held_per_thread)
+{
+       unsigned i;
+       unsigned hash_size = calc_hash_size(cache_size);
+       size_t len = sizeof(struct dm_block_manager) +
+                    sizeof(struct hlist_head) * hash_size;
+       struct dm_block_manager *bm;
+
+       bm = kmalloc(len, GFP_KERNEL);
+       if (!bm)
+               return NULL;
+
+       bm->bdev = bdev;
+       bm->cache_size = max(MAX_CACHE_SIZE, cache_size);
+       bm->max_held_per_thread = max_held_per_thread;
+       bm->block_size = block_size;
+       bm->nr_blocks = i_size_read(bdev->bd_inode);
+       do_div(bm->nr_blocks, block_size);
+       init_waitqueue_head(&bm->io_q);
+       spin_lock_init(&bm->lock);
+
+       INIT_LIST_HEAD(&bm->empty_list);
+       INIT_LIST_HEAD(&bm->clean_list);
+       INIT_LIST_HEAD(&bm->dirty_list);
+       INIT_LIST_HEAD(&bm->error_list);
+       bm->error_count = 0;
+       bm->available_count = 0;
+       bm->reading_count = 0;
+       bm->writing_count = 0;
+
+       sprintf(bm->buffer_cache_name, "dm_block_buffer-%d-%d",
+               MAJOR(disk_devt(bdev->bd_disk)),
+               MINOR(disk_devt(bdev->bd_disk)));
+
+       bm->buffer_cache = kmem_cache_create(bm->buffer_cache_name,
+                                            block_size, SECTOR_SIZE,
+                                            0, NULL);
+       if (!bm->buffer_cache)
+               goto bad_free_bm;
+
+       bm->hash_size = hash_size;
+       bm->hash_mask = hash_size - 1;
+       for (i = 0; i < hash_size; i++)
+               INIT_HLIST_HEAD(bm->buckets + i);
+
+       bm->io = dm_io_client_create();
+       if (!bm->io)
+               goto bad_free_buffer_cache;
+
+       if (populate_bm(bm, cache_size) < 0)
+               goto bad_free_io_client;
+
+       return bm;
+
+bad_free_io_client:
+       dm_io_client_destroy(bm->io);
+bad_free_buffer_cache:
+       kmem_cache_destroy(bm->buffer_cache);
+bad_free_bm:
+       kfree(bm);
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(dm_block_manager_create);
+
+void dm_block_manager_destroy(struct dm_block_manager *bm)
+{
+       int i;
+       struct dm_block *b, *btmp;
+       struct hlist_node *n, *tmp;
+
+       dm_io_client_destroy(bm->io);
+
+       for (i = 0; i < bm->hash_size; i++)
+               hlist_for_each_entry_safe(b, n, tmp, bm->buckets + i, hlist)
+                       free_block(b);
+
+       list_for_each_entry_safe(b, btmp, &bm->empty_list, list)
+               free_block(b);
+
+       kmem_cache_destroy(bm->buffer_cache);
+
+       kfree(bm);
+}
+EXPORT_SYMBOL_GPL(dm_block_manager_destroy);
+
+unsigned dm_bm_block_size(struct dm_block_manager *bm)
+{
+       return bm->block_size;
+}
+EXPORT_SYMBOL_GPL(dm_bm_block_size);
+
+dm_block_t dm_bm_nr_blocks(struct dm_block_manager *bm)
+{
+       return bm->nr_blocks;
+}
+
+static int lock_internal(struct dm_block_manager *bm, dm_block_t block,
+                        int how, int need_read, int can_block,
+                        struct dm_block_validator *v,
+                        struct dm_block **result)
+{
+       int r = 0;
+       struct dm_block *b;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bm->lock, flags);
+retry:
+       b = __find_block(bm, block);
+       if (b) {
+               /*
+                * The block may be in state BS_READING at this point.
+                * Which means we're racing for this block against another
+                * locking op.  This is fine, __wait_read_lockable() below
+                * will do the right thing.  We do need to be careful
+                * however that the validator isn't set until the lock is
+                * full granted, otherwise the other thread could get the
+                * lock, but this one's validator be used. This situation
+                * only arises if there's a programming error in the code
+                * driving bm.
+                */
+
+               switch (how) {
+               case READ:
+                       if (b->write_lock_pending || (b->state != BS_CLEAN &&
+                                                     b->state != BS_DIRTY &&
+                                                     b->state != BS_READ_LOCKED)) {
+                               if (!can_block) {
+                                       spin_unlock_irqrestore(&bm->lock, flags);
+                                       return -EWOULDBLOCK;
+                               }
+
+                               __wait_read_lockable(b, &flags);
+
+                               if (b->where != block)
+                                       goto retry;
+                       }
+                       break;
+
+               case WRITE:
+                       while (b->state != BS_CLEAN && b->state != BS_DIRTY) {
+                               if (!can_block) {
+                                       spin_unlock_irqrestore(&bm->lock, flags);
+                                       return -EWOULDBLOCK;
+                               }
+
+                               b->write_lock_pending++;
+                               __wait_unlocked(b, &flags);
+                               if (b->where != block)
+                                       /*
+                                        * Recycled blocks have their
+                                        * write_lock_pending count reset
+                                        * to zero, so no need to undo the
+                                        * above increment.
+                                        */
+                                       goto retry;
+                               b->write_lock_pending--;
+                       }
+                       break;
+               }
+
+               if (!need_read)
+                       b->validator = v;
+               else {
+                       if (b->validator && (v != b->validator)) {
+                               DMERR("validator mismatch (old=%s vs new=%s) for block %llu",
+                                     b->validator->name, v ? v->name : "NULL",
+                                     (unsigned long long)b->where);
+                               spin_unlock_irqrestore(&bm->lock, flags);
+                               return -EINVAL;
+                       }
+
+                       if (!b->validator && v) {
+                               b->validator = v;
+                               r = b->validator->check(b->validator, b, bm->block_size);
+                               if (r) {
+                                       DMERR("%s validator check failed for block %llu",
+                                             b->validator->name,
+                                             (unsigned long long)b->where);
+                                       spin_unlock_irqrestore(&bm->lock, flags);
+                                       return r;
+                               }
+                       }
+               }
+
+       } else if (!can_block) {
+               r = -EWOULDBLOCK;
+               goto out;
+
+       } else
+               r = __recycle_block(bm, block, need_read, v, flags, &b);
+
+       if (!r) {
+               switch (how) {
+               case READ:
+                       b->read_lock_count++;
+
+                       if (b->state == BS_DIRTY)
+                               __transition(b, BS_READ_LOCKED_DIRTY);
+                       else if (b->state == BS_CLEAN)
+                               __transition(b, BS_READ_LOCKED);
+                       break;
+
+               case WRITE:
+                       __transition(b, BS_WRITE_LOCKED);
+                       break;
+               }
+
+               *result = b;
+       }
+
+out:
+       spin_unlock_irqrestore(&bm->lock, flags);
+
+       return r;
+}
+
+int dm_bm_read_lock(struct dm_block_manager *bm, dm_block_t b,
+                   struct dm_block_validator *v,
+                   struct dm_block **result)
+{
+       return lock_internal(bm, b, READ, 1, 1, v, result);
+}
+EXPORT_SYMBOL_GPL(dm_bm_read_lock);
+
+int dm_bm_write_lock(struct dm_block_manager *bm,
+                    dm_block_t b, struct dm_block_validator *v,
+                    struct dm_block **result)
+{
+       return lock_internal(bm, b, WRITE, 1, 1, v, result);
+}
+EXPORT_SYMBOL_GPL(dm_bm_write_lock);
+
+int dm_bm_read_try_lock(struct dm_block_manager *bm,
+                       dm_block_t b, struct dm_block_validator *v,
+                       struct dm_block **result)
+{
+       return lock_internal(bm, b, READ, 1, 0, v, result);
+}
+
+int dm_bm_write_lock_zero(struct dm_block_manager *bm,
+                         dm_block_t b, struct dm_block_validator *v,
+                         struct dm_block **result)
+{
+       int r = lock_internal(bm, b, WRITE, 0, 1, v, result);
+
+       if (!r)
+               memset((*result)->data, 0, bm->block_size);
+
+       return r;
+}
+
+int dm_bm_unlock(struct dm_block *b)
+{
+       int r = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&b->bm->lock, flags);
+       switch (b->state) {
+       case BS_WRITE_LOCKED:
+               __transition(b, BS_DIRTY);
+               wake_up(&b->io_q);
+               break;
+
+       case BS_READ_LOCKED:
+               if (!--b->read_lock_count) {
+                       __transition(b, BS_CLEAN);
+                       wake_up(&b->io_q);
+               }
+               break;
+
+       case BS_READ_LOCKED_DIRTY:
+               if (!--b->read_lock_count) {
+                       __transition(b, BS_DIRTY);
+                       wake_up(&b->io_q);
+               }
+               break;
+
+       default:
+               DMERR("block = %llu not locked",
+                     (unsigned long long)b->where);
+               r = -EINVAL;
+               break;
+       }
+       spin_unlock_irqrestore(&b->bm->lock, flags);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_bm_unlock);
+
+static int __wait_flush(struct dm_block_manager *bm)
+{
+       int r = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bm->lock, flags);
+       __wait_all_writes(bm, &flags);
+
+       if (!list_empty(&bm->error_list)) {
+               r = -EIO;
+               __clear_errors(bm);
+       }
+       spin_unlock_irqrestore(&bm->lock, flags);
+
+       return r;
+}
+
+int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
+                          struct dm_block *superblock)
+{
+       int r;
+       unsigned long flags;
+
+       write_all_dirty(bm);
+       r = __wait_flush(bm);
+       if (r)
+               return r;
+
+       spin_lock_irqsave(&bm->lock, flags);
+       superblock->io_flags = REQ_FUA | REQ_FLUSH;
+       spin_unlock_irqrestore(&bm->lock, flags);
+
+       dm_bm_unlock(superblock);
+       write_all_dirty(bm);
+
+       return __wait_flush(bm);
+}
+
+int dm_bm_rebind_block_device(struct dm_block_manager *bm,
+                             struct block_device *bdev)
+{
+       unsigned long flags;
+       dm_block_t nr_blocks = i_size_read(bdev->bd_inode);
+
+       do_div(nr_blocks, bm->block_size);
+
+       spin_lock_irqsave(&bm->lock, flags);
+       if (nr_blocks < bm->nr_blocks) {
+               spin_unlock_irqrestore(&bm->lock, flags);
+               return -EINVAL;
+       }
+
+       bm->bdev = bdev;
+       bm->nr_blocks = nr_blocks;
+
+       /*
+        * Wait for any in-flight io that may be using the old bdev
+        */
+       __wait_all_io(bm, &flags);
+       spin_unlock_irqrestore(&bm->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dm_bm_rebind_block_device);
+
+/*----------------------------------------------------------------*/
+
+static int __init init_persistent_data(void)
+{
+       dm_block_cache = KMEM_CACHE(dm_block, SLAB_HWCACHE_ALIGN);
+       if (!dm_block_cache)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void __exit exit_persistent_data(void)
+{
+       kmem_cache_destroy(dm_block_cache);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
+MODULE_DESCRIPTION("Immutable metadata library for dm");
+module_init(init_persistent_data);
+module_exit(exit_persistent_data);
diff --git a/drivers/md/persistent-data/dm-block-manager.h b/drivers/md/persistent-data/dm-block-manager.h
new file mode 100644 (file)
index 0000000..38c49c7
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _LINUX_DM_BLOCK_MANAGER_H
+#define _LINUX_DM_BLOCK_MANAGER_H
+
+#include <linux/blkdev.h>
+#include <linux/types.h>
+#include <linux/crc32c.h>
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Block number.
+ */
+typedef uint64_t dm_block_t;
+
+/*
+ * An opaque handle to a block of data.
+ */
+struct dm_block;
+
+dm_block_t dm_block_location(struct dm_block *b);
+void *dm_block_data(struct dm_block *b);
+
+/*
+ * Use CRC32 checksumming on data blocks.
+ */
+static inline uint32_t dm_block_csum_data(const void *data_le, unsigned length)
+{
+       return crc32c(~(u32)0, data_le, length);
+}
+
+/*----------------------------------------------------------------*/
+
+struct dm_block_manager;
+
+/*
+ * @max_held_per_thread should be the maximum number of locks, read or
+ * write, that an individual thread holds at any one time.
+ */
+struct dm_block_manager *dm_block_manager_create(
+       struct block_device *bdev, unsigned block_size,
+       unsigned cache_size, unsigned max_held_per_thread);
+void dm_block_manager_destroy(struct dm_block_manager *bm);
+
+unsigned dm_bm_block_size(struct dm_block_manager *bm);
+dm_block_t dm_bm_nr_blocks(struct dm_block_manager *bm);
+
+/*----------------------------------------------------------------*/
+
+/*
+ * The validator allows the caller to verify newly-read data and modify
+ * the data just before writing, e.g. to calculate checksums.  It's
+ * important to be consistent with your use of validators.  The only time
+ * you can change validators is if you call dm_bm_write_lock_zero.
+ */
+struct dm_block_validator {
+       const char *name;
+       void (*prepare_for_write)(struct dm_block_validator *v, struct dm_block *b, size_t block_size);
+
+       /*
+        * Return 0 if the checksum is valid or < 0 on error.
+        */
+       int (*check)(struct dm_block_validator *v, struct dm_block *b, size_t block_size);
+};
+
+/*----------------------------------------------------------------*/
+
+/*
+ * You can have multiple concurrent readers or a single writer holding a
+ * block lock.
+ */
+
+/*
+ * dm_bm_lock() locks a block and returns through @result a pointer to
+ * memory that holds a copy of that block.  If you have write-locked the
+ * block then any changes you make to memory pointed to by @result will be
+ * written back to the disk sometime after dm_bm_unlock is called.
+ */
+int dm_bm_read_lock(struct dm_block_manager *bm, dm_block_t b,
+                   struct dm_block_validator *v,
+                   struct dm_block **result);
+
+int dm_bm_write_lock(struct dm_block_manager *bm, dm_block_t b,
+                    struct dm_block_validator *v,
+                    struct dm_block **result);
+
+/*
+ * The *_try_lock variants return -EWOULDBLOCK if the block isn't
+ * available immediately.
+ */
+int dm_bm_read_try_lock(struct dm_block_manager *bm, dm_block_t b,
+                       struct dm_block_validator *v,
+                       struct dm_block **result);
+
+/*
+ * Use dm_bm_write_lock_zero() when you know you're going to
+ * overwrite the block completely.  It saves a disk read.
+ */
+int dm_bm_write_lock_zero(struct dm_block_manager *bm, dm_block_t b,
+                         struct dm_block_validator *v,
+                         struct dm_block **result);
+
+int dm_bm_unlock(struct dm_block *b);
+
+/*
+ * It's a common idiom to have a superblock that should be committed last.
+ *
+ * @superblock should be write-locked on entry. It will be unlocked during
+ * this function.  All dirty blocks are guaranteed to be written and flushed
+ * before the superblock.
+ *
+ * This method always blocks.
+ */
+int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
+                          struct dm_block *superblock);
+
+/*
+ * The client may wish to change the block device to which the block
+ * manager points.  If you use this function then the cache remains intact,
+ * so the data must be identical on the both devices, e.g. a different
+ * path to the same disk, and it must be at least as big.
+ *
+ * This function guarantees that once it returns, no further IO will occur
+ * on the old device.
+ */
+int dm_bm_rebind_block_device(struct dm_block_manager *bm,
+                             struct block_device *bdev);
+
+#endif /* _LINUX_DM_BLOCK_MANAGER_H */
diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h
new file mode 100644 (file)
index 0000000..c693788
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_BTREE_INTERNAL_H
+#define DM_BTREE_INTERNAL_H
+
+#include "dm-btree.h"
+
+/*----------------------------------------------------------------*/
+
+/*
+ * We'll need 2 accessor functions for n->csum and n->blocknr
+ * to support dm-btree-spine.c in that case.
+ */
+
+enum node_flags {
+       INTERNAL_NODE = 1,
+       LEAF_NODE = 1 << 1
+};
+
+/*
+ * Every btree node begins with this structure.  Make sure it's a multiple
+ * of 8-bytes in size, otherwise the 64bit keys will be mis-aligned.
+ */
+struct node_header {
+       __le32 csum;
+       __le32 flags;
+       __le64 blocknr; /* Block this node is supposed to live in. */
+
+       __le32 nr_entries;
+       __le32 max_entries;
+       __le32 value_size;
+       __le32 padding;
+} __packed;
+
+struct node {
+       struct node_header header;
+       __le64 keys[0];
+} __packed;
+
+
+void inc_children(struct dm_transaction_manager *tm, struct node *n,
+                 struct dm_btree_value_type *vt);
+
+int new_block(struct dm_btree_info *info, struct dm_block **result);
+int unlock_block(struct dm_btree_info *info, struct dm_block *b);
+
+/*
+ * Spines keep track of the rolling locks.  There are 2 variants, read-only
+ * and one that uses shadowing.  These are separate structs to allow the
+ * type checker to spot misuse, for example accidentally calling read_lock
+ * on a shadow spine.
+ */
+struct ro_spine {
+       struct dm_btree_info *info;
+
+       int count;
+       struct dm_block *nodes[2];
+};
+
+void init_ro_spine(struct ro_spine *s, struct dm_btree_info *info);
+int exit_ro_spine(struct ro_spine *s);
+int ro_step(struct ro_spine *s, dm_block_t new_child);
+struct node *ro_node(struct ro_spine *s);
+
+struct shadow_spine {
+       struct dm_btree_info *info;
+
+       int count;
+       struct dm_block *nodes[2];
+
+       dm_block_t root;
+};
+
+void init_shadow_spine(struct shadow_spine *s, struct dm_btree_info *info);
+int exit_shadow_spine(struct shadow_spine *s);
+
+int shadow_step(struct shadow_spine *s, dm_block_t b,
+               struct dm_btree_value_type *vt, int *inc);
+
+/*
+ * The spine must have at least one entry before calling this.
+ */
+struct dm_block *shadow_current(struct shadow_spine *s);
+
+/*
+ * The spine must have at least two entries before calling this.
+ */
+struct dm_block *shadow_parent(struct shadow_spine *s);
+
+int shadow_has_parent(struct shadow_spine *s);
+
+int shadow_root(struct shadow_spine *s);
+
+/*
+ * Some inlines.
+ */
+static inline __le64 *key_ptr(struct node *n, uint32_t index)
+{
+       return n->keys + index;
+}
+
+static inline void *value_base(struct node *n)
+{
+       return &n->keys[le32_to_cpu(n->header.max_entries)];
+}
+
+static inline void *value_ptr(struct node *n, uint32_t index, size_t value_size)
+{
+       return value_base(n) + (value_size * index);
+}
+
+/*
+ * Assumes the values are suitably-aligned and converts to core format.
+ */
+static inline uint64_t value64(struct node *n, uint32_t index)
+{
+       __le64 *values_le = value_base(n);
+
+       return le64_to_cpu(values_le[index]);
+}
+
+/*
+ * Searching for a key within a single node.
+ */
+int lower_bound(struct node *n, uint64_t key);
+
+extern struct dm_block_validator btree_node_validator;
+
+#endif /* DM_BTREE_INTERNAL_H */
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
new file mode 100644 (file)
index 0000000..cdd71d6
--- /dev/null
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-btree.h"
+#include "dm-btree-internal.h"
+#include "dm-transaction-manager.h"
+
+#include <linux/module.h>
+
+/*
+ * Removing an entry from a btree
+ * ==============================
+ *
+ * A very important constraint for our btree is that no node, except the
+ * root, may have fewer than a certain number of entries.
+ * (MIN_ENTRIES <= nr_entries <= MAX_ENTRIES).
+ *
+ * Ensuring this is complicated by the way we want to only ever hold the
+ * locks on 2 nodes concurrently, and only change nodes in a top to bottom
+ * fashion.
+ *
+ * Each node may have a left or right sibling.  When decending the spine,
+ * if a node contains only MIN_ENTRIES then we try and increase this to at
+ * least MIN_ENTRIES + 1.  We do this in the following ways:
+ *
+ * [A] No siblings => this can only happen if the node is the root, in which
+ *     case we copy the childs contents over the root.
+ *
+ * [B] No left sibling
+ *     ==> rebalance(node, right sibling)
+ *
+ * [C] No right sibling
+ *     ==> rebalance(left sibling, node)
+ *
+ * [D] Both siblings, total_entries(left, node, right) <= DEL_THRESHOLD
+ *     ==> delete node adding it's contents to left and right
+ *
+ * [E] Both siblings, total_entries(left, node, right) > DEL_THRESHOLD
+ *     ==> rebalance(left, node, right)
+ *
+ * After these operations it's possible that the our original node no
+ * longer contains the desired sub tree.  For this reason this rebalancing
+ * is performed on the children of the current node.  This also avoids
+ * having a special case for the root.
+ *
+ * Once this rebalancing has occurred we can then step into the child node
+ * for internal nodes.  Or delete the entry for leaf nodes.
+ */
+
+/*
+ * Some little utilities for moving node data around.
+ */
+static void node_shift(struct node *n, int shift)
+{
+       uint32_t nr_entries = le32_to_cpu(n->header.nr_entries);
+
+       if (shift < 0) {
+               shift = -shift;
+               memmove(key_ptr(n, 0),
+                       key_ptr(n, shift),
+                       (nr_entries - shift) * sizeof(__le64));
+               memmove(value_ptr(n, 0, sizeof(__le64)),
+                       value_ptr(n, shift, sizeof(__le64)),
+                       (nr_entries - shift) * sizeof(__le64));
+       } else {
+               memmove(key_ptr(n, shift),
+                       key_ptr(n, 0),
+                       nr_entries * sizeof(__le64));
+               memmove(value_ptr(n, shift, sizeof(__le64)),
+                       value_ptr(n, 0, sizeof(__le64)),
+                       nr_entries * sizeof(__le64));
+       }
+}
+
+static void node_copy(struct node *left, struct node *right, int shift)
+{
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+
+       if (shift < 0) {
+               shift = -shift;
+               memcpy(key_ptr(left, nr_left),
+                      key_ptr(right, 0),
+                      shift * sizeof(__le64));
+               memcpy(value_ptr(left, nr_left, sizeof(__le64)),
+                      value_ptr(right, 0, sizeof(__le64)),
+                      shift * sizeof(__le64));
+       } else {
+               memcpy(key_ptr(right, 0),
+                      key_ptr(left, nr_left - shift),
+                      shift * sizeof(__le64));
+               memcpy(value_ptr(right, 0, sizeof(__le64)),
+                      value_ptr(left, nr_left - shift, sizeof(__le64)),
+                      shift * sizeof(__le64));
+       }
+}
+
+/*
+ * Delete a specific entry from a leaf node.
+ */
+static void delete_at(struct node *n, unsigned index, size_t value_size)
+{
+       unsigned nr_entries = le32_to_cpu(n->header.nr_entries);
+       unsigned nr_to_copy = nr_entries - (index + 1);
+
+       if (nr_to_copy) {
+               memmove(key_ptr(n, index),
+                       key_ptr(n, index + 1),
+                       nr_to_copy * sizeof(__le64));
+
+               memmove(value_ptr(n, index, value_size),
+                       value_ptr(n, index + 1, value_size),
+                       nr_to_copy * value_size);
+       }
+
+       n->header.nr_entries = cpu_to_le32(nr_entries - 1);
+}
+
+static unsigned del_threshold(struct node *n)
+{
+       return le32_to_cpu(n->header.max_entries) / 3;
+}
+
+static unsigned merge_threshold(struct node *n)
+{
+       /*
+        * The extra one is because we know we're potentially going to
+        * delete an entry.
+        */
+       return 2 * (le32_to_cpu(n->header.max_entries) / 3) + 1;
+}
+
+struct child {
+       unsigned index;
+       struct dm_block *block;
+       struct node *n;
+};
+
+static struct dm_btree_value_type le64_type = {
+       .context = NULL,
+       .size = sizeof(__le64),
+       .inc = NULL,
+       .dec = NULL,
+       .equal = NULL
+};
+
+static int init_child(struct dm_btree_info *info, struct node *parent,
+                     unsigned index, struct child *result)
+{
+       int r, inc;
+       dm_block_t root;
+
+       result->index = index;
+       root = value64(parent, index);
+
+       r = dm_tm_shadow_block(info->tm, root, &btree_node_validator,
+                              &result->block, &inc);
+       if (r)
+               return r;
+
+       result->n = dm_block_data(result->block);
+
+       if (inc)
+               inc_children(info->tm, result->n, &le64_type);
+
+       return 0;
+}
+
+static int exit_child(struct dm_btree_info *info, struct child *c)
+{
+       return dm_tm_unlock(info->tm, c->block);
+}
+
+static void shift(struct node *left, struct node *right, int count)
+{
+       if (!count)
+               return;
+
+       if (count > 0) {
+               node_shift(right, count);
+               node_copy(left, right, count);
+       } else {
+               node_copy(left, right, count);
+               node_shift(right, count);
+       }
+
+       left->header.nr_entries =
+               cpu_to_le32(le32_to_cpu(left->header.nr_entries) - count);
+
+       right->header.nr_entries =
+               cpu_to_le32(le32_to_cpu(right->header.nr_entries) + count);
+}
+
+static void __rebalance2(struct dm_btree_info *info, struct node *parent,
+                        struct child *l, struct child *r)
+{
+       struct node *left = l->n;
+       struct node *right = r->n;
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+
+       if (nr_left + nr_right <= merge_threshold(left)) {
+               /*
+                * Merge
+                */
+               node_copy(left, right, -nr_right);
+               left->header.nr_entries = cpu_to_le32(nr_left + nr_right);
+
+               *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
+                       cpu_to_le64(dm_block_location(l->block));
+               delete_at(parent, r->index, sizeof(__le64));
+
+               /*
+                * We need to decrement the right block, but not it's
+                * children, since they're still referenced by left.
+                */
+               dm_tm_dec(info->tm, dm_block_location(r->block));
+       } else {
+               /*
+                * Rebalance.
+                */
+               unsigned target_left = (nr_left + nr_right) / 2;
+
+               shift(left, right, nr_left - target_left);
+               *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
+                       cpu_to_le64(dm_block_location(l->block));
+               *((__le64 *) value_ptr(parent, r->index, sizeof(__le64))) =
+                       cpu_to_le64(dm_block_location(r->block));
+               *key_ptr(parent, r->index) = right->keys[0];
+       }
+}
+
+static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
+                     unsigned left_index)
+{
+       int r;
+       struct node *parent;
+       struct child left, right;
+
+       parent = dm_block_data(shadow_current(s));
+
+       r = init_child(info, parent, left_index, &left);
+       if (r)
+               return r;
+
+       r = init_child(info, parent, left_index + 1, &right);
+       if (r) {
+               exit_child(info, &left);
+               return r;
+       }
+
+       __rebalance2(info, parent, &left, &right);
+
+       r = exit_child(info, &left);
+       if (r) {
+               exit_child(info, &right);
+               return r;
+       }
+
+       r = exit_child(info, &right);
+       if (r)
+               return r;
+
+       return 0;
+}
+
+static void __rebalance3(struct dm_btree_info *info, struct node *parent,
+                        struct child *l, struct child *c, struct child *r)
+{
+       struct node *left = l->n;
+       struct node *center = c->n;
+       struct node *right = r->n;
+
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t nr_center = le32_to_cpu(center->header.nr_entries);
+       uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+
+       unsigned target;
+
+       if (((nr_left + nr_center + nr_right) / 2) < merge_threshold(center)) {
+               /*
+                * Delete center node:
+                *
+                * We dump as many entries from center as possible into
+                * left, then the rest in right, then rebalance2.  This
+                * wastes some cpu, but I want something simple atm.
+                */
+               unsigned shift = min(max_entries - nr_left, nr_center);
+
+               node_copy(left, center, -shift);
+               left->header.nr_entries = cpu_to_le32(nr_left + shift);
+
+               if (shift != nr_center) {
+                       shift = nr_center - shift;
+                       node_shift(right, shift);
+                       node_copy(center, right, shift);
+                       right->header.nr_entries = cpu_to_le32(nr_right + shift);
+               }
+
+               *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
+                       cpu_to_le64(dm_block_location(l->block));
+               *((__le64 *) value_ptr(parent, r->index, sizeof(__le64))) =
+                       cpu_to_le64(dm_block_location(r->block));
+               *key_ptr(parent, r->index) = right->keys[0];
+
+               delete_at(parent, c->index, sizeof(__le64));
+               r->index--;
+
+               dm_tm_dec(info->tm, dm_block_location(c->block));
+               __rebalance2(info, parent, l, r);
+
+               return;
+       }
+
+       /*
+        * Rebalance
+        */
+       target = (nr_left + nr_center + nr_right) / 3;
+       BUG_ON(target == nr_center);
+
+       /*
+        * Adjust the left node
+        */
+       shift(left, center, nr_left - target);
+
+       /*
+        * Adjust the right node
+        */
+       shift(center, right, target - nr_right);
+
+       *((__le64 *) value_ptr(parent, l->index, sizeof(__le64))) =
+               cpu_to_le64(dm_block_location(l->block));
+       *((__le64 *) value_ptr(parent, c->index, sizeof(__le64))) =
+               cpu_to_le64(dm_block_location(c->block));
+       *((__le64 *) value_ptr(parent, r->index, sizeof(__le64))) =
+               cpu_to_le64(dm_block_location(r->block));
+
+       *key_ptr(parent, c->index) = center->keys[0];
+       *key_ptr(parent, r->index) = right->keys[0];
+}
+
+static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
+                     unsigned left_index)
+{
+       int r;
+       struct node *parent = dm_block_data(shadow_current(s));
+       struct child left, center, right;
+
+       /*
+        * FIXME: fill out an array?
+        */
+       r = init_child(info, parent, left_index, &left);
+       if (r)
+               return r;
+
+       r = init_child(info, parent, left_index + 1, &center);
+       if (r) {
+               exit_child(info, &left);
+               return r;
+       }
+
+       r = init_child(info, parent, left_index + 2, &right);
+       if (r) {
+               exit_child(info, &left);
+               exit_child(info, &center);
+               return r;
+       }
+
+       __rebalance3(info, parent, &left, &center, &right);
+
+       r = exit_child(info, &left);
+       if (r) {
+               exit_child(info, &center);
+               exit_child(info, &right);
+               return r;
+       }
+
+       r = exit_child(info, &center);
+       if (r) {
+               exit_child(info, &right);
+               return r;
+       }
+
+       r = exit_child(info, &right);
+       if (r)
+               return r;
+
+       return 0;
+}
+
+static int get_nr_entries(struct dm_transaction_manager *tm,
+                         dm_block_t b, uint32_t *result)
+{
+       int r;
+       struct dm_block *block;
+       struct node *n;
+
+       r = dm_tm_read_lock(tm, b, &btree_node_validator, &block);
+       if (r)
+               return r;
+
+       n = dm_block_data(block);
+       *result = le32_to_cpu(n->header.nr_entries);
+
+       return dm_tm_unlock(tm, block);
+}
+
+static int rebalance_children(struct shadow_spine *s,
+                             struct dm_btree_info *info, uint64_t key)
+{
+       int i, r, has_left_sibling, has_right_sibling;
+       uint32_t child_entries;
+       struct node *n;
+
+       n = dm_block_data(shadow_current(s));
+
+       if (le32_to_cpu(n->header.nr_entries) == 1) {
+               struct dm_block *child;
+               dm_block_t b = value64(n, 0);
+
+               r = dm_tm_read_lock(info->tm, b, &btree_node_validator, &child);
+               if (r)
+                       return r;
+
+               memcpy(n, dm_block_data(child),
+                      dm_bm_block_size(dm_tm_get_bm(info->tm)));
+               r = dm_tm_unlock(info->tm, child);
+               dm_tm_dec(info->tm, dm_block_location(child));
+
+               return r;
+       }
+
+       i = lower_bound(n, key);
+       if (i < 0)
+               return -ENODATA;
+
+       r = get_nr_entries(info->tm, value64(n, i), &child_entries);
+       if (r)
+               return r;
+
+       if (child_entries > del_threshold(n))
+               return 0;
+
+       has_left_sibling = i > 0 ? 1 : 0;
+       has_right_sibling =
+               (i >= (le32_to_cpu(n->header.nr_entries) - 1)) ? 0 : 1;
+
+       if (!has_left_sibling)
+               r = rebalance2(s, info, i);
+
+       else if (!has_right_sibling)
+               r = rebalance2(s, info, i - 1);
+
+       else
+               r = rebalance3(s, info, i - 1);
+
+       return r;
+}
+
+static int do_leaf(struct node *n, uint64_t key, unsigned *index)
+{
+       int i = lower_bound(n, key);
+
+       if ((i < 0) ||
+           (i >= le32_to_cpu(n->header.nr_entries)) ||
+           (le64_to_cpu(n->keys[i]) != key))
+               return -ENODATA;
+
+       *index = i;
+
+       return 0;
+}
+
+/*
+ * Prepares for removal from one level of the hierarchy.  The caller must
+ * actually call delete_at() to remove the entry at index.
+ */
+static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
+                     struct dm_btree_value_type *vt, dm_block_t root,
+                     uint64_t key, unsigned *index)
+{
+       int i = *index, inc, r;
+       struct node *n;
+
+       for (;;) {
+               r = shadow_step(s, root, vt, &inc);
+               if (r < 0)
+                       break;
+
+               /*
+                * We have to patch up the parent node, ugly, but I don't
+                * see a way to do this automatically as part of the spine
+                * op.
+                */
+               if (shadow_has_parent(s)) {
+                       __le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
+                       memcpy(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(uint64_t)),
+                              &location, sizeof(__le64));
+               }
+
+               n = dm_block_data(shadow_current(s));
+               if (inc)
+                       inc_children(info->tm, n, vt);
+
+               if (le32_to_cpu(n->header.flags) & LEAF_NODE)
+                       return do_leaf(n, key, index);
+
+               r = rebalance_children(s, info, key);
+               if (r)
+                       break;
+
+               n = dm_block_data(shadow_current(s));
+               if (le32_to_cpu(n->header.flags) & LEAF_NODE)
+                       return do_leaf(n, key, index);
+
+               i = lower_bound(n, key);
+
+               /*
+                * We know the key is present, or else
+                * rebalance_children would have returned
+                * -ENODATA
+                */
+               root = value64(n, i);
+       }
+
+       return r;
+}
+
+int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
+                   uint64_t *keys, dm_block_t *new_root)
+{
+       unsigned level, last_level = info->levels - 1;
+       int index = 0, r = 0;
+       struct shadow_spine spine;
+       struct node *n;
+
+       init_shadow_spine(&spine, info);
+       for (level = 0; level < info->levels; level++) {
+               r = remove_raw(&spine, info,
+                              (level == last_level ?
+                               &info->value_type : &le64_type),
+                              root, keys[level], (unsigned *)&index);
+               if (r < 0)
+                       break;
+
+               n = dm_block_data(shadow_current(&spine));
+               if (level != last_level) {
+                       root = value64(n, index);
+                       continue;
+               }
+
+               BUG_ON(index < 0 || index >= le32_to_cpu(n->header.nr_entries));
+
+               if (info->value_type.dec)
+                       info->value_type.dec(info->value_type.context,
+                                            value_ptr(n, index, info->value_type.size));
+
+               delete_at(n, index, info->value_type.size);
+
+               r = 0;
+               *new_root = shadow_root(&spine);
+       }
+
+       exit_shadow_spine(&spine);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_btree_remove);
diff --git a/drivers/md/persistent-data/dm-btree-spine.c b/drivers/md/persistent-data/dm-btree-spine.c
new file mode 100644 (file)
index 0000000..15d2fb8
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-btree-internal.h"
+#include "dm-transaction-manager.h"
+
+#include <linux/device-mapper.h>
+
+#define DM_MSG_PREFIX "btree spine"
+
+/*----------------------------------------------------------------*/
+
+static void node_prepare_for_write(struct dm_block_validator *v,
+                                  struct dm_block *b,
+                                  size_t block_size)
+{
+       struct node *n = dm_block_data(b);
+       struct node_header *h = &n->header;
+
+       h->blocknr = cpu_to_le64(dm_block_location(b));
+       h->csum = cpu_to_le32(dm_block_csum_data(&h->flags, block_size - sizeof(__le32)));
+}
+
+static int node_check(struct dm_block_validator *v,
+                     struct dm_block *b,
+                     size_t block_size)
+{
+       struct node *n = dm_block_data(b);
+       struct node_header *h = &n->header;
+       size_t value_size;
+       __le32 csum_disk;
+
+       if (dm_block_location(b) != le64_to_cpu(h->blocknr)) {
+               DMERR("node_check failed blocknr %llu wanted %llu",
+                     le64_to_cpu(h->blocknr), dm_block_location(b));
+               return -ENOTBLK;
+       }
+
+       csum_disk = cpu_to_le32(dm_block_csum_data(&h->flags, block_size - sizeof(__le32)));
+       if (csum_disk != h->csum) {
+               DMERR("node_check failed csum %u wanted %u",
+                     le32_to_cpu(csum_disk), le32_to_cpu(h->csum));
+               return -EILSEQ;
+       }
+
+       value_size = le32_to_cpu(h->value_size);
+
+       if (sizeof(struct node_header) +
+           (sizeof(__le64) + value_size) * le32_to_cpu(h->max_entries) > block_size) {
+               DMERR("node_check failed: max_entries too large");
+               return -EILSEQ;
+       }
+
+       if (le32_to_cpu(h->nr_entries) > le32_to_cpu(h->max_entries)) {
+               DMERR("node_check failed, too many entries");
+               return -EILSEQ;
+       }
+
+       return 0;
+}
+
+struct dm_block_validator btree_node_validator = {
+       .name = "btree_node",
+       .prepare_for_write = node_prepare_for_write,
+       .check = node_check
+};
+
+/*----------------------------------------------------------------*/
+
+static int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
+                struct dm_block **result)
+{
+       return dm_tm_read_lock(info->tm, b, &btree_node_validator, result);
+}
+
+static int bn_shadow(struct dm_btree_info *info, dm_block_t orig,
+             struct dm_btree_value_type *vt,
+             struct dm_block **result, int *inc)
+{
+       int r;
+
+       r = dm_tm_shadow_block(info->tm, orig, &btree_node_validator,
+                              result, inc);
+       if (!r && *inc)
+               inc_children(info->tm, dm_block_data(*result), vt);
+
+       return r;
+}
+
+int new_block(struct dm_btree_info *info, struct dm_block **result)
+{
+       return dm_tm_new_block(info->tm, &btree_node_validator, result);
+}
+
+int unlock_block(struct dm_btree_info *info, struct dm_block *b)
+{
+       return dm_tm_unlock(info->tm, b);
+}
+
+/*----------------------------------------------------------------*/
+
+void init_ro_spine(struct ro_spine *s, struct dm_btree_info *info)
+{
+       s->info = info;
+       s->count = 0;
+       s->nodes[0] = NULL;
+       s->nodes[1] = NULL;
+}
+
+int exit_ro_spine(struct ro_spine *s)
+{
+       int r = 0, i;
+
+       for (i = 0; i < s->count; i++) {
+               int r2 = unlock_block(s->info, s->nodes[i]);
+               if (r2 < 0)
+                       r = r2;
+       }
+
+       return r;
+}
+
+int ro_step(struct ro_spine *s, dm_block_t new_child)
+{
+       int r;
+
+       if (s->count == 2) {
+               r = unlock_block(s->info, s->nodes[0]);
+               if (r < 0)
+                       return r;
+               s->nodes[0] = s->nodes[1];
+               s->count--;
+       }
+
+       r = bn_read_lock(s->info, new_child, s->nodes + s->count);
+       if (!r)
+               s->count++;
+
+       return r;
+}
+
+struct node *ro_node(struct ro_spine *s)
+{
+       struct dm_block *block;
+
+       BUG_ON(!s->count);
+       block = s->nodes[s->count - 1];
+
+       return dm_block_data(block);
+}
+
+/*----------------------------------------------------------------*/
+
+void init_shadow_spine(struct shadow_spine *s, struct dm_btree_info *info)
+{
+       s->info = info;
+       s->count = 0;
+}
+
+int exit_shadow_spine(struct shadow_spine *s)
+{
+       int r = 0, i;
+
+       for (i = 0; i < s->count; i++) {
+               int r2 = unlock_block(s->info, s->nodes[i]);
+               if (r2 < 0)
+                       r = r2;
+       }
+
+       return r;
+}
+
+int shadow_step(struct shadow_spine *s, dm_block_t b,
+               struct dm_btree_value_type *vt, int *inc)
+{
+       int r;
+
+       if (s->count == 2) {
+               r = unlock_block(s->info, s->nodes[0]);
+               if (r < 0)
+                       return r;
+               s->nodes[0] = s->nodes[1];
+               s->count--;
+       }
+
+       r = bn_shadow(s->info, b, vt, s->nodes + s->count, inc);
+       if (!r) {
+               if (!s->count)
+                       s->root = dm_block_location(s->nodes[0]);
+
+               s->count++;
+       }
+
+       return r;
+}
+
+struct dm_block *shadow_current(struct shadow_spine *s)
+{
+       BUG_ON(!s->count);
+
+       return s->nodes[s->count - 1];
+}
+
+struct dm_block *shadow_parent(struct shadow_spine *s)
+{
+       BUG_ON(s->count != 2);
+
+       return s->count == 2 ? s->nodes[0] : NULL;
+}
+
+int shadow_has_parent(struct shadow_spine *s)
+{
+       return s->count >= 2;
+}
+
+int shadow_root(struct shadow_spine *s)
+{
+       return s->root;
+}
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
new file mode 100644 (file)
index 0000000..ca16d5b
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-btree-internal.h"
+#include "dm-space-map.h"
+#include "dm-transaction-manager.h"
+
+#include <linux/module.h>
+#include <linux/device-mapper.h>
+
+#define DM_MSG_PREFIX "btree"
+
+/*----------------------------------------------------------------
+ * Array manipulation
+ *--------------------------------------------------------------*/
+static void memcpy_disk(void *dest, const void *src, size_t len)
+       __dm_written_to_disk(src)
+{
+       memcpy(dest, src, len);
+       __dm_unbless_for_disk(src);
+}
+
+static void array_insert(void *base, size_t elt_size, unsigned nr_elts,
+                        unsigned index, void *elt)
+       __dm_written_to_disk(elt)
+{
+       if (index < nr_elts)
+               memmove(base + (elt_size * (index + 1)),
+                       base + (elt_size * index),
+                       (nr_elts - index) * elt_size);
+
+       memcpy_disk(base + (elt_size * index), elt, elt_size);
+}
+
+/*----------------------------------------------------------------*/
+
+/* makes the assumption that no two keys are the same. */
+static int bsearch(struct node *n, uint64_t key, int want_hi)
+{
+       int lo = -1, hi = le32_to_cpu(n->header.nr_entries);
+
+       while (hi - lo > 1) {
+               int mid = lo + ((hi - lo) / 2);
+               uint64_t mid_key = le64_to_cpu(n->keys[mid]);
+
+               if (mid_key == key)
+                       return mid;
+
+               if (mid_key < key)
+                       lo = mid;
+               else
+                       hi = mid;
+       }
+
+       return want_hi ? hi : lo;
+}
+
+int lower_bound(struct node *n, uint64_t key)
+{
+       return bsearch(n, key, 0);
+}
+
+void inc_children(struct dm_transaction_manager *tm, struct node *n,
+                 struct dm_btree_value_type *vt)
+{
+       unsigned i;
+       uint32_t nr_entries = le32_to_cpu(n->header.nr_entries);
+
+       if (le32_to_cpu(n->header.flags) & INTERNAL_NODE)
+               for (i = 0; i < nr_entries; i++)
+                       dm_tm_inc(tm, value64(n, i));
+       else if (vt->inc)
+               for (i = 0; i < nr_entries; i++)
+                       vt->inc(vt->context,
+                               value_ptr(n, i, vt->size));
+}
+
+static int insert_at(size_t value_size, struct node *node, unsigned index,
+                     uint64_t key, void *value)
+                     __dm_written_to_disk(value)
+{
+       uint32_t nr_entries = le32_to_cpu(node->header.nr_entries);
+       __le64 key_le = cpu_to_le64(key);
+
+       if (index > nr_entries ||
+           index >= le32_to_cpu(node->header.max_entries)) {
+               DMERR("too many entries in btree node for insert");
+               __dm_unbless_for_disk(value);
+               return -ENOMEM;
+       }
+
+       __dm_bless_for_disk(&key_le);
+
+       array_insert(node->keys, sizeof(*node->keys), nr_entries, index, &key_le);
+       array_insert(value_base(node), value_size, nr_entries, index, value);
+       node->header.nr_entries = cpu_to_le32(nr_entries + 1);
+
+       return 0;
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * We want 3n entries (for some n).  This works more nicely for repeated
+ * insert remove loops than (2n + 1).
+ */
+static uint32_t calc_max_entries(size_t value_size, size_t block_size)
+{
+       uint32_t total, n;
+       size_t elt_size = sizeof(uint64_t) + value_size; /* key + value */
+
+       block_size -= sizeof(struct node_header);
+       total = block_size / elt_size;
+       n = total / 3;          /* rounds down */
+
+       return 3 * n;
+}
+
+int dm_btree_create(struct dm_btree_info *info, dm_block_t *root)
+{
+       int r;
+       struct dm_block *b;
+       struct node *n;
+       size_t block_size;
+       uint32_t max_entries;
+
+       r = new_block(info, &b);
+       if (r < 0)
+               return r;
+
+       block_size = dm_bm_block_size(dm_tm_get_bm(info->tm));
+       max_entries = calc_max_entries(info->value_type.size, block_size);
+
+       n = dm_block_data(b);
+       memset(n, 0, block_size);
+       n->header.flags = cpu_to_le32(LEAF_NODE);
+       n->header.nr_entries = cpu_to_le32(0);
+       n->header.max_entries = cpu_to_le32(max_entries);
+       n->header.value_size = cpu_to_le32(info->value_type.size);
+
+       *root = dm_block_location(b);
+
+       return unlock_block(info, b);
+}
+EXPORT_SYMBOL_GPL(dm_btree_create);
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Deletion uses a recursive algorithm, since we have limited stack space
+ * we explicitly manage our own stack on the heap.
+ */
+#define MAX_SPINE_DEPTH 64
+struct frame {
+       struct dm_block *b;
+       struct node *n;
+       unsigned level;
+       unsigned nr_children;
+       unsigned current_child;
+};
+
+struct del_stack {
+       struct dm_transaction_manager *tm;
+       int top;
+       struct frame spine[MAX_SPINE_DEPTH];
+};
+
+static int top_frame(struct del_stack *s, struct frame **f)
+{
+       if (s->top < 0) {
+               DMERR("btree deletion stack empty");
+               return -EINVAL;
+       }
+
+       *f = s->spine + s->top;
+
+       return 0;
+}
+
+static int unprocessed_frames(struct del_stack *s)
+{
+       return s->top >= 0;
+}
+
+static int push_frame(struct del_stack *s, dm_block_t b, unsigned level)
+{
+       int r;
+       uint32_t ref_count;
+
+       if (s->top >= MAX_SPINE_DEPTH - 1) {
+               DMERR("btree deletion stack out of memory");
+               return -ENOMEM;
+       }
+
+       r = dm_tm_ref(s->tm, b, &ref_count);
+       if (r)
+               return r;
+
+       if (ref_count > 1)
+               /*
+                * This is a shared node, so we can just decrement its
+                * reference counter and leave the children.
+                */
+               dm_tm_dec(s->tm, b);
+
+       else {
+               struct frame *f = s->spine + ++s->top;
+
+               r = dm_tm_read_lock(s->tm, b, &btree_node_validator, &f->b);
+               if (r) {
+                       s->top--;
+                       return r;
+               }
+
+               f->n = dm_block_data(f->b);
+               f->level = level;
+               f->nr_children = le32_to_cpu(f->n->header.nr_entries);
+               f->current_child = 0;
+       }
+
+       return 0;
+}
+
+static void pop_frame(struct del_stack *s)
+{
+       struct frame *f = s->spine + s->top--;
+
+       dm_tm_dec(s->tm, dm_block_location(f->b));
+       dm_tm_unlock(s->tm, f->b);
+}
+
+int dm_btree_destroy(struct dm_btree_info *info, dm_block_t root)
+{
+       int r;
+       struct del_stack *s;
+
+       s = kmalloc(sizeof(*s), GFP_KERNEL);
+       if (!s)
+               return -ENOMEM;
+
+       s->tm = info->tm;
+       s->top = -1;
+
+       r = push_frame(s, root, 1);
+       if (r)
+               goto out;
+
+       while (unprocessed_frames(s)) {
+               uint32_t flags;
+               struct frame *f;
+               dm_block_t b;
+
+               r = top_frame(s, &f);
+               if (r)
+                       goto out;
+
+               if (f->current_child >= f->nr_children) {
+                       pop_frame(s);
+                       continue;
+               }
+
+               flags = le32_to_cpu(f->n->header.flags);
+               if (flags & INTERNAL_NODE) {
+                       b = value64(f->n, f->current_child);
+                       f->current_child++;
+                       r = push_frame(s, b, f->level);
+                       if (r)
+                               goto out;
+
+               } else if (f->level != (info->levels - 1)) {
+                       b = value64(f->n, f->current_child);
+                       f->current_child++;
+                       r = push_frame(s, b, f->level + 1);
+                       if (r)
+                               goto out;
+
+               } else {
+                       if (info->value_type.dec) {
+                               unsigned i;
+
+                               for (i = 0; i < f->nr_children; i++)
+                                       info->value_type.dec(info->value_type.context,
+                                                            value_ptr(f->n, i, info->value_type.size));
+                       }
+                       f->current_child = f->nr_children;
+               }
+       }
+
+out:
+       kfree(s);
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_btree_destroy);
+
+// FIXME Implement or remove this fn before final submission.
+int dm_btree_delete_gt(struct dm_btree_info *info, dm_block_t root, uint64_t *key,
+                   dm_block_t *new_root)
+{
+       /* FIXME: implement */
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dm_btree_delete_gt);
+
+/*----------------------------------------------------------------*/
+
+static int btree_lookup_raw(struct ro_spine *s, dm_block_t block, uint64_t key,
+                           int (*search_fn)(struct node *, uint64_t),
+                           uint64_t *result_key, void *v, size_t value_size)
+{
+       int i, r;
+       uint32_t flags, nr_entries;
+
+       do {
+               r = ro_step(s, block);
+               if (r < 0)
+                       return r;
+
+               i = search_fn(ro_node(s), key);
+
+               flags = le32_to_cpu(ro_node(s)->header.flags);
+               nr_entries = le32_to_cpu(ro_node(s)->header.nr_entries);
+               if (i < 0 || i >= nr_entries)
+                       return -ENODATA;
+
+               if (flags & INTERNAL_NODE)
+                       block = value64(ro_node(s), i);
+
+       } while (!(flags & LEAF_NODE));
+
+       *result_key = le64_to_cpu(ro_node(s)->keys[i]);
+       memcpy(v, value_ptr(ro_node(s), i, value_size), value_size);
+
+       return 0;
+}
+
+int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
+                   uint64_t *keys, void *value_le)
+{
+       unsigned level, last_level = info->levels - 1;
+       int r = -ENODATA;
+       uint64_t rkey;
+       __le64 internal_value_le;
+       struct ro_spine spine;
+
+       init_ro_spine(&spine, info);
+       for (level = 0; level < info->levels; level++) {
+               size_t size;
+               void *value_p;
+
+               if (level == last_level) {
+                       value_p = value_le;
+                       size = info->value_type.size;
+
+               } else {
+                       value_p = &internal_value_le;
+                       size = sizeof(uint64_t);
+               }
+
+               r = btree_lookup_raw(&spine, root, keys[level],
+                                    lower_bound, &rkey,
+                                    value_p, size);
+
+               if (!r) {
+                       if (rkey != keys[level]) {
+                               exit_ro_spine(&spine);
+                               return -ENODATA;
+                       }
+               } else {
+                       exit_ro_spine(&spine);
+                       return r;
+               }
+
+               root = le64_to_cpu(internal_value_le);
+       }
+       exit_ro_spine(&spine);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_btree_lookup);
+
+/*
+ * Splits a node by creating a sibling node and shifting half the nodes
+ * contents across.  Assumes there is a parent node, and it has room for
+ * another child.
+ *
+ * Before:
+ *       +--------+
+ *       | Parent |
+ *       +--------+
+ *          |
+ *          v
+ *     +----------+
+ *     | A ++++++ |
+ *     +----------+
+ *
+ *
+ * After:
+ *             +--------+
+ *             | Parent |
+ *             +--------+
+ *               |     |
+ *               v     +------+
+ *         +---------+        |
+ *         | A* +++  |        v
+ *         +---------+   +-------+
+ *                       | B +++ |
+ *                       +-------+
+ *
+ * Where A* is a shadow of A.
+ */
+static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
+                              unsigned parent_index, uint64_t key)
+{
+       int r;
+       size_t size;
+       unsigned nr_left, nr_right;
+       struct dm_block *left, *right, *parent;
+       struct node *ln, *rn, *pn;
+       __le64 location;
+
+       left = shadow_current(s);
+
+       r = new_block(s->info, &right);
+       if (r < 0)
+               return r;
+
+       ln = dm_block_data(left);
+       rn = dm_block_data(right);
+
+       nr_left = le32_to_cpu(ln->header.nr_entries) / 2;
+       nr_right = le32_to_cpu(ln->header.nr_entries) - nr_left;
+
+       ln->header.nr_entries = cpu_to_le32(nr_left);
+
+       rn->header.flags = ln->header.flags;
+       rn->header.nr_entries = cpu_to_le32(nr_right);
+       rn->header.max_entries = ln->header.max_entries;
+       rn->header.value_size = ln->header.value_size;
+       memcpy(rn->keys, ln->keys + nr_left, nr_right * sizeof(rn->keys[0]));
+
+       size = le32_to_cpu(ln->header.flags) & INTERNAL_NODE ?
+               sizeof(uint64_t) : s->info->value_type.size;
+       memcpy(value_ptr(rn, 0, size), value_ptr(ln, nr_left, size),
+              size * nr_right);
+
+       /*
+        * Patch up the parent
+        */
+       parent = shadow_parent(s);
+
+       pn = dm_block_data(parent);
+       location = cpu_to_le64(dm_block_location(left));
+       __dm_bless_for_disk(&location);
+       memcpy_disk(value_ptr(pn, parent_index, sizeof(__le64)),
+                   &location, sizeof(__le64));
+
+       location = cpu_to_le64(dm_block_location(right));
+       __dm_bless_for_disk(&location);
+
+       r = insert_at(sizeof(__le64), pn, parent_index + 1,
+                     le64_to_cpu(rn->keys[0]), &location);
+       if (r)
+               return r;
+
+       if (key < le64_to_cpu(rn->keys[0])) {
+               unlock_block(s->info, right);
+               s->nodes[1] = left;
+       } else {
+               unlock_block(s->info, left);
+               s->nodes[1] = right;
+       }
+
+       return 0;
+}
+
+/*
+ * Splits a node by creating two new children beneath the given node.
+ *
+ * Before:
+ *       +----------+
+ *       | A ++++++ |
+ *       +----------+
+ *
+ *
+ * After:
+ *     +------------+
+ *     | A (shadow) |
+ *     +------------+
+ *         |   |
+ *   +------+  +----+
+ *   |              |
+ *   v              v
+ * +-------+    +-------+
+ * | B +++ |    | C +++ |
+ * +-------+    +-------+
+ */
+static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
+{
+       int r;
+       size_t size;
+       unsigned nr_left, nr_right;
+       struct dm_block *left, *right, *new_parent;
+       struct node *pn, *ln, *rn;
+       __le64 val;
+
+       new_parent = shadow_current(s);
+
+       r = new_block(s->info, &left);
+       if (r < 0)
+               return r;
+
+       r = new_block(s->info, &right);
+       if (r < 0) {
+               /* FIXME: put left */
+               return r;
+       }
+
+       pn = dm_block_data(new_parent);
+       ln = dm_block_data(left);
+       rn = dm_block_data(right);
+
+       nr_left = le32_to_cpu(pn->header.nr_entries) / 2;
+       nr_right = le32_to_cpu(pn->header.nr_entries) - nr_left;
+
+       ln->header.flags = pn->header.flags;
+       ln->header.nr_entries = cpu_to_le32(nr_left);
+       ln->header.max_entries = pn->header.max_entries;
+       ln->header.value_size = pn->header.value_size;
+
+       rn->header.flags = pn->header.flags;
+       rn->header.nr_entries = cpu_to_le32(nr_right);
+       rn->header.max_entries = pn->header.max_entries;
+       rn->header.value_size = pn->header.value_size;
+
+       memcpy(ln->keys, pn->keys, nr_left * sizeof(pn->keys[0]));
+       memcpy(rn->keys, pn->keys + nr_left, nr_right * sizeof(pn->keys[0]));
+
+       size = le32_to_cpu(pn->header.flags) & INTERNAL_NODE ?
+               sizeof(__le64) : s->info->value_type.size;
+       memcpy(value_ptr(ln, 0, size), value_ptr(pn, 0, size), nr_left * size);
+       memcpy(value_ptr(rn, 0, size), value_ptr(pn, nr_left, size),
+              nr_right * size);
+
+       /* new_parent should just point to l and r now */
+       pn->header.flags = cpu_to_le32(INTERNAL_NODE);
+       pn->header.nr_entries = cpu_to_le32(2);
+       pn->header.max_entries = cpu_to_le32(
+               calc_max_entries(sizeof(__le64),
+                                dm_bm_block_size(
+                                        dm_tm_get_bm(s->info->tm))));
+       pn->header.value_size = cpu_to_le32(sizeof(__le64));
+
+       val = cpu_to_le64(dm_block_location(left));
+       __dm_bless_for_disk(&val);
+       pn->keys[0] = ln->keys[0];
+       memcpy_disk(value_ptr(pn, 0, sizeof(__le64)), &val, sizeof(__le64));
+
+       val = cpu_to_le64(dm_block_location(right));
+       __dm_bless_for_disk(&val);
+       pn->keys[1] = rn->keys[0];
+       memcpy_disk(value_ptr(pn, 1, sizeof(__le64)), &val, sizeof(__le64));
+
+       /*
+        * rejig the spine.  This is ugly, since it knows too
+        * much about the spine
+        */
+       if (s->nodes[0] != new_parent) {
+               unlock_block(s->info, s->nodes[0]);
+               s->nodes[0] = new_parent;
+       }
+       if (key < le64_to_cpu(rn->keys[0])) {
+               unlock_block(s->info, right);
+               s->nodes[1] = left;
+       } else {
+               unlock_block(s->info, left);
+               s->nodes[1] = right;
+       }
+       s->count = 2;
+
+       return 0;
+}
+
+static int btree_insert_raw(struct shadow_spine *s, dm_block_t root,
+                           struct dm_btree_value_type *vt,
+                           uint64_t key, unsigned *index)
+{
+       int r, i = *index, inc, top = 1;
+       struct node *node;
+
+       for (;;) {
+               r = shadow_step(s, root, vt, &inc);
+               if (r < 0)
+                       return r;
+
+               node = dm_block_data(shadow_current(s));
+               if (inc)
+                       inc_children(s->info->tm, node, vt);
+
+               /*
+                * We have to patch up the parent node, ugly, but I don't
+                * see a way to do this automatically as part of the spine
+                * op.
+                */
+               if (shadow_has_parent(s) && i >= 0) { /* FIXME: second clause unness. */
+                       __le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
+
+                       __dm_bless_for_disk(&location);
+                       memcpy_disk(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(uint64_t)),
+                                   &location, sizeof(__le64));
+               }
+
+               node = dm_block_data(shadow_current(s));
+
+               if (node->header.nr_entries == node->header.max_entries) {
+                       if (top)
+                               r = btree_split_beneath(s, key);
+                       else
+                               r = btree_split_sibling(s, root, i, key);
+
+                       if (r < 0)
+                               return r;
+               }
+
+               node = dm_block_data(shadow_current(s));
+
+               i = lower_bound(node, key);
+
+               if (le32_to_cpu(node->header.flags) & LEAF_NODE)
+                       break;
+
+               if (i < 0) {
+                       /* change the bounds on the lowest key */
+                       node->keys[0] = cpu_to_le64(key);
+                       i = 0;
+               }
+
+               root = value64(node, i);
+               top = 0;
+       }
+
+       if (i < 0 || le64_to_cpu(node->keys[i]) != key)
+               i++;
+
+       /* we're about to overwrite this value, so undo the increment for it */
+       /* FIXME: shame that inc information is leaking outside the spine.
+        * Plus inc is just plain wrong in the event of a split */
+       if (le64_to_cpu(node->keys[i]) == key && inc)
+               if (vt->dec)
+                       vt->dec(vt->context, value_ptr(node, i, vt->size));
+
+       *index = i;
+       return 0;
+}
+
+static int insert(struct dm_btree_info *info, dm_block_t root,
+                 uint64_t *keys, void *value, dm_block_t *new_root,
+                 int *inserted)
+                 __dm_written_to_disk(value)
+{
+       int r, need_insert;
+       unsigned level, index = -1, last_level = info->levels - 1;
+       dm_block_t block = root;
+       struct shadow_spine spine;
+       struct node *n;
+       struct dm_btree_value_type le64_type;
+
+       le64_type.context = NULL;
+       le64_type.size = sizeof(__le64);
+       le64_type.inc = NULL;
+       le64_type.dec = NULL;
+       le64_type.equal = NULL;
+
+       init_shadow_spine(&spine, info);
+
+       for (level = 0; level < (info->levels - 1); level++) {
+               r = btree_insert_raw(&spine, block, &le64_type, keys[level], &index);
+               if (r < 0)
+                       goto bad;
+
+               n = dm_block_data(shadow_current(&spine));
+               need_insert = ((index >= le32_to_cpu(n->header.nr_entries)) ||
+                              (le64_to_cpu(n->keys[index]) != keys[level]));
+
+               if (need_insert) {
+                       dm_block_t new_tree;
+                       __le64 new_le;
+
+                       r = dm_btree_create(info, &new_tree);
+                       if (r < 0)
+                               goto bad;
+
+                       new_le = cpu_to_le64(new_tree);
+                       __dm_bless_for_disk(&new_le);
+
+                       r = insert_at(sizeof(uint64_t), n, index,
+                                     keys[level], &new_le);
+                       if (r)
+                               goto bad;
+               }
+
+               if (level < last_level)
+                       block = value64(n, index);
+       }
+
+       r = btree_insert_raw(&spine, block, &info->value_type,
+                            keys[level], &index);
+       if (r < 0)
+               goto bad;
+
+       n = dm_block_data(shadow_current(&spine));
+       need_insert = ((index >= le32_to_cpu(n->header.nr_entries)) ||
+                      (le64_to_cpu(n->keys[index]) != keys[level]));
+
+       if (need_insert) {
+               if (inserted)
+                       *inserted = 1;
+
+               r = insert_at(info->value_type.size, n, index,
+                             keys[level], value);
+               if (r)
+                       goto bad_unblessed;
+       } else {
+               if (inserted)
+                       *inserted = 0;
+
+               if (info->value_type.dec &&
+                   (!info->value_type.equal ||
+                    !info->value_type.equal(
+                            info->value_type.context,
+                            value_ptr(n, index, info->value_type.size),
+                            value))) {
+                       info->value_type.dec(info->value_type.context,
+                                            value_ptr(n, index, info->value_type.size));
+               }
+               memcpy_disk(value_ptr(n, index, info->value_type.size),
+                           value, info->value_type.size);
+       }
+
+       *new_root = shadow_root(&spine);
+       exit_shadow_spine(&spine);
+
+       return 0;
+
+bad:
+       __dm_unbless_for_disk(value);
+bad_unblessed:
+       exit_shadow_spine(&spine);
+       return r;
+}
+
+int dm_btree_insert(struct dm_btree_info *info, dm_block_t root,
+                   uint64_t *keys, void *value, dm_block_t *new_root)
+                   __dm_written_to_disk(value)
+{
+       return insert(info, root, keys, value, new_root, NULL);
+}
+EXPORT_SYMBOL_GPL(dm_btree_insert);
+
+int dm_btree_insert_notify(struct dm_btree_info *info, dm_block_t root,
+                          uint64_t *keys, void *value, dm_block_t *new_root,
+                          int *inserted)
+                          __dm_written_to_disk(value)
+{
+       return insert(info, root, keys, value, new_root, inserted);
+}
+EXPORT_SYMBOL_GPL(dm_btree_insert_notify);
+
+/*----------------------------------------------------------------*/
+
+int dm_btree_clone(struct dm_btree_info *info, dm_block_t root,
+                  dm_block_t *clone)
+{
+       int r;
+       struct dm_block *b, *orig_b;
+       struct node *b_node, *orig_node;
+
+       /* Copy the root node */
+       r = new_block(info, &b);
+       if (r < 0)
+               return r;
+
+       r = dm_tm_read_lock(info->tm, root, &btree_node_validator, &orig_b);
+       if (r < 0) {
+               dm_block_t location = dm_block_location(b);
+
+               unlock_block(info, b);
+               dm_tm_dec(info->tm, location);
+       }
+
+       *clone = dm_block_location(b);
+       b_node = dm_block_data(b);
+       orig_node = dm_block_data(orig_b);
+
+       memcpy(b_node, orig_node,
+              dm_bm_block_size(dm_tm_get_bm(info->tm)));
+       dm_tm_unlock(info->tm, orig_b);
+       inc_children(info->tm, b_node, &info->value_type);
+       dm_tm_unlock(info->tm, b);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dm_btree_clone);
+
+/*----------------------------------------------------------------*/
+
+static int find_highest_key(struct ro_spine *s, dm_block_t block,
+                           uint64_t *result_key, dm_block_t *next_block)
+{
+       int i, r;
+       uint32_t flags;
+
+       do {
+               r = ro_step(s, block);
+               if (r < 0)
+                       return r;
+
+               flags = le32_to_cpu(ro_node(s)->header.flags);
+               i = le32_to_cpu(ro_node(s)->header.nr_entries);
+               if (!i)
+                       return -ENODATA;
+               else
+                       i--;
+
+               *result_key = le64_to_cpu(ro_node(s)->keys[i]);
+               if (next_block || flags & INTERNAL_NODE)
+                       block = value64(ro_node(s), i);
+
+       } while (flags & INTERNAL_NODE);
+
+       if (next_block)
+               *next_block = block;
+       return 0;
+}
+
+int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
+                             uint64_t *result_keys)
+{
+       int r = 0, count = 0, level;
+       struct ro_spine spine;
+
+       init_ro_spine(&spine, info);
+       for (level = 0; level < info->levels; level++) {
+               r = find_highest_key(&spine, root, result_keys + level,
+                                    level == info->levels - 1 ? NULL : &root);
+               if (r == -ENODATA) {
+                       r = 0;
+                       break;
+
+               } else if (r)
+                       break;
+
+               count++;
+       }
+       exit_ro_spine(&spine);
+
+       return r ? r : count;
+}
+EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
diff --git a/drivers/md/persistent-data/dm-btree.h b/drivers/md/persistent-data/dm-btree.h
new file mode 100644 (file)
index 0000000..676c41f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+#ifndef _LINUX_DM_BTREE_H
+#define _LINUX_DM_BTREE_H
+
+#include "dm-block-manager.h"
+
+struct dm_transaction_manager;
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Annotations used to check on-disk metadata is handled as little-endian.
+ */
+#ifdef __CHECKER__
+#  define __dm_written_to_disk(x) __releases(x)
+#  define __dm_reads_from_disk(x) __acquires(x)
+#  define __dm_bless_for_disk(x) __acquire(x)
+#  define __dm_unbless_for_disk(x) __release(x)
+#else
+#  define __dm_written_to_disk(x)
+#  define __dm_reads_from_disk(x)
+#  define __dm_bless_for_disk(x)
+#  define __dm_unbless_for_disk(x)
+#endif
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Manipulates hierarchical B+ trees with 64-bit keys and arbitrary-sized
+ * values.
+ */
+
+/*
+ * Infomation about the values stored within the btree.
+ */
+struct dm_btree_value_type {
+       void *context;
+
+       /*
+        * The size in bytes of each value.
+        */
+       uint32_t size;
+
+       /*
+        * Any of these methods can be safely set to NULL if you do not
+        * need the corresponding feature.
+        */
+
+       /*
+        * The btree is making a duplicate of the value, for instance
+        * because previously-shared btree nodes have now diverged.
+        * @value argument is the new copy that the copy function may modify.
+        * (Probably it just wants to increment a reference count
+        * somewhere.) This method is _not_ called for insertion of a new
+        * value: It is assumed the ref count is already 1.
+        */
+       void (*inc)(void *context, void *value);
+
+       /*
+        * This value is being deleted.  The btree takes care of freeing
+        * the memory pointed to by @value.  Often the del function just
+        * needs to decrement a reference count somewhere.
+        */
+       void (*dec)(void *context, void *value);
+
+       /*
+        * A test for equality between two values.  When a value is
+        * overwritten with a new one, the old one has the dec method
+        * called _unless_ the new and old value are deemed equal.
+        */
+       int (*equal)(void *context, void *value1, void *value2);
+};
+
+/*
+ * The shape and contents of a btree.
+ */
+struct dm_btree_info {
+       struct dm_transaction_manager *tm;
+
+       /*
+        * Number of nested btrees. (Not the depth of a single tree.)
+        */
+       unsigned levels;
+       struct dm_btree_value_type value_type;
+};
+
+/*
+ * Set up an empty tree.  O(1).
+ */
+int dm_btree_create(struct dm_btree_info *info, dm_block_t *root);
+
+/*
+ * Destroy a tree.  O(n) - this is the slow one!  It can also block, so
+ * please don't call it on an IO path.
+ */
+int dm_btree_destroy(struct dm_btree_info *info, dm_block_t root);
+
+/*
+ * Delete part of a tree.  This is really specific to truncation of
+ * thin devices.  It only removes keys from the bottom level-btree that
+ * are greater than key[info->levels - 1].
+ */
+int dm_btree_delete_gt(struct dm_btree_info *info, dm_block_t root, uint64_t *key,
+                   dm_block_t *new_root);
+
+/*
+ * All the lookup functions return -ENODATA if the key cannot be found.
+ */
+
+/*
+ * Tries to find a key that matches exactly.  O(ln(n))
+ */
+int dm_btree_lookup(struct dm_btree_info *info, dm_block_t root,
+                   uint64_t *keys, void *value_le);
+
+/*
+ * Insertion (or overwrite an existing value).  O(ln(n))
+ */
+int dm_btree_insert(struct dm_btree_info *info, dm_block_t root,
+                   uint64_t *keys, void *value, dm_block_t *new_root)
+                   __dm_written_to_disk(value);
+
+/*
+ * A variant of insert that indicates whether it actually inserted or just
+ * overwrote.  Useful if you're keeping track of the number of entries in a
+ * tree.
+ */
+int dm_btree_insert_notify(struct dm_btree_info *info, dm_block_t root,
+                          uint64_t *keys, void *value, dm_block_t *new_root,
+                          int *inserted)
+                          __dm_written_to_disk(value);
+
+/*
+ * Remove a key if present.  This doesn't remove empty sub trees.  Normally
+ * subtrees represent a separate entity, like a snapshot map, so this is
+ * correct behaviour.  O(ln(n)).
+ */
+int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
+                   uint64_t *keys, dm_block_t *new_root);
+
+/*
+ * Clone a tree. O(1)
+ */
+int dm_btree_clone(struct dm_btree_info *info, dm_block_t root, dm_block_t *clone);
+
+/*
+ * Returns < 0 on failure.  Otherwise the number of key entries that have
+ * been filled out.  Remember trees can have zero entries, and as such have
+ * no highest key.
+ */
+int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
+                             uint64_t *result_keys);
+
+#endif /* _LINUX_DM_BTREE_H */
diff --git a/drivers/md/persistent-data/dm-persistent-data-internal.h b/drivers/md/persistent-data/dm-persistent-data-internal.h
new file mode 100644 (file)
index 0000000..b7a7ada
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _DM_PERSISTENT_DATA_INTERNAL_H
+#define _DM_PERSISTENT_DATA_INTERNAL_H
+
+#include "dm-block-manager.h"
+
+static inline unsigned dm_hash_block(dm_block_t b, unsigned hash_mask)
+{
+       const unsigned BIG_PRIME = 4294967291UL;
+
+       return (((unsigned) b) * BIG_PRIME) & hash_mask;
+}
+
+#endif /* _PERSISTENT_DATA_INTERNAL_H */
+
diff --git a/drivers/md/persistent-data/dm-space-map-common.h b/drivers/md/persistent-data/dm-space-map-common.h
new file mode 100644 (file)
index 0000000..8c4aef8
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_SPACE_MAP_COMMON_H
+#define DM_SPACE_MAP_COMMON_H
+
+#include "dm-btree.h"
+
+/*
+ *--------------------------------------------------------------------
+ * Low level disk format
+ *
+ * Bitmap btree
+ * ------------
+ *
+ * Each value stored in the btree is an index_entry.  This points to a
+ * block that is used as a bitmap.  Within the bitmap hold 2 bits per
+ * entry, which represent UNUSED = 0, REF_COUNT = 1, REF_COUNT = 2 and
+ * REF_COUNT = many.
+ *
+ * Refcount btree
+ * --------------
+ *
+ * Any entry that has a ref count higher than 2 gets entered in the ref
+ * count tree.  The leaf values for this tree is the 32-bit ref count.
+ *---------------------------------------------------------------------
+ */
+
+struct disk_index_entry {
+       __le64 blocknr;
+       __le32 nr_free;
+       __le32 none_free_before;
+} __packed;
+
+
+#define MAX_METADATA_BITMAPS 255
+struct disk_metadata_index {
+       __le32 csum;
+       __le32 padding;
+       __le64 blocknr;
+
+       struct disk_index_entry index[MAX_METADATA_BITMAPS];
+} __packed;
+
+struct ll_disk {
+       struct dm_transaction_manager *tm;
+       struct dm_btree_info bitmap_info;
+       struct dm_btree_info ref_count_info;
+
+       uint32_t block_size;
+       uint32_t entries_per_block;
+       dm_block_t nr_blocks;
+       dm_block_t nr_allocated;
+
+       /*
+        * bitmap_root may be a btree root or a simple index.
+        */
+       dm_block_t bitmap_root;
+
+       dm_block_t ref_count_root;
+
+       struct disk_metadata_index mi_le;
+};
+
+struct disk_sm_root {
+       __le64 nr_blocks;
+       __le64 nr_allocated;
+       __le64 bitmap_root;
+       __le64 ref_count_root;
+} __packed;
+
+#define ENTRIES_PER_BYTE 4
+
+struct disk_bitmap_header {
+       __le32 csum;
+       __le32 not_used;
+       __le64 blocknr;
+} __packed;
+
+/*
+ * These bitops work on a block's worth of bits.
+ */
+unsigned sm_lookup_bitmap(void *addr, unsigned b);
+void sm_set_bitmap(void *addr, unsigned b, unsigned val);
+int sm_find_free(void *addr, unsigned begin, unsigned end, unsigned *result);
+
+void *dm_bitmap_data(struct dm_block *b);
+
+extern struct dm_block_validator dm_sm_bitmap_validator;
+
+#endif /* DM_SPACE_MAP_COMMON_H */
diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c
new file mode 100644 (file)
index 0000000..6229a4e
--- /dev/null
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-space-map-common.h"
+#include "dm-space-map-disk.h"
+#include "dm-space-map.h"
+#include "dm-transaction-manager.h"
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/device-mapper.h>
+
+#define DM_MSG_PREFIX "space map disk"
+
+/*
+ * Bitmap validator
+ */
+static void bitmap_prepare_for_write(struct dm_block_validator *v,
+                                    struct dm_block *b,
+                                    size_t block_size)
+{
+       struct disk_bitmap_header *disk_header = dm_block_data(b);
+
+       disk_header->blocknr = cpu_to_le64(dm_block_location(b));
+       disk_header->csum = cpu_to_le32(dm_block_csum_data(&disk_header->not_used, block_size - sizeof(__le32)));
+}
+
+static int bitmap_check(struct dm_block_validator *v,
+                       struct dm_block *b,
+                       size_t block_size)
+{
+       struct disk_bitmap_header *disk_header = dm_block_data(b);
+       __le32 csum_disk;
+
+       if (dm_block_location(b) != le64_to_cpu(disk_header->blocknr)) {
+               DMERR("bitmap check failed blocknr %llu wanted %llu",
+                     le64_to_cpu(disk_header->blocknr), dm_block_location(b));
+               return -ENOTBLK;
+       }
+
+       csum_disk = cpu_to_le32(dm_block_csum_data(&disk_header->not_used, block_size - sizeof(__le32)));
+       if (csum_disk != disk_header->csum) {
+               DMERR("bitmap check failed csum %u wanted %u",
+                     le32_to_cpu(csum_disk), le32_to_cpu(disk_header->csum));
+               return -EILSEQ;
+       }
+
+       return 0;
+}
+
+struct dm_block_validator dm_sm_bitmap_validator = {
+       .name = "sm_bitmap",
+       .prepare_for_write = bitmap_prepare_for_write,
+       .check = bitmap_check
+};
+
+/*----------------------------------------------------------------*/
+
+#define ENTRIES_PER_WORD 32
+#define ENTRIES_SHIFT  5
+
+void *dm_bitmap_data(struct dm_block *b)
+{
+       return dm_block_data(b) + sizeof(struct disk_bitmap_header);
+}
+
+#define WORD_MASK_LOW 0x5555555555555555ULL
+#define WORD_MASK_HIGH 0xAAAAAAAAAAAAAAAAULL
+#define WORD_MASK_ALL 0xFFFFFFFFFFFFFFFFULL
+
+static unsigned bitmap_word_used(void *addr, unsigned b)
+{
+       __le64 *words_le = addr;
+       __le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
+
+       uint64_t bits = le64_to_cpu(*w_le);
+
+       return ((bits & WORD_MASK_LOW) == WORD_MASK_LOW ||
+               (bits & WORD_MASK_HIGH) == WORD_MASK_HIGH ||
+               (bits & WORD_MASK_ALL) == WORD_MASK_ALL);
+}
+
+unsigned sm_lookup_bitmap(void *addr, unsigned b)
+{
+       __le64 *words_le = addr;
+       __le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
+
+       b = (b & (ENTRIES_PER_WORD - 1)) << 1;
+
+       return (!!test_bit_le(b, (void *) w_le) << 1) |
+               (!!test_bit_le(b + 1, (void *) w_le));
+}
+
+void sm_set_bitmap(void *addr, unsigned b, unsigned val)
+{
+       __le64 *words_le = addr;
+       __le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
+
+       b = (b & (ENTRIES_PER_WORD - 1)) << 1;
+
+       if (val & 2)
+               __set_bit_le(b, (void *) w_le);
+       else
+               __clear_bit_le(b, (void *) w_le);
+
+       if (val & 1)
+               __set_bit_le(b + 1, (void *) w_le);
+       else
+               __clear_bit_le(b + 1, (void *) w_le);
+}
+
+int sm_find_free(void *addr, unsigned begin, unsigned end,
+                unsigned *result)
+{
+       while (begin < end) {
+               if (!(begin & (ENTRIES_PER_WORD - 1)) &&
+                   bitmap_word_used(addr, begin)) {
+                       begin += ENTRIES_PER_WORD;
+                       continue;
+               }
+
+               if (!sm_lookup_bitmap(addr, begin)) {
+                       *result = begin;
+                       return 0;
+               }
+
+               begin++;
+       }
+
+       return -ENOSPC;
+}
+
+static int disk_ll_init(struct ll_disk *io, struct dm_transaction_manager *tm)
+{
+       io->tm = tm;
+       io->bitmap_info.tm = tm;
+       io->bitmap_info.levels = 1;
+
+       /*
+        * Because the new bitmap blocks are created via a shadow
+        * operation, the old entry has already had its reference count
+        * decremented and we don't need the btree to do any bookkeeping.
+        */
+       io->bitmap_info.value_type.size = sizeof(struct disk_index_entry);
+       io->bitmap_info.value_type.inc = NULL;
+       io->bitmap_info.value_type.dec = NULL;
+       io->bitmap_info.value_type.equal = NULL;
+
+       io->ref_count_info.tm = tm;
+       io->ref_count_info.levels = 1;
+       io->ref_count_info.value_type.size = sizeof(uint32_t);
+       io->ref_count_info.value_type.inc = NULL;
+       io->ref_count_info.value_type.dec = NULL;
+       io->ref_count_info.value_type.equal = NULL;
+
+       io->block_size = dm_bm_block_size(dm_tm_get_bm(tm));
+
+       if (io->block_size > (1 << 30)) {
+               DMERR("block size too big to hold bitmaps");
+               return -EINVAL;
+       }
+
+       io->entries_per_block = (io->block_size - sizeof(struct disk_bitmap_header)) *
+                               ENTRIES_PER_BYTE;
+       io->nr_blocks = 0;
+       io->bitmap_root = 0;
+       io->ref_count_root = 0;
+
+       return 0;
+}
+
+static int disk_ll_new(struct ll_disk *io, struct dm_transaction_manager *tm)
+{
+       int r;
+
+       r = disk_ll_init(io, tm);
+       if (r < 0)
+               return r;
+
+       io->nr_blocks = 0;
+       io->nr_allocated = 0;
+       r = dm_btree_create(&io->bitmap_info, &io->bitmap_root);
+       if (r < 0)
+               return r;
+
+       r = dm_btree_create(&io->ref_count_info, &io->ref_count_root);
+       if (r < 0) {
+               dm_btree_destroy(&io->bitmap_info, io->bitmap_root);
+               return r;
+       }
+
+       return 0;
+}
+
+static int disk_ll_extend(struct ll_disk *io, dm_block_t extra_blocks)
+{
+       int r;
+       dm_block_t i, nr_blocks;
+       unsigned old_blocks, blocks;
+
+       nr_blocks = io->nr_blocks + extra_blocks;
+       old_blocks = dm_sector_div_up(io->nr_blocks, io->entries_per_block);
+       blocks = dm_sector_div_up(nr_blocks, io->entries_per_block);
+
+       for (i = old_blocks; i < blocks; i++) {
+               struct dm_block *b;
+               struct disk_index_entry idx;
+
+               r = dm_tm_new_block(io->tm, &dm_sm_bitmap_validator, &b);
+               if (r < 0)
+                       return r;
+               idx.blocknr = cpu_to_le64(dm_block_location(b));
+
+               r = dm_tm_unlock(io->tm, b);
+               if (r < 0)
+                       return r;
+
+               idx.nr_free = cpu_to_le32(io->entries_per_block);
+               idx.none_free_before = 0;
+               __dm_bless_for_disk(&idx);
+
+               r = dm_btree_insert(&io->bitmap_info, io->bitmap_root,
+                                   &i, &idx, &io->bitmap_root);
+               if (r < 0)
+                       return r;
+       }
+
+       io->nr_blocks = nr_blocks;
+       return 0;
+}
+
+static int disk_ll_open(struct ll_disk *ll, struct dm_transaction_manager *tm,
+                       void *root_le, size_t len)
+{
+       int r;
+       struct disk_sm_root *smr = root_le;
+
+       if (len < sizeof(struct disk_sm_root)) {
+               DMERR("sm_disk root too small");
+               return -ENOMEM;
+       }
+
+       r = disk_ll_init(ll, tm);
+       if (r < 0)
+               return r;
+
+       ll->nr_blocks = le64_to_cpu(smr->nr_blocks);
+       ll->nr_allocated = le64_to_cpu(smr->nr_allocated);
+       ll->bitmap_root = le64_to_cpu(smr->bitmap_root);
+       ll->ref_count_root = le64_to_cpu(smr->ref_count_root);
+
+       return 0;
+}
+
+static int disk_ll_lookup_bitmap(struct ll_disk *io, dm_block_t b, uint32_t *result)
+{
+       int r;
+       dm_block_t index = b;
+       struct disk_index_entry ie_disk;
+       struct dm_block *blk;
+
+       do_div(index, io->entries_per_block);
+       r = dm_btree_lookup(&io->bitmap_info, io->bitmap_root, &index, &ie_disk);
+       if (r < 0)
+               return r;
+
+       r = dm_tm_read_lock(io->tm, le64_to_cpu(ie_disk.blocknr), &dm_sm_bitmap_validator, &blk);
+       if (r < 0)
+               return r;
+
+       *result = sm_lookup_bitmap(dm_bitmap_data(blk), do_div(b, io->entries_per_block));
+
+       return dm_tm_unlock(io->tm, blk);
+}
+
+static int disk_ll_lookup(struct ll_disk *io, dm_block_t b, uint32_t *result)
+{
+       __le32 rc_le;
+       int r = disk_ll_lookup_bitmap(io, b, result);
+
+       if (r)
+               return r;
+
+       if (*result != 3)
+               return r;
+
+       r = dm_btree_lookup(&io->ref_count_info, io->ref_count_root, &b, &rc_le);
+       if (r < 0)
+               return r;
+
+       *result = le32_to_cpu(rc_le);
+
+       return r;
+}
+
+static int disk_ll_find_free_block(struct ll_disk *io, dm_block_t begin,
+                                  dm_block_t end, dm_block_t *result)
+{
+       int r;
+       struct disk_index_entry ie_disk;
+       dm_block_t i, index_begin = begin;
+       dm_block_t index_end = dm_sector_div_up(end, io->entries_per_block);
+
+       begin = do_div(index_begin, io->entries_per_block);
+
+       for (i = index_begin; i < index_end; i++, begin = 0) {
+               struct dm_block *blk;
+               unsigned position;
+               uint32_t bit_end;
+
+               r = dm_btree_lookup(&io->bitmap_info, io->bitmap_root, &i, &ie_disk);
+               if (r < 0)
+                       return r;
+
+               if (le32_to_cpu(ie_disk.nr_free) <= 0)
+                       continue;
+
+               r = dm_tm_read_lock(io->tm, le64_to_cpu(ie_disk.blocknr),
+                                   &dm_sm_bitmap_validator, &blk);
+               if (r < 0)
+                       return r;
+
+               bit_end = (i == index_end - 1) ?
+                       do_div(end, io->entries_per_block) : io->entries_per_block;
+
+               r = sm_find_free(dm_bitmap_data(blk),
+                                max((unsigned)begin, (unsigned)le32_to_cpu(ie_disk.none_free_before)),
+                                bit_end, &position);
+               if (r < 0) {
+                       dm_tm_unlock(io->tm, blk);
+                       continue;
+               }
+
+               r = dm_tm_unlock(io->tm, blk);
+               if (r < 0)
+                       return r;
+
+               *result = i * io->entries_per_block + (dm_block_t) position;
+
+               return 0;
+       }
+
+       return -ENOSPC;
+}
+
+static int disk_ll_insert(struct ll_disk *io, dm_block_t b, uint32_t ref_count)
+{
+       int r;
+       uint32_t bit, old;
+       struct dm_block *nb;
+       dm_block_t index = b;
+       struct disk_index_entry ie_disk;
+       void *bm_le;
+       int inc;
+
+       do_div(index, io->entries_per_block);
+       r = dm_btree_lookup(&io->bitmap_info, io->bitmap_root, &index, &ie_disk);
+       if (r < 0)
+               return r;
+
+       r = dm_tm_shadow_block(io->tm, le64_to_cpu(ie_disk.blocknr),
+                              &dm_sm_bitmap_validator, &nb, &inc);
+       if (r < 0) {
+               DMERR("dm_tm_shadow_block() failed");
+               return r;
+       }
+       ie_disk.blocknr = cpu_to_le64(dm_block_location(nb));
+
+       bm_le = dm_bitmap_data(nb);
+       bit = do_div(b, io->entries_per_block);
+       old = sm_lookup_bitmap(bm_le, bit);
+
+       if (ref_count <= 2) {
+               sm_set_bitmap(bm_le, bit, ref_count);
+
+               if (old > 2) {
+                       r = dm_btree_remove(&io->ref_count_info, io->ref_count_root,
+                                           &b, &io->ref_count_root);
+                       if (r) {
+                               dm_tm_unlock(io->tm, nb);
+                               return r;
+                       }
+               }
+       } else {
+               __le32 rc_le = cpu_to_le32(ref_count);
+
+               __dm_bless_for_disk(&rc_le);
+
+               sm_set_bitmap(bm_le, bit, 3);
+               r = dm_btree_insert(&io->ref_count_info, io->ref_count_root,
+                                   &b, &rc_le, &io->ref_count_root);
+               if (r < 0) {
+                       dm_tm_unlock(io->tm, nb);
+                       DMERR("ref count insert failed");
+                       return r;
+               }
+       }
+
+       r = dm_tm_unlock(io->tm, nb);
+       if (r < 0)
+               return r;
+
+       if (ref_count && !old) {
+               io->nr_allocated++;
+               ie_disk.nr_free = cpu_to_le32(le32_to_cpu(ie_disk.nr_free) - 1);
+               if (le32_to_cpu(ie_disk.none_free_before) == b)
+                       ie_disk.none_free_before = cpu_to_le32(b + 1);
+
+       } else if (old && !ref_count) {
+               io->nr_allocated--;
+               ie_disk.nr_free = cpu_to_le32(le32_to_cpu(ie_disk.nr_free) + 1);
+               ie_disk.none_free_before = cpu_to_le32(min((dm_block_t) le32_to_cpu(ie_disk.none_free_before), b));
+       }
+
+       __dm_bless_for_disk(&ie_disk);
+
+       r = dm_btree_insert(&io->bitmap_info, io->bitmap_root, &index, &ie_disk, &io->bitmap_root);
+       if (r < 0)
+               return r;
+
+       return 0;
+}
+
+static int disk_ll_inc(struct ll_disk *ll, dm_block_t b)
+{
+       int r;
+       uint32_t rc;
+
+       r = disk_ll_lookup(ll, b, &rc);
+       if (r)
+               return r;
+
+       return disk_ll_insert(ll, b, rc + 1);
+}
+
+static int disk_ll_dec(struct ll_disk *ll, dm_block_t b)
+{
+       int r;
+       uint32_t rc;
+
+       r = disk_ll_lookup(ll, b, &rc);
+       if (r)
+               return r;
+
+       if (!rc)
+               return -EINVAL;
+
+       return disk_ll_insert(ll, b, rc - 1);
+}
+
+/*--------------------------------------------------------------*/
+
+/*
+ * Space map interface.
+ */
+struct sm_disk {
+       struct dm_space_map sm;
+
+       struct ll_disk ll;
+};
+
+static void sm_disk_destroy(struct dm_space_map *sm)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       kfree(smd);
+}
+
+static int sm_disk_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       return disk_ll_extend(&smd->ll, extra_blocks);
+}
+
+static int sm_disk_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       *count = smd->ll.nr_blocks;
+
+       return 0;
+}
+
+static int sm_disk_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       *count = smd->ll.nr_blocks - smd->ll.nr_allocated;
+
+       return 0;
+}
+
+static int sm_disk_get_count(struct dm_space_map *sm, dm_block_t b,
+                            uint32_t *result)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       return disk_ll_lookup(&smd->ll, b, result);
+}
+
+static int sm_disk_count_is_more_than_one(struct dm_space_map *sm, dm_block_t b,
+                                         int *result)
+{
+       int r;
+       uint32_t count;
+
+       r = sm_disk_get_count(sm, b, &count);
+       if (r)
+               return r;
+
+       return count > 1;
+}
+
+static int sm_disk_set_count(struct dm_space_map *sm, dm_block_t b,
+                            uint32_t count)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       return disk_ll_insert(&smd->ll, b, count);
+}
+
+static int sm_disk_inc_block(struct dm_space_map *sm, dm_block_t b)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       return disk_ll_inc(&smd->ll, b);
+}
+
+static int sm_disk_dec_block(struct dm_space_map *sm, dm_block_t b)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       return disk_ll_dec(&smd->ll, b);
+}
+
+static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
+{
+       int r;
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+
+       /*
+        * FIXME: We should start the search where we left off.
+        */
+       r = disk_ll_find_free_block(&smd->ll, 0, smd->ll.nr_blocks, b);
+       if (r)
+               return r;
+
+       return disk_ll_inc(&smd->ll, *b);
+}
+
+static int sm_disk_commit(struct dm_space_map *sm)
+{
+       return 0;
+}
+
+static int sm_disk_root_size(struct dm_space_map *sm, size_t *result)
+{
+       *result = sizeof(struct disk_sm_root);
+
+       return 0;
+}
+
+static int sm_disk_copy_root(struct dm_space_map *sm, void *where_le, size_t max)
+{
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+       struct disk_sm_root root_le;
+
+       root_le.nr_blocks = cpu_to_le64(smd->ll.nr_blocks);
+       root_le.nr_allocated = cpu_to_le64(smd->ll.nr_allocated);
+       root_le.bitmap_root = cpu_to_le64(smd->ll.bitmap_root);
+       root_le.ref_count_root = cpu_to_le64(smd->ll.ref_count_root);
+
+       if (max < sizeof(root_le))
+               return -ENOSPC;
+
+       memcpy(where_le, &root_le, sizeof(root_le));
+
+       return 0;
+}
+
+/*----------------------------------------------------------------*/
+
+static struct dm_space_map ops = {
+       .destroy = sm_disk_destroy,
+       .extend = sm_disk_extend,
+       .get_nr_blocks = sm_disk_get_nr_blocks,
+       .get_nr_free = sm_disk_get_nr_free,
+       .get_count = sm_disk_get_count,
+       .count_is_more_than_one = sm_disk_count_is_more_than_one,
+       .set_count = sm_disk_set_count,
+       .inc_block = sm_disk_inc_block,
+       .dec_block = sm_disk_dec_block,
+       .new_block = sm_disk_new_block,
+       .commit = sm_disk_commit,
+       .root_size = sm_disk_root_size,
+       .copy_root = sm_disk_copy_root
+};
+
+struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm,
+                                      dm_block_t nr_blocks)
+{
+       int r;
+       struct sm_disk *smd;
+
+       smd = kmalloc(sizeof(*smd), GFP_KERNEL);
+       if (!smd)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(&smd->sm, &ops, sizeof(smd->sm));
+
+       r = disk_ll_new(&smd->ll, tm);
+       if (r)
+               goto bad;
+
+       r = disk_ll_extend(&smd->ll, nr_blocks);
+       if (r)
+               goto bad;
+
+       r = sm_disk_commit(&smd->sm);
+       if (r)
+               goto bad;
+
+       return &smd->sm;
+
+bad:
+       kfree(smd);
+       return ERR_PTR(r);
+}
+EXPORT_SYMBOL_GPL(dm_sm_disk_create);
+
+struct dm_space_map *dm_sm_disk_open(struct dm_transaction_manager *tm,
+                                    void *root_le, size_t len)
+{
+       int r;
+       struct sm_disk *smd;
+
+       smd = kmalloc(sizeof(*smd), GFP_KERNEL);
+       if (!smd)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(&smd->sm, &ops, sizeof(smd->sm));
+
+       r = disk_ll_open(&smd->ll, tm, root_le, len);
+       if (r)
+               goto bad;
+
+       r = sm_disk_commit(&smd->sm);
+       if (r)
+               goto bad;
+
+       return &smd->sm;
+
+bad:
+       kfree(smd);
+       return ERR_PTR(r);
+}
+EXPORT_SYMBOL_GPL(dm_sm_disk_open);
diff --git a/drivers/md/persistent-data/dm-space-map-disk.h b/drivers/md/persistent-data/dm-space-map-disk.h
new file mode 100644 (file)
index 0000000..7a6c363
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _LINUX_DM_SPACE_MAP_DISK_H
+#define _LINUX_DM_SPACE_MAP_DISK_H
+
+#include "dm-block-manager.h"
+
+struct dm_space_map;
+struct dm_transaction_manager;
+
+/*
+ * Unfortunately we have to use two-phase construction due to the cycle
+ * between the tm and sm.
+ */
+struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm,
+                                      dm_block_t nr_blocks);
+
+struct dm_space_map *dm_sm_disk_open(struct dm_transaction_manager *tm,
+                                    void *root, size_t len);
+
+#endif /* _LINUX_DM_SPACE_MAP_DISK_H */
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
new file mode 100644 (file)
index 0000000..166ed5f
--- /dev/null
@@ -0,0 +1,956 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-space-map.h"
+#include "dm-space-map-common.h"
+#include "dm-space-map-metadata.h"
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/device-mapper.h>
+
+#define DM_MSG_PREFIX "space map metadata"
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Index validator.
+ */
+static void index_prepare_for_write(struct dm_block_validator *v,
+                                   struct dm_block *b,
+                                   size_t block_size)
+{
+       struct disk_metadata_index *mi_le = dm_block_data(b);
+
+       mi_le->blocknr = cpu_to_le64(dm_block_location(b));
+       mi_le->csum = cpu_to_le32(dm_block_csum_data(&mi_le->padding, block_size - sizeof(__le32)));
+}
+
+static int index_check(struct dm_block_validator *v,
+                      struct dm_block *b,
+                      size_t block_size)
+{
+       struct disk_metadata_index *mi_le = dm_block_data(b);
+       __le32 csum_disk;
+
+       if (dm_block_location(b) != le64_to_cpu(mi_le->blocknr)) {
+               DMERR("index_check failed blocknr %llu wanted %llu",
+                     le64_to_cpu(mi_le->blocknr), dm_block_location(b));
+               return -ENOTBLK;
+       }
+
+       csum_disk = cpu_to_le32(dm_block_csum_data(&mi_le->padding,
+                                                block_size - sizeof(__le32)));
+       if (csum_disk != mi_le->csum) {
+               DMERR("index_check failed csum %u wanted %u",
+                     le32_to_cpu(csum_disk), le32_to_cpu(mi_le->csum));
+               return -EILSEQ;
+       }
+
+       return 0;
+}
+
+static struct dm_block_validator index_validator = {
+       .name = "index",
+       .prepare_for_write = index_prepare_for_write,
+       .check = index_check
+};
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Low-level disk ops.
+ */
+static int metadata_ll_init(struct ll_disk *ll, struct dm_transaction_manager *tm)
+{
+       ll->tm = tm;
+
+       ll->ref_count_info.tm = tm;
+       ll->ref_count_info.levels = 1;
+       ll->ref_count_info.value_type.size = sizeof(uint32_t);
+       ll->ref_count_info.value_type.inc = NULL;
+       ll->ref_count_info.value_type.dec = NULL;
+       ll->ref_count_info.value_type.equal = NULL;
+
+       ll->block_size = dm_bm_block_size(dm_tm_get_bm(tm));
+
+       if (ll->block_size > (1 << 30)) {
+               DMERR("block size too big to hold bitmaps");
+               return -EINVAL;
+       }
+
+       ll->entries_per_block = (ll->block_size - sizeof(struct disk_bitmap_header)) *
+                               ENTRIES_PER_BYTE;
+       ll->nr_blocks = 0;
+       ll->bitmap_root = 0;
+       ll->ref_count_root = 0;
+
+       return 0;
+}
+
+static int metadata_ll_new(struct ll_disk *ll, struct dm_transaction_manager *tm,
+                          dm_block_t nr_blocks)
+{
+       int r;
+       dm_block_t i;
+       unsigned blocks;
+       struct dm_block *index_block;
+
+       r = metadata_ll_init(ll, tm);
+       if (r < 0)
+               return r;
+
+       ll->nr_blocks = nr_blocks;
+       ll->nr_allocated = 0;
+
+       blocks = dm_sector_div_up(nr_blocks, ll->entries_per_block);
+       if (blocks > MAX_METADATA_BITMAPS) {
+               DMERR("metadata device too large");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < blocks; i++) {
+               struct dm_block *b;
+               struct disk_index_entry *idx_le = ll->mi_le.index + i;
+
+               r = dm_tm_new_block(tm, &dm_sm_bitmap_validator, &b);
+               if (r < 0)
+                       return r;
+               idx_le->blocknr = cpu_to_le64(dm_block_location(b));
+
+               r = dm_tm_unlock(tm, b);
+               if (r < 0)
+                       return r;
+
+               idx_le->nr_free = cpu_to_le32(ll->entries_per_block);
+               idx_le->none_free_before = 0;
+       }
+
+       /*
+        * Write the index.
+        */
+       r = dm_tm_new_block(tm, &index_validator, &index_block);
+       if (r)
+               return r;
+
+       ll->bitmap_root = dm_block_location(index_block);
+       memcpy(dm_block_data(index_block), &ll->mi_le, sizeof(ll->mi_le));
+       r = dm_tm_unlock(tm, index_block);
+       if (r)
+               return r;
+
+       r = dm_btree_create(&ll->ref_count_info, &ll->ref_count_root);
+       if (r < 0)
+               return r;
+
+       return 0;
+}
+
+static int metadata_ll_open(struct ll_disk *ll, struct dm_transaction_manager *tm,
+                           void *root_le, size_t len)
+{
+       int r;
+       struct disk_sm_root *smr = root_le;
+       struct dm_block *block;
+
+       if (len < sizeof(struct disk_sm_root)) {
+               DMERR("sm_metadata root too small");
+               return -ENOMEM;
+       }
+
+       r = metadata_ll_init(ll, tm);
+       if (r < 0)
+               return r;
+
+       ll->nr_blocks = le64_to_cpu(smr->nr_blocks);
+       ll->nr_allocated = le64_to_cpu(smr->nr_allocated);
+       ll->bitmap_root = le64_to_cpu(smr->bitmap_root);
+
+       r = dm_tm_read_lock(tm, le64_to_cpu(smr->bitmap_root),
+                           &index_validator, &block);
+       if (r)
+               return r;
+
+       memcpy(&ll->mi_le, dm_block_data(block), sizeof(ll->mi_le));
+       r = dm_tm_unlock(tm, block);
+       if (r)
+               return r;
+
+       ll->ref_count_root = le64_to_cpu(smr->ref_count_root);
+       return 0;
+}
+
+static int metadata_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result)
+{
+       int r;
+       dm_block_t index = b;
+       struct disk_index_entry *ie_disk;
+       struct dm_block *blk;
+
+       b = do_div(index, ll->entries_per_block);
+       ie_disk = ll->mi_le.index + index;
+
+       r = dm_tm_read_lock(ll->tm, le64_to_cpu(ie_disk->blocknr),
+                           &dm_sm_bitmap_validator, &blk);
+       if (r < 0)
+               return r;
+
+       *result = sm_lookup_bitmap(dm_bitmap_data(blk), b);
+
+       return dm_tm_unlock(ll->tm, blk);
+}
+
+static int metadata_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result)
+{
+       __le32 le_rc;
+       int r = metadata_ll_lookup_bitmap(ll, b, result);
+
+       if (r)
+               return r;
+
+       if (*result != 3)
+               return r;
+
+       r = dm_btree_lookup(&ll->ref_count_info, ll->ref_count_root, &b, &le_rc);
+       if (r < 0)
+               return r;
+
+       *result = le32_to_cpu(le_rc);
+
+       return r;
+}
+
+static int metadata_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
+                                      dm_block_t end, dm_block_t *result)
+{
+       int r;
+       struct disk_index_entry *ie_disk;
+       dm_block_t i, index_begin = begin;
+       dm_block_t index_end = dm_sector_div_up(end, ll->entries_per_block);
+
+       /*
+        * FIXME: Use shifts
+        */
+       begin = do_div(index_begin, ll->entries_per_block);
+       end = do_div(end, ll->entries_per_block);
+
+       for (i = index_begin; i < index_end; i++, begin = 0) {
+               struct dm_block *blk;
+               unsigned position;
+               uint32_t bit_end;
+
+               ie_disk = ll->mi_le.index + i;
+
+               if (le32_to_cpu(ie_disk->nr_free) <= 0)
+                       continue;
+
+               r = dm_tm_read_lock(ll->tm, le64_to_cpu(ie_disk->blocknr),
+                                   &dm_sm_bitmap_validator, &blk);
+               if (r < 0)
+                       return r;
+
+               bit_end = (i == index_end - 1) ?  end : ll->entries_per_block;
+
+               r = sm_find_free(dm_bitmap_data(blk), begin, bit_end, &position);
+               if (r < 0) {
+                       dm_tm_unlock(ll->tm, blk);
+                       /*
+                        * Avoiding retry (FIXME: explain why)
+                        */
+                       return r;
+               }
+
+               r = dm_tm_unlock(ll->tm, blk);
+               if (r < 0)
+                       return r;
+
+               *result = i * ll->entries_per_block + (dm_block_t) position;
+
+               return 0;
+       }
+
+       return -ENOSPC;
+}
+
+static int metadata_ll_insert(struct ll_disk *ll, dm_block_t b, uint32_t ref_count)
+{
+       int r;
+       uint32_t bit, old;
+       struct dm_block *nb;
+       dm_block_t index = b;
+       struct disk_index_entry *ie_disk;
+       void *bm_le;
+       int inc;
+
+       bit = do_div(index, ll->entries_per_block);
+       ie_disk = ll->mi_le.index + index;
+
+       r = dm_tm_shadow_block(ll->tm, le64_to_cpu(ie_disk->blocknr),
+                              &dm_sm_bitmap_validator, &nb, &inc);
+       if (r < 0) {
+               DMERR("dm_tm_shadow_block() failed");
+               return r;
+       }
+       ie_disk->blocknr = cpu_to_le64(dm_block_location(nb));
+
+       bm_le = dm_bitmap_data(nb);
+       old = sm_lookup_bitmap(bm_le, bit);
+
+       if (ref_count <= 2) {
+               sm_set_bitmap(bm_le, bit, ref_count);
+
+               r = dm_tm_unlock(ll->tm, nb);
+               if (r < 0)
+                       return r;
+
+               if (old > 2) {
+                       r = dm_btree_remove(&ll->ref_count_info,
+                                           ll->ref_count_root,
+                                           &b, &ll->ref_count_root);
+                       if (r) {
+                               sm_set_bitmap(bm_le, bit, old);
+                               return r;
+                       }
+               }
+       } else {
+               __le32 le_rc = cpu_to_le32(ref_count);
+
+               __dm_bless_for_disk(&le_rc);
+
+               sm_set_bitmap(bm_le, bit, 3);
+               r = dm_tm_unlock(ll->tm, nb);
+               if (r < 0) {
+                       __dm_unbless_for_disk(&le_rc);
+                       return r;
+               }
+
+               r = dm_btree_insert(&ll->ref_count_info, ll->ref_count_root,
+                                   &b, &le_rc, &ll->ref_count_root);
+               if (r < 0) {
+                       /* FIXME: release shadow? or assume the whole transaction will be ditched */
+                       DMERR("ref count insert failed");
+                       return r;
+               }
+       }
+
+       if (ref_count && !old) {
+               ll->nr_allocated++;
+               ie_disk->nr_free = cpu_to_le32(le32_to_cpu(ie_disk->nr_free) - 1);
+               if (le32_to_cpu(ie_disk->none_free_before) == b)
+                       ie_disk->none_free_before = cpu_to_le32(b + 1);
+       } else if (old && !ref_count) {
+               ll->nr_allocated--;
+               ie_disk->nr_free = cpu_to_le32(le32_to_cpu(ie_disk->nr_free) + 1);
+               ie_disk->none_free_before = cpu_to_le32(min((dm_block_t) le32_to_cpu(ie_disk->none_free_before), b));
+       }
+
+       return 0;
+}
+
+static int metadata_ll_inc(struct ll_disk *ll, dm_block_t b)
+{
+       int r;
+       uint32_t rc;
+
+       r = metadata_ll_lookup(ll, b, &rc);
+       if (r)
+               return r;
+
+       return metadata_ll_insert(ll, b, rc + 1);
+}
+
+static int metadata_ll_dec(struct ll_disk *ll, dm_block_t b)
+{
+       int r;
+       uint32_t rc;
+
+       r = metadata_ll_lookup(ll, b, &rc);
+       if (r)
+               return r;
+
+       if (!rc)
+               return -EINVAL;
+
+       return metadata_ll_insert(ll, b, rc - 1);
+}
+
+static int metadata_ll_commit(struct ll_disk *ll)
+{
+       int r, inc;
+       struct dm_block *b;
+
+       r = dm_tm_shadow_block(ll->tm, ll->bitmap_root, &index_validator, &b, &inc);
+       if (r)
+               return r;
+
+       memcpy(dm_block_data(b), &ll->mi_le, sizeof(ll->mi_le));
+       ll->bitmap_root = dm_block_location(b);
+
+       return dm_tm_unlock(ll->tm, b);
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Space map interface.
+ *
+ * The low level disk format is written using the standard btree and
+ * transaction manager.  This means that performing disk operations may
+ * cause us to recurse into the space map in order to allocate new blocks.
+ * For this reason we have a pool of pre-allocated blocks large enough to
+ * service any metadata_ll_disk operation.
+ */
+
+/*
+ * FIXME: we should calculate this based on the size of the device.
+ * Only the metadata space map needs this functionality.
+ */
+#define MAX_RECURSIVE_ALLOCATIONS 1024
+
+enum block_op_type {
+       BOP_INC,
+       BOP_DEC
+};
+
+struct block_op {
+       enum block_op_type type;
+       dm_block_t block;
+};
+
+struct sm_metadata {
+       struct dm_space_map sm;
+
+       struct ll_disk ll;
+       struct ll_disk old_ll;
+
+       dm_block_t begin;
+
+       unsigned recursion_count;
+       unsigned allocated_this_transaction;
+       unsigned nr_uncommitted;
+       struct block_op uncommitted[MAX_RECURSIVE_ALLOCATIONS];
+};
+
+static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b)
+{
+       struct block_op *op;
+
+       if (smm->nr_uncommitted == MAX_RECURSIVE_ALLOCATIONS) {
+               DMERR("too many recursive allocations");
+               return -ENOMEM;
+       }
+
+       op = smm->uncommitted + smm->nr_uncommitted++;
+       op->type = type;
+       op->block = b;
+
+       return 0;
+}
+
+static int commit_bop(struct sm_metadata *smm, struct block_op *op)
+{
+       int r = 0;
+
+       switch (op->type) {
+       case BOP_INC:
+               r = metadata_ll_inc(&smm->ll, op->block);
+               break;
+
+       case BOP_DEC:
+               r = metadata_ll_dec(&smm->ll, op->block);
+               break;
+       }
+
+       return r;
+}
+
+static void in(struct sm_metadata *smm)
+{
+       smm->recursion_count++;
+}
+
+static int out(struct sm_metadata *smm)
+{
+       int r = 0;
+
+       /*
+        * If we're not recursing then very bad things are happening.
+        */
+       if (!smm->recursion_count) {
+               DMERR("lost track of recursion depth");
+               return -ENOMEM;
+       }
+
+       if (smm->recursion_count == 1 && smm->nr_uncommitted) {
+               while (smm->nr_uncommitted && !r) {
+                       smm->nr_uncommitted--;
+                       r = commit_bop(smm, smm->uncommitted +
+                                      smm->nr_uncommitted);
+                       if (r)
+                               break;
+               }
+       }
+
+       smm->recursion_count--;
+
+       return r;
+}
+
+/*
+ * When using the out() function above, we often want to combine an error
+ * code for the operation run in the recursive context with that from
+ * out().
+ */
+static int combine_errors(int r1, int r2)
+{
+       return r1 ? r1 : r2;
+}
+
+static int recursing(struct sm_metadata *smm)
+{
+       return smm->recursion_count;
+}
+
+static void sm_metadata_destroy(struct dm_space_map *sm)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       kfree(smm);
+}
+
+static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
+{
+       DMERR("doesn't support extend");
+       return -EINVAL;
+}
+
+static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       *count = smm->ll.nr_blocks;
+
+       return 0;
+}
+
+static int sm_metadata_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       *count = smm->old_ll.nr_blocks - smm->old_ll.nr_allocated -
+                smm->allocated_this_transaction;
+
+       return 0;
+}
+
+static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b,
+                                uint32_t *result)
+{
+       int r, i;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+       unsigned adjustment = 0;
+
+       /*
+        * We may have some uncommitted adjustments to add.  This list
+        * should always be really short.
+        */
+       for (i = 0; i < smm->nr_uncommitted; i++) {
+               struct block_op *op = smm->uncommitted + i;
+
+               if (op->block != b)
+                       continue;
+
+               switch (op->type) {
+               case BOP_INC:
+                       adjustment++;
+                       break;
+
+               case BOP_DEC:
+                       adjustment--;
+                       break;
+               }
+       }
+
+       r = metadata_ll_lookup(&smm->ll, b, result);
+       if (r)
+               return r;
+
+       *result += adjustment;
+
+       return 0;
+}
+
+static int sm_metadata_count_is_more_than_one(struct dm_space_map *sm,
+                                             dm_block_t b, int *result)
+{
+       int r, i, adjustment = 0;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+       uint32_t rc;
+
+       /*
+        * We may have some uncommitted adjustments to add.  This list
+        * should always be really short.
+        */
+       for (i = 0; i < smm->nr_uncommitted; i++) {
+               struct block_op *op = smm->uncommitted + i;
+
+               if (op->block != b)
+                       continue;
+
+               switch (op->type) {
+               case BOP_INC:
+                       adjustment++;
+                       break;
+
+               case BOP_DEC:
+                       adjustment--;
+                       break;
+               }
+       }
+
+       if (adjustment > 1) {
+               *result = 1;
+               return 0;
+       }
+
+       r = metadata_ll_lookup_bitmap(&smm->ll, b, &rc);
+       if (r)
+               return r;
+
+       if (rc == 3)
+               /*
+                * We err on the side of caution, and always return true.
+                */
+               *result = 1;
+       else
+               *result = rc + adjustment > 1;
+
+       return 0;
+}
+
+static int sm_metadata_set_count(struct dm_space_map *sm, dm_block_t b,
+                                uint32_t count)
+{
+       int r, r2;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       if (smm->recursion_count) {
+               DMERR("cannot recurse set_count()");
+               return -EINVAL;
+       }
+
+       in(smm);
+       r = metadata_ll_insert(&smm->ll, b, count);
+       r2 = out(smm);
+
+       return combine_errors(r, r2);
+}
+
+static int sm_metadata_inc_block(struct dm_space_map *sm, dm_block_t b)
+{
+       int r, r2 = 0;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       if (recursing(smm))
+               r = add_bop(smm, BOP_INC, b);
+       else {
+               in(smm);
+               r = metadata_ll_inc(&smm->ll, b);
+               r2 = out(smm);
+       }
+
+       return combine_errors(r, r2);
+}
+
+static int sm_metadata_dec_block(struct dm_space_map *sm, dm_block_t b)
+{
+       int r, r2 = 0;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       if (recursing(smm))
+               r = add_bop(smm, BOP_DEC, b);
+       else {
+               in(smm);
+               r = metadata_ll_dec(&smm->ll, b);
+               r2 = out(smm);
+       }
+
+       return combine_errors(r, r2);
+}
+
+static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b)
+{
+       int r, r2 = 0;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       r = metadata_ll_find_free_block(&smm->old_ll, smm->begin, smm->old_ll.nr_blocks, b);
+       if (r)
+               return r;
+
+       smm->begin = *b + 1;
+
+       if (recursing(smm))
+               r = add_bop(smm, BOP_INC, *b);
+       else {
+               in(smm);
+               r = metadata_ll_inc(&smm->ll, *b);
+               r2 = out(smm);
+       }
+
+       if (!r)
+               smm->allocated_this_transaction++;
+
+       return combine_errors(r, r2);
+}
+
+static int sm_metadata_commit(struct dm_space_map *sm)
+{
+       int r;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
+
+       r = metadata_ll_commit(&smm->ll);
+       if (r)
+               return r;
+
+       memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
+       smm->begin = 0;
+       smm->allocated_this_transaction = 0;
+
+       return 0;
+}
+
+static int sm_metadata_root_size(struct dm_space_map *sm, size_t *result)
+{
+       *result = sizeof(struct disk_sm_root);
+
+       return 0;
+}
+
+static int sm_metadata_copy_root(struct dm_space_map *sm, void *where_le, size_t max)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+       struct disk_sm_root root_le;
+
+       root_le.nr_blocks = cpu_to_le64(smm->ll.nr_blocks);
+       root_le.nr_allocated = cpu_to_le64(smm->ll.nr_allocated);
+       root_le.bitmap_root = cpu_to_le64(smm->ll.bitmap_root);
+       root_le.ref_count_root = cpu_to_le64(smm->ll.ref_count_root);
+
+       if (max < sizeof(root_le))
+               return -ENOSPC;
+
+       memcpy(where_le, &root_le, sizeof(root_le));
+
+       return 0;
+}
+
+static struct dm_space_map ops = {
+       .destroy = sm_metadata_destroy,
+       .extend = sm_metadata_extend,
+       .get_nr_blocks = sm_metadata_get_nr_blocks,
+       .get_nr_free = sm_metadata_get_nr_free,
+       .get_count = sm_metadata_get_count,
+       .count_is_more_than_one = sm_metadata_count_is_more_than_one,
+       .set_count = sm_metadata_set_count,
+       .inc_block = sm_metadata_inc_block,
+       .dec_block = sm_metadata_dec_block,
+       .new_block = sm_metadata_new_block,
+       .commit = sm_metadata_commit,
+       .root_size = sm_metadata_root_size,
+       .copy_root = sm_metadata_copy_root
+};
+
+/*----------------------------------------------------------------*/
+
+/*
+ * When a new space map is created that manages its own space.  We use
+ * this tiny bootstrap allocator.
+ */
+static void sm_bootstrap_destroy(struct dm_space_map *sm)
+{
+}
+
+static int sm_bootstrap_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
+{
+       DMERR("boostrap doesn't support extend");
+
+       return -EINVAL;
+}
+
+static int sm_bootstrap_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       return smm->ll.nr_blocks;
+}
+
+static int sm_bootstrap_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       *count = smm->ll.nr_blocks - smm->begin;
+
+       return 0;
+}
+
+static int sm_bootstrap_get_count(struct dm_space_map *sm, dm_block_t b,
+                                 uint32_t *result)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       return b < smm->begin ? 1 : 0;
+}
+
+static int sm_bootstrap_count_is_more_than_one(struct dm_space_map *sm,
+                                              dm_block_t b, int *result)
+{
+       *result = 0;
+
+       return 0;
+}
+
+static int sm_bootstrap_set_count(struct dm_space_map *sm, dm_block_t b,
+                                 uint32_t count)
+{
+       DMERR("boostrap doesn't support set_count");
+
+       return -EINVAL;
+}
+
+static int sm_bootstrap_new_block(struct dm_space_map *sm, dm_block_t *b)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       /*
+        * We know the entire device is unused.
+        */
+       if (smm->begin == smm->ll.nr_blocks)
+               return -ENOSPC;
+
+       *b = smm->begin++;
+
+       return 0;
+}
+
+static int sm_bootstrap_inc_block(struct dm_space_map *sm, dm_block_t b)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       return add_bop(smm, BOP_INC, b);
+}
+
+static int sm_bootstrap_dec_block(struct dm_space_map *sm, dm_block_t b)
+{
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       return add_bop(smm, BOP_DEC, b);
+}
+
+static int sm_bootstrap_commit(struct dm_space_map *sm)
+{
+       return 0;
+}
+
+static int sm_bootstrap_root_size(struct dm_space_map *sm, size_t *result)
+{
+       DMERR("boostrap doesn't support root_size");
+
+       return -EINVAL;
+}
+
+static int sm_bootstrap_copy_root(struct dm_space_map *sm, void *where,
+                                 size_t max)
+{
+       DMERR("boostrap doesn't support copy_root");
+
+       return -EINVAL;
+}
+
+static struct dm_space_map bootstrap_ops = {
+       .destroy = sm_bootstrap_destroy,
+       .extend = sm_bootstrap_extend,
+       .get_nr_blocks = sm_bootstrap_get_nr_blocks,
+       .get_nr_free = sm_bootstrap_get_nr_free,
+       .get_count = sm_bootstrap_get_count,
+       .count_is_more_than_one = sm_bootstrap_count_is_more_than_one,
+       .set_count = sm_bootstrap_set_count,
+       .inc_block = sm_bootstrap_inc_block,
+       .dec_block = sm_bootstrap_dec_block,
+       .new_block = sm_bootstrap_new_block,
+       .commit = sm_bootstrap_commit,
+       .root_size = sm_bootstrap_root_size,
+       .copy_root = sm_bootstrap_copy_root
+};
+
+/*----------------------------------------------------------------*/
+
+struct dm_space_map *dm_sm_metadata_init(void)
+{
+       struct sm_metadata *smm;
+
+       smm = kmalloc(sizeof(*smm), GFP_KERNEL);
+       if (!smm)
+               return ERR_PTR(-ENOMEM);
+
+       memcpy(&smm->sm, &ops, sizeof(smm->sm));
+
+       return &smm->sm;
+}
+
+int dm_sm_metadata_create(struct dm_space_map *sm,
+                         struct dm_transaction_manager *tm,
+                         dm_block_t nr_blocks,
+                         dm_block_t superblock)
+{
+       int r;
+       dm_block_t i;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       smm->begin = superblock + 1;
+       smm->recursion_count = 0;
+       smm->allocated_this_transaction = 0;
+       smm->nr_uncommitted = 0;
+
+       memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
+       r = metadata_ll_new(&smm->ll, tm, nr_blocks);
+       if (r)
+               return r;
+       memcpy(&smm->sm, &ops, sizeof(smm->sm));
+
+       /*
+        * Now we need to update the newly created data structures with the
+        * allocated blocks that they were built from.
+        */
+       for (i = superblock; !r && i < smm->begin; i++)
+               r = metadata_ll_inc(&smm->ll, i);
+
+       if (r)
+               return r;
+
+       return sm_metadata_commit(sm);
+}
+
+int dm_sm_metadata_open(struct dm_space_map *sm,
+                       struct dm_transaction_manager *tm,
+                       void *root_le, size_t len)
+{
+       int r;
+       struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
+
+       r = metadata_ll_open(&smm->ll, tm, root_le, len);
+       if (r)
+               return r;
+
+       smm->begin = 0;
+       smm->recursion_count = 0;
+       smm->allocated_this_transaction = 0;
+       smm->nr_uncommitted = 0;
+
+       return sm_metadata_commit(sm);
+}
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.h b/drivers/md/persistent-data/dm-space-map-metadata.h
new file mode 100644 (file)
index 0000000..f327051
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_SPACE_MAP_METADATA_H
+#define DM_SPACE_MAP_METADATA_H
+
+#include "dm-transaction-manager.h"
+
+/*
+ * Unfortunately we have to use two-phase construction due to the cycle
+ * between the tm and sm.
+ */
+struct dm_space_map *dm_sm_metadata_init(void);
+
+/*
+ * Create a fresh space map.
+ */
+int dm_sm_metadata_create(struct dm_space_map *sm,
+                         struct dm_transaction_manager *tm,
+                         dm_block_t nr_blocks,
+                         dm_block_t superblock);
+
+/*
+ * Open from a previously-recorded root.
+ */
+int dm_sm_metadata_open(struct dm_space_map *sm,
+                       struct dm_transaction_manager *tm,
+                       void *root_le, size_t len);
+
+#endif /* DM_SPACE_MAP_METADATA_H */
diff --git a/drivers/md/persistent-data/dm-space-map.h b/drivers/md/persistent-data/dm-space-map.h
new file mode 100644 (file)
index 0000000..aff2029
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _LINUX_DM_SPACE_MAP_H
+#define _LINUX_DM_SPACE_MAP_H
+
+#include "dm-block-manager.h"
+
+/*
+ * struct dm_space_map keeps a record of how many times each block in a device
+ * is referenced.  It needs to be fixed on disk as part of the transaction.
+ */
+struct dm_space_map {
+       void (*destroy)(struct dm_space_map *sm);
+
+       int (*extend)(struct dm_space_map *sm, dm_block_t extra_blocks);
+
+       int (*get_nr_blocks)(struct dm_space_map *sm, dm_block_t *count);
+       int (*get_nr_free)(struct dm_space_map *sm, dm_block_t *count);
+
+       int (*get_count)(struct dm_space_map *sm, dm_block_t b, uint32_t *result);
+       int (*count_is_more_than_one)(struct dm_space_map *sm, dm_block_t b,
+                                     int *result);
+       int (*set_count)(struct dm_space_map *sm, dm_block_t b, uint32_t count);
+
+       int (*commit)(struct dm_space_map *sm);
+
+       int (*inc_block)(struct dm_space_map *sm, dm_block_t b);
+       int (*dec_block)(struct dm_space_map *sm, dm_block_t b);
+
+       /*
+        * new_block will increment the returned block.
+        */
+       int (*new_block)(struct dm_space_map *sm, dm_block_t *b);
+
+       /*
+        * The root contains all the information needed to fix the space map.
+        * Generally this info is small, so squirrel it away in a disk block
+        * along with other info.
+        */
+       int (*root_size)(struct dm_space_map *sm, size_t *result);
+       int (*copy_root)(struct dm_space_map *sm, void *copy_to_here_le, size_t len);
+};
+
+/*----------------------------------------------------------------*/
+
+static inline void dm_sm_destroy(struct dm_space_map *sm)
+{
+       sm->destroy(sm);
+}
+
+static inline int dm_sm_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
+{
+       return sm->extend(sm, extra_blocks);
+}
+
+static inline int dm_sm_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
+{
+       return sm->get_nr_blocks(sm, count);
+}
+
+static inline int dm_sm_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
+{
+       return sm->get_nr_free(sm, count);
+}
+
+static inline int dm_sm_get_count(struct dm_space_map *sm, dm_block_t b,
+                                 uint32_t *result)
+{
+       return sm->get_count(sm, b, result);
+}
+
+static inline int dm_sm_count_is_more_than_one(struct dm_space_map *sm,
+                                              dm_block_t b, int *result)
+{
+       return sm->count_is_more_than_one(sm, b, result);
+}
+
+static inline int dm_sm_set_count(struct dm_space_map *sm, dm_block_t b,
+                                 uint32_t count)
+{
+       return sm->set_count(sm, b, count);
+}
+
+static inline int dm_sm_commit(struct dm_space_map *sm)
+{
+       return sm->commit(sm);
+}
+
+static inline int dm_sm_inc_block(struct dm_space_map *sm, dm_block_t b)
+{
+       return sm->inc_block(sm, b);
+}
+
+static inline int dm_sm_dec_block(struct dm_space_map *sm, dm_block_t b)
+{
+       return sm->dec_block(sm, b);
+}
+
+static inline int dm_sm_new_block(struct dm_space_map *sm, dm_block_t *b)
+{
+       return sm->new_block(sm, b);
+}
+
+static inline int dm_sm_root_size(struct dm_space_map *sm, size_t *result)
+{
+       return sm->root_size(sm, result);
+}
+
+static inline int dm_sm_copy_root(struct dm_space_map *sm, void *copy_to_here_le, size_t len)
+{
+       return sm->copy_root(sm, copy_to_here_le, len);
+}
+
+#endif /* _LINUX_DM_SPACE_MAP_H */
diff --git a/drivers/md/persistent-data/dm-transaction-manager.c b/drivers/md/persistent-data/dm-transaction-manager.c
new file mode 100644 (file)
index 0000000..be594dd
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+#include "dm-transaction-manager.h"
+#include "dm-space-map.h"
+#include "dm-space-map-disk.h"
+#include "dm-space-map-metadata.h"
+#include "dm-persistent-data-internal.h"
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/device-mapper.h>
+
+#define DM_MSG_PREFIX "transaction manager"
+
+/*----------------------------------------------------------------*/
+
+struct shadow_info {
+       struct hlist_node hlist;
+       dm_block_t where;
+};
+
+/*
+ * It would be nice if we scaled with the size of transaction.
+ */
+#define HASH_SIZE 256
+#define HASH_MASK (HASH_SIZE - 1)
+
+struct dm_transaction_manager {
+       int is_clone;
+       struct dm_transaction_manager *real;
+
+       struct dm_block_manager *bm;
+       struct dm_space_map *sm;
+
+       spinlock_t lock;
+       struct hlist_head buckets[HASH_SIZE];
+};
+
+/*----------------------------------------------------------------*/
+
+static int is_shadow(struct dm_transaction_manager *tm, dm_block_t b)
+{
+       int r = 0;
+       unsigned bucket = dm_hash_block(b, HASH_MASK);
+       struct shadow_info *si;
+       struct hlist_node *n;
+
+       spin_lock(&tm->lock);
+
+       hlist_for_each_entry(si, n, tm->buckets + bucket, hlist)
+               if (si->where == b) {
+                       r = 1;
+                       break;
+               }
+
+       spin_unlock(&tm->lock);
+
+       return r;
+}
+
+/*
+ * This can silently fail if there's no memory.  We're ok with this since
+ * creating redundant shadows causes no harm.
+ */
+static void insert_shadow(struct dm_transaction_manager *tm, dm_block_t b)
+{
+       unsigned bucket;
+       struct shadow_info *si;
+
+       si = kmalloc(sizeof(*si), GFP_NOIO);
+       if (si) {
+               si->where = b;
+               bucket = dm_hash_block(b, HASH_MASK);
+
+               spin_lock(&tm->lock);
+               hlist_add_head(&si->hlist, tm->buckets + bucket);
+               spin_unlock(&tm->lock);
+       }
+}
+
+static void wipe_shadow_table(struct dm_transaction_manager *tm)
+{
+       struct shadow_info *si;
+       struct hlist_node *n, *tmp;
+       struct hlist_head *bucket;
+       int i;
+
+       spin_lock(&tm->lock);
+       for (i = 0; i < HASH_SIZE; i++) {
+               bucket = tm->buckets + i;
+               hlist_for_each_entry_safe(si, n, tmp, bucket, hlist)
+                       kfree(si);
+
+               INIT_HLIST_HEAD(bucket);
+       }
+       spin_unlock(&tm->lock);
+}
+
+/*----------------------------------------------------------------*/
+
+static struct dm_transaction_manager *dm_tm_create(struct dm_block_manager *bm,
+                                                  struct dm_space_map *sm)
+{
+       int i;
+       struct dm_transaction_manager *tm;
+
+       tm = kmalloc(sizeof(*tm), GFP_KERNEL);
+       if (!tm)
+               return ERR_PTR(-ENOMEM);
+
+       tm->is_clone = 0;
+       tm->real = NULL;
+       tm->bm = bm;
+       tm->sm = sm;
+
+       spin_lock_init(&tm->lock);
+       for (i = 0; i < HASH_SIZE; i++)
+               INIT_HLIST_HEAD(tm->buckets + i);
+
+       return tm;
+}
+
+struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transaction_manager *real)
+{
+       struct dm_transaction_manager *tm;
+
+       tm = kmalloc(sizeof(*tm), GFP_KERNEL);
+       if (tm) {
+               tm->is_clone = 1;
+               tm->real = real;
+       }
+
+       return tm;
+}
+EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone);
+
+void dm_tm_destroy(struct dm_transaction_manager *tm)
+{
+       kfree(tm);
+}
+EXPORT_SYMBOL_GPL(dm_tm_destroy);
+
+int dm_tm_pre_commit(struct dm_transaction_manager *tm)
+{
+       int r;
+
+       if (tm->is_clone)
+               return -EWOULDBLOCK;
+
+       r = dm_sm_commit(tm->sm);
+       if (r < 0)
+               return r;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dm_tm_pre_commit);
+
+int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root)
+{
+       if (tm->is_clone)
+               return -EWOULDBLOCK;
+
+       wipe_shadow_table(tm);
+
+       return dm_bm_flush_and_unlock(tm->bm, root);
+}
+EXPORT_SYMBOL_GPL(dm_tm_commit);
+
+int dm_tm_new_block(struct dm_transaction_manager *tm,
+                   struct dm_block_validator *v,
+                   struct dm_block **result)
+{
+       int r;
+       dm_block_t new_block;
+
+       if (tm->is_clone)
+               return -EWOULDBLOCK;
+
+       r = dm_sm_new_block(tm->sm, &new_block);
+       if (r < 0)
+               return r;
+
+       r = dm_bm_write_lock_zero(tm->bm, new_block, v, result);
+       if (r < 0) {
+               dm_sm_dec_block(tm->sm, new_block);
+               return r;
+       }
+
+       /*
+        * New blocks count as shadows in that they don't need to be
+        * shadowed again.
+        */
+       insert_shadow(tm, new_block);
+
+       return 0;
+}
+
+static int __shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
+                         struct dm_block_validator *v,
+                         struct dm_block **result, int *inc_children)
+{
+       int r;
+       dm_block_t new;
+       uint32_t count;
+       struct dm_block *orig_block;
+
+       r = dm_sm_new_block(tm->sm, &new);
+       if (r < 0)
+               return r;
+
+       r = dm_bm_write_lock_zero(tm->bm, new, v, result);
+       if (r < 0)
+               goto bad_dec_block;
+
+       r = dm_bm_read_lock(tm->bm, orig, v, &orig_block);
+       if (r < 0)
+               goto bad_dec_block;
+
+       memcpy(dm_block_data(*result), dm_block_data(orig_block),
+              dm_bm_block_size(tm->bm));
+
+       r = dm_bm_unlock(orig_block);
+       if (r < 0)
+               goto bad_dec_block;
+
+       r = dm_sm_get_count(tm->sm, orig, &count);
+       if (r < 0)
+               goto bad;
+
+       r = dm_sm_dec_block(tm->sm, orig);
+       if (r < 0)
+               goto bad;
+
+       *inc_children = count > 1;
+
+       return 0;
+
+bad:
+       dm_bm_unlock(*result);
+bad_dec_block:
+       dm_sm_dec_block(tm->sm, new);
+
+       return r;
+}
+
+int dm_tm_shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
+                      struct dm_block_validator *v, struct dm_block **result,
+                      int *inc_children)
+{
+       int r, more_than_one;
+
+       if (tm->is_clone)
+               return -EWOULDBLOCK;
+
+       if (is_shadow(tm, orig)) {
+               r = dm_sm_count_is_more_than_one(tm->sm, orig, &more_than_one);
+               if (r < 0)
+                       return r;
+
+               if (!more_than_one) {
+                       *inc_children = 0;
+                       return dm_bm_write_lock(tm->bm, orig, v, result);
+               }
+               /* fall through */
+       }
+
+       r = __shadow_block(tm, orig, v, result, inc_children);
+       if (r < 0)
+               return r;
+
+       insert_shadow(tm, dm_block_location(*result));
+
+       return r;
+}
+
+int dm_tm_read_lock(struct dm_transaction_manager *tm, dm_block_t b,
+                   struct dm_block_validator *v,
+                   struct dm_block **blk)
+{
+       if (tm->is_clone)
+               return dm_bm_read_try_lock(tm->real->bm, b, v, blk);
+
+       return dm_bm_read_lock(tm->bm, b, v, blk);
+}
+
+int dm_tm_unlock(struct dm_transaction_manager *tm, struct dm_block *b)
+{
+       return dm_bm_unlock(b);
+}
+EXPORT_SYMBOL_GPL(dm_tm_unlock);
+
+void dm_tm_inc(struct dm_transaction_manager *tm, dm_block_t b)
+{
+       /*
+        * The non-blocking clone doesn't support this.
+        */
+       BUG_ON(tm->is_clone);
+
+       dm_sm_inc_block(tm->sm, b);
+}
+EXPORT_SYMBOL_GPL(dm_tm_inc);
+
+void dm_tm_dec(struct dm_transaction_manager *tm, dm_block_t b)
+{
+       /*
+        * The non-blocking clone doesn't support this.
+        */
+       BUG_ON(tm->is_clone);
+
+       dm_sm_dec_block(tm->sm, b);
+}
+
+int dm_tm_ref(struct dm_transaction_manager *tm, dm_block_t b,
+             uint32_t *result)
+{
+       if (tm->is_clone)
+               return -EWOULDBLOCK;
+
+       return dm_sm_get_count(tm->sm, b, result);
+}
+
+struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm)
+{
+       return tm->bm;
+}
+
+/*----------------------------------------------------------------*/
+
+static int dm_tm_create_internal(struct dm_block_manager *bm,
+                                dm_block_t sb_location,
+                                struct dm_block_validator *sb_validator,
+                                size_t root_offset, size_t root_max_len,
+                                struct dm_transaction_manager **tm,
+                                struct dm_space_map **sm,
+                                struct dm_block **sblock,
+                                int create)
+{
+       int r;
+
+       *sm = dm_sm_metadata_init();
+       if (IS_ERR(*sm))
+               return PTR_ERR(*sm);
+
+       *tm = dm_tm_create(bm, *sm);
+       if (IS_ERR(*tm)) {
+               dm_sm_destroy(*sm);
+               return PTR_ERR(*tm);
+       }
+
+       if (create) {
+               r = dm_bm_write_lock_zero(dm_tm_get_bm(*tm), sb_location,
+                                         sb_validator, sblock);
+               if (r < 0) {
+                       DMERR("couldn't lock superblock");
+                       goto bad1;
+               }
+
+               r = dm_sm_metadata_create(*sm, *tm, dm_bm_nr_blocks(bm),
+                                         sb_location);
+               if (r) {
+                       DMERR("couldn't create metadata space map");
+                       goto bad2;
+               }
+
+       } else {
+               r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location,
+                                    sb_validator, sblock);
+               if (r < 0) {
+                       DMERR("couldn't lock superblock");
+                       goto bad1;
+               }
+
+               r = dm_sm_metadata_open(*sm, *tm,
+                                       dm_block_data(*sblock) + root_offset,
+                                       root_max_len);
+               if (IS_ERR(*sm)) {
+                       DMERR("couldn't open metadata space map");
+                       goto bad2;
+               }
+       }
+
+       return 0;
+
+bad2:
+       dm_tm_unlock(*tm, *sblock);
+bad1:
+       dm_tm_destroy(*tm);
+       dm_sm_destroy(*sm);
+       return r;
+}
+
+int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
+                        struct dm_block_validator *sb_validator,
+                        struct dm_transaction_manager **tm,
+                        struct dm_space_map **sm, struct dm_block **sblock)
+{
+       return dm_tm_create_internal(bm, sb_location, sb_validator,
+                                    0, 0, tm, sm, sblock, 1);
+}
+EXPORT_SYMBOL_GPL(dm_tm_create_with_sm);
+
+int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
+                      struct dm_block_validator *sb_validator,
+                      size_t root_offset, size_t root_max_len,
+                      struct dm_transaction_manager **tm,
+                      struct dm_space_map **sm, struct dm_block **sblock)
+{
+       return dm_tm_create_internal(bm, sb_location, sb_validator, root_offset,
+                                    root_max_len, tm, sm, sblock, 0);
+}
+EXPORT_SYMBOL_GPL(dm_tm_open_with_sm);
diff --git a/drivers/md/persistent-data/dm-transaction-manager.h b/drivers/md/persistent-data/dm-transaction-manager.h
new file mode 100644 (file)
index 0000000..c80f4c7
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef _LINUX_DM_TRANSACTION_MANAGER_H
+#define _LINUX_DM_TRANSACTION_MANAGER_H
+
+#include "dm-block-manager.h"
+
+struct dm_transaction_manager;
+struct dm_space_map;
+
+/*----------------------------------------------------------------*/
+
+/*
+ * This manages the scope of a transaction.  It also enforces immutability
+ * of the on-disk data structures by limiting access to writeable blocks.
+ *
+ * Clients should not fiddle with the block manager directly.
+ */
+
+void dm_tm_destroy(struct dm_transaction_manager *tm);
+
+/*
+ * The non-blocking version of a transaction manager is intended for use in
+ * fast path code that needs to do lookups e.g. a dm mapping function.
+ * You create the non-blocking variant from a normal tm.  The interface is
+ * the same, except that most functions will just return -EWOULDBLOCK.
+ * Methods that return void yet may block should not be called on a clone
+ * viz. tm_inc, tm_dec.  Call dm_tm_destroy() as you would with a normal tm
+ * when you've finished with it.  You may not destroy the original prior
+ * to clones.
+ */
+struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transaction_manager *real);
+
+/*
+ * We use a 2-phase commit here.
+ *
+ * i) In the first phase the block manager is told to start flushing, and
+ * the changes to the space map are written to disk.  You should interrogate
+ * your particular space map to get detail of its root node etc. to be
+ * included in your superblock.
+ *
+ * ii) @root will be committed last.  You shouldn't use more than the
+ * first 512 bytes of @root if you wish the transaction to survive a power
+ * failure.  You *must* have a write lock held on @root for both stage (i)
+ * and (ii).  The commit will drop the write lock.
+ */
+int dm_tm_pre_commit(struct dm_transaction_manager *tm);
+int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root);
+
+/*
+ * These methods are the only way to get hold of a writeable block.
+ */
+
+/*
+ * dm_tm_new_block() is pretty self-explanatory.  Make sure you do actually
+ * write to the whole of @data before you unlock, otherwise you could get
+ * a data leak.  (The other option is for tm_new_block() to zero new blocks
+ * before handing them out, which will be redundant in most, if not all,
+ * cases).
+ * Zeroes the new block and returns with write lock held.
+ */
+int dm_tm_new_block(struct dm_transaction_manager *tm,
+                   struct dm_block_validator *v,
+                   struct dm_block **result);
+
+/*
+ * dm_tm_shadow_block() allocates a new block and copies the data from @orig
+ * to it.  It then decrements the reference count on original block.  Use
+ * this to update the contents of a block in a data structure, don't
+ * confuse this with a clone - you shouldn't access the orig block after
+ * this operation.  Because the tm knows the scope of the transaction it
+ * can optimise requests for a shadow of a shadow to a no-op.  Don't forget
+ * to unlock when you've finished with the shadow.
+ *
+ * The @inc_children flag is used to tell the caller whether it needs to
+ * adjust reference counts for children.  (Data in the block may refer to
+ * other blocks.)
+ *
+ * Shadowing implicitly drops a reference on @orig so you must not have
+ * it locked when you call this.
+ */
+int dm_tm_shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
+                      struct dm_block_validator *v,
+                      struct dm_block **result, int *inc_children);
+
+/*
+ * Read access.  You can lock any block you want.  If there's a write lock
+ * on it outstanding then it'll block.
+ */
+int dm_tm_read_lock(struct dm_transaction_manager *tm, dm_block_t b,
+                   struct dm_block_validator *v,
+                   struct dm_block **result);
+
+int dm_tm_unlock(struct dm_transaction_manager *tm, struct dm_block *b);
+
+/*
+ * Functions for altering the reference count of a block directly.
+ */
+void dm_tm_inc(struct dm_transaction_manager *tm, dm_block_t b);
+
+void dm_tm_dec(struct dm_transaction_manager *tm, dm_block_t b);
+
+int dm_tm_ref(struct dm_transaction_manager *tm, dm_block_t b,
+             uint32_t *result);
+
+struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm);
+
+/*
+ * A little utility that ties the knot by producing a transaction manager
+ * that has a space map managed by the transaction manager...
+ *
+ * Returns a tm that has an open transaction to write the new disk sm.
+ * Caller should store the new sm root and commit.
+ */
+int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
+                        struct dm_block_validator *sb_validator,
+                        struct dm_transaction_manager **tm,
+                        struct dm_space_map **sm, struct dm_block **sblock);
+
+int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
+                      struct dm_block_validator *sb_validator,
+                      size_t root_offset, size_t root_max_len,
+                      struct dm_transaction_manager **tm,
+                      struct dm_space_map **sm, struct dm_block **sblock);
+
+#endif /* _LINUX_DM_TRANSACTION_MANAGER_H */
index dbae459fb02d7171291e1d8dcc3d7fa538ab02f4..dfdfdd78a910847cfca266a632c42fa2d50c992e 100644 (file)
@@ -4943,10 +4943,8 @@ static int run(mddev_t *mddev)
 abort:
        md_unregister_thread(mddev->thread);
        mddev->thread = NULL;
-       if (conf) {
-               print_raid5_conf(conf);
-               free_conf(conf);
-       }
+       print_raid5_conf(conf);
+       free_conf(conf);
        mddev->private = NULL;
        printk(KERN_ALERT "md/raid:%s: failed to run raid set.\n", mdname(mddev));
        return -EIO;
index 51752a9ef7a4e82c3f1519bf6d488376d5eeb98e..93d9869e0f15f3ecd10588a9bd981ab7a6ba8dfc 100644 (file)
@@ -1230,7 +1230,7 @@ static const struct net_device_ops dvb_netdev_ops = {
        .ndo_open               = dvb_net_open,
        .ndo_stop               = dvb_net_stop,
        .ndo_start_xmit         = dvb_net_tx,
-       .ndo_set_multicast_list = dvb_net_set_multicast_list,
+       .ndo_set_rx_mode        = dvb_net_set_multicast_list,
        .ndo_set_mac_address    = dvb_net_set_mac,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
index 85d3048c1d679dcc83cdf6a7afb8d0f6af1f15c2..fba6c6458cf94ebd362b5dd60dd4444d70bbc26b 100644 (file)
@@ -21,7 +21,7 @@
 #include <media/videobuf-dma-sg.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/via-core.h>
 #include <linux/via-gpio.h>
 #include <linux/via_i2c.h>
@@ -69,7 +69,7 @@ struct via_camera {
        struct mutex lock;
        enum viacam_opstate opstate;
        unsigned long flags;
-       struct pm_qos_request_list qos_request;
+       struct pm_qos_request qos_request;
        /*
         * GPIO info for power/reset management
         */
index 21574bdf485f3f422ca354e1bedc790a511de148..a99294839d74d4a5dfd81545ad8a1005f7718eb6 100644 (file)
@@ -404,6 +404,7 @@ config MFD_WM831X_I2C
        bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C"
        select MFD_CORE
        select MFD_WM831X
+       select REGMAP_I2C
        depends on I2C=y && GENERIC_HARDIRQS
        help
          Support for the Wolfson Microelecronics WM831x and WM832x PMICs
@@ -415,6 +416,7 @@ config MFD_WM831X_SPI
        bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI"
        select MFD_CORE
        select MFD_WM831X
+       select REGMAP_SPI
        depends on SPI_MASTER && GENERIC_HARDIRQS
        help
          Support for the Wolfson Microelecronics WM831x and WM832x PMICs
@@ -488,6 +490,7 @@ config MFD_WM8350_I2C
 config MFD_WM8994
        bool "Support Wolfson Microelectronics WM8994"
        select MFD_CORE
+       select REGMAP_I2C
        depends on I2C=y && GENERIC_HARDIRQS
        help
          The WM8994 is a highly integrated hi-fi CODEC designed for
@@ -500,6 +503,7 @@ config MFD_WM8994
 config MFD_PCF50633
        tristate "Support for NXP PCF50633"
        depends on I2C
+       select REGMAP_I2C
        help
          Say yes here if you have NXP PCF50633 chip on your board.
          This core driver provides register access and IRQ handling
index 56ba1943c91d71a0c3d0ff8cba69d9c9c56a85a1..882ea7192d8b55e17b670a4db20e36ab6315f5b3 100644 (file)
@@ -1086,7 +1086,7 @@ static inline void ab3550_remove_debugfs(void)
  * This sets up a default config in the AB3550 chip so that it
  * will work as expected.
  */
-static int __init ab3550_setup(struct ab3550 *ab)
+static int __devinit ab3550_setup(struct ab3550 *ab)
 {
        int err = 0;
        int i;
@@ -1193,7 +1193,7 @@ struct ab_family_id {
        char    *name;
 };
 
-static const struct ab_family_id ids[] __initdata = {
+static const struct ab_family_id ids[] __devinitconst = {
        /* AB3550 */
        {
                .id = AB3550_P1A,
@@ -1205,7 +1205,7 @@ static const struct ab_family_id ids[] __initdata = {
        }
 };
 
-static int __init ab3550_probe(struct i2c_client *client,
+static int __devinit ab3550_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
 {
        struct ab3550 *ab;
@@ -1326,7 +1326,7 @@ exit_no_detect:
        return err;
 }
 
-static int __exit ab3550_remove(struct i2c_client *client)
+static int __devexit ab3550_remove(struct i2c_client *client)
 {
        struct ab3550 *ab = i2c_get_clientdata(client);
        int num_i2c_clients = AB3550_NUM_BANKS;
@@ -1359,7 +1359,7 @@ static struct i2c_driver ab3550_driver = {
        },
        .id_table       = ab3550_id,
        .probe          = ab3550_probe,
-       .remove         = __exit_p(ab3550_remove),
+       .remove         = __devexit_p(ab3550_remove),
 };
 
 static int __init ab3550_i2c_init(void)
index f16afb234ff98a250d0ded3a9aac0d1768ab679b..e985d1701a83df56a463cb47ff2a1169bc894ba6 100644 (file)
@@ -143,12 +143,15 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name)
 }
 EXPORT_SYMBOL(ab8500_gpadc_get);
 
-static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
+/**
+ * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
+ */
+int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
        int ad_value)
 {
        int res;
 
-       switch (input) {
+       switch (channel) {
        case MAIN_CHARGER_V:
                /* For some reason we don't have calibrated data */
                if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
@@ -232,18 +235,46 @@ static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
        }
        return res;
 }
+EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage);
 
 /**
  * ab8500_gpadc_convert() - gpadc conversion
- * @input:     analog input to be converted to digital data
+ * @channel:   analog channel to be converted to digital data
  *
  * This function converts the selected analog i/p to digital
  * data.
  */
-int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
+int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel)
+{
+       int ad_value;
+       int voltage;
+
+       ad_value = ab8500_gpadc_read_raw(gpadc, channel);
+       if (ad_value < 0) {
+               dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel);
+               return ad_value;
+       }
+
+       voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value);
+
+       if (voltage < 0)
+               dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+                       " %d AD: 0x%x\n", channel, ad_value);
+
+       return voltage;
+}
+EXPORT_SYMBOL(ab8500_gpadc_convert);
+
+/**
+ * ab8500_gpadc_read_raw() - gpadc read
+ * @channel:   analog channel to be read
+ *
+ * This function obtains the raw ADC value, this then needs
+ * to be converted by calling ab8500_gpadc_ad_to_voltage()
+ */
+int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel)
 {
        int ret;
-       u16 data = 0;
        int looplimit = 0;
        u8 val, low_data, high_data;
 
@@ -278,9 +309,9 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
                goto out;
        }
 
-       /* Select the input source and set average samples to 16 */
+       /* Select the channel source and set average samples to 16 */
        ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
-               AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
+               AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16));
        if (ret < 0) {
                dev_err(gpadc->dev,
                        "gpadc_conversion: set avg samples failed\n");
@@ -292,7 +323,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
         * charging current sense if it needed, ABB 3.0 needs some special
         * treatment too.
         */
-       switch (input) {
+       switch (channel) {
        case MAIN_CHARGER_C:
        case USB_CHARGER_C:
                ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
@@ -359,7 +390,6 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
                goto out;
        }
 
-       data = (high_data << 8) | low_data;
        /* Disable GPADC */
        ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
                AB8500_GPADC_CTRL1_REG, DIS_GPADC);
@@ -370,8 +400,8 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
        /* Disable VTVout LDO this is required for GPADC */
        regulator_disable(gpadc->regu);
        mutex_unlock(&gpadc->ab8500_gpadc_lock);
-       ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data);
-       return ret;
+
+       return (high_data << 8) | low_data;
 
 out:
        /*
@@ -385,10 +415,10 @@ out:
        regulator_disable(gpadc->regu);
        mutex_unlock(&gpadc->ab8500_gpadc_lock);
        dev_err(gpadc->dev,
-               "gpadc_conversion: Failed to AD convert channel %d\n", input);
+               "gpadc_conversion: Failed to AD convert channel %d\n", channel);
        return ret;
 }
-EXPORT_SYMBOL(ab8500_gpadc_convert);
+EXPORT_SYMBOL(ab8500_gpadc_read_raw);
 
 /**
  * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
index c71ae09430c5c580e7f0cc5bbd0d3610fd8b5048..3bd85bddf6e31e51096937abdb60ff170779e1c3 100644 (file)
@@ -584,7 +584,7 @@ static int asic3_gpio_remove(struct platform_device *pdev)
        return gpiochip_remove(&asic->gpio);
 }
 
-static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
+static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
 {
        unsigned long flags;
        u32 cdex;
@@ -596,8 +596,6 @@ static int asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
                asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
        }
        spin_unlock_irqrestore(&asic->lock, flags);
-
-       return 0;
 }
 
 static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
@@ -779,6 +777,8 @@ static struct mfd_cell asic3_cell_mmc = {
        .name          = "tmio-mmc",
        .enable        = asic3_mmc_enable,
        .disable       = asic3_mmc_disable,
+       .suspend       = asic3_mmc_disable,
+       .resume        = asic3_mmc_enable,
        .platform_data = &asic3_mmc_data,
        .pdata_size    = sizeof(asic3_mmc_data),
        .num_resources = ARRAY_SIZE(asic3_mmc_resources),
@@ -811,24 +811,43 @@ static int asic3_leds_disable(struct platform_device *pdev)
        return 0;
 }
 
+static int asic3_leds_suspend(struct platform_device *pdev)
+{
+       const struct mfd_cell *cell = mfd_get_cell(pdev);
+       struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+       while (asic3_gpio_get(&asic->gpio, ASIC3_GPIO(C, cell->id)) != 0)
+               msleep(1);
+
+       asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]);
+
+       return 0;
+}
+
 static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = {
        [0] = {
                .name          = "leds-asic3",
                .id            = 0,
                .enable        = asic3_leds_enable,
                .disable       = asic3_leds_disable,
+               .suspend       = asic3_leds_suspend,
+               .resume        = asic3_leds_enable,
        },
        [1] = {
                .name          = "leds-asic3",
                .id            = 1,
                .enable        = asic3_leds_enable,
                .disable       = asic3_leds_disable,
+               .suspend       = asic3_leds_suspend,
+               .resume        = asic3_leds_enable,
        },
        [2] = {
                .name          = "leds-asic3",
                .id            = 2,
                .enable        = asic3_leds_enable,
                .disable       = asic3_leds_disable,
+               .suspend       = asic3_leds_suspend,
+               .resume        = asic3_leds_enable,
        },
 };
 
@@ -949,6 +968,7 @@ static int __init asic3_probe(struct platform_device *pdev)
                goto out_unmap;
        }
 
+       asic->gpio.label = "asic3";
        asic->gpio.base = pdata->gpio_base;
        asic->gpio.ngpio = ASIC3_NUM_GPIOS;
        asic->gpio.get = asic3_gpio_get;
index 5d1fca0277ef3da09560e219912a76c5e3d0af14..dc58750bb71bbfc52c45fd8afe93be1d5d288be7 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/mutex.h>
 #include <linux/mfd/core.h>
@@ -135,11 +136,13 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
        max8997->dev = &i2c->dev;
        max8997->i2c = i2c;
        max8997->type = id->driver_data;
+       max8997->irq = i2c->irq;
 
        if (!pdata)
                goto err;
 
-       max8997->wakeup = pdata->wakeup;
+       max8997->irq_base = pdata->irq_base;
+       max8997->ono = pdata->ono;
 
        mutex_init(&max8997->iolock);
 
@@ -152,6 +155,8 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 
        pm_runtime_set_active(max8997->dev);
 
+       max8997_irq_init(max8997);
+
        mfd_add_devices(max8997->dev, -1, max8997_devs,
                        ARRAY_SIZE(max8997_devs),
                        NULL, 0);
@@ -164,6 +169,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
        if (ret < 0)
                goto err_mfd;
 
+       /* MAX8997 has a power button input. */
+       device_init_wakeup(max8997->dev, pdata->wakeup);
+
        return ret;
 
 err_mfd:
@@ -393,7 +401,29 @@ static int max8997_restore(struct device *dev)
        return 0;
 }
 
+static int max8997_suspend(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev))
+               irq_set_irq_wake(max8997->irq, 1);
+       return 0;
+}
+
+static int max8997_resume(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev))
+               irq_set_irq_wake(max8997->irq, 0);
+       return max8997_irq_resume(max8997);
+}
+
 const struct dev_pm_ops max8997_pm = {
+       .suspend = max8997_suspend,
+       .resume = max8997_resume,
        .freeze = max8997_freeze,
        .restore = max8997_restore,
 };
index 9cee8e7f0bcb1297116667de77ab1d3f49ce1213..af5d9d0613716177bbd0dd53d6940dd5cbe7f596 100644 (file)
@@ -44,7 +44,7 @@
 
 #include <asm/mach/irq.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/menelaus.h>
 
 #define DRIVER_NAME                    "menelaus"
index 29601e7d606dc425591205597817cc19935066a4..86e14583a08276fd7f76dddd3afe3433f1dfa9a8 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -676,7 +677,6 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
                                | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
                                | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
 
-                       reg |= (1 << (i + 1));
                } else
                        continue;
 
index 57868416c76069d6e4d5ded2043a2a0403098e7a..ff1a7e741ecdfc6d8eb3d27cacaa47a1b492768a 100644 (file)
 #include <linux/i2c.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
 
 #include <linux/mfd/pcf50633/core.h>
 
-static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
-{
-       int ret;
-
-       ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
-                               num, data);
-       if (ret < 0)
-               dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
-
-       return ret;
-}
-
-static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
-{
-       int ret;
-
-       ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
-                               num, data);
-       if (ret < 0)
-               dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
-
-       return ret;
-
-}
-
 /* Read a block of up to 32 regs  */
 int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
                                        int nr_regs, u8 *data)
 {
        int ret;
 
-       mutex_lock(&pcf->lock);
-       ret = __pcf50633_read(pcf, reg, nr_regs, data);
-       mutex_unlock(&pcf->lock);
+       ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs);
+       if (ret != 0)
+               return ret;
 
-       return ret;
+       return nr_regs;
 }
 EXPORT_SYMBOL_GPL(pcf50633_read_block);
 
@@ -71,21 +48,22 @@ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
 {
        int ret;
 
-       mutex_lock(&pcf->lock);
-       ret = __pcf50633_write(pcf, reg, nr_regs, data);
-       mutex_unlock(&pcf->lock);
+       ret = regmap_raw_write(pcf->regmap, reg, data, nr_regs);
+       if (ret != 0)
+               return ret;
 
-       return ret;
+       return nr_regs;
 }
 EXPORT_SYMBOL_GPL(pcf50633_write_block);
 
 u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
 {
-       u8 val;
+       unsigned int val;
+       int ret;
 
-       mutex_lock(&pcf->lock);
-       __pcf50633_read(pcf, reg, 1, &val);
-       mutex_unlock(&pcf->lock);
+       ret = regmap_read(pcf->regmap, reg, &val);
+       if (ret < 0)
+               return -1;
 
        return val;
 }
@@ -93,56 +71,19 @@ EXPORT_SYMBOL_GPL(pcf50633_reg_read);
 
 int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
 {
-       int ret;
-
-       mutex_lock(&pcf->lock);
-       ret = __pcf50633_write(pcf, reg, 1, &val);
-       mutex_unlock(&pcf->lock);
-
-       return ret;
+       return regmap_write(pcf->regmap, reg, val);
 }
 EXPORT_SYMBOL_GPL(pcf50633_reg_write);
 
 int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
 {
-       int ret;
-       u8 tmp;
-
-       val &= mask;
-
-       mutex_lock(&pcf->lock);
-       ret = __pcf50633_read(pcf, reg, 1, &tmp);
-       if (ret < 0)
-               goto out;
-
-       tmp &= ~mask;
-       tmp |= val;
-       ret = __pcf50633_write(pcf, reg, 1, &tmp);
-
-out:
-       mutex_unlock(&pcf->lock);
-
-       return ret;
+       return regmap_update_bits(pcf->regmap, reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
 
 int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
 {
-       int ret;
-       u8 tmp;
-
-       mutex_lock(&pcf->lock);
-       ret = __pcf50633_read(pcf, reg, 1, &tmp);
-       if (ret < 0)
-               goto out;
-
-       tmp &= ~val;
-       ret = __pcf50633_write(pcf, reg, 1, &tmp);
-
-out:
-       mutex_unlock(&pcf->lock);
-
-       return ret;
+       return regmap_update_bits(pcf->regmap, reg, val, 0);
 }
 EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
 
@@ -251,6 +192,11 @@ static int pcf50633_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
 
+static struct regmap_config pcf50633_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
 static int __devinit pcf50633_probe(struct i2c_client *client,
                                const struct i2c_device_id *ids)
 {
@@ -272,16 +218,23 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
 
        mutex_init(&pcf->lock);
 
+       pcf->regmap = regmap_init_i2c(client, &pcf50633_regmap_config);
+       if (IS_ERR(pcf->regmap)) {
+               ret = PTR_ERR(pcf->regmap);
+               dev_err(pcf->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               goto err_free;
+       }
+
        i2c_set_clientdata(client, pcf);
        pcf->dev = &client->dev;
-       pcf->i2c_client = client;
 
        version = pcf50633_reg_read(pcf, 0);
        variant = pcf50633_reg_read(pcf, 1);
        if (version < 0 || variant < 0) {
                dev_err(pcf->dev, "Unable to probe pcf50633\n");
                ret = -ENODEV;
-               goto err_free;
+               goto err_regmap;
        }
 
        dev_info(pcf->dev, "Probed device version %d variant %d\n",
@@ -328,6 +281,8 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
 
        return 0;
 
+err_regmap:
+       regmap_exit(pcf->regmap);
 err_free:
        kfree(pcf);
 
@@ -351,6 +306,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
        for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
                platform_device_unregister(pcf->regulator_pdev[i]);
 
+       regmap_exit(pcf->regmap);
        kfree(pcf);
 
        return 0;
index c27e515b0722b2dfa72263e5bd3725ddd27885fd..de979742c6fc1049cf49f858870034f3885eeb05 100644 (file)
@@ -357,6 +357,7 @@ static int __devexit tc3589x_remove(struct i2c_client *client)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int tc3589x_suspend(struct device *dev)
 {
        struct tc3589x *tc3589x = dev_get_drvdata(dev);
@@ -387,6 +388,7 @@ static int tc3589x_resume(struct device *dev)
 
 static const SIMPLE_DEV_PM_OPS(tc3589x_dev_pm_ops, tc3589x_suspend,
                                                tc3589x_resume);
+#endif
 
 static const struct i2c_device_id tc3589x_id[] = {
        { "tc3589x", 24 },
index 696879e2eef77b2429fd8b52e77375a5032e45fc..02d65692ceb415a1ae95a863dd660adda46807c9 100644 (file)
@@ -697,7 +697,7 @@ static int __devinit timb_probe(struct pci_dev *dev,
                dev_err(&dev->dev, "The driver supports an older "
                        "version of the FPGA, please update the driver to "
                        "support %d.%d\n", priv->fw.major, priv->fw.minor);
-               goto err_ioremap;
+               goto err_config;
        }
        if (priv->fw.major < TIMB_SUPPORTED_MAJOR ||
                priv->fw.minor < TIMB_REQUIRED_MINOR) {
@@ -705,13 +705,13 @@ static int __devinit timb_probe(struct pci_dev *dev,
                        "please upgrade the FPGA to at least: %d.%d\n",
                        priv->fw.major, priv->fw.minor,
                        TIMB_SUPPORTED_MAJOR, TIMB_REQUIRED_MINOR);
-               goto err_ioremap;
+               goto err_config;
        }
 
        msix_entries = kzalloc(TIMBERDALE_NR_IRQS * sizeof(*msix_entries),
                GFP_KERNEL);
        if (!msix_entries)
-               goto err_ioremap;
+               goto err_config;
 
        for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
                msix_entries[i].entry = i;
@@ -825,6 +825,8 @@ err_mfd:
 err_create_file:
        pci_disable_msix(dev);
 err_msix:
+       kfree(msix_entries);
+err_config:
        iounmap(priv->ctl_membase);
 err_ioremap:
        release_mem_region(priv->ctl_mapbase, CHIPCTLSIZE);
@@ -833,7 +835,6 @@ err_request:
 err_start:
        pci_disable_device(dev);
 err_enable:
-       kfree(msix_entries);
        kfree(priv);
        pci_set_drvdata(dev, NULL);
        return -ENODEV;
index 2bfad5c86cc76875cc0765300a4f4f3bf24d7332..a56be931551c9ac7ee34e546a18891e8a2b6549d 100644 (file)
@@ -178,8 +178,10 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
        switch (tps65910_chip_id(tps65910)) {
        case TPS65910:
                tps65910->irq_num = TPS65910_NUM_IRQ;
+               break;
        case TPS65911:
                tps65910->irq_num = TPS65911_NUM_IRQ;
+               break;
        }
 
        /* Register with genirq */
index 8a7ee3139b86fda3bded6748e572893d37b577fb..ff16e9c3ba3096d93be899c88296c69b15afbf3e 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/kthread.h>
 #include <linux/slab.h>
 
 #include <linux/i2c/twl.h>
@@ -278,59 +277,6 @@ static const struct sih sih_modules_twl5031[8] = {
 
 static unsigned twl4030_irq_base;
 
-static struct completion irq_event;
-
-/*
- * This thread processes interrupts reported by the Primary Interrupt Handler.
- */
-static int twl4030_irq_thread(void *data)
-{
-       long irq = (long)data;
-       static unsigned i2c_errors;
-       static const unsigned max_i2c_errors = 100;
-
-
-       current->flags |= PF_NOFREEZE;
-
-       while (!kthread_should_stop()) {
-               int ret;
-               int module_irq;
-               u8 pih_isr;
-
-               /* Wait for IRQ, then read PIH irq status (also blocking) */
-               wait_for_completion_interruptible(&irq_event);
-
-               ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
-                                         REG_PIH_ISR_P1);
-               if (ret) {
-                       pr_warning("twl4030: I2C error %d reading PIH ISR\n",
-                                       ret);
-                       if (++i2c_errors >= max_i2c_errors) {
-                               printk(KERN_ERR "Maximum I2C error count"
-                                               " exceeded.  Terminating %s.\n",
-                                               __func__);
-                               break;
-                       }
-                       complete(&irq_event);
-                       continue;
-               }
-
-               /* these handlers deal with the relevant SIH irq status */
-               local_irq_disable();
-               for (module_irq = twl4030_irq_base;
-                               pih_isr;
-                               pih_isr >>= 1, module_irq++) {
-                       if (pih_isr & 0x1)
-                               generic_handle_irq(module_irq);
-               }
-               local_irq_enable();
-
-               enable_irq(irq);
-       }
-
-       return 0;
-}
-
 /*
  * handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt.
  * This is a chained interrupt, so there is no desc->action method for it.
@@ -342,9 +288,25 @@ static int twl4030_irq_thread(void *data)
  */
 static irqreturn_t handle_twl4030_pih(int irq, void *devid)
 {
-       /* Acknowledge, clear *AND* mask the interrupt... */
-       disable_irq_nosync(irq);
-       complete(devid);
+       int             module_irq;
+       irqreturn_t     ret;
+       u8              pih_isr;
+
+       ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
+                       REG_PIH_ISR_P1);
+       if (ret) {
+               pr_warning("twl4030: I2C error %d reading PIH ISR\n", ret);
+               return IRQ_NONE;
+       }
+
+       /* these handlers deal with the relevant SIH irq status */
+       for (module_irq = twl4030_irq_base;
+                       pih_isr;
+                       pih_isr >>= 1, module_irq++) {
+               if (pih_isr & 0x1)
+                       handle_nested_irq(module_irq);
+       }
+
        return IRQ_HANDLED;
 }
 /*----------------------------------------------------------------------*/
@@ -460,113 +422,17 @@ static inline void activate_irq(int irq)
 
 /*----------------------------------------------------------------------*/
 
-static DEFINE_SPINLOCK(sih_agent_lock);
-
-static struct workqueue_struct *wq;
-
 struct sih_agent {
        int                     irq_base;
        const struct sih        *sih;
 
        u32                     imr;
        bool                    imr_change_pending;
-       struct work_struct      mask_work;
-
-       u32                     edge_change;
-       struct work_struct      edge_work;
-};
-
-static void twl4030_sih_do_mask(struct work_struct *work)
-{
-       struct sih_agent        *agent;
-       const struct sih        *sih;
-       union {
-               u8      bytes[4];
-               u32     word;
-       }                       imr;
-       int                     status;
 
-       agent = container_of(work, struct sih_agent, mask_work);
-
-       /* see what work we have */
-       spin_lock_irq(&sih_agent_lock);
-       if (agent->imr_change_pending) {
-               sih = agent->sih;
-               /* byte[0] gets overwritten as we write ... */
-               imr.word = cpu_to_le32(agent->imr << 8);
-               agent->imr_change_pending = false;
-       } else
-               sih = NULL;
-       spin_unlock_irq(&sih_agent_lock);
-       if (!sih)
-               return;
-
-       /* write the whole mask ... simpler than subsetting it */
-       status = twl_i2c_write(sih->module, imr.bytes,
-                       sih->mask[irq_line].imr_offset, sih->bytes_ixr);
-       if (status)
-               pr_err("twl4030: %s, %s --> %d\n", __func__,
-                               "write", status);
-}
-
-static void twl4030_sih_do_edge(struct work_struct *work)
-{
-       struct sih_agent        *agent;
-       const struct sih        *sih;
-       u8                      bytes[6];
        u32                     edge_change;
-       int                     status;
-
-       agent = container_of(work, struct sih_agent, edge_work);
-
-       /* see what work we have */
-       spin_lock_irq(&sih_agent_lock);
-       edge_change = agent->edge_change;
-       agent->edge_change = 0;
-       sih = edge_change ? agent->sih : NULL;
-       spin_unlock_irq(&sih_agent_lock);
-       if (!sih)
-               return;
-
-       /* Read, reserving first byte for write scratch.  Yes, this
-        * could be cached for some speedup ... but be careful about
-        * any processor on the other IRQ line, EDR registers are
-        * shared.
-        */
-       status = twl_i2c_read(sih->module, bytes + 1,
-                       sih->edr_offset, sih->bytes_edr);
-       if (status) {
-               pr_err("twl4030: %s, %s --> %d\n", __func__,
-                               "read", status);
-               return;
-       }
-
-       /* Modify only the bits we know must change */
-       while (edge_change) {
-               int             i = fls(edge_change) - 1;
-               struct irq_data *idata = irq_get_irq_data(i + agent->irq_base);
-               int             byte = 1 + (i >> 2);
-               int             off = (i & 0x3) * 2;
-               unsigned int    type;
-
-               bytes[byte] &= ~(0x03 << off);
 
-               type = irqd_get_trigger_type(idata);
-               if (type & IRQ_TYPE_EDGE_RISING)
-                       bytes[byte] |= BIT(off + 1);
-               if (type & IRQ_TYPE_EDGE_FALLING)
-                       bytes[byte] |= BIT(off + 0);
-
-               edge_change &= ~BIT(i);
-       }
-
-       /* Write */
-       status = twl_i2c_write(sih->module, bytes,
-                       sih->edr_offset, sih->bytes_edr);
-       if (status)
-               pr_err("twl4030: %s, %s --> %d\n", __func__,
-                               "write", status);
-}
+       struct mutex            irq_lock;
+};
 
 /*----------------------------------------------------------------------*/
 
@@ -579,50 +445,125 @@ static void twl4030_sih_do_edge(struct work_struct *work)
 
 static void twl4030_sih_mask(struct irq_data *data)
 {
-       struct sih_agent *sih = irq_data_get_irq_chip_data(data);
-       unsigned long flags;
-
-       spin_lock_irqsave(&sih_agent_lock, flags);
-       sih->imr |= BIT(data->irq - sih->irq_base);
-       sih->imr_change_pending = true;
-       queue_work(wq, &sih->mask_work);
-       spin_unlock_irqrestore(&sih_agent_lock, flags);
+       struct sih_agent *agent = irq_data_get_irq_chip_data(data);
+
+       agent->imr |= BIT(data->irq - agent->irq_base);
+       agent->imr_change_pending = true;
 }
 
 static void twl4030_sih_unmask(struct irq_data *data)
 {
-       struct sih_agent *sih = irq_data_get_irq_chip_data(data);
-       unsigned long flags;
-
-       spin_lock_irqsave(&sih_agent_lock, flags);
-       sih->imr &= ~BIT(data->irq - sih->irq_base);
-       sih->imr_change_pending = true;
-       queue_work(wq, &sih->mask_work);
-       spin_unlock_irqrestore(&sih_agent_lock, flags);
+       struct sih_agent *agent = irq_data_get_irq_chip_data(data);
+
+       agent->imr &= ~BIT(data->irq - agent->irq_base);
+       agent->imr_change_pending = true;
 }
 
 static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
 {
-       struct sih_agent *sih = irq_data_get_irq_chip_data(data);
-       unsigned long flags;
+       struct sih_agent *agent = irq_data_get_irq_chip_data(data);
 
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                return -EINVAL;
 
-       spin_lock_irqsave(&sih_agent_lock, flags);
-       if (irqd_get_trigger_type(data) != trigger) {
-               sih->edge_change |= BIT(data->irq - sih->irq_base);
-               queue_work(wq, &sih->edge_work);
-       }
-       spin_unlock_irqrestore(&sih_agent_lock, flags);
+       if (irqd_get_trigger_type(data) != trigger)
+               agent->edge_change |= BIT(data->irq - agent->irq_base);
+
        return 0;
 }
 
+static void twl4030_sih_bus_lock(struct irq_data *data)
+{
+       struct sih_agent        *agent = irq_data_get_irq_chip_data(data);
+
+       mutex_lock(&agent->irq_lock);
+}
+
+static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
+{
+       struct sih_agent        *agent = irq_data_get_irq_chip_data(data);
+       const struct sih        *sih = agent->sih;
+       int                     status;
+
+       if (agent->imr_change_pending) {
+               union {
+                       u32     word;
+                       u8      bytes[4];
+               } imr;
+
+               /* byte[0] gets overwriten as we write ... */
+               imr.word = cpu_to_le32(agent->imr << 8);
+               agent->imr_change_pending = false;
+
+               /* write the whole mask ... simpler than subsetting it */
+               status = twl_i2c_write(sih->module, imr.bytes,
+                               sih->mask[irq_line].imr_offset,
+                               sih->bytes_ixr);
+               if (status)
+                       pr_err("twl4030: %s, %s --> %d\n", __func__,
+                                       "write", status);
+       }
+
+       if (agent->edge_change) {
+               u32             edge_change;
+               u8              bytes[6];
+
+               edge_change = agent->edge_change;
+               agent->edge_change = 0;
+
+               /*
+                * Read, reserving first byte for write scratch.  Yes, this
+                * could be cached for some speedup ... but be careful about
+                * any processor on the other IRQ line, EDR registers are
+                * shared.
+                */
+               status = twl_i2c_read(sih->module, bytes + 1,
+                               sih->edr_offset, sih->bytes_edr);
+               if (status) {
+                       pr_err("twl4030: %s, %s --> %d\n", __func__,
+                                       "read", status);
+                       return;
+               }
+
+               /* Modify only the bits we know must change */
+               while (edge_change) {
+                       int             i = fls(edge_change) - 1;
+                       struct irq_data *idata;
+                       int             byte = 1 + (i >> 2);
+                       int             off = (i & 0x3) * 2;
+                       unsigned int    type;
+
+                       idata = irq_get_irq_data(i + agent->irq_base);
+
+                       bytes[byte] &= ~(0x03 << off);
+
+                       type = irqd_get_trigger_type(idata);
+                       if (type & IRQ_TYPE_EDGE_RISING)
+                               bytes[byte] |= BIT(off + 1);
+                       if (type & IRQ_TYPE_EDGE_FALLING)
+                               bytes[byte] |= BIT(off + 0);
+
+                       edge_change &= ~BIT(i);
+               }
+
+               /* Write */
+               status = twl_i2c_write(sih->module, bytes,
+                               sih->edr_offset, sih->bytes_edr);
+               if (status)
+                       pr_err("twl4030: %s, %s --> %d\n", __func__,
+                                       "write", status);
+       }
+
+       mutex_unlock(&agent->irq_lock);
+}
+
 static struct irq_chip twl4030_sih_irq_chip = {
        .name           = "twl4030",
-       .irq_mask       = twl4030_sih_mask,
+       .irq_mask       = twl4030_sih_mask,
        .irq_unmask     = twl4030_sih_unmask,
        .irq_set_type   = twl4030_sih_set_type,
+       .irq_bus_lock   = twl4030_sih_bus_lock,
+       .irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock,
 };
 
 /*----------------------------------------------------------------------*/
@@ -655,9 +596,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
        int isr;
 
        /* reading ISR acks the IRQs, using clear-on-read mode */
-       local_irq_enable();
        isr = sih_read_isr(sih);
-       local_irq_disable();
 
        if (isr < 0) {
                pr_err("twl4030: %s SIH, read ISR error %d\n",
@@ -672,7 +611,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
                isr &= ~BIT(irq);
 
                if (irq < sih->bits)
-                       generic_handle_irq(agent->irq_base + irq);
+                       handle_nested_irq(agent->irq_base + irq);
                else
                        pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
                                sih->name, irq);
@@ -718,15 +657,14 @@ int twl4030_sih_setup(int module)
        agent->irq_base = irq_base;
        agent->sih = sih;
        agent->imr = ~0;
-       INIT_WORK(&agent->mask_work, twl4030_sih_do_mask);
-       INIT_WORK(&agent->edge_work, twl4030_sih_do_edge);
+       mutex_init(&agent->irq_lock);
 
        for (i = 0; i < sih->bits; i++) {
                irq = irq_base + i;
 
+               irq_set_chip_data(irq, agent);
                irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
                                         handle_edge_irq);
-               irq_set_chip_data(irq, agent);
                activate_irq(irq);
        }
 
@@ -758,7 +696,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 
        int                     status;
        int                     i;
-       struct task_struct      *task;
 
        /*
         * Mask and clear all TWL4030 interrupts since initially we do
@@ -768,12 +705,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        if (status < 0)
                return status;
 
-       wq = create_singlethread_workqueue("twl4030-irqchip");
-       if (!wq) {
-               pr_err("twl4030: workqueue FAIL\n");
-               return -ESRCH;
-       }
-
        twl4030_irq_base = irq_base;
 
        /* install an irq handler for each of the SIH modules;
@@ -787,6 +718,7 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        for (i = irq_base; i < irq_end; i++) {
                irq_set_chip_and_handler(i, &twl4030_irq_chip,
                                         handle_simple_irq);
+               irq_set_nested_thread(i, 1);
                activate_irq(i);
        }
        twl4030_irq_next = i;
@@ -801,34 +733,22 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        }
 
        /* install an irq handler to demultiplex the TWL4030 interrupt */
-
-
-       init_completion(&irq_event);
-
-       status = request_irq(irq_num, handle_twl4030_pih, IRQF_DISABLED,
-                               "TWL4030-PIH", &irq_event);
+       status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih,
+                       IRQF_DISABLED, "TWL4030-PIH", NULL);
        if (status < 0) {
                pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status);
                goto fail_rqirq;
        }
 
-       task = kthread_run(twl4030_irq_thread, (void *)(long)irq_num,
-                                                               "twl4030-irq");
-       if (IS_ERR(task)) {
-               pr_err("twl4030: could not create irq %d thread!\n", irq_num);
-               status = PTR_ERR(task);
-               goto fail_kthread;
-       }
        return status;
-fail_kthread:
-       free_irq(irq_num, &irq_event);
 fail_rqirq:
        /* clean up twl4030_sih_setup */
 fail:
-       for (i = irq_base; i < irq_end; i++)
+       for (i = irq_base; i < irq_end; i++) {
+               irq_set_nested_thread(i, 0);
                irq_set_chip_and_handler(i, NULL, NULL);
-       destroy_workqueue(wq);
-       wq = NULL;
+       }
+
        return status;
 }
 
index b5d598c3aa71b356f40fb9a5f89738eed16c5350..834f824d3c11075b18098a5c0b64a1abf066cd69 100644 (file)
@@ -510,8 +510,9 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req)
        u8 ch_msb, ch_lsb;
        int ret;
 
-       if (!req)
+       if (!req || !twl4030_madc)
                return -EINVAL;
+
        mutex_lock(&twl4030_madc->lock);
        if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
                ret = -EINVAL;
@@ -706,6 +707,8 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev)
        if (!madc)
                return -ENOMEM;
 
+       madc->dev = &pdev->dev;
+
        /*
         * Phoenix provides 2 interrupt lines. The first one is connected to
         * the OMAP. The other one can be connected to the other processor such
@@ -737,6 +740,28 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev)
                        TWL4030_BCI_BCICTL1);
                goto err_i2c;
        }
+
+       /* Check that MADC clock is on */
+       ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
+                               TWL4030_REG_GPBR1);
+               goto err_i2c;
+       }
+
+       /* If MADC clk is not on, turn it on */
+       if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
+               dev_info(&pdev->dev, "clk disabled, enabling\n");
+               regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
+               ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
+                                      TWL4030_REG_GPBR1);
+               if (ret) {
+                       dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
+                                       TWL4030_REG_GPBR1);
+                       goto err_i2c;
+               }
+       }
+
        platform_set_drvdata(pdev, madc);
        mutex_init(&madc->lock);
        ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
index eb3b5f88e566c73e6599705649c83ec9b2758f2d..dc757aa14aa4758b3b808c1282adf4a2de84db4e 100644 (file)
@@ -96,8 +96,6 @@ static int twl6030_irq_thread(void *data)
        static const unsigned max_i2c_errors = 100;
        int ret;
 
-       current->flags |= PF_NOFREEZE;
-
        while (!kthread_should_stop()) {
                int i;
                union {
@@ -331,12 +329,6 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 
        /* install an irq handler to demultiplex the TWL6030 interrupt */
        init_completion(&irq_event);
-       task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
-       if (IS_ERR(task)) {
-               pr_err("twl6030: could not create irq %d thread!\n", irq_num);
-               status = PTR_ERR(task);
-               goto fail_kthread;
-       }
 
        status = request_irq(irq_num, handle_twl6030_pih, IRQF_DISABLED,
                                "TWL6030-PIH", &irq_event);
@@ -344,11 +336,19 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
                pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status);
                goto fail_irq;
        }
+
+       task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq");
+       if (IS_ERR(task)) {
+               pr_err("twl6030: could not create irq %d thread!\n", irq_num);
+               status = PTR_ERR(task);
+               goto fail_kthread;
+       }
        return status;
-fail_irq:
-       free_irq(irq_num, &irq_event);
 
 fail_kthread:
+       free_irq(irq_num, &irq_event);
+
+fail_irq:
        for (i = irq_base; i < irq_end; i++)
                irq_set_chip_and_handler(i, NULL, NULL);
        return status;
index 282e76ab678f15c4cb3d792f571f47e04f6fd872..9338f8dcbb83581661793936fceb1a794efff0f2 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
@@ -160,27 +161,350 @@ int wm831x_reg_unlock(struct wm831x *wm831x)
 }
 EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
 
-static int wm831x_read(struct wm831x *wm831x, unsigned short reg,
-                      int bytes, void *dest)
+static bool wm831x_reg_readable(struct device *dev, unsigned int reg)
 {
-       int ret, i;
-       u16 *buf = dest;
-
-       BUG_ON(bytes % 2);
-       BUG_ON(bytes <= 0);
+       switch (reg) {
+       case WM831X_RESET_ID:
+       case WM831X_REVISION:
+       case WM831X_PARENT_ID:
+       case WM831X_SYSVDD_CONTROL:
+       case WM831X_THERMAL_MONITORING:
+       case WM831X_POWER_STATE:
+       case WM831X_WATCHDOG:
+       case WM831X_ON_PIN_CONTROL:
+       case WM831X_RESET_CONTROL:
+       case WM831X_CONTROL_INTERFACE:
+       case WM831X_SECURITY_KEY:
+       case WM831X_SOFTWARE_SCRATCH:
+       case WM831X_OTP_CONTROL:
+       case WM831X_GPIO_LEVEL:
+       case WM831X_SYSTEM_STATUS:
+       case WM831X_ON_SOURCE:
+       case WM831X_OFF_SOURCE:
+       case WM831X_SYSTEM_INTERRUPTS:
+       case WM831X_INTERRUPT_STATUS_1:
+       case WM831X_INTERRUPT_STATUS_2:
+       case WM831X_INTERRUPT_STATUS_3:
+       case WM831X_INTERRUPT_STATUS_4:
+       case WM831X_INTERRUPT_STATUS_5:
+       case WM831X_IRQ_CONFIG:
+       case WM831X_SYSTEM_INTERRUPTS_MASK:
+       case WM831X_INTERRUPT_STATUS_1_MASK:
+       case WM831X_INTERRUPT_STATUS_2_MASK:
+       case WM831X_INTERRUPT_STATUS_3_MASK:
+       case WM831X_INTERRUPT_STATUS_4_MASK:
+       case WM831X_INTERRUPT_STATUS_5_MASK:
+       case WM831X_RTC_WRITE_COUNTER:
+       case WM831X_RTC_TIME_1:
+       case WM831X_RTC_TIME_2:
+       case WM831X_RTC_ALARM_1:
+       case WM831X_RTC_ALARM_2:
+       case WM831X_RTC_CONTROL:
+       case WM831X_RTC_TRIM:
+       case WM831X_TOUCH_CONTROL_1:
+       case WM831X_TOUCH_CONTROL_2:
+       case WM831X_TOUCH_DATA_X:
+       case WM831X_TOUCH_DATA_Y:
+       case WM831X_TOUCH_DATA_Z:
+       case WM831X_AUXADC_DATA:
+       case WM831X_AUXADC_CONTROL:
+       case WM831X_AUXADC_SOURCE:
+       case WM831X_COMPARATOR_CONTROL:
+       case WM831X_COMPARATOR_1:
+       case WM831X_COMPARATOR_2:
+       case WM831X_COMPARATOR_3:
+       case WM831X_COMPARATOR_4:
+       case WM831X_GPIO1_CONTROL:
+       case WM831X_GPIO2_CONTROL:
+       case WM831X_GPIO3_CONTROL:
+       case WM831X_GPIO4_CONTROL:
+       case WM831X_GPIO5_CONTROL:
+       case WM831X_GPIO6_CONTROL:
+       case WM831X_GPIO7_CONTROL:
+       case WM831X_GPIO8_CONTROL:
+       case WM831X_GPIO9_CONTROL:
+       case WM831X_GPIO10_CONTROL:
+       case WM831X_GPIO11_CONTROL:
+       case WM831X_GPIO12_CONTROL:
+       case WM831X_GPIO13_CONTROL:
+       case WM831X_GPIO14_CONTROL:
+       case WM831X_GPIO15_CONTROL:
+       case WM831X_GPIO16_CONTROL:
+       case WM831X_CHARGER_CONTROL_1:
+       case WM831X_CHARGER_CONTROL_2:
+       case WM831X_CHARGER_STATUS:
+       case WM831X_BACKUP_CHARGER_CONTROL:
+       case WM831X_STATUS_LED_1:
+       case WM831X_STATUS_LED_2:
+       case WM831X_CURRENT_SINK_1:
+       case WM831X_CURRENT_SINK_2:
+       case WM831X_DCDC_ENABLE:
+       case WM831X_LDO_ENABLE:
+       case WM831X_DCDC_STATUS:
+       case WM831X_LDO_STATUS:
+       case WM831X_DCDC_UV_STATUS:
+       case WM831X_LDO_UV_STATUS:
+       case WM831X_DC1_CONTROL_1:
+       case WM831X_DC1_CONTROL_2:
+       case WM831X_DC1_ON_CONFIG:
+       case WM831X_DC1_SLEEP_CONTROL:
+       case WM831X_DC1_DVS_CONTROL:
+       case WM831X_DC2_CONTROL_1:
+       case WM831X_DC2_CONTROL_2:
+       case WM831X_DC2_ON_CONFIG:
+       case WM831X_DC2_SLEEP_CONTROL:
+       case WM831X_DC2_DVS_CONTROL:
+       case WM831X_DC3_CONTROL_1:
+       case WM831X_DC3_CONTROL_2:
+       case WM831X_DC3_ON_CONFIG:
+       case WM831X_DC3_SLEEP_CONTROL:
+       case WM831X_DC4_CONTROL:
+       case WM831X_DC4_SLEEP_CONTROL:
+       case WM831X_EPE1_CONTROL:
+       case WM831X_EPE2_CONTROL:
+       case WM831X_LDO1_CONTROL:
+       case WM831X_LDO1_ON_CONTROL:
+       case WM831X_LDO1_SLEEP_CONTROL:
+       case WM831X_LDO2_CONTROL:
+       case WM831X_LDO2_ON_CONTROL:
+       case WM831X_LDO2_SLEEP_CONTROL:
+       case WM831X_LDO3_CONTROL:
+       case WM831X_LDO3_ON_CONTROL:
+       case WM831X_LDO3_SLEEP_CONTROL:
+       case WM831X_LDO4_CONTROL:
+       case WM831X_LDO4_ON_CONTROL:
+       case WM831X_LDO4_SLEEP_CONTROL:
+       case WM831X_LDO5_CONTROL:
+       case WM831X_LDO5_ON_CONTROL:
+       case WM831X_LDO5_SLEEP_CONTROL:
+       case WM831X_LDO6_CONTROL:
+       case WM831X_LDO6_ON_CONTROL:
+       case WM831X_LDO6_SLEEP_CONTROL:
+       case WM831X_LDO7_CONTROL:
+       case WM831X_LDO7_ON_CONTROL:
+       case WM831X_LDO7_SLEEP_CONTROL:
+       case WM831X_LDO8_CONTROL:
+       case WM831X_LDO8_ON_CONTROL:
+       case WM831X_LDO8_SLEEP_CONTROL:
+       case WM831X_LDO9_CONTROL:
+       case WM831X_LDO9_ON_CONTROL:
+       case WM831X_LDO9_SLEEP_CONTROL:
+       case WM831X_LDO10_CONTROL:
+       case WM831X_LDO10_ON_CONTROL:
+       case WM831X_LDO10_SLEEP_CONTROL:
+       case WM831X_LDO11_ON_CONTROL:
+       case WM831X_LDO11_SLEEP_CONTROL:
+       case WM831X_POWER_GOOD_SOURCE_1:
+       case WM831X_POWER_GOOD_SOURCE_2:
+       case WM831X_CLOCK_CONTROL_1:
+       case WM831X_CLOCK_CONTROL_2:
+       case WM831X_FLL_CONTROL_1:
+       case WM831X_FLL_CONTROL_2:
+       case WM831X_FLL_CONTROL_3:
+       case WM831X_FLL_CONTROL_4:
+       case WM831X_FLL_CONTROL_5:
+       case WM831X_UNIQUE_ID_1:
+       case WM831X_UNIQUE_ID_2:
+       case WM831X_UNIQUE_ID_3:
+       case WM831X_UNIQUE_ID_4:
+       case WM831X_UNIQUE_ID_5:
+       case WM831X_UNIQUE_ID_6:
+       case WM831X_UNIQUE_ID_7:
+       case WM831X_UNIQUE_ID_8:
+       case WM831X_FACTORY_OTP_ID:
+       case WM831X_FACTORY_OTP_1:
+       case WM831X_FACTORY_OTP_2:
+       case WM831X_FACTORY_OTP_3:
+       case WM831X_FACTORY_OTP_4:
+       case WM831X_FACTORY_OTP_5:
+       case WM831X_CUSTOMER_OTP_ID:
+       case WM831X_DC1_OTP_CONTROL:
+       case WM831X_DC2_OTP_CONTROL:
+       case WM831X_DC3_OTP_CONTROL:
+       case WM831X_LDO1_2_OTP_CONTROL:
+       case WM831X_LDO3_4_OTP_CONTROL:
+       case WM831X_LDO5_6_OTP_CONTROL:
+       case WM831X_LDO7_8_OTP_CONTROL:
+       case WM831X_LDO9_10_OTP_CONTROL:
+       case WM831X_LDO11_EPE_CONTROL:
+       case WM831X_GPIO1_OTP_CONTROL:
+       case WM831X_GPIO2_OTP_CONTROL:
+       case WM831X_GPIO3_OTP_CONTROL:
+       case WM831X_GPIO4_OTP_CONTROL:
+       case WM831X_GPIO5_OTP_CONTROL:
+       case WM831X_GPIO6_OTP_CONTROL:
+       case WM831X_DBE_CHECK_DATA:
+               return true;
+       default:
+               return false;
+       }
+}
 
-       ret = wm831x->read_dev(wm831x, reg, bytes, dest);
-       if (ret < 0)
-               return ret;
+static bool wm831x_reg_writeable(struct device *dev, unsigned int reg)
+{
+       struct wm831x *wm831x = dev_get_drvdata(dev);
 
-       for (i = 0; i < bytes / 2; i++) {
-               buf[i] = be16_to_cpu(buf[i]);
+       if (wm831x_reg_locked(wm831x, reg))
+               return false;
 
-               dev_vdbg(wm831x->dev, "Read %04x from R%d(0x%x)\n",
-                        buf[i], reg + i, reg + i);
+       switch (reg) {
+       case WM831X_SYSVDD_CONTROL:
+       case WM831X_THERMAL_MONITORING:
+       case WM831X_POWER_STATE:
+       case WM831X_WATCHDOG:
+       case WM831X_ON_PIN_CONTROL:
+       case WM831X_RESET_CONTROL:
+       case WM831X_CONTROL_INTERFACE:
+       case WM831X_SECURITY_KEY:
+       case WM831X_SOFTWARE_SCRATCH:
+       case WM831X_OTP_CONTROL:
+       case WM831X_GPIO_LEVEL:
+       case WM831X_INTERRUPT_STATUS_1:
+       case WM831X_INTERRUPT_STATUS_2:
+       case WM831X_INTERRUPT_STATUS_3:
+       case WM831X_INTERRUPT_STATUS_4:
+       case WM831X_INTERRUPT_STATUS_5:
+       case WM831X_IRQ_CONFIG:
+       case WM831X_SYSTEM_INTERRUPTS_MASK:
+       case WM831X_INTERRUPT_STATUS_1_MASK:
+       case WM831X_INTERRUPT_STATUS_2_MASK:
+       case WM831X_INTERRUPT_STATUS_3_MASK:
+       case WM831X_INTERRUPT_STATUS_4_MASK:
+       case WM831X_INTERRUPT_STATUS_5_MASK:
+       case WM831X_RTC_TIME_1:
+       case WM831X_RTC_TIME_2:
+       case WM831X_RTC_ALARM_1:
+       case WM831X_RTC_ALARM_2:
+       case WM831X_RTC_CONTROL:
+       case WM831X_RTC_TRIM:
+       case WM831X_TOUCH_CONTROL_1:
+       case WM831X_TOUCH_CONTROL_2:
+       case WM831X_AUXADC_CONTROL:
+       case WM831X_AUXADC_SOURCE:
+       case WM831X_COMPARATOR_CONTROL:
+       case WM831X_COMPARATOR_1:
+       case WM831X_COMPARATOR_2:
+       case WM831X_COMPARATOR_3:
+       case WM831X_COMPARATOR_4:
+       case WM831X_GPIO1_CONTROL:
+       case WM831X_GPIO2_CONTROL:
+       case WM831X_GPIO3_CONTROL:
+       case WM831X_GPIO4_CONTROL:
+       case WM831X_GPIO5_CONTROL:
+       case WM831X_GPIO6_CONTROL:
+       case WM831X_GPIO7_CONTROL:
+       case WM831X_GPIO8_CONTROL:
+       case WM831X_GPIO9_CONTROL:
+       case WM831X_GPIO10_CONTROL:
+       case WM831X_GPIO11_CONTROL:
+       case WM831X_GPIO12_CONTROL:
+       case WM831X_GPIO13_CONTROL:
+       case WM831X_GPIO14_CONTROL:
+       case WM831X_GPIO15_CONTROL:
+       case WM831X_GPIO16_CONTROL:
+       case WM831X_CHARGER_CONTROL_1:
+       case WM831X_CHARGER_CONTROL_2:
+       case WM831X_CHARGER_STATUS:
+       case WM831X_BACKUP_CHARGER_CONTROL:
+       case WM831X_STATUS_LED_1:
+       case WM831X_STATUS_LED_2:
+       case WM831X_CURRENT_SINK_1:
+       case WM831X_CURRENT_SINK_2:
+       case WM831X_DCDC_ENABLE:
+       case WM831X_LDO_ENABLE:
+       case WM831X_DC1_CONTROL_1:
+       case WM831X_DC1_CONTROL_2:
+       case WM831X_DC1_ON_CONFIG:
+       case WM831X_DC1_SLEEP_CONTROL:
+       case WM831X_DC1_DVS_CONTROL:
+       case WM831X_DC2_CONTROL_1:
+       case WM831X_DC2_CONTROL_2:
+       case WM831X_DC2_ON_CONFIG:
+       case WM831X_DC2_SLEEP_CONTROL:
+       case WM831X_DC2_DVS_CONTROL:
+       case WM831X_DC3_CONTROL_1:
+       case WM831X_DC3_CONTROL_2:
+       case WM831X_DC3_ON_CONFIG:
+       case WM831X_DC3_SLEEP_CONTROL:
+       case WM831X_DC4_CONTROL:
+       case WM831X_DC4_SLEEP_CONTROL:
+       case WM831X_EPE1_CONTROL:
+       case WM831X_EPE2_CONTROL:
+       case WM831X_LDO1_CONTROL:
+       case WM831X_LDO1_ON_CONTROL:
+       case WM831X_LDO1_SLEEP_CONTROL:
+       case WM831X_LDO2_CONTROL:
+       case WM831X_LDO2_ON_CONTROL:
+       case WM831X_LDO2_SLEEP_CONTROL:
+       case WM831X_LDO3_CONTROL:
+       case WM831X_LDO3_ON_CONTROL:
+       case WM831X_LDO3_SLEEP_CONTROL:
+       case WM831X_LDO4_CONTROL:
+       case WM831X_LDO4_ON_CONTROL:
+       case WM831X_LDO4_SLEEP_CONTROL:
+       case WM831X_LDO5_CONTROL:
+       case WM831X_LDO5_ON_CONTROL:
+       case WM831X_LDO5_SLEEP_CONTROL:
+       case WM831X_LDO6_CONTROL:
+       case WM831X_LDO6_ON_CONTROL:
+       case WM831X_LDO6_SLEEP_CONTROL:
+       case WM831X_LDO7_CONTROL:
+       case WM831X_LDO7_ON_CONTROL:
+       case WM831X_LDO7_SLEEP_CONTROL:
+       case WM831X_LDO8_CONTROL:
+       case WM831X_LDO8_ON_CONTROL:
+       case WM831X_LDO8_SLEEP_CONTROL:
+       case WM831X_LDO9_CONTROL:
+       case WM831X_LDO9_ON_CONTROL:
+       case WM831X_LDO9_SLEEP_CONTROL:
+       case WM831X_LDO10_CONTROL:
+       case WM831X_LDO10_ON_CONTROL:
+       case WM831X_LDO10_SLEEP_CONTROL:
+       case WM831X_LDO11_ON_CONTROL:
+       case WM831X_LDO11_SLEEP_CONTROL:
+       case WM831X_POWER_GOOD_SOURCE_1:
+       case WM831X_POWER_GOOD_SOURCE_2:
+       case WM831X_CLOCK_CONTROL_1:
+       case WM831X_CLOCK_CONTROL_2:
+       case WM831X_FLL_CONTROL_1:
+       case WM831X_FLL_CONTROL_2:
+       case WM831X_FLL_CONTROL_3:
+       case WM831X_FLL_CONTROL_4:
+       case WM831X_FLL_CONTROL_5:
+               return true;
+       default:
+               return false;
        }
+}
 
-       return 0;
+static bool wm831x_reg_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case WM831X_SYSTEM_STATUS:
+       case WM831X_ON_SOURCE:
+       case WM831X_OFF_SOURCE:
+       case WM831X_GPIO_LEVEL:
+       case WM831X_SYSTEM_INTERRUPTS:
+       case WM831X_INTERRUPT_STATUS_1:
+       case WM831X_INTERRUPT_STATUS_2:
+       case WM831X_INTERRUPT_STATUS_3:
+       case WM831X_INTERRUPT_STATUS_4:
+       case WM831X_INTERRUPT_STATUS_5:
+       case WM831X_RTC_TIME_1:
+       case WM831X_RTC_TIME_2:
+       case WM831X_TOUCH_DATA_X:
+       case WM831X_TOUCH_DATA_Y:
+       case WM831X_TOUCH_DATA_Z:
+       case WM831X_AUXADC_DATA:
+       case WM831X_CHARGER_STATUS:
+       case WM831X_DCDC_STATUS:
+       case WM831X_LDO_STATUS:
+       case WM831X_DCDC_UV_STATUS:
+       case WM831X_LDO_UV_STATUS:
+               return true;
+       default:
+               return false;
+       }
 }
 
 /**
@@ -191,14 +515,10 @@ static int wm831x_read(struct wm831x *wm831x, unsigned short reg,
  */
 int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
 {
-       unsigned short val;
+       unsigned int val;
        int ret;
 
-       mutex_lock(&wm831x->io_lock);
-
-       ret = wm831x_read(wm831x, reg, 2, &val);
-
-       mutex_unlock(&wm831x->io_lock);
+       ret = regmap_read(wm831x->regmap, reg, &val);
 
        if (ret < 0)
                return ret;
@@ -218,15 +538,7 @@ EXPORT_SYMBOL_GPL(wm831x_reg_read);
 int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
                     int count, u16 *buf)
 {
-       int ret;
-
-       mutex_lock(&wm831x->io_lock);
-
-       ret = wm831x_read(wm831x, reg, count * 2, buf);
-
-       mutex_unlock(&wm831x->io_lock);
-
-       return ret;
+       return regmap_bulk_read(wm831x->regmap, reg, buf, count);
 }
 EXPORT_SYMBOL_GPL(wm831x_bulk_read);
 
@@ -234,7 +546,7 @@ static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
                        int bytes, void *src)
 {
        u16 *buf = src;
-       int i;
+       int i, ret;
 
        BUG_ON(bytes % 2);
        BUG_ON(bytes <= 0);
@@ -245,11 +557,10 @@ static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
 
                dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
                         buf[i], reg + i, reg + i);
-
-               buf[i] = cpu_to_be16(buf[i]);
+               ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
        }
 
-       return wm831x->write_dev(wm831x, reg, bytes, src);
+       return 0;
 }
 
 /**
@@ -286,20 +597,14 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
                    unsigned short mask, unsigned short val)
 {
        int ret;
-       u16 r;
 
        mutex_lock(&wm831x->io_lock);
 
-       ret = wm831x_read(wm831x, reg, 2, &r);
-       if (ret < 0)
-               goto out;
-
-       r &= ~mask;
-       r |= val & mask;
-
-       ret = wm831x_write(wm831x, reg, 2, &r);
+       if (!wm831x_reg_locked(wm831x, reg))
+               ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
+       else
+               ret = -EPERM;
 
-out:
        mutex_unlock(&wm831x->io_lock);
 
        return ret;
@@ -1292,6 +1597,17 @@ static struct mfd_cell backlight_devs[] = {
        },
 };
 
+struct regmap_config wm831x_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 16,
+
+       .max_register = WM831X_DBE_CHECK_DATA,
+       .readable_reg = wm831x_reg_readable,
+       .writeable_reg = wm831x_reg_writeable,
+       .volatile_reg = wm831x_reg_volatile,
+};
+EXPORT_SYMBOL_GPL(wm831x_regmap_config);
+
 /*
  * Instantiate the generic non-control parts of the device.
  */
@@ -1309,7 +1625,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
        switch (ret) {
        case 0x6204:
@@ -1318,20 +1634,20 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        default:
                dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
                ret = -EINVAL;
-               goto err;
+               goto err_regmap;
        }
 
        ret = wm831x_reg_read(wm831x, WM831X_REVISION);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
        rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
 
        ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
 
        /* Some engineering samples do not have the ID set, rely on
@@ -1406,7 +1722,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        default:
                dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
                ret = -EINVAL;
-               goto err;
+               goto err_regmap;
        }
 
        /* This will need revisiting in future but is OK for all
@@ -1420,7 +1736,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
        if (ret < 0) {
                dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
        if (ret != 0) {
                dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
@@ -1433,7 +1749,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
                ret = pdata->pre_init(wm831x);
                if (ret != 0) {
                        dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
-                       goto err;
+                       goto err_regmap;
                }
        }
 
@@ -1456,7 +1772,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 
        ret = wm831x_irq_init(wm831x, irq);
        if (ret != 0)
-               goto err;
+               goto err_regmap;
 
        wm831x_auxadc_init(wm831x);
 
@@ -1552,8 +1868,9 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 
 err_irq:
        wm831x_irq_exit(wm831x);
-err:
+err_regmap:
        mfd_remove_devices(wm831x->dev);
+       regmap_exit(wm831x->regmap);
        kfree(wm831x);
        return ret;
 }
@@ -1565,6 +1882,7 @@ void wm831x_device_exit(struct wm831x *wm831x)
        if (wm831x->irq_base)
                free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
        wm831x_irq_exit(wm831x);
+       regmap_exit(wm831x->regmap);
        kfree(wm831x);
 }
 
index a06cbc739716c25c57ae872f90c2ba9cc6fa506d..3ec6085d5fc061cd0c42fdeac507b51c6e53cd64 100644 (file)
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/regmap.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
 
-static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
-                                 int bytes, void *dest)
-{
-       struct i2c_client *i2c = wm831x->control_data;
-       int ret;
-       u16 r = cpu_to_be16(reg);
-
-       ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
-       if (ret < 0)
-               return ret;
-       if (ret != 2)
-               return -EIO;
-
-       ret = i2c_master_recv(i2c, dest, bytes);
-       if (ret < 0)
-               return ret;
-       if (ret != bytes)
-               return -EIO;
-       return 0;
-}
-
-/* Currently we allocate the write buffer on the stack; this is OK for
- * small writes - if we need to do large writes this will need to be
- * revised.
- */
-static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
-                                  int bytes, void *src)
-{
-       struct i2c_client *i2c = wm831x->control_data;
-       struct i2c_msg xfer[2];
-       int ret;
-
-       reg = cpu_to_be16(reg);
-
-       xfer[0].addr = i2c->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = 2;
-       xfer[0].buf = (char *)&reg;
-
-       xfer[1].addr = i2c->addr;
-       xfer[1].flags = I2C_M_NOSTART;
-       xfer[1].len = bytes;
-       xfer[1].buf = (char *)src;
-
-       ret = i2c_transfer(i2c->adapter, xfer, 2);
-       if (ret < 0)
-               return ret;
-       if (ret != 2)
-               return -EIO;
-
-       return 0;
-}
-
 static int wm831x_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm831x *wm831x;
+       int ret;
 
        wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
        if (wm831x == NULL)
@@ -86,9 +36,15 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm831x);
        wm831x->dev = &i2c->dev;
-       wm831x->control_data = i2c;
-       wm831x->read_dev = wm831x_i2c_read_device;
-       wm831x->write_dev = wm831x_i2c_write_device;
+
+       wm831x->regmap = regmap_init_i2c(i2c, &wm831x_regmap_config);
+       if (IS_ERR(wm831x->regmap)) {
+               ret = PTR_ERR(wm831x->regmap);
+               dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               kfree(wm831x);
+               return ret;
+       }
 
        return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
 }
index ada1835a54557b31424dc1f93297ffdb45b71a9a..a10937cfff4cdba3b92249ec93e69ea42b01058f 100644 (file)
@@ -596,8 +596,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
                         "No interrupt specified - functionality limited\n");
        }
 
-
-
        /* Enable top level interrupts, we mask at secondary level */
        wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
 
index eed8e4f7a5a14c6c724097567f1b817419dba3a9..5ea60cd860fc8911b01773df189ee24ad3aa38c7 100644 (file)
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
 
 #include <linux/mfd/wm831x/core.h>
 
-static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
-                                 int bytes, void *dest)
-{
-       u16 tx_val;
-       u16 *d = dest;
-       int r, ret;
-
-       /* Go register at a time */
-       for (r = reg; r < reg + (bytes / 2); r++) {
-               tx_val = r | 0x8000;
-
-               ret = spi_write_then_read(wm831x->control_data,
-                                         (u8 *)&tx_val, 2, (u8 *)d, 2);
-               if (ret != 0)
-                       return ret;
-
-               *d = be16_to_cpu(*d);
-
-               d++;
-       }
-
-       return 0;
-}
-
-static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
-                                  int bytes, void *src)
-{
-       struct spi_device *spi = wm831x->control_data;
-       u16 *s = src;
-       u16 data[2];
-       int ret, r;
-
-       /* Go register at a time */
-       for (r = reg; r < reg + (bytes / 2); r++) {
-               data[0] = r;
-               data[1] = *s++;
-
-               ret = spi_write(spi, (char *)&data, sizeof(data));
-               if (ret != 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
 static int __devinit wm831x_spi_probe(struct spi_device *spi)
 {
+       const struct spi_device_id *id = spi_get_device_id(spi);
        struct wm831x *wm831x;
        enum wm831x_parent type;
+       int ret;
 
-       /* Currently SPI support for ID tables is unmerged, we're faking it */
-       if (strcmp(spi->modalias, "wm8310") == 0)
-               type = WM8310;
-       else if (strcmp(spi->modalias, "wm8311") == 0)
-               type = WM8311;
-       else if (strcmp(spi->modalias, "wm8312") == 0)
-               type = WM8312;
-       else if (strcmp(spi->modalias, "wm8320") == 0)
-               type = WM8320;
-       else if (strcmp(spi->modalias, "wm8321") == 0)
-               type = WM8321;
-       else if (strcmp(spi->modalias, "wm8325") == 0)
-               type = WM8325;
-       else if (strcmp(spi->modalias, "wm8326") == 0)
-               type = WM8326;
-       else {
-               dev_err(&spi->dev, "Unknown device type\n");
-               return -EINVAL;
-       }
+       type = (enum wm831x_parent)id->driver_data;
 
        wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
        if (wm831x == NULL)
@@ -98,9 +39,15 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
 
        dev_set_drvdata(&spi->dev, wm831x);
        wm831x->dev = &spi->dev;
-       wm831x->control_data = spi;
-       wm831x->read_dev = wm831x_spi_read_device;
-       wm831x->write_dev = wm831x_spi_write_device;
+
+       wm831x->regmap = regmap_init_spi(spi, &wm831x_regmap_config);
+       if (IS_ERR(wm831x->regmap)) {
+               ret = PTR_ERR(wm831x->regmap);
+               dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               kfree(wm831x);
+               return ret;
+       }
 
        return wm831x_device_init(wm831x, type, spi->irq);
 }
@@ -126,79 +73,26 @@ static const struct dev_pm_ops wm831x_spi_pm = {
        .suspend = wm831x_spi_suspend,
 };
 
-static struct spi_driver wm8310_spi_driver = {
-       .driver = {
-               .name   = "wm8310",
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-               .pm     = &wm831x_spi_pm,
-       },
-       .probe          = wm831x_spi_probe,
-       .remove         = __devexit_p(wm831x_spi_remove),
-};
-
-static struct spi_driver wm8311_spi_driver = {
-       .driver = {
-               .name   = "wm8311",
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-               .pm     = &wm831x_spi_pm,
-       },
-       .probe          = wm831x_spi_probe,
-       .remove         = __devexit_p(wm831x_spi_remove),
-};
-
-static struct spi_driver wm8312_spi_driver = {
-       .driver = {
-               .name   = "wm8312",
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-               .pm     = &wm831x_spi_pm,
-       },
-       .probe          = wm831x_spi_probe,
-       .remove         = __devexit_p(wm831x_spi_remove),
-};
-
-static struct spi_driver wm8320_spi_driver = {
-       .driver = {
-               .name   = "wm8320",
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-               .pm     = &wm831x_spi_pm,
-       },
-       .probe          = wm831x_spi_probe,
-       .remove         = __devexit_p(wm831x_spi_remove),
-};
-
-static struct spi_driver wm8321_spi_driver = {
-       .driver = {
-               .name   = "wm8321",
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-               .pm     = &wm831x_spi_pm,
-       },
-       .probe          = wm831x_spi_probe,
-       .remove         = __devexit_p(wm831x_spi_remove),
+static const struct spi_device_id wm831x_spi_ids[] = {
+       { "wm8310", WM8310 },
+       { "wm8311", WM8311 },
+       { "wm8312", WM8312 },
+       { "wm8320", WM8320 },
+       { "wm8321", WM8321 },
+       { "wm8325", WM8325 },
+       { "wm8326", WM8326 },
+       { },
 };
+MODULE_DEVICE_TABLE(spi, wm831x_spi_id);
 
-static struct spi_driver wm8325_spi_driver = {
+static struct spi_driver wm831x_spi_driver = {
        .driver = {
-               .name   = "wm8325",
-               .bus    = &spi_bus_type,
-               .owner  = THIS_MODULE,
-               .pm     = &wm831x_spi_pm,
-       },
-       .probe          = wm831x_spi_probe,
-       .remove         = __devexit_p(wm831x_spi_remove),
-};
-
-static struct spi_driver wm8326_spi_driver = {
-       .driver = {
-               .name   = "wm8326",
+               .name   = "wm831x",
                .bus    = &spi_bus_type,
                .owner  = THIS_MODULE,
                .pm     = &wm831x_spi_pm,
        },
+       .id_table       = wm831x_spi_ids,
        .probe          = wm831x_spi_probe,
        .remove         = __devexit_p(wm831x_spi_remove),
 };
@@ -207,33 +101,9 @@ static int __init wm831x_spi_init(void)
 {
        int ret;
 
-       ret = spi_register_driver(&wm8310_spi_driver);
-       if (ret != 0)
-               pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
-
-       ret = spi_register_driver(&wm8311_spi_driver);
-       if (ret != 0)
-               pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
-
-       ret = spi_register_driver(&wm8312_spi_driver);
-       if (ret != 0)
-               pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
-
-       ret = spi_register_driver(&wm8320_spi_driver);
-       if (ret != 0)
-               pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
-
-       ret = spi_register_driver(&wm8321_spi_driver);
-       if (ret != 0)
-               pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
-
-       ret = spi_register_driver(&wm8325_spi_driver);
-       if (ret != 0)
-               pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
-
-       ret = spi_register_driver(&wm8326_spi_driver);
+       ret = spi_register_driver(&wm831x_spi_driver);
        if (ret != 0)
-               pr_err("Failed to register WM8326 SPI driver: %d\n", ret);
+               pr_err("Failed to register WM831x SPI driver: %d\n", ret);
 
        return 0;
 }
@@ -241,13 +111,7 @@ subsys_initcall(wm831x_spi_init);
 
 static void __exit wm831x_spi_exit(void)
 {
-       spi_unregister_driver(&wm8326_spi_driver);
-       spi_unregister_driver(&wm8325_spi_driver);
-       spi_unregister_driver(&wm8321_spi_driver);
-       spi_unregister_driver(&wm8320_spi_driver);
-       spi_unregister_driver(&wm8312_spi_driver);
-       spi_unregister_driver(&wm8311_spi_driver);
-       spi_unregister_driver(&wm8310_spi_driver);
+       spi_unregister_driver(&wm831x_spi_driver);
 }
 module_exit(wm831x_spi_exit);
 
index ebf99bef392f67e669bb0cd9c14ea9548c8ddfd8..d584f6b4d6e2dfd8fd982da3954b40e5fe412342 100644 (file)
@@ -37,7 +37,7 @@ static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
        return ret;
 }
 
-static int gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
+static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
 {
        if (db == WM8350_GPIO_DEBOUNCE_ON)
                return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
@@ -210,7 +210,7 @@ int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
                goto err;
        if (gpio_set_polarity(wm8350, gpio, pol))
                goto err;
-       if (gpio_set_debounce(wm8350, gpio, debounce))
+       if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
                goto err;
        if (gpio_set_dir(wm8350, gpio, dir))
                goto err;
index 597f82edacaa8cc010aaa2b3e28d3e5985a17f81..e06ba9440cdbea2c7143b7dcbe9f752e9d47936c 100644 (file)
  */
 
 #include <linux/bug.h>
+#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/wm8400-private.h>
 #include <linux/mfd/wm8400-audio.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
 static struct {
@@ -123,14 +125,9 @@ static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest)
        /* If there are any volatile reads then read back the entire block */
        for (i = reg; i < reg + num_regs; i++)
                if (reg_data[i].vol) {
-                       ret = wm8400->read_dev(wm8400->io_data, reg,
-                                              num_regs, dest);
-                       if (ret != 0)
-                               return ret;
-                       for (i = 0; i < num_regs; i++)
-                               dest[i] = be16_to_cpu(dest[i]);
-
-                       return 0;
+                       ret = regmap_bulk_read(wm8400->regmap, reg, dest,
+                                              num_regs);
+                       return ret;
                }
 
        /* Otherwise use the cache */
@@ -149,14 +146,11 @@ static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs,
        for (i = 0; i < num_regs; i++) {
                BUG_ON(!reg_data[reg + i].writable);
                wm8400->reg_cache[reg + i] = src[i];
-               src[i] = cpu_to_be16(src[i]);
+               ret = regmap_write(wm8400->regmap, reg, src[i]);
+               if (ret != 0)
+                       return ret;
        }
 
-       /* Do the actual I/O */
-       ret = wm8400->write_dev(wm8400->io_data, reg, num_regs, src);
-       if (ret != 0)
-               return -EIO;
-
        return 0;
 }
 
@@ -270,14 +264,14 @@ static int wm8400_init(struct wm8400 *wm8400,
        dev_set_drvdata(wm8400->dev, wm8400);
 
        /* Check that this is actually a WM8400 */
-       ret = wm8400->read_dev(wm8400->io_data, WM8400_RESET_ID, 1, &reg);
+       ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, &i);
        if (ret != 0) {
                dev_err(wm8400->dev, "Chip ID register read failed\n");
                return -EIO;
        }
-       if (be16_to_cpu(reg) != reg_data[WM8400_RESET_ID].default_val) {
+       if (i != reg_data[WM8400_RESET_ID].default_val) {
                dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n",
-                       be16_to_cpu(reg));
+                       reg);
                return -ENODEV;
        }
 
@@ -285,9 +279,8 @@ static int wm8400_init(struct wm8400 *wm8400,
         * is a PMIC we can't reset it safely so initialise the register
         * cache from the hardware.
         */
-       ret = wm8400->read_dev(wm8400->io_data, 0,
-                              ARRAY_SIZE(wm8400->reg_cache),
-                              wm8400->reg_cache);
+       ret = regmap_raw_read(wm8400->regmap, 0, wm8400->reg_cache,
+                             ARRAY_SIZE(wm8400->reg_cache));
        if (ret != 0) {
                dev_err(wm8400->dev, "Register cache read failed\n");
                return -EIO;
@@ -337,60 +330,13 @@ static void wm8400_release(struct wm8400 *wm8400)
        mfd_remove_devices(wm8400->dev);
 }
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static int wm8400_i2c_read(void *io_data, char reg, int count, u16 *dest)
-{
-       struct i2c_client *i2c = io_data;
-       struct i2c_msg xfer[2];
-       int ret;
-
-       /* Write register */
-       xfer[0].addr = i2c->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = 1;
-       xfer[0].buf = &reg;
-
-       /* Read data */
-       xfer[1].addr = i2c->addr;
-       xfer[1].flags = I2C_M_RD;
-       xfer[1].len = count * sizeof(u16);
-       xfer[1].buf = (u8 *)dest;
-
-       ret = i2c_transfer(i2c->adapter, xfer, 2);
-       if (ret == 2)
-               ret = 0;
-       else if (ret >= 0)
-               ret = -EIO;
-
-       return ret;
-}
-
-static int wm8400_i2c_write(void *io_data, char reg, int count, const u16 *src)
-{
-       struct i2c_client *i2c = io_data;
-       u8 *msg;
-       int ret;
-
-       /* We add 1 byte for device register - ideally I2C would gather. */
-       msg = kmalloc((count * sizeof(u16)) + 1, GFP_KERNEL);
-       if (msg == NULL)
-               return -ENOMEM;
-
-       msg[0] = reg;
-       memcpy(&msg[1], src, count * sizeof(u16));
-
-       ret = i2c_master_send(i2c, msg, (count * sizeof(u16)) + 1);
-
-       if (ret == (count * 2) + 1)
-               ret = 0;
-       else if (ret >= 0)
-               ret = -EIO;
-
-       kfree(msg);
-
-       return ret;
-}
+static const struct regmap_config wm8400_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 16,
+       .max_register = WM8400_REGISTER_COUNT - 1,
+};
 
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static int wm8400_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -403,18 +349,23 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
                goto err;
        }
 
-       wm8400->io_data = i2c;
-       wm8400->read_dev = wm8400_i2c_read;
-       wm8400->write_dev = wm8400_i2c_write;
+       wm8400->regmap = regmap_init_i2c(i2c, &wm8400_regmap_config);
+       if (IS_ERR(wm8400->regmap)) {
+               ret = PTR_ERR(wm8400->regmap);
+               goto struct_err;
+       }
+
        wm8400->dev = &i2c->dev;
        i2c_set_clientdata(i2c, wm8400);
 
        ret = wm8400_init(wm8400, i2c->dev.platform_data);
        if (ret != 0)
-               goto struct_err;
+               goto map_err;
 
        return 0;
 
+map_err:
+       regmap_exit(wm8400->regmap);
 struct_err:
        kfree(wm8400);
 err:
@@ -426,6 +377,7 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
        struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
 
        wm8400_release(wm8400);
+       regmap_exit(wm8400->regmap);
        kfree(wm8400);
 
        return 0;
index 96479c9b1728918e8672a6aa9d03847365594263..719fee8ec0d5d6e3904cadb86e1f5c7dca928520 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/pm_runtime.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/machine.h>
 
 static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
                       int bytes, void *dest)
 {
-       int ret, i;
-       u16 *buf = dest;
-
-       BUG_ON(bytes % 2);
-       BUG_ON(bytes <= 0);
-
-       ret = wm8994->read_dev(wm8994, reg, bytes, dest);
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < bytes / 2; i++) {
-               dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
-                        be16_to_cpu(buf[i]), reg + i, reg + i);
-       }
-
-       return 0;
+       return regmap_raw_read(wm8994->regmap, reg, dest, bytes);
 }
 
 /**
@@ -55,19 +42,15 @@ static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
  */
 int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
 {
-       unsigned short val;
+       unsigned int val;
        int ret;
 
-       mutex_lock(&wm8994->io_lock);
-
-       ret = wm8994_read(wm8994, reg, 2, &val);
-
-       mutex_unlock(&wm8994->io_lock);
+       ret = regmap_read(wm8994->regmap, reg, &val);
 
        if (ret < 0)
                return ret;
        else
-               return be16_to_cpu(val);
+               return val;
 }
 EXPORT_SYMBOL_GPL(wm8994_reg_read);
 
@@ -82,33 +65,13 @@ EXPORT_SYMBOL_GPL(wm8994_reg_read);
 int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
                     int count, u16 *buf)
 {
-       int ret;
-
-       mutex_lock(&wm8994->io_lock);
-
-       ret = wm8994_read(wm8994, reg, count * 2, buf);
-
-       mutex_unlock(&wm8994->io_lock);
-
-       return ret;
+       return regmap_bulk_read(wm8994->regmap, reg, buf, count);
 }
-EXPORT_SYMBOL_GPL(wm8994_bulk_read);
 
 static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
                        int bytes, const void *src)
 {
-       const u16 *buf = src;
-       int i;
-
-       BUG_ON(bytes % 2);
-       BUG_ON(bytes <= 0);
-
-       for (i = 0; i < bytes / 2; i++) {
-               dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
-                        be16_to_cpu(buf[i]), reg + i, reg + i);
-       }
-
-       return wm8994->write_dev(wm8994, reg, bytes, src);
+       return regmap_raw_write(wm8994->regmap, reg, src, bytes);
 }
 
 /**
@@ -121,17 +84,7 @@ static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
 int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
                     unsigned short val)
 {
-       int ret;
-
-       val = cpu_to_be16(val);
-
-       mutex_lock(&wm8994->io_lock);
-
-       ret = wm8994_write(wm8994, reg, 2, &val);
-
-       mutex_unlock(&wm8994->io_lock);
-
-       return ret;
+       return regmap_write(wm8994->regmap, reg, val);
 }
 EXPORT_SYMBOL_GPL(wm8994_reg_write);
 
@@ -146,15 +99,7 @@ EXPORT_SYMBOL_GPL(wm8994_reg_write);
 int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
                      int count, const u16 *buf)
 {
-       int ret;
-
-       mutex_lock(&wm8994->io_lock);
-
-       ret = wm8994_write(wm8994, reg, count * 2, buf);
-
-       mutex_unlock(&wm8994->io_lock);
-
-       return ret;
+       return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16));
 }
 EXPORT_SYMBOL_GPL(wm8994_bulk_write);
 
@@ -169,28 +114,7 @@ EXPORT_SYMBOL_GPL(wm8994_bulk_write);
 int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
                    unsigned short mask, unsigned short val)
 {
-       int ret;
-       u16 r;
-
-       mutex_lock(&wm8994->io_lock);
-
-       ret = wm8994_read(wm8994, reg, 2, &r);
-       if (ret < 0)
-               goto out;
-
-       r = be16_to_cpu(r);
-
-       r &= ~mask;
-       r |= val;
-
-       r = cpu_to_be16(r);
-
-       ret = wm8994_write(wm8994, reg, 2, &r);
-
-out:
-       mutex_unlock(&wm8994->io_lock);
-
-       return ret;
+       return regmap_update_bits(wm8994->regmap, reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(wm8994_set_bits);
 
@@ -281,6 +205,47 @@ static int wm8994_suspend(struct device *dev)
                return 0;
        }
 
+       ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read power status: %d\n", ret);
+       } else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA |
+                         WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA |
+                         WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) {
+               dev_dbg(dev, "CODEC still active, ignoring suspend\n");
+               return 0;
+       }
+
+       ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read power status: %d\n", ret);
+       } else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+                         WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA |
+                         WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) {
+               dev_dbg(dev, "CODEC still active, ignoring suspend\n");
+               return 0;
+       }
+
+       switch (wm8994->type) {
+       case WM8958:
+               ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to read power status: %d\n", ret);
+               } else if (ret & WM8958_MICD_ENA) {
+                       dev_dbg(dev, "CODEC still active, ignoring suspend\n");
+                       return 0;
+               }
+               break;
+       default:
+               break;
+       }
+
+       /* Disable LDO pulldowns while the device is suspended if we
+        * don't know that something will be driving them. */
+       if (!wm8994->ldo_ena_always_driven)
+               wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+                               WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
+                               WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
+
        /* GPIO configuration state is saved here since we may be configuring
         * the GPIO alternate functions even if we're not using the gpiolib
         * driver for them.
@@ -350,6 +315,11 @@ static int wm8994_resume(struct device *dev)
        if (ret < 0)
                dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
 
+       /* Disable LDO pulldowns while the device is active */
+       wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+                       WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
+                       0);
+
        wm8994->suspended = false;
 
        return 0;
@@ -378,6 +348,11 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
 }
 #endif
 
+static struct regmap_config wm8994_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 16,
+};
+
 /*
  * Instantiate the generic non-control parts of the device.
  */
@@ -387,7 +362,6 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
        const char *devname;
        int ret, i;
 
-       mutex_init(&wm8994->io_lock);
        dev_set_drvdata(wm8994->dev, wm8994);
 
        /* Add the on-chip regulators first for bootstrapping */
@@ -397,7 +371,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                              NULL, 0);
        if (ret != 0) {
                dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
-               goto err;
+               goto err_regmap;
        }
 
        switch (wm8994->type) {
@@ -409,7 +383,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                break;
        default:
                BUG();
-               goto err;
+               goto err_regmap;
        }
 
        wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
@@ -417,7 +391,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                                   GFP_KERNEL);
        if (!wm8994->supplies) {
                ret = -ENOMEM;
-               goto err;
+               goto err_regmap;
        }
 
        switch (wm8994->type) {
@@ -431,7 +405,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                break;
        default:
                BUG();
-               goto err;
+               goto err_regmap;
        }
                
        ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
@@ -513,8 +487,15 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                                                pdata->gpio_defaults[i]);
                        }
                }
+
+               wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
        }
 
+       /* Disable LDO pulldowns while the device is active */
+       wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
+                       WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
+                       0);
+
        /* In some system designs where the regulators are not in use,
         * we can achieve a small reduction in leakage currents by
         * floating LDO outputs.  This bit makes no difference if the
@@ -554,7 +535,8 @@ err_get:
        regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
 err_supplies:
        kfree(wm8994->supplies);
-err:
+err_regmap:
+       regmap_exit(wm8994->regmap);
        mfd_remove_devices(wm8994->dev);
        kfree(wm8994);
        return ret;
@@ -569,62 +551,15 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
                               wm8994->supplies);
        regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
        kfree(wm8994->supplies);
+       regmap_exit(wm8994->regmap);
        kfree(wm8994);
 }
 
-static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
-                                 int bytes, void *dest)
-{
-       struct i2c_client *i2c = wm8994->control_data;
-       int ret;
-       u16 r = cpu_to_be16(reg);
-
-       ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
-       if (ret < 0)
-               return ret;
-       if (ret != 2)
-               return -EIO;
-
-       ret = i2c_master_recv(i2c, dest, bytes);
-       if (ret < 0)
-               return ret;
-       if (ret != bytes)
-               return -EIO;
-       return 0;
-}
-
-static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
-                                  int bytes, const void *src)
-{
-       struct i2c_client *i2c = wm8994->control_data;
-       struct i2c_msg xfer[2];
-       int ret;
-
-       reg = cpu_to_be16(reg);
-
-       xfer[0].addr = i2c->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = 2;
-       xfer[0].buf = (char *)&reg;
-
-       xfer[1].addr = i2c->addr;
-       xfer[1].flags = I2C_M_NOSTART;
-       xfer[1].len = bytes;
-       xfer[1].buf = (char *)src;
-
-       ret = i2c_transfer(i2c->adapter, xfer, 2);
-       if (ret < 0)
-               return ret;
-       if (ret != 2)
-               return -EIO;
-
-       return 0;
-}
-
 static int wm8994_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm8994 *wm8994;
+       int ret;
 
        wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
        if (wm8994 == NULL)
@@ -632,12 +567,18 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm8994);
        wm8994->dev = &i2c->dev;
-       wm8994->control_data = i2c;
-       wm8994->read_dev = wm8994_i2c_read_device;
-       wm8994->write_dev = wm8994_i2c_write_device;
        wm8994->irq = i2c->irq;
        wm8994->type = id->driver_data;
 
+       wm8994->regmap = regmap_init_i2c(i2c, &wm8994_regmap_config);
+       if (IS_ERR(wm8994->regmap)) {
+               ret = PTR_ERR(wm8994->regmap);
+               dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               kfree(wm8994);
+               return ret;
+       }
+
        return wm8994_device_init(wm8994, i2c->irq);
 }
 
index 0a4d86c6c4a4d107502bc00ab3f3d25943d9e0f8..2d6423c2d19340015c9f4be263342387db661d9a 100644 (file)
@@ -146,6 +146,7 @@ config PHANTOM
 
 config INTEL_MID_PTI
        tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
+       depends on PCI
        default n
        help
          The PTI (Parallel Trace Interface) driver directs
index 0fd7e77bee297d1da1d877cfe8af2146644ef74c..dee33addcaebf82c2652e089830fff7d442a8ed2 100644 (file)
@@ -90,6 +90,7 @@
 #define PCH_PHUB_INTPIN_REG_WPERMIT_REG3       0x002C
 #define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE   0x0040
 #define CLKCFG_REG_OFFSET                      0x500
+#define FUNCSEL_REG_OFFSET                     0x508
 
 #define PCH_PHUB_OROM_SIZE 15360
 
  * @intpin_reg_wpermit_reg3:           INTPIN_REG_WPERMIT register 3 val
  * @int_reduce_control_reg:            INT_REDUCE_CONTROL registers val
  * @clkcfg_reg:                                CLK CFG register val
+ * @funcsel_reg:                       Function select register value
  * @pch_phub_base_address:             Register base address
  * @pch_phub_extrom_base_address:      external rom base address
  * @pch_mac_start_address:             MAC address area start address
@@ -128,6 +130,7 @@ struct pch_phub_reg {
        u32 intpin_reg_wpermit_reg3;
        u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
        u32 clkcfg_reg;
+       u32 funcsel_reg;
        void __iomem *pch_phub_base_address;
        void __iomem *pch_phub_extrom_base_address;
        u32 pch_mac_start_address;
@@ -211,6 +214,8 @@ static void pch_phub_save_reg_conf(struct pci_dev *pdev)
                        __func__, i, chip->int_reduce_control_reg[i]);
        }
        chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
+       if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
+               chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET);
 }
 
 /* pch_phub_restore_reg_conf - restore register configuration */
@@ -271,6 +276,8 @@ static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
        }
 
        iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
+       if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
+               iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET);
 }
 
 /**
@@ -594,8 +601,7 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
 
        pch_phub_read_gbe_mac_addr(chip, mac);
 
-       return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+       return sprintf(buf, "%pM\n", mac);
 }
 
 static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
index 54c91ffe4a9154fb7142f5f61a654658e8ab1fd0..ba168a7d54d42318d7d192e4158b482844c85be4 100644 (file)
@@ -338,6 +338,12 @@ void st_int_recv(void *disc_data,
                        /* Unknow packet? */
                default:
                        type = *ptr;
+                       if (st_gdata->list[type] == NULL) {
+                               pr_err("chip/interface misbehavior dropping"
+                                       " frame starting with 0x%02x", type);
+                               goto done;
+
+                       }
                        st_gdata->rx_skb = alloc_skb(
                                        st_gdata->list[type]->max_frame_size,
                                        GFP_ATOMIC);
@@ -354,6 +360,7 @@ void st_int_recv(void *disc_data,
                ptr++;
                count--;
        }
+done:
        spin_unlock_irqrestore(&st_gdata->lock, flags);
        pr_debug("done %s", __func__);
        return;
@@ -717,9 +724,10 @@ static void st_tty_close(struct tty_struct *tty)
         */
        spin_lock_irqsave(&st_gdata->lock, flags);
        for (i = ST_BT; i < ST_MAX_CHANNELS; i++) {
-               if (st_gdata->list[i] != NULL)
+               if (st_gdata->is_registered[i] == true)
                        pr_err("%d not un-registered", i);
                st_gdata->list[i] = NULL;
+               st_gdata->is_registered[i] = false;
        }
        st_gdata->protos_registered = 0;
        spin_unlock_irqrestore(&st_gdata->lock, flags);
index 38fd2f04c07eed8df424dd7ef6f04ba25d7f4054..3a3580566dfca39fa5e2882f1658418665a9e72d 100644 (file)
@@ -68,6 +68,7 @@ void validate_firmware_response(struct kim_data_s *kim_gdata)
        if (unlikely(skb->data[5] != 0)) {
                pr_err("no proper response during fw download");
                pr_err("data6 %x", skb->data[5]);
+               kfree_skb(skb);
                return;         /* keep waiting for the proper response */
        }
        /* becos of all the script being downloaded */
@@ -210,6 +211,7 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
                pr_err(" waiting for ver info- timed out ");
                return -ETIMEDOUT;
        }
+       INIT_COMPLETION(kim_gdata->kim_rcvd);
 
        version =
                MAKEWORD(kim_gdata->resp_buffer[13],
@@ -298,6 +300,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)
 
                switch (((struct bts_action *)ptr)->type) {
                case ACTION_SEND_COMMAND:       /* action send */
+                       pr_debug("S");
                        action_ptr = &(((struct bts_action *)ptr)->data[0]);
                        if (unlikely
                            (((struct hci_command *)action_ptr)->opcode ==
@@ -335,6 +338,10 @@ static long download_firmware(struct kim_data_s *kim_gdata)
                                release_firmware(kim_gdata->fw_entry);
                                return -ETIMEDOUT;
                        }
+                       /* reinit completion before sending for the
+                        * relevant wait
+                        */
+                       INIT_COMPLETION(kim_gdata->kim_rcvd);
 
                        /*
                         * Free space found in uart buffer, call st_int_write
@@ -361,6 +368,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)
                        }
                        break;
                case ACTION_WAIT_EVENT:  /* wait */
+                       pr_debug("W");
                        if (!wait_for_completion_timeout
                                        (&kim_gdata->kim_rcvd,
                                         msecs_to_jiffies(CMD_RESP_TIME))) {
@@ -434,11 +442,17 @@ long st_kim_start(void *kim_data)
 {
        long err = 0;
        long retry = POR_RETRY_COUNT;
+       struct ti_st_plat_data  *pdata;
        struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
 
        pr_info(" %s", __func__);
+       pdata = kim_gdata->kim_pdev->dev.platform_data;
 
        do {
+               /* platform specific enabling code here */
+               if (pdata->chip_enable)
+                       pdata->chip_enable(kim_gdata);
+
                /* Configure BT nShutdown to HIGH state */
                gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
                mdelay(5);      /* FIXME: a proper toggle */
@@ -460,6 +474,12 @@ long st_kim_start(void *kim_data)
                        pr_info("ldisc_install = 0");
                        sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
                                        NULL, "install");
+                       /* the following wait is never going to be completed,
+                        * since the ldisc was never installed, hence serving
+                        * as a mdelay of LDISC_TIME msecs */
+                       err = wait_for_completion_timeout
+                               (&kim_gdata->ldisc_installed,
+                                msecs_to_jiffies(LDISC_TIME));
                        err = -ETIMEDOUT;
                        continue;
                } else {
@@ -472,6 +492,13 @@ long st_kim_start(void *kim_data)
                                pr_info("ldisc_install = 0");
                                sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
                                                NULL, "install");
+                               /* this wait might be completed, though in the
+                                * tty_close() since the ldisc is already
+                                * installed */
+                               err = wait_for_completion_timeout
+                                       (&kim_gdata->ldisc_installed,
+                                        msecs_to_jiffies(LDISC_TIME));
+                               err = -EINVAL;
                                continue;
                        } else {        /* on success don't retry */
                                break;
@@ -489,6 +516,8 @@ long st_kim_stop(void *kim_data)
 {
        long err = 0;
        struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
+       struct ti_st_plat_data  *pdata =
+               kim_gdata->kim_pdev->dev.platform_data;
 
        INIT_COMPLETION(kim_gdata->ldisc_installed);
 
@@ -515,6 +544,10 @@ long st_kim_stop(void *kim_data)
        gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
        mdelay(1);
        gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
+
+       /* platform specific disable */
+       if (pdata->chip_disable)
+               pdata->chip_disable(kim_gdata);
        return err;
 }
 
index 3f2495138855457ac6dfc6cfa5de554ed47ee071..1ff460a8e9c74f67e584d634016fa25332fd351c 100644 (file)
@@ -22,6 +22,7 @@
 #define pr_fmt(fmt) "(stll) :" fmt
 #include <linux/skbuff.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/ti_wilink_st.h>
 
 /**********************************************************************/
@@ -37,6 +38,9 @@ static void send_ll_cmd(struct st_data_s *st_data,
 
 static void ll_device_want_to_sleep(struct st_data_s *st_data)
 {
+       struct kim_data_s       *kim_data;
+       struct ti_st_plat_data  *pdata;
+
        pr_debug("%s", __func__);
        /* sanity check */
        if (st_data->ll_state != ST_LL_AWAKE)
@@ -46,10 +50,19 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
        send_ll_cmd(st_data, LL_SLEEP_ACK);
        /* update state */
        st_data->ll_state = ST_LL_ASLEEP;
+
+       /* communicate to platform about chip asleep */
+       kim_data = st_data->kim_data;
+       pdata = kim_data->kim_pdev->dev.platform_data;
+       if (pdata->chip_asleep)
+               pdata->chip_asleep(NULL);
 }
 
 static void ll_device_want_to_wakeup(struct st_data_s *st_data)
 {
+       struct kim_data_s       *kim_data;
+       struct ti_st_plat_data  *pdata;
+
        /* diff actions in diff states */
        switch (st_data->ll_state) {
        case ST_LL_ASLEEP:
@@ -70,6 +83,12 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
        }
        /* update state */
        st_data->ll_state = ST_LL_AWAKE;
+
+       /* communicate to platform about chip wakeup */
+       kim_data = st_data->kim_data;
+       pdata = kim_data->kim_pdev->dev.platform_data;
+       if (pdata->chip_asleep)
+               pdata->chip_awake(NULL);
 }
 
 /**********************************************************************/
index 91a0a7460ebbe855d4a7753cf89db54432b35545..eb3069dfea8e987c950e0b6d019ab606b6545fa7 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
+#include <linux/fault-inject.h>
+#include <linux/random.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -83,6 +85,43 @@ static void mmc_flush_scheduled_work(void)
        flush_workqueue(workqueue);
 }
 
+#ifdef CONFIG_FAIL_MMC_REQUEST
+
+/*
+ * Internal function. Inject random data errors.
+ * If mmc_data is NULL no errors are injected.
+ */
+static void mmc_should_fail_request(struct mmc_host *host,
+                                   struct mmc_request *mrq)
+{
+       struct mmc_command *cmd = mrq->cmd;
+       struct mmc_data *data = mrq->data;
+       static const int data_errors[] = {
+               -ETIMEDOUT,
+               -EILSEQ,
+               -EIO,
+       };
+
+       if (!data)
+               return;
+
+       if (cmd->error || data->error ||
+           !should_fail(&host->fail_mmc_request, data->blksz * data->blocks))
+               return;
+
+       data->error = data_errors[random32() % ARRAY_SIZE(data_errors)];
+       data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9;
+}
+
+#else /* CONFIG_FAIL_MMC_REQUEST */
+
+static inline void mmc_should_fail_request(struct mmc_host *host,
+                                          struct mmc_request *mrq)
+{
+}
+
+#endif /* CONFIG_FAIL_MMC_REQUEST */
+
 /**
  *     mmc_request_done - finish processing an MMC request
  *     @host: MMC host which completed request
@@ -109,6 +148,8 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
                cmd->error = 0;
                host->ops->request(host, mrq);
        } else {
+               mmc_should_fail_request(host, mrq);
+
                led_trigger_event(host->led, LED_OFF);
 
                pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
@@ -133,7 +174,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
                if (mrq->done)
                        mrq->done(mrq);
 
-               mmc_host_clk_gate(host);
+               mmc_host_clk_release(host);
        }
 }
 
@@ -192,7 +233,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
                        mrq->stop->mrq = mrq;
                }
        }
-       mmc_host_clk_ungate(host);
+       mmc_host_clk_hold(host);
        led_trigger_event(host->led, LED_FULL);
        host->ops->request(host, mrq);
 }
@@ -728,15 +769,17 @@ static inline void mmc_set_ios(struct mmc_host *host)
  */
 void mmc_set_chip_select(struct mmc_host *host, int mode)
 {
+       mmc_host_clk_hold(host);
        host->ios.chip_select = mode;
        mmc_set_ios(host);
+       mmc_host_clk_release(host);
 }
 
 /*
  * Sets the host clock to the highest possible frequency that
  * is below "hz".
  */
-void mmc_set_clock(struct mmc_host *host, unsigned int hz)
+static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
 {
        WARN_ON(hz < host->f_min);
 
@@ -747,6 +790,13 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz)
        mmc_set_ios(host);
 }
 
+void mmc_set_clock(struct mmc_host *host, unsigned int hz)
+{
+       mmc_host_clk_hold(host);
+       __mmc_set_clock(host, hz);
+       mmc_host_clk_release(host);
+}
+
 #ifdef CONFIG_MMC_CLKGATE
 /*
  * This gates the clock by setting it to 0 Hz.
@@ -779,7 +829,7 @@ void mmc_ungate_clock(struct mmc_host *host)
        if (host->clk_old) {
                BUG_ON(host->ios.clock);
                /* This call will also set host->clk_gated to false */
-               mmc_set_clock(host, host->clk_old);
+               __mmc_set_clock(host, host->clk_old);
        }
 }
 
@@ -807,8 +857,10 @@ void mmc_set_ungated(struct mmc_host *host)
  */
 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
 {
+       mmc_host_clk_hold(host);
        host->ios.bus_mode = mode;
        mmc_set_ios(host);
+       mmc_host_clk_release(host);
 }
 
 /*
@@ -816,8 +868,10 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
  */
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
 {
+       mmc_host_clk_hold(host);
        host->ios.bus_width = width;
        mmc_set_ios(host);
+       mmc_host_clk_release(host);
 }
 
 /**
@@ -1015,8 +1069,10 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
 
                ocr &= 3 << bit;
 
+               mmc_host_clk_hold(host);
                host->ios.vdd = bit;
                mmc_set_ios(host);
+               mmc_host_clk_release(host);
        } else {
                pr_warning("%s: host doesn't support card's voltages\n",
                                mmc_hostname(host));
@@ -1063,8 +1119,10 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
  */
 void mmc_set_timing(struct mmc_host *host, unsigned int timing)
 {
+       mmc_host_clk_hold(host);
        host->ios.timing = timing;
        mmc_set_ios(host);
+       mmc_host_clk_release(host);
 }
 
 /*
@@ -1072,8 +1130,10 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
  */
 void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
 {
+       mmc_host_clk_hold(host);
        host->ios.drv_type = drv_type;
        mmc_set_ios(host);
+       mmc_host_clk_release(host);
 }
 
 /*
@@ -1091,6 +1151,8 @@ static void mmc_power_up(struct mmc_host *host)
 {
        int bit;
 
+       mmc_host_clk_hold(host);
+
        /* If ocr is set, we use it */
        if (host->ocr)
                bit = ffs(host->ocr) - 1;
@@ -1126,10 +1188,14 @@ static void mmc_power_up(struct mmc_host *host)
         * time required to reach a stable voltage.
         */
        mmc_delay(10);
+
+       mmc_host_clk_release(host);
 }
 
 static void mmc_power_off(struct mmc_host *host)
 {
+       mmc_host_clk_hold(host);
+
        host->ios.clock = 0;
        host->ios.vdd = 0;
 
@@ -1147,6 +1213,8 @@ static void mmc_power_off(struct mmc_host *host)
        host->ios.bus_width = MMC_BUS_WIDTH_1;
        host->ios.timing = MMC_TIMING_LEGACY;
        mmc_set_ios(host);
+
+       mmc_host_clk_release(host);
 }
 
 /*
index 998797ed67a6d0f49802985c31d70b8f4cef0be8..5acd707699c9816b3f0f9f983aa2e3312ef7931a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
+#include <linux/fault-inject.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -158,6 +159,23 @@ static int mmc_clock_opt_set(void *data, u64 val)
        return 0;
 }
 
+#ifdef CONFIG_FAIL_MMC_REQUEST
+
+static DECLARE_FAULT_ATTR(fail_mmc_request);
+
+#ifdef KERNEL
+/*
+ * Internal function. Pass the boot param fail_mmc_request to
+ * the setup fault injection attributes routine.
+ */
+static int __init setup_fail_mmc_request(char *str)
+{
+       return setup_fault_attr(&fail_mmc_request, str);
+}
+__setup("fail_mmc_request=", setup_fail_mmc_request);
+#endif /* KERNEL */
+#endif /* CONFIG_FAIL_MMC_REQUEST */
+
 DEFINE_SIMPLE_ATTRIBUTE(mmc_clock_fops, mmc_clock_opt_get, mmc_clock_opt_set,
        "%llu\n");
 
@@ -187,6 +205,13 @@ void mmc_add_host_debugfs(struct mmc_host *host)
        if (!debugfs_create_u32("clk_delay", (S_IRUSR | S_IWUSR),
                                root, &host->clk_delay))
                goto err_node;
+#endif
+#ifdef CONFIG_FAIL_MMC_REQUEST
+       host->fail_mmc_request = fail_mmc_request;
+       if (IS_ERR(fault_create_debugfs_attr("fail_mmc_request",
+                                            root,
+                                            &host->fail_mmc_request)))
+               goto err_node;
 #endif
        return;
 
index b29d3e8fd3a2ad713525c4be82c9b2f9699910ec..ca2e4f50f61580f65b213159af86647272fbea2d 100644 (file)
@@ -119,14 +119,14 @@ static void mmc_host_clk_gate_work(struct work_struct *work)
 }
 
 /**
- *     mmc_host_clk_ungate - ungate hardware MCI clocks
+ *     mmc_host_clk_hold - ungate hardware MCI clocks
  *     @host: host to ungate.
  *
  *     Makes sure the host ios.clock is restored to a non-zero value
  *     past this call. Increase clock reference count and ungate clock
  *     if we're the first user.
  */
-void mmc_host_clk_ungate(struct mmc_host *host)
+void mmc_host_clk_hold(struct mmc_host *host)
 {
        unsigned long flags;
 
@@ -164,14 +164,14 @@ static bool mmc_host_may_gate_card(struct mmc_card *card)
 }
 
 /**
- *     mmc_host_clk_gate - gate off hardware MCI clocks
+ *     mmc_host_clk_release - gate off hardware MCI clocks
  *     @host: host to gate.
  *
  *     Calls the host driver with ios.clock set to zero as often as possible
  *     in order to gate off hardware MCI clocks. Decrease clock reference
  *     count and schedule disabling of clock.
  */
-void mmc_host_clk_gate(struct mmc_host *host)
+void mmc_host_clk_release(struct mmc_host *host)
 {
        unsigned long flags;
 
@@ -179,7 +179,7 @@ void mmc_host_clk_gate(struct mmc_host *host)
        host->clk_requests--;
        if (mmc_host_may_gate_card(host->card) &&
            !host->clk_requests)
-               schedule_work(&host->clk_gate_work);
+               queue_work(system_nrt_wq, &host->clk_gate_work);
        spin_unlock_irqrestore(&host->clk_lock, flags);
 }
 
@@ -231,7 +231,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host)
        if (cancel_work_sync(&host->clk_gate_work))
                mmc_host_clk_gate_delayed(host);
        if (host->clk_gated)
-               mmc_host_clk_ungate(host);
+               mmc_host_clk_hold(host);
        /* There should be only one user now */
        WARN_ON(host->clk_requests > 1);
 }
@@ -301,6 +301,17 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        host->max_blk_size = 512;
        host->max_blk_count = PAGE_CACHE_SIZE / 512;
 
+       /*
+        * Enable runtime power management by default. This flag was added due
+        * to runtime power management causing disruption for some users, but
+        * the power on/off code has been improved since then.
+        *
+        * We'll enable this flag by default as an experiment, and if no
+        * problems are reported, we will follow up later and remove the flag
+        * altogether.
+        */
+       host->caps = MMC_CAP_POWER_OFF_CARD;
+
        return host;
 
 free:
index de199f91192851b0d4f3162a6dcbe78199fa9e59..fb8a5cd2e4a1e87bfab9439f8c9e44a3d75ee4b4 100644 (file)
@@ -16,16 +16,16 @@ int mmc_register_host_class(void);
 void mmc_unregister_host_class(void);
 
 #ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_ungate(struct mmc_host *host);
-void mmc_host_clk_gate(struct mmc_host *host);
+void mmc_host_clk_hold(struct mmc_host *host);
+void mmc_host_clk_release(struct mmc_host *host);
 unsigned int mmc_host_clk_rate(struct mmc_host *host);
 
 #else
-static inline void mmc_host_clk_ungate(struct mmc_host *host)
+static inline void mmc_host_clk_hold(struct mmc_host *host)
 {
 }
 
-static inline void mmc_host_clk_gate(struct mmc_host *host)
+static inline void mmc_host_clk_release(struct mmc_host *host)
 {
 }
 
index 633975ff2bb395f6e2e883c2e7ce05fb51ed8df2..0370e03e314253f027a36aa994591ea2817f0826 100644 (file)
@@ -469,56 +469,75 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
        return 0;
 }
 
-static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
+static void sd_update_bus_speed_mode(struct mmc_card *card)
 {
-       unsigned int bus_speed = 0, timing = 0;
-       int err;
-
        /*
         * If the host doesn't support any of the UHS-I modes, fallback on
         * default speed.
         */
        if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-           MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
-               return 0;
+           MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) {
+               card->sd_bus_speed = 0;
+               return;
+       }
 
        if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
            (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
-                       bus_speed = UHS_SDR104_BUS_SPEED;
-                       timing = MMC_TIMING_UHS_SDR104;
-                       card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+                       card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
        } else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
                   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
-                       bus_speed = UHS_DDR50_BUS_SPEED;
-                       timing = MMC_TIMING_UHS_DDR50;
-                       card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+                       card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
        } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
                    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
                    SD_MODE_UHS_SDR50)) {
-                       bus_speed = UHS_SDR50_BUS_SPEED;
-                       timing = MMC_TIMING_UHS_SDR50;
-                       card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+                       card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
        } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
                    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
                   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
-                       bus_speed = UHS_SDR25_BUS_SPEED;
-                       timing = MMC_TIMING_UHS_SDR25;
-                       card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+                       card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
        } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
                    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
                    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
                    SD_MODE_UHS_SDR12)) {
-                       bus_speed = UHS_SDR12_BUS_SPEED;
-                       timing = MMC_TIMING_UHS_SDR12;
-                       card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+                       card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
+       }
+}
+
+static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
+{
+       int err;
+       unsigned int timing = 0;
+
+       switch (card->sd_bus_speed) {
+       case UHS_SDR104_BUS_SPEED:
+               timing = MMC_TIMING_UHS_SDR104;
+               card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+               break;
+       case UHS_DDR50_BUS_SPEED:
+               timing = MMC_TIMING_UHS_DDR50;
+               card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+               break;
+       case UHS_SDR50_BUS_SPEED:
+               timing = MMC_TIMING_UHS_SDR50;
+               card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+               break;
+       case UHS_SDR25_BUS_SPEED:
+               timing = MMC_TIMING_UHS_SDR25;
+               card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+               break;
+       case UHS_SDR12_BUS_SPEED:
+               timing = MMC_TIMING_UHS_SDR12;
+               card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+               break;
+       default:
+               return 0;
        }
 
-       card->sd_bus_speed = bus_speed;
-       err = mmc_sd_switch(card, 1, 0, bus_speed, status);
+       err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status);
        if (err)
                return err;
 
-       if ((status[16] & 0xF) != bus_speed)
+       if ((status[16] & 0xF) != card->sd_bus_speed)
                printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
                        mmc_hostname(card->host));
        else {
@@ -618,18 +637,24 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
                mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
        }
 
+       /*
+        * Select the bus speed mode depending on host
+        * and card capability.
+        */
+       sd_update_bus_speed_mode(card);
+
        /* Set the driver strength for the card */
        err = sd_select_driver_type(card, status);
        if (err)
                goto out;
 
-       /* Set bus speed mode of the card */
-       err = sd_set_bus_speed_mode(card, status);
+       /* Set current limit for the card */
+       err = sd_set_current_limit(card, status);
        if (err)
                goto out;
 
-       /* Set current limit for the card */
-       err = sd_set_current_limit(card, status);
+       /* Set bus speed mode of the card */
+       err = sd_set_bus_speed_mode(card, status);
        if (err)
                goto out;
 
index a4aa3af86fedb68ad07eef68e37bff8f65b61e30..a8b4d2aa18e510817a6e83409558078639dd862d 100644 (file)
@@ -869,7 +869,11 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
 static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
 {
        struct at91mci_host *host = _host;
-       int present = !gpio_get_value(irq_to_gpio(irq));
+       int present;
+
+       /* entering this ISR means that we have configured det_pin:
+        * we can use its value in board structure */
+       present = !gpio_get_value(host->board->det_pin);
 
        /*
         * we expect this irq on both insert and remove,
index fc8a0fe7c5c57b1fbf3282733b285c7da40aaf8f..000b3ad0f5ca5d7e1bb1c5a0d81b2130c2279d73 100644 (file)
 #define __DRIVERS_MMC_ATMEL_MCI_H__
 
 /* MCI Register Definitions */
-#define MCI_CR                 0x0000  /* Control */
-# define MCI_CR_MCIEN          (  1 <<  0)     /* MCI Enable */
-# define MCI_CR_MCIDIS         (  1 <<  1)     /* MCI Disable */
-# define MCI_CR_PWSEN          (  1 <<  2)     /* Power Save Enable */
-# define MCI_CR_PWSDIS         (  1 <<  3)     /* Power Save Disable */
-# define MCI_CR_SWRST          (  1 <<  7)     /* Software Reset */
-#define MCI_MR                 0x0004  /* Mode */
-# define MCI_MR_CLKDIV(x)      ((x) <<  0)     /* Clock Divider */
-# define MCI_MR_PWSDIV(x)      ((x) <<  8)     /* Power Saving Divider */
-# define MCI_MR_RDPROOF                (  1 << 11)     /* Read Proof */
-# define MCI_MR_WRPROOF                (  1 << 12)     /* Write Proof */
-# define MCI_MR_PDCFBYTE       (  1 << 13)     /* Force Byte Transfer */
-# define MCI_MR_PDCPADV                (  1 << 14)     /* Padding Value */
-# define MCI_MR_PDCMODE                (  1 << 15)     /* PDC-oriented Mode */
-#define MCI_DTOR               0x0008  /* Data Timeout */
-# define MCI_DTOCYC(x)         ((x) <<  0)     /* Data Timeout Cycles */
-# define MCI_DTOMUL(x)         ((x) <<  4)     /* Data Timeout Multiplier */
-#define MCI_SDCR               0x000c  /* SD Card / SDIO */
-# define MCI_SDCSEL_SLOT_A     (  0 <<  0)     /* Select SD slot A */
-# define MCI_SDCSEL_SLOT_B     (  1 <<  0)     /* Select SD slot A */
-# define MCI_SDCSEL_MASK       (  3 <<  0)
-# define MCI_SDCBUS_1BIT       (  0 <<  6)     /* 1-bit data bus */
-# define MCI_SDCBUS_4BIT       (  2 <<  6)     /* 4-bit data bus */
-# define MCI_SDCBUS_8BIT       (  3 <<  6)     /* 8-bit data bus[2] */
-# define MCI_SDCBUS_MASK       (  3 <<  6)
-#define MCI_ARGR               0x0010  /* Command Argument */
-#define MCI_CMDR               0x0014  /* Command */
-# define MCI_CMDR_CMDNB(x)     ((x) <<  0)     /* Command Opcode */
-# define MCI_CMDR_RSPTYP_NONE  (  0 <<  6)     /* No response */
-# define MCI_CMDR_RSPTYP_48BIT (  1 <<  6)     /* 48-bit response */
-# define MCI_CMDR_RSPTYP_136BIT        (  2 <<  6)     /* 136-bit response */
-# define MCI_CMDR_SPCMD_INIT   (  1 <<  8)     /* Initialization command */
-# define MCI_CMDR_SPCMD_SYNC   (  2 <<  8)     /* Synchronized command */
-# define MCI_CMDR_SPCMD_INT    (  4 <<  8)     /* Interrupt command */
-# define MCI_CMDR_SPCMD_INTRESP        (  5 <<  8)     /* Interrupt response */
-# define MCI_CMDR_OPDCMD       (  1 << 11)     /* Open Drain */
-# define MCI_CMDR_MAXLAT_5CYC  (  0 << 12)     /* Max latency 5 cycles */
-# define MCI_CMDR_MAXLAT_64CYC (  1 << 12)     /* Max latency 64 cycles */
-# define MCI_CMDR_START_XFER   (  1 << 16)     /* Start data transfer */
-# define MCI_CMDR_STOP_XFER    (  2 << 16)     /* Stop data transfer */
-# define MCI_CMDR_TRDIR_WRITE  (  0 << 18)     /* Write data */
-# define MCI_CMDR_TRDIR_READ   (  1 << 18)     /* Read data */
-# define MCI_CMDR_BLOCK                (  0 << 19)     /* Single-block transfer */
-# define MCI_CMDR_MULTI_BLOCK  (  1 << 19)     /* Multi-block transfer */
-# define MCI_CMDR_STREAM       (  2 << 19)     /* MMC Stream transfer */
-# define MCI_CMDR_SDIO_BYTE    (  4 << 19)     /* SDIO Byte transfer */
-# define MCI_CMDR_SDIO_BLOCK   (  5 << 19)     /* SDIO Block transfer */
-# define MCI_CMDR_SDIO_SUSPEND (  1 << 24)     /* SDIO Suspend Command */
-# define MCI_CMDR_SDIO_RESUME  (  2 << 24)     /* SDIO Resume Command */
-#define MCI_BLKR               0x0018  /* Block */
-# define MCI_BCNT(x)           ((x) <<  0)     /* Data Block Count */
-# define MCI_BLKLEN(x)         ((x) << 16)     /* Data Block Length */
-#define MCI_CSTOR              0x001c  /* Completion Signal Timeout[2] */
-# define MCI_CSTOCYC(x)                ((x) <<  0)     /* CST cycles */
-# define MCI_CSTOMUL(x)                ((x) <<  4)     /* CST multiplier */
-#define MCI_RSPR               0x0020  /* Response 0 */
-#define MCI_RSPR1              0x0024  /* Response 1 */
-#define MCI_RSPR2              0x0028  /* Response 2 */
-#define MCI_RSPR3              0x002c  /* Response 3 */
-#define MCI_RDR                        0x0030  /* Receive Data */
-#define MCI_TDR                        0x0034  /* Transmit Data */
-#define MCI_SR                 0x0040  /* Status */
-#define MCI_IER                        0x0044  /* Interrupt Enable */
-#define MCI_IDR                        0x0048  /* Interrupt Disable */
-#define MCI_IMR                        0x004c  /* Interrupt Mask */
-# define MCI_CMDRDY            (  1 <<   0)    /* Command Ready */
-# define MCI_RXRDY             (  1 <<   1)    /* Receiver Ready */
-# define MCI_TXRDY             (  1 <<   2)    /* Transmitter Ready */
-# define MCI_BLKE              (  1 <<   3)    /* Data Block Ended */
-# define MCI_DTIP              (  1 <<   4)    /* Data Transfer In Progress */
-# define MCI_NOTBUSY           (  1 <<   5)    /* Data Not Busy */
-# define MCI_SDIOIRQA          (  1 <<   8)    /* SDIO IRQ in slot A */
-# define MCI_SDIOIRQB          (  1 <<   9)    /* SDIO IRQ in slot B */
-# define MCI_RINDE             (  1 <<  16)    /* Response Index Error */
-# define MCI_RDIRE             (  1 <<  17)    /* Response Direction Error */
-# define MCI_RCRCE             (  1 <<  18)    /* Response CRC Error */
-# define MCI_RENDE             (  1 <<  19)    /* Response End Bit Error */
-# define MCI_RTOE              (  1 <<  20)    /* Response Time-Out Error */
-# define MCI_DCRCE             (  1 <<  21)    /* Data CRC Error */
-# define MCI_DTOE              (  1 <<  22)    /* Data Time-Out Error */
-# define MCI_OVRE              (  1 <<  30)    /* RX Overrun Error */
-# define MCI_UNRE              (  1 <<  31)    /* TX Underrun Error */
-#define MCI_DMA                        0x0050  /* DMA Configuration[2] */
-# define MCI_DMA_OFFSET(x)     ((x) <<  0)     /* DMA Write Buffer Offset */
-# define MCI_DMA_CHKSIZE(x)    ((x) <<  4)     /* DMA Channel Read and Write Chunk Size */
-# define MCI_DMAEN             (  1 <<  8)     /* DMA Hardware Handshaking Enable */
-#define MCI_CFG                        0x0054  /* Configuration[2] */
-# define MCI_CFG_FIFOMODE_1DATA        (  1 <<  0)     /* MCI Internal FIFO control mode */
-# define MCI_CFG_FERRCTRL_COR  (  1 <<  4)     /* Flow Error flag reset control mode */
-# define MCI_CFG_HSMODE                (  1 <<  8)     /* High Speed Mode */
-# define MCI_CFG_LSYNC         (  1 << 12)     /* Synchronize on the last block */
-#define MCI_WPMR               0x00e4  /* Write Protection Mode[2] */
-# define MCI_WP_EN             (  1 <<  0)     /* WP Enable */
-# define MCI_WP_KEY            (0x4d4349 << 8) /* WP Key */
-#define MCI_WPSR               0x00e8  /* Write Protection Status[2] */
-# define MCI_GET_WP_VS(x)      ((x) & 0x0f)
-# define MCI_GET_WP_VSRC(x)    (((x) >> 8) & 0xffff)
-#define MCI_FIFO_APERTURE      0x0200  /* FIFO Aperture[2] */
+#define ATMCI_CR                       0x0000  /* Control */
+# define ATMCI_CR_MCIEN                        (  1 <<  0)     /* MCI Enable */
+# define ATMCI_CR_MCIDIS               (  1 <<  1)     /* MCI Disable */
+# define ATMCI_CR_PWSEN                        (  1 <<  2)     /* Power Save Enable */
+# define ATMCI_CR_PWSDIS               (  1 <<  3)     /* Power Save Disable */
+# define ATMCI_CR_SWRST                        (  1 <<  7)     /* Software Reset */
+#define ATMCI_MR                       0x0004  /* Mode */
+# define ATMCI_MR_CLKDIV(x)            ((x) <<  0)     /* Clock Divider */
+# define ATMCI_MR_PWSDIV(x)            ((x) <<  8)     /* Power Saving Divider */
+# define ATMCI_MR_RDPROOF              (  1 << 11)     /* Read Proof */
+# define ATMCI_MR_WRPROOF              (  1 << 12)     /* Write Proof */
+# define ATMCI_MR_PDCFBYTE             (  1 << 13)     /* Force Byte Transfer */
+# define ATMCI_MR_PDCPADV              (  1 << 14)     /* Padding Value */
+# define ATMCI_MR_PDCMODE              (  1 << 15)     /* PDC-oriented Mode */
+#define ATMCI_DTOR                     0x0008  /* Data Timeout */
+# define ATMCI_DTOCYC(x)               ((x) <<  0)     /* Data Timeout Cycles */
+# define ATMCI_DTOMUL(x)               ((x) <<  4)     /* Data Timeout Multiplier */
+#define ATMCI_SDCR                     0x000c  /* SD Card / SDIO */
+# define ATMCI_SDCSEL_SLOT_A           (  0 <<  0)     /* Select SD slot A */
+# define ATMCI_SDCSEL_SLOT_B           (  1 <<  0)     /* Select SD slot A */
+# define ATMCI_SDCSEL_MASK             (  3 <<  0)
+# define ATMCI_SDCBUS_1BIT             (  0 <<  6)     /* 1-bit data bus */
+# define ATMCI_SDCBUS_4BIT             (  2 <<  6)     /* 4-bit data bus */
+# define ATMCI_SDCBUS_8BIT             (  3 <<  6)     /* 8-bit data bus[2] */
+# define ATMCI_SDCBUS_MASK             (  3 <<  6)
+#define ATMCI_ARGR                     0x0010  /* Command Argument */
+#define ATMCI_CMDR                     0x0014  /* Command */
+# define ATMCI_CMDR_CMDNB(x)           ((x) <<  0)     /* Command Opcode */
+# define ATMCI_CMDR_RSPTYP_NONE                (  0 <<  6)     /* No response */
+# define ATMCI_CMDR_RSPTYP_48BIT       (  1 <<  6)     /* 48-bit response */
+# define ATMCI_CMDR_RSPTYP_136BIT      (  2 <<  6)     /* 136-bit response */
+# define ATMCI_CMDR_SPCMD_INIT         (  1 <<  8)     /* Initialization command */
+# define ATMCI_CMDR_SPCMD_SYNC         (  2 <<  8)     /* Synchronized command */
+# define ATMCI_CMDR_SPCMD_INT          (  4 <<  8)     /* Interrupt command */
+# define ATMCI_CMDR_SPCMD_INTRESP      (  5 <<  8)     /* Interrupt response */
+# define ATMCI_CMDR_OPDCMD             (  1 << 11)     /* Open Drain */
+# define ATMCI_CMDR_MAXLAT_5CYC                (  0 << 12)     /* Max latency 5 cycles */
+# define ATMCI_CMDR_MAXLAT_64CYC       (  1 << 12)     /* Max latency 64 cycles */
+# define ATMCI_CMDR_START_XFER         (  1 << 16)     /* Start data transfer */
+# define ATMCI_CMDR_STOP_XFER          (  2 << 16)     /* Stop data transfer */
+# define ATMCI_CMDR_TRDIR_WRITE                (  0 << 18)     /* Write data */
+# define ATMCI_CMDR_TRDIR_READ         (  1 << 18)     /* Read data */
+# define ATMCI_CMDR_BLOCK              (  0 << 19)     /* Single-block transfer */
+# define ATMCI_CMDR_MULTI_BLOCK                (  1 << 19)     /* Multi-block transfer */
+# define ATMCI_CMDR_STREAM             (  2 << 19)     /* MMC Stream transfer */
+# define ATMCI_CMDR_SDIO_BYTE          (  4 << 19)     /* SDIO Byte transfer */
+# define ATMCI_CMDR_SDIO_BLOCK         (  5 << 19)     /* SDIO Block transfer */
+# define ATMCI_CMDR_SDIO_SUSPEND       (  1 << 24)     /* SDIO Suspend Command */
+# define ATMCI_CMDR_SDIO_RESUME                (  2 << 24)     /* SDIO Resume Command */
+#define ATMCI_BLKR                     0x0018  /* Block */
+# define ATMCI_BCNT(x)                 ((x) <<  0)     /* Data Block Count */
+# define ATMCI_BLKLEN(x)               ((x) << 16)     /* Data Block Length */
+#define ATMCI_CSTOR                    0x001c  /* Completion Signal Timeout[2] */
+# define ATMCI_CSTOCYC(x)              ((x) <<  0)     /* CST cycles */
+# define ATMCI_CSTOMUL(x)              ((x) <<  4)     /* CST multiplier */
+#define ATMCI_RSPR                     0x0020  /* Response 0 */
+#define ATMCI_RSPR1                    0x0024  /* Response 1 */
+#define ATMCI_RSPR2                    0x0028  /* Response 2 */
+#define ATMCI_RSPR3                    0x002c  /* Response 3 */
+#define ATMCI_RDR                      0x0030  /* Receive Data */
+#define ATMCI_TDR                      0x0034  /* Transmit Data */
+#define ATMCI_SR                       0x0040  /* Status */
+#define ATMCI_IER                      0x0044  /* Interrupt Enable */
+#define ATMCI_IDR                      0x0048  /* Interrupt Disable */
+#define ATMCI_IMR                      0x004c  /* Interrupt Mask */
+# define ATMCI_CMDRDY                  (  1 <<   0)    /* Command Ready */
+# define ATMCI_RXRDY                   (  1 <<   1)    /* Receiver Ready */
+# define ATMCI_TXRDY                   (  1 <<   2)    /* Transmitter Ready */
+# define ATMCI_BLKE                    (  1 <<   3)    /* Data Block Ended */
+# define ATMCI_DTIP                    (  1 <<   4)    /* Data Transfer In Progress */
+# define ATMCI_NOTBUSY                 (  1 <<   5)    /* Data Not Busy */
+# define ATMCI_ENDRX                   (  1 <<   6)    /* End of RX Buffer */
+# define ATMCI_ENDTX                   (  1 <<   7)    /* End of TX Buffer */
+# define ATMCI_SDIOIRQA                        (  1 <<   8)    /* SDIO IRQ in slot A */
+# define ATMCI_SDIOIRQB                        (  1 <<   9)    /* SDIO IRQ in slot B */
+# define ATMCI_SDIOWAIT                        (  1 <<  12)    /* SDIO Read Wait Operation Status */
+# define ATMCI_CSRCV                   (  1 <<  13)    /* CE-ATA Completion Signal Received */
+# define ATMCI_RXBUFF                  (  1 <<  14)    /* RX Buffer Full */
+# define ATMCI_TXBUFE                  (  1 <<  15)    /* TX Buffer Empty */
+# define ATMCI_RINDE                   (  1 <<  16)    /* Response Index Error */
+# define ATMCI_RDIRE                   (  1 <<  17)    /* Response Direction Error */
+# define ATMCI_RCRCE                   (  1 <<  18)    /* Response CRC Error */
+# define ATMCI_RENDE                   (  1 <<  19)    /* Response End Bit Error */
+# define ATMCI_RTOE                    (  1 <<  20)    /* Response Time-Out Error */
+# define ATMCI_DCRCE                   (  1 <<  21)    /* Data CRC Error */
+# define ATMCI_DTOE                    (  1 <<  22)    /* Data Time-Out Error */
+# define ATMCI_CSTOE                   (  1 <<  23)    /* Completion Signal Time-out Error */
+# define ATMCI_BLKOVRE                 (  1 <<  24)    /* DMA Block Overrun Error */
+# define ATMCI_DMADONE                 (  1 <<  25)    /* DMA Transfer Done */
+# define ATMCI_FIFOEMPTY               (  1 <<  26)    /* FIFO Empty Flag */
+# define ATMCI_XFRDONE                 (  1 <<  27)    /* Transfer Done Flag */
+# define ATMCI_ACKRCV                  (  1 <<  28)    /* Boot Operation Acknowledge Received */
+# define ATMCI_ACKRCVE                 (  1 <<  29)    /* Boot Operation Acknowledge Error */
+# define ATMCI_OVRE                    (  1 <<  30)    /* RX Overrun Error */
+# define ATMCI_UNRE                    (  1 <<  31)    /* TX Underrun Error */
+#define ATMCI_DMA                      0x0050  /* DMA Configuration[2] */
+# define ATMCI_DMA_OFFSET(x)           ((x) <<  0)     /* DMA Write Buffer Offset */
+# define ATMCI_DMA_CHKSIZE(x)          ((x) <<  4)     /* DMA Channel Read and Write Chunk Size */
+# define ATMCI_DMAEN                   (  1 <<  8)     /* DMA Hardware Handshaking Enable */
+#define ATMCI_CFG                      0x0054  /* Configuration[2] */
+# define ATMCI_CFG_FIFOMODE_1DATA      (  1 <<  0)     /* MCI Internal FIFO control mode */
+# define ATMCI_CFG_FERRCTRL_COR                (  1 <<  4)     /* Flow Error flag reset control mode */
+# define ATMCI_CFG_HSMODE              (  1 <<  8)     /* High Speed Mode */
+# define ATMCI_CFG_LSYNC               (  1 << 12)     /* Synchronize on the last block */
+#define ATMCI_WPMR                     0x00e4  /* Write Protection Mode[2] */
+# define ATMCI_WP_EN                   (  1 <<  0)     /* WP Enable */
+# define ATMCI_WP_KEY                  (0x4d4349 << 8) /* WP Key */
+#define ATMCI_WPSR                     0x00e8  /* Write Protection Status[2] */
+# define ATMCI_GET_WP_VS(x)            ((x) & 0x0f)
+# define ATMCI_GET_WP_VSRC(x)          (((x) >> 8) & 0xffff)
+#define ATMCI_VERSION                  0x00FC  /* Version */
+#define ATMCI_FIFO_APERTURE            0x0200  /* FIFO Aperture[2] */
 
 /* This is not including the FIFO Aperture on MCI2 */
-#define MCI_REGS_SIZE          0x100
+#define ATMCI_REGS_SIZE                0x100
 
 /* Register access macros */
-#define mci_readl(port,reg)                            \
-       __raw_readl((port)->regs + MCI_##reg)
-#define mci_writel(port,reg,value)                     \
-       __raw_writel((value), (port)->regs + MCI_##reg)
+#define atmci_readl(port,reg)                          \
+       __raw_readl((port)->regs + reg)
+#define atmci_writel(port,reg,value)                   \
+       __raw_writel((value), (port)->regs + reg)
 
 #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */
index fa8cae1d7005c03524681564a38c1a7d5bb6a12b..a7ee5027146528aafc6b18fa8c2e55f32e32a174 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <mach/atmel-mci.h>
 #include <linux/atmel-mci.h>
+#include <linux/atmel_pdc.h>
 
 #include <asm/io.h>
 #include <asm/unaligned.h>
@@ -39,7 +40,7 @@
 
 #include "atmel-mci-regs.h"
 
-#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE)
+#define ATMCI_DATA_ERROR_FLAGS (ATMCI_DCRCE | ATMCI_DTOE | ATMCI_OVRE | ATMCI_UNRE)
 #define ATMCI_DMA_THRESHOLD    16
 
 enum {
@@ -58,18 +59,35 @@ enum atmel_mci_state {
        STATE_DATA_ERROR,
 };
 
+enum atmci_xfer_dir {
+       XFER_RECEIVE = 0,
+       XFER_TRANSMIT,
+};
+
+enum atmci_pdc_buf {
+       PDC_FIRST_BUF = 0,
+       PDC_SECOND_BUF,
+};
+
+struct atmel_mci_caps {
+       bool    has_dma;
+       bool    has_pdc;
+       bool    has_cfg_reg;
+       bool    has_cstor_reg;
+       bool    has_highspeed;
+       bool    has_rwproof;
+};
+
 struct atmel_mci_dma {
-#ifdef CONFIG_MMC_ATMELMCI_DMA
        struct dma_chan                 *chan;
        struct dma_async_tx_descriptor  *data_desc;
-#endif
 };
 
 /**
  * struct atmel_mci - MMC controller state shared between all slots
  * @lock: Spinlock protecting the queue and associated data.
  * @regs: Pointer to MMIO registers.
- * @sg: Scatterlist entry currently being processed by PIO code, if any.
+ * @sg: Scatterlist entry currently being processed by PIO or PDC code.
  * @pio_offset: Offset into the current scatterlist entry.
  * @cur_slot: The slot which is currently using the controller.
  * @mrq: The request currently being processed on @cur_slot,
@@ -77,6 +95,7 @@ struct atmel_mci_dma {
  * @cmd: The command currently being sent to the card, or NULL.
  * @data: The data currently being transferred, or NULL if no data
  *     transfer is in progress.
+ * @data_size: just data->blocks * data->blksz.
  * @dma: DMA client state.
  * @data_chan: DMA channel being used for the current data transfer.
  * @cmd_status: Snapshot of SR taken upon completion of the current
@@ -103,6 +122,13 @@ struct atmel_mci_dma {
  * @mck: The peripheral bus clock hooked up to the MMC controller.
  * @pdev: Platform device associated with the MMC controller.
  * @slot: Slots sharing this MMC controller.
+ * @caps: MCI capabilities depending on MCI version.
+ * @prepare_data: function to setup MCI before data transfer which
+ * depends on MCI capabilities.
+ * @submit_data: function to start data transfer which depends on MCI
+ * capabilities.
+ * @stop_transfer: function to stop data transfer which depends on MCI
+ * capabilities.
  *
  * Locking
  * =======
@@ -143,6 +169,7 @@ struct atmel_mci {
        struct mmc_request      *mrq;
        struct mmc_command      *cmd;
        struct mmc_data         *data;
+       unsigned int            data_size;
 
        struct atmel_mci_dma    dma;
        struct dma_chan         *data_chan;
@@ -166,7 +193,13 @@ struct atmel_mci {
        struct clk              *mck;
        struct platform_device  *pdev;
 
-       struct atmel_mci_slot   *slot[ATMEL_MCI_MAX_NR_SLOTS];
+       struct atmel_mci_slot   *slot[ATMCI_MAX_NR_SLOTS];
+
+       struct atmel_mci_caps   caps;
+
+       u32 (*prepare_data)(struct atmel_mci *host, struct mmc_data *data);
+       void (*submit_data)(struct atmel_mci *host, struct mmc_data *data);
+       void (*stop_transfer)(struct atmel_mci *host);
 };
 
 /**
@@ -219,31 +252,6 @@ struct atmel_mci_slot {
 #define atmci_set_pending(host, event)                         \
        set_bit(event, &host->pending_events)
 
-/*
- * Enable or disable features/registers based on
- * whether the processor supports them
- */
-static bool mci_has_rwproof(void)
-{
-       if (cpu_is_at91sam9261() || cpu_is_at91rm9200())
-               return false;
-       else
-               return true;
-}
-
-/*
- * The new MCI2 module isn't 100% compatible with the old MCI module,
- * and it has a few nice features which we want to use...
- */
-static inline bool atmci_is_mci2(void)
-{
-       if (cpu_is_at91sam9g45())
-               return true;
-
-       return false;
-}
-
-
 /*
  * The debugfs stuff below is mostly optimized away when
  * CONFIG_DEBUG_FS is not set.
@@ -352,7 +360,7 @@ static int atmci_regs_show(struct seq_file *s, void *v)
        struct atmel_mci        *host = s->private;
        u32                     *buf;
 
-       buf = kmalloc(MCI_REGS_SIZE, GFP_KERNEL);
+       buf = kmalloc(ATMCI_REGS_SIZE, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
@@ -363,47 +371,50 @@ static int atmci_regs_show(struct seq_file *s, void *v)
         */
        spin_lock_bh(&host->lock);
        clk_enable(host->mck);
-       memcpy_fromio(buf, host->regs, MCI_REGS_SIZE);
+       memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE);
        clk_disable(host->mck);
        spin_unlock_bh(&host->lock);
 
        seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
-                       buf[MCI_MR / 4],
-                       buf[MCI_MR / 4] & MCI_MR_RDPROOF ? " RDPROOF" : "",
-                       buf[MCI_MR / 4] & MCI_MR_WRPROOF ? " WRPROOF" : "",
-                       buf[MCI_MR / 4] & 0xff);
-       seq_printf(s, "DTOR:\t0x%08x\n", buf[MCI_DTOR / 4]);
-       seq_printf(s, "SDCR:\t0x%08x\n", buf[MCI_SDCR / 4]);
-       seq_printf(s, "ARGR:\t0x%08x\n", buf[MCI_ARGR / 4]);
+                       buf[ATMCI_MR / 4],
+                       buf[ATMCI_MR / 4] & ATMCI_MR_RDPROOF ? " RDPROOF" : "",
+                       buf[ATMCI_MR / 4] & ATMCI_MR_WRPROOF ? " WRPROOF" : "",
+                       buf[ATMCI_MR / 4] & 0xff);
+       seq_printf(s, "DTOR:\t0x%08x\n", buf[ATMCI_DTOR / 4]);
+       seq_printf(s, "SDCR:\t0x%08x\n", buf[ATMCI_SDCR / 4]);
+       seq_printf(s, "ARGR:\t0x%08x\n", buf[ATMCI_ARGR / 4]);
        seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n",
-                       buf[MCI_BLKR / 4],
-                       buf[MCI_BLKR / 4] & 0xffff,
-                       (buf[MCI_BLKR / 4] >> 16) & 0xffff);
-       if (atmci_is_mci2())
-               seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]);
+                       buf[ATMCI_BLKR / 4],
+                       buf[ATMCI_BLKR / 4] & 0xffff,
+                       (buf[ATMCI_BLKR / 4] >> 16) & 0xffff);
+       if (host->caps.has_cstor_reg)
+               seq_printf(s, "CSTOR:\t0x%08x\n", buf[ATMCI_CSTOR / 4]);
 
        /* Don't read RSPR and RDR; it will consume the data there */
 
-       atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
-       atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
+       atmci_show_status_reg(s, "SR", buf[ATMCI_SR / 4]);
+       atmci_show_status_reg(s, "IMR", buf[ATMCI_IMR / 4]);
 
-       if (atmci_is_mci2()) {
+       if (host->caps.has_dma) {
                u32 val;
 
-               val = buf[MCI_DMA / 4];
+               val = buf[ATMCI_DMA / 4];
                seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n",
                                val, val & 3,
                                ((val >> 4) & 3) ?
                                        1 << (((val >> 4) & 3) + 1) : 1,
-                               val & MCI_DMAEN ? " DMAEN" : "");
+                               val & ATMCI_DMAEN ? " DMAEN" : "");
+       }
+       if (host->caps.has_cfg_reg) {
+               u32 val;
 
-               val = buf[MCI_CFG / 4];
+               val = buf[ATMCI_CFG / 4];
                seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n",
                                val,
-                               val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
-                               val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
-                               val & MCI_CFG_HSMODE ? " HSMODE" : "",
-                               val & MCI_CFG_LSYNC ? " LSYNC" : "");
+                               val & ATMCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
+                               val & ATMCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
+                               val & ATMCI_CFG_HSMODE ? " HSMODE" : "",
+                               val & ATMCI_CFG_LSYNC ? " LSYNC" : "");
        }
 
        kfree(buf);
@@ -466,7 +477,7 @@ err:
        dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
 }
 
-static inline unsigned int ns_to_clocks(struct atmel_mci *host,
+static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
                                        unsigned int ns)
 {
        return (ns * (host->bus_hz / 1000000) + 999) / 1000;
@@ -482,7 +493,8 @@ static void atmci_set_timeout(struct atmel_mci *host,
        unsigned        dtocyc;
        unsigned        dtomul;
 
-       timeout = ns_to_clocks(host, data->timeout_ns) + data->timeout_clks;
+       timeout = atmci_ns_to_clocks(host, data->timeout_ns)
+               + data->timeout_clks;
 
        for (dtomul = 0; dtomul < 8; dtomul++) {
                unsigned shift = dtomul_to_shift[dtomul];
@@ -498,7 +510,7 @@ static void atmci_set_timeout(struct atmel_mci *host,
 
        dev_vdbg(&slot->mmc->class_dev, "setting timeout to %u cycles\n",
                        dtocyc << dtomul_to_shift[dtomul]);
-       mci_writel(host, DTOR, (MCI_DTOMUL(dtomul) | MCI_DTOCYC(dtocyc)));
+       atmci_writel(host, ATMCI_DTOR, (ATMCI_DTOMUL(dtomul) | ATMCI_DTOCYC(dtocyc)));
 }
 
 /*
@@ -512,13 +524,13 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
 
        cmd->error = -EINPROGRESS;
 
-       cmdr = MCI_CMDR_CMDNB(cmd->opcode);
+       cmdr = ATMCI_CMDR_CMDNB(cmd->opcode);
 
        if (cmd->flags & MMC_RSP_PRESENT) {
                if (cmd->flags & MMC_RSP_136)
-                       cmdr |= MCI_CMDR_RSPTYP_136BIT;
+                       cmdr |= ATMCI_CMDR_RSPTYP_136BIT;
                else
-                       cmdr |= MCI_CMDR_RSPTYP_48BIT;
+                       cmdr |= ATMCI_CMDR_RSPTYP_48BIT;
        }
 
        /*
@@ -526,34 +538,34 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
         * it's too difficult to determine whether this is an ACMD or
         * not. Better make it 64.
         */
-       cmdr |= MCI_CMDR_MAXLAT_64CYC;
+       cmdr |= ATMCI_CMDR_MAXLAT_64CYC;
 
        if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN)
-               cmdr |= MCI_CMDR_OPDCMD;
+               cmdr |= ATMCI_CMDR_OPDCMD;
 
        data = cmd->data;
        if (data) {
-               cmdr |= MCI_CMDR_START_XFER;
+               cmdr |= ATMCI_CMDR_START_XFER;
 
                if (cmd->opcode == SD_IO_RW_EXTENDED) {
-                       cmdr |= MCI_CMDR_SDIO_BLOCK;
+                       cmdr |= ATMCI_CMDR_SDIO_BLOCK;
                } else {
                        if (data->flags & MMC_DATA_STREAM)
-                               cmdr |= MCI_CMDR_STREAM;
+                               cmdr |= ATMCI_CMDR_STREAM;
                        else if (data->blocks > 1)
-                               cmdr |= MCI_CMDR_MULTI_BLOCK;
+                               cmdr |= ATMCI_CMDR_MULTI_BLOCK;
                        else
-                               cmdr |= MCI_CMDR_BLOCK;
+                               cmdr |= ATMCI_CMDR_BLOCK;
                }
 
                if (data->flags & MMC_DATA_READ)
-                       cmdr |= MCI_CMDR_TRDIR_READ;
+                       cmdr |= ATMCI_CMDR_TRDIR_READ;
        }
 
        return cmdr;
 }
 
-static void atmci_start_command(struct atmel_mci *host,
+static void atmci_send_command(struct atmel_mci *host,
                struct mmc_command *cmd, u32 cmd_flags)
 {
        WARN_ON(host->cmd);
@@ -563,43 +575,119 @@ static void atmci_start_command(struct atmel_mci *host,
                        "start command: ARGR=0x%08x CMDR=0x%08x\n",
                        cmd->arg, cmd_flags);
 
-       mci_writel(host, ARGR, cmd->arg);
-       mci_writel(host, CMDR, cmd_flags);
+       atmci_writel(host, ATMCI_ARGR, cmd->arg);
+       atmci_writel(host, ATMCI_CMDR, cmd_flags);
 }
 
-static void send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
+static void atmci_send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
 {
-       atmci_start_command(host, data->stop, host->stop_cmdr);
-       mci_writel(host, IER, MCI_CMDRDY);
+       atmci_send_command(host, data->stop, host->stop_cmdr);
+       atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
 }
 
-#ifdef CONFIG_MMC_ATMELMCI_DMA
-static void atmci_dma_cleanup(struct atmel_mci *host)
+/*
+ * Configure given PDC buffer taking care of alignement issues.
+ * Update host->data_size and host->sg.
+ */
+static void atmci_pdc_set_single_buf(struct atmel_mci *host,
+       enum atmci_xfer_dir dir, enum atmci_pdc_buf buf_nb)
+{
+       u32 pointer_reg, counter_reg;
+
+       if (dir == XFER_RECEIVE) {
+               pointer_reg = ATMEL_PDC_RPR;
+               counter_reg = ATMEL_PDC_RCR;
+       } else {
+               pointer_reg = ATMEL_PDC_TPR;
+               counter_reg = ATMEL_PDC_TCR;
+       }
+
+       if (buf_nb == PDC_SECOND_BUF) {
+               pointer_reg += ATMEL_PDC_SCND_BUF_OFF;
+               counter_reg += ATMEL_PDC_SCND_BUF_OFF;
+       }
+
+       atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
+       if (host->data_size <= sg_dma_len(host->sg)) {
+               if (host->data_size & 0x3) {
+                       /* If size is different from modulo 4, transfer bytes */
+                       atmci_writel(host, counter_reg, host->data_size);
+                       atmci_writel(host, ATMCI_MR, host->mode_reg | ATMCI_MR_PDCFBYTE);
+               } else {
+                       /* Else transfer 32-bits words */
+                       atmci_writel(host, counter_reg, host->data_size / 4);
+               }
+               host->data_size = 0;
+       } else {
+               /* We assume the size of a page is 32-bits aligned */
+               atmci_writel(host, counter_reg, sg_dma_len(host->sg) / 4);
+               host->data_size -= sg_dma_len(host->sg);
+               if (host->data_size)
+                       host->sg = sg_next(host->sg);
+       }
+}
+
+/*
+ * Configure PDC buffer according to the data size ie configuring one or two
+ * buffers. Don't use this function if you want to configure only the second
+ * buffer. In this case, use atmci_pdc_set_single_buf.
+ */
+static void atmci_pdc_set_both_buf(struct atmel_mci *host, int dir)
 {
-       struct mmc_data                 *data = host->data;
+       atmci_pdc_set_single_buf(host, dir, PDC_FIRST_BUF);
+       if (host->data_size)
+               atmci_pdc_set_single_buf(host, dir, PDC_SECOND_BUF);
+}
+
+/*
+ * Unmap sg lists, called when transfer is finished.
+ */
+static void atmci_pdc_cleanup(struct atmel_mci *host)
+{
+       struct mmc_data         *data = host->data;
 
        if (data)
-               dma_unmap_sg(host->dma.chan->device->dev,
-                            data->sg, data->sg_len,
-                            ((data->flags & MMC_DATA_WRITE)
-                             ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+               dma_unmap_sg(&host->pdev->dev,
+                               data->sg, data->sg_len,
+                               ((data->flags & MMC_DATA_WRITE)
+                                ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
 }
 
-static void atmci_stop_dma(struct atmel_mci *host)
+/*
+ * Disable PDC transfers. Update pending flags to EVENT_XFER_COMPLETE after
+ * having received ATMCI_TXBUFE or ATMCI_RXBUFF interrupt. Enable ATMCI_NOTBUSY
+ * interrupt needed for both transfer directions.
+ */
+static void atmci_pdc_complete(struct atmel_mci *host)
 {
-       struct dma_chan *chan = host->data_chan;
+       atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
+       atmci_pdc_cleanup(host);
 
-       if (chan) {
-               dmaengine_terminate_all(chan);
-               atmci_dma_cleanup(host);
-       } else {
-               /* Data transfer was stopped by the interrupt handler */
+       /*
+        * If the card was removed, data will be NULL. No point trying
+        * to send the stop command or waiting for NBUSY in this case.
+        */
+       if (host->data) {
                atmci_set_pending(host, EVENT_XFER_COMPLETE);
-               mci_writel(host, IER, MCI_NOTBUSY);
+               tasklet_schedule(&host->tasklet);
+               atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
        }
 }
 
-/* This function is called by the DMA driver from tasklet context. */
+static void atmci_dma_cleanup(struct atmel_mci *host)
+{
+       struct mmc_data                 *data = host->data;
+
+       if (data)
+               dma_unmap_sg(host->dma.chan->device->dev,
+                               data->sg, data->sg_len,
+                               ((data->flags & MMC_DATA_WRITE)
+                                ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+}
+
+/*
+ * This function is called by the DMA driver from tasklet context.
+ */
 static void atmci_dma_complete(void *arg)
 {
        struct atmel_mci        *host = arg;
@@ -607,9 +695,9 @@ static void atmci_dma_complete(void *arg)
 
        dev_vdbg(&host->pdev->dev, "DMA complete\n");
 
-       if (atmci_is_mci2())
+       if (host->caps.has_dma)
                /* Disable DMA hardware handshaking on MCI */
-               mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN);
+               atmci_writel(host, ATMCI_DMA, atmci_readl(host, ATMCI_DMA) & ~ATMCI_DMAEN);
 
        atmci_dma_cleanup(host);
 
@@ -641,11 +729,93 @@ static void atmci_dma_complete(void *arg)
                 * completion callback" rule of the dma engine
                 * framework.
                 */
-               mci_writel(host, IER, MCI_NOTBUSY);
+               atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
        }
 }
 
-static int
+/*
+ * Returns a mask of interrupt flags to be enabled after the whole
+ * request has been prepared.
+ */
+static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
+{
+       u32 iflags;
+
+       data->error = -EINPROGRESS;
+
+       host->sg = data->sg;
+       host->data = data;
+       host->data_chan = NULL;
+
+       iflags = ATMCI_DATA_ERROR_FLAGS;
+
+       /*
+        * Errata: MMC data write operation with less than 12
+        * bytes is impossible.
+        *
+        * Errata: MCI Transmit Data Register (TDR) FIFO
+        * corruption when length is not multiple of 4.
+        */
+       if (data->blocks * data->blksz < 12
+                       || (data->blocks * data->blksz) & 3)
+               host->need_reset = true;
+
+       host->pio_offset = 0;
+       if (data->flags & MMC_DATA_READ)
+               iflags |= ATMCI_RXRDY;
+       else
+               iflags |= ATMCI_TXRDY;
+
+       return iflags;
+}
+
+/*
+ * Set interrupt flags and set block length into the MCI mode register even
+ * if this value is also accessible in the MCI block register. It seems to be
+ * necessary before the High Speed MCI version. It also map sg and configure
+ * PDC registers.
+ */
+static u32
+atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
+{
+       u32 iflags, tmp;
+       unsigned int sg_len;
+       enum dma_data_direction dir;
+
+       data->error = -EINPROGRESS;
+
+       host->data = data;
+       host->sg = data->sg;
+       iflags = ATMCI_DATA_ERROR_FLAGS;
+
+       /* Enable pdc mode */
+       atmci_writel(host, ATMCI_MR, host->mode_reg | ATMCI_MR_PDCMODE);
+
+       if (data->flags & MMC_DATA_READ) {
+               dir = DMA_FROM_DEVICE;
+               iflags |= ATMCI_ENDRX | ATMCI_RXBUFF;
+       } else {
+               dir = DMA_TO_DEVICE;
+               iflags |= ATMCI_ENDTX | ATMCI_TXBUFE;
+       }
+
+       /* Set BLKLEN */
+       tmp = atmci_readl(host, ATMCI_MR);
+       tmp &= 0x0000ffff;
+       tmp |= ATMCI_BLKLEN(data->blksz);
+       atmci_writel(host, ATMCI_MR, tmp);
+
+       /* Configure PDC */
+       host->data_size = data->blocks * data->blksz;
+       sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, dir);
+       if (host->data_size)
+               atmci_pdc_set_both_buf(host,
+                       ((dir == DMA_FROM_DEVICE) ? XFER_RECEIVE : XFER_TRANSMIT));
+
+       return iflags;
+}
+
+static u32
 atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
 {
        struct dma_chan                 *chan;
@@ -654,6 +824,15 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
        unsigned int                    i;
        enum dma_data_direction         direction;
        unsigned int                    sglen;
+       u32 iflags;
+
+       data->error = -EINPROGRESS;
+
+       WARN_ON(host->data);
+       host->sg = NULL;
+       host->data = data;
+
+       iflags = ATMCI_DATA_ERROR_FLAGS;
 
        /*
         * We don't do DMA on "complex" transfers, i.e. with
@@ -661,13 +840,13 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
         * with all the DMA setup overhead for short transfers.
         */
        if (data->blocks * data->blksz < ATMCI_DMA_THRESHOLD)
-               return -EINVAL;
+               return atmci_prepare_data(host, data);
        if (data->blksz & 3)
-               return -EINVAL;
+               return atmci_prepare_data(host, data);
 
        for_each_sg(data->sg, sg, data->sg_len, i) {
                if (sg->offset & 3 || sg->length & 3)
-                       return -EINVAL;
+                       return atmci_prepare_data(host, data);
        }
 
        /* If we don't have a channel, we can't do DMA */
@@ -678,8 +857,8 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
        if (!chan)
                return -ENODEV;
 
-       if (atmci_is_mci2())
-               mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN);
+       if (host->caps.has_dma)
+               atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN);
 
        if (data->flags & MMC_DATA_READ)
                direction = DMA_FROM_DEVICE;
@@ -687,7 +866,7 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
                direction = DMA_TO_DEVICE;
 
        sglen = dma_map_sg(chan->device->dev, data->sg,
-                          data->sg_len, direction);
+                       data->sg_len, direction);
 
        desc = chan->device->device_prep_slave_sg(chan,
                        data->sg, sglen, direction,
@@ -699,13 +878,32 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
        desc->callback = atmci_dma_complete;
        desc->callback_param = host;
 
-       return 0;
+       return iflags;
 unmap_exit:
        dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, direction);
        return -ENOMEM;
 }
 
-static void atmci_submit_data(struct atmel_mci *host)
+static void
+atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
+{
+       return;
+}
+
+/*
+ * Start PDC according to transfer direction.
+ */
+static void
+atmci_submit_data_pdc(struct atmel_mci *host, struct mmc_data *data)
+{
+       if (data->flags & MMC_DATA_READ)
+               atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
+       else
+               atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
+}
+
+static void
+atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
 {
        struct dma_chan                 *chan = host->data_chan;
        struct dma_async_tx_descriptor  *desc = host->dma.data_desc;
@@ -716,64 +914,39 @@ static void atmci_submit_data(struct atmel_mci *host)
        }
 }
 
-#else /* CONFIG_MMC_ATMELMCI_DMA */
-
-static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
-{
-       return -ENOSYS;
-}
-
-static void atmci_submit_data(struct atmel_mci *host) {}
-
-static void atmci_stop_dma(struct atmel_mci *host)
+static void atmci_stop_transfer(struct atmel_mci *host)
 {
-       /* Data transfer was stopped by the interrupt handler */
        atmci_set_pending(host, EVENT_XFER_COMPLETE);
-       mci_writel(host, IER, MCI_NOTBUSY);
+       atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
 }
 
-#endif /* CONFIG_MMC_ATMELMCI_DMA */
-
 /*
- * Returns a mask of interrupt flags to be enabled after the whole
- * request has been prepared.
+ * Stop data transfer because error(s) occured.
  */
-static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
+static void atmci_stop_transfer_pdc(struct atmel_mci *host)
 {
-       u32 iflags;
-
-       data->error = -EINPROGRESS;
-
-       WARN_ON(host->data);
-       host->sg = NULL;
-       host->data = data;
-
-       iflags = ATMCI_DATA_ERROR_FLAGS;
-       if (atmci_prepare_data_dma(host, data)) {
-               host->data_chan = NULL;
+       atmci_set_pending(host, EVENT_XFER_COMPLETE);
+       atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
+}
 
-               /*
-                * Errata: MMC data write operation with less than 12
-                * bytes is impossible.
-                *
-                * Errata: MCI Transmit Data Register (TDR) FIFO
-                * corruption when length is not multiple of 4.
-                */
-               if (data->blocks * data->blksz < 12
-                               || (data->blocks * data->blksz) & 3)
-                       host->need_reset = true;
+static void atmci_stop_transfer_dma(struct atmel_mci *host)
+{
+       struct dma_chan *chan = host->data_chan;
 
-               host->sg = data->sg;
-               host->pio_offset = 0;
-               if (data->flags & MMC_DATA_READ)
-                       iflags |= MCI_RXRDY;
-               else
-                       iflags |= MCI_TXRDY;
+       if (chan) {
+               dmaengine_terminate_all(chan);
+               atmci_dma_cleanup(host);
+       } else {
+               /* Data transfer was stopped by the interrupt handler */
+               atmci_set_pending(host, EVENT_XFER_COMPLETE);
+               atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
        }
-
-       return iflags;
 }
 
+/*
+ * Start a request: prepare data if needed, prepare the command and activate
+ * interrupts.
+ */
 static void atmci_start_request(struct atmel_mci *host,
                struct atmel_mci_slot *slot)
 {
@@ -792,24 +965,24 @@ static void atmci_start_request(struct atmel_mci *host,
        host->data_status = 0;
 
        if (host->need_reset) {
-               mci_writel(host, CR, MCI_CR_SWRST);
-               mci_writel(host, CR, MCI_CR_MCIEN);
-               mci_writel(host, MR, host->mode_reg);
-               if (atmci_is_mci2())
-                       mci_writel(host, CFG, host->cfg_reg);
+               atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
+               atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
+               atmci_writel(host, ATMCI_MR, host->mode_reg);
+               if (host->caps.has_cfg_reg)
+                       atmci_writel(host, ATMCI_CFG, host->cfg_reg);
                host->need_reset = false;
        }
-       mci_writel(host, SDCR, slot->sdc_reg);
+       atmci_writel(host, ATMCI_SDCR, slot->sdc_reg);
 
-       iflags = mci_readl(host, IMR);
-       if (iflags & ~(MCI_SDIOIRQA | MCI_SDIOIRQB))
+       iflags = atmci_readl(host, ATMCI_IMR);
+       if (iflags & ~(ATMCI_SDIOIRQA | ATMCI_SDIOIRQB))
                dev_warn(&slot->mmc->class_dev, "WARNING: IMR=0x%08x\n",
                                iflags);
 
        if (unlikely(test_and_clear_bit(ATMCI_CARD_NEED_INIT, &slot->flags))) {
                /* Send init sequence (74 clock cycles) */
-               mci_writel(host, CMDR, MCI_CMDR_SPCMD_INIT);
-               while (!(mci_readl(host, SR) & MCI_CMDRDY))
+               atmci_writel(host, ATMCI_CMDR, ATMCI_CMDR_SPCMD_INIT);
+               while (!(atmci_readl(host, ATMCI_SR) & ATMCI_CMDRDY))
                        cpu_relax();
        }
        iflags = 0;
@@ -818,31 +991,31 @@ static void atmci_start_request(struct atmel_mci *host,
                atmci_set_timeout(host, slot, data);
 
                /* Must set block count/size before sending command */
-               mci_writel(host, BLKR, MCI_BCNT(data->blocks)
-                               | MCI_BLKLEN(data->blksz));
+               atmci_writel(host, ATMCI_BLKR, ATMCI_BCNT(data->blocks)
+                               | ATMCI_BLKLEN(data->blksz));
                dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n",
-                       MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
+                       ATMCI_BCNT(data->blocks) | ATMCI_BLKLEN(data->blksz));
 
-               iflags |= atmci_prepare_data(host, data);
+               iflags |= host->prepare_data(host, data);
        }
 
-       iflags |= MCI_CMDRDY;
+       iflags |= ATMCI_CMDRDY;
        cmd = mrq->cmd;
        cmdflags = atmci_prepare_command(slot->mmc, cmd);
-       atmci_start_command(host, cmd, cmdflags);
+       atmci_send_command(host, cmd, cmdflags);
 
        if (data)
-               atmci_submit_data(host);
+               host->submit_data(host, data);
 
        if (mrq->stop) {
                host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
-               host->stop_cmdr |= MCI_CMDR_STOP_XFER;
+               host->stop_cmdr |= ATMCI_CMDR_STOP_XFER;
                if (!(data->flags & MMC_DATA_WRITE))
-                       host->stop_cmdr |= MCI_CMDR_TRDIR_READ;
+                       host->stop_cmdr |= ATMCI_CMDR_TRDIR_READ;
                if (data->flags & MMC_DATA_STREAM)
-                       host->stop_cmdr |= MCI_CMDR_STREAM;
+                       host->stop_cmdr |= ATMCI_CMDR_STREAM;
                else
-                       host->stop_cmdr |= MCI_CMDR_MULTI_BLOCK;
+                       host->stop_cmdr |= ATMCI_CMDR_MULTI_BLOCK;
        }
 
        /*
@@ -851,7 +1024,7 @@ static void atmci_start_request(struct atmel_mci *host,
         * conditions (e.g. command and data complete, but stop not
         * prepared yet.)
         */
-       mci_writel(host, IER, iflags);
+       atmci_writel(host, ATMCI_IER, iflags);
 }
 
 static void atmci_queue_request(struct atmel_mci *host,
@@ -909,13 +1082,13 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct atmel_mci        *host = slot->host;
        unsigned int            i;
 
-       slot->sdc_reg &= ~MCI_SDCBUS_MASK;
+       slot->sdc_reg &= ~ATMCI_SDCBUS_MASK;
        switch (ios->bus_width) {
        case MMC_BUS_WIDTH_1:
-               slot->sdc_reg |= MCI_SDCBUS_1BIT;
+               slot->sdc_reg |= ATMCI_SDCBUS_1BIT;
                break;
        case MMC_BUS_WIDTH_4:
-               slot->sdc_reg |= MCI_SDCBUS_4BIT;
+               slot->sdc_reg |= ATMCI_SDCBUS_4BIT;
                break;
        }
 
@@ -926,10 +1099,10 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                spin_lock_bh(&host->lock);
                if (!host->mode_reg) {
                        clk_enable(host->mck);
-                       mci_writel(host, CR, MCI_CR_SWRST);
-                       mci_writel(host, CR, MCI_CR_MCIEN);
-                       if (atmci_is_mci2())
-                               mci_writel(host, CFG, host->cfg_reg);
+                       atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
+                       atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
+                       if (host->caps.has_cfg_reg)
+                               atmci_writel(host, ATMCI_CFG, host->cfg_reg);
                }
 
                /*
@@ -937,7 +1110,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                 * core ios update when finding the minimum.
                 */
                slot->clock = ios->clock;
-               for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+               for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                        if (host->slot[i] && host->slot[i]->clock
                                        && host->slot[i]->clock < clock_min)
                                clock_min = host->slot[i]->clock;
@@ -952,28 +1125,28 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        clkdiv = 255;
                }
 
-               host->mode_reg = MCI_MR_CLKDIV(clkdiv);
+               host->mode_reg = ATMCI_MR_CLKDIV(clkdiv);
 
                /*
                 * WRPROOF and RDPROOF prevent overruns/underruns by
                 * stopping the clock when the FIFO is full/empty.
                 * This state is not expected to last for long.
                 */
-               if (mci_has_rwproof())
-                       host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF);
+               if (host->caps.has_rwproof)
+                       host->mode_reg |= (ATMCI_MR_WRPROOF | ATMCI_MR_RDPROOF);
 
-               if (atmci_is_mci2()) {
+               if (host->caps.has_cfg_reg) {
                        /* setup High Speed mode in relation with card capacity */
                        if (ios->timing == MMC_TIMING_SD_HS)
-                               host->cfg_reg |= MCI_CFG_HSMODE;
+                               host->cfg_reg |= ATMCI_CFG_HSMODE;
                        else
-                               host->cfg_reg &= ~MCI_CFG_HSMODE;
+                               host->cfg_reg &= ~ATMCI_CFG_HSMODE;
                }
 
                if (list_empty(&host->queue)) {
-                       mci_writel(host, MR, host->mode_reg);
-                       if (atmci_is_mci2())
-                               mci_writel(host, CFG, host->cfg_reg);
+                       atmci_writel(host, ATMCI_MR, host->mode_reg);
+                       if (host->caps.has_cfg_reg)
+                               atmci_writel(host, ATMCI_CFG, host->cfg_reg);
                } else {
                        host->need_clock_update = true;
                }
@@ -984,16 +1157,16 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
                spin_lock_bh(&host->lock);
                slot->clock = 0;
-               for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+               for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                        if (host->slot[i] && host->slot[i]->clock) {
                                any_slot_active = true;
                                break;
                        }
                }
                if (!any_slot_active) {
-                       mci_writel(host, CR, MCI_CR_MCIDIS);
+                       atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
                        if (host->mode_reg) {
-                               mci_readl(host, MR);
+                               atmci_readl(host, ATMCI_MR);
                                clk_disable(host->mck);
                        }
                        host->mode_reg = 0;
@@ -1057,9 +1230,9 @@ static void atmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
        struct atmel_mci        *host = slot->host;
 
        if (enable)
-               mci_writel(host, IER, slot->sdio_irq);
+               atmci_writel(host, ATMCI_IER, slot->sdio_irq);
        else
-               mci_writel(host, IDR, slot->sdio_irq);
+               atmci_writel(host, ATMCI_IDR, slot->sdio_irq);
 }
 
 static const struct mmc_host_ops atmci_ops = {
@@ -1086,9 +1259,9 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq)
         * busy transferring data.
         */
        if (host->need_clock_update) {
-               mci_writel(host, MR, host->mode_reg);
-               if (atmci_is_mci2())
-                       mci_writel(host, CFG, host->cfg_reg);
+               atmci_writel(host, ATMCI_MR, host->mode_reg);
+               if (host->caps.has_cfg_reg)
+                       atmci_writel(host, ATMCI_CFG, host->cfg_reg);
        }
 
        host->cur_slot->mrq = NULL;
@@ -1117,16 +1290,16 @@ static void atmci_command_complete(struct atmel_mci *host,
        u32             status = host->cmd_status;
 
        /* Read the response from the card (up to 16 bytes) */
-       cmd->resp[0] = mci_readl(host, RSPR);
-       cmd->resp[1] = mci_readl(host, RSPR);
-       cmd->resp[2] = mci_readl(host, RSPR);
-       cmd->resp[3] = mci_readl(host, RSPR);
+       cmd->resp[0] = atmci_readl(host, ATMCI_RSPR);
+       cmd->resp[1] = atmci_readl(host, ATMCI_RSPR);
+       cmd->resp[2] = atmci_readl(host, ATMCI_RSPR);
+       cmd->resp[3] = atmci_readl(host, ATMCI_RSPR);
 
-       if (status & MCI_RTOE)
+       if (status & ATMCI_RTOE)
                cmd->error = -ETIMEDOUT;
-       else if ((cmd->flags & MMC_RSP_CRC) && (status & MCI_RCRCE))
+       else if ((cmd->flags & MMC_RSP_CRC) && (status & ATMCI_RCRCE))
                cmd->error = -EILSEQ;
-       else if (status & (MCI_RINDE | MCI_RDIRE | MCI_RENDE))
+       else if (status & (ATMCI_RINDE | ATMCI_RDIRE | ATMCI_RENDE))
                cmd->error = -EIO;
        else
                cmd->error = 0;
@@ -1136,10 +1309,10 @@ static void atmci_command_complete(struct atmel_mci *host,
                        "command error: status=0x%08x\n", status);
 
                if (cmd->data) {
-                       atmci_stop_dma(host);
+                       host->stop_transfer(host);
                        host->data = NULL;
-                       mci_writel(host, IDR, MCI_NOTBUSY
-                                       | MCI_TXRDY | MCI_RXRDY
+                       atmci_writel(host, ATMCI_IDR, ATMCI_NOTBUSY
+                                       | ATMCI_TXRDY | ATMCI_RXRDY
                                        | ATMCI_DATA_ERROR_FLAGS);
                }
        }
@@ -1191,11 +1364,11 @@ static void atmci_detect_change(unsigned long data)
                                 * Reset controller to terminate any ongoing
                                 * commands or data transfers.
                                 */
-                               mci_writel(host, CR, MCI_CR_SWRST);
-                               mci_writel(host, CR, MCI_CR_MCIEN);
-                               mci_writel(host, MR, host->mode_reg);
-                               if (atmci_is_mci2())
-                                       mci_writel(host, CFG, host->cfg_reg);
+                               atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
+                               atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN);
+                               atmci_writel(host, ATMCI_MR, host->mode_reg);
+                               if (host->caps.has_cfg_reg)
+                                       atmci_writel(host, ATMCI_CFG, host->cfg_reg);
 
                                host->data = NULL;
                                host->cmd = NULL;
@@ -1210,7 +1383,7 @@ static void atmci_detect_change(unsigned long data)
                                        /* fall through */
                                case STATE_SENDING_DATA:
                                        mrq->data->error = -ENOMEDIUM;
-                                       atmci_stop_dma(host);
+                                       host->stop_transfer(host);
                                        break;
                                case STATE_DATA_BUSY:
                                case STATE_DATA_ERROR:
@@ -1261,7 +1434,7 @@ static void atmci_tasklet_func(unsigned long priv)
        dev_vdbg(&host->pdev->dev,
                "tasklet: state %u pending/completed/mask %lx/%lx/%x\n",
                state, host->pending_events, host->completed_events,
-               mci_readl(host, IMR));
+               atmci_readl(host, ATMCI_IMR));
 
        do {
                prev_state = state;
@@ -1289,9 +1462,9 @@ static void atmci_tasklet_func(unsigned long priv)
                case STATE_SENDING_DATA:
                        if (atmci_test_and_clear_pending(host,
                                                EVENT_DATA_ERROR)) {
-                               atmci_stop_dma(host);
+                               host->stop_transfer(host);
                                if (data->stop)
-                                       send_stop_cmd(host, data);
+                                       atmci_send_stop_cmd(host, data);
                                state = STATE_DATA_ERROR;
                                break;
                        }
@@ -1313,11 +1486,11 @@ static void atmci_tasklet_func(unsigned long priv)
                        atmci_set_completed(host, EVENT_DATA_COMPLETE);
                        status = host->data_status;
                        if (unlikely(status & ATMCI_DATA_ERROR_FLAGS)) {
-                               if (status & MCI_DTOE) {
+                               if (status & ATMCI_DTOE) {
                                        dev_dbg(&host->pdev->dev,
                                                        "data timeout error\n");
                                        data->error = -ETIMEDOUT;
-                               } else if (status & MCI_DCRCE) {
+                               } else if (status & ATMCI_DCRCE) {
                                        dev_dbg(&host->pdev->dev,
                                                        "data CRC error\n");
                                        data->error = -EILSEQ;
@@ -1330,7 +1503,7 @@ static void atmci_tasklet_func(unsigned long priv)
                        } else {
                                data->bytes_xfered = data->blocks * data->blksz;
                                data->error = 0;
-                               mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS);
+                               atmci_writel(host, ATMCI_IDR, ATMCI_DATA_ERROR_FLAGS);
                        }
 
                        if (!data->stop) {
@@ -1340,7 +1513,7 @@ static void atmci_tasklet_func(unsigned long priv)
 
                        prev_state = state = STATE_SENDING_STOP;
                        if (!data->error)
-                               send_stop_cmd(host, data);
+                               atmci_send_stop_cmd(host, data);
                        /* fall through */
 
                case STATE_SENDING_STOP:
@@ -1380,7 +1553,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
        unsigned int            nbytes = 0;
 
        do {
-               value = mci_readl(host, RDR);
+               value = atmci_readl(host, ATMCI_RDR);
                if (likely(offset + 4 <= sg->length)) {
                        put_unaligned(value, (u32 *)(buf + offset));
 
@@ -1412,9 +1585,9 @@ static void atmci_read_data_pio(struct atmel_mci *host)
                        nbytes += offset;
                }
 
-               status = mci_readl(host, SR);
+               status = atmci_readl(host, ATMCI_SR);
                if (status & ATMCI_DATA_ERROR_FLAGS) {
-                       mci_writel(host, IDR, (MCI_NOTBUSY | MCI_RXRDY
+                       atmci_writel(host, ATMCI_IDR, (ATMCI_NOTBUSY | ATMCI_RXRDY
                                                | ATMCI_DATA_ERROR_FLAGS));
                        host->data_status = status;
                        data->bytes_xfered += nbytes;
@@ -1423,7 +1596,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
                        tasklet_schedule(&host->tasklet);
                        return;
                }
-       } while (status & MCI_RXRDY);
+       } while (status & ATMCI_RXRDY);
 
        host->pio_offset = offset;
        data->bytes_xfered += nbytes;
@@ -1431,8 +1604,8 @@ static void atmci_read_data_pio(struct atmel_mci *host)
        return;
 
 done:
-       mci_writel(host, IDR, MCI_RXRDY);
-       mci_writel(host, IER, MCI_NOTBUSY);
+       atmci_writel(host, ATMCI_IDR, ATMCI_RXRDY);
+       atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
        data->bytes_xfered += nbytes;
        smp_wmb();
        atmci_set_pending(host, EVENT_XFER_COMPLETE);
@@ -1451,7 +1624,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
        do {
                if (likely(offset + 4 <= sg->length)) {
                        value = get_unaligned((u32 *)(buf + offset));
-                       mci_writel(host, TDR, value);
+                       atmci_writel(host, ATMCI_TDR, value);
 
                        offset += 4;
                        nbytes += 4;
@@ -1472,20 +1645,20 @@ static void atmci_write_data_pio(struct atmel_mci *host)
 
                        host->sg = sg = sg_next(sg);
                        if (!sg) {
-                               mci_writel(host, TDR, value);
+                               atmci_writel(host, ATMCI_TDR, value);
                                goto done;
                        }
 
                        offset = 4 - remaining;
                        buf = sg_virt(sg);
                        memcpy((u8 *)&value + remaining, buf, offset);
-                       mci_writel(host, TDR, value);
+                       atmci_writel(host, ATMCI_TDR, value);
                        nbytes += offset;
                }
 
-               status = mci_readl(host, SR);
+               status = atmci_readl(host, ATMCI_SR);
                if (status & ATMCI_DATA_ERROR_FLAGS) {
-                       mci_writel(host, IDR, (MCI_NOTBUSY | MCI_TXRDY
+                       atmci_writel(host, ATMCI_IDR, (ATMCI_NOTBUSY | ATMCI_TXRDY
                                                | ATMCI_DATA_ERROR_FLAGS));
                        host->data_status = status;
                        data->bytes_xfered += nbytes;
@@ -1494,7 +1667,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
                        tasklet_schedule(&host->tasklet);
                        return;
                }
-       } while (status & MCI_TXRDY);
+       } while (status & ATMCI_TXRDY);
 
        host->pio_offset = offset;
        data->bytes_xfered += nbytes;
@@ -1502,8 +1675,8 @@ static void atmci_write_data_pio(struct atmel_mci *host)
        return;
 
 done:
-       mci_writel(host, IDR, MCI_TXRDY);
-       mci_writel(host, IER, MCI_NOTBUSY);
+       atmci_writel(host, ATMCI_IDR, ATMCI_TXRDY);
+       atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
        data->bytes_xfered += nbytes;
        smp_wmb();
        atmci_set_pending(host, EVENT_XFER_COMPLETE);
@@ -1511,7 +1684,7 @@ done:
 
 static void atmci_cmd_interrupt(struct atmel_mci *host, u32 status)
 {
-       mci_writel(host, IDR, MCI_CMDRDY);
+       atmci_writel(host, ATMCI_IDR, ATMCI_CMDRDY);
 
        host->cmd_status = status;
        smp_wmb();
@@ -1523,7 +1696,7 @@ static void atmci_sdio_interrupt(struct atmel_mci *host, u32 status)
 {
        int     i;
 
-       for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+       for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                struct atmel_mci_slot *slot = host->slot[i];
                if (slot && (status & slot->sdio_irq)) {
                        mmc_signal_sdio_irq(slot->mmc);
@@ -1539,40 +1712,92 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
        unsigned int            pass_count = 0;
 
        do {
-               status = mci_readl(host, SR);
-               mask = mci_readl(host, IMR);
+               status = atmci_readl(host, ATMCI_SR);
+               mask = atmci_readl(host, ATMCI_IMR);
                pending = status & mask;
                if (!pending)
                        break;
 
                if (pending & ATMCI_DATA_ERROR_FLAGS) {
-                       mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS
-                                       | MCI_RXRDY | MCI_TXRDY);
-                       pending &= mci_readl(host, IMR);
+                       atmci_writel(host, ATMCI_IDR, ATMCI_DATA_ERROR_FLAGS
+                                       | ATMCI_RXRDY | ATMCI_TXRDY);
+                       pending &= atmci_readl(host, ATMCI_IMR);
 
                        host->data_status = status;
                        smp_wmb();
                        atmci_set_pending(host, EVENT_DATA_ERROR);
                        tasklet_schedule(&host->tasklet);
                }
-               if (pending & MCI_NOTBUSY) {
-                       mci_writel(host, IDR,
-                                       ATMCI_DATA_ERROR_FLAGS | MCI_NOTBUSY);
+
+               if (pending & ATMCI_TXBUFE) {
+                       atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE);
+                       atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
+                       /*
+                        * We can receive this interruption before having configured
+                        * the second pdc buffer, so we need to reconfigure first and
+                        * second buffers again
+                        */
+                       if (host->data_size) {
+                               atmci_pdc_set_both_buf(host, XFER_TRANSMIT);
+                               atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
+                               atmci_writel(host, ATMCI_IER, ATMCI_TXBUFE);
+                       } else {
+                               atmci_pdc_complete(host);
+                       }
+               } else if (pending & ATMCI_ENDTX) {
+                       atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
+
+                       if (host->data_size) {
+                               atmci_pdc_set_single_buf(host,
+                                               XFER_TRANSMIT, PDC_SECOND_BUF);
+                               atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
+                       }
+               }
+
+               if (pending & ATMCI_RXBUFF) {
+                       atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF);
+                       atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
+                       /*
+                        * We can receive this interruption before having configured
+                        * the second pdc buffer, so we need to reconfigure first and
+                        * second buffers again
+                        */
+                       if (host->data_size) {
+                               atmci_pdc_set_both_buf(host, XFER_RECEIVE);
+                               atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
+                               atmci_writel(host, ATMCI_IER, ATMCI_RXBUFF);
+                       } else {
+                               atmci_pdc_complete(host);
+                       }
+               } else if (pending & ATMCI_ENDRX) {
+                       atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
+
+                       if (host->data_size) {
+                               atmci_pdc_set_single_buf(host,
+                                               XFER_RECEIVE, PDC_SECOND_BUF);
+                               atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
+                       }
+               }
+
+
+               if (pending & ATMCI_NOTBUSY) {
+                       atmci_writel(host, ATMCI_IDR,
+                                       ATMCI_DATA_ERROR_FLAGS | ATMCI_NOTBUSY);
                        if (!host->data_status)
                                host->data_status = status;
                        smp_wmb();
                        atmci_set_pending(host, EVENT_DATA_COMPLETE);
                        tasklet_schedule(&host->tasklet);
                }
-               if (pending & MCI_RXRDY)
+               if (pending & ATMCI_RXRDY)
                        atmci_read_data_pio(host);
-               if (pending & MCI_TXRDY)
+               if (pending & ATMCI_TXRDY)
                        atmci_write_data_pio(host);
 
-               if (pending & MCI_CMDRDY)
+               if (pending & ATMCI_CMDRDY)
                        atmci_cmd_interrupt(host, status);
 
-               if (pending & (MCI_SDIOIRQA | MCI_SDIOIRQB))
+               if (pending & (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB))
                        atmci_sdio_interrupt(host, status);
 
        } while (pass_count++ < 5);
@@ -1621,7 +1846,7 @@ static int __init atmci_init_slot(struct atmel_mci *host,
        mmc->ocr_avail  = MMC_VDD_32_33 | MMC_VDD_33_34;
        if (sdio_irq)
                mmc->caps |= MMC_CAP_SDIO_IRQ;
-       if (atmci_is_mci2())
+       if (host->caps.has_highspeed)
                mmc->caps |= MMC_CAP_SD_HIGHSPEED;
        if (slot_data->bus_width >= 4)
                mmc->caps |= MMC_CAP_4_BIT_DATA;
@@ -1704,8 +1929,7 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot,
        mmc_free_host(slot->mmc);
 }
 
-#ifdef CONFIG_MMC_ATMELMCI_DMA
-static bool filter(struct dma_chan *chan, void *slave)
+static bool atmci_filter(struct dma_chan *chan, void *slave)
 {
        struct mci_dma_data     *sl = slave;
 
@@ -1730,14 +1954,14 @@ static void atmci_configure_dma(struct atmel_mci *host)
                dma_cap_mask_t mask;
 
                setup_dma_addr(pdata->dma_slave,
-                              host->mapbase + MCI_TDR,
-                              host->mapbase + MCI_RDR);
+                              host->mapbase + ATMCI_TDR,
+                              host->mapbase + ATMCI_RDR);
 
                /* Try to grab a DMA channel */
                dma_cap_zero(mask);
                dma_cap_set(DMA_SLAVE, mask);
                host->dma.chan =
-                       dma_request_channel(mask, filter, pdata->dma_slave);
+                       dma_request_channel(mask, atmci_filter, pdata->dma_slave);
        }
        if (!host->dma.chan)
                dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
@@ -1746,9 +1970,60 @@ static void atmci_configure_dma(struct atmel_mci *host)
                                        "Using %s for DMA transfers\n",
                                        dma_chan_name(host->dma.chan));
 }
+
+static inline unsigned int atmci_get_version(struct atmel_mci *host)
+{
+       return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
+}
+
+/*
+ * HSMCI (High Speed MCI) module is not fully compatible with MCI module.
+ * HSMCI provides DMA support and a new config register but no more supports
+ * PDC.
+ */
+static void __init atmci_get_cap(struct atmel_mci *host)
+{
+       unsigned int version;
+
+       version = atmci_get_version(host);
+       dev_info(&host->pdev->dev,
+                       "version: 0x%x\n", version);
+
+       host->caps.has_dma = 0;
+       host->caps.has_pdc = 0;
+       host->caps.has_cfg_reg = 0;
+       host->caps.has_cstor_reg = 0;
+       host->caps.has_highspeed = 0;
+       host->caps.has_rwproof = 0;
+
+       /* keep only major version number */
+       switch (version & 0xf00) {
+       case 0x100:
+       case 0x200:
+               host->caps.has_pdc = 1;
+               host->caps.has_rwproof = 1;
+               break;
+       case 0x300:
+       case 0x400:
+       case 0x500:
+#ifdef CONFIG_AT_HDMAC
+               host->caps.has_dma = 1;
 #else
-static void atmci_configure_dma(struct atmel_mci *host) {}
+               host->caps.has_dma = 0;
+               dev_info(&host->pdev->dev,
+                       "has dma capability but dma engine is not selected, then use pio\n");
 #endif
+               host->caps.has_cfg_reg = 1;
+               host->caps.has_cstor_reg = 1;
+               host->caps.has_highspeed = 1;
+               host->caps.has_rwproof = 1;
+               break;
+       default:
+               dev_warn(&host->pdev->dev,
+                               "Unmanaged mci version, set minimum capabilities\n");
+               break;
+       }
+}
 
 static int __init atmci_probe(struct platform_device *pdev)
 {
@@ -1789,7 +2064,7 @@ static int __init atmci_probe(struct platform_device *pdev)
                goto err_ioremap;
 
        clk_enable(host->mck);
-       mci_writel(host, CR, MCI_CR_SWRST);
+       atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST);
        host->bus_hz = clk_get_rate(host->mck);
        clk_disable(host->mck);
 
@@ -1801,7 +2076,27 @@ static int __init atmci_probe(struct platform_device *pdev)
        if (ret)
                goto err_request_irq;
 
-       atmci_configure_dma(host);
+       /* Get MCI capabilities and set operations according to it */
+       atmci_get_cap(host);
+       if (host->caps.has_dma) {
+               dev_info(&pdev->dev, "using DMA\n");
+               host->prepare_data = &atmci_prepare_data_dma;
+               host->submit_data = &atmci_submit_data_dma;
+               host->stop_transfer = &atmci_stop_transfer_dma;
+       } else if (host->caps.has_pdc) {
+               dev_info(&pdev->dev, "using PDC\n");
+               host->prepare_data = &atmci_prepare_data_pdc;
+               host->submit_data = &atmci_submit_data_pdc;
+               host->stop_transfer = &atmci_stop_transfer_pdc;
+       } else {
+               dev_info(&pdev->dev, "no DMA, no PDC\n");
+               host->prepare_data = &atmci_prepare_data;
+               host->submit_data = &atmci_submit_data;
+               host->stop_transfer = &atmci_stop_transfer;
+       }
+
+       if (host->caps.has_dma)
+               atmci_configure_dma(host);
 
        platform_set_drvdata(pdev, host);
 
@@ -1810,13 +2105,13 @@ static int __init atmci_probe(struct platform_device *pdev)
        ret = -ENODEV;
        if (pdata->slot[0].bus_width) {
                ret = atmci_init_slot(host, &pdata->slot[0],
-                               0, MCI_SDCSEL_SLOT_A, MCI_SDIOIRQA);
+                               0, ATMCI_SDCSEL_SLOT_A, ATMCI_SDIOIRQA);
                if (!ret)
                        nr_slots++;
        }
        if (pdata->slot[1].bus_width) {
                ret = atmci_init_slot(host, &pdata->slot[1],
-                               1, MCI_SDCSEL_SLOT_B, MCI_SDIOIRQB);
+                               1, ATMCI_SDCSEL_SLOT_B, ATMCI_SDIOIRQB);
                if (!ret)
                        nr_slots++;
        }
@@ -1833,10 +2128,8 @@ static int __init atmci_probe(struct platform_device *pdev)
        return 0;
 
 err_init_slot:
-#ifdef CONFIG_MMC_ATMELMCI_DMA
        if (host->dma.chan)
                dma_release_channel(host->dma.chan);
-#endif
        free_irq(irq, host);
 err_request_irq:
        iounmap(host->regs);
@@ -1854,15 +2147,15 @@ static int __exit atmci_remove(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, NULL);
 
-       for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+       for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                if (host->slot[i])
                        atmci_cleanup_slot(host->slot[i], i);
        }
 
        clk_enable(host->mck);
-       mci_writel(host, IDR, ~0UL);
-       mci_writel(host, CR, MCI_CR_MCIDIS);
-       mci_readl(host, SR);
+       atmci_writel(host, ATMCI_IDR, ~0UL);
+       atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS);
+       atmci_readl(host, ATMCI_SR);
        clk_disable(host->mck);
 
 #ifdef CONFIG_MMC_ATMELMCI_DMA
@@ -1885,7 +2178,7 @@ static int atmci_suspend(struct device *dev)
        struct atmel_mci *host = dev_get_drvdata(dev);
        int i;
 
-        for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+        for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                struct atmel_mci_slot *slot = host->slot[i];
                int ret;
 
@@ -1916,7 +2209,7 @@ static int atmci_resume(struct device *dev)
        int i;
        int ret = 0;
 
-       for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+       for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
                struct atmel_mci_slot *slot = host->slot[i];
                int err;
 
index a6c329040140420ab73ded04fa08c7ca9cdaa07e..2dba999caf2c997ecf0fb3a53dcb47d63c852d74 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <plat/board.h>
 #include <plat/mmc.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/dma.h>
 #include <plat/mux.h>
 #include <plat/fpga.h>
index 0e9780f5a4a9d8147c9eaa9d1524fd6ebbc59331..4557aa1567a596b417136c1e19f4ce81124da04d 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #define SDHCI_VENDOR_SPEC              0xC0
 #define  SDHCI_VENDOR_SPEC_SDIO_QUIRK  0x00000002
 
+/*
+ * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
+ * Bit25 is used in STD SPEC, and is reserved in fsl eSDHC design,
+ * but bit28 is used as the INT DMA ERR in fsl eSDHC design.
+ * Define this macro DMA error INT for fsl eSDHC
+ */
+#define SDHCI_INT_VENDOR_SPEC_DMA_ERR  0x10000000
+
 /*
  * The CMDTYPE of the CMD register (offset 0xE) should be set to
  * "11" when the STOP CMD12 is issued on imx53 to abort one
@@ -134,6 +143,27 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
                        val |= SDHCI_CARD_PRESENT;
        }
 
+       if (unlikely(reg == SDHCI_CAPABILITIES)) {
+               /* In FSL esdhc IC module, only bit20 is used to indicate the
+                * ADMA2 capability of esdhc, but this bit is messed up on
+                * some SOCs (e.g. on MX25, MX35 this bit is set, but they
+                * don't actually support ADMA2). So set the BROKEN_ADMA
+                * uirk on MX25/35 platforms.
+                */
+
+               if (val & SDHCI_CAN_DO_ADMA1) {
+                       val &= ~SDHCI_CAN_DO_ADMA1;
+                       val |= SDHCI_CAN_DO_ADMA2;
+               }
+       }
+
+       if (unlikely(reg == SDHCI_INT_STATUS)) {
+               if (val & SDHCI_INT_VENDOR_SPEC_DMA_ERR) {
+                       val &= ~SDHCI_INT_VENDOR_SPEC_DMA_ERR;
+                       val |= SDHCI_INT_ADMA_ERROR;
+               }
+       }
+
        return val;
 }
 
@@ -178,6 +208,13 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
                        writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
        }
 
+       if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
+               if (val & SDHCI_INT_ADMA_ERROR) {
+                       val &= ~SDHCI_INT_ADMA_ERROR;
+                       val |= SDHCI_INT_VENDOR_SPEC_DMA_ERR;
+               }
+       }
+
        writel(val, host->ioaddr + reg);
 }
 
@@ -310,9 +347,10 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 };
 
 static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
-       .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
+       .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_HISPD_BIT
+                       | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
+                       | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC
                        | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
-       /* ADMA has issues. Might be fixable */
        .ops = &sdhci_esdhc_ops,
 };
 
@@ -404,7 +442,8 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 
        if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
                /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
-               host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+               host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK
+                       | SDHCI_QUIRK_BROKEN_ADMA;
 
        if (is_imx53_esdhc(imx_data))
                imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
index 18b0bd31de78a661a1839d094e756df9d7ce6762..2ae4a76f89279de0b207b493a20034cdd0225340 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <mach/sdhci.h>
 
 #include "sdhci-pltfm.h"
@@ -73,10 +74,8 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
 
 static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci)
 {
-       struct platform_device *pdev = to_platform_device(mmc_dev(sdhci->mmc));
-       struct tegra_sdhci_platform_data *plat;
-
-       plat = pdev->dev.platform_data;
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
+       struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
 
        if (!gpio_is_valid(plat->wp_gpio))
                return -1;
@@ -94,12 +93,10 @@ static irqreturn_t carddetect_irq(int irq, void *data)
 
 static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
 {
-       struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
-       struct tegra_sdhci_platform_data *plat;
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
        u32 ctrl;
 
-       plat = pdev->dev.platform_data;
-
        ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
        if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) {
                ctrl &= ~SDHCI_CTRL_4BITBUS;
@@ -131,6 +128,34 @@ static struct sdhci_pltfm_data sdhci_tegra_pdata = {
        .ops  = &tegra_sdhci_ops,
 };
 
+static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-sdhci", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
+
+static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
+                                               struct platform_device *pdev)
+{
+       struct tegra_sdhci_platform_data *plat;
+       struct device_node *np = pdev->dev.of_node;
+
+       if (!np)
+               return NULL;
+
+       plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
+       if (!plat) {
+               dev_err(&pdev->dev, "Can't allocate platform data\n");
+               return NULL;
+       }
+
+       plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+       plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+       plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
+
+       return plat;
+}
+
 static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
 {
        struct sdhci_pltfm_host *pltfm_host;
@@ -147,12 +172,17 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
 
        plat = pdev->dev.platform_data;
 
+       if (plat == NULL)
+               plat = sdhci_tegra_dt_parse_pdata(pdev);
+
        if (plat == NULL) {
                dev_err(mmc_dev(host->mmc), "missing platform data\n");
                rc = -ENXIO;
                goto err_no_plat;
        }
 
+       pltfm_host->priv = plat;
+
        if (gpio_is_valid(plat->power_gpio)) {
                rc = gpio_request(plat->power_gpio, "sdhci_power");
                if (rc) {
@@ -247,13 +277,11 @@ static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
 {
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-       struct tegra_sdhci_platform_data *plat;
+       struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
        int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
 
        sdhci_remove_host(host, dead);
 
-       plat = pdev->dev.platform_data;
-
        if (gpio_is_valid(plat->wp_gpio)) {
                tegra_gpio_disable(plat->wp_gpio);
                gpio_free(plat->wp_gpio);
@@ -282,6 +310,7 @@ static struct platform_driver sdhci_tegra_driver = {
        .driver         = {
                .name   = "sdhci-tegra",
                .owner  = THIS_MODULE,
+               .of_match_table = sdhci_tegra_dt_match,
        },
        .probe          = sdhci_tegra_probe,
        .remove         = __devexit_p(sdhci_tegra_remove),
index 774f6439d7ce06be72eee93ee1896e0e32fab9ea..0c4a672f5db618bd68c96b4bb7a6239bdf7f12aa 100644 (file)
@@ -120,11 +120,11 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
        mmc_data->hclk = clk_get_rate(priv->clk);
        mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
        mmc_data->get_cd = sh_mobile_sdhi_get_cd;
-       if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
-               mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
        mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
        if (p) {
                mmc_data->flags = p->tmio_flags;
+               if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
+                       mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
                mmc_data->ocr_mask = p->tmio_ocr_mask;
                mmc_data->capabilities |= p->tmio_caps;
 
index 4be8373d43e5c6af542c8a5a609fc8402e9b1dc0..4925aa962af3539c6bf96b33e694f9a290d5fab0 100644 (file)
@@ -12,19 +12,6 @@ menuconfig MTD
 
 if MTD
 
-config MTD_DEBUG
-       bool "Debugging"
-       help
-         This turns on low-level debugging for the entire MTD sub-system.
-         Normally, you should say 'N'.
-
-config MTD_DEBUG_VERBOSE
-       int "Debugging verbosity (0 = quiet, 3 = noisy)"
-       depends on MTD_DEBUG
-       default "0"
-       help
-         Determines the verbosity level of the MTD debugging messages.
-
 config MTD_TESTS
        tristate "MTD tests support"
        depends on m
@@ -137,7 +124,8 @@ config MTD_AFS_PARTS
          'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
 
 config MTD_OF_PARTS
-       def_bool y
+       tristate "OpenFirmware partitioning information support"
+       default Y
        depends on OF
        help
          This provides a partition parsing function which derives
index 39664c4229ff5139293dc63d27e09837d2a7696b..9aaac3ac89f3f55e64adb4d72f1e94c8c3967e16 100644 (file)
@@ -5,8 +5,8 @@
 # Core functionality.
 obj-$(CONFIG_MTD)              += mtd.o
 mtd-y                          := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o
-mtd-$(CONFIG_MTD_OF_PARTS)     += ofpart.o
 
+obj-$(CONFIG_MTD_OF_PARTS)     += ofpart.o
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
 obj-$(CONFIG_MTD_AFS_PARTS)    += afs.o
index 302372c08b566cf61b7f0022aa059779bc123208..89a02f6f65dc1ae4c2752e6d941602c6a7295709 100644 (file)
@@ -162,8 +162,8 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
 }
 
 static int parse_afs_partitions(struct mtd_info *mtd,
-                         struct mtd_partition **pparts,
-                         unsigned long origin)
+                               struct mtd_partition **pparts,
+                               struct mtd_part_parser_data *data)
 {
        struct mtd_partition *parts;
        u_int mask, off, idx, sz;
index 6697a1ec72d067ec07a42c15986740ea33169095..71bfa2efb3ea233b2f3be377ccaba8241a9e7407 100644 (file)
@@ -46,7 +46,7 @@ struct ar7_bin_rec {
 
 static int create_mtd_partitions(struct mtd_info *master,
                                 struct mtd_partition **pparts,
-                                unsigned long origin)
+                                struct mtd_part_parser_data *data)
 {
        struct ar7_bin_rec header;
        unsigned int offset;
index 23175edd5634ff16190b4d7be6ca74d3392e5e80..8d70895a58d6b424d34563e7f43a2a13df57ddfb 100644 (file)
@@ -145,8 +145,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
        if (((major << 8) | minor) < 0x3131) {
                /* CFI version 1.0 => don't trust bootloc */
 
-               DEBUG(MTD_DEBUG_LEVEL1,
-                       "%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
+               pr_debug("%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
                        map->name, cfi->mfr, cfi->id);
 
                /* AFAICS all 29LV400 with a bottom boot block have a device ID
@@ -166,8 +165,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
                         * the 8-bit device ID.
                         */
                        (cfi->mfr == CFI_MFR_MACRONIX)) {
-                       DEBUG(MTD_DEBUG_LEVEL1,
-                               "%s: Macronix MX29LV400C with bottom boot block"
+                       pr_debug("%s: Macronix MX29LV400C with bottom boot block"
                                " detected\n", map->name);
                        extp->TopBottom = 2;    /* bottom boot */
                } else
@@ -178,8 +176,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
                        extp->TopBottom = 2;    /* bottom boot */
                }
 
-               DEBUG(MTD_DEBUG_LEVEL1,
-                       "%s: AMD CFI PRI V%c.%c has no boot block field;"
+               pr_debug("%s: AMD CFI PRI V%c.%c has no boot block field;"
                        " deduced %s from Device ID\n", map->name, major, minor,
                        extp->TopBottom == 2 ? "bottom" : "top");
        }
@@ -191,7 +188,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
        if (cfi->cfiq->BufWriteTimeoutTyp) {
-               DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
+               pr_debug("Using buffer write method\n" );
                mtd->write = cfi_amdstd_write_buffers;
        }
 }
@@ -443,8 +440,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
        mtd->writesize = 1;
        mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): write buffer size %d\n",
-               __func__, mtd->writebufsize);
+       pr_debug("MTD %s(): write buffer size %d\n", __func__,
+                       mtd->writebufsize);
 
        mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
 
@@ -1163,7 +1160,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
                return ret;
        }
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
+       pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
               __func__, adr, datum.x[0] );
 
        /*
@@ -1174,7 +1171,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
         */
        oldd = map_read(map, adr);
        if (map_word_equal(map, oldd, datum)) {
-               DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP\n",
+               pr_debug("MTD %s(): NOP\n",
                       __func__);
                goto op_done;
        }
@@ -1400,7 +1397,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 
        datum = map_word_load(map, buf);
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
+       pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
               __func__, adr, datum.x[0] );
 
        XIP_INVAL_CACHED_RANGE(map, adr, len);
@@ -1587,7 +1584,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
                return ret;
        }
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
+       pr_debug("MTD %s(): ERASE 0x%.8lx\n",
               __func__, chip->start );
 
        XIP_INVAL_CACHED_RANGE(map, adr, map->size);
@@ -1675,7 +1672,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
                return ret;
        }
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
+       pr_debug("MTD %s(): ERASE 0x%.8lx\n",
               __func__, adr );
 
        XIP_INVAL_CACHED_RANGE(map, adr, len);
@@ -1801,8 +1798,7 @@ static int do_atmel_lock(struct map_info *map, struct flchip *chip,
                goto out_unlock;
        chip->state = FL_LOCKING;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
-             __func__, adr, len);
+       pr_debug("MTD %s(): LOCK 0x%08lx len %d\n", __func__, adr, len);
 
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
                         cfi->device_type, NULL);
@@ -1837,8 +1833,7 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
                goto out_unlock;
        chip->state = FL_UNLOCKING;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
-             __func__, adr, len);
+       pr_debug("MTD %s(): LOCK 0x%08lx len %d\n", __func__, adr, len);
 
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
                         cfi->device_type, NULL);
index 5e3cc80128aa90beec305b168b02c50f56f3b6f8..89c6595454a508925fe6c5accf0fbd44d1af56f9 100644 (file)
@@ -34,8 +34,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
 
        /* Refuse the operation if the we cannot look behind the chip */
        if (chip->start < 0x400000) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                       "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
+               pr_debug( "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
                        __func__, chip->start );
                return -EIO;
        }
index ea832ea0e4aacac6840dbfcfa73a9f7e0262667e..c443f527a53a5d9dae069701c9b1e0c497e63999 100644 (file)
@@ -1914,11 +1914,10 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi)
         * (oh and incidentaly the jedec spec - 3.5.3.3) the reset
         * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
         * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
-        * as they will ignore the writes and dont care what address
+        * as they will ignore the writes and don't care what address
         * the F0 is written to */
        if (cfi->addr_unlock1) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "reset unlock called %x %x \n",
+               pr_debug( "reset unlock called %x %x \n",
                       cfi->addr_unlock1,cfi->addr_unlock2);
                cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
                cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
@@ -1941,7 +1940,7 @@ static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int in
        uint8_t uaddr;
 
        if (!(jedec_table[index].devtypes & cfi->device_type)) {
-               DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n",
+               pr_debug("Rejecting potential %s with incompatible %d-bit device type\n",
                      jedec_table[index].name, 4 * (1<<cfi->device_type));
                return 0;
        }
@@ -2021,7 +2020,7 @@ static inline int jedec_match( uint32_t base,
                 * there aren't.
                 */
                if (finfo->dev_id > 0xff) {
-                       DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
+                       pr_debug("%s(): ID is not 8bit\n",
                               __func__);
                        goto match_done;
                }
@@ -2045,12 +2044,10 @@ static inline int jedec_match( uint32_t base,
        }
 
        /* the part size must fit in the memory window */
-       DEBUG( MTD_DEBUG_LEVEL3,
-              "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
+       pr_debug("MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
               __func__, base, 1 << finfo->dev_size, base + (1 << finfo->dev_size) );
        if ( base + cfi_interleave(cfi) * ( 1 << finfo->dev_size ) > map->size ) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
+               pr_debug("MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
                       __func__, finfo->mfr_id, finfo->dev_id,
                       1 << finfo->dev_size );
                goto match_done;
@@ -2061,13 +2058,12 @@ static inline int jedec_match( uint32_t base,
 
        uaddr = finfo->uaddr;
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
+       pr_debug("MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
               __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
        if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
             && ( unlock_addrs[uaddr].addr1 / cfi->device_type != cfi->addr_unlock1 ||
                  unlock_addrs[uaddr].addr2 / cfi->device_type != cfi->addr_unlock2 ) ) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                       "MTD %s(): 0x%.4x 0x%.4x did not match\n",
+               pr_debug("MTD %s(): 0x%.4x 0x%.4x did not match\n",
                        __func__,
                        unlock_addrs[uaddr].addr1,
                        unlock_addrs[uaddr].addr2);
@@ -2083,15 +2079,13 @@ static inline int jedec_match( uint32_t base,
         * FIXME - write a driver that takes all of the chip info as
         * module parameters, doesn't probe but forces a load.
         */
-       DEBUG( MTD_DEBUG_LEVEL3,
-              "MTD %s(): check ID's disappear when not in ID mode\n",
+       pr_debug("MTD %s(): check ID's disappear when not in ID mode\n",
               __func__ );
        jedec_reset( base, map, cfi );
        mfr = jedec_read_mfr( map, base, cfi );
        id = jedec_read_id( map, base, cfi );
        if ( mfr == cfi->mfr && id == cfi->id ) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
+               pr_debug("MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
                       "You might need to manually specify JEDEC parameters.\n",
                        __func__, cfi->mfr, cfi->id );
                goto match_done;
@@ -2104,7 +2098,7 @@ static inline int jedec_match( uint32_t base,
         * Put the device back in ID mode - only need to do this if we
         * were truly frobbing a real device.
         */
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
+       pr_debug("MTD %s(): return to ID mode\n", __func__ );
        if (cfi->addr_unlock1) {
                cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
                cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
@@ -2167,13 +2161,11 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
 
                cfi->mfr = jedec_read_mfr(map, base, cfi);
                cfi->id = jedec_read_id(map, base, cfi);
-               DEBUG(MTD_DEBUG_LEVEL3,
-                     "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
+               pr_debug("Search for id:(%02x %02x) interleave(%d) type(%d)\n",
                        cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
                for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
                        if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
-                               DEBUG( MTD_DEBUG_LEVEL3,
-                                      "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
+                               pr_debug("MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
                                       __func__, cfi->mfr, cfi->id,
                                       cfi->addr_unlock1, cfi->addr_unlock2 );
                                if (!cfi_jedec_setup(map, cfi, i))
index e790f38893b00b2f0c0c645b3d66fd1b6a90651b..1b11f94695e9d884999e592e82479b94c01f182d 100644 (file)
@@ -188,10 +188,7 @@ static struct mtd_partition * newpart(char *s,
                             extra_mem_size;
                parts = kzalloc(alloc_size, GFP_KERNEL);
                if (!parts)
-               {
-                       printk(KERN_ERR ERRP "out of memory\n");
                        return NULL;
-               }
                extra_mem = (unsigned char *)(parts + *num_parts);
        }
        /* enter this partition (offset will be calculated later if it is zero at this point) */
@@ -316,8 +313,8 @@ static int mtdpart_setup_real(char *s)
  * the first one in the chain if a NULL mtd_id is passed in.
  */
 static int parse_cmdline_partitions(struct mtd_info *master,
-                             struct mtd_partition **pparts,
-                             unsigned long origin)
+                                   struct mtd_partition **pparts,
+                                   struct mtd_part_parser_data *data)
 {
        unsigned long offset;
        int i;
index f7fbf6025ef286de5f7fc61c1d3eada86695073f..8c97033094965c140cd8d688d0504bdea42674ad 100644 (file)
@@ -82,8 +82,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
        void __iomem *docptr = doc->virtadr;
        unsigned long timeo = jiffies + (HZ * 10);
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "_DoC_WaitReady called for out-of-line wait\n");
+       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
 
        /* Out-of-line routine to wait for chip response */
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
@@ -92,7 +91,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
                DoC_Delay(doc, 2);
 
                if (time_after(jiffies, timeo)) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+                       pr_debug("_DoC_WaitReady timed out.\n");
                        return -EIO;
                }
                udelay(1);
@@ -323,8 +322,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
 
        /* Reset the chip */
        if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
-               DEBUG(MTD_DEBUG_LEVEL2,
-                     "DoC_Command (reset) for %d,%d returned true\n",
+               pr_debug("DoC_Command (reset) for %d,%d returned true\n",
                      floor, chip);
                return 0;
        }
@@ -332,8 +330,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
 
        /* Read the NAND chip ID: 1. Send ReadID command */
        if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
-               DEBUG(MTD_DEBUG_LEVEL2,
-                     "DoC_Command (ReadID) for %d,%d returned true\n",
+               pr_debug("DoC_Command (ReadID) for %d,%d returned true\n",
                      floor, chip);
                return 0;
        }
@@ -699,7 +696,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
 #ifdef ECC_DEBUG
                        printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
-                       /* Read the ECC syndrom through the DiskOnChip ECC
+                       /* Read the ECC syndrome through the DiskOnChip ECC
                           logic.  These syndrome will be all ZERO when there
                           is no error */
                        for (i = 0; i < 6; i++) {
index 241192f05bc8d2cb8bcc601f2c61b06cd815274e..3d2b459cea924b3ff03a21e74b32a92a8f8f0abb 100644 (file)
@@ -55,15 +55,14 @@ static int _DoC_WaitReady(void __iomem * docptr)
 {
        unsigned short c = 0xffff;
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "_DoC_WaitReady called for out-of-line wait\n");
+       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
 
        /* Out-of-line routine to wait for chip response */
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
                ;
 
        if (c == 0)
-               DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+               pr_debug("_DoC_WaitReady timed out.\n");
 
        return (c == 0);
 }
@@ -464,7 +463,7 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
 #ifdef ECC_DEBUG
                printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
-               /* Read the ECC syndrom through the DiskOnChip ECC logic.
+               /* Read the ECC syndrome through the DiskOnChip ECC logic.
                   These syndrome will be all ZERO when there is no error */
                for (i = 0; i < 6; i++) {
                        syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
index 09ae0adc3ad07be984d9b936d9eda7fe24e0e86d..d28c9d99979f710fdcbb40a3a58e92e119890370 100644 (file)
@@ -61,15 +61,14 @@ static int _DoC_WaitReady(void __iomem * docptr)
 {
        unsigned int c = 0xffff;
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "_DoC_WaitReady called for out-of-line wait\n");
+       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
 
        /* Out-of-line routine to wait for chip response */
        while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
                ;
 
        if (c == 0)
-               DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+               pr_debug("_DoC_WaitReady timed out.\n");
 
        return (c == 0);
 }
@@ -655,7 +654,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
 #ifdef ECC_DEBUG
                printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
-               /* Read the ECC syndrom through the DiskOnChip ECC logic.
+               /* Read the ECC syndrome through the DiskOnChip ECC logic.
                   These syndrome will be all ZERO when there is no error */
                for (i = 0; i < 6; i++)
                        syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
index 37ef29a73ee43993ded8414fb8dcbaafdbf1c20a..4a1c39b6f37df4276b2fb27749aadcd37995d235 100644 (file)
@@ -2,7 +2,7 @@
  * ECC algorithm for M-systems disk on chip. We use the excellent Reed
  * Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the
  * GNU GPL License. The rest is simply to convert the disk on chip
- * syndrom into a standard syndom.
+ * syndrome into a standard syndome.
  *
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
  * Copyright (C) 2000 Netgem S.A.
index 772a0ff89e0f7e316279d82632d0893ad89b0f64..3a11ea628e58a2249bbe1d54939a77d2003690cb 100644 (file)
@@ -34,9 +34,6 @@
 /* debugging */
 //#define LART_DEBUG
 
-/* partition support */
-#define HAVE_PARTITIONS
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -44,9 +41,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mtd/mtd.h>
-#ifdef HAVE_PARTITIONS
 #include <linux/mtd/partitions.h>
-#endif
 
 #ifndef CONFIG_SA1100_LART
 #error This is for LART architecture only
@@ -598,7 +593,6 @@ static struct mtd_erase_region_info erase_regions[] = {
        }
 };
 
-#ifdef HAVE_PARTITIONS
 static struct mtd_partition lart_partitions[] = {
        /* blob */
        {
@@ -619,7 +613,7 @@ static struct mtd_partition lart_partitions[] = {
                .size   = INITRD_LEN,           /* MTDPART_SIZ_FULL */
        }
 };
-#endif
+#define NUM_PARTITIONS ARRAY_SIZE(lart_partitions)
 
 static int __init lart_flash_init (void)
 {
@@ -668,7 +662,6 @@ static int __init lart_flash_init (void)
                           result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024,
                           result,mtd.eraseregions[result].numblocks);
 
-#ifdef HAVE_PARTITIONS
    printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions));
 
    for (result = 0; result < ARRAY_SIZE(lart_partitions); result++)
@@ -681,25 +674,16 @@ static int __init lart_flash_init (void)
                         result,lart_partitions[result].offset,
                         result,lart_partitions[result].size,lart_partitions[result].size / 1024);
 #endif
-#endif
 
-#ifndef HAVE_PARTITIONS
-   result = mtd_device_register(&mtd, NULL, 0);
-#else
    result = mtd_device_register(&mtd, lart_partitions,
                                 ARRAY_SIZE(lart_partitions));
-#endif
 
    return (result);
 }
 
 static void __exit lart_flash_exit (void)
 {
-#ifndef HAVE_PARTITIONS
-   mtd_device_unregister(&mtd);
-#else
    mtd_device_unregister(&mtd);
-#endif
 }
 
 module_init (lart_flash_init);
index 35180e475c4c565fded31dc91d6fe05c91aec805..e6ba034c45bc56a3d303eda8510600790b900944 100644 (file)
@@ -88,7 +88,6 @@ struct m25p {
        struct spi_device       *spi;
        struct mutex            lock;
        struct mtd_info         mtd;
-       unsigned                partitioned:1;
        u16                     page_size;
        u16                     addr_width;
        u8                      erase_opcode;
@@ -209,9 +208,8 @@ static int wait_till_ready(struct m25p *flash)
  */
 static int erase_chip(struct m25p *flash)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %lldKiB\n",
-             dev_name(&flash->spi->dev), __func__,
-             (long long)(flash->mtd.size >> 10));
+       pr_debug("%s: %s %lldKiB\n", dev_name(&flash->spi->dev), __func__,
+                       (long long)(flash->mtd.size >> 10));
 
        /* Wait until finished previous write command. */
        if (wait_till_ready(flash))
@@ -250,9 +248,8 @@ static int m25p_cmdsz(struct m25p *flash)
  */
 static int erase_sector(struct m25p *flash, u32 offset)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
-                       dev_name(&flash->spi->dev), __func__,
-                       flash->mtd.erasesize / 1024, offset);
+       pr_debug("%s: %s %dKiB at 0x%08x\n", dev_name(&flash->spi->dev),
+                       __func__, flash->mtd.erasesize / 1024, offset);
 
        /* Wait until finished previous write command. */
        if (wait_till_ready(flash))
@@ -286,9 +283,9 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
        u32 addr,len;
        uint32_t rem;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%llx, len %lld\n",
-             dev_name(&flash->spi->dev), __func__, "at",
-             (long long)instr->addr, (long long)instr->len);
+       pr_debug("%s: %s at 0x%llx, len %lld\n", dev_name(&flash->spi->dev),
+                       __func__, (long long)instr->addr,
+                       (long long)instr->len);
 
        /* sanity checks */
        if (instr->addr + instr->len > flash->mtd.size)
@@ -348,9 +345,8 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
        struct spi_transfer t[2];
        struct spi_message m;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
-                       dev_name(&flash->spi->dev), __func__, "from",
-                       (u32)from, len);
+       pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+                       __func__, (u32)from, len);
 
        /* sanity checks */
        if (!len)
@@ -417,9 +413,8 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
        struct spi_transfer t[2];
        struct spi_message m;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
-                       dev_name(&flash->spi->dev), __func__, "to",
-                       (u32)to, len);
+       pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+                       __func__, (u32)to, len);
 
        *retlen = 0;
 
@@ -510,9 +505,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
        size_t actual;
        int cmd_sz, ret;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
-                       dev_name(&flash->spi->dev), __func__, "to",
-                       (u32)to, len);
+       pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+                       __func__, (u32)to, len);
 
        *retlen = 0;
 
@@ -788,8 +782,8 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
         */
        tmp = spi_write_then_read(spi, &code, 1, id, 5);
        if (tmp < 0) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
-                       dev_name(&spi->dev), tmp);
+               pr_debug("%s: error %d reading JEDEC ID\n",
+                               dev_name(&spi->dev), tmp);
                return ERR_PTR(tmp);
        }
        jedec = id[0];
@@ -825,8 +819,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
        struct m25p                     *flash;
        struct flash_info               *info;
        unsigned                        i;
-       struct mtd_partition            *parts = NULL;
-       int                             nr_parts = 0;
+       struct mtd_part_parser_data     ppdata;
 
        /* Platform data helps sort out which chip type we have, as
         * well as how this board partitions it.  If we don't have
@@ -928,6 +921,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
        if (info->flags & M25P_NO_ERASE)
                flash->mtd.flags |= MTD_NO_ERASE;
 
+       ppdata.of_node = spi->dev.of_node;
        flash->mtd.dev.parent = &spi->dev;
        flash->page_size = info->page_size;
 
@@ -945,8 +939,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
        dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
                        (long long)flash->mtd.size >> 10);
 
-       DEBUG(MTD_DEBUG_LEVEL2,
-               "mtd .name = %s, .size = 0x%llx (%lldMiB) "
+       pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
                        ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
                flash->mtd.name,
                (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
@@ -955,8 +948,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
 
        if (flash->mtd.numeraseregions)
                for (i = 0; i < flash->mtd.numeraseregions; i++)
-                       DEBUG(MTD_DEBUG_LEVEL2,
-                               "mtd.eraseregions[%d] = { .offset = 0x%llx, "
+                       pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, "
                                ".erasesize = 0x%.8x (%uKiB), "
                                ".numblocks = %d }\n",
                                i, (long long)flash->mtd.eraseregions[i].offset,
@@ -968,41 +960,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
        /* partitions should match sector boundaries; and it may be good to
         * use readonly partitions for writeprotected sectors (BP2..BP0).
         */
-       if (mtd_has_cmdlinepart()) {
-               static const char *part_probes[]
-                       = { "cmdlinepart", NULL, };
-
-               nr_parts = parse_mtd_partitions(&flash->mtd,
-                                               part_probes, &parts, 0);
-       }
-
-       if (nr_parts <= 0 && data && data->parts) {
-               parts = data->parts;
-               nr_parts = data->nr_parts;
-       }
-
-#ifdef CONFIG_MTD_OF_PARTS
-       if (nr_parts <= 0 && spi->dev.of_node) {
-               nr_parts = of_mtd_parse_partitions(&spi->dev,
-                                                  spi->dev.of_node, &parts);
-       }
-#endif
-
-       if (nr_parts > 0) {
-               for (i = 0; i < nr_parts; i++) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
-                             "{.name = %s, .offset = 0x%llx, "
-                             ".size = 0x%llx (%lldKiB) }\n",
-                             i, parts[i].name,
-                             (long long)parts[i].offset,
-                             (long long)parts[i].size,
-                             (long long)(parts[i].size >> 10));
-               }
-               flash->partitioned = 1;
-       }
-
-       return mtd_device_register(&flash->mtd, parts, nr_parts) == 1 ?
-               -ENODEV : 0;
+       return mtd_device_parse_register(&flash->mtd, NULL, &ppdata,
+                       data ? data->parts : NULL,
+                       data ? data->nr_parts : 0);
 }
 
 
index 13749d458a313297fed127f39399b3432e3be1ff..d75c7af18a638d9f94588565e2d6b3271c95b05d 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/mutex.h>
 #include <linux/err.h>
 #include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
@@ -24,7 +26,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
-
 /*
  * DataFlash is a kind of SPI flash.  Most AT45 chips have two buffers in
  * each chip, which may be used for double buffered I/O; but this driver
@@ -98,6 +99,16 @@ struct dataflash {
        struct mtd_info         mtd;
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id dataflash_dt_ids[] = {
+       { .compatible = "atmel,at45", },
+       { .compatible = "atmel,dataflash", },
+       { /* sentinel */ }
+};
+#else
+#define dataflash_dt_ids NULL
+#endif
+
 /* ......................................................................... */
 
 /*
@@ -122,7 +133,7 @@ static int dataflash_waitready(struct spi_device *spi)
        for (;;) {
                status = dataflash_status(spi);
                if (status < 0) {
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n",
+                       pr_debug("%s: status %d?\n",
                                        dev_name(&spi->dev), status);
                        status = 0;
                }
@@ -149,7 +160,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
        uint8_t                 *command;
        uint32_t                rem;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%llx len 0x%llx\n",
+       pr_debug("%s: erase addr=0x%llx len 0x%llx\n",
              dev_name(&spi->dev), (long long)instr->addr,
              (long long)instr->len);
 
@@ -187,7 +198,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
                command[2] = (uint8_t)(pageaddr >> 8);
                command[3] = 0;
 
-               DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n",
+               pr_debug("ERASE %s: (%x) %x %x %x [%i]\n",
                        do_block ? "block" : "page",
                        command[0], command[1], command[2], command[3],
                        pageaddr);
@@ -238,8 +249,8 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
        uint8_t                 *command;
        int                     status;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n",
-               dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len));
+       pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev),
+                       (unsigned)from, (unsigned)(from + len));
 
        *retlen = 0;
 
@@ -255,7 +266,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        command = priv->command;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n",
+       pr_debug("READ: (%x) %x %x %x\n",
                command[0], command[1], command[2], command[3]);
 
        spi_message_init(&msg);
@@ -287,7 +298,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
                *retlen = msg.actual_length - 8;
                status = 0;
        } else
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n",
+               pr_debug("%s: read %x..%x --> %d\n",
                        dev_name(&priv->spi->dev),
                        (unsigned)from, (unsigned)(from + len),
                        status);
@@ -314,7 +325,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
        int                     status = -EINVAL;
        uint8_t                 *command;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n",
+       pr_debug("%s: write 0x%x..0x%x\n",
                dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len));
 
        *retlen = 0;
@@ -340,7 +351,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
 
        mutex_lock(&priv->lock);
        while (remaining > 0) {
-               DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
+               pr_debug("write @ %i:%i len=%i\n",
                        pageaddr, offset, writelen);
 
                /* REVISIT:
@@ -368,12 +379,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                        command[2] = (addr & 0x0000FF00) >> 8;
                        command[3] = 0;
 
-                       DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n",
+                       pr_debug("TRANSFER: (%x) %x %x %x\n",
                                command[0], command[1], command[2], command[3]);
 
                        status = spi_sync(spi, &msg);
                        if (status < 0)
-                               DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n",
+                               pr_debug("%s: xfer %u -> %d\n",
                                        dev_name(&spi->dev), addr, status);
 
                        (void) dataflash_waitready(priv->spi);
@@ -386,7 +397,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                command[2] = (addr & 0x0000FF00) >> 8;
                command[3] = (addr & 0x000000FF);
 
-               DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n",
+               pr_debug("PROGRAM: (%x) %x %x %x\n",
                        command[0], command[1], command[2], command[3]);
 
                x[1].tx_buf = writebuf;
@@ -395,7 +406,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                status = spi_sync(spi, &msg);
                spi_transfer_del(x + 1);
                if (status < 0)
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n",
+                       pr_debug("%s: pgm %u/%u -> %d\n",
                                dev_name(&spi->dev), addr, writelen, status);
 
                (void) dataflash_waitready(priv->spi);
@@ -410,12 +421,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                command[2] = (addr & 0x0000FF00) >> 8;
                command[3] = 0;
 
-               DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n",
+               pr_debug("COMPARE: (%x) %x %x %x\n",
                        command[0], command[1], command[2], command[3]);
 
                status = spi_sync(spi, &msg);
                if (status < 0)
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n",
+                       pr_debug("%s: compare %u -> %d\n",
                                dev_name(&spi->dev), addr, status);
 
                status = dataflash_waitready(priv->spi);
@@ -634,11 +645,10 @@ add_dataflash_otp(struct spi_device *spi, char *name,
 {
        struct dataflash                *priv;
        struct mtd_info                 *device;
+       struct mtd_part_parser_data     ppdata;
        struct flash_platform_data      *pdata = spi->dev.platform_data;
        char                            *otp_tag = "";
        int                             err = 0;
-       struct mtd_partition            *parts;
-       int                             nr_parts = 0;
 
        priv = kzalloc(sizeof *priv, GFP_KERNEL);
        if (!priv)
@@ -677,28 +687,11 @@ add_dataflash_otp(struct spi_device *spi, char *name,
                        pagesize, otp_tag);
        dev_set_drvdata(&spi->dev, priv);
 
-       if (mtd_has_cmdlinepart()) {
-               static const char *part_probes[] = { "cmdlinepart", NULL, };
-
-               nr_parts = parse_mtd_partitions(device, part_probes, &parts,
-                                               0);
-       }
+       ppdata.of_node = spi->dev.of_node;
+       err = mtd_device_parse_register(device, NULL, &ppdata,
+                       pdata ? pdata->parts : NULL,
+                       pdata ? pdata->nr_parts : 0);
 
-       if (nr_parts <= 0 && pdata && pdata->parts) {
-               parts = pdata->parts;
-               nr_parts = pdata->nr_parts;
-       }
-
-       if (nr_parts > 0) {
-               priv->partitioned = 1;
-               err = mtd_device_register(device, parts, nr_parts);
-               goto out;
-       }
-
-       if (mtd_device_register(device, NULL, 0) == 1)
-               err = -ENODEV;
-
-out:
        if (!err)
                return 0;
 
@@ -787,7 +780,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
         */
        tmp = spi_write_then_read(spi, &code, 1, id, 3);
        if (tmp < 0) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
+               pr_debug("%s: error %d reading JEDEC ID\n",
                        dev_name(&spi->dev), tmp);
                return ERR_PTR(tmp);
        }
@@ -804,7 +797,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
                        tmp < ARRAY_SIZE(dataflash_data);
                        tmp++, info++) {
                if (info->jedec_id == jedec) {
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: OTP, sector protect%s\n",
+                       pr_debug("%s: OTP, sector protect%s\n",
                                dev_name(&spi->dev),
                                (info->flags & SUP_POW2PS)
                                        ? ", binary pagesize" : ""
@@ -812,8 +805,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
                        if (info->flags & SUP_POW2PS) {
                                status = dataflash_status(spi);
                                if (status < 0) {
-                                       DEBUG(MTD_DEBUG_LEVEL1,
-                                               "%s: status error %d\n",
+                                       pr_debug("%s: status error %d\n",
                                                dev_name(&spi->dev), status);
                                        return ERR_PTR(status);
                                }
@@ -878,7 +870,7 @@ static int __devinit dataflash_probe(struct spi_device *spi)
         */
        status = dataflash_status(spi);
        if (status <= 0 || status == 0xff) {
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n",
+               pr_debug("%s: status error %d\n",
                                dev_name(&spi->dev), status);
                if (status == 0 || status == 0xff)
                        status = -ENODEV;
@@ -914,14 +906,14 @@ static int __devinit dataflash_probe(struct spi_device *spi)
                break;
        /* obsolete AT45DB1282 not (yet?) supported */
        default:
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n",
-                               dev_name(&spi->dev), status & 0x3c);
+               pr_debug("%s: unsupported device (%x)\n", dev_name(&spi->dev),
+                               status & 0x3c);
                status = -ENODEV;
        }
 
        if (status < 0)
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n",
-                               dev_name(&spi->dev), status);
+               pr_debug("%s: add_dataflash --> %d\n", dev_name(&spi->dev),
+                               status);
 
        return status;
 }
@@ -931,7 +923,7 @@ static int __devexit dataflash_remove(struct spi_device *spi)
        struct dataflash        *flash = dev_get_drvdata(&spi->dev);
        int                     status;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev));
+       pr_debug("%s: remove\n", dev_name(&spi->dev));
 
        status = mtd_device_unregister(&flash->mtd);
        if (status == 0) {
@@ -946,6 +938,7 @@ static struct spi_driver dataflash_driver = {
                .name           = "mtd_dataflash",
                .bus            = &spi_bus_type,
                .owner          = THIS_MODULE,
+               .of_match_table = dataflash_dt_ids,
        },
 
        .probe          = dataflash_probe,
index 83e80c65d6e70ce9b508591ff814eab6150c9d08..d38ef3bffe8d0723806835df2d1093a017757380 100644 (file)
@@ -52,8 +52,6 @@ struct sst25l_flash {
        struct spi_device       *spi;
        struct mutex            lock;
        struct mtd_info         mtd;
-
-       int                     partitioned;
 };
 
 struct flash_info {
@@ -381,8 +379,6 @@ static int __devinit sst25l_probe(struct spi_device *spi)
        struct sst25l_flash *flash;
        struct flash_platform_data *data;
        int ret, i;
-       struct mtd_partition *parts = NULL;
-       int nr_parts = 0;
 
        flash_info = sst25l_match_device(spi);
        if (!flash_info)
@@ -414,8 +410,7 @@ static int __devinit sst25l_probe(struct spi_device *spi)
        dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
                 (long long)flash->mtd.size >> 10);
 
-       DEBUG(MTD_DEBUG_LEVEL2,
-             "mtd .name = %s, .size = 0x%llx (%lldMiB) "
+       pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
              ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
              flash->mtd.name,
              (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
@@ -423,37 +418,10 @@ static int __devinit sst25l_probe(struct spi_device *spi)
              flash->mtd.numeraseregions);
 
 
-       if (mtd_has_cmdlinepart()) {
-               static const char *part_probes[] = {"cmdlinepart", NULL};
-
-               nr_parts = parse_mtd_partitions(&flash->mtd,
-                                               part_probes,
-                                               &parts, 0);
-       }
-
-       if (nr_parts <= 0 && data && data->parts) {
-               parts = data->parts;
-               nr_parts = data->nr_parts;
-       }
-
-       if (nr_parts > 0) {
-               for (i = 0; i < nr_parts; i++) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
-                             "{.name = %s, .offset = 0x%llx, "
-                             ".size = 0x%llx (%lldKiB) }\n",
-                             i, parts[i].name,
-                             (long long)parts[i].offset,
-                             (long long)parts[i].size,
-                             (long long)(parts[i].size >> 10));
-               }
-
-               flash->partitioned = 1;
-               return mtd_device_register(&flash->mtd, parts,
-                                          nr_parts);
-       }
-
-       ret = mtd_device_register(&flash->mtd, NULL, 0);
-       if (ret == 1) {
+       ret = mtd_device_parse_register(&flash->mtd, NULL, 0,
+                       data ? data->parts : NULL,
+                       data ? data->nr_parts : 0);
+       if (ret) {
                kfree(flash);
                dev_set_drvdata(&spi->dev, NULL);
                return -ENODEV;
index 037b399df3f1a384dbdc45b9c6d9dbf0d3c8abaf..c7382bb686c679efef42dd5218cce645002512eb 100644 (file)
@@ -339,7 +339,7 @@ static int erase_xfer(partition_t *part,
     struct erase_info *erase;
 
     xfer = &part->XferInfo[xfernum];
-    DEBUG(1, "ftl_cs: erasing xfer unit at 0x%x\n", xfer->Offset);
+    pr_debug("ftl_cs: erasing xfer unit at 0x%x\n", xfer->Offset);
     xfer->state = XFER_ERASING;
 
     /* Is there a free erase slot? Always in MTD. */
@@ -415,7 +415,7 @@ static int prepare_xfer(partition_t *part, int i)
     xfer = &part->XferInfo[i];
     xfer->state = XFER_FAILED;
 
-    DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
+    pr_debug("ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
 
     /* Write the transfer unit header */
     header = part->header;
@@ -476,7 +476,7 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
 
     eun = &part->EUNInfo[srcunit];
     xfer = &part->XferInfo[xferunit];
-    DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
+    pr_debug("ftl_cs: copying block 0x%x to 0x%x\n",
          eun->Offset, xfer->Offset);
 
 
@@ -598,7 +598,7 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
     unit with the fewest erases, and usually pick the data unit with
     the most deleted blocks.  But with a small probability, pick the
     oldest data unit instead.  This means that we generally postpone
-    the next reclaimation as long as possible, but shuffle static
+    the next reclamation as long as possible, but shuffle static
     stuff around a bit for wear leveling.
 
 ======================================================================*/
@@ -609,8 +609,8 @@ static int reclaim_block(partition_t *part)
     uint32_t best;
     int queued, ret;
 
-    DEBUG(0, "ftl_cs: reclaiming space...\n");
-    DEBUG(3, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
+    pr_debug("ftl_cs: reclaiming space...\n");
+    pr_debug("NumTransferUnits == %x\n", part->header.NumTransferUnits);
     /* Pick the least erased transfer unit */
     best = 0xffffffff; xfer = 0xffff;
     do {
@@ -618,22 +618,22 @@ static int reclaim_block(partition_t *part)
        for (i = 0; i < part->header.NumTransferUnits; i++) {
            int n=0;
            if (part->XferInfo[i].state == XFER_UNKNOWN) {
-               DEBUG(3,"XferInfo[%d].state == XFER_UNKNOWN\n",i);
+               pr_debug("XferInfo[%d].state == XFER_UNKNOWN\n",i);
                n=1;
                erase_xfer(part, i);
            }
            if (part->XferInfo[i].state == XFER_ERASING) {
-               DEBUG(3,"XferInfo[%d].state == XFER_ERASING\n",i);
+               pr_debug("XferInfo[%d].state == XFER_ERASING\n",i);
                n=1;
                queued = 1;
            }
            else if (part->XferInfo[i].state == XFER_ERASED) {
-               DEBUG(3,"XferInfo[%d].state == XFER_ERASED\n",i);
+               pr_debug("XferInfo[%d].state == XFER_ERASED\n",i);
                n=1;
                prepare_xfer(part, i);
            }
            if (part->XferInfo[i].state == XFER_PREPARED) {
-               DEBUG(3,"XferInfo[%d].state == XFER_PREPARED\n",i);
+               pr_debug("XferInfo[%d].state == XFER_PREPARED\n",i);
                n=1;
                if (part->XferInfo[i].EraseCount <= best) {
                    best = part->XferInfo[i].EraseCount;
@@ -641,12 +641,12 @@ static int reclaim_block(partition_t *part)
                }
            }
                if (!n)
-                   DEBUG(3,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
+                   pr_debug("XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
 
        }
        if (xfer == 0xffff) {
            if (queued) {
-               DEBUG(1, "ftl_cs: waiting for transfer "
+               pr_debug("ftl_cs: waiting for transfer "
                      "unit to be prepared...\n");
                if (part->mbd.mtd->sync)
                        part->mbd.mtd->sync(part->mbd.mtd);
@@ -656,7 +656,7 @@ static int reclaim_block(partition_t *part)
                    printk(KERN_NOTICE "ftl_cs: reclaim failed: no "
                           "suitable transfer units!\n");
                else
-                   DEBUG(1, "ftl_cs: reclaim failed: no "
+                   pr_debug("ftl_cs: reclaim failed: no "
                          "suitable transfer units!\n");
 
                return -EIO;
@@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
 
     eun = 0;
     if ((jiffies % shuffle_freq) == 0) {
-       DEBUG(1, "ftl_cs: recycling freshest block...\n");
+       pr_debug("ftl_cs: recycling freshest block...\n");
        best = 0xffffffff;
        for (i = 0; i < part->DataUnits; i++)
            if (part->EUNInfo[i].EraseCount <= best) {
@@ -686,7 +686,7 @@ static int reclaim_block(partition_t *part)
                printk(KERN_NOTICE "ftl_cs: reclaim failed: "
                       "no free blocks!\n");
            else
-               DEBUG(1,"ftl_cs: reclaim failed: "
+               pr_debug("ftl_cs: reclaim failed: "
                       "no free blocks!\n");
 
            return -EIO;
@@ -771,7 +771,7 @@ static uint32_t find_free(partition_t *part)
        printk(KERN_NOTICE "ftl_cs: bad free list!\n");
        return 0;
     }
-    DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
+    pr_debug("ftl_cs: found free block at %d in %d\n", blk, eun);
     return blk;
 
 } /* find_free */
@@ -791,7 +791,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
     int ret;
     size_t offset, retlen;
 
-    DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
+    pr_debug("ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
          part, sector, nblocks);
     if (!(part->state & FTL_FORMATTED)) {
        printk(KERN_NOTICE "ftl_cs: bad partition\n");
@@ -840,7 +840,7 @@ static int set_bam_entry(partition_t *part, uint32_t log_addr,
     int ret;
     size_t retlen, offset;
 
-    DEBUG(2, "ftl_cs: set_bam_entry(0x%p, 0x%x, 0x%x)\n",
+    pr_debug("ftl_cs: set_bam_entry(0x%p, 0x%x, 0x%x)\n",
          part, log_addr, virt_addr);
     bsize = 1 << part->header.EraseUnitSize;
     eun = log_addr / bsize;
@@ -905,7 +905,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
     int ret;
     size_t retlen, offset;
 
-    DEBUG(2, "ftl_cs: ftl_write(0x%p, %ld, %ld)\n",
+    pr_debug("ftl_cs: ftl_write(0x%p, %ld, %ld)\n",
          part, sector, nblocks);
     if (!(part->state & FTL_FORMATTED)) {
        printk(KERN_NOTICE "ftl_cs: bad partition\n");
@@ -1011,7 +1011,7 @@ static int ftl_discardsect(struct mtd_blktrans_dev *dev,
        partition_t *part = (void *)dev;
        uint32_t bsize = 1 << part->header.EraseUnitSize;
 
-       DEBUG(1, "FTL erase sector %ld for %d sectors\n",
+       pr_debug("FTL erase sector %ld for %d sectors\n",
              sector, nr_sects);
 
        while (nr_sects) {
index d7592e67d04861cfc2a952112445ef0601dd58ce..21aa981e42cde83df58eae966ed41f78e9132b30 100644 (file)
@@ -63,14 +63,12 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                return;
        }
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: add_mtd for %s\n", mtd->name);
+       pr_debug("INFTL: add_mtd for %s\n", mtd->name);
 
        inftl = kzalloc(sizeof(*inftl), GFP_KERNEL);
 
-       if (!inftl) {
-               printk(KERN_WARNING "INFTL: Out of memory for data structures\n");
+       if (!inftl)
                return;
-       }
 
        inftl->mbd.mtd = mtd;
        inftl->mbd.devnum = -1;
@@ -133,7 +131,7 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
        struct INFTLrecord *inftl = (void *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: remove_dev (i=%d)\n", dev->devnum);
+       pr_debug("INFTL: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
 
@@ -215,16 +213,16 @@ static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate)
        u16 pot = inftl->LastFreeEUN;
        int silly = inftl->nb_blocks;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=%p,"
-               "desperate=%d)\n", inftl, desperate);
+       pr_debug("INFTL: INFTL_findfreeblock(inftl=%p,desperate=%d)\n",
+                       inftl, desperate);
 
        /*
         * Normally, we force a fold to happen before we run out of free
         * blocks completely.
         */
        if (!desperate && inftl->numfreeEUNs < 2) {
-               DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free "
-                       "EUNs (%d)\n", inftl->numfreeEUNs);
+               pr_debug("INFTL: there are too few free EUNs (%d)\n",
+                               inftl->numfreeEUNs);
                return BLOCK_NIL;
        }
 
@@ -259,8 +257,8 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
        struct inftl_oob oob;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,"
-               "pending=%d)\n", inftl, thisVUC, pendingblock);
+       pr_debug("INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,pending=%d)\n",
+                       inftl, thisVUC, pendingblock);
 
        memset(BlockMap, 0xff, sizeof(BlockMap));
        memset(BlockDeleted, 0, sizeof(BlockDeleted));
@@ -323,8 +321,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
         * Chain, and the Erase Unit into which we are supposed to be copying.
         * Go for it.
         */
-       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n",
-               thisVUC, targetEUN);
+       pr_debug("INFTL: folding chain %d into unit %d\n", thisVUC, targetEUN);
 
        for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) {
                unsigned char movebuf[SECTORSIZE];
@@ -355,8 +352,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
                                        (block * SECTORSIZE), SECTORSIZE,
                                        &retlen, movebuf);
                        if (ret != -EIO)
-                               DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
-                                     "away on retry?\n");
+                               pr_debug("INFTL: error went away on retry?\n");
                }
                memset(&oob, 0xff, sizeof(struct inftl_oob));
                oob.b.Status = oob.b.Status1 = SECTOR_USED;
@@ -372,8 +368,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
         * is important, by doing oldest first if we crash/reboot then it
         * it is relatively simple to clean up the mess).
         */
-       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n",
-               thisVUC);
+       pr_debug("INFTL: want to erase virtual chain %d\n", thisVUC);
 
        for (;;) {
                /* Find oldest unit in chain. */
@@ -421,7 +416,7 @@ static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
        u16 ChainLength = 0, thislen;
        u16 chain, EUN;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=%p,"
+       pr_debug("INFTL: INFTL_makefreeblock(inftl=%p,"
                "pending=%d)\n", inftl, pendingblock);
 
        for (chain = 0; chain < inftl->nb_blocks; chain++) {
@@ -484,8 +479,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
        size_t retlen;
        int silly, silly2 = 3;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=%p,"
-               "block=%d)\n", inftl, block);
+       pr_debug("INFTL: INFTL_findwriteunit(inftl=%p,block=%d)\n",
+                       inftl, block);
 
        do {
                /*
@@ -501,8 +496,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
                                       blockofs, 8, &retlen, (char *)&bci);
 
                        status = bci.Status | bci.Status1;
-                       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
-                               "EUN %d is %x\n", block , writeEUN, status);
+                       pr_debug("INFTL: status of block %d in EUN %d is %x\n",
+                                       block , writeEUN, status);
 
                        switch(status) {
                        case SECTOR_FREE:
@@ -555,9 +550,9 @@ hitused:
                         * Hopefully we free something, lets try again.
                         * This time we are desperate...
                         */
-                       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 "
-                               "to find free EUN to accommodate write to "
-                               "VUC %d\n", thisVUC);
+                       pr_debug("INFTL: using desperate==1 to find free EUN "
+                                       "to accommodate write to VUC %d\n",
+                                       thisVUC);
                        writeEUN = INFTL_findfreeblock(inftl, 1);
                        if (writeEUN == BLOCK_NIL) {
                                /*
@@ -647,7 +642,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
        struct inftl_bci bci;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=%p,"
+       pr_debug("INFTL: INFTL_trydeletechain(inftl=%p,"
                "thisVUC=%d)\n", inftl, thisVUC);
 
        memset(BlockUsed, 0, sizeof(BlockUsed));
@@ -711,7 +706,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
         * For each block in the chain free it and make it available
         * for future use. Erase from the oldest unit first.
         */
-       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC);
+       pr_debug("INFTL: deleting empty VUC %d\n", thisVUC);
 
        for (;;) {
                u16 *prevEUN = &inftl->VUtable[thisVUC];
@@ -719,7 +714,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
 
                /* If the chain is all gone already, we're done */
                if (thisEUN == BLOCK_NIL) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
+                       pr_debug("INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
                        return;
                }
 
@@ -731,7 +726,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
                        thisEUN = *prevEUN;
                }
 
-               DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
+               pr_debug("Deleting EUN %d from VUC %d\n",
                      thisEUN, thisVUC);
 
                if (INFTL_formatblock(inftl, thisEUN) < 0) {
@@ -767,7 +762,7 @@ static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
        size_t retlen;
        struct inftl_bci bci;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=%p,"
+       pr_debug("INFTL: INFTL_deleteblock(inftl=%p,"
                "block=%d)\n", inftl, block);
 
        while (thisEUN < inftl->nb_blocks) {
@@ -826,7 +821,7 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
        struct inftl_oob oob;
        char *p, *pend;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=%p,block=%ld,"
+       pr_debug("INFTL: inftl_writeblock(inftl=%p,block=%ld,"
                "buffer=%p)\n", inftl, block, buffer);
 
        /* Is block all zero? */
@@ -876,7 +871,7 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
        struct inftl_bci bci;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld,"
+       pr_debug("INFTL: inftl_readblock(inftl=%p,block=%ld,"
                "buffer=%p)\n", inftl, block, buffer);
 
        while (thisEUN < inftl->nb_blocks) {
index 104052e774b06a33ce56191f62077d29b8af57e6..2ff601f816cebd12b4210b199e85fbcbdfb424cf 100644 (file)
@@ -53,7 +53,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
        struct INFTLPartition *ip;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=%p)\n", inftl);
+       pr_debug("INFTL: find_boot_record(inftl=%p)\n", inftl);
 
         /*
         * Assume logical EraseSize == physical erasesize for starting the
@@ -139,24 +139,20 @@ static int find_boot_record(struct INFTLrecord *inftl)
                mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
                mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-               if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-                       printk("INFTL: Media Header ->\n"
-                               "    bootRecordID          = %s\n"
-                               "    NoOfBootImageBlocks   = %d\n"
-                               "    NoOfBinaryPartitions  = %d\n"
-                               "    NoOfBDTLPartitions    = %d\n"
-                               "    BlockMultiplerBits    = %d\n"
-                               "    FormatFlgs            = %d\n"
-                               "    OsakVersion           = 0x%x\n"
-                               "    PercentUsed           = %d\n",
-                               mh->bootRecordID, mh->NoOfBootImageBlocks,
-                               mh->NoOfBinaryPartitions,
-                               mh->NoOfBDTLPartitions,
-                               mh->BlockMultiplierBits, mh->FormatFlags,
-                               mh->OsakVersion, mh->PercentUsed);
-               }
-#endif
+               pr_debug("INFTL: Media Header ->\n"
+                        "    bootRecordID          = %s\n"
+                        "    NoOfBootImageBlocks   = %d\n"
+                        "    NoOfBinaryPartitions  = %d\n"
+                        "    NoOfBDTLPartitions    = %d\n"
+                        "    BlockMultiplerBits    = %d\n"
+                        "    FormatFlgs            = %d\n"
+                        "    OsakVersion           = 0x%x\n"
+                        "    PercentUsed           = %d\n",
+                        mh->bootRecordID, mh->NoOfBootImageBlocks,
+                        mh->NoOfBinaryPartitions,
+                        mh->NoOfBDTLPartitions,
+                        mh->BlockMultiplierBits, mh->FormatFlags,
+                        mh->OsakVersion, mh->PercentUsed);
 
                if (mh->NoOfBDTLPartitions == 0) {
                        printk(KERN_WARNING "INFTL: Media Header sanity check "
@@ -200,19 +196,15 @@ static int find_boot_record(struct INFTLrecord *inftl)
                        ip->spareUnits = le32_to_cpu(ip->spareUnits);
                        ip->Reserved0 = le32_to_cpu(ip->Reserved0);
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-                       if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-                               printk("    PARTITION[%d] ->\n"
-                                       "        virtualUnits    = %d\n"
-                                       "        firstUnit       = %d\n"
-                                       "        lastUnit        = %d\n"
-                                       "        flags           = 0x%x\n"
-                                       "        spareUnits      = %d\n",
-                                       i, ip->virtualUnits, ip->firstUnit,
-                                       ip->lastUnit, ip->flags,
-                                       ip->spareUnits);
-                       }
-#endif
+                       pr_debug("    PARTITION[%d] ->\n"
+                                "        virtualUnits    = %d\n"
+                                "        firstUnit       = %d\n"
+                                "        lastUnit        = %d\n"
+                                "        flags           = 0x%x\n"
+                                "        spareUnits      = %d\n",
+                                i, ip->virtualUnits, ip->firstUnit,
+                                ip->lastUnit, ip->flags,
+                                ip->spareUnits);
 
                        if (ip->Reserved0 != ip->firstUnit) {
                                struct erase_info *instr = &inftl->instr;
@@ -375,7 +367,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
  *
  * Return: 0 when succeed, -1 on error.
  *
- * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
+ * ToDo: 1. Is it necessary to check_free_sector after erasing ??
  */
 int INFTL_formatblock(struct INFTLrecord *inftl, int block)
 {
@@ -385,8 +377,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
        struct mtd_info *mtd = inftl->mbd.mtd;
        int physblock;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p,"
-               "block=%d)\n", inftl, block);
+       pr_debug("INFTL: INFTL_formatblock(inftl=%p,block=%d)\n", inftl, block);
 
        memset(instr, 0, sizeof(struct erase_info));
 
@@ -476,30 +467,30 @@ void INFTL_dumptables(struct INFTLrecord *s)
 {
        int i;
 
-       printk("-------------------------------------------"
+       pr_debug("-------------------------------------------"
                "----------------------------------\n");
 
-       printk("VUtable[%d] ->", s->nb_blocks);
+       pr_debug("VUtable[%d] ->", s->nb_blocks);
        for (i = 0; i < s->nb_blocks; i++) {
                if ((i % 8) == 0)
-                       printk("\n%04x: ", i);
-               printk("%04x ", s->VUtable[i]);
+                       pr_debug("\n%04x: ", i);
+               pr_debug("%04x ", s->VUtable[i]);
        }
 
-       printk("\n-------------------------------------------"
+       pr_debug("\n-------------------------------------------"
                "----------------------------------\n");
 
-       printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
+       pr_debug("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
        for (i = 0; i <= s->lastEUN; i++) {
                if ((i % 8) == 0)
-                       printk("\n%04x: ", i);
-               printk("%04x ", s->PUtable[i]);
+                       pr_debug("\n%04x: ", i);
+               pr_debug("%04x ", s->PUtable[i]);
        }
 
-       printk("\n-------------------------------------------"
+       pr_debug("\n-------------------------------------------"
                "----------------------------------\n");
 
-       printk("INFTL ->\n"
+       pr_debug("INFTL ->\n"
                "  EraseSize       = %d\n"
                "  h/s/c           = %d/%d/%d\n"
                "  numvunits       = %d\n"
@@ -513,7 +504,7 @@ void INFTL_dumptables(struct INFTLrecord *s)
                s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs,
                s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks);
 
-       printk("\n-------------------------------------------"
+       pr_debug("\n-------------------------------------------"
                "----------------------------------\n");
 }
 
@@ -521,25 +512,25 @@ void INFTL_dumpVUchains(struct INFTLrecord *s)
 {
        int logical, block, i;
 
-       printk("-------------------------------------------"
+       pr_debug("-------------------------------------------"
                "----------------------------------\n");
 
-       printk("INFTL Virtual Unit Chains:\n");
+       pr_debug("INFTL Virtual Unit Chains:\n");
        for (logical = 0; logical < s->nb_blocks; logical++) {
                block = s->VUtable[logical];
                if (block > s->nb_blocks)
                        continue;
-               printk("  LOGICAL %d --> %d ", logical, block);
+               pr_debug("  LOGICAL %d --> %d ", logical, block);
                for (i = 0; i < s->nb_blocks; i++) {
                        if (s->PUtable[block] == BLOCK_NIL)
                                break;
                        block = s->PUtable[block];
-                       printk("%d ", block);
+                       pr_debug("%d ", block);
                }
-               printk("\n");
+               pr_debug("\n");
        }
 
-       printk("-------------------------------------------"
+       pr_debug("-------------------------------------------"
                "----------------------------------\n");
 }
 
@@ -555,7 +546,7 @@ int INFTL_mount(struct INFTLrecord *s)
        int i;
        u8 *ANACtable, ANAC;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=%p)\n", s);
+       pr_debug("INFTL: INFTL_mount(inftl=%p)\n", s);
 
        /* Search for INFTL MediaHeader and Spare INFTL Media Header */
        if (find_boot_record(s) < 0) {
@@ -585,7 +576,7 @@ int INFTL_mount(struct INFTLrecord *s)
         * NOTEXPLORED state. Then at the end we will try to format it and
         * mark it as free.
         */
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");
+       pr_debug("INFTL: pass 1, explore each unit\n");
        for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {
                if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)
                        continue;
@@ -717,17 +708,14 @@ int INFTL_mount(struct INFTLrecord *s)
                logical_block = BLOCK_NIL;
        }
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-       if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-               INFTL_dumptables(s);
-#endif
+       INFTL_dumptables(s);
 
        /*
         * Second pass, check for infinite loops in chains. These are
         * possible because we don't update the previous pointers when
         * we fold chains. No big deal, just fix them up in PUtable.
         */
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");
+       pr_debug("INFTL: pass 2, validate virtual chains\n");
        for (logical_block = 0; logical_block < s->numvunits; logical_block++) {
                block = s->VUtable[logical_block];
                last_block = BLOCK_NIL;
@@ -772,12 +760,8 @@ int INFTL_mount(struct INFTLrecord *s)
                }
        }
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-       if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-               INFTL_dumptables(s);
-       if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-               INFTL_dumpVUchains(s);
-#endif
+       INFTL_dumptables(s);
+       INFTL_dumpVUchains(s);
 
        /*
         * Third pass, format unreferenced blocks and init free block count.
@@ -785,7 +769,7 @@ int INFTL_mount(struct INFTLrecord *s)
        s->numfreeEUNs = 0;
        s->LastFreeEUN = BLOCK_NIL;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");
+       pr_debug("INFTL: pass 3, format unused blocks\n");
        for (block = s->firstEUN; block <= s->lastEUN; block++) {
                if (s->PUtable[block] == BLOCK_NOTEXPLORED) {
                        printk("INFTL: unreferenced block %d, formatting it\n",
index c0c328c5b133ccf51785a19385ae7a48a747aeaf..1b0d56cf4c47975b85a5f12d2c6af100543b7e6f 100644 (file)
@@ -41,8 +41,6 @@ config MTD_PHYSMAP_START
          are mapped on your particular target board. Refer to the
          memory map which should hopefully be in the documentation for
          your board.
-         Ignore this option if you use run-time physmap configuration
-         (i.e., run-time calling physmap_configure()).
 
 config MTD_PHYSMAP_LEN
        hex "Physical length of flash mapping"
@@ -55,8 +53,6 @@ config MTD_PHYSMAP_LEN
          than the total amount of flash present. Refer to the memory
          map which should hopefully be in the documentation for your
          board.
-         Ignore this option if you use run-time physmap configuration
-         (i.e., run-time calling physmap_configure()).
 
 config MTD_PHYSMAP_BANKWIDTH
        int "Bank width in octets"
@@ -67,8 +63,6 @@ config MTD_PHYSMAP_BANKWIDTH
          in octets. For example, if you have a data bus width of 32
          bits, you would set the bus width octet value to 4. This is
          used internally by the CFI drivers.
-         Ignore this option if you use run-time physmap configuration
-         (i.e., run-time calling physmap_configure()).
 
 config MTD_PHYSMAP_OF
        tristate "Flash device in physical memory map based on OF description"
@@ -260,7 +254,6 @@ config MTD_BCM963XX
 config MTD_LANTIQ
        tristate "Lantiq SoC NOR support"
        depends on LANTIQ
-       select MTD_PARTITIONS
        help
          Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
 
@@ -398,13 +391,6 @@ config MTD_AUTCPU12
          This enables access to the NV-RAM on autronix autcpu12 board.
          If you have such a board, say 'Y'.
 
-config MTD_EDB7312
-       tristate "CFI Flash device mapped on EDB7312"
-       depends on ARCH_EDB7312 && MTD_CFI
-       help
-         This enables access to the CFI Flash on the Cogent EDB7312 board.
-         If you have such a board, say 'Y' here.
-
 config MTD_IMPA7
        tristate "JEDEC Flash device mapped on impA7"
        depends on ARM && MTD_JEDECPROBE
@@ -412,14 +398,6 @@ config MTD_IMPA7
          This enables access to the NOR Flash on the impA7 board of
          implementa GmbH. If you have such a board, say 'Y' here.
 
-config MTD_CEIVA
-       tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
-       depends on MTD_JEDECPROBE && ARCH_CEIVA
-       help
-         This enables access to the flash chips on the Ceiva/Polaroid
-         PhotoMax Digital Picture Frame.
-         If you have such a device, say 'Y'.
-
 config MTD_H720X
        tristate "Hynix evaluation board mappings"
        depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
index cb48b11affff8aef535ac93cc96a936e85cd8c32..45dcb8b14f22f0b0cb3b4ed4d7ce85d447c4da79 100644 (file)
@@ -19,7 +19,6 @@ obj-$(CONFIG_MTD_CK804XROM)   += ck804xrom.o
 obj-$(CONFIG_MTD_TSUNAMI)      += tsunami_flash.o
 obj-$(CONFIG_MTD_PXA2XX)       += pxa2xx-flash.o
 obj-$(CONFIG_MTD_MBX860)       += mbx860.o
-obj-$(CONFIG_MTD_CEIVA)                += ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)      += octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)      += physmap.o
 obj-$(CONFIG_MTD_PHYSMAP_OF)   += physmap_of.o
@@ -40,7 +39,6 @@ obj-$(CONFIG_MTD_DBOX2)               += dbox2-flash.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)          += pci.o
 obj-$(CONFIG_MTD_AUTCPU12)     += autcpu12-nvram.o
-obj-$(CONFIG_MTD_EDB7312)      += edb7312.o
 obj-$(CONFIG_MTD_IMPA7)                += impa7.o
 obj-$(CONFIG_MTD_FORTUNET)     += fortunet.o
 obj-$(CONFIG_MTD_UCLINUX)      += uclinux.o
index 67815eed2f0039b94a8e86301cf21bc4b88b9df5..6d6b2b5674ee6f4f27282e8356b301446a66c3eb 100644 (file)
@@ -41,7 +41,6 @@ struct async_state {
        uint32_t flash_ambctl0, flash_ambctl1;
        uint32_t save_ambctl0, save_ambctl1;
        unsigned long irq_flags;
-       struct mtd_partition *parts;
 };
 
 static void switch_to_flash(struct async_state *state)
@@ -165,18 +164,8 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
-       if (ret > 0) {
-               pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n");
-               mtd_device_register(state->mtd, pdata->parts, ret);
-               state->parts = pdata->parts;
-       } else if (pdata->nr_parts) {
-               pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n");
-               mtd_device_register(state->mtd, pdata->parts, pdata->nr_parts);
-       } else {
-               pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n");
-               mtd_device_register(state->mtd, NULL, 0);
-       }
+       mtd_device_parse_register(state->mtd, part_probe_types, 0,
+                       pdata->parts, pdata->nr_parts);
 
        platform_set_drvdata(pdev, state);
 
@@ -188,7 +177,6 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev)
        struct async_state *state = platform_get_drvdata(pdev);
        gpio_free(state->enet_flash_pin);
        mtd_device_unregister(state->mtd);
-       kfree(state->parts);
        map_destroy(state->mtd);
        kfree(state);
        return 0;
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
deleted file mode 100644 (file)
index 06f9c98..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Ceiva flash memory driver.
- * Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net>
- *
- * Note: this driver supports jedec compatible devices. Modification
- * for CFI compatible devices should be straight forward: change
- * jedec_probe to cfi_probe.
- *
- * Based on: sa1100-flash.c, which has the following copyright:
- * Flash memory access on SA11x0 based devices
- *
- * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/concat.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-
-/*
- * This isn't complete yet, so...
- */
-#define CONFIG_MTD_CEIVA_STATICMAP
-
-#ifdef CONFIG_MTD_CEIVA_STATICMAP
-/*
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
- * structure.
- *
- * Please note:
- *  1. The flash size given should be the largest flash size that can
- *     be accommodated.
- *
- *  2. The bus width must defined in clps_setup_flash.
- *
- * The MTD layer will detect flash chip aliasing and reduce the size of
- * the map accordingly.
- *
- */
-
-#ifdef CONFIG_ARCH_CEIVA
-/* Flash / Partition sizing */
-/* For the 28F8003, we use the block mapping to calcuate the sizes */
-#define MAX_SIZE_KiB                  (16 + 8 + 8 + 96 + (7*128))
-#define BOOT_PARTITION_SIZE_KiB       (16)
-#define PARAMS_PARTITION_SIZE_KiB     (8)
-#define KERNEL_PARTITION_SIZE_KiB     (4*128)
-/* Use both remaining portion of first flash, and all of second flash */
-#define ROOT_PARTITION_SIZE_KiB       (3*128) + (8*128)
-
-static struct mtd_partition ceiva_partitions[] = {
-       {
-               .name = "Ceiva BOOT partition",
-               .size   = BOOT_PARTITION_SIZE_KiB*1024,
-               .offset = 0,
-
-       },{
-               .name = "Ceiva parameters partition",
-               .size   = PARAMS_PARTITION_SIZE_KiB*1024,
-               .offset = (16 + 8) * 1024,
-       },{
-               .name = "Ceiva kernel partition",
-               .size = (KERNEL_PARTITION_SIZE_KiB)*1024,
-               .offset = 0x20000,
-
-       },{
-               .name = "Ceiva root filesystem partition",
-               .offset = MTDPART_OFS_APPEND,
-               .size = (ROOT_PARTITION_SIZE_KiB)*1024,
-       }
-};
-#endif
-
-static int __init clps_static_partitions(struct mtd_partition **parts)
-{
-       int nb_parts = 0;
-
-#ifdef CONFIG_ARCH_CEIVA
-       if (machine_is_ceiva()) {
-               *parts       = ceiva_partitions;
-               nb_parts     = ARRAY_SIZE(ceiva_partitions);
-       }
-#endif
-       return nb_parts;
-}
-#endif
-
-struct clps_info {
-       unsigned long base;
-       unsigned long size;
-       int width;
-       void *vbase;
-       struct map_info *map;
-       struct mtd_info *mtd;
-       struct resource *res;
-};
-
-#define NR_SUBMTD 4
-
-static struct clps_info info[NR_SUBMTD];
-
-static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd)
-{
-       struct mtd_info *subdev[nr];
-       struct map_info *maps;
-       int i, found = 0, ret = 0;
-
-       /*
-        * Allocate the map_info structs in one go.
-        */
-       maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
-       if (!maps)
-               return -ENOMEM;
-       /*
-        * Claim and then map the memory regions.
-        */
-       for (i = 0; i < nr; i++) {
-               if (clps[i].base == (unsigned long)-1)
-                       break;
-
-               clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash");
-               if (!clps[i].res) {
-                       ret = -EBUSY;
-                       break;
-               }
-
-               clps[i].map = maps + i;
-
-               clps[i].map->name = "clps flash";
-               clps[i].map->phys = clps[i].base;
-
-               clps[i].vbase = ioremap(clps[i].base, clps[i].size);
-               if (!clps[i].vbase) {
-                       ret = -ENOMEM;
-                       break;
-               }
-
-               clps[i].map->virt = (void __iomem *)clps[i].vbase;
-               clps[i].map->bankwidth = clps[i].width;
-               clps[i].map->size = clps[i].size;
-
-               simple_map_init(&clps[i].map);
-
-               clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
-               if (clps[i].mtd == NULL) {
-                       ret = -ENXIO;
-                       break;
-               }
-               clps[i].mtd->owner = THIS_MODULE;
-               subdev[i] = clps[i].mtd;
-
-               printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
-                       "%d-bit\n", clps[i].base, clps[i].mtd->size >> 20,
-                       clps[i].width * 8);
-               found += 1;
-       }
-
-       /*
-        * ENXIO is special.  It means we didn't find a chip when
-        * we probed.  We need to tear down the mapping, free the
-        * resource and mark it as such.
-        */
-       if (ret == -ENXIO) {
-               iounmap(clps[i].vbase);
-               clps[i].vbase = NULL;
-               release_resource(clps[i].res);
-               clps[i].res = NULL;
-       }
-
-       /*
-        * If we found one device, don't bother with concat support.
-        * If we found multiple devices, use concat if we have it
-        * available, otherwise fail.
-        */
-       if (ret == 0 || ret == -ENXIO) {
-               if (found == 1) {
-                       *rmtd = subdev[0];
-                       ret = 0;
-               } else if (found > 1) {
-                       /*
-                        * We detected multiple devices.  Concatenate
-                        * them together.
-                        */
-                       *rmtd = mtd_concat_create(subdev, found,
-                                                 "clps flash");
-                       if (*rmtd == NULL)
-                               ret = -ENXIO;
-               }
-       }
-
-       /*
-        * If we failed, clean up.
-        */
-       if (ret) {
-               do {
-                       if (clps[i].mtd)
-                               map_destroy(clps[i].mtd);
-                       if (clps[i].vbase)
-                               iounmap(clps[i].vbase);
-                       if (clps[i].res)
-                               release_resource(clps[i].res);
-               } while (i--);
-
-               kfree(maps);
-       }
-
-       return ret;
-}
-
-static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd)
-{
-       int i;
-
-       mtd_device_unregister(mtd);
-
-       if (mtd != clps[0].mtd)
-               mtd_concat_destroy(mtd);
-
-       for (i = NR_SUBMTD; i >= 0; i--) {
-               if (clps[i].mtd)
-                       map_destroy(clps[i].mtd);
-               if (clps[i].vbase)
-                       iounmap(clps[i].vbase);
-               if (clps[i].res)
-                       release_resource(clps[i].res);
-       }
-       kfree(clps[0].map);
-}
-
-/*
- * We define the memory space, size, and width for the flash memory
- * space here.
- */
-
-static int __init clps_setup_flash(void)
-{
-       int nr = 0;
-
-#ifdef CONFIG_ARCH_CEIVA
-       if (machine_is_ceiva()) {
-               info[0].base = CS0_PHYS_BASE;
-               info[0].size = SZ_32M;
-               info[0].width = CEIVA_FLASH_WIDTH;
-               info[1].base = CS1_PHYS_BASE;
-               info[1].size = SZ_32M;
-               info[1].width = CEIVA_FLASH_WIDTH;
-               nr = 2;
-       }
-#endif
-       return nr;
-}
-
-static struct mtd_partition *parsed_parts;
-static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
-
-static void __init clps_locate_partitions(struct mtd_info *mtd)
-{
-       const char *part_type = NULL;
-       int nr_parts = 0;
-       do {
-               /*
-                * Partition selection stuff.
-                */
-               nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
-               if (nr_parts > 0) {
-                       part_type = "command line";
-                       break;
-               }
-#ifdef CONFIG_MTD_CEIVA_STATICMAP
-               nr_parts = clps_static_partitions(&parsed_parts);
-               if (nr_parts > 0) {
-                       part_type = "static";
-                       break;
-               }
-               printk("found: %d partitions\n", nr_parts);
-#endif
-       } while (0);
-
-       if (nr_parts == 0) {
-               printk(KERN_NOTICE "clps flash: no partition info "
-                       "available, registering whole flash\n");
-               mtd_device_register(mtd, NULL, 0);
-       } else {
-               printk(KERN_NOTICE "clps flash: using %s partition "
-                       "definition\n", part_type);
-               mtd_device_register(mtd, parsed_parts, nr_parts);
-       }
-
-       /* Always succeeds. */
-}
-
-static void __exit clps_destroy_partitions(void)
-{
-       kfree(parsed_parts);
-}
-
-static struct mtd_info *mymtd;
-
-static int __init clps_mtd_init(void)
-{
-       int ret;
-       int nr;
-
-       nr = clps_setup_flash();
-       if (nr < 0)
-               return nr;
-
-       ret = clps_setup_mtd(info, nr, &mymtd);
-       if (ret)
-               return ret;
-
-       clps_locate_partitions(mymtd);
-
-       return 0;
-}
-
-static void __exit clps_mtd_cleanup(void)
-{
-       clps_destroy_mtd(info, mymtd);
-       clps_destroy_partitions();
-}
-
-module_init(clps_mtd_init);
-module_exit(clps_mtd_cleanup);
-
-MODULE_AUTHOR("Rob Scott");
-MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver");
-MODULE_LICENSE("GPL");
index 7a9e1989c977a1c77694daead3cfd5b62013cb0d..f43b365b848c41ebf2e1a8614762de835b84bbbe 100644 (file)
@@ -145,14 +145,10 @@ static struct map_info dc21285_map = {
 
 
 /* Partition stuff */
-static struct mtd_partition *dc21285_parts;
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 static int __init init_dc21285(void)
 {
-
-       int nrparts;
-
        /* Determine bankwidth */
        switch (*CSR_SA110_CNTL & (3<<14)) {
                case SA110_CNTL_ROMWIDTH_8:
@@ -200,8 +196,7 @@ static int __init init_dc21285(void)
 
        dc21285_mtd->owner = THIS_MODULE;
 
-       nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
-       mtd_device_register(dc21285_mtd, dc21285_parts, nrparts);
+       mtd_device_parse_register(dc21285_mtd, probes, 0, NULL, 0);
 
        if(machine_is_ebsa285()) {
                /*
@@ -224,8 +219,6 @@ static int __init init_dc21285(void)
 static void __exit cleanup_dc21285(void)
 {
        mtd_device_unregister(dc21285_mtd);
-       if (dc21285_parts)
-               kfree(dc21285_parts);
        map_destroy(dc21285_mtd);
        iounmap(dc21285_map.virt);
 }
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
deleted file mode 100644 (file)
index fe42a21..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Handle mapping of the NOR flash on Cogent EDB7312 boards
- *
- * Copyright 2002 SYSGO Real-Time Solutions GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#define WINDOW_ADDR 0x00000000      /* physical properties of flash */
-#define WINDOW_SIZE 0x01000000
-#define BUSWIDTH    2
-#define FLASH_BLOCKSIZE_MAIN   0x20000
-#define FLASH_NUMBLOCKS_MAIN   128
-/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */
-#define PROBETYPES { "cfi_probe", NULL }
-
-#define MSG_PREFIX "EDB7312-NOR:"   /* prefix for our printk()'s */
-#define MTDID      "edb7312-nor"    /* for mtdparts= partitioning */
-
-static struct mtd_info *mymtd;
-
-struct map_info edb7312nor_map = {
-       .name = "NOR flash on EDB7312",
-       .size = WINDOW_SIZE,
-       .bankwidth = BUSWIDTH,
-       .phys = WINDOW_ADDR,
-};
-
-/*
- * MTD partitioning stuff
- */
-static struct mtd_partition static_partitions[3] =
-{
-       {
-               .name = "ARMboot",
-               .size = 0x40000,
-               .offset = 0
-       },
-       {
-               .name = "Kernel",
-               .size = 0x200000,
-               .offset = 0x40000
-       },
-       {
-               .name = "RootFS",
-               .size = 0xDC0000,
-               .offset = 0x240000
-       },
-};
-
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
-static int                   mtd_parts_nb = 0;
-static struct mtd_partition *mtd_parts    = 0;
-
-static int __init init_edb7312nor(void)
-{
-       static const char *rom_probe_types[] = PROBETYPES;
-       const char **type;
-       const char *part_type = 0;
-
-               printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
-              WINDOW_SIZE, WINDOW_ADDR);
-       edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-       if (!edb7312nor_map.virt) {
-               printk(MSG_PREFIX "failed to ioremap\n");
-               return -EIO;
-       }
-
-       simple_map_init(&edb7312nor_map);
-
-       mymtd = 0;
-       type = rom_probe_types;
-       for(; !mymtd && *type; type++) {
-               mymtd = do_map_probe(*type, &edb7312nor_map);
-       }
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
-
-               mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
-               if (mtd_parts_nb > 0)
-                       part_type = "detected";
-
-               if (mtd_parts_nb == 0) {
-                       mtd_parts = static_partitions;
-                       mtd_parts_nb = ARRAY_SIZE(static_partitions);
-                       part_type = "static";
-               }
-
-               if (mtd_parts_nb == 0)
-                       printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
-               else
-                       printk(KERN_NOTICE MSG_PREFIX
-                              "using %s partition definition\n", part_type);
-               /* Register the whole device first. */
-               mtd_device_register(mymtd, NULL, 0);
-               mtd_device_register(mymtd, mtd_parts, mtd_parts_nb);
-               return 0;
-       }
-
-       iounmap((void *)edb7312nor_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_edb7312nor(void)
-{
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-       if (edb7312nor_map.virt) {
-               iounmap((void *)edb7312nor_map.virt);
-               edb7312nor_map.virt = 0;
-       }
-}
-
-module_init(init_edb7312nor);
-module_exit(cleanup_edb7312nor);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
-MODULE_DESCRIPTION("Generic configurable MTD map driver");
index 7568c5f8b8ae648cb88754e94b34e03ec19c2d65..1ec66f031c51655bb4904c985565f47fc2fc3bfe 100644 (file)
@@ -187,7 +187,6 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  */
 static int __devinit gpio_flash_probe(struct platform_device *pdev)
 {
-       int nr_parts;
        size_t i, arr_size;
        struct physmap_flash_data *pdata;
        struct resource *memory;
@@ -252,20 +251,9 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       nr_parts = parse_mtd_partitions(state->mtd, part_probe_types,
-                                       &pdata->parts, 0);
-       if (nr_parts > 0) {
-               pr_devinit(KERN_NOTICE PFX "Using commandline partition definition\n");
-               kfree(pdata->parts);
-       } else if (pdata->nr_parts) {
-               pr_devinit(KERN_NOTICE PFX "Using board partition definition\n");
-               nr_parts = pdata->nr_parts;
-       } else {
-               pr_devinit(KERN_NOTICE PFX "no partition info available, registering whole flash at once\n");
-               nr_parts = 0;
-       }
 
-       mtd_device_register(state->mtd, pdata->parts, nr_parts);
+       mtd_device_parse_register(state->mtd, part_probe_types, 0,
+                       pdata->parts, pdata->nr_parts);
 
        return 0;
 }
index 7f035860a36bd43b8683945804fee50690f32351..49c14187fc66dc0e469f071db2971d2c0ca4be10 100644 (file)
@@ -58,18 +58,11 @@ static struct mtd_partition h720x_partitions[] = {
 
 #define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions)
 
-static int                   nr_mtd_parts;
-static struct mtd_partition *mtd_parts;
-static const char *probes[] = { "cmdlinepart", NULL };
-
 /*
  * Initialize FLASH support
  */
 static int __init h720x_mtd_init(void)
 {
-
-       char    *part_type = NULL;
-
        h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size);
 
        if (!h720x_map.virt) {
@@ -92,16 +85,8 @@ static int __init h720x_mtd_init(void)
        if (mymtd) {
                mymtd->owner = THIS_MODULE;
 
-               nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
-               if (nr_mtd_parts > 0)
-                       part_type = "command line";
-               if (nr_mtd_parts <= 0) {
-                       mtd_parts = h720x_partitions;
-                       nr_mtd_parts = NUM_PARTITIONS;
-                       part_type = "builtin";
-               }
-               printk(KERN_INFO "Using %s partition table\n", part_type);
-               mtd_device_register(mymtd, mtd_parts, nr_mtd_parts);
+               mtd_device_parse_register(mymtd, NULL, 0,
+                               h720x_partitions, NUM_PARTITIONS);
                return 0;
        }
 
@@ -120,10 +105,6 @@ static void __exit h720x_mtd_cleanup(void)
                map_destroy(mymtd);
        }
 
-       /* Free partition info, if commandline partition was used */
-       if (mtd_parts && (mtd_parts != h720x_partitions))
-               kfree (mtd_parts);
-
        if (h720x_map.virt) {
                iounmap((void *)h720x_map.virt);
                h720x_map.virt = 0;
index 404a50cbafa0596ef7ea8d2e0d760607d90bf3df..f47aedb24366bb0f1073a1d6c5803a103f029709 100644 (file)
@@ -49,7 +49,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
 /*
  * MTD partitioning stuff
  */
-static struct mtd_partition static_partitions[] =
+static struct mtd_partition partitions[] =
 {
        {
                .name = "FileSystem",
@@ -58,16 +58,10 @@ static struct mtd_partition static_partitions[] =
        },
 };
 
-static int mtd_parts_nb[NUM_FLASHBANKS];
-static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
-
-static const char *probes[] = { "cmdlinepart", NULL };
-
 static int __init init_impa7(void)
 {
        static const char *rom_probe_types[] = PROBETYPES;
        const char **type;
-       const char *part_type = 0;
        int i;
        static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = {
          { WINDOW_ADDR0, WINDOW_SIZE0 },
@@ -97,23 +91,9 @@ static int __init init_impa7(void)
                if (impa7_mtd[i]) {
                        impa7_mtd[i]->owner = THIS_MODULE;
                        devicesfound++;
-                       mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
-                                                              probes,
-                                                              &mtd_parts[i],
-                                                              0);
-                       if (mtd_parts_nb[i] > 0) {
-                               part_type = "command line";
-                       } else {
-                               mtd_parts[i] = static_partitions;
-                               mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
-                               part_type = "static";
-                       }
-
-                       printk(KERN_NOTICE MSG_PREFIX
-                              "using %s partition definition\n",
-                              part_type);
-                       mtd_device_register(impa7_mtd[i],
-                                           mtd_parts[i], mtd_parts_nb[i]);
+                       mtd_device_parse_register(impa7_mtd[i], NULL, 0,
+                                                 partitions,
+                                                 ARRAY_SIZE(partitions));
                }
                else
                        iounmap((void *)impa7_map[i].virt);
index d2f47be8754b211392c0841fd32685396878481a..08c239604ee44e1b71438feda4d30f065b0663f6 100644 (file)
@@ -44,7 +44,6 @@ struct vr_nor_mtd {
        void __iomem *csr_base;
        struct map_info map;
        struct mtd_info *info;
-       int nr_parts;
        struct pci_dev *dev;
 };
 
@@ -71,13 +70,9 @@ static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p)
 
 static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p)
 {
-       struct mtd_partition *parts;
-       static const char *part_probes[] = { "cmdlinepart", NULL };
-
        /* register the flash bank */
        /* partition the flash bank */
-       p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0);
-       return mtd_device_register(p->info, parts, p->nr_parts);
+       return mtd_device_parse_register(p->info, NULL, 0, NULL, 0);
 }
 
 static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
index 1594a802631d439f008c58b601e5c29ab6d14a21..437fcd2f352f8095b658cc4a9d1ef28cc01eddf5 100644 (file)
@@ -38,7 +38,6 @@
 struct ixp2000_flash_info {
        struct          mtd_info *mtd;
        struct          map_info map;
-       struct          mtd_partition *partitions;
        struct          resource *res;
 };
 
@@ -125,8 +124,6 @@ static int ixp2000_flash_remove(struct platform_device *dev)
        if (info->map.map_priv_1)
                iounmap((void *) info->map.map_priv_1);
 
-       kfree(info->partitions);
-
        if (info->res) {
                release_resource(info->res);
                kfree(info->res);
@@ -229,13 +226,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
        }
        info->mtd->owner = THIS_MODULE;
 
-       err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
-       if (err > 0) {
-               err = mtd_device_register(info->mtd, info->partitions, err);
-               if(err)
-                       dev_err(&dev->dev, "Could not parse partitions\n");
-       }
-
+       err = mtd_device_parse_register(info->mtd, probes, 0, NULL, 0);
        if (err)
                goto Error;
 
index 155b21942f4777a1aea10a8a22b04778ca82ec33..30409015a3de1d67e9d37c2ce345b0a837a28006 100644 (file)
@@ -145,7 +145,6 @@ static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
 struct ixp4xx_flash_info {
        struct mtd_info *mtd;
        struct map_info map;
-       struct mtd_partition *partitions;
        struct resource *res;
 };
 
@@ -168,8 +167,6 @@ static int ixp4xx_flash_remove(struct platform_device *dev)
        if (info->map.virt)
                iounmap(info->map.virt);
 
-       kfree(info->partitions);
-
        if (info->res) {
                release_resource(info->res);
                kfree(info->res);
@@ -185,8 +182,6 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 {
        struct flash_platform_data *plat = dev->dev.platform_data;
        struct ixp4xx_flash_info *info;
-       const char *part_type = NULL;
-       int nr_parts = 0;
        int err = -1;
 
        if (!plat)
@@ -252,28 +247,12 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
        /* Use the fast version */
        info->map.write = ixp4xx_write16;
 
-       nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions,
-                                       dev->resource->start);
-       if (nr_parts > 0) {
-               part_type = "dynamic";
-       } else {
-               info->partitions = plat->parts;
-               nr_parts = plat->nr_parts;
-               part_type = "static";
-       }
-       if (nr_parts == 0)
-               printk(KERN_NOTICE "IXP4xx flash: no partition info "
-                       "available, registering whole flash\n");
-       else
-               printk(KERN_NOTICE "IXP4xx flash: using %s partition "
-                       "definition\n", part_type);
-
-       err = mtd_device_register(info->mtd, info->partitions, nr_parts);
-       if (err)
+       err = mtd_device_parse_register(info->mtd, probes, dev->resource->start,
+                       plat->parts, plat->nr_parts);
+       if (err) {
                printk(KERN_ERR "Could not parse partitions\n");
-
-       if (err)
                goto Error;
+       }
 
        return 0;
 
index a90cabd7b84d92eb75c061d02805c0db5d15f614..4f10e27ada551d12f77cfd4d72b02f15ef9c5c8d 100644 (file)
@@ -107,16 +107,12 @@ ltq_copy_to(struct map_info *map, unsigned long to,
        spin_unlock_irqrestore(&ebu_lock, flags);
 }
 
-static const char const *part_probe_types[] = { "cmdlinepart", NULL };
-
 static int __init
 ltq_mtd_probe(struct platform_device *pdev)
 {
        struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
        struct ltq_mtd *ltq_mtd;
-       struct mtd_partition *parts;
        struct resource *res;
-       int nr_parts = 0;
        struct cfi_private *cfi;
        int err;
 
@@ -172,17 +168,8 @@ ltq_mtd_probe(struct platform_device *pdev)
        cfi->addr_unlock1 ^= 1;
        cfi->addr_unlock2 ^= 1;
 
-       nr_parts = parse_mtd_partitions(ltq_mtd->mtd,
-                               part_probe_types, &parts, 0);
-       if (nr_parts > 0) {
-               dev_info(&pdev->dev,
-                       "using %d partitions from cmdline", nr_parts);
-       } else {
-               nr_parts = ltq_mtd_data->nr_parts;
-               parts = ltq_mtd_data->parts;
-       }
-
-       err = add_mtd_partitions(ltq_mtd->mtd, parts, nr_parts);
+       err = mtd_device_parse_register(ltq_mtd->mtd, NULL, 0,
+                       ltq_mtd_data->parts, ltq_mtd_data->nr_parts);
        if (err) {
                dev_err(&pdev->dev, "failed to add partitions\n");
                goto err_destroy;
@@ -208,7 +195,7 @@ ltq_mtd_remove(struct platform_device *pdev)
 
        if (ltq_mtd) {
                if (ltq_mtd->mtd) {
-                       del_mtd_partitions(ltq_mtd->mtd);
+                       mtd_device_unregister(ltq_mtd->mtd);
                        map_destroy(ltq_mtd->mtd);
                }
                if (ltq_mtd->map->virt)
index 5936c466e901369be6b0d7a9a13c4330fe78fcdc..119baa7d74773088ea0f07ffd316b6ee2c807b7d 100644 (file)
@@ -33,9 +33,6 @@ struct latch_addr_flash_info {
        /* cache; could be found out of res */
        unsigned long           win_mask;
 
-       int                     nr_parts;
-       struct mtd_partition    *parts;
-
        spinlock_t              lock;
 };
 
@@ -97,8 +94,6 @@ static void lf_copy_from(struct map_info *map, void *to,
 
 static char *rom_probe_types[] = { "cfi_probe", NULL };
 
-static char *part_probe_types[] = { "cmdlinepart", NULL };
-
 static int latch_addr_flash_remove(struct platform_device *dev)
 {
        struct latch_addr_flash_info *info;
@@ -112,8 +107,6 @@ static int latch_addr_flash_remove(struct platform_device *dev)
        latch_addr_data = dev->dev.platform_data;
 
        if (info->mtd != NULL) {
-               if (info->nr_parts)
-                       kfree(info->parts);
                mtd_device_unregister(info->mtd);
                map_destroy(info->mtd);
        }
@@ -206,21 +199,8 @@ static int __devinit latch_addr_flash_probe(struct platform_device *dev)
        }
        info->mtd->owner = THIS_MODULE;
 
-       err = parse_mtd_partitions(info->mtd, (const char **)part_probe_types,
-                                  &info->parts, 0);
-       if (err > 0) {
-               mtd_device_register(info->mtd, info->parts, err);
-               return 0;
-       }
-       if (latch_addr_data->nr_parts) {
-               pr_notice("Using latch-addr-flash partition information\n");
-               mtd_device_register(info->mtd,
-                                   latch_addr_data->parts,
-                                   latch_addr_data->nr_parts);
-               return 0;
-       }
-
-       mtd_device_register(info->mtd, NULL, 0);
+       mtd_device_parse_register(info->mtd, NULL, 0,
+                       latch_addr_data->parts, latch_addr_data->nr_parts);
        return 0;
 
 iounmap:
index bbe168b65c26a392e09bc8bdb4783b2d5c7ab06f..e8e9fec23553d06ea34410633c12c8cce558fdb2 100644 (file)
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 
-#ifdef CONFIG_MTD_DEBUG
-static int debug = CONFIG_MTD_DEBUG_VERBOSE;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
-#undef DEBUG
-#define DEBUG(n, format, arg...) \
-       if (n <= debug) {        \
-               printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
-       }
-
-#else
-#undef DEBUG
-#define DEBUG(n, arg...)
-static const int debug = 0;
-#endif
-
 #define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
 
 #define DRIVER_DESC    "PCMCIA Flash memory card driver"
@@ -105,13 +89,13 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
        int ret;
 
        if (!pcmcia_dev_present(dev->p_dev)) {
-               DEBUG(1, "device removed");
+               pr_debug("device removed\n");
                return 0;
        }
 
        offset = to & ~(dev->win_size-1);
        if (offset != dev->offset) {
-               DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
+               pr_debug("Remapping window from 0x%8.8x to 0x%8.8x\n",
                      dev->offset, offset);
                ret = pcmcia_map_mem_page(dev->p_dev, win, offset);
                if (ret != 0)
@@ -132,7 +116,7 @@ static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readb(addr);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx", ofs, addr, d.x[0]);
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n", ofs, addr, d.x[0]);
        return d;
 }
 
@@ -147,7 +131,7 @@ static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readw(addr);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx", ofs, addr, d.x[0]);
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n", ofs, addr, d.x[0]);
        return d;
 }
 
@@ -157,7 +141,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        unsigned long win_size = dev->win_size;
 
-       DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
+       pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
        while(len) {
                int toread = win_size - (from & (win_size-1));
                caddr_t addr;
@@ -169,7 +153,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
                if(!addr)
                        return;
 
-               DEBUG(4, "memcpy from %p to %p len = %d", addr, to, toread);
+               pr_debug("memcpy from %p to %p len = %d\n", addr, to, toread);
                memcpy_fromio(to, addr, toread);
                len -= toread;
                to += toread;
@@ -185,7 +169,7 @@ static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long
        if(!addr)
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02lx", adr, addr, d.x[0]);
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%02lx\n", adr, addr, d.x[0]);
        writeb(d.x[0], addr);
 }
 
@@ -196,7 +180,7 @@ static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long
        if(!addr)
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04lx", adr, addr, d.x[0]);
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%04lx\n", adr, addr, d.x[0]);
        writew(d.x[0], addr);
 }
 
@@ -206,7 +190,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        unsigned long win_size = dev->win_size;
 
-       DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
+       pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
        while(len) {
                int towrite = win_size - (to & (win_size-1));
                caddr_t addr;
@@ -218,7 +202,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
                if(!addr)
                        return;
 
-               DEBUG(4, "memcpy from %p to %p len = %d", from, addr, towrite);
+               pr_debug("memcpy from %p to %p len = %d\n", from, addr, towrite);
                memcpy_toio(addr, from, towrite);
                len -= towrite;
                to += towrite;
@@ -240,7 +224,7 @@ static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readb(win_base + ofs);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx",
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n",
              ofs, win_base + ofs, d.x[0]);
        return d;
 }
@@ -255,7 +239,7 @@ static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readw(win_base + ofs);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx",
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n",
              ofs, win_base + ofs, d.x[0]);
        return d;
 }
@@ -268,7 +252,7 @@ static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from,
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
+       pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
        memcpy_fromio(to, win_base + from, len);
 }
 
@@ -280,7 +264,7 @@ static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02lx",
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%02lx\n",
              adr, win_base + adr, d.x[0]);
        writeb(d.x[0], win_base + adr);
 }
@@ -293,7 +277,7 @@ static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04lx",
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%04lx\n",
              adr, win_base + adr, d.x[0]);
        writew(d.x[0], win_base + adr);
 }
@@ -306,7 +290,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
+       pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
        memcpy_toio(win_base + to, from, len);
 }
 
@@ -316,7 +300,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        struct pcmcia_device *link = dev->p_dev;
 
-       DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
+       pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
        pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
 }
 
@@ -325,7 +309,7 @@ static void pcmciamtd_release(struct pcmcia_device *link)
 {
        struct pcmciamtd_dev *dev = link->priv;
 
-       DEBUG(3, "link = 0x%p", link);
+       pr_debug("link = 0x%p\n", link);
 
        if (link->resource[2]->end) {
                if(dev->win_base) {
@@ -337,7 +321,6 @@ static void pcmciamtd_release(struct pcmcia_device *link)
 }
 
 
-#ifdef CONFIG_MTD_DEBUG
 static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
                                tuple_t *tuple,
                                void *priv_data)
@@ -347,7 +330,7 @@ static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
        if (!pcmcia_parse_tuple(tuple, &parse)) {
                cistpl_format_t *t = &parse.format;
                (void)t; /* Shut up, gcc */
-               DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
+               pr_debug("Format type: %u, Error Detection: %u, offset = %u, length =%u\n",
                        t->type, t->edc, t->offset, t->length);
        }
        return -ENOSPC;
@@ -363,12 +346,11 @@ static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
        if (!pcmcia_parse_tuple(tuple, &parse)) {
                cistpl_jedec_t *t = &parse.jedec;
                for (i = 0; i < t->nid; i++)
-                       DEBUG(2, "JEDEC: 0x%02x 0x%02x",
+                       pr_debug("JEDEC: 0x%02x 0x%02x\n",
                              t->id[i].mfr, t->id[i].info);
        }
        return -ENOSPC;
 }
-#endif
 
 static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
                                tuple_t *tuple,
@@ -382,14 +364,14 @@ static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
        if (pcmcia_parse_tuple(tuple, &parse))
                return -EINVAL;
 
-       DEBUG(2, "Common memory:");
+       pr_debug("Common memory:\n");
        dev->pcmcia_map.size = t->dev[0].size;
        /* from here on: DEBUG only */
        for (i = 0; i < t->ndev; i++) {
-               DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
-               DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
-               DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
-               DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
+               pr_debug("Region %d, type = %u\n", i, t->dev[i].type);
+               pr_debug("Region %d, wp = %u\n", i, t->dev[i].wp);
+               pr_debug("Region %d, speed = %u ns\n", i, t->dev[i].speed);
+               pr_debug("Region %d, size = %u bytes\n", i, t->dev[i].size);
        }
        return 0;
 }
@@ -409,12 +391,12 @@ static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
        dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
        /* from here on: DEBUG only */
        for (i = 0; i < t->ngeo; i++) {
-               DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
-               DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
-               DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
-               DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
-               DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
-               DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
+               pr_debug("region: %d bankwidth = %u\n", i, t->geo[i].buswidth);
+               pr_debug("region: %d erase_block = %u\n", i, t->geo[i].erase_block);
+               pr_debug("region: %d read_block = %u\n", i, t->geo[i].read_block);
+               pr_debug("region: %d write_block = %u\n", i, t->geo[i].write_block);
+               pr_debug("region: %d partition = %u\n", i, t->geo[i].partition);
+               pr_debug("region: %d interleave = %u\n", i, t->geo[i].interleave);
        }
        return 0;
 }
@@ -432,13 +414,11 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
                        if (p_dev->prod_id[i])
                                strcat(dev->mtd_name, p_dev->prod_id[i]);
                }
-               DEBUG(2, "Found name: %s", dev->mtd_name);
+               pr_debug("Found name: %s\n", dev->mtd_name);
        }
 
-#ifdef CONFIG_MTD_DEBUG
        pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
        pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
-#endif
        pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
        pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
 
@@ -450,12 +430,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
 
        if(force_size) {
                dev->pcmcia_map.size = force_size << 20;
-               DEBUG(2, "size forced to %dM", force_size);
+               pr_debug("size forced to %dM\n", force_size);
        }
 
        if(bankwidth) {
                dev->pcmcia_map.bankwidth = bankwidth;
-               DEBUG(2, "bankwidth forced to %d", bankwidth);
+               pr_debug("bankwidth forced to %d\n", bankwidth);
        }
 
        dev->pcmcia_map.name = dev->mtd_name;
@@ -464,7 +444,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
                *new_name = 1;
        }
 
-       DEBUG(1, "Device: Size: %lu Width:%d Name: %s",
+       pr_debug("Device: Size: %lu Width:%d Name: %s\n",
              dev->pcmcia_map.size,
              dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
 }
@@ -479,7 +459,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        static char *probes[] = { "jedec_probe", "cfi_probe" };
        int new_name = 0;
 
-       DEBUG(3, "link=0x%p", link);
+       pr_debug("link=0x%p\n", link);
 
        card_settings(dev, link, &new_name);
 
@@ -512,11 +492,11 @@ static int pcmciamtd_config(struct pcmcia_device *link)
 
        do {
                int ret;
-               DEBUG(2, "requesting window with size = %luKiB memspeed = %d",
+               pr_debug("requesting window with size = %luKiB memspeed = %d\n",
                        (unsigned long) resource_size(link->resource[2]) >> 10,
                        mem_speed);
                ret = pcmcia_request_window(link, link->resource[2], mem_speed);
-               DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
+               pr_debug("ret = %d dev->win_size = %d\n", ret, dev->win_size);
                if(ret) {
                        j++;
                        link->resource[2]->start = 0;
@@ -524,21 +504,21 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                                        force_size << 20 : MAX_PCMCIA_ADDR;
                        link->resource[2]->end >>= j;
                } else {
-                       DEBUG(2, "Got window of size %luKiB", (unsigned long)
+                       pr_debug("Got window of size %luKiB\n", (unsigned long)
                                resource_size(link->resource[2]) >> 10);
                        dev->win_size = resource_size(link->resource[2]);
                        break;
                }
        } while (link->resource[2]->end >= 0x1000);
 
-       DEBUG(2, "dev->win_size = %d", dev->win_size);
+       pr_debug("dev->win_size = %d\n", dev->win_size);
 
        if(!dev->win_size) {
                dev_err(&dev->p_dev->dev, "Cannot allocate memory window\n");
                pcmciamtd_release(link);
                return -ENODEV;
        }
-       DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
+       pr_debug("Allocated a window of %dKiB\n", dev->win_size >> 10);
 
        /* Get write protect status */
        dev->win_base = ioremap(link->resource[2]->start,
@@ -549,7 +529,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                pcmciamtd_release(link);
                return -ENODEV;
        }
-       DEBUG(1, "mapped window dev = %p @ %pR, base = %p",
+       pr_debug("mapped window dev = %p @ %pR, base = %p\n",
              dev, link->resource[2], dev->win_base);
 
        dev->offset = 0;
@@ -564,7 +544,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        }
 
        link->config_index = 0;
-       DEBUG(2, "Setting Configuration");
+       pr_debug("Setting Configuration\n");
        ret = pcmcia_enable_device(link);
        if (ret != 0) {
                if (dev->win_base) {
@@ -580,17 +560,17 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                mtd = do_map_probe("map_rom", &dev->pcmcia_map);
        } else {
                for(i = 0; i < ARRAY_SIZE(probes); i++) {
-                       DEBUG(1, "Trying %s", probes[i]);
+                       pr_debug("Trying %s\n", probes[i]);
                        mtd = do_map_probe(probes[i], &dev->pcmcia_map);
                        if(mtd)
                                break;
 
-                       DEBUG(1, "FAILED: %s", probes[i]);
+                       pr_debug("FAILED: %s\n", probes[i]);
                }
        }
 
        if(!mtd) {
-               DEBUG(1, "Can not find an MTD");
+               pr_debug("Can not find an MTD\n");
                pcmciamtd_release(link);
                return -ENODEV;
        }
@@ -617,7 +597,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        /* If the memory found is fits completely into the mapped PCMCIA window,
           use the faster non-remapping read/write functions */
        if(mtd->size <= dev->win_size) {
-               DEBUG(1, "Using non remapping memory functions");
+               pr_debug("Using non remapping memory functions\n");
                dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
                if (dev->pcmcia_map.bankwidth == 1) {
                        dev->pcmcia_map.read = pcmcia_read8;
@@ -645,7 +625,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
 
 static int pcmciamtd_suspend(struct pcmcia_device *dev)
 {
-       DEBUG(2, "EVENT_PM_RESUME");
+       pr_debug("EVENT_PM_RESUME\n");
 
        /* get_lock(link); */
 
@@ -654,7 +634,7 @@ static int pcmciamtd_suspend(struct pcmcia_device *dev)
 
 static int pcmciamtd_resume(struct pcmcia_device *dev)
 {
-       DEBUG(2, "EVENT_PM_SUSPEND");
+       pr_debug("EVENT_PM_SUSPEND\n");
 
        /* free_lock(link); */
 
@@ -666,7 +646,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
 {
        struct pcmciamtd_dev *dev = link->priv;
 
-       DEBUG(3, "link=0x%p", link);
+       pr_debug("link=0x%p\n", link);
 
        if(dev->mtd_info) {
                mtd_device_unregister(dev->mtd_info);
@@ -686,7 +666,7 @@ static int pcmciamtd_probe(struct pcmcia_device *link)
        /* Create new memory card device */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev) return -ENOMEM;
-       DEBUG(1, "dev=0x%p", dev);
+       pr_debug("dev=0x%p\n", dev);
 
        dev->p_dev = link;
        link->priv = dev;
@@ -755,7 +735,7 @@ static int __init init_pcmciamtd(void)
 
 static void __exit exit_pcmciamtd(void)
 {
-       DEBUG(1, DRIVER_DESC " unloading");
+       pr_debug(DRIVER_DESC " unloading");
        pcmcia_unregister_driver(&pcmciamtd_driver);
 }
 
index f64cee4a3bfbeba9674fea84c4465e645d925594..66e8200079c2c25633db8f662967825575b89915 100644 (file)
@@ -27,8 +27,6 @@ struct physmap_flash_info {
        struct mtd_info         *mtd[MAX_RESOURCES];
        struct mtd_info         *cmtd;
        struct map_info         map[MAX_RESOURCES];
-       int                     nr_parts;
-       struct mtd_partition    *parts;
 };
 
 static int physmap_flash_remove(struct platform_device *dev)
@@ -46,8 +44,6 @@ static int physmap_flash_remove(struct platform_device *dev)
 
        if (info->cmtd) {
                mtd_device_unregister(info->cmtd);
-               if (info->nr_parts)
-                       kfree(info->parts);
                if (info->cmtd != info->mtd[0])
                        mtd_concat_destroy(info->cmtd);
        }
@@ -175,23 +171,8 @@ static int physmap_flash_probe(struct platform_device *dev)
        if (err)
                goto err_out;
 
-       err = parse_mtd_partitions(info->cmtd, part_probe_types,
-                                  &info->parts, 0);
-       if (err > 0) {
-               mtd_device_register(info->cmtd, info->parts, err);
-               info->nr_parts = err;
-               return 0;
-       }
-
-       if (physmap_data->nr_parts) {
-               printk(KERN_NOTICE "Using physmap partition information\n");
-               mtd_device_register(info->cmtd, physmap_data->parts,
-                                   physmap_data->nr_parts);
-               return 0;
-       }
-
-       mtd_device_register(info->cmtd, NULL, 0);
-
+       mtd_device_parse_register(info->cmtd, part_probe_types, 0,
+                                 physmap_data->parts, physmap_data->nr_parts);
        return 0;
 
 err_out:
@@ -245,21 +226,6 @@ static struct platform_device physmap_flash = {
        .num_resources  = 1,
        .resource       = &physmap_flash_resource,
 };
-
-void physmap_configure(unsigned long addr, unsigned long size,
-               int bankwidth, void (*set_vpp)(struct map_info *, int))
-{
-       physmap_flash_resource.start = addr;
-       physmap_flash_resource.end = addr + size - 1;
-       physmap_flash_data.width = bankwidth;
-       physmap_flash_data.set_vpp = set_vpp;
-}
-
-void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
-{
-       physmap_flash_data.nr_parts = num_parts;
-       physmap_flash_data.parts = parts;
-}
 #endif
 
 static int __init physmap_init(void)
index d251d1db129b3fd81391302b1add42b0052e869d..7d65f9d3e6902e442003dfd7455953d1199c2d9a 100644 (file)
@@ -34,58 +34,10 @@ struct of_flash_list {
 
 struct of_flash {
        struct mtd_info         *cmtd;
-       struct mtd_partition    *parts;
        int list_size; /* number of elements in of_flash_list */
        struct of_flash_list    list[0];
 };
 
-#define OF_FLASH_PARTS(info)   ((info)->parts)
-static int parse_obsolete_partitions(struct platform_device *dev,
-                                    struct of_flash *info,
-                                    struct device_node *dp)
-{
-       int i, plen, nr_parts;
-       const struct {
-               __be32 offset, len;
-       } *part;
-       const char *names;
-
-       part = of_get_property(dp, "partitions", &plen);
-       if (!part)
-               return 0; /* No partitions found */
-
-       dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
-
-       nr_parts = plen / sizeof(part[0]);
-
-       info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL);
-       if (!info->parts)
-               return -ENOMEM;
-
-       names = of_get_property(dp, "partition-names", &plen);
-
-       for (i = 0; i < nr_parts; i++) {
-               info->parts[i].offset = be32_to_cpu(part->offset);
-               info->parts[i].size   = be32_to_cpu(part->len) & ~1;
-               if (be32_to_cpu(part->len) & 1) /* bit 0 set signifies read only partition */
-                       info->parts[i].mask_flags = MTD_WRITEABLE;
-
-               if (names && (plen > 0)) {
-                       int len = strlen(names) + 1;
-
-                       info->parts[i].name = (char *)names;
-                       plen -= len;
-                       names += len;
-               } else {
-                       info->parts[i].name = "unnamed";
-               }
-
-               part++;
-       }
-
-       return nr_parts;
-}
-
 static int of_flash_remove(struct platform_device *dev)
 {
        struct of_flash *info;
@@ -101,11 +53,8 @@ static int of_flash_remove(struct platform_device *dev)
                mtd_concat_destroy(info->cmtd);
        }
 
-       if (info->cmtd) {
-               if (OF_FLASH_PARTS(info))
-                       kfree(OF_FLASH_PARTS(info));
+       if (info->cmtd)
                mtd_device_unregister(info->cmtd);
-       }
 
        for (i = 0; i < info->list_size; i++) {
                if (info->list[i].mtd)
@@ -165,7 +114,8 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,
    specifies the list of partition probers to use. If none is given then the
    default is use. These take precedence over other device tree
    information. */
-static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL };
+static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",
+                                       "ofpart", "ofoldpart", NULL };
 static const char ** __devinit of_get_probes(struct device_node *dp)
 {
        const char *cp;
@@ -218,6 +168,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
        int reg_tuple_size;
        struct mtd_info **mtd_list = NULL;
        resource_size_t res_size;
+       struct mtd_part_parser_data ppdata;
 
        match = of_match_device(of_flash_match, &dev->dev);
        if (!match)
@@ -331,29 +282,12 @@ static int __devinit of_flash_probe(struct platform_device *dev)
        if (err)
                goto err_out;
 
+       ppdata.of_node = dp;
        part_probe_types = of_get_probes(dp);
-       err = parse_mtd_partitions(info->cmtd, part_probe_types,
-                                  &info->parts, 0);
-       if (err < 0) {
-               of_free_probes(part_probe_types);
-               goto err_out;
-       }
+       mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
+                       NULL, 0);
        of_free_probes(part_probe_types);
 
-       if (err == 0) {
-               err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
-               if (err < 0)
-                       goto err_out;
-       }
-
-       if (err == 0) {
-               err = parse_obsolete_partitions(dev, info, dp);
-               if (err < 0)
-                       goto err_out;
-       }
-
-       mtd_device_register(info->cmtd, info->parts, err);
-
        kfree(mtd_list);
 
        return 0;
index 9ca1eccba4bc2e70b0d5e7ea6c3be5d014f6da5e..94f553489725280d2ec851023f17745e86c48d9a 100644 (file)
@@ -44,8 +44,6 @@ struct platram_info {
        struct device           *dev;
        struct mtd_info         *mtd;
        struct map_info          map;
-       struct mtd_partition    *partitions;
-       bool                    free_partitions;
        struct resource         *area;
        struct platdata_mtd_ram *pdata;
 };
@@ -95,10 +93,6 @@ static int platram_remove(struct platform_device *pdev)
 
        if (info->mtd) {
                mtd_device_unregister(info->mtd);
-               if (info->partitions) {
-                       if (info->free_partitions)
-                               kfree(info->partitions);
-               }
                map_destroy(info->mtd);
        }
 
@@ -228,21 +222,8 @@ static int platram_probe(struct platform_device *pdev)
        /* check to see if there are any available partitions, or wether
         * to add this device whole */
 
-       if (!pdata->nr_partitions) {
-               /* try to probe using the supplied probe type */
-               if (pdata->probes) {
-                       err = parse_mtd_partitions(info->mtd, pdata->probes,
-                                          &info->partitions, 0);
-                       info->free_partitions = 1;
-                       if (err > 0)
-                               err = mtd_device_register(info->mtd,
-                                       info->partitions, err);
-               }
-       }
-       /* use the static mapping */
-       else
-               err = mtd_device_register(info->mtd, pdata->partitions,
-                                         pdata->nr_partitions);
+       err = mtd_device_parse_register(info->mtd, pdata->probes, 0,
+                       pdata->partitions, pdata->nr_partitions);
        if (!err)
                dev_info(&pdev->dev, "registered mtd device\n");
 
index 7ae137d4b99871bbbe94f6b11effa25b5537875d..411a17df9fc13ee2fd78d8e54456e18095bdd91f 100644 (file)
@@ -41,8 +41,6 @@ static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
 }
 
 struct pxa2xx_flash_info {
-       struct mtd_partition    *parts;
-       int                     nr_parts;
        struct mtd_info         *mtd;
        struct map_info         map;
 };
@@ -55,9 +53,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *flash = pdev->dev.platform_data;
        struct pxa2xx_flash_info *info;
-       struct mtd_partition *parts;
        struct resource *res;
-       int ret = 0;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
@@ -71,8 +67,6 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
        info->map.bankwidth = flash->width;
        info->map.phys = res->start;
        info->map.size = resource_size(res);
-       info->parts = flash->parts;
-       info->nr_parts = flash->nr_parts;
 
        info->map.virt = ioremap(info->map.phys, info->map.size);
        if (!info->map.virt) {
@@ -104,18 +98,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
        }
        info->mtd->owner = THIS_MODULE;
 
-       ret = parse_mtd_partitions(info->mtd, probes, &parts, 0);
-
-       if (ret > 0) {
-               info->nr_parts = ret;
-               info->parts = parts;
-       }
-
-       if (!info->nr_parts)
-               printk("Registering %s as whole device\n",
-                      info->map.name);
-
-       mtd_device_register(info->mtd, info->parts, info->nr_parts);
+       mtd_device_parse_register(info->mtd, probes, 0, NULL, 0);
 
        platform_set_drvdata(pdev, info);
        return 0;
@@ -133,7 +116,6 @@ static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
        iounmap(info->map.virt);
        if (info->map.cached)
                iounmap(info->map.cached);
-       kfree(info->parts);
        kfree(info);
        return 0;
 }
index 761fb459d2c74179105fb9ded586681c66ae6aae..0237f197fd1238f553732f73a2db64ddba98c0f6 100644 (file)
@@ -25,8 +25,6 @@
 struct rbtx4939_flash_info {
        struct mtd_info *mtd;
        struct map_info map;
-       int nr_parts;
-       struct mtd_partition *parts;
 };
 
 static int rbtx4939_flash_remove(struct platform_device *dev)
@@ -41,8 +39,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
        if (info->mtd) {
                struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
 
-               if (info->nr_parts)
-                       kfree(info->parts);
                mtd_device_unregister(info->mtd);
                map_destroy(info->mtd);
        }
@@ -50,7 +46,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
 }
 
 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
-static const char *part_probe_types[] = { "cmdlinepart", NULL };
 
 static int rbtx4939_flash_probe(struct platform_device *dev)
 {
@@ -107,22 +102,11 @@ static int rbtx4939_flash_probe(struct platform_device *dev)
        info->mtd->owner = THIS_MODULE;
        if (err)
                goto err_out;
+       err = mtd_device_parse_register(info->mtd, NULL, 0,
+                       pdata->parts, pdata->nr_parts);
 
-       err = parse_mtd_partitions(info->mtd, part_probe_types,
-                               &info->parts, 0);
-       if (err > 0) {
-               mtd_device_register(info->mtd, info->parts, err);
-               info->nr_parts = err;
-               return 0;
-       }
-
-       if (pdata->nr_parts) {
-               pr_notice("Using rbtx4939 partition information\n");
-               mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
-               return 0;
-       }
-
-       mtd_device_register(info->mtd, NULL, 0);
+       if (err)
+               goto err_out;
        return 0;
 
 err_out:
index a9b5e0e5c4c559b059842468d5c15a70f0bfc7c3..fa9c0a9670cd88a4e050ba65f0d70f51fee9f3d7 100644 (file)
@@ -131,10 +131,8 @@ struct sa_subdev_info {
 };
 
 struct sa_info {
-       struct mtd_partition    *parts;
        struct mtd_info         *mtd;
        int                     num_subdev;
-       unsigned int            nr_parts;
        struct sa_subdev_info   subdev[0];
 };
 
@@ -231,8 +229,6 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
                        mtd_concat_destroy(info->mtd);
        }
 
-       kfree(info->parts);
-
        for (i = info->num_subdev - 1; i >= 0; i--)
                sa1100_destroy_subdev(&info->subdev[i]);
        kfree(info);
@@ -341,10 +337,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *plat = pdev->dev.platform_data;
-       struct mtd_partition *parts;
-       const char *part_type = NULL;
        struct sa_info *info;
-       int err, nr_parts = 0;
+       int err;
 
        if (!plat)
                return -ENODEV;
@@ -358,26 +352,8 @@ static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
        /*
         * Partition selection stuff.
         */
-       nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0);
-       if (nr_parts > 0) {
-               info->parts = parts;
-               part_type = "dynamic";
-       } else {
-               parts = plat->parts;
-               nr_parts = plat->nr_parts;
-               part_type = "static";
-       }
-
-       if (nr_parts == 0)
-               printk(KERN_NOTICE "SA1100 flash: no partition info "
-                       "available, registering whole flash\n");
-       else
-               printk(KERN_NOTICE "SA1100 flash: using %s partition "
-                       "definition\n", part_type);
-
-       mtd_device_register(info->mtd, parts, nr_parts);
-
-       info->nr_parts = nr_parts;
+       mtd_device_parse_register(info->mtd, part_probes, 0,
+                       plat->parts, plat->nr_parts);
 
        platform_set_drvdata(pdev, info);
        err = 0;
index cbf6bade9354681164e707b2e43924b21a833578..496c40704aff6567dcd7546b0cb9c87742222263 100644 (file)
@@ -19,8 +19,6 @@
 static struct mtd_info *flash_mtd;
 static struct mtd_info *eprom_mtd;
 
-static struct mtd_partition *parsed_parts;
-
 struct map_info soleng_eprom_map = {
        .name = "Solution Engine EPROM",
        .size = 0x400000,
@@ -51,12 +49,14 @@ static struct mtd_partition superh_se_partitions[] = {
                .size = MTDPART_SIZ_FULL,
        }
 };
+#define NUM_PARTITIONS ARRAY_SIZE(superh_se_partitions)
+#else
+#define superh_se_partitions NULL
+#define NUM_PARTITIONS 0
 #endif /* CONFIG_MTD_SUPERH_RESERVE */
 
 static int __init init_soleng_maps(void)
 {
-       int nr_parts = 0;
-
        /* First probe at offset 0 */
        soleng_flash_map.phys = 0;
        soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0);
@@ -92,21 +92,8 @@ static int __init init_soleng_maps(void)
                mtd_device_register(eprom_mtd, NULL, 0);
        }
 
-       nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
-
-#ifdef CONFIG_MTD_SUPERH_RESERVE
-       if (nr_parts <= 0) {
-               printk(KERN_NOTICE "Using configured partition at 0x%08x.\n",
-                      CONFIG_MTD_SUPERH_RESERVE);
-               parsed_parts = superh_se_partitions;
-               nr_parts = sizeof(superh_se_partitions)/sizeof(*parsed_parts);
-       }
-#endif /* CONFIG_MTD_SUPERH_RESERVE */
-
-       if (nr_parts > 0)
-               mtd_device_register(flash_mtd, parsed_parts, nr_parts);
-       else
-               mtd_device_register(flash_mtd, NULL, 0);
+       mtd_device_parse_register(flash_mtd, probes, 0,
+                       superh_se_partitions, NUM_PARTITIONS);
 
        return 0;
 }
@@ -118,10 +105,7 @@ static void __exit cleanup_soleng_maps(void)
                map_destroy(eprom_mtd);
        }
 
-       if (parsed_parts)
-               mtd_device_unregister(flash_mtd);
-       else
-               mtd_device_unregister(flash_mtd);
+       mtd_device_unregister(flash_mtd);
        map_destroy(flash_mtd);
 }
 
index 901ce968efaebc11acf9e9c4e5460dfec7fc3e3d..aa7e0cb2893c791311e71356ec79d074745129a6 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/immap_cpm2.h>
 
 static struct mtd_info *sbcmtd[3];
-static struct mtd_partition *sbcmtd_parts[3];
 
 struct map_info sbc82xx_flash_map[3] = {
        {.name = "Boot flash"},
@@ -101,6 +100,7 @@ static int __init init_sbc82xx_flash(void)
        for (i=0; i<3; i++) {
                int8_t flashcs[3] = { 0, 6, 1 };
                int nr_parts;
+               struct mtd_partition *defparts;
 
                printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
                       sbc82xx_flash_map[i].name,
@@ -113,7 +113,8 @@ static int __init init_sbc82xx_flash(void)
                }
                printk(" at %08lx)\n",  sbc82xx_flash_map[i].phys);
 
-               sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size);
+               sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys,
+                                                   sbc82xx_flash_map[i].size);
 
                if (!sbc82xx_flash_map[i].virt) {
                        printk("Failed to ioremap\n");
@@ -129,24 +130,20 @@ static int __init init_sbc82xx_flash(void)
 
                sbcmtd[i]->owner = THIS_MODULE;
 
-               nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes,
-                                               &sbcmtd_parts[i], 0);
-               if (nr_parts > 0) {
-                       mtd_device_register(sbcmtd[i], sbcmtd_parts[i],
-                                           nr_parts);
-                       continue;
-               }
-
                /* No partitioning detected. Use default */
                if (i == 2) {
-                       mtd_device_register(sbcmtd[i], NULL, 0);
+                       defparts = NULL;
+                       nr_parts = 0;
                } else if (i == bigflash) {
-                       mtd_device_register(sbcmtd[i], bigflash_parts,
-                                           ARRAY_SIZE(bigflash_parts));
+                       defparts = bigflash_parts;
+                       nr_parts = ARRAY_SIZE(bigflash_parts);
                } else {
-                       mtd_device_register(sbcmtd[i], smallflash_parts,
-                                           ARRAY_SIZE(smallflash_parts));
+                       defparts = smallflash_parts;
+                       nr_parts = ARRAY_SIZE(smallflash_parts);
                }
+
+               mtd_device_parse_register(sbcmtd[i], part_probes, 0,
+                                         defparts, nr_parts);
        }
        return 0;
 }
@@ -159,12 +156,8 @@ static void __exit cleanup_sbc82xx_flash(void)
                if (!sbcmtd[i])
                        continue;
 
-               if (i<2 || sbcmtd_parts[i])
-                       mtd_device_unregister(sbcmtd[i]);
-               else
-                       mtd_device_unregister(sbcmtd[i]);
+               mtd_device_unregister(sbcmtd[i]);
 
-               kfree(sbcmtd_parts[i]);
                map_destroy(sbcmtd[i]);
 
                iounmap((void *)sbc82xx_flash_map[i].virt);
index 3326615ad66b957c57234bf3eb83699a393ff62e..7c1dc908a17475eeb1f610deb8f36505e5b2e439 100644 (file)
@@ -44,7 +44,7 @@ struct mtdblk_dev {
        enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
 };
 
-static struct mutex mtdblks_lock;
+static DEFINE_MUTEX(mtdblks_lock);
 
 /*
  * Cache stuff...
@@ -119,7 +119,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
        if (mtdblk->cache_state != STATE_DIRTY)
                return 0;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
+       pr_debug("mtdblock: writing cached data for \"%s\" "
                        "at 0x%lx, size 0x%x\n", mtd->name,
                        mtdblk->cache_offset, mtdblk->cache_size);
 
@@ -148,7 +148,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
        size_t retlen;
        int ret;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
+       pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
                mtd->name, pos, len);
 
        if (!sect_size)
@@ -218,7 +218,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
        size_t retlen;
        int ret;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
+       pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
                        mtd->name, pos, len);
 
        if (!sect_size)
@@ -283,7 +283,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
 {
        struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
 
-       DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
+       pr_debug("mtdblock_open\n");
 
        mutex_lock(&mtdblks_lock);
        if (mtdblk->count) {
@@ -303,7 +303,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
 
        mutex_unlock(&mtdblks_lock);
 
-       DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
+       pr_debug("ok\n");
 
        return 0;
 }
@@ -312,7 +312,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
 {
        struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
 
-       DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
+       pr_debug("mtdblock_release\n");
 
        mutex_lock(&mtdblks_lock);
 
@@ -329,7 +329,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
 
        mutex_unlock(&mtdblks_lock);
 
-       DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
+       pr_debug("ok\n");
 
        return 0;
 }
@@ -389,8 +389,6 @@ static struct mtd_blktrans_ops mtdblock_tr = {
 
 static int __init init_mtdblock(void)
 {
-       mutex_init(&mtdblks_lock);
-
        return register_mtd_blktrans(&mtdblock_tr);
 }
 
index f1af2228a1b1ec2e90ee2cb19958a68f0d7bb0da..a75d55577e49d20383a8ad14908ceda3d2ad2321 100644 (file)
@@ -43,7 +43,7 @@ static struct vfsmount *mtd_inode_mnt __read_mostly;
 
 /*
  * Data structure to hold the pointer to the mtd device as well
- * as mode information ofr various use cases.
+ * as mode information of various use cases.
  */
 struct mtd_file_info {
        struct mtd_info *mtd;
@@ -86,7 +86,7 @@ static int mtd_open(struct inode *inode, struct file *file)
        struct mtd_file_info *mfi;
        struct inode *mtd_ino;
 
-       DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n");
+       pr_debug("MTD_open\n");
 
        /* You can't open the RO devices RW */
        if ((file->f_mode & FMODE_WRITE) && (minor & 1))
@@ -151,7 +151,7 @@ static int mtd_close(struct inode *inode, struct file *file)
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
 
-       DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
+       pr_debug("MTD_close\n");
 
        /* Only sync if opened RW */
        if ((file->f_mode & FMODE_WRITE) && mtd->sync)
@@ -195,7 +195,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
        size_t size = count;
        char *kbuf;
 
-       DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
+       pr_debug("MTD_read\n");
 
        if (*ppos + count > mtd->size)
                count = mtd->size - *ppos;
@@ -233,9 +233,9 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
                default:
                        ret = mtd->read(mtd, *ppos, len, &retlen, kbuf);
                }
-               /* Nand returns -EBADMSG on ecc errors, but it returns
+               /* Nand returns -EBADMSG on ECC errors, but it returns
                 * the data. For our userspace tools it is important
-                * to dump areas with ecc errors !
+                * to dump areas with ECC errors!
                 * For kernel internal usage it also might return -EUCLEAN
                 * to signal the caller that a bitflip has occurred and has
                 * been corrected by the ECC algorithm.
@@ -278,7 +278,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
        int ret=0;
        int len;
 
-       DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
+       pr_debug("MTD_write\n");
 
        if (*ppos == mtd->size)
                return -ENOSPC;
@@ -320,6 +320,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
                        ops.mode = MTD_OOB_RAW;
                        ops.datbuf = kbuf;
                        ops.oobbuf = NULL;
+                       ops.ooboffs = 0;
                        ops.len = len;
 
                        ret = mtd->write_oob(mtd, *ppos, &ops);
@@ -472,13 +473,29 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
                ret = -EFAULT;
 
        kfree(ops.oobbuf);
+
+       /*
+        * NAND returns -EBADMSG on ECC errors, but it returns the OOB
+        * data. For our userspace tools it is important to dump areas
+        * with ECC errors!
+        * For kernel internal usage it also might return -EUCLEAN
+        * to signal the caller that a bitflip has occured and has
+        * been corrected by the ECC algorithm.
+        *
+        * Note: currently the standard NAND function, nand_read_oob_std,
+        * does not calculate ECC for the OOB area, so do not rely on
+        * this behavior unless you have replaced it with your own.
+        */
+       if (ret == -EUCLEAN || ret == -EBADMSG)
+               return 0;
+
        return ret;
 }
 
 /*
  * Copies (and truncates, if necessary) data from the larger struct,
  * nand_ecclayout, to the smaller, deprecated layout struct,
- * nand_ecclayout_user. This is necessary only to suppport the deprecated
+ * nand_ecclayout_user. This is necessary only to support the deprecated
  * API ioctl ECCGETLAYOUT while allowing all new functionality to use
  * nand_ecclayout flexibly (i.e. the struct may change size in new
  * releases without requiring major rewrites).
@@ -553,7 +570,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
        u_long size;
        struct mtd_info_user info;
 
-       DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
+       pr_debug("MTD_ioctl\n");
 
        size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
        if (cmd & IOC_IN) {
@@ -882,7 +899,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
        }
 #endif
 
-       /* This ioctl is being deprecated - it truncates the ecc layout */
+       /* This ioctl is being deprecated - it truncates the ECC layout */
        case ECCGETLAYOUT:
        {
                struct nand_ecclayout_user *usrlay;
index e601672a53050900d3d0b8cf084829db6d10d9bd..d3fabd144d6c380acd13029420a92957bb264fe2 100644 (file)
@@ -770,7 +770,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],       /* subdevices to c
 
        /*
         * Set up the new "super" device's MTD object structure, check for
-        * incompatibilites between the subdevices.
+        * incompatibilities between the subdevices.
         */
        concat->mtd.type = subdev[0]->type;
        concat->mtd.flags = subdev[0]->flags;
index c510aff289a88d077d9e42c6854bfdcd1533e3be..09bdbac51868bb2fd8f19ff744df66dbbc248ef6 100644 (file)
@@ -362,7 +362,7 @@ int add_mtd_device(struct mtd_info *mtd)
                              MTD_DEVT(i) + 1,
                              NULL, "mtd%dro", i);
 
-       DEBUG(0, "mtd: Giving out device %d to %s\n", i, mtd->name);
+       pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name);
        /* No need to get a refcount on the module containing
           the notifier, since we hold the mtd_table_mutex */
        list_for_each_entry(not, &mtd_notifiers, list)
@@ -429,27 +429,62 @@ out_error:
 }
 
 /**
- * mtd_device_register - register an MTD device.
+ * mtd_device_parse_register - parse partitions and register an MTD device.
  *
- * @master: the MTD device to register
- * @parts: the partitions to register - only valid if nr_parts > 0
- * @nr_parts: the number of partitions in parts.  If zero then the full MTD
- *            device is registered
+ * @mtd: the MTD device to register
+ * @types: the list of MTD partition probes to try, see
+ *         'parse_mtd_partitions()' for more information
+ * @parser_data: MTD partition parser-specific data
+ * @parts: fallback partition information to register, if parsing fails;
+ *         only valid if %nr_parts > %0
+ * @nr_parts: the number of partitions in parts, if zero then the full
+ *            MTD device is registered if no partition info is found
  *
- * Register an MTD device with the system and optionally, a number of
- * partitions.  If nr_parts is 0 then the whole device is registered, otherwise
- * only the partitions are registered.  To register both the full device *and*
- * the partitions, call mtd_device_register() twice, once with nr_parts == 0
- * and once equal to the number of partitions.
+ * This function aggregates MTD partitions parsing (done by
+ * 'parse_mtd_partitions()') and MTD device and partitions registering. It
+ * basically follows the most common pattern found in many MTD drivers:
+ *
+ * * It first tries to probe partitions on MTD device @mtd using parsers
+ *   specified in @types (if @types is %NULL, then the default list of parsers
+ *   is used, see 'parse_mtd_partitions()' for more information). If none are
+ *   found this functions tries to fallback to information specified in
+ *   @parts/@nr_parts.
+ * * If any partitioning info was found, this function registers the found
+ *   partitions.
+ * * If no partitions were found this function just registers the MTD device
+ *   @mtd and exits.
+ *
+ * Returns zero in case of success and a negative error code in case of failure.
  */
-int mtd_device_register(struct mtd_info *master,
-                       const struct mtd_partition *parts,
-                       int nr_parts)
+int mtd_device_parse_register(struct mtd_info *mtd, const char **types,
+                             struct mtd_part_parser_data *parser_data,
+                             const struct mtd_partition *parts,
+                             int nr_parts)
 {
-       return parts ? add_mtd_partitions(master, parts, nr_parts) :
-               add_mtd_device(master);
+       int err;
+       struct mtd_partition *real_parts;
+
+       err = parse_mtd_partitions(mtd, types, &real_parts, parser_data);
+       if (err <= 0 && nr_parts) {
+               real_parts = kmemdup(parts, sizeof(*parts) * nr_parts,
+                                    GFP_KERNEL);
+               err = nr_parts;
+               if (!parts)
+                       err = -ENOMEM;
+       }
+
+       if (err > 0) {
+               err = add_mtd_partitions(mtd, real_parts, err);
+               kfree(real_parts);
+       } else if (err == 0) {
+               err = add_mtd_device(mtd);
+               if (err == 1)
+                       err = -ENODEV;
+       }
+
+       return err;
 }
-EXPORT_SYMBOL_GPL(mtd_device_register);
+EXPORT_SYMBOL_GPL(mtd_device_parse_register);
 
 /**
  * mtd_device_unregister - unregister an existing MTD device.
index 0ed6126b4c1ffb0cc40c7f161926daf20d14bb0b..961a38408542b70df255a8ba05871a2ffb43a3fa 100644 (file)
@@ -15,6 +15,9 @@ extern int del_mtd_device(struct mtd_info *mtd);
 extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *,
                              int);
 extern int del_mtd_partitions(struct mtd_info *);
+extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
+                               struct mtd_partition **pparts,
+                               struct mtd_part_parser_data *data);
 
 #define mtd_for_each_device(mtd)                       \
        for ((mtd) = __mtd_next_device(0);              \
index 630be3e7da04f2eed1ab628c21004ba077d4522c..c90b7ba362d74e1a05346b5104c227633f0a4e2d 100644 (file)
@@ -479,6 +479,19 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
                               (unsigned long long)cur_offset, (unsigned long long)slave->offset);
                }
        }
+       if (slave->offset == MTDPART_OFS_RETAIN) {
+               slave->offset = cur_offset;
+               if (master->size - slave->offset >= slave->mtd.size) {
+                       slave->mtd.size = master->size - slave->offset
+                                                       - slave->mtd.size;
+               } else {
+                       printk(KERN_ERR "mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n",
+                               part->name, master->size - slave->offset,
+                               slave->mtd.size);
+                       /* register to preserve ordering */
+                       goto out_register;
+               }
+       }
        if (slave->mtd.size == MTDPART_SIZ_FULL)
                slave->mtd.size = master->size - slave->offset;
 
@@ -693,6 +706,8 @@ static struct mtd_part_parser *get_partition_parser(const char *name)
        return ret;
 }
 
+#define put_partition_parser(p) do { module_put((p)->owner); } while (0)
+
 int register_mtd_parser(struct mtd_part_parser *p)
 {
        spin_lock(&part_parser_lock);
@@ -712,19 +727,51 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
 }
 EXPORT_SYMBOL_GPL(deregister_mtd_parser);
 
+/*
+ * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
+ * are changing this array!
+ */
+static const char *default_mtd_part_types[] = {
+       "cmdlinepart",
+       "ofpart",
+       NULL
+};
+
+/**
+ * parse_mtd_partitions - parse MTD partitions
+ * @master: the master partition (describes whole MTD device)
+ * @types: names of partition parsers to try or %NULL
+ * @pparts: array of partitions found is returned here
+ * @data: MTD partition parser-specific data
+ *
+ * This function tries to find partition on MTD device @master. It uses MTD
+ * partition parsers, specified in @types. However, if @types is %NULL, then
+ * the default list of parsers is used. The default list contains only the
+ * "cmdlinepart" and "ofpart" parsers ATM.
+ *
+ * This function may return:
+ * o a negative error code in case of failure
+ * o zero if no partitions were found
+ * o a positive number of found partitions, in which case on exit @pparts will
+ *   point to an array containing this number of &struct mtd_info objects.
+ */
 int parse_mtd_partitions(struct mtd_info *master, const char **types,
-                        struct mtd_partition **pparts, unsigned long origin)
+                        struct mtd_partition **pparts,
+                        struct mtd_part_parser_data *data)
 {
        struct mtd_part_parser *parser;
        int ret = 0;
 
+       if (!types)
+               types = default_mtd_part_types;
+
        for ( ; ret <= 0 && *types; types++) {
                parser = get_partition_parser(*types);
                if (!parser && !request_module("%s", *types))
                                parser = get_partition_parser(*types);
                if (!parser)
                        continue;
-               ret = (*parser->parse_fn)(master, pparts, origin);
+               ret = (*parser->parse_fn)(master, pparts, data);
                if (ret > 0) {
                        printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
                               ret, parser->name, master->name);
@@ -733,7 +780,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
        }
        return ret;
 }
-EXPORT_SYMBOL_GPL(parse_mtd_partitions);
 
 int mtd_is_partition(struct mtd_info *mtd)
 {
index 16b02a1fc100ce542bfdaad9bb6fdbf7f8b433fe..80fe5dcac111ca44f92c538ac61320c269a4ad20 100644 (file)
@@ -26,12 +26,12 @@ static int get_sb_mtd_compare(struct super_block *sb, void *_mtd)
        struct mtd_info *mtd = _mtd;
 
        if (sb->s_mtd == mtd) {
-               DEBUG(2, "MTDSB: Match on device %d (\"%s\")\n",
+               pr_debug("MTDSB: Match on device %d (\"%s\")\n",
                      mtd->index, mtd->name);
                return 1;
        }
 
-       DEBUG(2, "MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
+       pr_debug("MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
              sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name);
        return 0;
 }
@@ -70,7 +70,7 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
                goto already_mounted;
 
        /* fresh new superblock */
-       DEBUG(1, "MTDSB: New superblock for device %d (\"%s\")\n",
+       pr_debug("MTDSB: New superblock for device %d (\"%s\")\n",
              mtd->index, mtd->name);
 
        sb->s_flags = flags;
@@ -87,7 +87,7 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
 
        /* new mountpoint for an already mounted superblock */
 already_mounted:
-       DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
+       pr_debug("MTDSB: Device %d (\"%s\") is already mounted\n",
              mtd->index, mtd->name);
        put_mtd_device(mtd);
        return dget(sb->s_root);
@@ -108,7 +108,7 @@ static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags,
 
        mtd = get_mtd_device(NULL, mtdnr);
        if (IS_ERR(mtd)) {
-               DEBUG(0, "MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
+               pr_debug("MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
                return ERR_CAST(mtd);
        }
 
@@ -131,7 +131,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
        if (!dev_name)
                return ERR_PTR(-EINVAL);
 
-       DEBUG(2, "MTDSB: dev_name \"%s\"\n", dev_name);
+       pr_debug("MTDSB: dev_name \"%s\"\n", dev_name);
 
        /* the preferred way of mounting in future; especially when
         * CONFIG_BLOCK=n - we specify the underlying MTD device by number or
@@ -142,7 +142,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
                        struct mtd_info *mtd;
 
                        /* mount by MTD device name */
-                       DEBUG(1, "MTDSB: mtd:%%s, name \"%s\"\n",
+                       pr_debug("MTDSB: mtd:%%s, name \"%s\"\n",
                              dev_name + 4);
 
                        mtd = get_mtd_device_nm(dev_name + 4);
@@ -163,7 +163,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
                        mtdnr = simple_strtoul(dev_name + 3, &endptr, 0);
                        if (!*endptr) {
                                /* It was a valid number */
-                               DEBUG(1, "MTDSB: mtd%%d, mtdnr %d\n",
+                               pr_debug("MTDSB: mtd%%d, mtdnr %d\n",
                                      mtdnr);
                                return mount_mtd_nr(fs_type, flags,
                                                     dev_name, data,
@@ -179,10 +179,10 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
        bdev = lookup_bdev(dev_name);
        if (IS_ERR(bdev)) {
                ret = PTR_ERR(bdev);
-               DEBUG(1, "MTDSB: lookup_bdev() returned %d\n", ret);
+               pr_debug("MTDSB: lookup_bdev() returned %d\n", ret);
                return ERR_PTR(ret);
        }
-       DEBUG(1, "MTDSB: lookup_bdev() returned 0\n");
+       pr_debug("MTDSB: lookup_bdev() returned 0\n");
 
        ret = -EINVAL;
 
index fd7885327611d75d68a25e788fa7a44950109513..9961063b90a262b7080be6a925c1b62cb3146b0c 100644 (file)
@@ -86,7 +86,7 @@ struct swap_eb {
        unsigned int flags;
        unsigned int active_count;
        unsigned int erase_count;
-       unsigned int pad;               /* speeds up pointer decremtnt */
+       unsigned int pad;               /* speeds up pointer decrement */
 };
 
 #define MTDSWAP_ECNT_MIN(rbroot) (rb_entry(rb_first(rbroot), struct swap_eb, \
@@ -1374,11 +1374,10 @@ static int mtdswap_init(struct mtdswap_dev *d, unsigned int eblocks,
                goto revmap_fail;
 
        eblk_bytes = sizeof(struct swap_eb)*d->eblks;
-       d->eb_data = vmalloc(eblk_bytes);
+       d->eb_data = vzalloc(eblk_bytes);
        if (!d->eb_data)
                goto eb_data_fail;
 
-       memset(d->eb_data, 0, eblk_bytes);
        for (i = 0; i < pages; i++)
                d->page_data[i] = BLOCK_UNDEF;
 
index 4c3425235adc573edbbd2a77ee6efc661c81f75b..7ec5b494583fe4baade52e7c43b7e354e3cba6d2 100644 (file)
@@ -83,13 +83,6 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR
           scratch register here to enable this feature. On Intel Moorestown
           boards, the scratch register is at 0xFF108018.
 
-config MTD_NAND_EDB7312
-       tristate "Support for Cirrus Logic EBD7312 evaluation board"
-       depends on ARCH_EDB7312
-       help
-         This enables the driver for the Cirrus Logic EBD7312 evaluation
-         board to access the onboard NAND Flash.
-
 config MTD_NAND_H1900
        tristate "iPAQ H1900 flash"
        depends on ARCH_PXA
@@ -116,10 +109,11 @@ config MTD_NAND_AMS_DELTA
          Support for NAND flash on Amstrad E3 (Delta).
 
 config MTD_NAND_OMAP2
-       tristate "NAND Flash device on OMAP2 and OMAP3"
-       depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3)
+       tristate "NAND Flash device on OMAP2, OMAP3 and OMAP4"
+       depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4)
        help
-          Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
+          Support for NAND flash on Texas Instruments OMAP2, OMAP3 and OMAP4
+         platforms.
 
 config MTD_NAND_IDS
        tristate
index 5745d831168e4e6f581deb1e12bb3a5b77f456fd..c9334e9af9125ef9695095c104774962ab67e5c8 100644 (file)
@@ -13,7 +13,6 @@ obj-$(CONFIG_MTD_NAND_SPIA)           += spia.o
 obj-$(CONFIG_MTD_NAND_AMS_DELTA)       += ams-delta.o
 obj-$(CONFIG_MTD_NAND_AUTCPU12)                += autcpu12.o
 obj-$(CONFIG_MTD_NAND_DENALI)          += denali.o
-obj-$(CONFIG_MTD_NAND_EDB7312)         += edb7312.o
 obj-$(CONFIG_MTD_NAND_AU1550)          += au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)           += bf5xx_nand.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)  += ppchameleonevb.o
index 78017eb9318ebc7dbbf4c8269b83b3d0ca924e34..9e6b498c9bebb07191d8146f447a89c56d2ca11b 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/sizes.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/board-ams-delta.h>
 
 /*
index 55da20ccc7a8996f0d80be785b91452e35dd8225..23e5d77c39fcaf998f81125e51d22ccf1ce9b2d3 100644 (file)
@@ -161,37 +161,6 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
                 !!host->board->rdy_pin_active_low;
 }
 
-/*
- * Minimal-overhead PIO for data access.
- */
-static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_readsb(nand_chip->IO_ADDR_R, buf, len);
-}
-
-static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2);
-}
-
-static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_writesb(nand_chip->IO_ADDR_W, buf, len);
-}
-
-static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2);
-}
-
 static void dma_complete_func(void *completion)
 {
        complete(completion);
@@ -266,33 +235,27 @@ err_buf:
 static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
-       struct atmel_nand_host *host = chip->priv;
 
        if (use_dma && len > mtd->oobsize)
                /* only use DMA for bigger than oob size: better performances */
                if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
                        return;
 
-       if (host->board->bus_width_16)
-               atmel_read_buf16(mtd, buf, len);
-       else
-               atmel_read_buf8(mtd, buf, len);
+       /* if no DMA operation possible, use PIO */
+       memcpy_fromio(buf, chip->IO_ADDR_R, len);
 }
 
 static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
-       struct atmel_nand_host *host = chip->priv;
 
        if (use_dma && len > mtd->oobsize)
                /* only use DMA for bigger than oob size: better performances */
                if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
                        return;
 
-       if (host->board->bus_width_16)
-               atmel_write_buf16(mtd, buf, len);
-       else
-               atmel_write_buf8(mtd, buf, len);
+       /* if no DMA operation possible, use PIO */
+       memcpy_toio(chip->IO_ADDR_W, buf, len);
 }
 
 /*
@@ -481,10 +444,6 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
        }
 }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
-
 /*
  * Probe for the NAND device.
  */
@@ -496,8 +455,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        struct resource *regs;
        struct resource *mem;
        int res;
-       struct mtd_partition *partitions = NULL;
-       int num_partitions = 0;
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mem) {
@@ -583,7 +540,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 
        if (on_flash_bbt) {
                printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
-               nand_chip->options |= NAND_USE_FLASH_BBT;
+               nand_chip->bbt_options |= NAND_BBT_USE_FLASH;
        }
 
        if (!cpu_has_dma())
@@ -594,7 +551,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 
                dma_cap_zero(mask);
                dma_cap_set(DMA_MEMCPY, mask);
-               host->dma_chan = dma_request_channel(mask, 0, NULL);
+               host->dma_chan = dma_request_channel(mask, NULL, NULL);
                if (!host->dma_chan) {
                        dev_err(host->dev, "Failed to request DMA channel\n");
                        use_dma = 0;
@@ -655,27 +612,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                goto err_scan_tail;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        mtd->name = "atmel_nand";
-       num_partitions = parse_mtd_partitions(mtd, part_probes,
-                                             &partitions, 0);
-#endif
-       if (num_partitions <= 0 && host->board->partition_info)
-               partitions = host->board->partition_info(mtd->size,
-                                                        &num_partitions);
-
-       if ((!partitions) || (num_partitions == 0)) {
-               printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n");
-               res = -ENXIO;
-               goto err_no_partitions;
-       }
-
-       res = mtd_device_register(mtd, partitions, num_partitions);
+       res = mtd_device_parse_register(mtd, NULL, 0,
+                       host->board->parts, host->board->num_parts);
        if (!res)
                return res;
 
-err_no_partitions:
-       nand_release(mtd);
 err_scan_tail:
 err_scan_ident:
 err_no_card:
index e7767eef4505665279142ba57e13a43e6ac4b35b..60d58d3f1fcc518b1175eeba6c293b573ead9dbe 100644 (file)
@@ -48,7 +48,7 @@ static const struct mtd_partition partition_info[] = {
  * au_read_byte -  read one byte from the chip
  * @mtd:       MTD device structure
  *
- *  read function for 8bit buswith
+ * read function for 8bit buswidth
  */
 static u_char au_read_byte(struct mtd_info *mtd)
 {
@@ -63,7 +63,7 @@ static u_char au_read_byte(struct mtd_info *mtd)
  * @mtd:       MTD device structure
  * @byte:      pointer to data byte to write
  *
- *  write function for 8it buswith
+ * write function for 8it buswidth
  */
 static void au_write_byte(struct mtd_info *mtd, u_char byte)
 {
@@ -73,11 +73,10 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
 }
 
 /**
- * au_read_byte16 -  read one byte endianess aware from the chip
+ * au_read_byte16 -  read one byte endianness aware from the chip
  * @mtd:       MTD device structure
  *
- *  read function for 16bit buswith with
- * endianess conversion
+ * read function for 16bit buswidth with endianness conversion
  */
 static u_char au_read_byte16(struct mtd_info *mtd)
 {
@@ -88,12 +87,11 @@ static u_char au_read_byte16(struct mtd_info *mtd)
 }
 
 /**
- * au_write_byte16 -  write one byte endianess aware to the chip
+ * au_write_byte16 -  write one byte endianness aware to the chip
  * @mtd:       MTD device structure
  * @byte:      pointer to data byte to write
  *
- *  write function for 16bit buswith with
- * endianess conversion
+ * write function for 16bit buswidth with endianness conversion
  */
 static void au_write_byte16(struct mtd_info *mtd, u_char byte)
 {
@@ -106,8 +104,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
  * au_read_word -  read one word from the chip
  * @mtd:       MTD device structure
  *
- *  read function for 16bit buswith without
- * endianess conversion
+ * read function for 16bit buswidth without endianness conversion
  */
 static u16 au_read_word(struct mtd_info *mtd)
 {
@@ -123,7 +120,7 @@ static u16 au_read_word(struct mtd_info *mtd)
  * @buf:       data buffer
  * @len:       number of bytes to write
  *
- *  write function for 8bit buswith
+ * write function for 8bit buswidth
  */
 static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
@@ -142,7 +139,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
  * @buf:       buffer to store date
  * @len:       number of bytes to read
  *
- *  read function for 8bit buswith
+ * read function for 8bit buswidth
  */
 static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
@@ -161,7 +158,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
  * @buf:       buffer containing the data to compare
  * @len:       number of bytes to compare
  *
- *  verify function for 8bit buswith
+ * verify function for 8bit buswidth
  */
 static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
@@ -183,7 +180,7 @@ static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
  * @buf:       data buffer
  * @len:       number of bytes to write
  *
- *  write function for 16bit buswith
+ * write function for 16bit buswidth
  */
 static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
 {
@@ -205,7 +202,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
  * @buf:       buffer to store date
  * @len:       number of bytes to read
  *
- *  read function for 16bit buswith
+ * read function for 16bit buswidth
  */
 static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
 {
@@ -226,7 +223,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
  * @buf:       buffer containing the data to compare
  * @len:       number of bytes to compare
  *
- *  verify function for 16bit buswith
+ * verify function for 16bit buswidth
  */
 static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
 {
index eddc9a2249859efe157dac13f8042da3afaf26e6..2e42ec2e8ff48a285b939e7510ea91d22dd6035f 100644 (file)
@@ -172,9 +172,9 @@ static int __init autcpu12_init(void)
 
        /* Enable the following for a flash based bad block table */
        /*
-          this->options = NAND_USE_FLASH_BBT;
+          this->bbt_options = NAND_BBT_USE_FLASH;
         */
-       this->options = NAND_USE_FLASH_BBT;
+       this->bbt_options = NAND_BBT_USE_FLASH;
 
        /* Scan to find existence of the device */
        if (nand_scan(autcpu12_mtd, 1)) {
index 8c569e454dc5b52248fa98017e0d1071f6700f64..46b58d67284726fe2cee86852f9fe4640679a8a6 100644 (file)
@@ -52,8 +52,6 @@
 static const __devinitconst char gBanner[] = KERN_INFO \
        "BCM UMI MTD NAND Driver: 1.00\n";
 
-const char *part_probes[] = { "cmdlinepart", NULL };
-
 #if NAND_ECC_BCH
 static uint8_t scan_ff_pattern[] = { 0xff };
 
@@ -376,16 +374,18 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       if (!r)
-               return -ENXIO;
+       if (!r) {
+               err = -ENXIO;
+               goto out_free;
+       }
 
        /* map physical address */
        bcm_umi_io_base = ioremap(r->start, resource_size(r));
 
        if (!bcm_umi_io_base) {
                printk(KERN_ERR "ioremap to access BCM UMI NAND chip failed\n");
-               kfree(board_mtd);
-               return -EIO;
+               err = -EIO;
+               goto out_free;
        }
 
        /* Get pointer to private data */
@@ -401,9 +401,8 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
        /* Initialize the NAND hardware.  */
        if (bcm_umi_nand_inithw() < 0) {
                printk(KERN_ERR "BCM UMI NAND chip could not be initialized\n");
-               iounmap(bcm_umi_io_base);
-               kfree(board_mtd);
-               return -EIO;
+               err = -EIO;
+               goto out_unmap;
        }
 
        /* Set address of NAND IO lines */
@@ -436,7 +435,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
 #if USE_DMA
        err = nand_dma_init();
        if (err != 0)
-               return err;
+               goto out_unmap;
 #endif
 
        /* Figure out the size of the device that we have.
@@ -447,9 +446,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
        err = nand_scan_ident(board_mtd, 1, NULL);
        if (err) {
                printk(KERN_ERR "nand_scan failed: %d\n", err);
-               iounmap(bcm_umi_io_base);
-               kfree(board_mtd);
-               return err;
+               goto out_unmap;
        }
 
        /* Now that we know the nand size, we can setup the ECC layout */
@@ -468,13 +465,14 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
                {
                        printk(KERN_ERR "NAND - Unrecognized pagesize: %d\n",
                                         board_mtd->writesize);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out_unmap;
                }
        }
 
 #if NAND_ECC_BCH
        if (board_mtd->writesize > 512) {
-               if (this->options & NAND_USE_FLASH_BBT)
+               if (this->bbt_options & NAND_BBT_USE_FLASH)
                        largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
                this->badblock_pattern = &largepage_bbt;
        }
@@ -485,33 +483,20 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
        err = nand_scan_tail(board_mtd);
        if (err) {
                printk(KERN_ERR "nand_scan failed: %d\n", err);
-               iounmap(bcm_umi_io_base);
-               kfree(board_mtd);
-               return err;
+               goto out_unmap;
        }
 
        /* Register the partitions */
-       {
-               int nr_partitions;
-               struct mtd_partition *partition_info;
-
-               board_mtd->name = "bcm_umi-nand";
-               nr_partitions =
-                   parse_mtd_partitions(board_mtd, part_probes,
-                                        &partition_info, 0);
-
-               if (nr_partitions <= 0) {
-                       printk(KERN_ERR "BCM UMI NAND: Too few partitions - %d\n",
-                              nr_partitions);
-                       iounmap(bcm_umi_io_base);
-                       kfree(board_mtd);
-                       return -EIO;
-               }
-               mtd_device_register(board_mtd, partition_info, nr_partitions);
-       }
+       board_mtd->name = "bcm_umi-nand";
+       mtd_device_parse_register(board_mtd, NULL, 0, NULL, 0);
 
        /* Return happy */
        return 0;
+out_unmap:
+       iounmap(bcm_umi_io_base);
+out_free:
+       kfree(board_mtd);
+       return err;
 }
 
 static int bcm_umi_nand_remove(struct platform_device *pdev)
index 87ebb4e5b0c3b97949050ec10ff2a62b081c9bac..11a56df89eab3831f747dfd322bfcacd62e526bc 100644 (file)
@@ -57,7 +57,6 @@
 
 struct cafe_priv {
        struct nand_chip nand;
-       struct mtd_partition *parts;
        struct pci_dev *pdev;
        void __iomem *mmio;
        struct rs_control *rs;
@@ -371,7 +370,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
        return 1;
 }
 /**
- * cafe_nand_read_page_syndrome - {REPLACABLE] hardware ecc syndrom based page read
+ * cafe_nand_read_page_syndrome - [REPLACEABLE] hardware ecc syndrome based page read
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
@@ -630,8 +629,6 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
        struct cafe_priv *cafe;
        uint32_t ctrl;
        int err = 0;
-       struct mtd_partition *parts;
-       int nr_parts;
 
        /* Very old versions shared the same PCI ident for all three
           functions on the chip. Verify the class too... */
@@ -686,7 +683,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
        cafe->nand.chip_delay = 0;
 
        /* Enable the following for a flash based bad block table */
-       cafe->nand.options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR | NAND_OWN_BUFFERS;
+       cafe->nand.bbt_options = NAND_BBT_USE_FLASH;
+       cafe->nand.options = NAND_NO_AUTOINCR | NAND_OWN_BUFFERS;
 
        if (skipbbt) {
                cafe->nand.options |= NAND_SKIP_BBTSCAN;
@@ -799,18 +797,9 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, mtd);
 
-       /* We register the whole device first, separate from the partitions */
-       mtd_device_register(mtd, NULL, 0);
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        mtd->name = "cafe_nand";
-#endif
-       nr_parts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
-       if (nr_parts > 0) {
-               cafe->parts = parts;
-               dev_info(&cafe->pdev->dev, "%d partitions found\n", nr_parts);
-               mtd_device_register(mtd, parts, nr_parts);
-       }
+       mtd_device_parse_register(mtd, part_probes, 0, NULL, 0);
+
        goto out;
 
  out_irq:
index 6fc043a30d1e20809dccb6d3555ee1603823415e..31308e694bd3055d4d0d83cedd4b4f5b29920144 100644 (file)
@@ -50,8 +50,6 @@ static struct mtd_partition partition_info[] = {
 };
 #define NUM_PARTITIONS (ARRAY_SIZE(partition_info))
 
-const char *part_probes[] = { "cmdlinepart", NULL };
-
 static u_char cmx270_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
@@ -151,9 +149,6 @@ static int cmx270_device_ready(struct mtd_info *mtd)
 static int __init cmx270_init(void)
 {
        struct nand_chip *this;
-       const char *part_type;
-       struct mtd_partition *mtd_parts;
-       int mtd_parts_nb = 0;
        int ret;
 
        if (!(machine_is_armcore() && cpu_is_pxa27x()))
@@ -222,23 +217,9 @@ static int __init cmx270_init(void)
                goto err_scan;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       mtd_parts_nb = parse_mtd_partitions(cmx270_nand_mtd, part_probes,
-                                           &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-#endif
-       if (!mtd_parts_nb) {
-               mtd_parts = partition_info;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
-
        /* Register the partitions */
-       pr_notice("Using %s partition definition\n", part_type);
-       ret = mtd_device_register(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
+       ret = mtd_device_parse_register(cmx270_nand_mtd, NULL, 0,
+                                       partition_info, NUM_PARTITIONS);
        if (ret)
                goto err_scan;
 
index f59ad1f2d5dbe7e23fa10a7762332ff2ee44e3cb..414afa7935637522709f6273f2df9930a1170a6a 100644 (file)
@@ -239,7 +239,8 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        this->ecc.correct  = nand_correct_data;
 
        /* Enable the following for a flash based bad block table */
-       this->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
+       this->bbt_options = NAND_BBT_USE_FLASH;
+       this->options = NAND_NO_AUTOINCR;
 
        /* Scan to find existence of the device */
        if (nand_scan(new_mtd, 1)) {
@@ -277,15 +278,11 @@ static int is_geode(void)
        return 0;
 }
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 static int __init cs553x_init(void)
 {
        int err = -ENXIO;
        int i;
        uint64_t val;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = NULL;
 
        /* If the CPU isn't a Geode GX or LX, abort */
        if (!is_geode())
@@ -315,13 +312,9 @@ static int __init cs553x_init(void)
           do mtdconcat etc. if we want to. */
        for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
                if (cs553x_mtd[i]) {
-
                        /* If any devices registered, return success. Else the last error. */
-                       mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0);
-                       if (mtd_parts_nb > 0)
-                               printk(KERN_NOTICE "Using command line partition definition\n");
-                       mtd_device_register(cs553x_mtd[i], mtd_parts,
-                                           mtd_parts_nb);
+                       mtd_device_parse_register(cs553x_mtd[i], NULL, 0,
+                                                 NULL, 0);
                        err = 0;
                }
        }
index 1f34951ae1a7426f0344a7327c56a5b1105c7bc8..c153e1f77f90d0e58dc6d892f2395a71e500b7ef 100644 (file)
@@ -57,7 +57,6 @@ struct davinci_nand_info {
 
        struct device           *dev;
        struct clk              *clk;
-       bool                    partitioned;
 
        bool                    is_readmode;
 
@@ -530,8 +529,6 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
        int                             ret;
        uint32_t                        val;
        nand_ecc_modes_t                ecc_mode;
-       struct mtd_partition            *mtd_parts = NULL;
-       int                             mtd_parts_nb = 0;
 
        /* insist on board-specific configuration */
        if (!pdata)
@@ -581,7 +578,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
        info->chip.chip_delay   = 0;
        info->chip.select_chip  = nand_davinci_select_chip;
 
-       /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
+       /* options such as NAND_BBT_USE_FLASH */
+       info->chip.bbt_options  = pdata->bbt_options;
+       /* options such as 16-bit widths */
        info->chip.options      = pdata->options;
        info->chip.bbt_td       = pdata->bbt_td;
        info->chip.bbt_md       = pdata->bbt_md;
@@ -751,33 +750,8 @@ syndrome_done:
        if (ret < 0)
                goto err_scan;
 
-       if (mtd_has_cmdlinepart()) {
-               static const char *probes[] __initconst = {
-                       "cmdlinepart", NULL
-               };
-
-               mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
-                                                   &mtd_parts, 0);
-       }
-
-       if (mtd_parts_nb <= 0) {
-               mtd_parts = pdata->parts;
-               mtd_parts_nb = pdata->nr_parts;
-       }
-
-       /* Register any partitions */
-       if (mtd_parts_nb > 0) {
-               ret = mtd_device_register(&info->mtd, mtd_parts,
-                                         mtd_parts_nb);
-               if (ret == 0)
-                       info->partitioned = true;
-       }
-
-       /* If there's no partition info, just package the whole chip
-        * as a single MTD device.
-        */
-       if (!info->partitioned)
-               ret = mtd_device_register(&info->mtd, NULL, 0) ? -ENODEV : 0;
+       ret = mtd_device_parse_register(&info->mtd, NULL, 0,
+                       pdata->parts, pdata->nr_parts);
 
        if (ret < 0)
                goto err_scan;
@@ -816,9 +790,6 @@ err_nomem:
 static int __exit nand_davinci_remove(struct platform_device *pdev)
 {
        struct davinci_nand_info *info = platform_get_drvdata(pdev);
-       int status;
-
-       status = mtd_device_unregister(&info->mtd);
 
        spin_lock_irq(&davinci_nand_lock);
        if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME)
index d5276218945fe296cb1c1b8c29cb8f21929dfb42..3984d488f9abbf5a3d6ed77fd49e2c4b7dc79381 100644 (file)
@@ -1346,6 +1346,7 @@ static void denali_hw_init(struct denali_nand_info *denali)
         * */
        denali->bbtskipbytes = ioread32(denali->flash_reg +
                                                SPARE_AREA_SKIP_BYTES);
+       detect_max_banks(denali);
        denali_nand_reset(denali);
        iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
        iowrite32(CHIP_EN_DONT_CARE__FLAG,
@@ -1356,7 +1357,6 @@ static void denali_hw_init(struct denali_nand_info *denali)
        /* Should set value for these registers when init */
        iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES);
        iowrite32(1, denali->flash_reg + ECC_ENABLE);
-       detect_max_banks(denali);
        denali_nand_timing_set(denali);
        denali_irq_init(denali);
 }
@@ -1577,7 +1577,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        denali->nand.bbt_md = &bbt_mirror_descr;
 
        /* skip the scan for now until we have OOB read and write support */
-       denali->nand.options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN;
+       denali->nand.bbt_options |= NAND_BBT_USE_FLASH;
+       denali->nand.options |= NAND_SKIP_BBTSCAN;
        denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
 
        /* Denali Controller only support 15bit and 8bit ECC in MRST,
@@ -1676,7 +1677,6 @@ static void denali_pci_remove(struct pci_dev *dev)
        struct denali_nand_info *denali = pci_get_drvdata(dev);
 
        nand_release(&denali->mtd);
-       mtd_device_unregister(&denali->mtd);
 
        denali_irq_cleanup(dev->irq, denali);
 
index 7837728d02ff4c15987d6275d593d3464b6cf073..de93a989aa54866b92c29f09388e1cd57a78bfa4 100644 (file)
@@ -132,7 +132,7 @@ static struct rs_control *rs_decoder;
 
 /*
  * The HW decoder in the DoC ASIC's provides us a error syndrome,
- * which we must convert to a standard syndrom usable by the generic
+ * which we must convert to a standard syndrome usable by the generic
  * Reed-Solomon library code.
  *
  * Fabrice Bellard figured this out in the old docecc code. I added
@@ -153,7 +153,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
        ds[3] = ((ecc[3] & 0xc0) >> 6) | ((ecc[0] & 0xff) << 2);
        parity = ecc[1];
 
-       /* Initialize the syndrom buffer */
+       /* Initialize the syndrome buffer */
        for (i = 0; i < NROOTS; i++)
                s[i] = ds[0];
        /*
@@ -1652,7 +1652,7 @@ static int __init doc_probe(unsigned long physadr)
        nand->ecc.mode          = NAND_ECC_HW_SYNDROME;
        nand->ecc.size          = 512;
        nand->ecc.bytes         = 6;
-       nand->options           = NAND_USE_FLASH_BBT;
+       nand->bbt_options       = NAND_BBT_USE_FLASH;
 
        doc->physadr            = physadr;
        doc->virtadr            = virtadr;
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
deleted file mode 100644 (file)
index 8400d0f..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- *  drivers/mtd/nand/edb7312.c
- *
- *  Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
- *
- *  Derived from drivers/mtd/nand/autcpu12.c
- *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   CLEP7312 board which utilizes the Toshiba TC58V64AFT part. This is
- *   a 64Mibit (8MiB x 8 bits) NAND flash device.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <mach/hardware.h>     /* for CLPS7111_VIRT_BASE */
-#include <asm/sizes.h>
-#include <asm/hardware/clps7111.h>
-
-/*
- * MTD structure for EDB7312 board
- */
-static struct mtd_info *ep7312_mtd = NULL;
-
-/*
- * Values specific to the EDB7312 board (used with EP7312 processor)
- */
-#define EP7312_FIO_PBASE 0x10000000    /* Phys address of flash */
-#define EP7312_PXDR    0x0001  /*
-                                * IO offset to Port B data register
-                                * where the CLE, ALE and NCE pins
-                                * are wired to.
-                                */
-#define EP7312_PXDDR   0x0041  /*
-                                * IO offset to Port B data direction
-                                * register so we can control the IO
-                                * lines.
-                                */
-
-/*
- * Module stuff
- */
-
-static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE;
-static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
-static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
-
-/*
- * Define static partitions for flash device
- */
-static struct mtd_partition partition_info[] = {
-       {.name = "EP7312 Nand Flash",
-        .offset = 0,
-        .size = 8 * 1024 * 1024}
-};
-
-#define NUM_PARTITIONS 1
-
-/*
- *     hardware specific access to control-lines
- *
- *     NAND_NCE: bit 0 -> bit 6 (bit 7 = 1)
- *     NAND_CLE: bit 1 -> bit 4
- *     NAND_ALE: bit 2 -> bit 5
- */
-static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
-       struct nand_chip *chip = mtd->priv;
-
-       if (ctrl & NAND_CTRL_CHANGE) {
-               unsigned char bits = 0x80;
-
-               bits |= (ctrl & (NAND_CLE | NAND_ALE)) << 3;
-               bits |= (ctrl & NAND_NCE) ? 0x00 : 0x40;
-
-               clps_writeb((clps_readb(ep7312_pxdr)  & 0xF0) | bits,
-                           ep7312_pxdr);
-       }
-       if (cmd != NAND_CMD_NONE)
-               writeb(cmd, chip->IO_ADDR_W);
-}
-
-/*
- *     read device ready pin
- */
-static int ep7312_device_ready(struct mtd_info *mtd)
-{
-       return 1;
-}
-
-const char *part_probes[] = { "cmdlinepart", NULL };
-
-/*
- * Main initialization routine
- */
-static int __init ep7312_init(void)
-{
-       struct nand_chip *this;
-       const char *part_type = 0;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = 0;
-       void __iomem *ep7312_fio_base;
-
-       /* Allocate memory for MTD device structure and private data */
-       ep7312_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-       if (!ep7312_mtd) {
-               printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
-               return -ENOMEM;
-       }
-
-       /* map physical address */
-       ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
-       if (!ep7312_fio_base) {
-               printk("ioremap EDB7312 NAND flash failed\n");
-               kfree(ep7312_mtd);
-               return -EIO;
-       }
-
-       /* Get pointer to private data */
-       this = (struct nand_chip *)(&ep7312_mtd[1]);
-
-       /* Initialize structures */
-       memset(ep7312_mtd, 0, sizeof(struct mtd_info));
-       memset(this, 0, sizeof(struct nand_chip));
-
-       /* Link the private data with the MTD structure */
-       ep7312_mtd->priv = this;
-       ep7312_mtd->owner = THIS_MODULE;
-
-       /*
-        * Set GPIO Port B control register so that the pins are configured
-        * to be outputs for controlling the NAND flash.
-        */
-       clps_writeb(0xf0, ep7312_pxddr);
-
-       /* insert callbacks */
-       this->IO_ADDR_R = ep7312_fio_base;
-       this->IO_ADDR_W = ep7312_fio_base;
-       this->cmd_ctrl = ep7312_hwcontrol;
-       this->dev_ready = ep7312_device_ready;
-       /* 15 us command delay time */
-       this->chip_delay = 15;
-
-       /* Scan to find existence of the device */
-       if (nand_scan(ep7312_mtd, 1)) {
-               iounmap((void *)ep7312_fio_base);
-               kfree(ep7312_mtd);
-               return -ENXIO;
-       }
-       ep7312_mtd->name = "edb7312-nand";
-       mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-       if (mtd_parts_nb == 0) {
-               mtd_parts = partition_info;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
-
-       /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(ep7312_mtd, mtd_parts, mtd_parts_nb);
-
-       /* Return happy */
-       return 0;
-}
-
-module_init(ep7312_init);
-
-/*
- * Clean up routine
- */
-static void __exit ep7312_cleanup(void)
-{
-       struct nand_chip *this = (struct nand_chip *)&ep7312_mtd[1];
-
-       /* Release resources, unregister device */
-       nand_release(ap7312_mtd);
-
-       /* Release io resource */
-       iounmap(this->IO_ADDR_R);
-
-       /* Free the MTD device structure */
-       kfree(ep7312_mtd);
-}
-
-module_exit(ep7312_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
-MODULE_DESCRIPTION("MTD map driver for Cogent EDB7312 board");
index 33d8aad8bba5a47b2c0135acf4132454bab12eea..eedd8ee2c9ac8b83059edf9cf5856a12e4a53e48 100644 (file)
@@ -75,7 +75,6 @@ struct fsl_elbc_fcm_ctrl {
        unsigned int use_mdr;    /* Non zero if the MDR is to be set      */
        unsigned int oob;        /* Non zero if operating on OOB data     */
        unsigned int counter;    /* counter for the initializations       */
-       char *oob_poi;           /* Place to write ECC after read back    */
 };
 
 /* These map to the positions used by the FCM hardware ECC generator */
@@ -244,6 +243,25 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
                return -EIO;
        }
 
+       if (chip->ecc.mode != NAND_ECC_HW)
+               return 0;
+
+       if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
+               uint32_t lteccr = in_be32(&lbc->lteccr);
+               /*
+                * if command was a full page read and the ELBC
+                * has the LTECCR register, then bits 12-15 (ppc order) of
+                * LTECCR indicates which 512 byte sub-pages had fixed errors.
+                * bits 28-31 are uncorrectable errors, marked elsewhere.
+                * for small page nand only 1 bit is used.
+                * if the ELBC doesn't have the lteccr register it reads 0
+                */
+               if (lteccr & 0x000F000F)
+                       out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
+               if (lteccr & 0x000F0000)
+                       mtd->ecc_stats.corrected++;
+       }
+
        return 0;
 }
 
@@ -435,7 +453,6 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
        case NAND_CMD_PAGEPROG: {
-               int full_page;
                dev_vdbg(priv->dev,
                         "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG "
                         "writing %d bytes.\n", elbc_fcm_ctrl->index);
@@ -445,34 +462,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                 * write so the HW generates the ECC.
                 */
                if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
-                   elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) {
+                   elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
                        out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
-                       full_page = 0;
-               } else {
+               else
                        out_be32(&lbc->fbcr, 0);
-                       full_page = 1;
-               }
 
                fsl_elbc_run_command(mtd);
-
-               /* Read back the page in order to fill in the ECC for the
-                * caller.  Is this really needed?
-                */
-               if (full_page && elbc_fcm_ctrl->oob_poi) {
-                       out_be32(&lbc->fbcr, 3);
-                       set_addr(mtd, 6, page_addr, 1);
-
-                       elbc_fcm_ctrl->read_bytes = mtd->writesize + 9;
-
-                       fsl_elbc_do_read(chip, 1);
-                       fsl_elbc_run_command(mtd);
-
-                       memcpy_fromio(elbc_fcm_ctrl->oob_poi + 6,
-                               &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], 3);
-                       elbc_fcm_ctrl->index += 3;
-               }
-
-               elbc_fcm_ctrl->oob_poi = NULL;
                return;
        }
 
@@ -752,13 +747,8 @@ static void fsl_elbc_write_page(struct mtd_info *mtd,
                                 struct nand_chip *chip,
                                 const uint8_t *buf)
 {
-       struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
-
        fsl_elbc_write_buf(mtd, buf, mtd->writesize);
        fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-       elbc_fcm_ctrl->oob_poi = chip->oob_poi;
 }
 
 static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
@@ -791,8 +781,8 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
        chip->bbt_md = &bbt_mirror_descr;
 
        /* set up nand options */
-       chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
-                       NAND_USE_FLASH_BBT;
+       chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
 
        chip->controller = &elbc_fcm_ctrl->controller;
        chip->priv = priv;
@@ -829,7 +819,6 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
 
        elbc_fcm_ctrl->chips[priv->bank] = NULL;
        kfree(priv);
-       kfree(elbc_fcm_ctrl);
        return 0;
 }
 
@@ -842,13 +831,14 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
        struct resource res;
        struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl;
        static const char *part_probe_types[]
-               = { "cmdlinepart", "RedBoot", NULL };
-       struct mtd_partition *parts;
+               = { "cmdlinepart", "RedBoot", "ofpart", NULL };
        int ret;
        int bank;
        struct device *dev;
        struct device_node *node = pdev->dev.of_node;
+       struct mtd_part_parser_data ppdata;
 
+       ppdata.of_node = pdev->dev.of_node;
        if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
                return -ENODEV;
        lbc = fsl_lbc_ctrl_dev->regs;
@@ -934,17 +924,8 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
 
        /* First look for RedBoot table or partitions on the command
         * line, these take precedence over device tree information */
-       ret = parse_mtd_partitions(&priv->mtd, part_probe_types, &parts, 0);
-       if (ret < 0)
-               goto err;
-
-       if (ret == 0) {
-               ret = of_mtd_parse_partitions(priv->dev, node, &parts);
-               if (ret < 0)
-                       goto err;
-       }
-
-       mtd_device_register(&priv->mtd, parts, ret);
+       mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata,
+                                 NULL, 0);
 
        printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
               (unsigned long long)res.start, priv->bank);
index 23752fd5bc590d40e7ac5fb15ad93af05d9e6882..b4f3cc9f32fbe5614ad8d1a0a1cbe905ee01d3f5 100644 (file)
@@ -158,7 +158,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
 {
        int ret;
        struct device_node *flash_np;
-       static const char *part_types[] = { "cmdlinepart", NULL, };
+       struct mtd_part_parser_data ppdata;
 
        fun->chip.IO_ADDR_R = fun->io_base;
        fun->chip.IO_ADDR_W = fun->io_base;
@@ -192,18 +192,12 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
        if (ret)
                goto err;
 
-       ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
-
-#ifdef CONFIG_MTD_OF_PARTS
-       if (ret == 0) {
-               ret = of_mtd_parse_partitions(fun->dev, flash_np, &fun->parts);
-               if (ret < 0)
-                       goto err;
-       }
-#endif
-       ret = mtd_device_register(&fun->mtd, fun->parts, ret);
+       ppdata.of_node = flash_np;
+       ret = mtd_device_parse_register(&fun->mtd, NULL, &ppdata, NULL, 0);
 err:
        of_node_put(flash_np);
+       if (ret)
+               kfree(fun->mtd.name);
        return ret;
 }
 
index e9b275ac381ce89fd53f6d5fbb1895d205ce2462..e53b76064133fc52bded214fb57a94696abcb891 100644 (file)
@@ -146,7 +146,7 @@ static struct mtd_partition partition_info_16KB_blk[] = {
        {
                .name = "Root File System",
                .offset = 0x460000,
-               .size = 0,
+               .size = MTDPART_SIZ_FULL,
        },
 };
 
@@ -173,13 +173,10 @@ static struct mtd_partition partition_info_128KB_blk[] = {
        {
                .name = "Root File System",
                .offset = 0x800000,
-               .size = 0,
+               .size = MTDPART_SIZ_FULL,
        },
 };
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /**
  * struct fsmc_nand_data - structure for FSMC NAND device state
@@ -187,8 +184,6 @@ const char *part_probes[] = { "cmdlinepart", NULL };
  * @pid:               Part ID on the AMBA PrimeCell format
  * @mtd:               MTD info for a NAND flash.
  * @nand:              Chip related info for a NAND flash.
- * @partitions:                Partition info for a NAND Flash.
- * @nr_partitions:     Total number of partition of a NAND flash.
  *
  * @ecc_place:         ECC placing locations in oobfree type format.
  * @bank:              Bank number for probed device.
@@ -203,8 +198,6 @@ struct fsmc_nand_data {
        u32                     pid;
        struct mtd_info         mtd;
        struct nand_chip        nand;
-       struct mtd_partition    *partitions;
-       unsigned int            nr_partitions;
 
        struct fsmc_eccplace    *ecc_place;
        unsigned int            bank;
@@ -716,65 +709,17 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
         * platform data,
         * default partition information present in driver.
         */
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        /*
-        * Check if partition info passed via command line
+        * Check for partition info passed
         */
        host->mtd.name = "nand";
-       host->nr_partitions = parse_mtd_partitions(&host->mtd, part_probes,
-                       &host->partitions, 0);
-       if (host->nr_partitions <= 0) {
-#endif
-               /*
-                * Check if partition info passed via command line
-                */
-               if (pdata->partitions) {
-                       host->partitions = pdata->partitions;
-                       host->nr_partitions = pdata->nr_partitions;
-               } else {
-                       struct mtd_partition *partition;
-                       int i;
-
-                       /* Select the default partitions info */
-                       switch (host->mtd.size) {
-                       case 0x01000000:
-                       case 0x02000000:
-                       case 0x04000000:
-                               host->partitions = partition_info_16KB_blk;
-                               host->nr_partitions =
-                                       sizeof(partition_info_16KB_blk) /
-                                       sizeof(struct mtd_partition);
-                               break;
-                       case 0x08000000:
-                       case 0x10000000:
-                       case 0x20000000:
-                       case 0x40000000:
-                               host->partitions = partition_info_128KB_blk;
-                               host->nr_partitions =
-                                       sizeof(partition_info_128KB_blk) /
-                                       sizeof(struct mtd_partition);
-                               break;
-                       default:
-                               ret = -ENXIO;
-                               pr_err("Unsupported NAND size\n");
-                               goto err_probe;
-                       }
-
-                       partition = host->partitions;
-                       for (i = 0; i < host->nr_partitions; i++, partition++) {
-                               if (partition->size == 0) {
-                                       partition->size = host->mtd.size -
-                                               partition->offset;
-                                       break;
-                               }
-                       }
-               }
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       }
-#endif
-
-       ret = mtd_device_register(&host->mtd, host->partitions,
-                                 host->nr_partitions);
+       ret = mtd_device_parse_register(&host->mtd, NULL, 0,
+                       host->mtd.size <= 0x04000000 ?
+                               partition_info_16KB_blk :
+                               partition_info_128KB_blk,
+                       host->mtd.size <= 0x04000000 ?
+                               ARRAY_SIZE(partition_info_16KB_blk) :
+                               ARRAY_SIZE(partition_info_128KB_blk));
        if (ret)
                goto err_probe;
 
@@ -822,7 +767,7 @@ static int fsmc_nand_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        if (host) {
-               mtd_device_unregister(&host->mtd);
+               nand_release(&host->mtd);
                clk_disable(host->clk);
                clk_put(host->clk);
 
index 02a03e67109c90ce2534757b4053ada8e8469956..5dc6f0d92f1af7be563fd269b70ee505b0a08b9c 100644 (file)
@@ -81,9 +81,6 @@ static int h1910_device_ready(struct mtd_info *mtd)
 static int __init h1910_init(void)
 {
        struct nand_chip *this;
-       const char *part_type = 0;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = 0;
        void __iomem *nandaddr;
 
        if (!machine_is_h1900())
@@ -136,22 +133,10 @@ static int __init h1910_init(void)
                iounmap((void *)nandaddr);
                return -ENXIO;
        }
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand");
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-#endif
-       if (mtd_parts_nb == 0) {
-               mtd_parts = partition_info;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
+       mtd_device_parse_register(h1910_nand_mtd, NULL, 0,
+                       partition_info, NUM_PARTITIONS);
 
        /* Return happy */
        return 0;
index 6e813daed068d359f66f3c2ffb65abf46d924a44..e2664073a89b8eae1afa5c2ef5fe3d81e0348722 100644 (file)
@@ -251,10 +251,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
        return 0;
 }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static const char *part_probes[] = {"cmdline", NULL};
-#endif
-
 static int jz_nand_ioremap_resource(struct platform_device *pdev,
        const char *name, struct resource **res, void __iomem **base)
 {
@@ -299,8 +295,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
        struct nand_chip *chip;
        struct mtd_info *mtd;
        struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
-       struct mtd_partition *partition_info;
-       int num_partitions = 0;
 
        nand = kzalloc(sizeof(*nand), GFP_KERNEL);
        if (!nand) {
@@ -373,15 +367,9 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
                goto err_gpio_free;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       num_partitions = parse_mtd_partitions(mtd, part_probes,
-                                               &partition_info, 0);
-#endif
-       if (num_partitions <= 0 && pdata) {
-               num_partitions = pdata->num_partitions;
-               partition_info = pdata->partitions;
-       }
-       ret = mtd_device_register(mtd, partition_info, num_partitions);
+       ret = mtd_device_parse_register(mtd, NULL, 0,
+                       pdata ? pdata->partitions : NULL,
+                       pdata ? pdata->num_partitions : 0);
 
        if (ret) {
                dev_err(&pdev->dev, "Failed to add mtd device\n");
index eb1fbac63eb6015ce2804d7e676698c4b51cd3ed..5ede64706346084dd5cdd6d38612d532ec493992 100644 (file)
@@ -131,8 +131,6 @@ struct mpc5121_nfc_prv {
 
 static void mpc5121_nfc_done(struct mtd_info *mtd);
 
-static const char *mpc5121_nfc_pprobes[] = { "cmdlinepart", NULL };
-
 /* Read NFC register */
 static inline u16 nfc_read(struct mtd_info *mtd, uint reg)
 {
@@ -656,13 +654,13 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        struct mpc5121_nfc_prv *prv;
        struct resource res;
        struct mtd_info *mtd;
-       struct mtd_partition *parts;
        struct nand_chip *chip;
        unsigned long regs_paddr, regs_size;
        const __be32 *chips_no;
        int resettime = 0;
        int retval = 0;
        int rev, len;
+       struct mtd_part_parser_data ppdata;
 
        /*
         * Check SoC revision. This driver supports only NFC
@@ -727,6 +725,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        }
 
        mtd->name = "MPC5121 NAND";
+       ppdata.of_node = dn;
        chip->dev_ready = mpc5121_nfc_dev_ready;
        chip->cmdfunc = mpc5121_nfc_command;
        chip->read_byte = mpc5121_nfc_read_byte;
@@ -735,7 +734,8 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        chip->write_buf = mpc5121_nfc_write_buf;
        chip->verify_buf = mpc5121_nfc_verify_buf;
        chip->select_chip = mpc5121_nfc_select_chip;
-       chip->options = NAND_NO_AUTOINCR | NAND_USE_FLASH_BBT;
+       chip->options = NAND_NO_AUTOINCR;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
        chip->ecc.mode = NAND_ECC_SOFT;
 
        /* Support external chip-select logic on ADS5121 board */
@@ -837,19 +837,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        dev_set_drvdata(dev, mtd);
 
        /* Register device in MTD */
-       retval = parse_mtd_partitions(mtd, mpc5121_nfc_pprobes, &parts, 0);
-#ifdef CONFIG_MTD_OF_PARTS
-       if (retval == 0)
-               retval = of_mtd_parse_partitions(dev, dn, &parts);
-#endif
-       if (retval < 0) {
-               dev_err(dev, "Error parsing MTD partitions!\n");
-               devm_free_irq(dev, prv->irq, mtd);
-               retval = -EINVAL;
-               goto error;
-       }
-
-       retval = mtd_device_register(mtd, parts, retval);
+       retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
        if (retval) {
                dev_err(dev, "Error adding MTD device!\n");
                devm_free_irq(dev, prv->irq, mtd);
index 90df34c4d26cae887454de88099fa6c672c6b88d..4d4c67763cb012dbd293bd49f90c37b6dfc308b4 100644 (file)
@@ -41,7 +41,7 @@
 
 #define nfc_is_v21()           (cpu_is_mx25() || cpu_is_mx35())
 #define nfc_is_v1()            (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2()          cpu_is_mx51()
+#define nfc_is_v3_2()          (cpu_is_mx51() || cpu_is_mx53())
 #define nfc_is_v3()            nfc_is_v3_2()
 
 /* Addresses for NFC registers */
 struct mxc_nand_host {
        struct mtd_info         mtd;
        struct nand_chip        nand;
-       struct mtd_partition    *parts;
        struct device           *dev;
 
        void                    *spare0;
@@ -350,8 +349,7 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
                        udelay(1);
                }
                if (max_retries < 0)
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: INT not set\n",
-                             __func__);
+                       pr_debug("%s: INT not set\n", __func__);
        }
 }
 
@@ -371,7 +369,7 @@ static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)
  * waits for completion. */
 static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
+       pr_debug("send_cmd(host, 0x%x, %d)\n", cmd, useirq);
 
        writew(cmd, NFC_V1_V2_FLASH_CMD);
        writew(NFC_CMD, NFC_V1_V2_CONFIG2);
@@ -387,8 +385,7 @@ static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
                        udelay(1);
                }
                if (max_retries < 0)
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: RESET failed\n",
-                             __func__);
+                       pr_debug("%s: RESET failed\n", __func__);
        } else {
                /* Wait for operation to complete */
                wait_op_done(host, useirq);
@@ -411,7 +408,7 @@ static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast)
  * a NAND command. */
 static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
+       pr_debug("send_addr(host, 0x%x %d)\n", addr, islast);
 
        writew(addr, NFC_V1_V2_FLASH_ADDR);
        writew(NFC_ADDR, NFC_V1_V2_CONFIG2);
@@ -561,8 +558,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
        uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT);
 
        if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
+               pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
                return -1;
        }
 
@@ -932,8 +928,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
+       pr_debug("mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
              command, column, page_addr);
 
        /* Reset command state information */
@@ -1044,7 +1039,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
        struct mxc_nand_host *host;
        struct resource *res;
-       int err = 0, __maybe_unused nr_parts = 0;
+       int err = 0;
        struct nand_ecclayout *oob_smallpage, *oob_largepage;
 
        /* Allocate memory for MTD device structure and private data */
@@ -1179,7 +1174,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
                this->bbt_td = &bbt_main_descr;
                this->bbt_md = &bbt_mirror_descr;
                /* update flash based bbt */
-               this->options |= NAND_USE_FLASH_BBT;
+               this->bbt_options |= NAND_BBT_USE_FLASH;
        }
 
        init_completion(&host->op_completion);
@@ -1231,16 +1226,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        }
 
        /* Register the partitions */
-       nr_parts =
-           parse_mtd_partitions(mtd, part_probes, &host->parts, 0);
-       if (nr_parts > 0)
-               mtd_device_register(mtd, host->parts, nr_parts);
-       else if (pdata->parts)
-               mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
-       else {
-               pr_info("Registering %s as whole device\n", mtd->name);
-               mtd_device_register(mtd, NULL, 0);
-       }
+       mtd_device_parse_register(mtd, part_probes, 0,
+                       pdata->parts, pdata->nr_parts);
 
        platform_set_drvdata(pdev, host);
 
index a46e9bb847bd0ac52743f14ab07133cc9a98b231..d2ee68a14d911b0038c4b4b15eb98567a9d8ed79 100644 (file)
@@ -21,7 +21,7 @@
  *  TODO:
  *     Enable cached programming for 2k page size chips
  *     Check, if mtd->ecctype should be set to MTD_ECC_HW
- *     if we have HW ecc support.
+ *     if we have HW ECC support.
  *     The AG-AND chips have nice features for speed improvement,
  *     which are not supported yet. Read / program 4 pages in one go.
  *     BBT table is not serialized, has to be fixed
@@ -113,21 +113,19 @@ static int check_offs_len(struct mtd_info *mtd,
 
        /* Start address must align on block boundary */
        if (ofs & ((1 << chip->phys_erase_shift) - 1)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Unaligned address\n", __func__);
+               pr_debug("%s: unaligned address\n", __func__);
                ret = -EINVAL;
        }
 
        /* Length must align on block boundary */
        if (len & ((1 << chip->phys_erase_shift) - 1)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Length not block aligned\n",
-                                       __func__);
+               pr_debug("%s: length not block aligned\n", __func__);
                ret = -EINVAL;
        }
 
        /* Do not allow past end of device */
        if (ofs + len > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Past end of device\n",
-                                       __func__);
+               pr_debug("%s: past end of device\n", __func__);
                ret = -EINVAL;
        }
 
@@ -136,9 +134,9 @@ static int check_offs_len(struct mtd_info *mtd,
 
 /**
  * nand_release_device - [GENERIC] release chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Deselect, release chip lock and wake up anyone waiting on the device
+ * Deselect, release chip lock and wake up anyone waiting on the device.
  */
 static void nand_release_device(struct mtd_info *mtd)
 {
@@ -157,9 +155,9 @@ static void nand_release_device(struct mtd_info *mtd)
 
 /**
  * nand_read_byte - [DEFAULT] read one byte from the chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Default read function for 8bit buswith
+ * Default read function for 8bit buswidth
  */
 static uint8_t nand_read_byte(struct mtd_info *mtd)
 {
@@ -169,10 +167,11 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)
 
 /**
  * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
- * @mtd:       MTD device structure
+ * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
+ * @mtd: MTD device structure
+ *
+ * Default read function for 16bit buswidth with endianness conversion.
  *
- * Default read function for 16bit buswith with
- * endianess conversion
  */
 static uint8_t nand_read_byte16(struct mtd_info *mtd)
 {
@@ -182,10 +181,9 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd)
 
 /**
  * nand_read_word - [DEFAULT] read one word from the chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Default read function for 16bit buswith without
- * endianess conversion
+ * Default read function for 16bit buswidth without endianness conversion.
  */
 static u16 nand_read_word(struct mtd_info *mtd)
 {
@@ -195,8 +193,8 @@ static u16 nand_read_word(struct mtd_info *mtd)
 
 /**
  * nand_select_chip - [DEFAULT] control CE line
- * @mtd:       MTD device structure
- * @chipnr:    chipnumber to select, -1 for deselect
+ * @mtd: MTD device structure
+ * @chipnr: chipnumber to select, -1 for deselect
  *
  * Default select function for 1 chip devices.
  */
@@ -218,11 +216,11 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr)
 
 /**
  * nand_write_buf - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
  *
- * Default write function for 8bit buswith
+ * Default write function for 8bit buswidth.
  */
 static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -235,11 +233,11 @@ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_read_buf - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
  *
- * Default read function for 8bit buswith
+ * Default read function for 8bit buswidth.
  */
 static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
@@ -252,11 +250,11 @@ static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 
 /**
  * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
  *
- * Default verify function for 8bit buswith
+ * Default verify function for 8bit buswidth.
  */
 static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -271,11 +269,11 @@ static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_write_buf16 - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
  *
- * Default write function for 16bit buswith
+ * Default write function for 16bit buswidth.
  */
 static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -291,11 +289,11 @@ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_read_buf16 - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
  *
- * Default read function for 16bit buswith
+ * Default read function for 16bit buswidth.
  */
 static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 {
@@ -310,11 +308,11 @@ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 
 /**
  * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
  *
- * Default verify function for 16bit buswith
+ * Default verify function for 16bit buswidth.
  */
 static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -332,9 +330,9 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_block_bad - [DEFAULT] Read bad block marker from the chip
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
+ * @getchip: 0, if the chip is already selected
  *
  * Check, if the block is bad.
  */
@@ -344,7 +342,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
        struct nand_chip *chip = mtd->priv;
        u16 bad;
 
-       if (chip->options & NAND_BBT_SCANLASTPAGE)
+       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
@@ -384,11 +382,11 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 
 /**
  * nand_default_block_markbad - [DEFAULT] mark a block bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
  *
- * This is the default implementation, which can be overridden by
- * a hardware specific driver.
+ * This is the default implementation, which can be overridden by a hardware
+ * specific driver.
 */
 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
@@ -396,7 +394,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        uint8_t buf[2] = { 0, 0 };
        int block, ret, i = 0;
 
-       if (chip->options & NAND_BBT_SCANLASTPAGE)
+       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        /* Get block number */
@@ -404,16 +402,17 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        if (chip->bbt)
                chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
-       /* Do we have a flash based bad block table ? */
-       if (chip->options & NAND_USE_FLASH_BBT)
+       /* Do we have a flash based bad block table? */
+       if (chip->bbt_options & NAND_BBT_USE_FLASH)
                ret = nand_update_bbt(mtd, ofs);
        else {
                nand_get_device(chip, mtd, FL_WRITING);
 
-               /* Write to first two pages and to byte 1 and 6 if necessary.
-                * If we write to more than one location, the first error
-                * encountered quits the procedure. We write two bytes per
-                * location, so we dont have to mess with 16 bit access.
+               /*
+                * Write to first two pages if necessary. If we write to more
+                * than one location, the first error encountered quits the
+                * procedure. We write two bytes per location, so we dont have
+                * to mess with 16 bit access.
                 */
                do {
                        chip->ops.len = chip->ops.ooblen = 2;
@@ -423,14 +422,9 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
                        ret = nand_do_write_oob(mtd, ofs, &chip->ops);
 
-                       if (!ret && (chip->options & NAND_BBT_SCANBYTE1AND6)) {
-                               chip->ops.ooboffs = NAND_SMALL_BADBLOCK_POS
-                                       & ~0x01;
-                               ret = nand_do_write_oob(mtd, ofs, &chip->ops);
-                       }
                        i++;
                        ofs += mtd->writesize;
-               } while (!ret && (chip->options & NAND_BBT_SCAN2NDPAGE) &&
+               } while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) &&
                                i < 2);
 
                nand_release_device(mtd);
@@ -443,16 +437,16 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
 /**
  * nand_check_wp - [GENERIC] check if the chip is write protected
- * @mtd:       MTD device structure
- * Check, if the device is write protected
+ * @mtd: MTD device structure
  *
- * The function expects, that the device is already selected
+ * Check, if the device is write protected. The function expects, that the
+ * device is already selected.
  */
 static int nand_check_wp(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
 
-       /* broken xD cards report WP despite being writable */
+       /* Broken xD cards report WP despite being writable */
        if (chip->options & NAND_BROKEN_XD)
                return 0;
 
@@ -463,10 +457,10 @@ static int nand_check_wp(struct mtd_info *mtd)
 
 /**
  * nand_block_checkbad - [GENERIC] Check if a block is marked bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
- * @allowbbt:  1, if its allowed to access the bbt area
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
+ * @getchip: 0, if the chip is already selected
+ * @allowbbt: 1, if its allowed to access the bbt area
  *
  * Check, if the block is bad. Either by reading the bad block table or
  * calling of the scan function.
@@ -485,8 +479,8 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
 
 /**
  * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
- * @mtd:       MTD device structure
- * @timeo:     Timeout
+ * @mtd: MTD device structure
+ * @timeo: Timeout
  *
  * Helper function for nand_wait_ready used when needing to wait in interrupt
  * context.
@@ -505,10 +499,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
        }
 }
 
-/*
- * Wait for the ready pin, after a command
- * The timeout is catched later.
- */
+/* Wait for the ready pin, after a command. The timeout is caught later. */
 void nand_wait_ready(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
@@ -519,7 +510,7 @@ void nand_wait_ready(struct mtd_info *mtd)
                return panic_nand_wait_ready(mtd, 400);
 
        led_trigger_event(nand_led_trigger, LED_FULL);
-       /* wait until command is processed or timeout occures */
+       /* Wait until command is processed or timeout occurs */
        do {
                if (chip->dev_ready(mtd))
                        break;
@@ -531,13 +522,13 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);
 
 /**
  * nand_command - [DEFAULT] Send command to NAND device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
  *
- * Send command to NAND device. This function is used for small page
- * devices (256/512 Bytes per page)
+ * Send command to NAND device. This function is used for small page devices
+ * (256/512 Bytes per page).
  */
 static void nand_command(struct mtd_info *mtd, unsigned int command,
                         int column, int page_addr)
@@ -545,9 +536,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        register struct nand_chip *chip = mtd->priv;
        int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
 
-       /*
-        * Write out the command to the device.
-        */
+       /* Write out the command to the device */
        if (command == NAND_CMD_SEQIN) {
                int readcmd;
 
@@ -567,9 +556,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        }
        chip->cmd_ctrl(mtd, command, ctrl);
 
-       /*
-        * Address cycle, when necessary
-        */
+       /* Address cycle, when necessary */
        ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
        /* Serially input address */
        if (column != -1) {
@@ -590,8 +577,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
 
        /*
-        * program and erase have their own busy handlers
-        * status and sequential in needs no delay
+        * Program and erase have their own busy handlers status and sequential
+        * in needs no delay
         */
        switch (command) {
 
@@ -625,8 +612,10 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
                        return;
                }
        }
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine.
+        */
        ndelay(100);
 
        nand_wait_ready(mtd);
@@ -634,14 +623,14 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 
 /**
  * nand_command_lp - [DEFAULT] Send command to NAND large page device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
  *
  * Send command to NAND device. This is the version for the new large page
- * devices We dont have the separate regions as we have in the small page
- * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
+ * devices. We don't have the separate regions as we have in the small page
+ * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
  */
 static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                            int column, int page_addr)
@@ -683,8 +672,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
 
        /*
-        * program and erase have their own busy handlers
-        * status, sequential in, and deplete1 need no delay
+        * Program and erase have their own busy handlers status, sequential
+        * in, and deplete1 need no delay.
         */
        switch (command) {
 
@@ -698,14 +687,12 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_DEPLETE1:
                return;
 
-               /*
-                * read error status commands require only a short delay
-                */
        case NAND_CMD_STATUS_ERROR:
        case NAND_CMD_STATUS_ERROR0:
        case NAND_CMD_STATUS_ERROR1:
        case NAND_CMD_STATUS_ERROR2:
        case NAND_CMD_STATUS_ERROR3:
+               /* Read error status commands require only a short delay */
                udelay(chip->chip_delay);
                return;
 
@@ -739,7 +726,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        default:
                /*
                 * If we don't have access to the busy pin, we apply the given
-                * command delay
+                * command delay.
                 */
                if (!chip->dev_ready) {
                        udelay(chip->chip_delay);
@@ -747,8 +734,10 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                }
        }
 
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine.
+        */
        ndelay(100);
 
        nand_wait_ready(mtd);
@@ -756,25 +745,25 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
 
 /**
  * panic_nand_get_device - [GENERIC] Get chip for selected access
- * @chip:      the nand chip descriptor
- * @mtd:       MTD device structure
- * @new_state: the state which is requested
+ * @chip: the nand chip descriptor
+ * @mtd: MTD device structure
+ * @new_state: the state which is requested
  *
  * Used when in panic, no locks are taken.
  */
 static void panic_nand_get_device(struct nand_chip *chip,
                      struct mtd_info *mtd, int new_state)
 {
-       /* Hardware controller shared among independend devices */
+       /* Hardware controller shared among independent devices */
        chip->controller->active = chip;
        chip->state = new_state;
 }
 
 /**
  * nand_get_device - [GENERIC] Get chip for selected access
- * @chip:      the nand chip descriptor
- * @mtd:       MTD device structure
- * @new_state: the state which is requested
+ * @chip: the nand chip descriptor
+ * @mtd: MTD device structure
+ * @new_state: the state which is requested
  *
  * Get the device and lock it for exclusive access
  */
@@ -812,10 +801,10 @@ retry:
 }
 
 /**
- * panic_nand_wait - [GENERIC]  wait until the command is done
- * @mtd:       MTD device structure
- * @chip:      NAND chip structure
- * @timeo:     Timeout
+ * panic_nand_wait - [GENERIC] wait until the command is done
+ * @mtd: MTD device structure
+ * @chip: NAND chip structure
+ * @timeo: timeout
  *
  * Wait for command done. This is a helper function for nand_wait used when
  * we are in interrupt context. May happen when in panic and trying to write
@@ -838,13 +827,13 @@ static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_wait - [DEFAULT]  wait until the command is done
- * @mtd:       MTD device structure
- * @chip:      NAND chip structure
+ * nand_wait - [DEFAULT] wait until the command is done
+ * @mtd: MTD device structure
+ * @chip: NAND chip structure
  *
- * Wait for command done. This applies to erase and program only
- * Erase can take up to 400ms and program up to 20ms according to
- * general NAND and SmartMedia specs
+ * Wait for command done. This applies to erase and program only. Erase can
+ * take up to 400ms and program up to 20ms according to general NAND and
+ * SmartMedia specs.
  */
 static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
@@ -859,8 +848,10 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 
        led_trigger_event(nand_led_trigger, LED_FULL);
 
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in any
+        * case on any machine.
+        */
        ndelay(100);
 
        if ((state == FL_ERASING) && (chip->options & NAND_IS_AND))
@@ -890,16 +881,15 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 
 /**
  * __nand_unlock - [REPLACEABLE] unlocks specified locked blocks
- *
  * @mtd: mtd info
  * @ofs: offset to start unlock from
  * @len: length to unlock
- * @invert:   when = 0, unlock the range of blocks within the lower and
- *                      upper boundary address
- *            when = 1, unlock the range of blocks outside the boundaries
- *                      of the lower and upper boundary address
+ * @invert: when = 0, unlock the range of blocks within the lower and
+ *                    upper boundary address
+ *          when = 1, unlock the range of blocks outside the boundaries
+ *                    of the lower and upper boundary address
  *
- * return - unlock status
+ * Returs unlock status.
  */
 static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
                                        uint64_t len, int invert)
@@ -919,10 +909,9 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
 
        /* Call wait ready function */
        status = chip->waitfunc(mtd, chip);
-       udelay(1000);
        /* See if device thinks it succeeded */
        if (status & 0x01) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Error status = 0x%08x\n",
+               pr_debug("%s: error status = 0x%08x\n",
                                        __func__, status);
                ret = -EIO;
        }
@@ -932,12 +921,11 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
 
 /**
  * nand_unlock - [REPLACEABLE] unlocks specified locked blocks
- *
  * @mtd: mtd info
  * @ofs: offset to start unlock from
  * @len: length to unlock
  *
- * return - unlock status
+ * Returns unlock status.
  */
 int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
@@ -945,7 +933,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        int chipnr;
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
+       pr_debug("%s: start = 0x%012llx, len = %llu\n",
                        __func__, (unsigned long long)ofs, len);
 
        if (check_offs_len(mtd, ofs, len))
@@ -964,7 +952,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
+               pr_debug("%s: device is write protected!\n",
                                        __func__);
                ret = -EIO;
                goto out;
@@ -981,18 +969,16 @@ EXPORT_SYMBOL(nand_unlock);
 
 /**
  * nand_lock - [REPLACEABLE] locks all blocks present in the device
- *
  * @mtd: mtd info
  * @ofs: offset to start unlock from
  * @len: length to unlock
  *
- * return - lock status
+ * This feature is not supported in many NAND parts. 'Micron' NAND parts do
+ * have this feature, but it allows only to lock all blocks, not for specified
+ * range for block. Implementing 'lock' feature by making use of 'unlock', for
+ * now.
  *
- * This feature is not supported in many NAND parts. 'Micron' NAND parts
- * do have this feature, but it allows only to lock all blocks, not for
- * specified range for block.
- *
- * Implementing 'lock' feature by making use of 'unlock', for now.
+ * Returns lock status.
  */
 int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
@@ -1000,7 +986,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        int chipnr, status, page;
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
+       pr_debug("%s: start = 0x%012llx, len = %llu\n",
                        __func__, (unsigned long long)ofs, len);
 
        if (check_offs_len(mtd, ofs, len))
@@ -1015,7 +1001,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
+               pr_debug("%s: device is write protected!\n",
                                        __func__);
                status = MTD_ERASE_FAILED;
                ret = -EIO;
@@ -1028,10 +1014,9 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
        /* Call wait ready function */
        status = chip->waitfunc(mtd, chip);
-       udelay(1000);
        /* See if device thinks it succeeded */
        if (status & 0x01) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Error status = 0x%08x\n",
+               pr_debug("%s: error status = 0x%08x\n",
                                        __func__, status);
                ret = -EIO;
                goto out;
@@ -1047,13 +1032,13 @@ out:
 EXPORT_SYMBOL(nand_lock);
 
 /**
- * nand_read_page_raw - [Intern] read raw page data without ecc
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_raw - [INTERN] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * Not for syndrome calculating ecc controllers, which use a special oob layout
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
                              uint8_t *buf, int page)
@@ -1064,11 +1049,11 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
  * We need a special oob layout and handling even when OOB isn't used.
  */
@@ -1107,11 +1092,11 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  */
 static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
                                uint8_t *buf, int page)
@@ -1148,12 +1133,12 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @data_offs: offset of requested data within the page
- * @readlen:   data length
- * @bufpoi:    buffer to store read data
+ * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @data_offs: offset of requested data within the page
+ * @readlen: data length
+ * @bufpoi: buffer to store read data
  */
 static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                        uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
@@ -1166,12 +1151,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
        int index = 0;
 
-       /* Column address wihin the page aligned to ECC size (256bytes). */
+       /* Column address within the page aligned to ECC size (256bytes) */
        start_step = data_offs / chip->ecc.size;
        end_step = (data_offs + readlen - 1) / chip->ecc.size;
        num_steps = end_step - start_step + 1;
 
-       /* Data size aligned to ECC ecc.size*/
+       /* Data size aligned to ECC ecc.size */
        datafrag_len = num_steps * chip->ecc.size;
        eccfrag_len = num_steps * chip->ecc.bytes;
 
@@ -1183,13 +1168,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        p = bufpoi + data_col_addr;
        chip->read_buf(mtd, p, datafrag_len);
 
-       /* Calculate  ECC */
+       /* Calculate ECC */
        for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
                chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
 
-       /* The performance is faster if to position offsets
-          according to ecc.pos. Let make sure here that
-          there are no gaps in ecc positions */
+       /*
+        * The performance is faster if we position offsets according to
+        * ecc.pos. Let's make sure that there are no gaps in ECC positions.
+        */
        for (i = 0; i < eccfrag_len - 1; i++) {
                if (eccpos[i + start_step * chip->ecc.bytes] + 1 !=
                        eccpos[i + start_step * chip->ecc.bytes + 1]) {
@@ -1201,8 +1187,10 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
                chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
        } else {
-               /* send the command to read the particular ecc bytes */
-               /* take care about buswidth alignment in read_buf */
+               /*
+                * Send the command to read the particular ECC bytes take care
+                * about buswidth alignment in read_buf.
+                */
                index = start_step * chip->ecc.bytes;
 
                aligned_pos = eccpos[index] & ~(busw - 1);
@@ -1235,13 +1223,13 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * Not for syndrome calculating ecc controllers which need a special oob layout
+ * Not for syndrome calculating ECC controllers which need a special oob layout.
  */
 static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                                uint8_t *buf, int page)
@@ -1280,18 +1268,17 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_hwecc_oob_first - [REPLACABLE] hw ecc, read oob first
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_hwecc_oob_first - [REPLACEABLE] hw ecc, read oob first
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * Hardware ECC for large page chips, require OOB to be read first.
- * For this ECC mode, the write_page method is re-used from ECC_HW.
- * These methods read/write ECC from the OOB area, unlike the
- * ECC_HW_SYNDROME support with multiple ECC steps, follows the
- * "infix ECC" scheme and reads/writes ECC from the data area, by
- * overwriting the NAND manufacturer bad block markings.
+ * Hardware ECC for large page chips, require OOB to be read first. For this
+ * ECC mode, the write_page method is re-used from ECC_HW. These methods
+ * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
+ * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
+ * the data area, by overwriting the NAND manufacturer bad block markings.
  */
 static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
        struct nand_chip *chip, uint8_t *buf, int page)
@@ -1329,14 +1316,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 }
 
 /**
- * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * The hw generator calculates the error syndrome automatically. Therefor
- * we need a special oob layout and handling.
+ * The hw generator calculates the error syndrome automatically. Therefore we
+ * need a special oob layout and handling.
  */
 static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                                   uint8_t *buf, int page)
@@ -1384,11 +1371,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_transfer_oob - [Internal] Transfer oob to client buffer
- * @chip:      nand chip structure
- * @oob:       oob destination address
- * @ops:       oob ops structure
- * @len:       size of oob to transfer
+ * nand_transfer_oob - [INTERN] Transfer oob to client buffer
+ * @chip: nand chip structure
+ * @oob: oob destination address
+ * @ops: oob ops structure
+ * @len: size of oob to transfer
  */
 static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
                                  struct mtd_oob_ops *ops, size_t len)
@@ -1406,7 +1393,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
                size_t bytes = 0;
 
                for (; free->length && len; free++, len -= bytes) {
-                       /* Read request not from offset 0 ? */
+                       /* Read request not from offset 0? */
                        if (unlikely(roffs)) {
                                if (roffs >= free->length) {
                                        roffs -= free->length;
@@ -1432,11 +1419,10 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 }
 
 /**
- * nand_do_read_ops - [Internal] Read data with ECC
- *
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob ops structure
+ * nand_do_read_ops - [INTERN] Read data with ECC
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob ops structure
  *
  * Internal function. Called with chip held.
  */
@@ -1473,7 +1459,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                bytes = min(mtd->writesize - col, readlen);
                aligned = (bytes == mtd->writesize);
 
-               /* Is the current page in the buffer ? */
+               /* Is the current page in the buffer? */
                if (realpage != chip->pagebuf || oob) {
                        bufpoi = aligned ? buf : chip->buffers->databuf;
 
@@ -1539,7 +1525,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                if (!readlen)
                        break;
 
-               /* For subsequent reads align to page boundary. */
+               /* For subsequent reads align to page boundary */
                col = 0;
                /* Increment page address */
                realpage++;
@@ -1552,8 +1538,9 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, chipnr);
                }
 
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
+               /*
+                * Check, if the chip supports auto page increment or if we
+                * have hit a block boundary.
                 */
                if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
                        sndcmd = 1;
@@ -1574,13 +1561,13 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
 /**
  * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @retlen:    pointer to variable to store the number of read bytes
- * @buf:       the databuffer to put data
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @len: number of bytes to read
+ * @retlen: pointer to variable to store the number of read bytes
+ * @buf: the databuffer to put data
  *
- * Get hold of the chip and call nand_do_read
+ * Get hold of the chip and call nand_do_read.
  */
 static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
                     size_t *retlen, uint8_t *buf)
@@ -1610,11 +1597,11 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
 }
 
 /**
- * nand_read_oob_std - [REPLACABLE] the most common OOB data read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to read
- * @sndcmd:    flag whether to issue read command or not
+ * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
+ * @sndcmd: flag whether to issue read command or not
  */
 static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                             int page, int sndcmd)
@@ -1628,12 +1615,12 @@ static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC
+ * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
  *                         with syndromes
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to read
- * @sndcmd:    flag whether to issue read command or not
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
+ * @sndcmd: flag whether to issue read command or not
  */
 static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                                  int page, int sndcmd)
@@ -1667,10 +1654,10 @@ static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_oob_std - [REPLACABLE] the most common OOB data write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to write
+ * nand_write_oob_std - [REPLACEABLE] the most common OOB data write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
  */
 static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                              int page)
@@ -1690,11 +1677,11 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC
- *                          with syndrome - only for large page flash !
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to write
+ * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
+ *                          with syndrome - only for large page flash
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
  */
 static int nand_write_oob_syndrome(struct mtd_info *mtd,
                                   struct nand_chip *chip, int page)
@@ -1749,34 +1736,37 @@ static int nand_write_oob_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_do_read_oob - [Intern] NAND read out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operations description structure
+ * nand_do_read_oob - [INTERN] NAND read out-of-band
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob operations description structure
  *
- * NAND read out-of-band data from the spare area
+ * NAND read out-of-band data from the spare area.
  */
 static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
 {
        int page, realpage, chipnr, sndcmd = 1;
        struct nand_chip *chip = mtd->priv;
+       struct mtd_ecc_stats stats;
        int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
        int readlen = ops->ooblen;
        int len;
        uint8_t *buf = ops->oobbuf;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08Lx, len = %i\n",
+       pr_debug("%s: from = 0x%08Lx, len = %i\n",
                        __func__, (unsigned long long)from, readlen);
 
+       stats = mtd->ecc_stats;
+
        if (ops->mode == MTD_OOB_AUTO)
                len = chip->ecc.layout->oobavail;
        else
                len = mtd->oobsize;
 
        if (unlikely(ops->ooboffs >= len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start read "
-                                       "outside oob\n", __func__);
+               pr_debug("%s: attempt to start read outside oob\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -1784,8 +1774,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
        if (unlikely(from >= mtd->size ||
                     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
                                        (from >> chip->page_shift)) * len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt read beyond end "
-                                       "of device\n", __func__);
+               pr_debug("%s: attempt to read beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -1830,24 +1820,29 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, chipnr);
                }
 
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
+               /*
+                * Check, if the chip supports auto page increment or if we
+                * have hit a block boundary.
                 */
                if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
                        sndcmd = 1;
        }
 
        ops->oobretlen = ops->ooblen;
-       return 0;
+
+       if (mtd->ecc_stats.failed - stats.failed)
+               return -EBADMSG;
+
+       return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
 }
 
 /**
  * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob operation description structure
  *
- * NAND read data and/or out-of-band data
+ * NAND read data and/or out-of-band data.
  */
 static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops)
@@ -1859,8 +1854,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
 
        /* Do not allow reads past end of device */
        if (ops->datbuf && (from + ops->len) > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt read "
-                               "beyond end of device\n", __func__);
+               pr_debug("%s: attempt to read beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -1888,12 +1883,12 @@ out:
 
 
 /**
- * nand_write_page_raw - [Intern] raw page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_raw - [INTERN] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  *
- * Not for syndrome calculating ecc controllers, which use a special oob layout
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
                                const uint8_t *buf)
@@ -1903,10 +1898,10 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_page_raw_syndrome - [Intern] raw page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_raw_syndrome - [INTERN] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
@@ -1942,10 +1937,10 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
                chip->write_buf(mtd, oob, size);
 }
 /**
- * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  */
 static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
                                  const uint8_t *buf)
@@ -1957,7 +1952,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        const uint8_t *p = buf;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
 
-       /* Software ecc calculation */
+       /* Software ECC calculation */
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
@@ -1968,10 +1963,10 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_page_hwecc - [REPLACABLE] hardware ecc based page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  */
 static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                                  const uint8_t *buf)
@@ -1996,13 +1991,13 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_page_syndrome - [REPLACABLE] hardware ecc syndrom based page write
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  *
- * The hw generator calculates the error syndrome automatically. Therefor
- * we need a special oob layout and handling.
+ * The hw generator calculates the error syndrome automatically. Therefore we
+ * need a special oob layout and handling.
  */
 static void nand_write_page_syndrome(struct mtd_info *mtd,
                                    struct nand_chip *chip, const uint8_t *buf)
@@ -2041,12 +2036,12 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
 
 /**
  * nand_write_page - [REPLACEABLE] write one page
- * @mtd:       MTD device structure
- * @chip:      NAND chip descriptor
- * @buf:       the data to write
- * @page:      page number to write
- * @cached:    cached programming
- * @raw:       use _raw version of write_page
+ * @mtd: MTD device structure
+ * @chip: NAND chip descriptor
+ * @buf: the data to write
+ * @page: page number to write
+ * @cached: cached programming
+ * @raw: use _raw version of write_page
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                           const uint8_t *buf, int page, int cached, int raw)
@@ -2061,8 +2056,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                chip->ecc.write_page(mtd, chip, buf);
 
        /*
-        * Cached progamming disabled for now, Not sure if its worth the
-        * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s)
+        * Cached progamming disabled for now. Not sure if it's worth the
+        * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s).
         */
        cached = 0;
 
@@ -2072,7 +2067,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                status = chip->waitfunc(mtd, chip);
                /*
                 * See if operation failed and additional status checks are
-                * available
+                * available.
                 */
                if ((status & NAND_STATUS_FAIL) && (chip->errstat))
                        status = chip->errstat(mtd, chip, FL_WRITING, status,
@@ -2096,15 +2091,23 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_fill_oob - [Internal] Transfer client buffer to oob
- * @chip:      nand chip structure
- * @oob:       oob data buffer
- * @len:       oob data write length
- * @ops:       oob ops structure
+ * nand_fill_oob - [INTERN] Transfer client buffer to oob
+ * @mtd: MTD device structure
+ * @oob: oob data buffer
+ * @len: oob data write length
+ * @ops: oob ops structure
  */
-static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
-                                               struct mtd_oob_ops *ops)
+static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
+                             struct mtd_oob_ops *ops)
 {
+       struct nand_chip *chip = mtd->priv;
+
+       /*
+        * Initialise to all 0xFF, to avoid the possibility of left over OOB
+        * data from a previous OOB read.
+        */
+       memset(chip->oob_poi, 0xff, mtd->oobsize);
+
        switch (ops->mode) {
 
        case MTD_OOB_PLACE:
@@ -2118,7 +2121,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
                size_t bytes = 0;
 
                for (; free->length && len; free++, len -= bytes) {
-                       /* Write request not from offset 0 ? */
+                       /* Write request not from offset 0? */
                        if (unlikely(woffs)) {
                                if (woffs >= free->length) {
                                        woffs -= free->length;
@@ -2146,12 +2149,12 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
 #define NOTALIGNED(x)  ((x & (chip->subpagesize - 1)) != 0)
 
 /**
- * nand_do_write_ops - [Internal] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operations description structure
+ * nand_do_write_ops - [INTERN] NAND write with ECC
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operations description structure
  *
- * NAND write with ECC
+ * NAND write with ECC.
  */
 static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -2172,10 +2175,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        if (!writelen)
                return 0;
 
-       /* reject writes, which are not page aligned */
+       /* Reject writes, which are not page aligned */
        if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
-               printk(KERN_NOTICE "%s: Attempt to write not "
-                               "page aligned data\n", __func__);
+               pr_notice("%s: attempt to write non page aligned data\n",
+                          __func__);
                return -EINVAL;
        }
 
@@ -2201,10 +2204,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
            (chip->pagebuf << chip->page_shift) < (to + ops->len))
                chip->pagebuf = -1;
 
-       /* If we're not given explicit OOB data, let it be 0xFF */
-       if (likely(!oob))
-               memset(chip->oob_poi, 0xff, mtd->oobsize);
-
        /* Don't allow multipage oob writes with offset */
        if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
                return -EINVAL;
@@ -2214,7 +2213,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                int cached = writelen > bytes && page != blockmask;
                uint8_t *wbuf = buf;
 
-               /* Partial page write ? */
+               /* Partial page write? */
                if (unlikely(column || writelen < (mtd->writesize - 1))) {
                        cached = 0;
                        bytes = min_t(int, bytes - column, (int) writelen);
@@ -2226,7 +2225,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
                if (unlikely(oob)) {
                        size_t len = min(oobwritelen, oobmaxlen);
-                       oob = nand_fill_oob(chip, oob, len, ops);
+                       oob = nand_fill_oob(mtd, oob, len, ops);
                        oobwritelen -= len;
                }
 
@@ -2260,11 +2259,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
 /**
  * panic_nand_write - [MTD Interface] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @len: number of bytes to write
+ * @retlen: pointer to variable to store the number of written bytes
+ * @buf: the data to write
  *
  * NAND write with ECC. Used when performing writes in interrupt context, this
  * may for example be called by mtdoops when writing an oops while in panic.
@@ -2281,10 +2280,10 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
        if (!len)
                return 0;
 
-       /* Wait for the device to get ready */
+       /* Wait for the device to get ready */
        panic_nand_wait(mtd, chip, 400);
 
-       /* Grab the device */
+       /* Grab the device */
        panic_nand_get_device(chip, mtd, FL_WRITING);
 
        chip->ops.len = len;
@@ -2299,13 +2298,13 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 /**
  * nand_write - [MTD Interface] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @len: number of bytes to write
+ * @retlen: pointer to variable to store the number of written bytes
+ * @buf: the data to write
  *
- * NAND write with ECC
+ * NAND write with ECC.
  */
 static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                          size_t *retlen, const uint8_t *buf)
@@ -2336,11 +2335,11 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 /**
  * nand_do_write_oob - [MTD Interface] NAND write out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operation description structure
  *
- * NAND write out-of-band
+ * NAND write out-of-band.
  */
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -2348,7 +2347,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        int chipnr, page, status, len;
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
+       pr_debug("%s: to = 0x%08x, len = %i\n",
                         __func__, (unsigned int)to, (int)ops->ooblen);
 
        if (ops->mode == MTD_OOB_AUTO)
@@ -2358,14 +2357,14 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 
        /* Do not allow write past end of page */
        if ((ops->ooboffs + ops->ooblen) > len) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write "
-                               "past end of page\n", __func__);
+               pr_debug("%s: attempt to write past end of page\n",
+                               __func__);
                return -EINVAL;
        }
 
        if (unlikely(ops->ooboffs >= len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start "
-                               "write outside oob\n", __func__);
+               pr_debug("%s: attempt to start write outside oob\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -2374,8 +2373,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                     ops->ooboffs + ops->ooblen >
                        ((mtd->size >> chip->page_shift) -
                         (to >> chip->page_shift)) * len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt write beyond "
-                               "end of device\n", __func__);
+               pr_debug("%s: attempt to write beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -2401,10 +2400,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        if (page == chip->pagebuf)
                chip->pagebuf = -1;
 
-       memset(chip->oob_poi, 0xff, mtd->oobsize);
-       nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
+       nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
        status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
-       memset(chip->oob_poi, 0xff, mtd->oobsize);
 
        if (status)
                return status;
@@ -2416,9 +2413,9 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 
 /**
  * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operation description structure
  */
 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                          struct mtd_oob_ops *ops)
@@ -2430,8 +2427,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
 
        /* Do not allow writes past end of device */
        if (ops->datbuf && (to + ops->len) > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt write beyond "
-                               "end of device\n", __func__);
+               pr_debug("%s: attempt to write beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -2458,11 +2455,11 @@ out:
 }
 
 /**
- * single_erease_cmd - [GENERIC] NAND standard block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
+ * single_erase_cmd - [GENERIC] NAND standard block erase command function
+ * @mtd: MTD device structure
+ * @page: the page address of the block which will be erased
  *
- * Standard erase command for NAND chips
+ * Standard erase command for NAND chips.
  */
 static void single_erase_cmd(struct mtd_info *mtd, int page)
 {
@@ -2473,12 +2470,11 @@ static void single_erase_cmd(struct mtd_info *mtd, int page)
 }
 
 /**
- * multi_erease_cmd - [GENERIC] AND specific block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
+ * multi_erase_cmd - [GENERIC] AND specific block erase command function
+ * @mtd: MTD device structure
+ * @page: the page address of the block which will be erased
  *
- * AND multi block erase command function
- * Erase 4 consecutive blocks
+ * AND multi block erase command function. Erase 4 consecutive blocks.
  */
 static void multi_erase_cmd(struct mtd_info *mtd, int page)
 {
@@ -2493,10 +2489,10 @@ static void multi_erase_cmd(struct mtd_info *mtd, int page)
 
 /**
  * nand_erase - [MTD Interface] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
+ * @mtd: MTD device structure
+ * @instr: erase instruction
  *
- * Erase one ore more blocks
+ * Erase one ore more blocks.
  */
 static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
@@ -2505,12 +2501,12 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 #define BBT_PAGE_MASK  0xffffff3f
 /**
- * nand_erase_nand - [Internal] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
- * @allowbbt:  allow erasing the bbt area
+ * nand_erase_nand - [INTERN] erase block(s)
+ * @mtd: MTD device structure
+ * @instr: erase instruction
+ * @allowbbt: allow erasing the bbt area
  *
- * Erase one ore more blocks
+ * Erase one ore more blocks.
  */
 int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                    int allowbbt)
@@ -2521,9 +2517,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        unsigned int bbt_masked_page = 0xffffffff;
        loff_t len;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
-                               __func__, (unsigned long long)instr->addr,
-                               (unsigned long long)instr->len);
+       pr_debug("%s: start = 0x%012llx, len = %llu\n",
+                       __func__, (unsigned long long)instr->addr,
+                       (unsigned long long)instr->len);
 
        if (check_offs_len(mtd, instr->addr, instr->len))
                return -EINVAL;
@@ -2545,8 +2541,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
-                                       __func__);
+               pr_debug("%s: device is write protected!\n",
+                               __func__);
                instr->state = MTD_ERASE_FAILED;
                goto erase_exit;
        }
@@ -2555,7 +2551,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
         * If BBT requires refresh, set the BBT page mask to see if the BBT
         * should be rewritten. Otherwise the mask is set to 0xffffffff which
         * can not be matched. This is also done when the bbt is actually
-        * erased to avoid recusrsive updates
+        * erased to avoid recursive updates.
         */
        if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
                bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2566,20 +2562,18 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        instr->state = MTD_ERASING;
 
        while (len) {
-               /*
-                * heck if we have a bad block, we do not erase bad blocks !
-                */
+               /* Heck if we have a bad block, we do not erase bad blocks! */
                if (nand_block_checkbad(mtd, ((loff_t) page) <<
                                        chip->page_shift, 0, allowbbt)) {
-                       printk(KERN_WARNING "%s: attempt to erase a bad block "
-                                       "at page 0x%08x\n", __func__, page);
+                       pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
+                                   __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
                }
 
                /*
                 * Invalidate the page cache, if we erase the block which
-                * contains the current cached page
+                * contains the current cached page.
                 */
                if (page <= chip->pagebuf && chip->pagebuf <
                    (page + pages_per_block))
@@ -2599,8 +2593,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                /* See if block erase succeeded */
                if (status & NAND_STATUS_FAIL) {
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: Failed erase, "
-                                       "page 0x%08x\n", __func__, page);
+                       pr_debug("%s: failed erase, page 0x%08x\n",
+                                       __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        instr->fail_addr =
                                ((loff_t)page << chip->page_shift);
@@ -2609,7 +2603,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                /*
                 * If BBT requires refresh, set the BBT rewrite flag to the
-                * page being erased
+                * page being erased.
                 */
                if (bbt_masked_page != 0xffffffff &&
                    (page & BBT_PAGE_MASK) == bbt_masked_page)
@@ -2628,7 +2622,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                        /*
                         * If BBT requires refresh and BBT-PERCHIP, set the BBT
-                        * page mask to see if this BBT should be rewritten
+                        * page mask to see if this BBT should be rewritten.
                         */
                        if (bbt_masked_page != 0xffffffff &&
                            (chip->bbt_td->options & NAND_BBT_PERCHIP))
@@ -2651,7 +2645,7 @@ erase_exit:
 
        /*
         * If BBT requires refresh and erase was successful, rewrite any
-        * selected bad block tables
+        * selected bad block tables.
         */
        if (bbt_masked_page == 0xffffffff || ret)
                return ret;
@@ -2659,10 +2653,10 @@ erase_exit:
        for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
                if (!rewrite_bbt[chipnr])
                        continue;
-               /* update the BBT for chip */
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: nand_update_bbt "
-                       "(%d:0x%0llx 0x%0x)\n", __func__, chipnr,
-                       rewrite_bbt[chipnr], chip->bbt_td->pages[chipnr]);
+               /* Update the BBT for chip */
+               pr_debug("%s: nand_update_bbt (%d:0x%0llx 0x%0x)\n",
+                               __func__, chipnr, rewrite_bbt[chipnr],
+                               chip->bbt_td->pages[chipnr]);
                nand_update_bbt(mtd, rewrite_bbt[chipnr]);
        }
 
@@ -2672,15 +2666,15 @@ erase_exit:
 
 /**
  * nand_sync - [MTD Interface] sync
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Sync is actually a wait for chip ready function
+ * Sync is actually a wait for chip ready function.
  */
 static void nand_sync(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__);
+       pr_debug("%s: called\n", __func__);
 
        /* Grab the lock and see if the device is available */
        nand_get_device(chip, mtd, FL_SYNCING);
@@ -2690,8 +2684,8 @@ static void nand_sync(struct mtd_info *mtd)
 
 /**
  * nand_block_isbad - [MTD Interface] Check if block at offset is bad
- * @mtd:       MTD device structure
- * @offs:      offset relative to mtd start
+ * @mtd: MTD device structure
+ * @offs: offset relative to mtd start
  */
 static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
@@ -2704,8 +2698,8 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 
 /**
  * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
- * @mtd:       MTD device structure
- * @ofs:       offset relative to mtd start
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
  */
 static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
@@ -2714,7 +2708,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
        ret = nand_block_isbad(mtd, ofs);
        if (ret) {
-               /* If it was bad already, return success and do nothing. */
+               /* If it was bad already, return success and do nothing */
                if (ret > 0)
                        return 0;
                return ret;
@@ -2725,7 +2719,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
 /**
  * nand_suspend - [MTD Interface] Suspend the NAND flash
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  */
 static int nand_suspend(struct mtd_info *mtd)
 {
@@ -2736,7 +2730,7 @@ static int nand_suspend(struct mtd_info *mtd)
 
 /**
  * nand_resume - [MTD Interface] Resume the NAND flash
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  */
 static void nand_resume(struct mtd_info *mtd)
 {
@@ -2745,13 +2739,11 @@ static void nand_resume(struct mtd_info *mtd)
        if (chip->state == FL_PM_SUSPENDED)
                nand_release_device(mtd);
        else
-               printk(KERN_ERR "%s called for a chip which is not "
-                      "in suspended state\n", __func__);
+               pr_err("%s called for a chip which is not in suspended state\n",
+                       __func__);
 }
 
-/*
- * Set default functions
- */
+/* Set default functions */
 static void nand_set_defaults(struct nand_chip *chip, int busw)
 {
        /* check for proper chip_delay setup, set 20us if not */
@@ -2793,23 +2785,21 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
 
 }
 
-/*
- * sanitize ONFI strings so we can safely print them
- */
+/* Sanitize ONFI strings so we can safely print them */
 static void sanitize_string(uint8_t *s, size_t len)
 {
        ssize_t i;
 
-       /* null terminate */
+       /* Null terminate */
        s[len - 1] = 0;
 
-       /* remove non printable chars */
+       /* Remove non printable chars */
        for (i = 0; i < len - 1; i++) {
                if (s[i] < ' ' || s[i] > 127)
                        s[i] = '?';
        }
 
-       /* remove trailing spaces */
+       /* Remove trailing spaces */
        strim(s);
 }
 
@@ -2826,28 +2816,28 @@ static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
 }
 
 /*
- * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
+ * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
  */
 static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
-                                       int busw)
+                                       int *busw)
 {
        struct nand_onfi_params *p = &chip->onfi_params;
        int i;
        int val;
 
-       /* try ONFI for unknow chip or LP */
+       /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
                chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
                return 0;
 
-       printk(KERN_INFO "ONFI flash detected\n");
+       pr_info("ONFI flash detected\n");
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
                chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
-                       printk(KERN_INFO "ONFI param page %d valid\n", i);
+                       pr_info("ONFI param page %d valid\n", i);
                        break;
                }
        }
@@ -2855,7 +2845,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        if (i == 3)
                return 0;
 
-       /* check version */
+       /* Check version */
        val = le16_to_cpu(p->revision);
        if (val & (1 << 5))
                chip->onfi_version = 23;
@@ -2871,8 +2861,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                chip->onfi_version = 0;
 
        if (!chip->onfi_version) {
-               printk(KERN_INFO "%s: unsupported ONFI version: %d\n",
-                                                               __func__, val);
+               pr_info("%s: unsupported ONFI version: %d\n", __func__, val);
                return 0;
        }
 
@@ -2884,9 +2873,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
        mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
        chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
-       busw = 0;
+       *busw = 0;
        if (le16_to_cpu(p->features) & 1)
-               busw = NAND_BUSWIDTH_16;
+               *busw = NAND_BUSWIDTH_16;
 
        chip->options &= ~NAND_CHIPOPTIONS_MSK;
        chip->options |= (NAND_NO_READRDY |
@@ -2896,7 +2885,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /*
- * Get the flash and manufacturer id and lookup if the type is supported
+ * Get the flash and manufacturer id and lookup if the type is supported.
  */
 static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                                                  struct nand_chip *chip,
@@ -2913,7 +2902,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        /*
         * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
-        * after power-up
+        * after power-up.
         */
        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
 
@@ -2924,7 +2913,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        *maf_id = chip->read_byte(mtd);
        *dev_id = chip->read_byte(mtd);
 
-       /* Try again to make sure, as some systems the bus-hold or other
+       /*
+        * Try again to make sure, as some systems the bus-hold or other
         * interface concerns can cause random data which looks like a
         * possibly credible NAND flash to appear. If the two results do
         * not match, ignore the device completely.
@@ -2936,9 +2926,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                id_data[i] = chip->read_byte(mtd);
 
        if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
-               printk(KERN_INFO "%s: second ID read did not match "
-                      "%02x,%02x against %02x,%02x\n", __func__,
-                      *maf_id, *dev_id, id_data[0], id_data[1]);
+               pr_info("%s: second ID read did not match "
+                       "%02x,%02x against %02x,%02x\n", __func__,
+                       *maf_id, *dev_id, id_data[0], id_data[1]);
                return ERR_PTR(-ENODEV);
        }
 
@@ -2952,7 +2942,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->onfi_version = 0;
        if (!type->name || !type->pagesize) {
                /* Check is chip is ONFI compliant */
-               ret = nand_flash_detect_onfi(mtd, chip, busw);
+               ret = nand_flash_detect_onfi(mtd, chip, &busw);
                if (ret)
                        goto ident_done;
        }
@@ -2973,7 +2963,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->chipsize = (uint64_t)type->chipsize << 20;
 
        if (!type->pagesize && chip->init_size) {
-               /* set the pagesize, oobsize, erasesize by the driver*/
+               /* Set the pagesize, oobsize, erasesize by the driver */
                busw = chip->init_size(mtd, chip, id_data);
        } else if (!type->pagesize) {
                int extid;
@@ -3033,7 +3023,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                }
        } else {
                /*
-                * Old devices have chip data hardcoded in the device id table
+                * Old devices have chip data hardcoded in the device id table.
                 */
                mtd->erasesize = type->erasesize;
                mtd->writesize = type->pagesize;
@@ -3043,7 +3033,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                /*
                 * Check for Spansion/AMD ID + repeating 5th, 6th byte since
                 * some Spansion chips have erasesize that conflicts with size
-                * listed in nand_ids table
+                * listed in nand_ids table.
                 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
                 */
                if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
@@ -3057,15 +3047,16 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->options &= ~NAND_CHIPOPTIONS_MSK;
        chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
 
-       /* Check if chip is a not a samsung device. Do not clear the
-        * options for chips which are not having an extended id.
+       /*
+        * Check if chip is not a Samsung device. Do not clear the
+        * options for chips which do not have an extended id.
         */
        if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
                chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 ident_done:
 
        /*
-        * Set chip as a default. Board drivers can override it, if necessary
+        * Set chip as a default. Board drivers can override it, if necessary.
         */
        chip->options |= NAND_NO_AUTOINCR;
 
@@ -3077,21 +3068,21 @@ ident_done:
 
        /*
         * Check, if buswidth is correct. Hardware drivers should set
-        * chip correct !
+        * chip correct!
         */
        if (busw != (chip->options & NAND_BUSWIDTH_16)) {
-               printk(KERN_INFO "NAND device: Manufacturer ID:"
-                      " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
-                      *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
-               printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
-                      (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
-                      busw ? 16 : 8);
+               pr_info("NAND device: Manufacturer ID:"
+                       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
+                       *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+               pr_warn("NAND bus width %d instead %d bit\n",
+                          (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
+                          busw ? 16 : 8);
                return ERR_PTR(-EINVAL);
        }
 
        /* Calculate the address shift from the page size */
        chip->page_shift = ffs(mtd->writesize) - 1;
-       /* Convert chipsize to number of pages per chip -1. */
+       /* Convert chipsize to number of pages per chip -1 */
        chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
 
        chip->bbt_erase_shift = chip->phys_erase_shift =
@@ -3121,7 +3112,7 @@ ident_done:
        if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                        (*maf_id == NAND_MFR_SAMSUNG ||
                         *maf_id == NAND_MFR_HYNIX))
-               chip->options |= NAND_BBT_SCANLASTPAGE;
+               chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
        else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                                (*maf_id == NAND_MFR_SAMSUNG ||
                                 *maf_id == NAND_MFR_HYNIX ||
@@ -3129,17 +3120,7 @@ ident_done:
                                 *maf_id == NAND_MFR_AMD)) ||
                        (mtd->writesize == 2048 &&
                         *maf_id == NAND_MFR_MICRON))
-               chip->options |= NAND_BBT_SCAN2NDPAGE;
-
-       /*
-        * Numonyx/ST 2K pages, x8 bus use BOTH byte 1 and 6
-        */
-       if (!(busw & NAND_BUSWIDTH_16) &&
-                       *maf_id == NAND_MFR_STMICRO &&
-                       mtd->writesize == 2048) {
-               chip->options |= NAND_BBT_SCANBYTE1AND6;
-               chip->badblockpos = 0;
-       }
+               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
 
        /* Check for AND chips with 4 page planes */
        if (chip->options & NAND_4PAGE_ARRAY)
@@ -3147,12 +3128,11 @@ ident_done:
        else
                chip->erase_cmd = single_erase_cmd;
 
-       /* Do not replace user supplied command function ! */
+       /* Do not replace user supplied command function! */
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
 
-       /* TODO onfi flash name */
-       printk(KERN_INFO "NAND device: Manufacturer ID:"
+       pr_info("NAND device: Manufacturer ID:"
                " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
                nand_manuf_ids[maf_idx].name,
                chip->onfi_version ? chip->onfi_params.model : type->name);
@@ -3162,12 +3142,12 @@ ident_done:
 
 /**
  * nand_scan_ident - [NAND Interface] Scan for the NAND device
- * @mtd:            MTD device structure
- * @maxchips:       Number of chips to scan for
- * @table:          Alternative NAND ID table
+ * @mtd: MTD device structure
+ * @maxchips: number of chips to scan for
+ * @table: alternative NAND ID table
  *
- * This is the first phase of the normal nand_scan() function. It
- * reads the flash ID and sets up MTD fields accordingly.
+ * This is the first phase of the normal nand_scan() function. It reads the
+ * flash ID and sets up MTD fields accordingly.
  *
  * The mtd->owner field must be set to the module of the caller.
  */
@@ -3189,7 +3169,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 
        if (IS_ERR(type)) {
                if (!(chip->options & NAND_SCAN_SILENT_NODEV))
-                       printk(KERN_WARNING "No NAND device found.\n");
+                       pr_warn("No NAND device found\n");
                chip->select_chip(mtd, -1);
                return PTR_ERR(type);
        }
@@ -3207,7 +3187,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                        break;
        }
        if (i > 1)
-               printk(KERN_INFO "%d NAND chips detected\n", i);
+               pr_info("%d NAND chips detected\n", i);
 
        /* Store the number of chips and calc total size for mtd */
        chip->numchips = i;
@@ -3220,11 +3200,11 @@ EXPORT_SYMBOL(nand_scan_ident);
 
 /**
  * nand_scan_tail - [NAND Interface] Scan for the NAND device
- * @mtd:           MTD device structure
+ * @mtd: MTD device structure
  *
- * This is the second phase of the normal nand_scan() function. It
- * fills out all the uninitialized function pointers with the defaults
- * and scans for a bad block table if appropriate.
+ * This is the second phase of the normal nand_scan() function. It fills out
+ * all the uninitialized function pointers with the defaults and scans for a
+ * bad block table if appropriate.
  */
 int nand_scan_tail(struct mtd_info *mtd)
 {
@@ -3240,7 +3220,7 @@ int nand_scan_tail(struct mtd_info *mtd)
        chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
        /*
-        * If no default placement scheme is given, select an appropriate one
+        * If no default placement scheme is given, select an appropriate one.
         */
        if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) {
                switch (mtd->oobsize) {
@@ -3257,8 +3237,8 @@ int nand_scan_tail(struct mtd_info *mtd)
                        chip->ecc.layout = &nand_oob_128;
                        break;
                default:
-                       printk(KERN_WARNING "No oob scheme defined for "
-                              "oobsize %d\n", mtd->oobsize);
+                       pr_warn("No oob scheme defined for oobsize %d\n",
+                                  mtd->oobsize);
                        BUG();
                }
        }
@@ -3267,7 +3247,7 @@ int nand_scan_tail(struct mtd_info *mtd)
                chip->write_page = nand_write_page;
 
        /*
-        * check ECC mode, default to software if 3byte/512byte hardware ECC is
+        * Check ECC mode, default to software if 3byte/512byte hardware ECC is
         * selected and we have 256 byte pagesize fallback to software ECC
         */
 
@@ -3276,15 +3256,15 @@ int nand_scan_tail(struct mtd_info *mtd)
                /* Similar to NAND_ECC_HW, but a separate read_page handle */
                if (!chip->ecc.calculate || !chip->ecc.correct ||
                     !chip->ecc.hwctl) {
-                       printk(KERN_WARNING "No ECC functions supplied; "
-                              "Hardware ECC not possible\n");
+                       pr_warn("No ECC functions supplied; "
+                                  "hardware ECC not possible\n");
                        BUG();
                }
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_hwecc_oob_first;
 
        case NAND_ECC_HW:
-               /* Use standard hwecc read page function ? */
+               /* Use standard hwecc read page function? */
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_hwecc;
                if (!chip->ecc.write_page)
@@ -3305,11 +3285,11 @@ int nand_scan_tail(struct mtd_info *mtd)
                     chip->ecc.read_page == nand_read_page_hwecc ||
                     !chip->ecc.write_page ||
                     chip->ecc.write_page == nand_write_page_hwecc)) {
-                       printk(KERN_WARNING "No ECC functions supplied; "
-                              "Hardware ECC not possible\n");
+                       pr_warn("No ECC functions supplied; "
+                                  "hardware ECC not possible\n");
                        BUG();
                }
-               /* Use standard syndrome read/write page function ? */
+               /* Use standard syndrome read/write page function? */
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_syndrome;
                if (!chip->ecc.write_page)
@@ -3325,9 +3305,9 @@ int nand_scan_tail(struct mtd_info *mtd)
 
                if (mtd->writesize >= chip->ecc.size)
                        break;
-               printk(KERN_WARNING "%d byte HW ECC not possible on "
-                      "%d byte page size, fallback to SW ECC\n",
-                      chip->ecc.size, mtd->writesize);
+               pr_warn("%d byte HW ECC not possible on "
+                          "%d byte page size, fallback to SW ECC\n",
+                          chip->ecc.size, mtd->writesize);
                chip->ecc.mode = NAND_ECC_SOFT;
 
        case NAND_ECC_SOFT:
@@ -3347,7 +3327,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
        case NAND_ECC_SOFT_BCH:
                if (!mtd_nand_has_bch()) {
-                       printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n");
+                       pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
                        BUG();
                }
                chip->ecc.calculate = nand_bch_calculate_ecc;
@@ -3362,8 +3342,8 @@ int nand_scan_tail(struct mtd_info *mtd)
                /*
                 * Board driver should supply ecc.size and ecc.bytes values to
                 * select how many bits are correctable; see nand_bch_init()
-                * for details.
-                * Otherwise, default to 4 bits for large page devices
+                * for details. Otherwise, default to 4 bits for large page
+                * devices.
                 */
                if (!chip->ecc.size && (mtd->oobsize >= 64)) {
                        chip->ecc.size = 512;
@@ -3374,14 +3354,14 @@ int nand_scan_tail(struct mtd_info *mtd)
                                               chip->ecc.bytes,
                                               &chip->ecc.layout);
                if (!chip->ecc.priv) {
-                       printk(KERN_WARNING "BCH ECC initialization failed!\n");
+                       pr_warn("BCH ECC initialization failed!\n");
                        BUG();
                }
                break;
 
        case NAND_ECC_NONE:
-               printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
-                      "This is not recommended !!\n");
+               pr_warn("NAND_ECC_NONE selected by board driver. "
+                          "This is not recommended!\n");
                chip->ecc.read_page = nand_read_page_raw;
                chip->ecc.write_page = nand_write_page_raw;
                chip->ecc.read_oob = nand_read_oob_std;
@@ -3393,14 +3373,13 @@ int nand_scan_tail(struct mtd_info *mtd)
                break;
 
        default:
-               printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
-                      chip->ecc.mode);
+               pr_warn("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode);
                BUG();
        }
 
        /*
         * The number of bytes available for a client to place data into
-        * the out of band area
+        * the out of band area.
         */
        chip->ecc.layout->oobavail = 0;
        for (i = 0; chip->ecc.layout->oobfree[i].length
@@ -3411,19 +3390,16 @@ int nand_scan_tail(struct mtd_info *mtd)
 
        /*
         * Set the number of read / write steps for one page depending on ECC
-        * mode
+        * mode.
         */
        chip->ecc.steps = mtd->writesize / chip->ecc.size;
        if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
-               printk(KERN_WARNING "Invalid ecc parameters\n");
+               pr_warn("Invalid ECC parameters\n");
                BUG();
        }
        chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
 
-       /*
-        * Allow subpage writes up to ecc.steps. Not possible for MLC
-        * FLASH.
-        */
+       /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
        if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
            !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
                switch (chip->ecc.steps) {
@@ -3481,9 +3457,11 @@ int nand_scan_tail(struct mtd_info *mtd)
 }
 EXPORT_SYMBOL(nand_scan_tail);
 
-/* is_module_text_address() isn't exported, and it's mostly a pointless
+/*
+ * is_module_text_address() isn't exported, and it's mostly a pointless
  * test if this is a module _anyway_ -- they'd have to try _really_ hard
- * to call us from in-kernel code if the core NAND support is modular. */
+ * to call us from in-kernel code if the core NAND support is modular.
+ */
 #ifdef MODULE
 #define caller_is_module() (1)
 #else
@@ -3493,15 +3471,13 @@ EXPORT_SYMBOL(nand_scan_tail);
 
 /**
  * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd:       MTD device structure
- * @maxchips:  Number of chips to scan for
- *
- * This fills out all the uninitialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- * The mtd->owner field must be set to the module of the caller
+ * @mtd: MTD device structure
+ * @maxchips: number of chips to scan for
  *
+ * This fills out all the uninitialized function pointers with the defaults.
+ * The flash ID is read and the mtd/chip structures are filled with the
+ * appropriate values. The mtd->owner field must be set to the module of the
+ * caller.
  */
 int nand_scan(struct mtd_info *mtd, int maxchips)
 {
@@ -3509,8 +3485,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
 
        /* Many callers got this wrong, so check for it for a while... */
        if (!mtd->owner && caller_is_module()) {
-               printk(KERN_CRIT "%s called with NULL mtd->owner!\n",
-                               __func__);
+               pr_crit("%s called with NULL mtd->owner!\n", __func__);
                BUG();
        }
 
@@ -3523,8 +3498,8 @@ EXPORT_SYMBOL(nand_scan);
 
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
- * @mtd:       MTD device structure
-*/
+ * @mtd: MTD device structure
+ */
 void nand_release(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
@@ -3538,11 +3513,6 @@ void nand_release(struct mtd_info *mtd)
        kfree(chip->bbt);
        if (!(chip->options & NAND_OWN_BUFFERS))
                kfree(chip->buffers);
-
-       /* Free bad block descriptor memory */
-       if (chip->badblock_pattern && chip->badblock_pattern->options
-                       & NAND_BBT_DYNAMICSTRUCT)
-               kfree(chip->badblock_pattern);
 }
 EXPORT_SYMBOL_GPL(nand_release);
 
index ccbeaa1e4a8ed42ccddac88f2780915dc3407736..6aa8125772b8c69c723915545872cace25a1de30 100644 (file)
@@ -14,7 +14,7 @@
  *
  * When nand_scan_bbt is called, then it tries to find the bad block table
  * depending on the options in the BBT descriptor(s). If no flash based BBT
- * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
+ * (NAND_BBT_USE_FLASH) is specified then the device is scanned for factory
  * marked good / bad blocks. This information is used to create a memory BBT.
  * Once a new bad block is discovered then the "factory" information is updated
  * on the device.
@@ -36,9 +36,9 @@
  * The table is marked in the OOB area with an ident pattern and a version
  * number which indicates which of both tables is more up to date. If the NAND
  * controller needs the complete OOB area for the ECC information then the
- * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
- * and the version byte into the data area and the OOB area will remain
- * untouched.
+ * option NAND_BBT_NO_OOB should be used (along with NAND_BBT_USE_FLASH, of
+ * course): it moves the ident pattern and the version byte into the data area
+ * and the OOB area will remain untouched.
  *
  * The table uses 2 bits per block
  * 11b:                block is good
@@ -80,17 +80,15 @@ static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
 
 /**
  * check_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @len:       the length of buffer to search
- * @paglen:    the pagelength
- * @td:                search pattern descriptor
+ * @buf: the buffer to search
+ * @len: the length of buffer to search
+ * @paglen: the pagelength
+ * @td: search pattern descriptor
  *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers.
- * If the SCAN_EMPTY option is set then check, if all bytes except the
- * pattern area contain 0xff
- *
-*/
+ * Check for a pattern at the given place. Used to search bad block tables and
+ * good / bad block identifiers. If the SCAN_EMPTY option is set then check, if
+ * all bytes except the pattern area contain 0xff.
+ */
 static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
 {
        int i, end = 0;
@@ -114,28 +112,6 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
                        return -1;
        }
 
-       /* Check both positions 1 and 6 for pattern? */
-       if (td->options & NAND_BBT_SCANBYTE1AND6) {
-               if (td->options & NAND_BBT_SCANEMPTY) {
-                       p += td->len;
-                       end += NAND_SMALL_BADBLOCK_POS - td->offs;
-                       /* Check region between positions 1 and 6 */
-                       for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len;
-                                       i++) {
-                               if (*p++ != 0xff)
-                                       return -1;
-                       }
-               }
-               else {
-                       p += NAND_SMALL_BADBLOCK_POS - td->offs;
-               }
-               /* Compare the pattern */
-               for (i = 0; i < td->len; i++) {
-                       if (p[i] != td->pattern[i])
-                               return -1;
-               }
-       }
-
        if (td->options & NAND_BBT_SCANEMPTY) {
                p += td->len;
                end += td->len;
@@ -149,14 +125,13 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
 
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @td:                search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers. Same as check_pattern, but
- * no optional empty check
+ * @buf: the buffer to search
+ * @td:        search pattern descriptor
  *
-*/
+ * Check for a pattern at the given place. Used to search bad block tables and
+ * good / bad block identifiers. Same as check_pattern, but no optional empty
+ * check.
+ */
 static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
 {
        int i;
@@ -167,21 +142,14 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
                if (p[td->offs + i] != td->pattern[i])
                        return -1;
        }
-       /* Need to check location 1 AND 6? */
-       if (td->options & NAND_BBT_SCANBYTE1AND6) {
-               for (i = 0; i < td->len; i++) {
-                       if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i])
-                               return -1;
-               }
-       }
        return 0;
 }
 
 /**
  * add_marker_len - compute the length of the marker in data area
- * @td:                BBT descriptor used for computation
+ * @td: BBT descriptor used for computation
  *
- * The length will be 0 if the markeris located in OOB area.
+ * The length will be 0 if the marker is located in OOB area.
  */
 static u32 add_marker_len(struct nand_bbt_descr *td)
 {
@@ -198,15 +166,14 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @page:      the starting page
- * @num:       the number of bbt descriptors to read
- * @td:                the bbt describtion table
- * @offs:      offset in the memory table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @page: the starting page
+ * @num: the number of bbt descriptors to read
+ * @td: the bbt describtion table
+ * @offs: offset in the memory table
  *
  * Read the bad block table starting from page.
- *
  */
 static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                struct nand_bbt_descr *td, int offs)
@@ -238,10 +205,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                res = mtd->read(mtd, from, len, &retlen, buf);
                if (res < 0) {
                        if (retlen != len) {
-                               printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
+                               pr_info("nand_bbt: error reading bad block table\n");
                                return res;
                        }
-                       printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
+                       pr_warn("nand_bbt: ECC error while reading bad block table\n");
                }
 
                /* Analyse data */
@@ -252,17 +219,19 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                                if (tmp == msk)
                                        continue;
                                if (reserved_block_code && (tmp == reserved_block_code)) {
-                                       printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n",
-                                              (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                                       pr_info("nand_read_bbt: reserved block at 0x%012llx\n",
+                                                (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
                                        this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
                                        mtd->ecc_stats.bbtblocks++;
                                        continue;
                                }
-                               /* Leave it for now, if its matured we can move this
-                                * message to MTD_DEBUG_LEVEL0 */
-                               printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n",
-                                      (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
-                               /* Factory marked bad or worn out ? */
+                               /*
+                                * Leave it for now, if it's matured we can
+                                * move this message to pr_debug.
+                                */
+                               pr_info("nand_read_bbt: bad block at 0x%012llx\n",
+                                        (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                               /* Factory marked bad or worn out? */
                                if (tmp == 0)
                                        this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
                                else
@@ -278,15 +247,15 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 
 /**
  * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @chip:      read the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @chip: read the table for a specific chip, -1 read all chips; aplies only if
+ *        NAND_BBT_PERCHIP option is set
  *
- * Read the bad block table for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
-*/
+ * Read the bad block table for all chips starting at a given page. We assume
+ * that the bbt bits are in consecutive order.
+ */
 static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
 {
        struct nand_chip *this = mtd->priv;
@@ -312,9 +281,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
        return 0;
 }
 
-/*
- * BBT marker is in the first page, no OOB.
- */
+/* BBT marker is in the first page, no OOB */
 static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         struct nand_bbt_descr *td)
 {
@@ -328,9 +295,7 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
        return mtd->read(mtd, offs, len, &retlen, buf);
 }
 
-/*
- * Scan read raw data from flash
- */
+/* Scan read raw data from flash */
 static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         size_t len)
 {
@@ -347,14 +312,20 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                        ops.oobbuf = buf + len;
                        ops.datbuf = buf;
                        ops.len = len;
-                       return mtd->read_oob(mtd, offs, &ops);
+                       res = mtd->read_oob(mtd, offs, &ops);
+
+                       /* Ignore ECC errors when checking for BBM */
+                       if (res != -EUCLEAN && res != -EBADMSG)
+                               return res;
+                       return 0;
                } else {
                        ops.oobbuf = buf + mtd->writesize;
                        ops.datbuf = buf;
                        ops.len = mtd->writesize;
                        res = mtd->read_oob(mtd, offs, &ops);
 
-                       if (res)
+                       /* Ignore ECC errors when checking for BBM */
+                       if (res && res != -EUCLEAN && res != -EBADMSG)
                                return res;
                }
 
@@ -373,9 +344,7 @@ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                return scan_read_raw_oob(mtd, buf, offs, len);
 }
 
-/*
- * Scan write data with oob to flash
- */
+/* Scan write data with oob to flash */
 static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
                          uint8_t *buf, uint8_t *oob)
 {
@@ -402,15 +371,14 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
 
 /**
  * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md:        descriptor for the bad block table mirror
  *
- * Read the bad block table(s) for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
- *
-*/
+ * Read the bad block table(s) for all chips starting at a given page. We
+ * assume that the bbt bits are in consecutive order.
+ */
 static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                         struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
@@ -421,8 +389,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
                              mtd->writesize, td);
                td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
-               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
-                      td->pages[0], td->version[0]);
+               pr_info("Bad block table at page %d, version 0x%02X\n",
+                        td->pages[0], td->version[0]);
        }
 
        /* Read the mirror version, if available */
@@ -430,15 +398,13 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
                              mtd->writesize, td);
                md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
-               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
-                      md->pages[0], md->version[0]);
+               pr_info("Bad block table at page %d, version 0x%02X\n",
+                        md->pages[0], md->version[0]);
        }
        return 1;
 }
 
-/*
- * Scan a given block full
- */
+/* Scan a given block full */
 static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
                           loff_t offs, uint8_t *buf, size_t readlen,
                           int scanlen, int len)
@@ -456,9 +422,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
        return 0;
 }
 
-/*
- * Scan a given block partially
- */
+/* Scan a given block partially */
 static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
                           loff_t offs, uint8_t *buf, int len)
 {
@@ -473,12 +437,12 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 
        for (j = 0; j < len; j++) {
                /*
-                * Read the full oob until read_oob is fixed to
-                * handle single byte reads for 16 bit
-                * buswidth
+                * Read the full oob until read_oob is fixed to handle single
+                * byte reads for 16 bit buswidth.
                 */
                ret = mtd->read_oob(mtd, offs, &ops);
-               if (ret)
+               /* Ignore ECC errors when checking for BBM */
+               if (ret && ret != -EUCLEAN && ret != -EBADMSG)
                        return ret;
 
                if (check_short_pattern(buf, bd))
@@ -491,14 +455,14 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
- * @chip:      create the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @bd: descriptor for the good/bad block search pattern
+ * @chip: create the table for a specific chip, -1 read all chips; applies only
+ *        if NAND_BBT_PERCHIP option is set
  *
- * Create a bad block table by scanning the device
- * for the given good/bad block identify pattern
+ * Create a bad block table by scanning the device for the given good/bad block
+ * identify pattern.
  */
 static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        struct nand_bbt_descr *bd, int chip)
@@ -509,7 +473,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        loff_t from;
        size_t readlen;
 
-       printk(KERN_INFO "Scanning device for bad blocks\n");
+       pr_info("Scanning device for bad blocks\n");
 
        if (bd->options & NAND_BBT_SCANALLPAGES)
                len = 1 << (this->bbt_erase_shift - this->page_shift);
@@ -529,14 +493,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        }
 
        if (chip == -1) {
-               /* Note that numblocks is 2 * (real numblocks) here, see i+=2
-                * below as it makes shifting and masking less painful */
+               /*
+                * Note that numblocks is 2 * (real numblocks) here, see i+=2
+                * below as it makes shifting and masking less painful
+                */
                numblocks = mtd->size >> (this->bbt_erase_shift - 1);
                startblock = 0;
                from = 0;
        } else {
                if (chip >= this->numchips) {
-                       printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
+                       pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n",
                               chip + 1, this->numchips);
                        return -EINVAL;
                }
@@ -546,7 +512,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
                from = (loff_t)startblock << (this->bbt_erase_shift - 1);
        }
 
-       if (this->options & NAND_BBT_SCANLASTPAGE)
+       if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
                from += mtd->erasesize - (mtd->writesize * len);
 
        for (i = startblock; i < numblocks;) {
@@ -565,8 +531,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
                if (ret) {
                        this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                       printk(KERN_WARNING "Bad eraseblock %d at 0x%012llx\n",
-                              i >> 1, (unsigned long long)from);
+                       pr_warn("Bad eraseblock %d at 0x%012llx\n",
+                               i >> 1, (unsigned long long)from);
                        mtd->ecc_stats.badblocks++;
                }
 
@@ -578,20 +544,18 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 /**
  * search_bbt - [GENERIC] scan the device for a specific bad block table
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
  *
- * Read the bad block table by searching for a given ident pattern.
- * Search is preformed either from the beginning up or from the end of
- * the device downwards. The search starts always at the start of a
- * block.
- * If the option NAND_BBT_PERCHIP is given, each chip is searched
- * for a bbt, which contains the bad block information of this chip.
- * This is necessary to provide support for certain DOC devices.
+ * Read the bad block table by searching for a given ident pattern. Search is
+ * preformed either from the beginning up or from the end of the device
+ * downwards. The search starts always at the start of a block. If the option
+ * NAND_BBT_PERCHIP is given, each chip is searched for a bbt, which contains
+ * the bad block information of this chip. This is necessary to provide support
+ * for certain DOC devices.
  *
- * The bbt ident pattern resides in the oob area of the first page
- * in a block.
+ * The bbt ident pattern resides in the oob area of the first page in a block.
  */
 static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
 {
@@ -602,7 +566,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        int bbtblocks;
        int blocktopage = this->bbt_erase_shift - this->page_shift;
 
-       /* Search direction top -> down ? */
+       /* Search direction top -> down? */
        if (td->options & NAND_BBT_LASTBLOCK) {
                startblock = (mtd->size >> this->bbt_erase_shift) - 1;
                dir = -1;
@@ -611,7 +575,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                dir = 1;
        }
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chips = this->numchips;
                bbtblocks = this->chipsize >> this->bbt_erase_shift;
@@ -650,23 +614,23 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        /* Check, if we found a bbt for each requested chip */
        for (i = 0; i < chips; i++) {
                if (td->pages[i] == -1)
-                       printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
+                       pr_warn("Bad block table not found for chip %d\n", i);
                else
-                       printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
-                              td->version[i]);
+                       pr_info("Bad block table found at page %d, version "
+                                "0x%02X\n", td->pages[i], td->version[i]);
        }
        return 0;
 }
 
 /**
  * search_read_bbts - [GENERIC] scan the device for bad block table(s)
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md: descriptor for the bad block table mirror
  *
- * Search and read the bad block table(s)
-*/
+ * Search and read the bad block table(s).
+ */
 static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
        /* Search the primary table */
@@ -682,16 +646,14 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
 
 /**
  * write_bbt - [GENERIC] (Re)write the bad block table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md: descriptor for the bad block table mirror
+ * @chipsel: selector for a specific chip, -1 for all
  *
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- * @chipsel:   selector for a specific chip, -1 for all
- *
- * (Re)write the bad block table
- *
-*/
+ * (Re)write the bad block table.
+ */
 static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
                     int chipsel)
@@ -714,10 +676,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
        if (!rcode)
                rcode = 0xff;
-       /* Write bad block table per chip rather than per device ? */
+       /* Write bad block table per chip rather than per device? */
        if (td->options & NAND_BBT_PERCHIP) {
                numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
-               /* Full device write or specific chip ? */
+               /* Full device write or specific chip? */
                if (chipsel == -1) {
                        nrchips = this->numchips;
                } else {
@@ -731,8 +693,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
        /* Loop through the chips */
        for (; chip < nrchips; chip++) {
-
-               /* There was already a version of the table, reuse the page
+               /*
+                * There was already a version of the table, reuse the page
                 * This applies for absolute placement too, as we have the
                 * page nr. in td->pages.
                 */
@@ -741,8 +703,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        goto write;
                }
 
-               /* Automatic placement of the bad block table */
-               /* Search direction top -> down ? */
+               /*
+                * Automatic placement of the bad block table. Search direction
+                * top -> down?
+                */
                if (td->options & NAND_BBT_LASTBLOCK) {
                        startblock = numblocks * (chip + 1) - 1;
                        dir = -1;
@@ -766,7 +730,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        if (!md || md->pages[chip] != page)
                                goto write;
                }
-               printk(KERN_ERR "No space left to write bad block table\n");
+               pr_err("No space left to write bad block table\n");
                return -ENOSPC;
        write:
 
@@ -793,7 +757,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
                to = ((loff_t) page) << this->page_shift;
 
-               /* Must we save the block contents ? */
+               /* Must we save the block contents? */
                if (td->options & NAND_BBT_SAVECONTENT) {
                        /* Make it block aligned */
                        to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
@@ -801,14 +765,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        res = mtd->read(mtd, to, len, &retlen, buf);
                        if (res < 0) {
                                if (retlen != len) {
-                                       printk(KERN_INFO "nand_bbt: Error "
-                                              "reading block for writing "
-                                              "the bad block table\n");
+                                       pr_info("nand_bbt: error reading block "
+                                               "for writing the bad block table\n");
                                        return res;
                                }
-                               printk(KERN_WARNING "nand_bbt: ECC error "
-                                      "while reading block for writing "
-                                      "bad block table\n");
+                               pr_warn("nand_bbt: ECC error while reading "
+                                       "block for writing bad block table\n");
                        }
                        /* Read oob data */
                        ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
@@ -827,13 +789,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                } else if (td->options & NAND_BBT_NO_OOB) {
                        ooboffs = 0;
                        offs = td->len;
-                       /* the version byte */
+                       /* The version byte */
                        if (td->options & NAND_BBT_VERSION)
                                offs++;
                        /* Calc length */
                        len = (size_t) (numblocks >> sft);
                        len += offs;
-                       /* Make it page aligned ! */
+                       /* Make it page aligned! */
                        len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len);
@@ -842,7 +804,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                } else {
                        /* Calc length */
                        len = (size_t) (numblocks >> sft);
-                       /* Make it page aligned ! */
+                       /* Make it page aligned! */
                        len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len +
@@ -856,13 +818,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (td->options & NAND_BBT_VERSION)
                        buf[ooboffs + td->veroffs] = td->version[chip];
 
-               /* walk through the memory table */
+               /* Walk through the memory table */
                for (i = 0; i < numblocks;) {
                        uint8_t dat;
                        dat = this->bbt[bbtoffs + (i >> 2)];
                        for (j = 0; j < 4; j++, i++) {
                                int sftcnt = (i << (3 - sft)) & sftmsk;
-                               /* Do not store the reserved bbt blocks ! */
+                               /* Do not store the reserved bbt blocks! */
                                buf[offs + (i >> sft)] &=
                                        ~(msk[dat & 0x03] << sftcnt);
                                dat >>= 2;
@@ -883,8 +845,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (res < 0)
                        goto outerr;
 
-               printk(KERN_DEBUG "Bad block table written to 0x%012llx, version "
-                      "0x%02X\n", (unsigned long long)to, td->version[chip]);
+               pr_info("Bad block table written to 0x%012llx, version 0x%02X\n",
+                        (unsigned long long)to, td->version[chip]);
 
                /* Mark it as used */
                td->pages[chip] = page;
@@ -892,19 +854,18 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
        return 0;
 
  outerr:
-       printk(KERN_WARNING
-              "nand_bbt: Error while writing bad block table %d\n", res);
+       pr_warn("nand_bbt: error while writing bad block table %d\n", res);
        return res;
 }
 
 /**
  * nand_memory_bbt - [GENERIC] create a memory based bad block table
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
+ * @mtd: MTD device structure
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The function creates a memory based bbt by scanning the device
- * for manufacturer / software marked good / bad blocks
-*/
+ * The function creates a memory based bbt by scanning the device for
+ * manufacturer / software marked good / bad blocks.
+ */
 static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
@@ -915,16 +876,15 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
 
 /**
  * check_create - [GENERIC] create and write bbt(s) if necessary
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The function checks the results of the previous call to read_bbt
- * and creates / updates the bbt(s) if necessary
- * Creation is necessary if no bbt was found for the chip/device
- * Update is necessary if one of the tables is missing or the
- * version nr. of one table is less than the other
-*/
+ * The function checks the results of the previous call to read_bbt and creates
+ * / updates the bbt(s) if necessary. Creation is necessary if no bbt was found
+ * for the chip/device. Update is necessary if one of the tables is missing or
+ * the version nr. of one table is less than the other.
+ */
 static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
 {
        int i, chips, writeops, chipsel, res;
@@ -933,7 +893,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
        struct nand_bbt_descr *md = this->bbt_md;
        struct nand_bbt_descr *rd, *rd2;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP)
                chips = this->numchips;
        else
@@ -943,9 +903,9 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
                writeops = 0;
                rd = NULL;
                rd2 = NULL;
-               /* Per chip or per device ? */
+               /* Per chip or per device? */
                chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
-               /* Mirrored table available ? */
+               /* Mirrored table available? */
                if (md) {
                        if (td->pages[i] == -1 && md->pages[i] == -1) {
                                writeops = 0x03;
@@ -994,33 +954,33 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
                        goto writecheck;
                }
        create:
-               /* Create the bad block table by scanning the device ? */
+               /* Create the bad block table by scanning the device? */
                if (!(td->options & NAND_BBT_CREATE))
                        continue;
 
                /* Create the table in memory by scanning the chip(s) */
-               if (!(this->options & NAND_CREATE_EMPTY_BBT))
+               if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY))
                        create_bbt(mtd, buf, bd, chipsel);
 
                td->version[i] = 1;
                if (md)
                        md->version[i] = 1;
        writecheck:
-               /* read back first ? */
+               /* Read back first? */
                if (rd)
                        read_abs_bbt(mtd, buf, rd, chipsel);
-               /* If they weren't versioned, read both. */
+               /* If they weren't versioned, read both */
                if (rd2)
                        read_abs_bbt(mtd, buf, rd2, chipsel);
 
-               /* Write the bad block table to the device ? */
+               /* Write the bad block table to the device? */
                if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
                        res = write_bbt(mtd, buf, td, md, chipsel);
                        if (res < 0)
                                return res;
                }
 
-               /* Write the mirror bad block table to the device ? */
+               /* Write the mirror bad block table to the device? */
                if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
                        res = write_bbt(mtd, buf, md, td, chipsel);
                        if (res < 0)
@@ -1032,20 +992,19 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 
 /**
  * mark_bbt_regions - [GENERIC] mark the bad block table regions
- * @mtd:       MTD device structure
- * @td:                bad block table descriptor
+ * @mtd: MTD device structure
+ * @td: bad block table descriptor
  *
- * The bad block table regions are marked as "bad" to prevent
- * accidental erasures / writes. The regions are identified by
- * the mark 0x02.
-*/
+ * The bad block table regions are marked as "bad" to prevent accidental
+ * erasures / writes. The regions are identified by the mark 0x02.
+ */
 static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 {
        struct nand_chip *this = mtd->priv;
        int i, j, chips, block, nrblocks, update;
        uint8_t oldval, newval;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chips = this->numchips;
                nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
@@ -1082,9 +1041,11 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
                                update = 1;
                        block += 2;
                }
-               /* If we want reserved blocks to be recorded to flash, and some
-                  new ones have been marked, then we need to update the stored
-                  bbts.  This should only happen once. */
+               /*
+                * If we want reserved blocks to be recorded to flash, and some
+                * new ones have been marked, then we need to update the stored
+                * bbts.  This should only happen once.
+                */
                if (update && td->reserved_block_code)
                        nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1));
        }
@@ -1092,8 +1053,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 
 /**
  * verify_bbt_descr - verify the bad block description
- * @mtd:       MTD device structure
- * @bd:                the table to verify
+ * @mtd: MTD device structure
+ * @bd: the table to verify
  *
  * This functions performs a few sanity checks on the bad block description
  * table.
@@ -1111,16 +1072,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        pattern_len = bd->len;
        bits = bd->options & NAND_BBT_NRBITS_MSK;
 
-       BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
-                       !(this->options & NAND_USE_FLASH_BBT));
+       BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) &&
+                       !(this->bbt_options & NAND_BBT_USE_FLASH));
        BUG_ON(!bits);
 
        if (bd->options & NAND_BBT_VERSION)
                pattern_len++;
 
        if (bd->options & NAND_BBT_NO_OOB) {
-               BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
-               BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
+               BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH));
+               BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB));
                BUG_ON(bd->offs);
                if (bd->options & NAND_BBT_VERSION)
                        BUG_ON(bd->veroffs != bd->len);
@@ -1140,18 +1101,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
 /**
  * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
- *
- * The function checks, if a bad block table(s) is/are already
- * available. If not it scans the device for manufacturer
- * marked good / bad blocks and writes the bad block table(s) to
- * the selected place.
+ * @mtd: MTD device structure
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The bad block table memory is allocated here. It must be freed
- * by calling the nand_free_bbt function.
+ * The function checks, if a bad block table(s) is/are already available. If
+ * not it scans the device for manufacturer marked good / bad blocks and writes
+ * the bad block table(s) to the selected place.
  *
-*/
+ * The bad block table memory is allocated here. It must be freed by calling
+ * the nand_free_bbt function.
+ */
 int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
@@ -1161,19 +1120,21 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        struct nand_bbt_descr *md = this->bbt_md;
 
        len = mtd->size >> (this->bbt_erase_shift + 2);
-       /* Allocate memory (2bit per block) and clear the memory bad block table */
+       /*
+        * Allocate memory (2bit per block) and clear the memory bad block
+        * table.
+        */
        this->bbt = kzalloc(len, GFP_KERNEL);
-       if (!this->bbt) {
-               printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
+       if (!this->bbt)
                return -ENOMEM;
-       }
 
-       /* If no primary table decriptor is given, scan the device
-        * to build a memory based bad block table
+       /*
+        * If no primary table decriptor is given, scan the device to build a
+        * memory based bad block table.
         */
        if (!td) {
                if ((res = nand_memory_bbt(mtd, bd))) {
-                       printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
+                       pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
                        kfree(this->bbt);
                        this->bbt = NULL;
                }
@@ -1187,13 +1148,12 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = vmalloc(len);
        if (!buf) {
-               printk(KERN_ERR "nand_bbt: Out of memory\n");
                kfree(this->bbt);
                this->bbt = NULL;
                return -ENOMEM;
        }
 
-       /* Is the bbt at a given page ? */
+       /* Is the bbt at a given page? */
        if (td->options & NAND_BBT_ABSPAGE) {
                res = read_abs_bbts(mtd, buf, td, md);
        } else {
@@ -1215,11 +1175,11 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
 /**
  * nand_update_bbt - [NAND Interface] update bad block table(s)
- * @mtd:       MTD device structure
- * @offs:      the offset of the newly marked block
+ * @mtd: MTD device structure
+ * @offs: the offset of the newly marked block
  *
- * The function updates the bad block table(s)
-*/
+ * The function updates the bad block table(s).
+ */
 int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 {
        struct nand_chip *this = mtd->priv;
@@ -1236,14 +1196,12 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        len = (1 << this->bbt_erase_shift);
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = kmalloc(len, GFP_KERNEL);
-       if (!buf) {
-               printk(KERN_ERR "nand_update_bbt: Out of memory\n");
+       if (!buf)
                return -ENOMEM;
-       }
 
        writeops = md != NULL ? 0x03 : 0x01;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chip = (int)(offs >> this->chip_shift);
                chipsel = chip;
@@ -1256,13 +1214,13 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        if (md)
                md->version[chip]++;
 
-       /* Write the bad block table to the device ? */
+       /* Write the bad block table to the device? */
        if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
                res = write_bbt(mtd, buf, td, md, chipsel);
                if (res < 0)
                        goto out;
        }
-       /* Write the mirror bad block table to the device ? */
+       /* Write the mirror bad block table to the device? */
        if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
                res = write_bbt(mtd, buf, md, td, chipsel);
        }
@@ -1272,8 +1230,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        return res;
 }
 
-/* Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks. */
+/*
+ * Define some generic bad / good block scan pattern which are used
+ * while scanning a device for factory marked good / bad blocks.
+ */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
 static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
@@ -1285,8 +1245,7 @@ static struct nand_bbt_descr agand_flashbased = {
        .pattern = scan_agand_pattern
 };
 
-/* Generic flash bbt decriptors
-*/
+/* Generic flash bbt descriptors */
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
 static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
 
@@ -1330,31 +1289,26 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
        .pattern = mirror_pattern
 };
 
-#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
-               NAND_BBT_SCANBYTE1AND6)
 /**
- * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
- * @this:      NAND chip to create descriptor for
+ * nand_create_default_bbt_descr - [INTERN] Creates a BBT descriptor structure
+ * @this: NAND chip to create descriptor for
  *
  * This function allocates and initializes a nand_bbt_descr for BBM detection
  * based on the properties of "this". The new descriptor is stored in
  * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
  * passed to this function.
- *
  */
 static int nand_create_default_bbt_descr(struct nand_chip *this)
 {
        struct nand_bbt_descr *bd;
        if (this->badblock_pattern) {
-               printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
+               pr_warn("BBT descr already allocated; not replacing\n");
                return -EINVAL;
        }
        bd = kzalloc(sizeof(*bd), GFP_KERNEL);
-       if (!bd) {
-               printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
+       if (!bd)
                return -ENOMEM;
-       }
-       bd->options = this->options & BBT_SCAN_OPTIONS;
+       bd->options = this->bbt_options;
        bd->offs = this->badblockpos;
        bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
        bd->pattern = scan_ff_pattern;
@@ -1365,22 +1319,20 @@ static int nand_create_default_bbt_descr(struct nand_chip *this)
 
 /**
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
- * @mtd:       MTD device structure
- *
- * This function selects the default bad block table
- * support for the device and calls the nand_scan_bbt function
+ * @mtd: MTD device structure
  *
-*/
+ * This function selects the default bad block table support for the device and
+ * calls the nand_scan_bbt function.
+ */
 int nand_default_bbt(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
-       /* Default for AG-AND. We must use a flash based
-        * bad block table as the devices have factory marked
-        * _good_ blocks. Erasing those blocks leads to loss
-        * of the good / bad information, so we _must_ store
-        * this information in a good / bad table during
-        * startup
+       /*
+        * Default for AG-AND. We must use a flash based bad block table as the
+        * devices have factory marked _good_ blocks. Erasing those blocks
+        * leads to loss of the good / bad information, so we _must_ store this
+        * information in a good / bad table during startup.
         */
        if (this->options & NAND_IS_AND) {
                /* Use the default pattern descriptors */
@@ -1388,15 +1340,15 @@ int nand_default_bbt(struct mtd_info *mtd)
                        this->bbt_td = &bbt_main_descr;
                        this->bbt_md = &bbt_mirror_descr;
                }
-               this->options |= NAND_USE_FLASH_BBT;
+               this->bbt_options |= NAND_BBT_USE_FLASH;
                return nand_scan_bbt(mtd, &agand_flashbased);
        }
 
-       /* Is a flash based bad block table requested ? */
-       if (this->options & NAND_USE_FLASH_BBT) {
+       /* Is a flash based bad block table requested? */
+       if (this->bbt_options & NAND_BBT_USE_FLASH) {
                /* Use the default pattern descriptors */
                if (!this->bbt_td) {
-                       if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
+                       if (this->bbt_options & NAND_BBT_NO_OOB) {
                                this->bbt_td = &bbt_main_no_bbt_descr;
                                this->bbt_md = &bbt_mirror_no_bbt_descr;
                        } else {
@@ -1417,11 +1369,10 @@ int nand_default_bbt(struct mtd_info *mtd)
 
 /**
  * nand_isbad_bbt - [NAND Interface] Check if a block is bad
- * @mtd:       MTD device structure
- * @offs:      offset in the device
- * @allowbbt:  allow access to bad block table region
- *
-*/
+ * @mtd: MTD device structure
+ * @offs: offset in the device
+ * @allowbbt: allow access to bad block table region
+ */
 int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
 {
        struct nand_chip *this = mtd->priv;
@@ -1432,8 +1383,9 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
        block = (int)(offs >> (this->bbt_erase_shift - 1));
        res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
-             (unsigned int)offs, block >> 1, res);
+       pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: "
+                       "(block %d) 0x%02x\n",
+                       (unsigned int)offs, block >> 1, res);
 
        switch ((int)res) {
        case 0x00:
index 0f931e757116fa73b904c2783e46c29cc5a1312b..3803e0bba23be42444b8ab229052478a21bccabd 100644 (file)
@@ -93,8 +93,8 @@ int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
                                buf[errloc[i] >> 3] ^= (1 << (errloc[i] & 7));
                        /* else error in ecc, no action needed */
 
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: corrected bitflip %u\n",
-                             __func__, errloc[i]);
+                       pr_debug("%s: corrected bitflip %u\n", __func__,
+                                       errloc[i]);
                }
        } else if (count < 0) {
                printk(KERN_ERR "ecc unrecoverable error\n");
index 271b8e735e8fa1ea21f64a0751d5ab94e147c398..b7cfe0d37121c8bdf78e5147f1cbed41c90b2f0c 100644 (file)
@@ -110,7 +110,7 @@ static const char bitsperbyte[256] = {
 
 /*
  * addressbits is a lookup table to filter out the bits from the xor-ed
- * ecc data that identify the faulty location.
+ * ECC data that identify the faulty location.
  * this is only used for repairing parity
  * see the comments in nand_correct_data for more details
  */
@@ -153,7 +153,7 @@ static const char addressbits[256] = {
  * __nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
  *                      block
  * @buf:       input buffer with raw data
- * @eccsize:   data bytes per ecc step (256 or 512)
+ * @eccsize:   data bytes per ECC step (256 or 512)
  * @code:      output buffer with ECC
  */
 void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
@@ -348,7 +348,7 @@ void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
                rp17 = (par ^ rp16) & 0xff;
 
        /*
-        * Finally calculate the ecc bits.
+        * Finally calculate the ECC bits.
         * Again here it might seem that there are performance optimisations
         * possible, but benchmarks showed that on the system this is developed
         * the code below is the fastest
@@ -436,7 +436,7 @@ EXPORT_SYMBOL(nand_calculate_ecc);
  * @buf:       raw data read from the chip
  * @read_ecc:  ECC from the chip
  * @calc_ecc:  the ECC calculated from raw data
- * @eccsize:   data bytes per ecc step (256 or 512)
+ * @eccsize:   data bytes per ECC step (256 or 512)
  *
  * Detect and correct a 1 bit error for eccsize byte block
  */
@@ -505,7 +505,7 @@ int __nand_correct_data(unsigned char *buf,
        }
        /* count nr of bits; use table lookup, faster than calculating it */
        if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
-               return 1;       /* error in ecc data; no action needed */
+               return 1;       /* error in ECC data; no action needed */
 
        printk(KERN_ERR "uncorrectable error : ");
        return -1;
index 357e8c5252a8c38df3d8ba3885a7fc948b34303c..34c03be7730105c3a26867637700f8c0ade83219 100644 (file)
@@ -2273,9 +2273,9 @@ static int __init ns_init_module(void)
 
        switch (bbt) {
        case 2:
-                chip->options |= NAND_USE_FLASH_BBT_NO_OOB;
+                chip->bbt_options |= NAND_BBT_NO_OOB;
        case 1:
-                chip->options |= NAND_USE_FLASH_BBT;
+                chip->bbt_options |= NAND_BBT_USE_FLASH;
        case 0:
                break;
        default:
index ea2dea8a9c88b6f72e8b59fcd724b085617abfca..ee1713907b92b0684a64de524ca564214699f705 100644 (file)
@@ -42,7 +42,6 @@ struct ndfc_controller {
        struct nand_chip chip;
        int chip_select;
        struct nand_hw_control ndfc_control;
-       struct mtd_partition *parts;
 };
 
 static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];
@@ -159,13 +158,9 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 static int ndfc_chip_init(struct ndfc_controller *ndfc,
                          struct device_node *node)
 {
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       static const char *part_types[] = { "cmdlinepart", NULL };
-#else
-       static const char *part_types[] = { NULL };
-#endif
        struct device_node *flash_np;
        struct nand_chip *chip = &ndfc->chip;
+       struct mtd_part_parser_data ppdata;
        int ret;
 
        chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
@@ -193,6 +188,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
        if (!flash_np)
                return -ENODEV;
 
+       ppdata->of_node = flash_np;
        ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
                        dev_name(&ndfc->ofdev->dev), flash_np->name);
        if (!ndfc->mtd.name) {
@@ -204,18 +200,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
        if (ret)
                goto err;
 
-       ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0);
-       if (ret < 0)
-               goto err;
-
-       if (ret == 0) {
-               ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np,
-                                             &ndfc->parts);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = mtd_device_register(&ndfc->mtd, ndfc->parts, ret);
+       ret = mtd_device_parse_register(&ndfc->mtd, NULL, &ppdata, NULL, 0);
 
 err:
        of_node_put(flash_np);
@@ -288,6 +273,7 @@ static int __devexit ndfc_remove(struct platform_device *ofdev)
        struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev);
 
        nand_release(&ndfc->mtd);
+       kfree(ndfc->mtd.name);
 
        return 0;
 }
index b6a5c86ab31e922e1ddcf81dc88257012d61ad08..b463ecfb4c1a248713073ab019efed1af2f3d538 100644 (file)
@@ -187,6 +187,7 @@ static int nomadik_nand_remove(struct platform_device *pdev)
                pdata->exit();
 
        if (host) {
+               nand_release(&host->mtd);
                iounmap(host->cmd_va);
                iounmap(host->data_va);
                iounmap(host->addr_va);
index 9c30a0b031715f5d8a26dfd3fb3abbb7418adb6f..fa8faedfad6ee086d15bad4d249b3b0bd0874991 100644 (file)
@@ -339,6 +339,7 @@ static int __devexit nuc900_nand_remove(struct platform_device *pdev)
        struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);
        struct resource *res;
 
+       nand_release(&nuc900_nand->mtd);
        iounmap(nuc900_nand->reg);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
index 0db2c0e7656ae7abbde5536ca8c842a465482696..19b283f2c80c39b40c7e065ff92ee100131d61eb 100644 (file)
@@ -94,8 +94,6 @@
 #define P4e_s(a)       (TF(a & NAND_Ecc_P4e)           << 0)
 #define P4o_s(a)       (TF(a & NAND_Ecc_P4o)           << 1)
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -114,7 +112,6 @@ struct omap_nand_info {
        struct nand_hw_control          controller;
        struct omap_nand_platform_data  *pdata;
        struct mtd_info                 mtd;
-       struct mtd_partition            *parts;
        struct nand_chip                nand;
        struct platform_device          *pdev;
 
@@ -744,12 +741,12 @@ static int omap_compare_ecc(u8 *ecc_data1,        /* read from NAND memory */
 
        case 1:
                /* Uncorrectable error */
-               DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
+               pr_debug("ECC UNCORRECTED_ERROR 1\n");
                return -1;
 
        case 11:
                /* UN-Correctable error */
-               DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR B\n");
+               pr_debug("ECC UNCORRECTED_ERROR B\n");
                return -1;
 
        case 12:
@@ -766,8 +763,8 @@ static int omap_compare_ecc(u8 *ecc_data1,  /* read from NAND memory */
 
                find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
 
-               DEBUG(MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at "
-                               "offset: %d, bit: %d\n", find_byte, find_bit);
+               pr_debug("Correcting single bit ECC error at offset: "
+                               "%d, bit: %d\n", find_byte, find_bit);
 
                page_data[find_byte] ^= (1 << find_bit);
 
@@ -779,7 +776,7 @@ static int omap_compare_ecc(u8 *ecc_data1,  /* read from NAND memory */
                            ecc_data2[2] == 0)
                                return 0;
                }
-               DEBUG(MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n");
+               pr_debug("UNCORRECTED_ERROR default\n");
                return -1;
        }
 }
@@ -1103,13 +1100,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
                goto out_release_mem_region;
        }
 
-       err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
-       if (err > 0)
-               mtd_device_register(&info->mtd, info->parts, err);
-       else if (pdata->parts)
-               mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts);
-       else
-               mtd_device_register(&info->mtd, NULL, 0);
+       mtd_device_parse_register(&info->mtd, NULL, 0,
+                       pdata->parts, pdata->nr_parts);
 
        platform_set_drvdata(pdev, &info->mtd);
 
index 7794d0680f913b87932ba28d20729e642db382fb..29f505adaf8411581fcbb8d78d09935bef07f36d 100644 (file)
@@ -21,8 +21,6 @@
 #include <mach/hardware.h>
 #include <plat/orion_nand.h>
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
        struct nand_chip *nc = mtd->priv;
@@ -81,8 +79,6 @@ static int __init orion_nand_probe(struct platform_device *pdev)
        struct resource *res;
        void __iomem *io_base;
        int ret = 0;
-       struct mtd_partition *partitions = NULL;
-       int num_part = 0;
 
        nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL);
        if (!nc) {
@@ -132,17 +128,9 @@ static int __init orion_nand_probe(struct platform_device *pdev)
                goto no_dev;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        mtd->name = "orion_nand";
-       num_part = parse_mtd_partitions(mtd, part_probes, &partitions, 0);
-#endif
-       /* If cmdline partitions have been passed, let them be used */
-       if (num_part <= 0) {
-               num_part = board->nr_parts;
-               partitions = board->parts;
-       }
-
-       ret = mtd_device_register(mtd, partitions, num_part);
+       ret = mtd_device_parse_register(mtd, NULL, 0,
+                       board->parts, board->nr_parts);
        if (ret) {
                nand_release(mtd);
                goto no_dev;
index b1aa41b8a4eb6cd0d660d7c38eef8d1be00c0190..a97264ececdbe2278edf20b11a2d072bd38feba4 100644 (file)
@@ -155,7 +155,8 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev)
        chip->ecc.mode = NAND_ECC_SOFT;
 
        /* Enable the following for a flash based bad block table */
-       chip->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
+       chip->options = NAND_NO_AUTOINCR;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
 
        /* Scan to find existence of the device */
        if (nand_scan(pasemi_nand_mtd, 1)) {
index 633c04bf76f6c158aa4029ab83dc6a3d7f3ddca9..ea8e1234e0e25895ed2a731ae1a0225d616468fa 100644 (file)
@@ -21,8 +21,6 @@ struct plat_nand_data {
        struct nand_chip        chip;
        struct mtd_info         mtd;
        void __iomem            *io_base;
-       int                     nr_parts;
-       struct mtd_partition    *parts;
 };
 
 /*
@@ -79,6 +77,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
        data->chip.read_buf = pdata->ctrl.read_buf;
        data->chip.chip_delay = pdata->chip.chip_delay;
        data->chip.options |= pdata->chip.options;
+       data->chip.bbt_options |= pdata->chip.bbt_options;
 
        data->chip.ecc.hwctl = pdata->ctrl.hwcontrol;
        data->chip.ecc.layout = pdata->chip.ecclayout;
@@ -99,23 +98,9 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
                goto out;
        }
 
-       if (pdata->chip.part_probe_types) {
-               err = parse_mtd_partitions(&data->mtd,
-                                       pdata->chip.part_probe_types,
-                                       &data->parts, 0);
-               if (err > 0) {
-                       mtd_device_register(&data->mtd, data->parts, err);
-                       return 0;
-               }
-       }
-       if (pdata->chip.set_parts)
-               pdata->chip.set_parts(data->mtd.size, &pdata->chip);
-       if (pdata->chip.partitions) {
-               data->parts = pdata->chip.partitions;
-               err = mtd_device_register(&data->mtd, data->parts,
-                       pdata->chip.nr_partitions);
-       } else
-               err = mtd_device_register(&data->mtd, NULL, 0);
+       err = mtd_device_parse_register(&data->mtd,
+                       pdata->chip.part_probe_types, 0,
+                       pdata->chip.partitions, pdata->chip.nr_partitions);
 
        if (!err)
                return err;
@@ -145,8 +130,6 @@ static int __devexit plat_nand_remove(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        nand_release(&data->mtd);
-       if (data->parts && data->parts != pdata->chip.partitions)
-               kfree(data->parts);
        if (pdata->ctrl.remove)
                pdata->ctrl.remove(pdev);
        iounmap(data->io_base);
index 3bbb796b451c7994ab754610c433333308329a88..7e52af51a1986a419e66501bc3286c1e53397651 100644 (file)
@@ -99,8 +99,6 @@ static struct mtd_partition partition_info_evb[] = {
 
 #define NUM_PARTITIONS 1
 
-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id);
-
 /*
  *     hardware specific access to control-lines
  */
@@ -187,18 +185,12 @@ static int ppchameleonevb_device_ready(struct mtd_info *minfo)
 }
 #endif
 
-const char *part_probes[] = { "cmdlinepart", NULL };
-const char *part_probes_evb[] = { "cmdlinepart", NULL };
-
 /*
  * Main initialization routine
  */
 static int __init ppchameleonevb_init(void)
 {
        struct nand_chip *this;
-       const char *part_type = 0;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = 0;
        void __iomem *ppchameleon_fio_base;
        void __iomem *ppchameleonevb_fio_base;
 
@@ -281,24 +273,13 @@ static int __init ppchameleonevb_init(void)
 #endif
 
        ppchameleon_mtd->name = "ppchameleon-nand";
-       mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-
-       if (mtd_parts_nb == 0) {
-               if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
-                       mtd_parts = partition_info_me;
-               else
-                       mtd_parts = partition_info_hi;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
+       mtd_device_parse_register(ppchameleon_mtd, NULL, 0,
+                       ppchameleon_mtd->size == NAND_SMALL_SIZE ?
+                               partition_info_me :
+                               partition_info_hi,
+                       NUM_PARTITIONS);
 
  nand_evb_init:
        /****************************
@@ -382,21 +363,13 @@ static int __init ppchameleonevb_init(void)
        }
 
        ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
-       mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-
-       if (mtd_parts_nb == 0) {
-               mtd_parts = partition_info_evb;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(ppchameleonevb_mtd, mtd_parts, mtd_parts_nb);
+       mtd_device_parse_register(ppchameleonevb_mtd, NULL, 0,
+                       ppchameleon_mtd->size == NAND_SMALL_SIZE ?
+                               partition_info_me :
+                               partition_info_hi,
+                       NUM_PARTITIONS);
 
        /* Return happy */
        return 0;
index 1fb3b3a805818edca37ed2e07bfd8bd90b3d0f4b..9eb7f879969e31a2e5bd987bd27a5295f992516e 100644 (file)
@@ -110,6 +110,7 @@ enum {
 
 enum {
        STATE_IDLE = 0,
+       STATE_PREPARED,
        STATE_CMD_HANDLE,
        STATE_DMA_READING,
        STATE_DMA_WRITING,
@@ -120,21 +121,40 @@ enum {
        STATE_READY,
 };
 
-struct pxa3xx_nand_info {
-       struct nand_chip        nand_chip;
+struct pxa3xx_nand_host {
+       struct nand_chip        chip;
+       struct pxa3xx_nand_cmdset *cmdset;
+       struct mtd_info         *mtd;
+       void                    *info_data;
+
+       /* page size of attached chip */
+       unsigned int            page_size;
+       int                     use_ecc;
+       int                     cs;
 
+       /* calculated from pxa3xx_nand_flash data */
+       unsigned int            col_addr_cycles;
+       unsigned int            row_addr_cycles;
+       size_t                  read_id_bytes;
+
+       /* cached register value */
+       uint32_t                reg_ndcr;
+       uint32_t                ndtr0cs0;
+       uint32_t                ndtr1cs0;
+};
+
+struct pxa3xx_nand_info {
        struct nand_hw_control  controller;
        struct platform_device   *pdev;
-       struct pxa3xx_nand_cmdset *cmdset;
 
        struct clk              *clk;
        void __iomem            *mmio_base;
        unsigned long           mmio_phys;
+       struct completion       cmd_complete;
 
        unsigned int            buf_start;
        unsigned int            buf_count;
 
-       struct mtd_info         *mtd;
        /* DMA information */
        int                     drcmr_dat;
        int                     drcmr_cmd;
@@ -142,44 +162,27 @@ struct pxa3xx_nand_info {
        unsigned char           *data_buff;
        unsigned char           *oob_buff;
        dma_addr_t              data_buff_phys;
-       size_t                  data_buff_size;
        int                     data_dma_ch;
        struct pxa_dma_desc     *data_desc;
        dma_addr_t              data_desc_addr;
 
-       uint32_t                reg_ndcr;
-
-       /* saved column/page_addr during CMD_SEQIN */
-       int                     seqin_column;
-       int                     seqin_page_addr;
-
-       /* relate to the command */
+       struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
        unsigned int            state;
 
+       int                     cs;
        int                     use_ecc;        /* use HW ECC ? */
        int                     use_dma;        /* use DMA ? */
        int                     is_ready;
 
        unsigned int            page_size;      /* page size of attached chip */
        unsigned int            data_size;      /* data size in FIFO */
+       unsigned int            oob_size;
        int                     retcode;
-       struct completion       cmd_complete;
 
        /* generated NDCBx register values */
        uint32_t                ndcb0;
        uint32_t                ndcb1;
        uint32_t                ndcb2;
-
-       /* timing calcuted from setting */
-       uint32_t                ndtr0cs0;
-       uint32_t                ndtr1cs0;
-
-       /* calculated from pxa3xx_nand_flash data */
-       size_t          oob_size;
-       size_t          read_id_bytes;
-
-       unsigned int    col_addr_cycles;
-       unsigned int    row_addr_cycles;
 };
 
 static int use_dma = 1;
@@ -225,7 +228,7 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
 /* Define a default flash type setting serve as flash detecting only */
 #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
 
-const char *mtd_names[] = {"pxa3xx_nand-0", NULL};
+const char *mtd_names[] = {"pxa3xx_nand-0", "pxa3xx_nand-1", NULL};
 
 #define NDTR0_tCH(c)   (min((c), 7) << 19)
 #define NDTR0_tCS(c)   (min((c), 7) << 16)
@@ -241,9 +244,10 @@ const char *mtd_names[] = {"pxa3xx_nand-0", NULL};
 /* convert nano-seconds to nand flash controller clock cycles */
 #define ns2cycle(ns, clk)      (int)((ns) * (clk / 1000000) / 1000)
 
-static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
+static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
                                   const struct pxa3xx_nand_timing *t)
 {
+       struct pxa3xx_nand_info *info = host->info_data;
        unsigned long nand_clk = clk_get_rate(info->clk);
        uint32_t ndtr0, ndtr1;
 
@@ -258,23 +262,24 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
                NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
                NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
 
-       info->ndtr0cs0 = ndtr0;
-       info->ndtr1cs0 = ndtr1;
+       host->ndtr0cs0 = ndtr0;
+       host->ndtr1cs0 = ndtr1;
        nand_writel(info, NDTR0CS0, ndtr0);
        nand_writel(info, NDTR1CS0, ndtr1);
 }
 
 static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 {
-       int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
+       struct pxa3xx_nand_host *host = info->host[info->cs];
+       int oob_enable = host->reg_ndcr & NDCR_SPARE_EN;
 
-       info->data_size = info->page_size;
+       info->data_size = host->page_size;
        if (!oob_enable) {
                info->oob_size = 0;
                return;
        }
 
-       switch (info->page_size) {
+       switch (host->page_size) {
        case 2048:
                info->oob_size = (info->use_ecc) ? 40 : 64;
                break;
@@ -292,9 +297,10 @@ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
  */
 static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
 {
+       struct pxa3xx_nand_host *host = info->host[info->cs];
        uint32_t ndcr;
 
-       ndcr = info->reg_ndcr;
+       ndcr = host->reg_ndcr;
        ndcr |= info->use_ecc ? NDCR_ECC_EN : 0;
        ndcr |= info->use_dma ? NDCR_DMA_EN : 0;
        ndcr |= NDCR_ND_RUN;
@@ -359,7 +365,7 @@ static void handle_data_pio(struct pxa3xx_nand_info *info)
                                        DIV_ROUND_UP(info->oob_size, 4));
                break;
        default:
-               printk(KERN_ERR "%s: invalid state %d\n", __func__,
+               dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
                                info->state);
                BUG();
        }
@@ -385,7 +391,7 @@ static void start_data_dma(struct pxa3xx_nand_info *info)
                desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC;
                break;
        default:
-               printk(KERN_ERR "%s: invalid state %d\n", __func__,
+               dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
                                info->state);
                BUG();
        }
@@ -416,6 +422,15 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 {
        struct pxa3xx_nand_info *info = devid;
        unsigned int status, is_completed = 0;
+       unsigned int ready, cmd_done;
+
+       if (info->cs == 0) {
+               ready           = NDSR_FLASH_RDY;
+               cmd_done        = NDSR_CS0_CMDD;
+       } else {
+               ready           = NDSR_RDY;
+               cmd_done        = NDSR_CS1_CMDD;
+       }
 
        status = nand_readl(info, NDSR);
 
@@ -437,11 +452,11 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
                        handle_data_pio(info);
                }
        }
-       if (status & NDSR_CS0_CMDD) {
+       if (status & cmd_done) {
                info->state = STATE_CMD_DONE;
                is_completed = 1;
        }
-       if (status & NDSR_FLASH_RDY) {
+       if (status & ready) {
                info->is_ready = 1;
                info->state = STATE_READY;
        }
@@ -463,12 +478,6 @@ NORMAL_IRQ_EXIT:
        return IRQ_HANDLED;
 }
 
-static int pxa3xx_nand_dev_ready(struct mtd_info *mtd)
-{
-       struct pxa3xx_nand_info *info = mtd->priv;
-       return (nand_readl(info, NDSR) & NDSR_RDY) ? 1 : 0;
-}
-
 static inline int is_buf_blank(uint8_t *buf, size_t len)
 {
        for (; len > 0; len--)
@@ -481,10 +490,12 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                uint16_t column, int page_addr)
 {
        uint16_t cmd;
-       int addr_cycle, exec_cmd, ndcb0;
-       struct mtd_info *mtd = info->mtd;
+       int addr_cycle, exec_cmd;
+       struct pxa3xx_nand_host *host;
+       struct mtd_info *mtd;
 
-       ndcb0 = 0;
+       host = info->host[info->cs];
+       mtd = host->mtd;
        addr_cycle = 0;
        exec_cmd = 1;
 
@@ -495,6 +506,10 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
        info->use_ecc           = 0;
        info->is_ready          = 0;
        info->retcode           = ERR_NONE;
+       if (info->cs != 0)
+               info->ndcb0 = NDCB0_CSEL;
+       else
+               info->ndcb0 = 0;
 
        switch (command) {
        case NAND_CMD_READ0:
@@ -512,20 +527,19 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                break;
        }
 
-       info->ndcb0 = ndcb0;
-       addr_cycle = NDCB0_ADDR_CYC(info->row_addr_cycles
-                                   + info->col_addr_cycles);
+       addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
+                                   + host->col_addr_cycles);
 
        switch (command) {
        case NAND_CMD_READOOB:
        case NAND_CMD_READ0:
-               cmd = info->cmdset->read1;
+               cmd = host->cmdset->read1;
                if (command == NAND_CMD_READOOB)
                        info->buf_start = mtd->writesize + column;
                else
                        info->buf_start = column;
 
-               if (unlikely(info->page_size < PAGE_CHUNK_SIZE))
+               if (unlikely(host->page_size < PAGE_CHUNK_SIZE))
                        info->ndcb0 |= NDCB0_CMD_TYPE(0)
                                        | addr_cycle
                                        | (cmd & NDCB0_CMD1_MASK);
@@ -537,7 +551,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 
        case NAND_CMD_SEQIN:
                /* small page addr setting */
-               if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) {
+               if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) {
                        info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
                                        | (column & 0xFF);
 
@@ -564,7 +578,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                        break;
                }
 
-               cmd = info->cmdset->program;
+               cmd = host->cmdset->program;
                info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
                                | NDCB0_AUTO_RS
                                | NDCB0_ST_ROW_EN
@@ -574,8 +588,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                break;
 
        case NAND_CMD_READID:
-               cmd = info->cmdset->read_id;
-               info->buf_count = info->read_id_bytes;
+               cmd = host->cmdset->read_id;
+               info->buf_count = host->read_id_bytes;
                info->ndcb0 |= NDCB0_CMD_TYPE(3)
                                | NDCB0_ADDR_CYC(1)
                                | cmd;
@@ -583,7 +597,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                info->data_size = 8;
                break;
        case NAND_CMD_STATUS:
-               cmd = info->cmdset->read_status;
+               cmd = host->cmdset->read_status;
                info->buf_count = 1;
                info->ndcb0 |= NDCB0_CMD_TYPE(4)
                                | NDCB0_ADDR_CYC(1)
@@ -593,7 +607,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                break;
 
        case NAND_CMD_ERASE1:
-               cmd = info->cmdset->erase;
+               cmd = host->cmdset->erase;
                info->ndcb0 |= NDCB0_CMD_TYPE(2)
                                | NDCB0_AUTO_RS
                                | NDCB0_ADDR_CYC(3)
@@ -604,7 +618,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 
                break;
        case NAND_CMD_RESET:
-               cmd = info->cmdset->reset;
+               cmd = host->cmdset->reset;
                info->ndcb0 |= NDCB0_CMD_TYPE(5)
                                | cmd;
 
@@ -616,8 +630,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 
        default:
                exec_cmd = 0;
-               printk(KERN_ERR "pxa3xx-nand: non-supported"
-                       " command %x\n", command);
+               dev_err(&info->pdev->dev, "non-supported command %x\n",
+                               command);
                break;
        }
 
@@ -627,7 +641,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
                                int column, int page_addr)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        int ret, exec_cmd;
 
        /*
@@ -635,9 +650,21 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
         * "byte" address into a "word" address appropriate
         * for indexing a word-oriented device
         */
-       if (info->reg_ndcr & NDCR_DWIDTH_M)
+       if (host->reg_ndcr & NDCR_DWIDTH_M)
                column /= 2;
 
+       /*
+        * There may be different NAND chip hooked to
+        * different chip select, so check whether
+        * chip select has been changed, if yes, reset the timing
+        */
+       if (info->cs != host->cs) {
+               info->cs = host->cs;
+               nand_writel(info, NDTR0CS0, host->ndtr0cs0);
+               nand_writel(info, NDTR1CS0, host->ndtr1cs0);
+       }
+
+       info->state = STATE_PREPARED;
        exec_cmd = prepare_command_pool(info, command, column, page_addr);
        if (exec_cmd) {
                init_completion(&info->cmd_complete);
@@ -646,12 +673,12 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
                ret = wait_for_completion_timeout(&info->cmd_complete,
                                CHIP_DELAY_TIMEOUT);
                if (!ret) {
-                       printk(KERN_ERR "Wait time out!!!\n");
+                       dev_err(&info->pdev->dev, "Wait time out!!!\n");
                        /* Stop State Machine for next command cycle */
                        pxa3xx_nand_stop(info);
                }
-               info->state = STATE_IDLE;
        }
+       info->state = STATE_IDLE;
 }
 
 static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
@@ -664,7 +691,8 @@ static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
 static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
                struct nand_chip *chip, uint8_t *buf, int page)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
 
        chip->read_buf(mtd, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -685,6 +713,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
                 * OOB, ignore such double bit errors
                 */
                if (is_buf_blank(buf, mtd->writesize))
+                       info->retcode = ERR_NONE;
+               else
                        mtd->ecc_stats.failed++;
        }
 
@@ -693,7 +723,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
 
 static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        char retval = 0xFF;
 
        if (info->buf_start < info->buf_count)
@@ -705,7 +736,8 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
 
 static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        u16 retval = 0xFFFF;
 
        if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) {
@@ -717,7 +749,8 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
 
 static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
 
        memcpy(buf, info->data_buff + info->buf_start, real_len);
@@ -727,7 +760,8 @@ static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 static void pxa3xx_nand_write_buf(struct mtd_info *mtd,
                const uint8_t *buf, int len)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
 
        memcpy(info->data_buff + info->buf_start, buf, real_len);
@@ -747,7 +781,8 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
 
 static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
 
        /* pxa3xx_nand_send_command has waited for command complete */
        if (this->state == FL_WRITING || this->state == FL_ERASING) {
@@ -770,54 +805,70 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 {
        struct platform_device *pdev = info->pdev;
        struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
+       struct pxa3xx_nand_host *host = info->host[info->cs];
        uint32_t ndcr = 0x0; /* enable all interrupts */
 
-       if (f->page_size != 2048 && f->page_size != 512)
+       if (f->page_size != 2048 && f->page_size != 512) {
+               dev_err(&pdev->dev, "Current only support 2048 and 512 size\n");
                return -EINVAL;
+       }
 
-       if (f->flash_width != 16 && f->flash_width != 8)
+       if (f->flash_width != 16 && f->flash_width != 8) {
+               dev_err(&pdev->dev, "Only support 8bit and 16 bit!\n");
                return -EINVAL;
+       }
 
        /* calculate flash information */
-       info->cmdset = &default_cmdset;
-       info->page_size = f->page_size;
-       info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
+       host->cmdset = &default_cmdset;
+       host->page_size = f->page_size;
+       host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
 
        /* calculate addressing information */
-       info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
+       host->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
 
        if (f->num_blocks * f->page_per_block > 65536)
-               info->row_addr_cycles = 3;
+               host->row_addr_cycles = 3;
        else
-               info->row_addr_cycles = 2;
+               host->row_addr_cycles = 2;
 
        ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
-       ndcr |= (info->col_addr_cycles == 2) ? NDCR_RA_START : 0;
+       ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0;
        ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0;
        ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0;
        ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0;
        ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0;
 
-       ndcr |= NDCR_RD_ID_CNT(info->read_id_bytes);
+       ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
        ndcr |= NDCR_SPARE_EN; /* enable spare by default */
 
-       info->reg_ndcr = ndcr;
+       host->reg_ndcr = ndcr;
 
-       pxa3xx_nand_set_timing(info, f->timing);
+       pxa3xx_nand_set_timing(host, f->timing);
        return 0;
 }
 
 static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 {
+       /*
+        * We set 0 by hard coding here, for we don't support keep_config
+        * when there is more than one chip attached to the controller
+        */
+       struct pxa3xx_nand_host *host = info->host[0];
        uint32_t ndcr = nand_readl(info, NDCR);
-       info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
-       /* set info fields needed to read id */
-       info->read_id_bytes = (info->page_size == 2048) ? 4 : 2;
-       info->reg_ndcr = ndcr;
-       info->cmdset = &default_cmdset;
 
-       info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
-       info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
+       if (ndcr & NDCR_PAGE_SZ) {
+               host->page_size = 2048;
+               host->read_id_bytes = 4;
+       } else {
+               host->page_size = 512;
+               host->read_id_bytes = 2;
+       }
+
+       host->reg_ndcr = ndcr & ~NDCR_INT_MASK;
+       host->cmdset = &default_cmdset;
+
+       host->ndtr0cs0 = nand_readl(info, NDTR0CS0);
+       host->ndtr1cs0 = nand_readl(info, NDTR1CS0);
 
        return 0;
 }
@@ -847,7 +898,6 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
                return -ENOMEM;
        }
 
-       info->data_buff_size = MAX_BUFF_SIZE;
        info->data_desc = (void *)info->data_buff + data_desc_offset;
        info->data_desc_addr = info->data_buff_phys + data_desc_offset;
 
@@ -855,7 +905,7 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
                                pxa3xx_nand_data_dma_irq, info);
        if (info->data_dma_ch < 0) {
                dev_err(&pdev->dev, "failed to request data dma\n");
-               dma_free_coherent(&pdev->dev, info->data_buff_size,
+               dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
                                info->data_buff, info->data_buff_phys);
                return info->data_dma_ch;
        }
@@ -865,24 +915,28 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 
 static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
 {
-       struct mtd_info *mtd = info->mtd;
-       struct nand_chip *chip = mtd->priv;
-
+       struct mtd_info *mtd;
+       int ret;
+       mtd = info->host[info->cs]->mtd;
        /* use the common timing to make a try */
-       pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
-       chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+       ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
+       if (ret)
+               return ret;
+
+       pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
        if (info->is_ready)
-               return 1;
-       else
                return 0;
+
+       return -ENODEV;
 }
 
 static int pxa3xx_nand_scan(struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        struct platform_device *pdev = info->pdev;
        struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
-       struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} };
+       struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL;
        const struct pxa3xx_nand_flash *f = NULL;
        struct nand_chip *chip = mtd->priv;
        uint32_t id = -1;
@@ -893,22 +947,20 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
                goto KEEP_CONFIG;
 
        ret = pxa3xx_nand_sensing(info);
-       if (!ret) {
-               kfree(mtd);
-               info->mtd = NULL;
-               printk(KERN_INFO "There is no nand chip on cs 0!\n");
+       if (ret) {
+               dev_info(&info->pdev->dev, "There is no chip on cs %d!\n",
+                        info->cs);
 
-               return -EINVAL;
+               return ret;
        }
 
        chip->cmdfunc(mtd, NAND_CMD_READID, 0, 0);
        id = *((uint16_t *)(info->data_buff));
        if (id != 0)
-               printk(KERN_INFO "Detect a flash id %x\n", id);
+               dev_info(&info->pdev->dev, "Detect a flash id %x\n", id);
        else {
-               kfree(mtd);
-               info->mtd = NULL;
-               printk(KERN_WARNING "Read out ID 0, potential timing set wrong!!\n");
+               dev_warn(&info->pdev->dev,
+                        "Read out ID 0, potential timing set wrong!!\n");
 
                return -EINVAL;
        }
@@ -926,14 +978,17 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
        }
 
        if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) {
-               kfree(mtd);
-               info->mtd = NULL;
-               printk(KERN_ERR "ERROR!! flash not defined!!!\n");
+               dev_err(&info->pdev->dev, "ERROR!! flash not defined!!!\n");
 
                return -EINVAL;
        }
 
-       pxa3xx_nand_config_flash(info, f);
+       ret = pxa3xx_nand_config_flash(info, f);
+       if (ret) {
+               dev_err(&info->pdev->dev, "ERROR! Configure failed\n");
+               return ret;
+       }
+
        pxa3xx_flash_ids[0].name = f->name;
        pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff;
        pxa3xx_flash_ids[0].pagesize = f->page_size;
@@ -942,62 +997,78 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
        pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block;
        if (f->flash_width == 16)
                pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16;
+       pxa3xx_flash_ids[1].name = NULL;
+       def = pxa3xx_flash_ids;
 KEEP_CONFIG:
-       if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids))
+       chip->ecc.mode = NAND_ECC_HW;
+       chip->ecc.size = host->page_size;
+
+       chip->options = NAND_NO_AUTOINCR;
+       chip->options |= NAND_NO_READRDY;
+       if (host->reg_ndcr & NDCR_DWIDTH_M)
+               chip->options |= NAND_BUSWIDTH_16;
+
+       if (nand_scan_ident(mtd, 1, def))
                return -ENODEV;
        /* calculate addressing information */
-       info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1;
+       if (mtd->writesize >= 2048)
+               host->col_addr_cycles = 2;
+       else
+               host->col_addr_cycles = 1;
+
        info->oob_buff = info->data_buff + mtd->writesize;
        if ((mtd->size >> chip->page_shift) > 65536)
-               info->row_addr_cycles = 3;
+               host->row_addr_cycles = 3;
        else
-               info->row_addr_cycles = 2;
-       mtd->name = mtd_names[0];
-       chip->ecc.mode = NAND_ECC_HW;
-       chip->ecc.size = f->page_size;
-
-       chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0;
-       chip->options |= NAND_NO_AUTOINCR;
-       chip->options |= NAND_NO_READRDY;
+               host->row_addr_cycles = 2;
 
+       mtd->name = mtd_names[0];
        return nand_scan_tail(mtd);
 }
 
-static
-struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev)
+static int alloc_nand_resource(struct platform_device *pdev)
 {
+       struct pxa3xx_nand_platform_data *pdata;
        struct pxa3xx_nand_info *info;
+       struct pxa3xx_nand_host *host;
        struct nand_chip *chip;
        struct mtd_info *mtd;
        struct resource *r;
-       int ret, irq;
+       int ret, irq, cs;
 
-       mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info),
-                       GFP_KERNEL);
-       if (!mtd) {
+       pdata = pdev->dev.platform_data;
+       info = kzalloc(sizeof(*info) + (sizeof(*mtd) +
+                      sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
+       if (!info) {
                dev_err(&pdev->dev, "failed to allocate memory\n");
-               return NULL;
+               return -ENOMEM;
        }
 
-       info = (struct pxa3xx_nand_info *)(&mtd[1]);
-       chip = (struct nand_chip *)(&mtd[1]);
        info->pdev = pdev;
-       info->mtd = mtd;
-       mtd->priv = info;
-       mtd->owner = THIS_MODULE;
-
-       chip->ecc.read_page     = pxa3xx_nand_read_page_hwecc;
-       chip->ecc.write_page    = pxa3xx_nand_write_page_hwecc;
-       chip->controller        = &info->controller;
-       chip->waitfunc          = pxa3xx_nand_waitfunc;
-       chip->select_chip       = pxa3xx_nand_select_chip;
-       chip->dev_ready         = pxa3xx_nand_dev_ready;
-       chip->cmdfunc           = pxa3xx_nand_cmdfunc;
-       chip->read_word         = pxa3xx_nand_read_word;
-       chip->read_byte         = pxa3xx_nand_read_byte;
-       chip->read_buf          = pxa3xx_nand_read_buf;
-       chip->write_buf         = pxa3xx_nand_write_buf;
-       chip->verify_buf        = pxa3xx_nand_verify_buf;
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               mtd = (struct mtd_info *)((unsigned int)&info[1] +
+                     (sizeof(*mtd) + sizeof(*host)) * cs);
+               chip = (struct nand_chip *)(&mtd[1]);
+               host = (struct pxa3xx_nand_host *)chip;
+               info->host[cs] = host;
+               host->mtd = mtd;
+               host->cs = cs;
+               host->info_data = info;
+               mtd->priv = host;
+               mtd->owner = THIS_MODULE;
+
+               chip->ecc.read_page     = pxa3xx_nand_read_page_hwecc;
+               chip->ecc.write_page    = pxa3xx_nand_write_page_hwecc;
+               chip->controller        = &info->controller;
+               chip->waitfunc          = pxa3xx_nand_waitfunc;
+               chip->select_chip       = pxa3xx_nand_select_chip;
+               chip->cmdfunc           = pxa3xx_nand_cmdfunc;
+               chip->read_word         = pxa3xx_nand_read_word;
+               chip->read_byte         = pxa3xx_nand_read_byte;
+               chip->read_buf          = pxa3xx_nand_read_buf;
+               chip->write_buf         = pxa3xx_nand_write_buf;
+               chip->verify_buf        = pxa3xx_nand_verify_buf;
+       }
 
        spin_lock_init(&chip->controller->lock);
        init_waitqueue_head(&chip->controller->wq);
@@ -1070,13 +1141,13 @@ struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, info);
 
-       return info;
+       return 0;
 
 fail_free_buf:
        free_irq(irq, info);
        if (use_dma) {
                pxa_free_dma(info->data_dma_ch);
-               dma_free_coherent(&pdev->dev, info->data_buff_size,
+               dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
                        info->data_buff, info->data_buff_phys);
        } else
                kfree(info->data_buff);
@@ -1088,17 +1159,21 @@ fail_put_clk:
        clk_disable(info->clk);
        clk_put(info->clk);
 fail_free_mtd:
-       kfree(mtd);
-       return NULL;
+       kfree(info);
+       return ret;
 }
 
 static int pxa3xx_nand_remove(struct platform_device *pdev)
 {
        struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-       struct mtd_info *mtd = info->mtd;
+       struct pxa3xx_nand_platform_data *pdata;
        struct resource *r;
-       int irq;
+       int irq, cs;
 
+       if (!info)
+               return 0;
+
+       pdata = pdev->dev.platform_data;
        platform_set_drvdata(pdev, NULL);
 
        irq = platform_get_irq(pdev, 0);
@@ -1106,7 +1181,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
                free_irq(irq, info);
        if (use_dma) {
                pxa_free_dma(info->data_dma_ch);
-               dma_free_writecombine(&pdev->dev, info->data_buff_size,
+               dma_free_writecombine(&pdev->dev, MAX_BUFF_SIZE,
                                info->data_buff, info->data_buff_phys);
        } else
                kfree(info->data_buff);
@@ -1118,10 +1193,9 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
        clk_disable(info->clk);
        clk_put(info->clk);
 
-       if (mtd) {
-               mtd_device_unregister(mtd);
-               kfree(mtd);
-       }
+       for (cs = 0; cs < pdata->num_cs; cs++)
+               nand_release(info->host[cs]->mtd);
+       kfree(info);
        return 0;
 }
 
@@ -1129,6 +1203,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 {
        struct pxa3xx_nand_platform_data *pdata;
        struct pxa3xx_nand_info *info;
+       int ret, cs, probe_success;
 
        pdata = pdev->dev.platform_data;
        if (!pdata) {
@@ -1136,52 +1211,88 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       info = alloc_nand_resource(pdev);
-       if (info == NULL)
-               return -ENOMEM;
-
-       if (pxa3xx_nand_scan(info->mtd)) {
-               dev_err(&pdev->dev, "failed to scan nand\n");
-               pxa3xx_nand_remove(pdev);
-               return -ENODEV;
+       ret = alloc_nand_resource(pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "alloc nand resource failed\n");
+               return ret;
        }
 
-       if (mtd_has_cmdlinepart()) {
-               const char *probes[] = { "cmdlinepart", NULL };
-               struct mtd_partition *parts;
-               int nr_parts;
+       info = platform_get_drvdata(pdev);
+       probe_success = 0;
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               info->cs = cs;
+               ret = pxa3xx_nand_scan(info->host[cs]->mtd);
+               if (ret) {
+                       dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
+                               cs);
+                       continue;
+               }
 
-               nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0);
+               ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, 0,
+                               pdata->parts[cs], pdata->nr_parts[cs]);
+               if (!ret)
+                       probe_success = 1;
+       }
 
-               if (nr_parts)
-                       return mtd_device_register(info->mtd, parts, nr_parts);
+       if (!probe_success) {
+               pxa3xx_nand_remove(pdev);
+               return -ENODEV;
        }
 
-       return mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
+       return 0;
 }
 
 #ifdef CONFIG_PM
 static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-       struct mtd_info *mtd = info->mtd;
+       struct pxa3xx_nand_platform_data *pdata;
+       struct mtd_info *mtd;
+       int cs;
 
+       pdata = pdev->dev.platform_data;
        if (info->state) {
                dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
                return -EAGAIN;
        }
 
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               mtd = info->host[cs]->mtd;
+               mtd->suspend(mtd);
+       }
+
        return 0;
 }
 
 static int pxa3xx_nand_resume(struct platform_device *pdev)
 {
        struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-       struct mtd_info *mtd = info->mtd;
+       struct pxa3xx_nand_platform_data *pdata;
+       struct mtd_info *mtd;
+       int cs;
 
-       nand_writel(info, NDTR0CS0, info->ndtr0cs0);
-       nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-       clk_enable(info->clk);
+       pdata = pdev->dev.platform_data;
+       /* We don't want to handle interrupt without calling mtd routine */
+       disable_int(info, NDCR_INT_MASK);
+
+       /*
+        * Directly set the chip select to a invalid value,
+        * then the driver would reset the timing according
+        * to current chip select at the beginning of cmdfunc
+        */
+       info->cs = 0xff;
+
+       /*
+        * As the spec says, the NDSR would be updated to 0x1800 when
+        * doing the nand_clk disable/enable.
+        * To prevent it damaging state machine of the driver, clear
+        * all status before resume
+        */
+       nand_writel(info, NDSR, NDSR_MASK);
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               mtd = info->host[cs]->mtd;
+               mtd->resume(mtd);
+       }
 
        return 0;
 }
index c9f9127ff7708ee06fae1bd6e159f8e0619f20e5..f309addc2fa0505137f83a7a389bcb74b4fff9e6 100644 (file)
@@ -351,7 +351,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
                return 0;
        }
 
-       /* Read the syndrom pattern from the FPGA and correct the bitorder */
+       /* Read the syndrome pattern from the FPGA and correct the bitorder */
        rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
        for (i = 0; i < 8; i++) {
                ecc[i] = bitrev8(*rs_ecc);
@@ -380,7 +380,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
        /* Let the library code do its magic. */
        res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
        if (res > 0) {
-               DEBUG(MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
+               pr_debug("rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
        }
        return res;
 }
@@ -444,7 +444,6 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
                len = mtd->writesize;
                buf = kmalloc(len, GFP_KERNEL);
                if (!buf) {
-                       printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
                        er_stat = 1;
                        goto out;
                }
index 4405468f196b076c6b97fb1366ec8fff55d684a8..868685db6712fa3c18b593b4e9a171707f68f228 100644 (file)
@@ -723,7 +723,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
 
        /* free the common resources */
 
-       if (info->clk != NULL && !IS_ERR(info->clk)) {
+       if (!IS_ERR(info->clk)) {
                s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
                clk_put(info->clk);
        }
@@ -744,26 +744,15 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
-const char *part_probes[] = { "cmdlinepart", NULL };
 static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
                                      struct s3c2410_nand_mtd *mtd,
                                      struct s3c2410_nand_set *set)
 {
-       struct mtd_partition *part_info;
-       int nr_part = 0;
+       if (set)
+               mtd->mtd.name = set->name;
 
-       if (set == NULL)
-               return mtd_device_register(&mtd->mtd, NULL, 0);
-
-       mtd->mtd.name = set->name;
-       nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0);
-
-       if (nr_part <= 0 && set->nr_partitions > 0) {
-               nr_part = set->nr_partitions;
-               part_info = set->partitions;
-       }
-
-       return mtd_device_register(&mtd->mtd, part_info, nr_part);
+       return mtd_device_parse_register(&mtd->mtd, NULL, 0,
+                       set->partitions, set->nr_partitions);
 }
 
 /**
@@ -880,8 +869,10 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
        /* If you use u-boot BBT creation code, specifying this flag will
         * let the kernel fish out the BBT from the NAND, and also skip the
         * full NAND scan that can take 1/2s or so. Little things... */
-       if (set->flash_bbt)
-               chip->options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN;
+       if (set->flash_bbt) {
+               chip->bbt_options |= NAND_BBT_USE_FLASH;
+               chip->options |= NAND_SKIP_BBTSCAN;
+       }
 }
 
 /**
index 19e24ed089ea9dd05d1bc9b4ea25dc406d5ede90..619d2a504788b050aa46cc48e0cd13c31588d921 100644 (file)
@@ -103,16 +103,12 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat,
        return readb(sharpsl->io + ECCCNTR) != 0;
 }
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 /*
  * Main initialization routine
  */
 static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
 {
        struct nand_chip *this;
-       struct mtd_partition *sharpsl_partition_info;
-       int nr_partitions;
        struct resource *r;
        int err = 0;
        struct sharpsl_nand *sharpsl;
@@ -184,14 +180,9 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
 
        /* Register the partitions */
        sharpsl->mtd.name = "sharpsl-nand";
-       nr_partitions = parse_mtd_partitions(&sharpsl->mtd, part_probes, &sharpsl_partition_info, 0);
-       if (nr_partitions <= 0) {
-               nr_partitions = data->nr_partitions;
-               sharpsl_partition_info = data->partitions;
-       }
 
-       err = mtd_device_register(&sharpsl->mtd, sharpsl_partition_info,
-                                 nr_partitions);
+       err = mtd_device_parse_register(&sharpsl->mtd, NULL, 0,
+                       data->partitions, data->nr_partitions);
        if (err)
                goto err_add;
 
index ca2d0555729e466b43940043c9d044334f3719d4..0fb24f9c232772dac3c307bff2c7eb7a2d690c5f 100644 (file)
@@ -155,8 +155,6 @@ static int socrates_nand_device_ready(struct mtd_info *mtd)
        return 1;
 }
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 /*
  * Probe for the NAND device.
  */
@@ -166,8 +164,7 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
        struct mtd_info *mtd;
        struct nand_chip *nand_chip;
        int res;
-       struct mtd_partition *partitions = NULL;
-       int num_partitions = 0;
+       struct mtd_part_parser_data ppdata;
 
        /* Allocate memory for the device structure (and zero it) */
        host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
@@ -193,6 +190,7 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
        mtd->name = "socrates_nand";
        mtd->owner = THIS_MODULE;
        mtd->dev.parent = &ofdev->dev;
+       ppdata.of_node = ofdev->dev.of_node;
 
        /*should never be accessed directly */
        nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
@@ -225,30 +223,10 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
                goto out;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       num_partitions = parse_mtd_partitions(mtd, part_probes,
-                                             &partitions, 0);
-       if (num_partitions < 0) {
-               res = num_partitions;
-               goto release;
-       }
-#endif
-
-       if (num_partitions == 0) {
-               num_partitions = of_mtd_parse_partitions(&ofdev->dev,
-                                                        ofdev->dev.of_node,
-                                                        &partitions);
-               if (num_partitions < 0) {
-                       res = num_partitions;
-                       goto release;
-               }
-       }
-
-       res = mtd_device_register(mtd, partitions, num_partitions);
+       res = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
        if (!res)
                return res;
 
-release:
        nand_release(mtd);
 
 out:
index 11e8371b56834e8b0c79f64fe4d54393be849630..beebd95f76907de7e32102d0dd9a7593be99d0a7 100644 (file)
@@ -121,9 +121,6 @@ struct tmio_nand {
 
 #define mtd_to_tmio(m)                 container_of(m, struct tmio_nand, mtd)
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /*--------------------------------------------------------------------------*/
 
@@ -381,8 +378,6 @@ static int tmio_probe(struct platform_device *dev)
        struct tmio_nand *tmio;
        struct mtd_info *mtd;
        struct nand_chip *nand_chip;
-       struct mtd_partition *parts;
-       int nbparts = 0;
        int retval;
 
        if (data == NULL)
@@ -461,15 +456,9 @@ static int tmio_probe(struct platform_device *dev)
                goto err_scan;
        }
        /* Register the partitions */
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
-#endif
-       if (nbparts <= 0 && data) {
-               parts = data->partition;
-               nbparts = data->num_partitions;
-       }
-
-       retval = mtd_device_register(mtd, parts, nbparts);
+       retval = mtd_device_parse_register(mtd, NULL, 0,
+                       data ? data->partition : NULL,
+                       data ? data->num_partitions : 0);
        if (!retval)
                return retval;
 
index bfba4e39a6c5cd5866d95b0fd114896489935a62..ace46fdaef58cfb3b51fc9c981e637bb7e0fd2a4 100644 (file)
@@ -74,7 +74,6 @@ struct txx9ndfmc_drvdata {
        unsigned char hold;     /* in gbusclock */
        unsigned char spw;      /* in gbusclock */
        struct nand_hw_control hw_control;
-       struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
 };
 
 static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
@@ -287,7 +286,6 @@ static int txx9ndfmc_nand_scan(struct mtd_info *mtd)
 static int __init txx9ndfmc_probe(struct platform_device *dev)
 {
        struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
-       static const char *probes[] = { "cmdlinepart", NULL };
        int hold, spw;
        int i;
        struct txx9ndfmc_drvdata *drvdata;
@@ -333,7 +331,6 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
                struct txx9ndfmc_priv *txx9_priv;
                struct nand_chip *chip;
                struct mtd_info *mtd;
-               int nr_parts;
 
                if (!(plat->ch_mask & (1 << i)))
                        continue;
@@ -393,9 +390,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
                }
                mtd->name = txx9_priv->mtdname;
 
-               nr_parts = parse_mtd_partitions(mtd, probes,
-                                               &drvdata->parts[i], 0);
-               mtd_device_register(mtd, drvdata->parts[i], nr_parts);
+               mtd_device_parse_register(mtd, NULL, 0, NULL, 0);
                drvdata->mtds[i] = mtd;
        }
 
@@ -421,7 +416,6 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev)
                txx9_priv = chip->priv;
 
                nand_release(mtd);
-               kfree(drvdata->parts[i]);
                kfree(txx9_priv->mtdname);
                kfree(txx9_priv);
        }
index b155666acfbe5a1c07ebfa37b1b1ec3c1140d07c..93d6fc68b89245ba48ab973eb8bda2339f7d4d3e 100644 (file)
@@ -63,14 +63,12 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                return;
        }
 
-       DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);
+       pr_debug("NFTL: add_mtd for %s\n", mtd->name);
 
        nftl = kzalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
 
-       if (!nftl) {
-               printk(KERN_WARNING "NFTL: out of memory for data structures\n");
+       if (!nftl)
                return;
-       }
 
        nftl->mbd.mtd = mtd;
        nftl->mbd.devnum = -1;
@@ -132,7 +130,7 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
        struct NFTLrecord *nftl = (void *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
+       pr_debug("NFTL: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
        kfree(nftl->ReplUnitTable);
@@ -220,7 +218,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
 
        /* Normally, we force a fold to happen before we run out of free blocks completely */
        if (!desperate && nftl->numfreeEUNs < 2) {
-               DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n");
+               pr_debug("NFTL_findfreeblock: there are too few free EUNs\n");
                return BLOCK_NIL;
        }
 
@@ -291,8 +289,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
                        if (block == 2) {
                                foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
                                if (foldmark == FOLD_MARK_IN_PROGRESS) {
-                                       DEBUG(MTD_DEBUG_LEVEL1,
-                                             "Write Inhibited on EUN %d\n", thisEUN);
+                                       pr_debug("Write Inhibited on EUN %d\n", thisEUN);
                                        inplace = 0;
                                } else {
                                        /* There's no other reason not to do inplace,
@@ -357,7 +354,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
                        if (BlockLastState[block] != SECTOR_FREE &&
                            BlockMap[block] != BLOCK_NIL &&
                            BlockMap[block] != targetEUN) {
-                               DEBUG(MTD_DEBUG_LEVEL1, "Setting inplace to 0. VUC %d, "
+                               pr_debug("Setting inplace to 0. VUC %d, "
                                      "block %d was %x lastEUN, "
                                      "and is in EUN %d (%s) %d\n",
                                      thisVUC, block, BlockLastState[block],
@@ -373,14 +370,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
                    pendingblock < ((thisVUC + 1)* (nftl->EraseSize / 512)) &&
                    BlockLastState[pendingblock - (thisVUC * (nftl->EraseSize / 512))] !=
                    SECTOR_FREE) {
-                       DEBUG(MTD_DEBUG_LEVEL1, "Pending write not free in EUN %d. "
+                       pr_debug("Pending write not free in EUN %d. "
                              "Folding out of place.\n", targetEUN);
                        inplace = 0;
                }
        }
 
        if (!inplace) {
-               DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
+               pr_debug("Cannot fold Virtual Unit Chain %d in place. "
                      "Trying out-of-place\n", thisVUC);
                /* We need to find a targetEUN to fold into. */
                targetEUN = NFTL_findfreeblock(nftl, 1);
@@ -410,7 +407,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
           and the Erase Unit into which we are supposed to be copying.
           Go for it.
        */
-       DEBUG(MTD_DEBUG_LEVEL1,"Folding chain %d into unit %d\n", thisVUC, targetEUN);
+       pr_debug("Folding chain %d into unit %d\n", thisVUC, targetEUN);
        for (block = 0; block < nftl->EraseSize / 512 ; block++) {
                unsigned char movebuf[512];
                int ret;
@@ -457,7 +454,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
           has duplicate chains, we need to free one of the chains because it's not necessary any more.
        */
        thisEUN = nftl->EUNtable[thisVUC];
-       DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
+       pr_debug("Want to erase\n");
 
        /* For each block in the old chain (except the targetEUN of course),
           free it and make it available for future use */
@@ -570,7 +567,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
                                      (writeEUN * nftl->EraseSize) + blockofs,
                                      8, &retlen, (char *)&bci);
 
-                       DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
+                       pr_debug("Status of block %d in EUN %d is %x\n",
                              block , writeEUN, le16_to_cpu(bci.Status));
 
                        status = bci.Status | bci.Status1;
@@ -623,7 +620,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
                                   but they are reserved for when we're
                                   desperate. Well, now we're desperate.
                                */
-                               DEBUG(MTD_DEBUG_LEVEL1, "Using desperate==1 to find free EUN to accommodate write to VUC %d\n", thisVUC);
+                               pr_debug("Using desperate==1 to find free EUN to accommodate write to VUC %d\n", thisVUC);
                                writeEUN = NFTL_findfreeblock(nftl, 1);
                        }
                        if (writeEUN == BLOCK_NIL) {
index e3cd1ffad2f624c203237068847a5643c3254941..ac4092591aea035068e169900b099ca8121c2185 100644 (file)
@@ -32,7 +32,7 @@
 
 /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
  *     various device information of the NFTL partition and Bad Unit Table. Update
- *     the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
+ *     the ReplUnitTable[] table according to the Bad Unit Table. ReplUnitTable[]
  *     is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
  */
 static int find_boot_record(struct NFTLrecord *nftl)
@@ -297,7 +297,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
  *
  * Return: 0 when succeed, -1 on error.
  *
- *  ToDo: 1. Is it neceressary to check_free_sector after erasing ??
+ *  ToDo: 1. Is it necessary to check_free_sector after erasing ??
  */
 int NFTL_formatblock(struct NFTLrecord *nftl, int block)
 {
@@ -337,7 +337,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
                nb_erases = le32_to_cpu(uci.WearInfo);
                nb_erases++;
 
-               /* wrap (almost impossible with current flashs) or free block */
+               /* wrap (almost impossible with current flash) or free block */
                if (nb_erases == 0)
                        nb_erases = 1;
 
@@ -363,10 +363,10 @@ fail:
  *     Mark as 'IGNORE' each incorrect sector. This check is only done if the chain
  *     was being folded when NFTL was interrupted.
  *
- *     The check_free_sectors in this function is neceressary. There is a possible
+ *     The check_free_sectors in this function is necessary. There is a possible
  *     situation that after writing the Data area, the Block Control Information is
  *     not updated according (due to power failure or something) which leaves the block
- *     in an umconsistent state. So we have to check if a block is really FREE in this
+ *     in an inconsistent state. So we have to check if a block is really FREE in this
  *     case. */
 static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
 {
@@ -428,7 +428,7 @@ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
 
        for (;;) {
                length++;
-               /* avoid infinite loops, although this is guaranted not to
+               /* avoid infinite loops, although this is guaranteed not to
                   happen because of the previous checks */
                if (length >= nftl->nb_blocks) {
                        printk("nftl: length too long %d !\n", length);
@@ -447,11 +447,11 @@ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
 /* format_chain: Format an invalid Virtual Unit chain. It frees all the Erase Units in a
  *     Virtual Unit Chain, i.e. all the units are disconnected.
  *
- *     It is not stricly correct to begin from the first block of the chain because
+ *     It is not strictly correct to begin from the first block of the chain because
  *     if we stop the code, we may see again a valid chain if there was a first_block
  *     flag in a block inside it. But is it really a problem ?
  *
- * FixMe: Figure out what the last statesment means. What if power failure when we are
+ * FixMe: Figure out what the last statement means. What if power failure when we are
  *     in the for (;;) loop formatting blocks ??
  */
 static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
@@ -485,7 +485,7 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
  *     totally free (only 0xff).
  *
  * Definition: Free Erase Unit -- A properly erased/formatted Free Erase Unit should have meet the
- *     following critia:
+ *     following criteria:
  *     1. */
 static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
 {
@@ -502,7 +502,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
        erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
        if (erase_mark != ERASE_MARK) {
                /* if no erase mark, the block must be totally free. This is
-                  possible in two cases : empty filsystem or interrupted erase (very unlikely) */
+                  possible in two cases : empty filesystem or interrupted erase (very unlikely) */
                if (check_free_sectors (nftl, block * nftl->EraseSize, nftl->EraseSize, 1) != 0)
                        return -1;
 
@@ -544,7 +544,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
 /* get_fold_mark: Read fold mark from Unit Control Information #2, we use FOLD_MARK_IN_PROGRESS
  *     to indicate that we are in the progression of a Virtual Unit Chain folding. If the UCI #2
  *     is FOLD_MARK_IN_PROGRESS when mounting the NFTL, the (previous) folding process is interrupted
- *     for some reason. A clean up/check of the VUC is neceressary in this case.
+ *     for some reason. A clean up/check of the VUC is necessary in this case.
  *
  * WARNING: return 0 if read error
  */
@@ -657,7 +657,7 @@ int NFTL_mount(struct NFTLrecord *s)
                                                printk("Block %d: incorrect logical block: %d expected: %d\n",
                                                       block, logical_block, first_logical_block);
                                                /* the chain is incorrect : we must format it,
-                                                  but we need to read it completly */
+                                                  but we need to read it completely */
                                                do_format_chain = 1;
                                        }
                                        if (is_first_block) {
@@ -669,7 +669,7 @@ int NFTL_mount(struct NFTLrecord *s)
                                                        printk("Block %d: incorrectly marked as first block in chain\n",
                                                               block);
                                                        /* the chain is incorrect : we must format it,
-                                                          but we need to read it completly */
+                                                          but we need to read it completely */
                                                        do_format_chain = 1;
                                                } else {
                                                        printk("Block %d: folding in progress - ignoring first block flag\n",
index a996718fa6b06e05607dae1f86bf01a8ff024dd5..64be8f0848b075cdccb647309ff88d12b3fa547d 100644 (file)
 #include <linux/slab.h>
 #include <linux/mtd/partitions.h>
 
-int __devinit of_mtd_parse_partitions(struct device *dev,
-                                      struct device_node *node,
-                                      struct mtd_partition **pparts)
+static int parse_ofpart_partitions(struct mtd_info *master,
+                                  struct mtd_partition **pparts,
+                                  struct mtd_part_parser_data *data)
 {
+       struct device_node *node;
        const char *partname;
        struct device_node *pp;
        int nr_parts, i;
 
+
+       if (!data)
+               return 0;
+
+       node = data->of_node;
+       if (!node)
+               return 0;
+
        /* First count the subnodes */
        pp = NULL;
        nr_parts = 0;
@@ -69,7 +78,7 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
 
        if (!i) {
                of_node_put(pp);
-               dev_err(dev, "No valid partition found on %s\n", node->full_name);
+               pr_err("No valid partition found on %s\n", node->full_name);
                kfree(*pparts);
                *pparts = NULL;
                return -EINVAL;
@@ -77,6 +86,99 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
 
        return nr_parts;
 }
-EXPORT_SYMBOL(of_mtd_parse_partitions);
+
+static struct mtd_part_parser ofpart_parser = {
+       .owner = THIS_MODULE,
+       .parse_fn = parse_ofpart_partitions,
+       .name = "ofpart",
+};
+
+static int parse_ofoldpart_partitions(struct mtd_info *master,
+                                     struct mtd_partition **pparts,
+                                     struct mtd_part_parser_data *data)
+{
+       struct device_node *dp;
+       int i, plen, nr_parts;
+       const struct {
+               __be32 offset, len;
+       } *part;
+       const char *names;
+
+       if (!data)
+               return 0;
+
+       dp = data->of_node;
+       if (!dp)
+               return 0;
+
+       part = of_get_property(dp, "partitions", &plen);
+       if (!part)
+               return 0; /* No partitions found */
+
+       pr_warning("Device tree uses obsolete partition map binding: %s\n",
+                       dp->full_name);
+
+       nr_parts = plen / sizeof(part[0]);
+
+       *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
+       if (!pparts)
+               return -ENOMEM;
+
+       names = of_get_property(dp, "partition-names", &plen);
+
+       for (i = 0; i < nr_parts; i++) {
+               (*pparts)[i].offset = be32_to_cpu(part->offset);
+               (*pparts)[i].size   = be32_to_cpu(part->len) & ~1;
+               /* bit 0 set signifies read only partition */
+               if (be32_to_cpu(part->len) & 1)
+                       (*pparts)[i].mask_flags = MTD_WRITEABLE;
+
+               if (names && (plen > 0)) {
+                       int len = strlen(names) + 1;
+
+                       (*pparts)[i].name = (char *)names;
+                       plen -= len;
+                       names += len;
+               } else {
+                       (*pparts)[i].name = "unnamed";
+               }
+
+               part++;
+       }
+
+       return nr_parts;
+}
+
+static struct mtd_part_parser ofoldpart_parser = {
+       .owner = THIS_MODULE,
+       .parse_fn = parse_ofoldpart_partitions,
+       .name = "ofoldpart",
+};
+
+static int __init ofpart_parser_init(void)
+{
+       int rc;
+       rc = register_mtd_parser(&ofpart_parser);
+       if (rc)
+               goto out;
+
+       rc = register_mtd_parser(&ofoldpart_parser);
+       if (!rc)
+               return 0;
+
+       deregister_mtd_parser(&ofoldpart_parser);
+out:
+       return rc;
+}
+
+module_init(ofpart_parser_init);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree");
+MODULE_AUTHOR("Vitaly Wool, David Gibson");
+/*
+ * When MTD core cannot find the requested parser, it tries to load the module
+ * with the same name. Since we provide the ofoldpart parser, we should have
+ * the corresponding alias.
+ */
+MODULE_ALIAS("ofoldpart");
index 2d70d354d846b6d36efb334434533445c0e21270..7813095264a56192dbd13c0948da04cfdfd5f82f 100644 (file)
  */
 #define DRIVER_NAME    "onenand-flash"
 
-static const char *part_probes[] = { "cmdlinepart", NULL,  };
-
 struct onenand_info {
        struct mtd_info         mtd;
-       struct mtd_partition    *parts;
        struct onenand_chip     onenand;
 };
 
@@ -73,13 +70,9 @@ static int __devinit generic_onenand_probe(struct platform_device *pdev)
                goto out_iounmap;
        }
 
-       err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
-       if (err > 0)
-               mtd_device_register(&info->mtd, info->parts, err);
-       else if (err <= 0 && pdata && pdata->parts)
-               mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts);
-       else
-               err = mtd_device_register(&info->mtd, NULL, 0);
+       err = mtd_device_parse_register(&info->mtd, NULL, 0,
+                       pdata ? pdata->parts : NULL,
+                       pdata ? pdata->nr_parts : 0);
 
        platform_set_drvdata(pdev, info);
 
@@ -104,7 +97,6 @@ static int __devexit generic_onenand_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        if (info) {
-               mtd_device_unregister(&info->mtd);
                onenand_release(&info->mtd);
                release_mem_region(res->start, size);
                iounmap(info->onenand.base);
index a916dec292156a524438b117400837fd7d9f6145..7e9ea6852b671d3e1b09f1c259eee49be3ecb968 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/mach/flash.h>
 #include <plat/gpmc.h>
 #include <plat/onenand.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #include <plat/dma.h>
 
@@ -57,7 +57,6 @@ struct omap2_onenand {
        unsigned long phys_base;
        int gpio_irq;
        struct mtd_info mtd;
-       struct mtd_partition *parts;
        struct onenand_chip onenand;
        struct completion irq_done;
        struct completion dma_done;
@@ -67,8 +66,6 @@ struct omap2_onenand {
        struct regulator *regulator;
 };
 
-static const char *part_probes[] = { "cmdlinepart", NULL,  };
-
 static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
 {
        struct omap2_onenand *c = data;
@@ -741,6 +738,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
                c->regulator = regulator_get(&pdev->dev, "vonenand");
                if (IS_ERR(c->regulator)) {
                        dev_err(&pdev->dev,  "Failed to get regulator\n");
+                       r = PTR_ERR(c->regulator);
                        goto err_release_dma;
                }
                c->onenand.enable = omap2_onenand_enable;
@@ -753,13 +751,9 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
        if ((r = onenand_scan(&c->mtd, 1)) < 0)
                goto err_release_regulator;
 
-       r = parse_mtd_partitions(&c->mtd, part_probes, &c->parts, 0);
-       if (r > 0)
-               r = mtd_device_register(&c->mtd, c->parts, r);
-       else if (pdata->parts != NULL)
-               r = mtd_device_register(&c->mtd, pdata->parts, pdata->nr_parts);
-       else
-               r = mtd_device_register(&c->mtd, NULL, 0);
+       r = mtd_device_parse_register(&c->mtd, NULL, 0,
+                       pdata ? pdata->parts : NULL,
+                       pdata ? pdata->nr_parts : 0);
        if (r)
                goto err_release_onenand;
 
@@ -786,7 +780,6 @@ err_release_mem_region:
 err_free_cs:
        gpmc_cs_free(c->gpmc_cs);
 err_kfree:
-       kfree(c->parts);
        kfree(c);
 
        return r;
@@ -809,7 +802,6 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
        iounmap(c->onenand.base);
        release_mem_region(c->phys_base, ONENAND_IO_SIZE);
        gpmc_cs_free(c->gpmc_cs);
-       kfree(c->parts);
        kfree(c);
 
        return 0;
index ac9e959802a7b113e838ecb8d6e24aee5b7df524..de98791f81019ddf76fb5cb1a3b7e7afd1b35357 100644 (file)
@@ -1015,7 +1015,7 @@ static void onenand_release_device(struct mtd_info *mtd)
 }
 
 /**
- * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
+ * onenand_transfer_auto_oob - [INTERN] oob auto-placement transfer
  * @param mtd          MTD device structure
  * @param buf          destination address
  * @param column       oob offset to read from
@@ -1122,8 +1122,8 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
        int ret = 0;
        int writesize = this->writesize;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-             __func__, (unsigned int) from, (int) len);
+       pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
+                       (int)len);
 
        if (ops->mode == MTD_OOB_AUTO)
                oobsize = this->ecclayout->oobavail;
@@ -1226,8 +1226,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
        int ret = 0, boundary = 0;
        int writesize = this->writesize;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-                       __func__, (unsigned int) from, (int) len);
+       pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
+                       (int)len);
 
        if (ops->mode == MTD_OOB_AUTO)
                oobsize = this->ecclayout->oobavail;
@@ -1357,8 +1357,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
 
        from += ops->ooboffs;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-               __func__, (unsigned int) from, (int) len);
+       pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
+                       (int)len);
 
        /* Initialize return length value */
        ops->oobretlen = 0;
@@ -1576,8 +1576,8 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
        size_t len = ops->ooblen;
        u_char *buf = ops->oobbuf;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %zi\n",
-               __func__, (unsigned int) from, len);
+       pr_debug("%s: from = 0x%08x, len = %zi\n", __func__, (unsigned int)from,
+                       len);
 
        /* Initialize return value */
        ops->oobretlen = 0;
@@ -1750,8 +1750,8 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
        /* Wait for any existing operation to clear */
        onenand_panic_wait(mtd);
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
-               __func__, (unsigned int) to, (int) len);
+       pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
+                       (int)len);
 
        /* Initialize retlen, in case of early exit */
        *retlen = 0;
@@ -1821,7 +1821,7 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 }
 
 /**
- * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
+ * onenand_fill_auto_oob - [INTERN] oob auto-placement transfer
  * @param mtd          MTD device structure
  * @param oob_buf      oob buffer
  * @param buf          source address
@@ -1883,8 +1883,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
        u_char *oobbuf;
        int ret = 0, cmd;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
-               __func__, (unsigned int) to, (int) len);
+       pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
+                       (int)len);
 
        /* Initialize retlen, in case of early exit */
        ops->retlen = 0;
@@ -2055,7 +2055,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
 
 
 /**
- * onenand_write_oob_nolock - [Internal] OneNAND write out-of-band
+ * onenand_write_oob_nolock - [INTERN] OneNAND write out-of-band
  * @param mtd          MTD device structure
  * @param to           offset to write to
  * @param len          number of bytes to write
@@ -2078,8 +2078,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 
        to += ops->ooboffs;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
-               __func__, (unsigned int) to, (int) len);
+       pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
+                       (int)len);
 
        /* Initialize retlen, in case of early exit */
        ops->oobretlen = 0;
@@ -2281,7 +2281,7 @@ static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
 }
 
 /**
- * onenand_multiblock_erase - [Internal] erase block(s) using multiblock erase
+ * onenand_multiblock_erase - [INTERN] erase block(s) using multiblock erase
  * @param mtd          MTD device structure
  * @param instr                erase instruction
  * @param region       erase region
@@ -2397,7 +2397,7 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 
 
 /**
- * onenand_block_by_block_erase - [Internal] erase block(s) using regular erase
+ * onenand_block_by_block_erase - [INTERN] erase block(s) using regular erase
  * @param mtd          MTD device structure
  * @param instr                erase instruction
  * @param region       erase region
@@ -2489,8 +2489,9 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
        struct mtd_erase_region_info *region = NULL;
        loff_t region_offset = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start=0x%012llx, len=%llu\n", __func__,
-             (unsigned long long) instr->addr, (unsigned long long) instr->len);
+       pr_debug("%s: start=0x%012llx, len=%llu\n", __func__,
+                       (unsigned long long)instr->addr,
+                       (unsigned long long)instr->len);
 
        /* Do not allow erase past end of device */
        if (unlikely((len + addr) > mtd->size)) {
@@ -2558,7 +2559,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
  */
 static void onenand_sync(struct mtd_info *mtd)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__);
+       pr_debug("%s: called\n", __func__);
 
        /* Grab the lock and see if the device is available */
        onenand_get_device(mtd, FL_SYNCING);
@@ -2922,7 +2923,7 @@ static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr,
 }
 
 /**
- * onenand_otp_write_oob_nolock - [Internal] OneNAND write out-of-band, specific to OTP
+ * onenand_otp_write_oob_nolock - [INTERN] OneNAND write out-of-band, specific to OTP
  * @param mtd          MTD device structure
  * @param to           offset to write to
  * @param len          number of bytes to write
@@ -3429,6 +3430,19 @@ static void onenand_check_features(struct mtd_info *mtd)
                else if (numbufs == 1) {
                        this->options |= ONENAND_HAS_4KB_PAGE;
                        this->options |= ONENAND_HAS_CACHE_PROGRAM;
+                       /*
+                        * There are two different 4KiB pagesize chips
+                        * and no way to detect it by H/W config values.
+                        *
+                        * To detect the correct NOP for each chips,
+                        * It should check the version ID as workaround.
+                        *
+                        * Now it has as following
+                        * KFM4G16Q4M has NOP 4 with version ID 0x0131
+                        * KFM4G16Q5M has NOP 1 with versoin ID 0x013e
+                        */
+                       if ((this->version_id & 0xf) == 0xe)
+                               this->options |= ONENAND_HAS_NOP_1;
                }
 
        case ONENAND_DEVICE_DENSITY_2Gb:
@@ -4054,6 +4068,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
                        this->ecclayout = &onenand_oob_128;
                        mtd->subpage_sft = 2;
                }
+               if (ONENAND_IS_NOP_1(this))
+                       mtd->subpage_sft = 0;
                break;
        case 64:
                this->ecclayout = &onenand_oob_64;
index fc2c16a0fd1cd4fbf4e76e33ac87578aaf0b38d7..3b9a2a9573c6aae98e2d6418f90d3870eb0dc02b 100644 (file)
@@ -153,7 +153,7 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
        block = (int) (onenand_block(this, offs) << 1);
        res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+       pr_debug("onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
                (unsigned int) offs, block >> 1, res);
 
        switch ((int) res) {
@@ -188,10 +188,8 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len = this->chipsize >> (this->erase_shift + 2);
        /* Allocate memory (2bit per block) and clear the memory bad block table */
        bbm->bbt = kzalloc(len, GFP_KERNEL);
-       if (!bbm->bbt) {
-               printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
+       if (!bbm->bbt)
                return -ENOMEM;
-       }
 
        /* Set the bad block position */
        bbm->badblockpos = ONENAND_BADBLOCK_POS;
index 3306b5b3c736b82206cd1e56ee5afd9e11bd5dfa..5474547eafc2fc271b2000bcf5c146a18b4a8372 100644 (file)
@@ -147,7 +147,6 @@ struct s3c_onenand {
        struct resource *dma_res;
        unsigned long   phys_base;
        struct completion       complete;
-       struct mtd_partition *parts;
 };
 
 #define CMD_MAP_00(dev, addr)          (dev->cmd_map(MAP_00, ((addr) << 1)))
@@ -157,8 +156,6 @@ struct s3c_onenand {
 
 static struct s3c_onenand *onenand;
 
-static const char *part_probes[] = { "cmdlinepart", NULL, };
-
 static inline int s3c_read_reg(int offset)
 {
        return readl(onenand->base + offset);
@@ -1017,13 +1014,9 @@ static int s3c_onenand_probe(struct platform_device *pdev)
        if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
                dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
 
-       err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0);
-       if (err > 0)
-               mtd_device_register(mtd, onenand->parts, err);
-       else if (err <= 0 && pdata && pdata->parts)
-               mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
-       else
-               err = mtd_device_register(mtd, NULL, 0);
+       err = mtd_device_parse_register(mtd, NULL, 0,
+                                       pdata ? pdata->parts : NULL,
+                                       pdata ? pdata->nr_parts : 0);
 
        platform_set_drvdata(pdev, mtd);
 
index 7a87d07cd79f4bcae8dcf11241d0b052fa765cd9..56e48ea7ff0530bdac72324596006bb730a7363f 100644 (file)
@@ -56,8 +56,8 @@ static inline int redboot_checksum(struct fis_image_desc *img)
 }
 
 static int parse_redboot_partitions(struct mtd_info *master,
-                             struct mtd_partition **pparts,
-                             unsigned long fis_origin)
+                                   struct mtd_partition **pparts,
+                                   struct mtd_part_parser_data *data)
 {
        int nrparts = 0;
        struct fis_image_desc *buf;
@@ -197,11 +197,10 @@ static int parse_redboot_partitions(struct mtd_info *master,
                        goto out;
                }
                new_fl->img = &buf[i];
-                if (fis_origin) {
-                        buf[i].flash_base -= fis_origin;
-                } else {
-                        buf[i].flash_base &= master->size-1;
-                }
+               if (data && data->origin)
+                       buf[i].flash_base -= data->origin;
+               else
+                       buf[i].flash_base &= master->size-1;
 
                /* I'm sure the JFFS2 code has done me permanent damage.
                 * I now think the following is _normal_
index ed3d6cd2c6dca216e097bfd5491544283be5ac11..311a9e39a9563a32fd5b2e6c18fa89a1bf61dd85 100644 (file)
@@ -34,7 +34,7 @@ module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 
-/* ------------------- sysfs attributtes ---------------------------------- */
+/* ------------------- sysfs attributes ---------------------------------- */
 struct sm_sysfs_attribute {
        struct device_attribute dev_attr;
        char *data;
@@ -138,7 +138,7 @@ static int sm_get_lba(uint8_t *lba)
        if ((lba[0] & 0xF8) != 0x10)
                return -2;
 
-       /* check parity - endianess doesn't matter */
+       /* check parity - endianness doesn't matter */
        if (hweight16(*(uint16_t *)lba) & 1)
                return -2;
 
@@ -147,7 +147,7 @@ static int sm_get_lba(uint8_t *lba)
 
 
 /*
- * Read LBA asscociated with block
+ * Read LBA associated with block
  * returns -1, if block is erased
  * returns -2 if error happens
  */
@@ -252,7 +252,7 @@ static int sm_read_sector(struct sm_ftl *ftl,
                return 0;
        }
 
-       /* User might not need the oob, but we do for data vertification */
+       /* User might not need the oob, but we do for data verification */
        if (!oob)
                oob = &tmp_oob;
 
@@ -276,7 +276,7 @@ again:
                        return ret;
        }
 
-       /* Unfortunelly, oob read will _always_ succeed,
+       /* Unfortunately, oob read will _always_ succeed,
                despite card removal..... */
        ret = mtd->read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
 
@@ -447,14 +447,14 @@ static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
 
        /* We aren't checking the return value, because we don't care */
        /* This also fails on fake xD cards, but I guess these won't expose
-               any bad blocks till fail completly */
+               any bad blocks till fail completely */
        for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
                sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
 }
 
 /*
  * Erase a block within a zone
- * If erase succedes, it updates free block fifo, otherwise marks block as bad
+ * If erase succeeds, it updates free block fifo, otherwise marks block as bad
  */
 static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
                          int put_free)
@@ -510,7 +510,7 @@ static void sm_erase_callback(struct erase_info *self)
        complete(&ftl->erase_completion);
 }
 
-/* Throughtly test that block is valid. */
+/* Thoroughly test that block is valid. */
 static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
 {
        int boffset;
@@ -526,7 +526,7 @@ static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
        for (boffset = 0; boffset < ftl->block_size;
                                        boffset += SM_SECTOR_SIZE) {
 
-               /* This shoudn't happen anyway */
+               /* This shouldn't happen anyway */
                if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
                        return -2;
 
index 5cd18979333296b738696d9430d79b2cd4ce2775..5f917f0a9609f20a90c50ef0aa8daf653eaa8515 100644 (file)
@@ -135,8 +135,7 @@ static int get_valid_cis_sector(struct mtd_info *mtd)
                                /* Found */
                                cis_sector = (int)(offset >> SECTOR_SHIFT);
                        } else {
-                               DEBUG(MTD_DEBUG_LEVEL1,
-                                       "SSFDC_RO: CIS/IDI sector not found"
+                               pr_debug("SSFDC_RO: CIS/IDI sector not found"
                                        " on %s (mtd%d)\n", mtd->name,
                                        mtd->index);
                        }
@@ -221,8 +220,7 @@ static int get_logical_address(uint8_t *oob_buf)
                        block_address >>= 1;
 
                        if (get_parity(block_address, 10) != parity) {
-                               DEBUG(MTD_DEBUG_LEVEL0,
-                                       "SSFDC_RO: logical address field%d"
+                               pr_debug("SSFDC_RO: logical address field%d"
                                        "parity error(0x%04X)\n", j+1,
                                        block_address);
                        } else {
@@ -235,7 +233,7 @@ static int get_logical_address(uint8_t *oob_buf)
        if (!ok)
                block_address = -2;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "SSFDC_RO: get_logical_address() %d\n",
+       pr_debug("SSFDC_RO: get_logical_address() %d\n",
                block_address);
 
        return block_address;
@@ -249,7 +247,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
        int ret, block_address, phys_block;
        struct mtd_info *mtd = ssfdc->mbd.mtd;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: build_block_map() nblks=%d (%luK)\n",
+       pr_debug("SSFDC_RO: build_block_map() nblks=%d (%luK)\n",
              ssfdc->map_len,
              (unsigned long)ssfdc->map_len * ssfdc->erase_size / 1024);
 
@@ -262,8 +260,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
 
                ret = read_raw_oob(mtd, offset, oob_buf);
                if (ret < 0) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                               "SSFDC_RO: mtd read_oob() failed at %lu\n",
+                       pr_debug("SSFDC_RO: mtd read_oob() failed at %lu\n",
                                offset);
                        return -1;
                }
@@ -279,8 +276,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
                        ssfdc->logic_block_map[block_address] =
                                (unsigned short)phys_block;
 
-                       DEBUG(MTD_DEBUG_LEVEL2,
-                               "SSFDC_RO: build_block_map() phys_block=%d,"
+                       pr_debug("SSFDC_RO: build_block_map() phys_block=%d,"
                                "logic_block_addr=%d, zone=%d\n",
                                phys_block, block_address, zone_index);
                }
@@ -304,11 +300,8 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                return;
 
        ssfdc = kzalloc(sizeof(struct ssfdcr_record), GFP_KERNEL);
-       if (!ssfdc) {
-               printk(KERN_WARNING
-                       "SSFDC_RO: out of memory for data structures\n");
+       if (!ssfdc)
                return;
-       }
 
        ssfdc->mbd.mtd = mtd;
        ssfdc->mbd.devnum = -1;
@@ -319,8 +312,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        ssfdc->erase_size = mtd->erasesize;
        ssfdc->map_len = (u32)mtd->size / mtd->erasesize;
 
-       DEBUG(MTD_DEBUG_LEVEL1,
-               "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
+       pr_debug("SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
                ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len,
                DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE));
 
@@ -331,7 +323,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        ssfdc->cylinders = (unsigned short)(((u32)mtd->size >> SECTOR_SHIFT) /
                        ((long)ssfdc->sectors * (long)ssfdc->heads));
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n",
+       pr_debug("SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n",
                ssfdc->cylinders, ssfdc->heads , ssfdc->sectors,
                (long)ssfdc->cylinders * (long)ssfdc->heads *
                (long)ssfdc->sectors);
@@ -342,11 +334,8 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        /* Allocate logical block map */
        ssfdc->logic_block_map = kmalloc(sizeof(ssfdc->logic_block_map[0]) *
                                         ssfdc->map_len, GFP_KERNEL);
-       if (!ssfdc->logic_block_map) {
-               printk(KERN_WARNING
-                       "SSFDC_RO: out of memory for data structures\n");
+       if (!ssfdc->logic_block_map)
                goto out_err;
-       }
        memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) *
                ssfdc->map_len);
 
@@ -371,7 +360,7 @@ static void ssfdcr_remove_dev(struct mtd_blktrans_dev *dev)
 {
        struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: remove_dev (i=%d)\n", dev->devnum);
+       pr_debug("SSFDC_RO: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
        kfree(ssfdc->logic_block_map);
@@ -387,8 +376,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
        offset = (int)(logic_sect_no % sectors_per_block);
        block_address = (int)(logic_sect_no / sectors_per_block);
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-               "SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d,"
+       pr_debug("SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d,"
                " block_addr=%d\n", logic_sect_no, sectors_per_block, offset,
                block_address);
 
@@ -397,8 +385,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
 
        block_address = ssfdc->logic_block_map[block_address];
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-               "SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n",
+       pr_debug("SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n",
                block_address);
 
        if (block_address < 0xffff) {
@@ -407,8 +394,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
                sect_no = (unsigned long)block_address * sectors_per_block +
                                offset;
 
-               DEBUG(MTD_DEBUG_LEVEL3,
-                       "SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n",
+               pr_debug("SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n",
                        sect_no);
 
                if (read_physical_sector(ssfdc->mbd.mtd, buf, sect_no) < 0)
@@ -424,7 +410,7 @@ static int ssfdcr_getgeo(struct mtd_blktrans_dev *dev,  struct hd_geometry *geo)
 {
        struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n",
+       pr_debug("SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n",
                        ssfdc->cylinders, ssfdc->heads, ssfdc->sectors);
 
        geo->heads = ssfdc->heads;
index afe71aa15c4b4493c5e2c5d50946d71122c35b98..836792d1d60ebe728e92b46190f89606a23335c3 100644 (file)
@@ -75,7 +75,8 @@ static int read_eraseblock_by_page(int ebnum)
                        ops.datbuf    = NULL;
                        ops.oobbuf    = oobbuf;
                        ret = mtd->read_oob(mtd, addr, &ops);
-                       if (ret || ops.oobretlen != mtd->oobsize) {
+                       if ((ret && ret != -EUCLEAN) ||
+                                       ops.oobretlen != mtd->oobsize) {
                                printk(PRINT_PREF "error: read oob failed at "
                                                  "%#llx\n", (long long)addr);
                                if (!err)
index 8d0314dbd946c99141d0870542376c367bbf35cb..df5e9900aa00983f337c6629f93bda6e92ae0265 100644 (file)
@@ -2,9 +2,6 @@
 # Network device configuration
 #
 
-config HAVE_NET_MACB
-       bool
-
 menuconfig NETDEVICES
        default y if UML
        depends on NET
@@ -189,2822 +186,80 @@ config MII
 
 source "drivers/net/phy/Kconfig"
 
+config SUNGEM_PHY
+       tristate
+
 #
 #      Ethernet
 #
 
-menuconfig NET_ETHERNET
-       bool "Ethernet (10 or 100Mbit)"
-       depends on !UML
-       ---help---
-         Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
-         type of Local Area Network (LAN) in universities and companies.
-
-         Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over
-         coaxial cable, linking computers in a chain), 10BASE-T or twisted
-         pair (10 Mbps over twisted pair cable, linking computers to central
-         hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs),
-         100BASE-TX (100 Mbps over two twisted pair cables, using hubs),
-         100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair
-         cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links)
-         [the 100BASE varieties are also known as Fast Ethernet], and Gigabit
-         Ethernet (1 Gbps over optical fiber or short copper links).
-
-         If your Linux machine will be connected to an Ethernet and you have
-         an Ethernet network interface card (NIC) installed in your computer,
-         say Y here and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>. You will then also have
-         to say Y to the driver for your particular NIC.
-
-         Note that the answer to this question won't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about Ethernet network cards. If unsure, say N.
-
-if NET_ETHERNET
-
-config MACB
-       tristate "Atmel MACB support"
-       depends on HAVE_NET_MACB
-       select PHYLIB
-       help
-         The Atmel MACB ethernet interface is found on many AT32 and AT91
-         parts. Say Y to include support for the MACB chip.
-
-         To compile this driver as a module, choose M here: the module
-         will be called macb.
-
-source "drivers/net/arm/Kconfig"
-
-config AX88796
-       tristate "ASIX AX88796 NE2000 clone support"
-       depends on ARM || MIPS || SUPERH
-       select PHYLIB
-       select MDIO_BITBANG
-       help
-         AX88796 driver, using platform bus to provide
-         chip detection and resources
-
-config AX88796_93CX6
-       bool "ASIX AX88796 external 93CX6 eeprom support"
-       depends on AX88796
-       select EEPROM_93CX6
-       help
-         Select this if your platform comes with an external 93CX6 eeprom.
-
-config MACE
-       tristate "MACE (Power Mac ethernet) support"
-       depends on PPC_PMAC && PPC32
-       select CRC32
-       help
-         Power Macintoshes and clones with Ethernet built-in on the
-         motherboard will usually use a MACE (Medium Access Control for
-         Ethernet) interface. Say Y to include support for the MACE chip.
-
-         To compile this driver as a module, choose M here: the module
-         will be called mace.
-
-config MACE_AAUI_PORT
-       bool "Use AAUI port instead of TP by default"
-       depends on MACE
-       help
-         Some Apple machines (notably the Apple Network Server) which use the
-         MACE ethernet chip have an Apple AUI port (small 15-pin connector),
-         instead of an 8-pin RJ45 connector for twisted-pair ethernet.  Say
-         Y here if you have such a machine.  If unsure, say N.
-         The driver will default to AAUI on ANS anyway, and if you use it as
-         a module, you can provide the port_aaui=0|1 to force the driver.
-
-config BMAC
-       tristate "BMAC (G3 ethernet) support"
-       depends on PPC_PMAC && PPC32
-       select CRC32
-       help
-         Say Y for support of BMAC Ethernet interfaces. These are used on G3
-         computers.
-
-         To compile this driver as a module, choose M here: the module
-         will be called bmac.
-
-config ARIADNE
-       tristate "Ariadne support"
-       depends on ZORRO
-       help
-         If you have a Village Tronic Ariadne Ethernet adapter, say Y.
-         Otherwise, say N.
-
-         To compile this driver as a module, choose M here: the module
-         will be called ariadne.
-
-config A2065
-       tristate "A2065 support"
-       depends on ZORRO
-       select CRC32
-       help
-         If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
-         say N.
-
-         To compile this driver as a module, choose M here: the module
-         will be called a2065.
-
-config HYDRA
-       tristate "Hydra support"
-       depends on ZORRO
-       select CRC32
-       help
-         If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
-
-         To compile this driver as a module, choose M here: the module
-         will be called hydra.
-
-config ZORRO8390
-       tristate "Zorro NS8390-based Ethernet support"
-       depends on ZORRO
-       select CRC32
-       help
-         This driver is for Zorro Ethernet cards using an NS8390-compatible
-         chipset, like the Village Tronic Ariadne II and the Individual
-         Computers X-Surf Ethernet cards. If you have such a card, say Y.
-         Otherwise, say N.
-
-         To compile this driver as a module, choose M here: the module
-         will be called zorro8390.
-
-config APNE
-       tristate "PCMCIA NE2000 support"
-       depends on AMIGA_PCMCIA
-       select CRC32
-       help
-         If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
-         say N.
-
-         To compile this driver as a module, choose M here: the module
-         will be called apne.
-
-config MAC8390
-       bool "Macintosh NS 8390 based ethernet cards"
-       depends on MAC
-       select CRC32
-       help
-         If you want to include a driver to support Nubus or LC-PDS
-         Ethernet cards using an NS8390 chipset or its equivalent, say Y
-         and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-config MAC89x0
-       tristate "Macintosh CS89x0 based ethernet cards"
-       depends on MAC
-       ---help---
-         Support for CS89x0 chipset based Ethernet cards.  If you have a
-         Nubus or LC-PDS network (Ethernet) card of this type, say Y and
-         read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. This module will
-         be called mac89x0.
-
-config MACSONIC
-       tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
-       depends on MAC
-       ---help---
-         Support for NatSemi SONIC based Ethernet devices.  This includes
-         the onboard Ethernet in many Quadras as well as some LC-PDS,
-         a few Nubus and all known Comm Slot Ethernet cards.  If you have
-         one of these say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. This module will
-         be called macsonic.
-
-config MACMACE
-       bool "Macintosh (AV) onboard MACE ethernet"
-       depends on MAC
-       select CRC32
-       help
-         Support for the onboard AMD 79C940 MACE Ethernet controller used in
-         the 660AV and 840AV Macintosh.  If you have one of these Macintoshes
-         say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-config MVME147_NET
-       tristate "MVME147 (Lance) Ethernet support"
-       depends on MVME147
-       select CRC32
-       help
-         Support for the on-board Ethernet interface on the Motorola MVME147
-         single-board computer.  Say Y here to include the
-         driver for this chip in your kernel.
-         To compile this driver as a module, choose M here.
-
-config MVME16x_NET
-       tristate "MVME16x Ethernet support"
-       depends on MVME16x
-       help
-         This is the driver for the Ethernet interface on the Motorola
-         MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the
-         driver for this chip in your kernel.
-         To compile this driver as a module, choose M here.
-
-config BVME6000_NET
-       tristate "BVME6000 Ethernet support"
-       depends on BVME6000
-       help
-         This is the driver for the Ethernet interface on BVME4000 and
-         BVME6000 VME boards.  Say Y here to include the driver for this chip
-         in your kernel.
-         To compile this driver as a module, choose M here.
-
-config ATARILANCE
-       tristate "Atari Lance support"
-       depends on ATARI
-       help
-         Say Y to include support for several Atari Ethernet adapters based
-         on the AMD Lance chipset: RieblCard (with or without battery), or
-         PAMCard VME (also the version by Rhotron, with different addresses).
-
-config SUN3LANCE
-       tristate "Sun3/Sun3x on-board LANCE support"
-       depends on SUN3 || SUN3X
-       help
-         Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
-         featured an AMD Lance 10Mbit Ethernet controller on board; say Y
-         here to compile in the Linux driver for this and enable Ethernet.
-         General Linux information on the Sun 3 and 3x series (now
-         discontinued) is at
-         <http://www.angelfire.com/ca2/tech68k/sun3.html>.
-
-         If you're not building a kernel for a Sun 3, say N.
-
-config SUN3_82586
-       bool "Sun3 on-board Intel 82586 support"
-       depends on SUN3
-       help
-         This driver enables support for the on-board Intel 82586 based
-         Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards.  Note
-         that this driver does not support 82586-based adapters on additional
-         VME boards.
-
-config HPLANCE
-       bool "HP on-board LANCE support"
-       depends on DIO
-       select CRC32
-       help
-         If you want to use the builtin "LANCE" Ethernet controller on an
-         HP300 machine, say Y here.
-
-config LASI_82596
-       tristate "Lasi ethernet"
-       depends on GSC
-       help
-         Say Y here to support the builtin Intel 82596 ethernet controller
-         found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
+source "drivers/net/ethernet/Kconfig"
 
-config SNI_82596
-       tristate "SNI RM ethernet"
-       depends on NET_ETHERNET && SNI_RM
-       help
-         Say Y here to support the on-board Intel 82596 ethernet controller
-         built into SNI RM machines.
+source "drivers/net/tokenring/Kconfig"
 
-config KORINA
-       tristate "Korina (IDT RC32434) Ethernet support"
-       depends on NET_ETHERNET && MIKROTIK_RB532
-       help
-         If you have a Mikrotik RouterBoard 500 or IDT RC32434
-         based system say Y. Otherwise say N.
+source "drivers/net/wireless/Kconfig"
 
-config MIPS_JAZZ_SONIC
-       tristate "MIPS JAZZ onboard SONIC Ethernet support"
-       depends on MACH_JAZZ
-       help
-         This is the driver for the onboard card of MIPS Magnum 4000,
-         Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
+source "drivers/net/wimax/Kconfig"
 
-config XTENSA_XT2000_SONIC
-       tristate "Xtensa XT2000 onboard SONIC Ethernet support"
-       depends on XTENSA_PLATFORM_XT2000
-       help
-         This is the driver for the onboard card of the Xtensa XT2000 board.
+source "drivers/net/usb/Kconfig"
 
-config MIPS_AU1X00_ENET
-       tristate "MIPS AU1000 Ethernet support"
-       depends on MIPS_ALCHEMY
-       select PHYLIB
-       select CRC32
-       help
-         If you have an Alchemy Semi AU1X00 based system
-         say Y.  Otherwise, say N.
+source "drivers/net/pcmcia/Kconfig"
 
-config SGI_IOC3_ETH
-       bool "SGI IOC3 Ethernet"
-       depends on PCI && SGI_IP27
-       select CRC32
-       select MII
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
+source "drivers/net/wan/Kconfig"
 
-config MIPS_SIM_NET
-       tristate "MIPS simulator Network device"
-       depends on MIPS_SIM
-       help
-         The MIPSNET device is a simple Ethernet network device which is
-         emulated by the MIPS Simulator.
-         If you are not using a MIPSsim or are unsure, say N.
+source "drivers/atm/Kconfig"
 
-config SGI_O2MACE_ETH
-       tristate "SGI O2 MACE Fast Ethernet support"
-       depends on SGI_IP32=y
+source "drivers/ieee802154/Kconfig"
 
-config STNIC
-       tristate "National DP83902AV  support"
-       depends on SUPERH
-       select CRC32
-       help
-         Support for cards based on the National Semiconductor DP83902AV
-         ST-NIC Serial Network Interface Controller for Twisted Pair.  This
-         is a 10Mbit/sec Ethernet controller.  Product overview and specs at
-         <http://www.national.com/pf/DP/DP83902A.html>.
+source "drivers/s390/net/Kconfig"
 
-         If unsure, say N.
+source "drivers/net/caif/Kconfig"
 
-config SH_ETH
-       tristate "Renesas SuperH Ethernet support"
-       depends on SUPERH && \
-               (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
-                CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
-                CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
-       select CRC32
+config MAC_PUV3
+       tristate "PKUnity v3 UMAL Gigabit Network Adapter support"
+       depends on UNICORE32 && ARCH_PUV3
        select MII
-       select MDIO_BITBANG
        select PHYLIB
-       help
-         Renesas SuperH Ethernet device driver.
-         This driver supporting CPUs are:
-               - SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
-
-config SUNLANCE
-       tristate "Sun LANCE support"
-       depends on SBUS
-       select CRC32
-       help
-         This driver supports the "le" interface present on all 32-bit Sparc
-         systems, on some older Ultra systems and as an Sbus option.  These
-         cards are based on the AMD Lance chipset, which is better known
-         via the NE2100 cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sunlance.
-
-config HAPPYMEAL
-       tristate "Sun Happy Meal 10/100baseT support"
-       depends on SBUS || PCI
-       select CRC32
-       help
-         This driver supports the "hme" interface present on most Ultra
-         systems and as an option on older Sbus systems. This driver supports
-         both PCI and Sbus devices. This driver also supports the "qfe" quad
-         100baseT device available in both PCI and Sbus configurations.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sunhme.
-
-config SUNBMAC
-       tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
-       depends on SBUS && EXPERIMENTAL
-       select CRC32
-       help
-         This driver supports the "be" interface available as an Sbus option.
-         This is Sun's older 100baseT Ethernet device.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sunbmac.
-
-config SUNQE
-       tristate "Sun QuadEthernet support"
-       depends on SBUS
-       select CRC32
-       help
-         This driver supports the "qe" 10baseT Ethernet device, available as
-         an Sbus option. Note that this is not the same as Quad FastEthernet
-         "qfe" which is supported by the Happy Meal driver instead.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sunqe.
-
-config SUNGEM
-       tristate "Sun GEM support"
-       depends on PCI
-       select CRC32
-       help
-         Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
-         <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
-
-config CASSINI
-       tristate "Sun Cassini support"
-       depends on PCI
-       select CRC32
-       help
-         Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
-         <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
-
-config SUNVNET
-       tristate "Sun Virtual Network support"
-       depends on SUN_LDOMS
-       help
-         Support for virtual network devices under Sun Logical Domains.
-
-config NET_VENDOR_3COM
-       bool "3COM cards"
-       depends on ISA || EISA || MCA || PCI
-       help
-         If you have a network (Ethernet) card belonging to this class, say Y
-         and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about 3COM cards. If you say Y, you will be asked for
-         your specific card in the following questions.
-
-config EL1
-       tristate "3c501 \"EtherLink\" support"
-       depends on NET_VENDOR_3COM && ISA
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.  Also, consider buying a
-         new card, since the 3c501 is slow, broken, and obsolete: you will
-         have problems.  Some people suggest to ping ("man ping") a nearby
-         machine every minute ("man cron") when using this card.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c501.
-
-config EL2
-       tristate "3c503 \"EtherLink II\" support"
-       depends on NET_VENDOR_3COM && ISA
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c503.
-
-config ELPLUS
-       tristate "3c505 \"EtherLink Plus\" support"
-       depends on NET_VENDOR_3COM && ISA && ISA_DMA_API
-       ---help---
-         Information about this network (Ethernet) card can be found in
-         <file:Documentation/networking/3c505.txt>.  If you have a card of
-         this type, say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c505.
-
-config EL16
-       tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
-       depends on NET_VENDOR_3COM && ISA && EXPERIMENTAL
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c507.
-
-config EL3
-       tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support"
-       depends on NET_VENDOR_3COM && (ISA || EISA || MCA)
-       ---help---
-         If you have a network (Ethernet) card belonging to the 3Com
-         EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
-         from <http://www.tldp.org/docs.html#howto>.
-
-         If your card is not working you may need to use the DOS
-         setup disk to disable Plug & Play mode, and to select the default
-         media type.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c509.
-
-config 3C515
-       tristate "3c515 ISA \"Fast EtherLink\""
-       depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API
-       help
-         If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
-         network card, say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c515.
-
-config ELMC
-       tristate "3c523 \"EtherLink/MC\" support"
-       depends on NET_VENDOR_3COM && MCA_LEGACY
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c523.
-
-config ELMC_II
-       tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
-       depends on NET_VENDOR_3COM && MCA && MCA_LEGACY
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called 3c527.
-
-config VORTEX
-       tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
-       depends on NET_VENDOR_3COM && (PCI || EISA)
-       select MII
-       ---help---
-         This option enables driver support for a large number of 10Mbps and
-         10/100Mbps EISA, PCI and PCMCIA 3Com network cards:
-
-         "Vortex"    (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
-         "Boomerang" (EtherLink XL 3c900 or 3c905)            PCI
-         "Cyclone"   (3c540/3c900/3c905/3c980/3c575/3c656)    PCI and Cardbus
-         "Tornado"   (3c905)                                  PCI
-         "Hurricane" (3c555/3cSOHO)                           PCI
-
-         If you have such a card, say Y and read the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>. More
-         specific information is in
-         <file:Documentation/networking/vortex.txt> and in the comments at
-         the beginning of <file:drivers/net/3c59x.c>.
-
-         To compile this support as a module, choose M here.
-
-config TYPHOON
-       tristate "3cr990 series \"Typhoon\" support"
-       depends on NET_VENDOR_3COM && PCI
-       select CRC32
-       ---help---
-         This option enables driver support for the 3cr990 series of cards:
-
-         3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
-         3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
-         3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
-
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
 
-         To compile this driver as a module, choose M here. The module
-         will be called typhoon.
-
-config LANCE
-       tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
-       depends on ISA && ISA_DMA_API
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
-         of this type.
-
-         To compile this driver as a module, choose M here: the module
-         will be called lance.  This is recommended.
-
-config NET_VENDOR_SMC
-       bool "Western Digital/SMC cards"
-       depends on ISA || MCA || EISA || MAC
-       help
-         If you have a network (Ethernet) card belonging to this class, say Y
-         and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about Western Digital cards. If you say Y, you will be
-         asked for your specific card in the following questions.
-
-config WD80x3
-       tristate "WD80*3 support"
-       depends on NET_VENDOR_SMC && ISA
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called wd.
-
-config ULTRAMCA
-       tristate "SMC Ultra MCA support"
-       depends on NET_VENDOR_SMC && MCA
-       select CRC32
+config XEN_NETDEV_FRONTEND
+       tristate "Xen network device frontend driver"
+       depends on XEN
+       select XEN_XENBUS_FRONTEND
+       default y
        help
-         If you have a network (Ethernet) card of this type and are running
-         an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called smc-mca.
-
-config ULTRA
-       tristate "SMC Ultra support"
-       depends on NET_VENDOR_SMC && ISA
-       select CRC32
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
+         This driver provides support for Xen paravirtual network
+         devices exported by a Xen network driver domain (often
+         domain 0).
 
-         Important: There have been many reports that, with some motherboards
-         mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
-         such as some BusLogic models) causes corruption problems with many
-         operating systems. The Linux smc-ultra driver has a work-around for
-         this but keep it in mind if you have such a SCSI card and have
-         problems.
+         The corresponding Linux backend driver is enabled by the
+         CONFIG_XEN_NETDEV_BACKEND option.
 
-         To compile this driver as a module, choose M here. The module
-         will be called smc-ultra.
+         If you are compiling a kernel for use as Xen guest, you
+         should say Y here. To compile this driver as a module, chose
+         M here: the module will be called xen-netfront.
 
-config ULTRA32
-       tristate "SMC Ultra32 EISA support"
-       depends on NET_VENDOR_SMC && EISA
-       select CRC32
+config XEN_NETDEV_BACKEND
+       tristate "Xen backend network device"
+       depends on XEN_BACKEND
        help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called smc-ultra32.
+         This driver allows the kernel to act as a Xen network driver
+         domain which exports paravirtual network devices to other
+         Xen domains. These devices can be accessed by any operating
+         system that implements a compatible front end.
 
-config BFIN_MAC
-       tristate "Blackfin on-chip MAC support"
-       depends on NET_ETHERNET && (BF516 || BF518 || BF526 || BF527 || BF536 || BF537)
-       select CRC32
-       select MII
-       select PHYLIB
-       select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
-       help
-         This is the driver for Blackfin on-chip mac device. Say Y if you want it
-         compiled into the kernel. This driver is also available as a module
-         ( = code which can be inserted in and removed from the running kernel
-         whenever you want). The module will be called bfin_mac.
-
-config BFIN_MAC_USE_L1
-       bool "Use L1 memory for rx/tx packets"
-       depends on BFIN_MAC && (BF527 || BF537)
-       default y
-       help
-         To get maximum network performance, you should use L1 memory as rx/tx buffers.
-         Say N here if you want to reserve L1 memory for other uses.
-
-config BFIN_TX_DESC_NUM
-       int "Number of transmit buffer packets"
-       depends on BFIN_MAC
-       range 6 10 if BFIN_MAC_USE_L1
-       range 10 100
-       default "10"
-       help
-         Set the number of buffer packets used in driver.
-
-config BFIN_RX_DESC_NUM
-       int "Number of receive buffer packets"
-       depends on BFIN_MAC
-       range 20 100 if BFIN_MAC_USE_L1
-       range 20 800
-       default "20"
-       help
-         Set the number of buffer packets used in driver.
+         The corresponding Linux frontend driver is enabled by the
+         CONFIG_XEN_NETDEV_FRONTEND configuration option.
 
-config BFIN_MAC_USE_HWSTAMP
-       bool "Use IEEE 1588 hwstamp"
-       depends on BFIN_MAC && BF518
-       default y
-       help
-         To support the IEEE 1588 Precision Time Protocol (PTP), select y here
-
-config SMC9194
-       tristate "SMC 9194 support"
-       depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
-       select CRC32
-       ---help---
-         This is support for the SMC9xxx based Ethernet cards. Choose this
-         option if you have a DELL laptop with the docking station, or
-         another SMC9192/9194 based chipset.  Say Y if you want it compiled
-         into the kernel, and read the file
-         <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called smc9194.
-
-config SMC91X
-       tristate "SMC 91C9x/91C1xxx support"
-       select CRC32
-       select MII
-       depends on ARM || M32R || SUPERH || \
-               MIPS || BLACKFIN || MN10300 || COLDFIRE
-       help
-         This is a driver for SMC's 91x series of Ethernet chipsets,
-         including the SMC91C94 and the SMC91C111. Say Y if you want it
-         compiled into the kernel, and read the file
-         <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO,
-         available from  <http://www.tldp.org/docs.html#howto>.
-
-         This driver is also available as a module ( = code which can be
-         inserted in and removed from the running kernel whenever you want).
-         The module will be called smc91x.  If you want to compile it as a
-         module, say M here and read <file:Documentation/kbuild/modules.txt>.
-
-config PXA168_ETH
-       tristate "Marvell pxa168 ethernet support"
-       depends on CPU_PXA168
-       select PHYLIB
-       help
-         This driver supports the pxa168 Ethernet ports.
-
-         To compile this driver as a module, choose M here. The module
-         will be called pxa168_eth.
-
-config NET_NETX
-       tristate "NetX Ethernet support"
-       select MII
-       depends on ARCH_NETX
-       help
-         This is support for the Hilscher netX builtin Ethernet ports
-
-         To compile this driver as a module, choose M here. The module
-         will be called netx-eth.
-
-config TI_DAVINCI_EMAC
-       tristate "TI DaVinci EMAC Support"
-       depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
-       select TI_DAVINCI_MDIO
-       select TI_DAVINCI_CPDMA
-       select PHYLIB
-       help
-         This driver supports TI's DaVinci Ethernet .
-
-         To compile this driver as a module, choose M here: the module
-         will be called davinci_emac_driver.  This is recommended.
-
-config TI_DAVINCI_MDIO
-       tristate "TI DaVinci MDIO Support"
-       depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
-       select PHYLIB
-       help
-         This driver supports TI's DaVinci MDIO module.
-
-         To compile this driver as a module, choose M here: the module
-         will be called davinci_mdio.  This is recommended.
-
-config TI_DAVINCI_CPDMA
-       tristate "TI DaVinci CPDMA Support"
-       depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
-       help
-         This driver supports TI's DaVinci CPDMA dma engine.
-
-         To compile this driver as a module, choose M here: the module
-         will be called davinci_cpdma.  This is recommended.
-
-config DM9000
-       tristate "DM9000 support"
-       depends on ARM || BLACKFIN || MIPS
-       select CRC32
-       select MII
-       ---help---
-         Support for DM9000 chipset.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called dm9000.
-
-config DM9000_DEBUGLEVEL
-       int "DM9000 maximum debug level"
-       depends on DM9000
-       default 4
-       help
-         The maximum level of debugging code compiled into the DM9000
-         driver.
-
-config DM9000_FORCE_SIMPLE_PHY_POLL
-       bool "Force simple NSR based PHY polling"
-       depends on DM9000
-       ---help---
-         This configuration forces the DM9000 to use the NSR's LinkStatus
-         bit to determine if the link is up or down instead of the more
-         costly MII PHY reads. Note, this will not work if the chip is
-         operating with an external PHY.
-
-config ENC28J60
-       tristate "ENC28J60 support"
-       depends on EXPERIMENTAL && SPI && NET_ETHERNET
-       select CRC32
-       ---help---
-         Support for the Microchip EN28J60 ethernet chip.
-
-         To compile this driver as a module, choose M here. The module will be
-         called enc28j60.
-
-config ENC28J60_WRITEVERIFY
-       bool "Enable write verify"
-       depends on ENC28J60
-       ---help---
-         Enable the verify after the buffer write useful for debugging purpose.
-         If unsure, say N.
-
-config ETHOC
-       tristate "OpenCores 10/100 Mbps Ethernet MAC support"
-       depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA
-       select MII
-       select PHYLIB
-       select CRC32
-       select BITREVERSE
-       help
-         Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
-
-config GRETH
-       tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
-       depends on SPARC
-       select PHYLIB
-       select CRC32
-       help
-         Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
-
-config SMC911X
-       tristate "SMSC LAN911[5678] support"
-       select CRC32
-       select MII
-       depends on ARM || SUPERH || MN10300
-       help
-         This is a driver for SMSC's LAN911x series of Ethernet chipsets
-         including the new LAN9115, LAN9116, LAN9117, and LAN9118.
-         Say Y if you want it compiled into the kernel, 
-         and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         This driver is also available as a module. The module will be 
-         called smc911x.  If you want to compile it as a module, say M 
-         here and read <file:Documentation/kbuild/modules.txt>
-
-config SMSC911X
-       tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
-       depends on ARM || SUPERH || BLACKFIN || MIPS || MN10300
-       select CRC32
-       select MII
-       select PHYLIB
-       ---help---
-         Say Y here if you want support for SMSC LAN911x and LAN921x families
-         of ethernet controllers.
-
-         To compile this driver as a module, choose M here and read
-         <file:Documentation/networking/net-modules.txt>. The module
-         will be called smsc911x.
-
-config SMSC911X_ARCH_HOOKS
-       def_bool n
-       depends on SMSC911X
-       help
-         If the arch enables this, it allows the arch to implement various
-         hooks for more comprehensive interrupt control and also to override
-         the source of the MAC address.
-
-config NET_VENDOR_RACAL
-       bool "Racal-Interlan (Micom) NI cards"
-       depends on ISA
-       help
-         If you have a network (Ethernet) card belonging to this class, such
-         as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about NI cards. If you say Y, you will be asked for
-         your specific card in the following questions.
-
-config NI5010
-       tristate "NI5010 support (EXPERIMENTAL)"
-       depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>. Note that this is still
-         experimental code.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ni5010.
-
-config NI52
-       tristate "NI5210 support"
-       depends on NET_VENDOR_RACAL && ISA
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ni52.
-
-config NI65
-       tristate "NI6510 support"
-       depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ni65.
-
-config DNET
-       tristate "Dave ethernet support (DNET)"
-       depends on NET_ETHERNET && HAS_IOMEM
-       select PHYLIB
-       help
-         The Dave ethernet interface (DNET) is found on Qong Board FPGA.
-         Say Y to include support for the DNET chip.
-
-         To compile this driver as a module, choose M here: the module
-         will be called dnet.
-
-source "drivers/net/tulip/Kconfig"
-
-config AT1700
-       tristate "AT1700/1720 support (EXPERIMENTAL)"
-       depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
-       select CRC32
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called at1700.
-
-config DEPCA
-       tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
-       depends on ISA || EISA || MCA
-       select CRC32
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto> as well as
-         <file:drivers/net/depca.c>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called depca.
-
-config HP100
-       tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
-       depends on ISA || EISA || PCI
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called hp100.
-
-config NET_ISA
-       bool "Other ISA cards"
-       depends on ISA
-       ---help---
-         If your network (Ethernet) card hasn't been mentioned yet and its
-         bus system (that's the way the cards talks to the other components
-         of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y.
-         Make sure you know the name of your card. Read the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         If unsure, say Y.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the remaining ISA network card questions. If you say Y, you will be
-         asked for your specific card in the following questions.
-
-config E2100
-       tristate "Cabletron E21xx support"
-       depends on NET_ISA
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called e2100.
-
-config EWRK3
-       tristate "EtherWORKS 3 (DE203, DE204, DE205) support"
-       depends on NET_ISA
-       select CRC32
-       ---help---
-         This driver supports the DE203, DE204 and DE205 network (Ethernet)
-         cards. If this is for you, say Y and read
-         <file:Documentation/networking/ewrk3.txt> in the kernel source as
-         well as the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ewrk3.
-
-config EEXPRESS
-       tristate "EtherExpress 16 support"
-       depends on NET_ISA
-       ---help---
-         If you have an EtherExpress16 network (Ethernet) card, say Y and
-         read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.  Note that the Intel
-         EtherExpress16 card used to be regarded as a very poor choice
-         because the driver was very unreliable. We now have a new driver
-         that should do better.
-
-         To compile this driver as a module, choose M here. The module
-         will be called eexpress.
-
-config EEXPRESS_PRO
-       tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
-       depends on NET_ISA
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y. This
-         driver supports Intel i82595{FX,TX} based boards. Note however
-         that the EtherExpress PRO/100 Ethernet card has its own separate
-         driver.  Please read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called eepro.
-
-config HPLAN_PLUS
-       tristate "HP PCLAN+ (27247B and 27252A) support"
-       depends on NET_ISA
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called hp-plus.
-
-config HPLAN
-       tristate "HP PCLAN (27245 and other 27xxx series) support"
-       depends on NET_ISA
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called hp.
-
-config LP486E
-       tristate "LP486E on board Ethernet"
-       depends on NET_ISA
-       help
-         Say Y here to support the 82596-based on-board Ethernet controller
-         for the Panther motherboard, which is one of the two shipped in the
-         Intel Professional Workstation.
-
-config ETH16I
-       tristate "ICL EtherTeam 16i/32 support"
-       depends on NET_ISA
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called eth16i.
-
-config NE2000
-       tristate "NE2000/NE1000 support"
-       depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
-       select CRC32
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.  Many Ethernet cards
-         without a specific driver are compatible with NE2000.
-
-         If you have a PCI NE2000 card however, say N here and Y to "PCI
-         NE2000 and clone support" under "EISA, VLB, PCI and on board
-         controllers" below. If you have a NE2000 card and are running on
-         an MCA system (a bus system used on some IBM PS/2 computers and
-         laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
-         below.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ne.
-
-config ZNET
-       tristate "Zenith Z-Note support (EXPERIMENTAL)"
-       depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API
-       help
-         The Zenith Z-Note notebook computer has a built-in network
-         (Ethernet) card, and this is the Linux driver for it. Note that the
-         IBM Thinkpad 300 is compatible with the Z-Note and is also supported
-         by this driver. Read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-config SEEQ8005
-       tristate "SEEQ8005 support (EXPERIMENTAL)"
-       depends on NET_ISA && EXPERIMENTAL
-       help
-         This is a driver for the SEEQ 8005 network (Ethernet) card.  If this
-         is for you, read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called seeq8005.
-
-config NE2_MCA
-       tristate "NE/2 (ne2000 MCA version) support"
-       depends on MCA_LEGACY
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ne2.
-
-config IBMLANA
-       tristate "IBM LAN Adapter/A support"
-       depends on MCA
-       ---help---
-         This is a Micro Channel Ethernet adapter.  You need to set
-         CONFIG_MCA to use this driver.  It is both available as an in-kernel
-         driver and as a module.
-
-         To compile this driver as a module, choose M here. The only
-         currently supported card is the IBM LAN Adapter/A for Ethernet.  It
-         will both support 16K and 32K memory windows, however a 32K window
-         gives a better security against packet losses.  Usage of multiple
-         boards with this driver should be possible, but has not been tested
-         up to now due to lack of hardware.
-
-config IBMVETH
-       tristate "IBM LAN Virtual Ethernet support"
-       depends on PPC_PSERIES
-       ---help---
-         This driver supports virtual ethernet adapters on newer IBM iSeries
-         and pSeries systems.
-
-         To compile this driver as a module, choose M here. The module will
-         be called ibmveth.
-
-source "drivers/net/ibm_newemac/Kconfig"
-
-config NET_PCI
-       bool "EISA, VLB, PCI and on board controllers"
-       depends on ISA || EISA || PCI
-       help
-         This is another class of network cards which attach directly to the
-         bus. If you have one of those, say Y and read the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about this class of network cards. If you say Y, you
-         will be asked for your specific card in the following questions. If
-         you are unsure, say Y.
-
-config PCNET32
-       tristate "AMD PCnet32 PCI support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
-         answer Y here and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called pcnet32.
-
-config AMD8111_ETH
-       tristate "AMD 8111 (new PCI lance) support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         If you have an AMD 8111-based PCI lance ethernet card,
-         answer Y here and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called amd8111e.
-
-config ADAPTEC_STARFIRE
-       tristate "Adaptec Starfire/DuraLAN support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
-         adapter. The DuraLAN chip is used on the 64 bit PCI boards from
-         Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
-         driver.
-
-         To compile this driver as a module, choose M here: the module
-         will be called starfire.  This is recommended.
-
-config AC3200
-       tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
-       depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ac3200.
-
-config KSZ884X_PCI
-       tristate "Micrel KSZ8841/2 PCI"
-       depends on NET_PCI && PCI
-       select MII
-       select CRC32
-       help
-         This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ksz884x.
-
-config APRICOT
-       tristate "Apricot Xen-II on board Ethernet"
-       depends on NET_PCI && ISA
-       help
-         If you have a network (Ethernet) controller of this type, say Y and
-         read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called apricot.
-
-config B44
-       tristate "Broadcom 440x/47xx ethernet support"
-       depends on SSB_POSSIBLE && HAS_DMA
-       select SSB
-       select MII
-       help
-         If you have a network (Ethernet) controller of this type, say Y
-         or M and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called b44.
-
-# Auto-select SSB PCI-HOST support, if possible
-config B44_PCI_AUTOSELECT
-       bool
-       depends on B44 && SSB_PCIHOST_POSSIBLE
-       select SSB_PCIHOST
-       default y
-
-# Auto-select SSB PCICORE driver, if possible
-config B44_PCICORE_AUTOSELECT
-       bool
-       depends on B44 && SSB_DRIVER_PCICORE_POSSIBLE
-       select SSB_DRIVER_PCICORE
-       default y
-
-config B44_PCI
-       bool
-       depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
-       default y
-
-config FORCEDETH
-       tristate "nForce Ethernet support"
-       depends on NET_PCI && PCI
-       help
-         If you have a network (Ethernet) controller of this type, say Y and
-         read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called forcedeth.
-
-config CS89x0
-       tristate "CS89x0 support"
-       depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
-               || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
-       ---help---
-         Support for CS89x0 chipset based Ethernet cards. If you have a
-         network (Ethernet) card of this type, say Y and read the
-         Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto> as well as
-         <file:Documentation/networking/cs89x0.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called cs89x0.
-
-config CS89x0_NONISA_IRQ
-       def_bool y
-       depends on CS89x0 != n
-       depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
-
-config TC35815
-       tristate "TOSHIBA TC35815 Ethernet support"
-       depends on NET_PCI && PCI && MIPS
-       select PHYLIB
-
-config E100
-       tristate "Intel(R) PRO/100+ support"
-       depends on NET_PCI && PCI
-       select MII
-       ---help---
-         This driver supports Intel(R) PRO/100 family of adapters.
-         To verify that your adapter is supported, find the board ID number 
-         on the adapter. Look for a label that has a barcode and a number 
-         in the format 123456-001 (six digits hyphen three digits). 
-
-         Use the above information and the Adapter & Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         to identify the adapter.
-
-         For the latest Intel PRO/100 network driver for Linux, see:
-
-         <http://www.intel.com/p/en_US/support/highlights/network/pro100plus>
-
-         More specific information on configuring the driver is in 
-         <file:Documentation/networking/e100.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called e100.
-
-config LNE390
-       tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
-       depends on NET_PCI && EISA && EXPERIMENTAL
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called lne390.
-
-config FEALNX
-       tristate "Myson MTD-8xx PCI Ethernet support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         Say Y here to support the Myson MTD-800 family of PCI-based Ethernet 
-         cards. <http://www.myson.com.tw/>
-
-config NATSEMI
-       tristate "National Semiconductor DP8381x series PCI Ethernet support"
-       depends on NET_PCI && PCI
-       select CRC32
-       help
-         This driver is for the National Semiconductor DP83810 series,
-         which is used in cards from PureData, NetGear, Linksys
-         and others, including the 83815 chip.
-         More specific information and updates are available from
-         <http://www.scyld.com/network/natsemi.html>.
-
-config NE2K_PCI
-       tristate "PCI NE2000 and clones support (see help)"
-       depends on NET_PCI && PCI
-       select CRC32
-       ---help---
-         This driver is for NE2000 compatible PCI cards. It will not work
-         with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
-         support" below). If you have a PCI NE2000 network (Ethernet) card,
-         say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         This driver also works for the following NE2000 clone cards:
-         RealTek RTL-8029  Winbond 89C940  Compex RL2000  KTI ET32P2
-         NetVin NV5000SC   Via 86C926      SureCom NE34   Winbond
-         Holtek HT80232    Holtek HT80229
-
-         To compile this driver as a module, choose M here. The module
-         will be called ne2k-pci.
-
-config NE3210
-       tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)"
-       depends on NET_PCI && EISA && EXPERIMENTAL
-       select CRC32
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.  Note that this driver
-         will NOT WORK for NE3200 cards as they are completely different.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ne3210.
-
-config ES3210
-       tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)"
-       depends on NET_PCI && EISA && EXPERIMENTAL
-       select CRC32
-       help
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called es3210.
-
-config 8139CP
-       tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)"
-       depends on NET_PCI && PCI && EXPERIMENTAL
-       select CRC32
-       select MII
-       help
-         This is a driver for the Fast Ethernet PCI network cards based on
-         the RTL8139C+ chips. If you have one of those, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8139cp.  This is recommended.
-
-config 8139TOO
-       tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       ---help---
-         This is a driver for the Fast Ethernet PCI network cards based on
-         the RTL 8129/8130/8139 chips. If you have one of those, say Y and
-         read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here: the module
-         will be called 8139too.  This is recommended.
-
-config 8139TOO_PIO
-       bool "Use PIO instead of MMIO"
-       default y
-       depends on 8139TOO
-       help
-         This instructs the driver to use programmed I/O ports (PIO) instead
-         of PCI shared memory (MMIO).  This can possibly solve some problems
-         in case your mainboard has memory consistency issues.  If unsure,
-         say N.
-
-config 8139TOO_TUNE_TWISTER
-       bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
-       depends on 8139TOO
-       help
-         This implements a function which might come in handy in case you
-         are using low quality on long cabling. It is required for RealTek
-         RTL-8139 revision K boards, and totally unused otherwise.  It tries
-         to match the transceiver to the cable characteristics. This is
-         experimental since hardly documented by the manufacturer.
-         If unsure, say Y.
-
-config 8139TOO_8129
-       bool "Support for older RTL-8129/8130 boards"
-       depends on 8139TOO
-       help
-         This enables support for the older and uncommon RTL-8129 and
-         RTL-8130 chips, which support MII via an external transceiver,
-         instead of an internal one.  Disabling this option will save some
-         memory by making the code size smaller.  If unsure, say Y.
-
-config 8139_OLD_RX_RESET
-       bool "Use older RX-reset method"
-       depends on 8139TOO
-       help
-         The 8139too driver was recently updated to contain a more rapid
-         reset sequence, in the face of severe receive errors.  This "new"
-         RX-reset method should be adequate for all boards.  But if you
-         experience problems, you can enable this option to restore the
-         old RX-reset behavior.  If unsure, say N.
-
-config R6040
-       tristate "RDC R6040 Fast Ethernet Adapter support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       select PHYLIB
-       help
-         This is a driver for the R6040 Fast Ethernet MACs found in the
-         the RDC R-321x System-on-chips.
-
-         To compile this driver as a module, choose M here: the module
-         will be called r6040. This is recommended.
-
-config SIS900
-       tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       ---help---
-         This is a driver for the Fast Ethernet PCI network cards based on
-         the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
-         SiS 630 and SiS 540 chipsets.
-
-         This driver also supports AMD 79C901 HomePNA so that you can use
-         your phone line as a network cable.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sis900.  This is recommended.
-
-config EPIC100
-       tristate "SMC EtherPower II"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
-         which is based on the SMC83c17x (EPIC/100).
-         More specific information and updates are available from
-         <http://www.scyld.com/network/epic100.html>.
-
-config SMSC9420
-       tristate "SMSC LAN9420 PCI ethernet adapter support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select PHYLIB
-       select SMSC_PHY
-       help
-         This is a driver for SMSC's LAN9420 PCI ethernet adapter.
-         Say Y if you want it compiled into the kernel,
-         and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         This driver is also available as a module. The module will be
-         called smsc9420.  If you want to compile it as a module, say M
-         here and read <file:Documentation/kbuild/modules.txt>
-
-config SUNDANCE
-       tristate "Sundance Alta support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         This driver is for the Sundance "Alta" chip.
-         More specific information and updates are available from
-         <http://www.scyld.com/network/sundance.html>.
-
-config SUNDANCE_MMIO
-       bool "Use MMIO instead of PIO"
-       depends on SUNDANCE
-       help
-         Enable memory-mapped I/O for interaction with Sundance NIC registers.
-         Do NOT enable this by default, PIO (enabled when MMIO is disabled)
-         is known to solve bugs on certain chips.
-
-         If unsure, say N.
-
-config TLAN
-       tristate "TI ThunderLAN support"
-       depends on NET_PCI && (PCI || EISA)
-       ---help---
-         If you have a PCI Ethernet network card based on the ThunderLAN chip
-         which is supported by this driver, say Y and read the
-         Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         Devices currently supported by this driver are Compaq Netelligent,
-         Compaq NetFlex and Olicom cards.  Please read the file
-         <file:Documentation/networking/tlan.txt> for more details.
-
-         To compile this driver as a module, choose M here. The module
-         will be called tlan.
-
-         Please email feedback to <torben.mathiasen@compaq.com>.
-
-config KS8842
-       tristate "Micrel KSZ8841/42 with generic bus interface"
-       depends on HAS_IOMEM && DMA_ENGINE
-       help
-         This platform driver is for KSZ8841(1-port) / KS8842(2-port)
-         ethernet switch chip (managed, VLAN, QoS) from Micrel or
-         Timberdale(FPGA).
-
-config KS8851
-       tristate "Micrel KS8851 SPI"
-       depends on SPI
-       select MII
-       select CRC32
-       help
-         SPI driver for Micrel KS8851 SPI attached network chip.
-
-config KS8851_MLL
-       tristate "Micrel KS8851 MLL"
-       depends on HAS_IOMEM
-       select MII
-       help
-         This platform driver is for Micrel KS8851 Address/data bus
-         multiplexed network chip.
-
-config VIA_RHINE
-       tristate "VIA Rhine support"
-       depends on NET_PCI && PCI
-       select CRC32
-       select MII
-       help
-         If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
-         Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
-         Ethernet functions can also be found integrated on South Bridges
-         (e.g. VT8235).
-
-         To compile this driver as a module, choose M here. The module
-         will be called via-rhine.
-
-config VIA_RHINE_MMIO
-       bool "Use MMIO instead of PIO"
-       depends on VIA_RHINE
-       help
-         This instructs the driver to use PCI shared memory (MMIO) instead of
-         programmed I/O ports (PIO). Enabling this gives an improvement in
-         processing time in parts of the driver.
-
-         If unsure, say Y.
-
-config SC92031
-       tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
-       depends on NET_PCI && PCI && EXPERIMENTAL
-       select CRC32
-       ---help---
-         This is a driver for the Fast Ethernet PCI network cards based on
-         the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you
-         have one of these, say Y here.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sc92031.  This is recommended.
-
-config CPMAC
-       tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
-       depends on NET_ETHERNET && EXPERIMENTAL && AR7
-       select PHYLIB
-       help
-         TI AR7 CPMAC Ethernet support
-
-config NET_POCKET
-       bool "Pocket and portable adapters"
-       depends on PARPORT
-       ---help---
-         Cute little network (Ethernet) devices which attach to the parallel
-         port ("pocket adapters"), commonly used with laptops. If you have
-         one of those, say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         If you want to plug a network (or some other) card into the PCMCIA
-         (or PC-card) slot of your laptop instead (PCMCIA is the standard for
-         credit card size extension cards used by all modern laptops), you
-         need the pcmcia-cs package (location contained in the file
-         <file:Documentation/Changes>) and you can say N here.
-
-         Laptop users should read the Linux Laptop home page at
-         <http://www.linux-on-laptops.com/> or
-         Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about this class of network devices. If you say Y, you
-         will be asked for your specific device in the following questions.
-
-config ATP
-       tristate "AT-LAN-TEC/RealTek pocket adapter support"
-       depends on NET_POCKET && PARPORT && X86
-       select CRC32
-       ---help---
-         This is a network (Ethernet) device which attaches to your parallel
-         port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>, if you
-         want to use this.  If you intend to use this driver, you should have
-         said N to the "Parallel printer support", because the two drivers
-         don't like each other.
-
-         To compile this driver as a module, choose M here: the module
-         will be called atp.
-
-config DE600
-       tristate "D-Link DE600 pocket adapter support"
-       depends on NET_POCKET && PARPORT
-       ---help---
-         This is a network (Ethernet) device which attaches to your parallel
-         port. Read <file:Documentation/networking/DLINK.txt> as well as the
-         Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>, if you want to use
-         this. It is possible to have several devices share a single parallel
-         port and it is safe to compile the corresponding drivers into the
-         kernel.
-
-         To compile this driver as a module, choose M here: the module
-         will be called de600.
-
-config DE620
-       tristate "D-Link DE620 pocket adapter support"
-       depends on NET_POCKET && PARPORT
-       ---help---
-         This is a network (Ethernet) device which attaches to your parallel
-         port. Read <file:Documentation/networking/DLINK.txt> as well as the
-         Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>, if you want to use
-         this. It is possible to have several devices share a single parallel
-         port and it is safe to compile the corresponding drivers into the
-         kernel.
-
-         To compile this driver as a module, choose M here: the module
-         will be called de620.
-
-config SGISEEQ
-       tristate "SGI Seeq ethernet controller support"
-       depends on SGI_HAS_SEEQ
-       help
-         Say Y here if you have an Seeq based Ethernet network card. This is
-         used in many Silicon Graphics machines.
-
-config DECLANCE
-       tristate "DEC LANCE ethernet controller support"
-       depends on MACH_DECSTATION
-       select CRC32
-       help
-         This driver is for the series of Ethernet controllers produced by
-         DEC (now Compaq) based on the AMD Lance chipset, including the
-         DEPCA series.  (This chipset is better known via the NE2100 cards.)
-
-config FEC
-       bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
-       depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
-               IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC
-       default IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC if ARM
-       select PHYLIB
-       help
-         Say Y here if you want to use the built-in 10/100 Fast ethernet
-         controller on some Motorola ColdFire and Freescale i.MX processors.
-
-config FEC_MPC52xx
-       tristate "MPC52xx FEC driver"
-       depends on PPC_MPC52xx && PPC_BESTCOMM
-       select CRC32
-       select PHYLIB
-       select PPC_BESTCOMM_FEC
-       ---help---
-         This option enables support for the MPC5200's on-chip
-         Fast Ethernet Controller
-         If compiled as module, it will be called fec_mpc52xx.
-
-config FEC_MPC52xx_MDIO
-       bool "MPC52xx FEC MDIO bus driver"
-       depends on FEC_MPC52xx
-       default y
-       ---help---
-         The MPC5200's FEC can connect to the Ethernet either with
-         an external MII PHY chip or 10 Mbps 7-wire interface
-         (Motorola? industry standard).
-         If your board uses an external PHY connected to FEC, enable this.
-         If not sure, enable.
-         If compiled as module, it will be called fec_mpc52xx_phy.
-
-config NE_H8300
-       tristate "NE2000 compatible support for H8/300"
-       depends on H8300
-       help
-         Say Y here if you want to use the NE2000 compatible
-         controller on the Renesas H8/300 processor.
-
-config ATL2
-       tristate "Atheros L2 Fast Ethernet support"
-       depends on PCI
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros L2 fast ethernet adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl2.
-
-config XILINX_EMACLITE
-       tristate "Xilinx 10/100 Ethernet Lite support"
-       depends on PPC32 || MICROBLAZE
-       select PHYLIB
-       help
-         This driver supports the 10/100 Ethernet Lite from Xilinx.
-
-config BCM63XX_ENET
-       tristate "Broadcom 63xx internal mac support"
-       depends on BCM63XX
-       select MII
-       select PHYLIB
-       help
-         This driver supports the ethernet MACs in the Broadcom 63xx
-         MIPS chipset family (BCM63XX).
-
-config FTMAC100
-       tristate "Faraday FTMAC100 10/100 Ethernet support"
-       depends on ARM
-       select MII
-       help
-         This driver supports the FTMAC100 10/100 Ethernet controller
-         from Faraday. It is used on Faraday A320, Andes AG101 and some
-         other ARM/NDS32 SoC's.
-
-config LANTIQ_ETOP
-       tristate "Lantiq SoC ETOP driver"
-       depends on SOC_TYPE_XWAY
-       help
-         Support for the MII0 inside the Lantiq SoC
-
-
-source "drivers/net/fs_enet/Kconfig"
-
-source "drivers/net/octeon/Kconfig"
-
-endif # NET_ETHERNET
-
-#
-#      Gigabit Ethernet
-#
-
-menuconfig NETDEV_1000
-       bool "Ethernet (1000 Mbit)"
-       depends on !UML
-       default y
-       ---help---
-         Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
-         type of Local Area Network (LAN) in universities and companies.
-
-         Say Y here to get to see options for Gigabit Ethernet drivers.
-         This option alone does not add any kernel code.
-         Note that drivers supporting both 100 and 1000 MBit may be listed
-         under "Ethernet (10 or 100MBit)" instead.
-
-         If you say N, all options in this submenu will be skipped and disabled.
-
-if NETDEV_1000
-
-config ACENIC
-       tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
-       depends on PCI
-       ---help---
-         Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
-         GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
-         adapter. The driver allows for using the Jumbo Frame option (9000
-         bytes/frame) however it requires that your switches can handle this
-         as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig
-         line.
-
-         To compile this driver as a module, choose M here: the
-         module will be called acenic.
-
-config ACENIC_OMIT_TIGON_I
-       bool "Omit support for old Tigon I based AceNICs"
-       depends on ACENIC
-       help
-         Say Y here if you only have Tigon II based AceNICs and want to leave
-         out support for the older Tigon I based cards which are no longer
-         being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
-         version)).  This will reduce the size of the driver object by
-         app. 100KB.  If you are not sure whether your card is a Tigon I or a
-         Tigon II, say N here.
-
-         The safe and default value for this is N.
-
-config DL2K
-       tristate "DL2000/TC902x-based Gigabit Ethernet support"
-       depends on PCI
-       select CRC32
-       help
-         This driver supports DL2000/TC902x-based Gigabit ethernet cards,
-         which includes
-         D-Link DGE-550T Gigabit Ethernet Adapter.
-         D-Link DL2000-based Gigabit Ethernet Adapter.
-         Sundance/Tamarack TC902x Gigabit Ethernet Adapter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called dl2k.
-
-config E1000
-       tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
-       depends on PCI
-       ---help---
-         This driver supports Intel(R) PRO/1000 gigabit ethernet family of
-         adapters.  For more information on how to identify your adapter, go 
-         to the Adapter & Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         More specific information on configuring the driver is in 
-         <file:Documentation/networking/e1000.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called e1000.
-
-config E1000E
-       tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
-       depends on PCI && (!SPARC32 || BROKEN)
-       select CRC32
-       ---help---
-         This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
-         ethernet family of adapters. For PCI or PCI-X e1000 adapters,
-         use the regular e1000 driver For more information on how to
-         identify your adapter, go to the Adapter & Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         To compile this driver as a module, choose M here. The module
-         will be called e1000e.
-
-config IP1000
-       tristate "IP1000 Gigabit Ethernet support"
-       depends on PCI && EXPERIMENTAL
-       select MII
-       ---help---
-         This driver supports IP1000 gigabit Ethernet cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called ipg.  This is recommended.
-
-config IGB
-       tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
-       depends on PCI
-       ---help---
-         This driver supports Intel(R) 82575/82576 gigabit ethernet family of
-         adapters.  For more information on how to identify your adapter, go
-         to the Adapter & Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         More specific information on configuring the driver is in
-         <file:Documentation/networking/e1000.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called igb.
-
-config IGB_DCA
-       bool "Direct Cache Access (DCA) Support"
-       default y
-       depends on IGB && DCA && !(IGB=y && DCA=m)
-       ---help---
-         Say Y here if you want to use Direct Cache Access (DCA) in the
-         driver.  DCA is a method for warming the CPU cache before data
-         is used, with the intent of lessening the impact of cache misses.
-
-config IGBVF
-       tristate "Intel(R) 82576 Virtual Function Ethernet support"
-       depends on PCI
-       ---help---
-         This driver supports Intel(R) 82576 virtual functions.  For more
-         information on how to identify your adapter, go to the Adapter &
-         Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         More specific information on configuring the driver is in
-         <file:Documentation/networking/e1000.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called igbvf.
-
-source "drivers/net/ixp2000/Kconfig"
-
-config NS83820
-       tristate "National Semiconductor DP83820 support"
-       depends on PCI
-       help
-         This is a driver for the National Semiconductor DP83820 series
-         of gigabit ethernet MACs.  Cards using this chipset include
-         the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
-         SOHO-GA2000T, SOHO-GA2500T.  The driver supports the use of
-         zero copy.
-
-config HAMACHI
-       tristate "Packet Engines Hamachi GNIC-II support"
-       depends on PCI
-       select MII
-       help
-         If you have a Gigabit Ethernet card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module will be
-         called hamachi.
-
-config YELLOWFIN
-       tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
-       select CRC32
-       ---help---
-         Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet
-         adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is
-         used by the Beowulf Linux cluster project.  See
-         <http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html> for more
-         information about this driver in particular and Beowulf in general.
-
-         To compile this driver as a module, choose M here: the module
-         will be called yellowfin.  This is recommended.
-
-config R8169
-       tristate "Realtek 8169 gigabit ethernet support"
-       depends on PCI
-       select FW_LOADER
-       select CRC32
-       select MII
-       ---help---
-         Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
-
-         To compile this driver as a module, choose M here: the module
-         will be called r8169.  This is recommended.
-
-config SB1250_MAC
-       tristate "SB1250 Gigabit Ethernet support"
-       depends on SIBYTE_SB1xxx_SOC
-       select PHYLIB
-       ---help---
-         This driver supports Gigabit Ethernet interfaces based on the
-         Broadcom SiByte family of System-On-a-Chip parts.  They include
-         the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
-         and BCM1480 chips.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sb1250-mac.
-
-config SIS190
-       tristate "SiS190/SiS191 gigabit ethernet support"
-       depends on PCI
-       select CRC32
-       select MII
-       ---help---
-         Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
-         a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
-         appear in lan on motherboard designs which are based on SiS 965
-         and SiS 966 south bridge.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sis190.  This is recommended.
-
-config SKGE
-       tristate "Marvell Yukon Gigabit Ethernet support"
-       depends on PCI
-       select CRC32
-       ---help---
-         This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
-         and related Gigabit Ethernet adapters. It is a new smaller driver
-         with better performance and more complete ethtool support.
-
-         It does not support the link failover and network management 
-         features that "portable" vendor supplied sk98lin driver does.
-
-         This driver supports adapters based on the original Yukon chipset:
-         Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
-         Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872.
-
-         It does not support the newer Yukon2 chipset: a separate driver,
-         sky2, is provided for these adapters.
-
-         To compile this driver as a module, choose M here: the module
-         will be called skge.  This is recommended.
-
-config SKGE_DEBUG
-       bool "Debugging interface"
-       depends on SKGE && DEBUG_FS
-       help
-         This option adds the ability to dump driver state for debugging.
-         The file /sys/kernel/debug/skge/ethX displays the state of the internal
-         transmit and receive rings.
-
-         If unsure, say N.
-
-config SKGE_GENESIS
-       bool "Support for older SysKonnect Genesis boards"
-       depends on SKGE
-       help
-         This enables support for the older and uncommon SysKonnect Genesis
-        chips, which support MII via an external transceiver, instead of
-        an internal one. Disabling this option will save some memory
-        by making code smaller. If unsure say Y.
-
-config SKY2
-       tristate "Marvell Yukon 2 support"
-       depends on PCI
-       select CRC32
-       ---help---
-         This driver supports Gigabit Ethernet adapters based on the
-         Marvell Yukon 2 chipset:
-         Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
-         88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
-
-         There is companion driver for the older Marvell Yukon and
-         SysKonnect Genesis based adapters: skge.
-
-         To compile this driver as a module, choose M here: the module
-         will be called sky2.  This is recommended.
-
-config SKY2_DEBUG
-       bool "Debugging interface"
-       depends on SKY2 && DEBUG_FS
-       help
-         This option adds the ability to dump driver state for debugging.
-         The file /sys/kernel/debug/sky2/ethX displays the state of the internal
-         transmit and receive rings.
-
-         If unsure, say N.
-
-config VIA_VELOCITY
-       tristate "VIA Velocity support"
-       depends on PCI
-       select CRC32
-       select CRC_CCITT
-       select MII
-       help
-         If you have a VIA "Velocity" based network card say Y here.
-
-         To compile this driver as a module, choose M here. The module
-         will be called via-velocity.
-
-config TIGON3
-       tristate "Broadcom Tigon3 support"
-       depends on PCI
-       select PHYLIB
-       help
-         This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called tg3.  This is recommended.
-
-config BNX2
-       tristate "Broadcom NetXtremeII support"
-       depends on PCI
-       select CRC32
-       select FW_LOADER
-       help
-         This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called bnx2.  This is recommended.
-
-config CNIC
-       tristate "Broadcom CNIC support"
-       depends on PCI
-       select BNX2
-       select UIO
-       help
-         This driver supports offload features of Broadcom NetXtremeII
-         gigabit Ethernet cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called cnic.  This is recommended.
-
-config SPIDER_NET
-       tristate "Spider Gigabit Ethernet driver"
-       depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
-       select FW_LOADER
-       help
-         This driver supports the Gigabit Ethernet chips present on the
-         Cell Processor-Based Blades from IBM.
-
-config TSI108_ETH
-       tristate "Tundra TSI108 gigabit Ethernet support"
-       depends on TSI108_BRIDGE
-       help
-         This driver supports Tundra TSI108 gigabit Ethernet ports.
-         To compile this driver as a module, choose M here: the module
-         will be called tsi108_eth.
-
-config GELIC_NET
-       tristate "PS3 Gigabit Ethernet driver"
-       depends on PPC_PS3
-       select PS3_SYS_MANAGER
-       help
-         This driver supports the network device on the PS3 game
-         console.  This driver has built-in support for Ethernet.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ps3_gelic.
-
-config GELIC_WIRELESS
-       bool "PS3 Wireless support"
-       depends on WLAN
-       depends on GELIC_NET
-       select WIRELESS_EXT
-       help
-         This option adds the support for the wireless feature of PS3.
-         If you have the wireless-less model of PS3 or have no plan to
-         use wireless feature, disabling this option saves memory.  As
-         the driver automatically distinguishes the models, you can
-         safely enable this option even if you have a wireless-less model.
-
-config FSL_PQ_MDIO
-       tristate "Freescale PQ MDIO"
-       depends on FSL_SOC
-       select PHYLIB
-       help
-         This driver supports the MDIO bus used by the gianfar and UCC drivers.
-
-config GIANFAR
-       tristate "Gianfar Ethernet"
-       depends on FSL_SOC
-       select FSL_PQ_MDIO
-       select PHYLIB
-       select CRC32
-       help
-         This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
-         and MPC86xx family of chips, and the FEC on the 8540.
-
-config UCC_GETH
-       tristate "Freescale QE Gigabit Ethernet"
-       depends on QUICC_ENGINE
-       select FSL_PQ_MDIO
-       select PHYLIB
-       help
-         This driver supports the Gigabit Ethernet mode of the QUICC Engine,
-         which is available on some Freescale SOCs.
-
-config UGETH_TX_ON_DEMAND
-       bool "Transmit on Demand support"
-       depends on UCC_GETH
-
-config MV643XX_ETH
-       tristate "Marvell Discovery (643XX) and Orion ethernet support"
-       depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
-       select INET_LRO
-       select PHYLIB
-       help
-         This driver supports the gigabit ethernet MACs in the
-         Marvell Discovery PPC/MIPS chipset family (MV643XX) and
-         in the Marvell Orion ARM SoC family.
-
-         Some boards that use the Discovery chipset are the Momenco
-         Ocelot C and Jaguar ATX and Pegasos II.
-
-config XILINX_LL_TEMAC
-       tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
-       depends on PPC || MICROBLAZE
-       select PHYLIB
-       help
-         This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
-         core used in Xilinx Spartan and Virtex FPGAs
-
-config QLA3XXX
-       tristate "QLogic QLA3XXX Network Driver Support"
-       depends on PCI
-       help
-         This driver supports QLogic ISP3XXX gigabit Ethernet cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called qla3xxx.
-
-config ATL1
-       tristate "Atheros/Attansic L1 Gigabit Ethernet support"
-       depends on PCI
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros/Attansic L1 gigabit ethernet
-         adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl1.
-
-config ATL1E
-       tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros L1E gigabit ethernet adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl1e.
-
-config ATL1C
-       tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros L1C gigabit ethernet adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl1c.
-
-config JME
-       tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
-       depends on PCI
-       select CRC32
-       select MII
-       ---help---
-         This driver supports the PCI-Express gigabit ethernet adapters
-         based on JMicron JMC250 chipset.
-
-         To compile this driver as a module, choose M here. The module
-         will be called jme.
-
-config S6GMAC
-       tristate "S6105 GMAC ethernet support"
-       depends on XTENSA_VARIANT_S6000
-       select PHYLIB
-       help
-         This driver supports the on chip ethernet device on the
-         S6105 xtensa processor.
-
-         To compile this driver as a module, choose M here. The module
-         will be called s6gmac.
-
-source "drivers/net/stmmac/Kconfig"
-
-config PCH_GBE
-       tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GbE"
-       depends on PCI
-       select MII
-       ---help---
-         This is a gigabit ethernet driver for EG20T PCH.
-         EG20T PCH is the platform controller hub that is used in Intel's
-         general embedded platform.
-         EG20T PCH has Gigabit Ethernet interface.
-         Using this interface, it is able to access system devices connected
-         to Gigabit Ethernet.
-         This driver enables Gigabit Ethernet function.
-
-         This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-         Output Hub), ML7223.
-         ML7223 IOH is for MP(Media Phone) use.
-         ML7223 is companion chip for Intel Atom E6xx series.
-         ML7223 is completely compatible for Intel EG20T PCH.
-
-config FTGMAC100
-       tristate "Faraday FTGMAC100 Gigabit Ethernet support"
-       depends on ARM
-       select PHYLIB
-       help
-         This driver supports the FTGMAC100 Gigabit Ethernet controller
-         from Faraday. It is used on Faraday A369, Andes AG102 and some
-         other ARM/NDS32 SoC's.
-
-endif # NETDEV_1000
-
-#
-#      10 Gigabit Ethernet
-#
-
-menuconfig NETDEV_10000
-       bool "Ethernet (10000 Mbit)"
-       depends on !UML
-       default y
-       ---help---
-         Say Y here to get to see options for 10 Gigabit Ethernet drivers.
-         This option alone does not add any kernel code.
-
-         If you say N, all options in this submenu will be skipped and disabled.
-
-if NETDEV_10000
-
-config MDIO
-       tristate
-
-config CHELSIO_T1
-       tristate "Chelsio 10Gb Ethernet support"
-       depends on PCI
-       select CRC32
-       select MDIO
-       help
-         This driver supports Chelsio gigabit and 10-gigabit
-         Ethernet cards. More information about adapter features and
-         performance tuning is in <file:Documentation/networking/cxgb.txt>.
-
-         For general information about Chelsio and our products, visit
-         our website at <http://www.chelsio.com>.
-
-         For customer support, please visit our customer support page at
-         <http://www.chelsio.com/support.html>.
-
-         Please send feedback to <linux-bugs@chelsio.com>.
-
-         To compile this driver as a module, choose M here: the module
-         will be called cxgb.
-
-config CHELSIO_T1_1G
-       bool "Chelsio gigabit Ethernet support"
-       depends on CHELSIO_T1
-       help
-         Enables support for Chelsio's gigabit Ethernet PCI cards.  If you
-         are using only 10G cards say 'N' here.
-
-config CHELSIO_T3
-       tristate "Chelsio Communications T3 10Gb Ethernet support"
-       depends on PCI && INET
-       select FW_LOADER
-       select MDIO
-       help
-         This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
-         adapters.
-
-         For general information about Chelsio and our products, visit
-         our website at <http://www.chelsio.com>.
-
-         For customer support, please visit our customer support page at
-         <http://www.chelsio.com/support.html>.
-
-         Please send feedback to <linux-bugs@chelsio.com>.
-
-         To compile this driver as a module, choose M here: the module
-         will be called cxgb3.
-
-config CHELSIO_T4
-       tristate "Chelsio Communications T4 Ethernet support"
-       depends on PCI
-       select FW_LOADER
-       select MDIO
-       help
-         This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
-         adapters.
-
-         For general information about Chelsio and our products, visit
-         our website at <http://www.chelsio.com>.
-
-         For customer support, please visit our customer support page at
-         <http://www.chelsio.com/support.html>.
-
-         Please send feedback to <linux-bugs@chelsio.com>.
-
-         To compile this driver as a module choose M here; the module
-         will be called cxgb4.
-
-config CHELSIO_T4VF
-       tristate "Chelsio Communications T4 Virtual Function Ethernet support"
-       depends on PCI
-       help
-         This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
-         adapters with PCI-E SR-IOV Virtual Functions.
-
-         For general information about Chelsio and our products, visit
-         our website at <http://www.chelsio.com>.
-
-         For customer support, please visit our customer support page at
-         <http://www.chelsio.com/support.html>.
-
-         Please send feedback to <linux-bugs@chelsio.com>.
-
-         To compile this driver as a module choose M here; the module
-         will be called cxgb4vf.
-
-config EHEA
-       tristate "eHEA Ethernet support"
-       depends on IBMEBUS && INET && SPARSEMEM
-       select INET_LRO
-       ---help---
-         This driver supports the IBM pSeries eHEA ethernet adapter.
-
-         To compile the driver as a module, choose M here. The module
-         will be called ehea.
-
-config ENIC
-       tristate "Cisco VIC Ethernet NIC Support"
-       depends on PCI && INET
-       help
-         This enables the support for the Cisco VIC Ethernet card.
-
-config IXGBE
-       tristate "Intel(R) 10GbE PCI Express adapters support"
-       depends on PCI && INET
-       select MDIO
-       ---help---
-         This driver supports Intel(R) 10GbE PCI Express family of
-         adapters.  For more information on how to identify your adapter, go
-         to the Adapter & Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         To compile this driver as a module, choose M here. The module
-         will be called ixgbe.
-
-config IXGBE_DCA
-       bool "Direct Cache Access (DCA) Support"
-       default y
-       depends on IXGBE && DCA && !(IXGBE=y && DCA=m)
-       ---help---
-         Say Y here if you want to use Direct Cache Access (DCA) in the
-         driver.  DCA is a method for warming the CPU cache before data
-         is used, with the intent of lessening the impact of cache misses.
-
-config IXGBE_DCB
-       bool "Data Center Bridging (DCB) Support"
-       default n
-       depends on IXGBE && DCB
-       ---help---
-         Say Y here if you want to use Data Center Bridging (DCB) in the
-         driver.
-
-         If unsure, say N.
-
-config IXGBEVF
-       tristate "Intel(R) 82599 Virtual Function Ethernet support"
-       depends on PCI_MSI
-       ---help---
-         This driver supports Intel(R) 82599 virtual functions.  For more
-         information on how to identify your adapter, go to the Adapter &
-         Driver ID Guide at:
-
-         <http://support.intel.com/support/network/sb/CS-008441.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         More specific information on configuring the driver is in
-         <file:Documentation/networking/ixgbevf.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ixgbevf.  MSI-X interrupt support is required
-         for this driver to work correctly.
-
-config IXGB
-       tristate "Intel(R) PRO/10GbE support"
-       depends on PCI
-       ---help---
-         This driver supports Intel(R) PRO/10GbE family of adapters for
-         PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver
-         instead. For more information on how to identify your adapter, go
-         to the Adapter & Driver ID Guide at:
-
-         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-         For general information and support, go to the Intel support
-         website at:
-
-         <http://support.intel.com>
-
-         More specific information on configuring the driver is in 
-         <file:Documentation/networking/ixgb.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ixgb.
-
-config S2IO
-       tristate "Exar Xframe 10Gb Ethernet Adapter"
-       depends on PCI
-       ---help---
-         This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters.
-
-         More specific information on configuring the driver is in 
-         <file:Documentation/networking/s2io.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called s2io.
-
-config VXGE
-       tristate "Exar X3100 Series 10GbE PCIe Server Adapter"
-       depends on PCI && INET
-       ---help---
-         This driver supports Exar Corp's X3100 Series 10 GbE PCIe
-         I/O Virtualized Server Adapter.
-
-         More specific information on configuring the driver is in
-         <file:Documentation/networking/vxge.txt>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called vxge.
-
-config VXGE_DEBUG_TRACE_ALL
-       bool "Enabling All Debug trace statments in driver"
-       default n
-       depends on VXGE
-       ---help---
-         Say Y here if you want to enabling all the debug trace statements in
-         the vxge driver. By default only few debug trace statements are
-         enabled.
-
-config MYRI10GE
-       tristate "Myricom Myri-10G Ethernet support"
-       depends on PCI && INET
-       select FW_LOADER
-       select CRC32
-       select INET_LRO
-       ---help---
-         This driver supports Myricom Myri-10G Dual Protocol interface in
-         Ethernet mode. If the eeprom on your board is not recent enough,
-         you will need a newer firmware image.
-         You may get this image or more information, at:
-
-         <http://www.myri.com/scs/download-Myri10GE.html>
-
-         To compile this driver as a module, choose M here. The module
-         will be called myri10ge.
-
-config MYRI10GE_DCA
-       bool "Direct Cache Access (DCA) Support"
-       default y
-       depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m)
-       ---help---
-         Say Y here if you want to use Direct Cache Access (DCA) in the
-         driver.  DCA is a method for warming the CPU cache before data
-         is used, with the intent of lessening the impact of cache misses.
-
-config NETXEN_NIC
-       tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
-       depends on PCI
-       select FW_LOADER
-       help
-         This enables the support for NetXen's Gigabit Ethernet card.
-
-config NIU
-       tristate "Sun Neptune 10Gbit Ethernet support"
-       depends on PCI
-       select CRC32
-       help
-         This enables support for cards based upon Sun's
-         Neptune chipset.
-
-config PASEMI_MAC
-       tristate "PA Semi 1/10Gbit MAC"
-       depends on PPC_PASEMI && PCI && INET
-       select PHYLIB
-       select INET_LRO
-       help
-         This driver supports the on-chip 1/10Gbit Ethernet controller on
-         PA Semi's PWRficient line of chips.
-
-config MLX4_EN
-       tristate "Mellanox Technologies 10Gbit Ethernet support"
-       depends on PCI && INET
-       select MLX4_CORE
-       select INET_LRO
-       help
-         This driver supports Mellanox Technologies ConnectX Ethernet
-         devices.
-
-config MLX4_CORE
-       tristate
-       depends on PCI
-       default n
-
-config MLX4_DEBUG
-       bool "Verbose debugging output" if (MLX4_CORE && EXPERT)
-       depends on MLX4_CORE
-       default y
-       ---help---
-         This option causes debugging code to be compiled into the
-         mlx4_core driver.  The output can be turned on via the
-         debug_level module parameter (which can also be set after
-         the driver is loaded through sysfs).
-
-config TEHUTI
-       tristate "Tehuti Networks 10G Ethernet"
-       depends on PCI
-       help
-         Tehuti Networks 10G Ethernet NIC
-
-config BNX2X
-       tristate "Broadcom NetXtremeII 10Gb support"
-       depends on PCI
-       select FW_LOADER
-       select ZLIB_INFLATE
-       select LIBCRC32C
-       select MDIO
-       help
-         This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
-         To compile this driver as a module, choose M here: the module
-         will be called bnx2x.  This is recommended.
-
-config QLCNIC
-       tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
-       depends on PCI
-       select FW_LOADER
-       help
-         This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
-         devices.
-
-config QLGE
-       tristate "QLogic QLGE 10Gb Ethernet Driver Support"
-       depends on PCI
-       help
-         This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
-
-         To compile this driver as a module, choose M here: the module
-         will be called qlge.
-
-config BNA
-       tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
-       depends on PCI
-       ---help---
-         This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
-         cards.
-         To compile this driver as a module, choose M here: the module
-         will be called bna.
-
-         For general information and support, go to the Brocade support
-         website at:
-
-         <http://support.brocade.com>
-
-source "drivers/net/sfc/Kconfig"
-
-source "drivers/net/benet/Kconfig"
-
-endif # NETDEV_10000
-
-source "drivers/net/tokenring/Kconfig"
-
-source "drivers/net/wireless/Kconfig"
-
-source "drivers/net/wimax/Kconfig"
-
-source "drivers/net/usb/Kconfig"
-
-source "drivers/net/pcmcia/Kconfig"
-
-source "drivers/net/wan/Kconfig"
-
-source "drivers/atm/Kconfig"
-
-source "drivers/ieee802154/Kconfig"
-
-source "drivers/s390/net/Kconfig"
-
-source "drivers/net/caif/Kconfig"
-
-config TILE_NET
-       tristate "Tilera GBE/XGBE network driver support"
-       depends on TILE
-       default y
-       select CRC32
-       help
-         This is a standard Linux network device driver for the
-         on-chip Tilera Gigabit Ethernet and XAUI interfaces.
-
-         To compile this driver as a module, choose M here: the module
-         will be called tile_net.
-
-config XEN_NETDEV_FRONTEND
-       tristate "Xen network device frontend driver"
-       depends on XEN
-       select XEN_XENBUS_FRONTEND
-       default y
-       help
-         This driver provides support for Xen paravirtual network
-         devices exported by a Xen network driver domain (often
-         domain 0).
-
-         The corresponding Linux backend driver is enabled by the
-         CONFIG_XEN_NETDEV_BACKEND option.
-
-         If you are compiling a kernel for use as Xen guest, you
-         should say Y here. To compile this driver as a module, chose
-         M here: the module will be called xen-netfront.
-
-config XEN_NETDEV_BACKEND
-       tristate "Xen backend network device"
-       depends on XEN_BACKEND
-       help
-         This driver allows the kernel to act as a Xen network driver
-         domain which exports paravirtual network devices to other
-         Xen domains. These devices can be accessed by any operating
-         system that implements a compatible front end.
-
-         The corresponding Linux frontend driver is enabled by the
-         CONFIG_XEN_NETDEV_FRONTEND configuration option.
-
-         The backend driver presents a standard network device
-         endpoint for each paravirtual network device to the driver
-         domain network stack. These can then be bridged or routed
-         etc in order to provide full network connectivity.
+         The backend driver presents a standard network device
+         endpoint for each paravirtual network device to the driver
+         domain network stack. These can then be bridged or routed
+         etc in order to provide full network connectivity.
 
          If you are compiling a kernel to run in a Xen network driver
          domain (often this is domain 0) you should say Y here. To
          compile this driver as a module, chose M here: the module
          will be called xen-netback.
 
-config ISERIES_VETH
-       tristate "iSeries Virtual Ethernet driver support"
-       depends on PPC_ISERIES
-
 config RIONET
        tristate "RapidIO Ethernet over messaging driver support"
        depends on RAPIDIO
index e1eca2ab505ea248648346e21269ae380c0b7634..9896ad111cc8b226fb4022703c01d90e1d90b5cb 100644 (file)
 #
-# Makefile for the Linux network (ethercard) device drivers.
+# Makefile for the Linux network device drivers.
 #
 
 obj-$(CONFIG_MII) += mii.o
 obj-$(CONFIG_MDIO) += mdio.o
 obj-$(CONFIG_PHYLIB) += phy/
-
-obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
-obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
-obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
-
-obj-$(CONFIG_E1000) += e1000/
-obj-$(CONFIG_E1000E) += e1000e/
-obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
-obj-$(CONFIG_IGB) += igb/
-obj-$(CONFIG_IGBVF) += igbvf/
-obj-$(CONFIG_IXGBE) += ixgbe/
-obj-$(CONFIG_IXGBEVF) += ixgbevf/
-obj-$(CONFIG_IXGB) += ixgb/
-obj-$(CONFIG_IP1000) += ipg.o
-obj-$(CONFIG_CHELSIO_T1) += chelsio/
-obj-$(CONFIG_CHELSIO_T3) += cxgb3/
-obj-$(CONFIG_CHELSIO_T4) += cxgb4/
-obj-$(CONFIG_CHELSIO_T4VF) += cxgb4vf/
-obj-$(CONFIG_EHEA) += ehea/
 obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
-obj-$(CONFIG_ATL1) += atlx/
-obj-$(CONFIG_ATL2) += atlx/
-obj-$(CONFIG_ATL1E) += atl1e/
-obj-$(CONFIG_ATL1C) += atl1c/
-obj-$(CONFIG_GIANFAR) += gianfar_driver.o
-obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
-obj-$(CONFIG_TEHUTI) += tehuti.o
-obj-$(CONFIG_ENIC) += enic/
-obj-$(CONFIG_JME) += jme.o
-obj-$(CONFIG_BE2NET) += benet/
 obj-$(CONFIG_VMXNET3) += vmxnet3/
-obj-$(CONFIG_BNA) += bna/
-
-gianfar_driver-objs := gianfar.o \
-               gianfar_ethtool.o \
-               gianfar_sysfs.o
-
-obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
-
-obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
 
 #
 # link order important here
 #
 obj-$(CONFIG_PLIP) += plip.o
-
 obj-$(CONFIG_ROADRUNNER) += rrunner.o
-
-obj-$(CONFIG_HAPPYMEAL) += sunhme.o
-obj-$(CONFIG_SUNLANCE) += sunlance.o
-obj-$(CONFIG_SUNQE) += sunqe.o
-obj-$(CONFIG_SUNBMAC) += sunbmac.o
-obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o
-obj-$(CONFIG_CASSINI) += cassini.o
-obj-$(CONFIG_SUNVNET) += sunvnet.o
-
-obj-$(CONFIG_MACE) += mace.o
-obj-$(CONFIG_BMAC) += bmac.o
-
-obj-$(CONFIG_VORTEX) += 3c59x.o
-obj-$(CONFIG_TYPHOON) += typhoon.o
-obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
-obj-$(CONFIG_PCNET32) += pcnet32.o
-obj-$(CONFIG_E100) += e100.o
-obj-$(CONFIG_TLAN) += tlan.o
-obj-$(CONFIG_EPIC100) += epic100.o
-obj-$(CONFIG_SMSC9420) += smsc9420.o
-obj-$(CONFIG_SIS190) += sis190.o
-obj-$(CONFIG_SIS900) += sis900.o
-obj-$(CONFIG_R6040) += r6040.o
-obj-$(CONFIG_YELLOWFIN) += yellowfin.o
-obj-$(CONFIG_ACENIC) += acenic.o
-obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
-obj-$(CONFIG_NATSEMI) += natsemi.o
-obj-$(CONFIG_NS83820) += ns83820.o
-obj-$(CONFIG_STNIC) += stnic.o 8390.o
-obj-$(CONFIG_FEALNX) += fealnx.o
-obj-$(CONFIG_TIGON3) += tg3.o
-obj-$(CONFIG_BNX2) += bnx2.o
-obj-$(CONFIG_CNIC) += cnic.o
-obj-$(CONFIG_BNX2X) += bnx2x/
-spidernet-y += spider_net.o spider_net_ethtool.o
-obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
-obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
-gelic_wireless-$(CONFIG_GELIC_WIRELESS) += ps3_gelic_wireless.o
-ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
-obj-$(CONFIG_TC35815) += tc35815.o
-obj-$(CONFIG_SKGE) += skge.o
-obj-$(CONFIG_SKY2) += sky2.o
 obj-$(CONFIG_SKFP) += skfp/
-obj-$(CONFIG_KS8842)   += ks8842.o
-obj-$(CONFIG_KS8851)   += ks8851.o
-obj-$(CONFIG_KS8851_MLL)       += ks8851_mll.o
-obj-$(CONFIG_KSZ884X_PCI)      += ksz884x.o
-obj-$(CONFIG_VIA_RHINE) += via-rhine.o
-obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
-obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
 obj-$(CONFIG_RIONET) += rionet.o
-obj-$(CONFIG_SH_ETH) += sh_eth.o
-obj-$(CONFIG_STMMAC_ETH) += stmmac/
 
 #
 # end link order section
 #
 
-obj-$(CONFIG_SUNDANCE) += sundance.o
-obj-$(CONFIG_HAMACHI) += hamachi.o
 obj-$(CONFIG_NET) += Space.o loopback.o
-obj-$(CONFIG_SEEQ8005) += seeq8005.o
 obj-$(CONFIG_NET_SB1000) += sb1000.o
-obj-$(CONFIG_MAC8390) += mac8390.o
-obj-$(CONFIG_APNE) += apne.o 8390.o
-obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
-obj-$(CONFIG_HP100) += hp100.o
-obj-$(CONFIG_SMC9194) += smc9194.o
-obj-$(CONFIG_FEC) += fec.o
-obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
-ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
-       obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
-endif
-obj-$(CONFIG_WD80x3) += wd.o 8390.o
-obj-$(CONFIG_EL2) += 3c503.o 8390p.o
-obj-$(CONFIG_NE2000) += ne.o 8390p.o
-obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o
-obj-$(CONFIG_HPLAN) += hp.o 8390p.o
-obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o
-obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
-obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
-obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
-obj-$(CONFIG_E2100) += e2100.o 8390.o
-obj-$(CONFIG_ES3210) += es3210.o 8390.o
-obj-$(CONFIG_LNE390) += lne390.o 8390.o
-obj-$(CONFIG_NE3210) += ne3210.o 8390.o
-obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
-obj-$(CONFIG_B44) += b44.o
-obj-$(CONFIG_FORCEDETH) += forcedeth.o
-obj-$(CONFIG_NE_H8300) += ne-h8300.o
-obj-$(CONFIG_AX88796) += ax88796.o
-obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
-obj-$(CONFIG_FTGMAC100) += ftgmac100.o
-obj-$(CONFIG_FTMAC100) += ftmac100.o
-
-obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
-obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
-ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
-obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
-obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
-obj-$(CONFIG_QLA3XXX) += qla3xxx.o
-obj-$(CONFIG_QLCNIC) += qlcnic/
-obj-$(CONFIG_QLGE) += qlge/
-
+obj-$(CONFIG_MAC_PUV3) += mac-puv3.o
 obj-$(CONFIG_PPP) += ppp_generic.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
 obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
@@ -167,7 +33,6 @@ obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
 obj-$(CONFIG_PPPOL2TP) += pppox.o
 obj-$(CONFIG_PPTP) += pppox.o pptp.o
-
 obj-$(CONFIG_SLIP) += slip.o
 obj-$(CONFIG_SLHC) += slhc.o
 
@@ -178,97 +43,13 @@ obj-$(CONFIG_DUMMY) += dummy.o
 obj-$(CONFIG_IFB) += ifb.o
 obj-$(CONFIG_MACVLAN) += macvlan.o
 obj-$(CONFIG_MACVTAP) += macvtap.o
-obj-$(CONFIG_DE600) += de600.o
-obj-$(CONFIG_DE620) += de620.o
-obj-$(CONFIG_LANCE) += lance.o
-obj-$(CONFIG_SUN3_82586) += sun3_82586.o
-obj-$(CONFIG_SUN3LANCE) += sun3lance.o
 obj-$(CONFIG_DEFXX) += defxx.o
-obj-$(CONFIG_SGISEEQ) += sgiseeq.o
-obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
-obj-$(CONFIG_AT1700) += at1700.o
-obj-$(CONFIG_EL1) += 3c501.o
-obj-$(CONFIG_EL16) += 3c507.o
-obj-$(CONFIG_ELMC) += 3c523.o
-obj-$(CONFIG_IBMLANA) += ibmlana.o
-obj-$(CONFIG_ELMC_II) += 3c527.o
-obj-$(CONFIG_EL3) += 3c509.o
-obj-$(CONFIG_3C515) += 3c515.o
-obj-$(CONFIG_EEXPRESS) += eexpress.o
-obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
-obj-$(CONFIG_8139CP) += 8139cp.o
-obj-$(CONFIG_8139TOO) += 8139too.o
-obj-$(CONFIG_ZNET) += znet.o
-obj-$(CONFIG_CPMAC) += cpmac.o
-obj-$(CONFIG_DEPCA) += depca.o
-obj-$(CONFIG_EWRK3) += ewrk3.o
-obj-$(CONFIG_ATP) += atp.o
-obj-$(CONFIG_NI5010) += ni5010.o
-obj-$(CONFIG_NI52) += ni52.o
-obj-$(CONFIG_NI65) += ni65.o
-obj-$(CONFIG_ELPLUS) += 3c505.o
-obj-$(CONFIG_AC3200) += ac3200.o 8390.o
-obj-$(CONFIG_APRICOT) += 82596.o
-obj-$(CONFIG_LASI_82596) += lasi_82596.o
-obj-$(CONFIG_SNI_82596) += sni_82596.o
-obj-$(CONFIG_MVME16x_NET) += 82596.o
-obj-$(CONFIG_BVME6000_NET) += 82596.o
-obj-$(CONFIG_SC92031) += sc92031.o
-
-# This is also a 82596 and should probably be merged
-obj-$(CONFIG_LP486E) += lp486e.o
-
-obj-$(CONFIG_ETH16I) += eth16i.o
-obj-$(CONFIG_ZORRO8390) += zorro8390.o
-obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
-obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
 obj-$(CONFIG_EQUALIZER) += eql.o
-obj-$(CONFIG_KORINA) += korina.o
-obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
-obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
-obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
-obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
-obj-$(CONFIG_DECLANCE) += declance.o
-obj-$(CONFIG_ATARILANCE) += atarilance.o
-obj-$(CONFIG_A2065) += a2065.o
-obj-$(CONFIG_HYDRA) += hydra.o
-obj-$(CONFIG_ARIADNE) += ariadne.o
-obj-$(CONFIG_CS89x0) += cs89x0.o
-obj-$(CONFIG_MACSONIC) += macsonic.o
-obj-$(CONFIG_MACMACE) += macmace.o
-obj-$(CONFIG_MAC89x0) += mac89x0.o
 obj-$(CONFIG_TUN) += tun.o
 obj-$(CONFIG_VETH) += veth.o
-obj-$(CONFIG_NET_NETX) += netx-eth.o
-obj-$(CONFIG_DL2K) += dl2k.o
-obj-$(CONFIG_R8169) += r8169.o
-obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
-obj-$(CONFIG_IBMVETH) += ibmveth.o
-obj-$(CONFIG_S2IO) += s2io.o
-obj-$(CONFIG_VXGE) += vxge/
-obj-$(CONFIG_MYRI10GE) += myri10ge/
-obj-$(CONFIG_SMC91X) += smc91x.o
-obj-$(CONFIG_SMC911X) += smc911x.o
-obj-$(CONFIG_SMSC911X) += smsc911x.o
-obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
-obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
-obj-$(CONFIG_DM9000) += dm9000.o
-obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
-pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
-obj-$(CONFIG_MLX4_CORE) += mlx4/
-obj-$(CONFIG_ENC28J60) += enc28j60.o
-obj-$(CONFIG_ETHOC) += ethoc.o
-obj-$(CONFIG_GRETH) += greth.o
-obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
-
-obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
 
-obj-$(CONFIG_DNET) += dnet.o
-obj-$(CONFIG_MACB) += macb.o
-obj-$(CONFIG_S6GMAC) += s6gmac.o
-
-obj-$(CONFIG_ARM) += arm/
 obj-$(CONFIG_DEV_APPLETALK) += appletalk/
+obj-$(CONFIG_ETHERNET) += ethernet/
 obj-$(CONFIG_TR) += tokenring/
 obj-$(CONFIG_WAN) += wan/
 obj-$(CONFIG_ARCNET) += arcnet/
@@ -285,24 +66,15 @@ obj-$(CONFIG_USB_IPHETH)        += usb/
 obj-$(CONFIG_USB_CDC_PHONET)   += usb/
 
 obj-$(CONFIG_WLAN) += wireless/
-obj-$(CONFIG_NET_TULIP) += tulip/
 obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
 obj-$(CONFIG_ETRAX_ETHERNET) += cris/
-obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
 
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 
-obj-$(CONFIG_FS_ENET) += fs_enet/
-
-obj-$(CONFIG_NETXEN_NIC) += netxen/
-obj-$(CONFIG_NIU) += niu.o
 obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
-obj-$(CONFIG_SFC) += sfc/
 
 obj-$(CONFIG_WIMAX) += wimax/
 obj-$(CONFIG_CAIF) += caif/
 
-obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
-obj-$(CONFIG_PCH_GBE) += pch_gbe/
-obj-$(CONFIG_TILE_NET) += tile/
+obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o
index 748c9f526e713274d8d3c722bd321c0a0e845e28..9abd4eb86dc1bf7a38b692657696062f8dc7e974 100644 (file)
@@ -264,7 +264,7 @@ static const struct net_device_ops cops_netdev_ops = {
        .ndo_start_xmit         = cops_send_packet,
        .ndo_tx_timeout         = cops_timeout,
         .ndo_do_ioctl           = cops_ioctl,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
 };
 
 /*
index 34ffb5422628eb74c2aa75322741a8c942eac76a..6057b30417a2f5d89e17ab5f80e1aba7c4d73822 100644 (file)
@@ -1014,7 +1014,7 @@ static int __init ltpc_probe_dma(int base, int dma)
 static const struct net_device_ops ltpc_netdev = {
        .ndo_start_xmit         = ltpc_xmit,
        .ndo_do_ioctl           = ltpc_ioctl,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
 };
 
 struct net_device * __init ltpc_probe(void)
index 7bfb91f3285737dd72427f68fccd1bb05291064f..7b96c5f47e8ddfab20d17319a9b959d018404f2f 100644 (file)
@@ -154,7 +154,7 @@ const struct net_device_ops com20020_netdev_ops = {
        .ndo_stop       = arcnet_close,
        .ndo_start_xmit = arcnet_send_packet,
        .ndo_tx_timeout = arcnet_timeout,
-       .ndo_set_multicast_list = com20020_set_mc_list,
+       .ndo_set_rx_mode = com20020_set_mc_list,
 };
 
 /* Set up the struct net_device associated with this card.  Called after
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
deleted file mode 100644 (file)
index 39e1c0d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Acorn Network device configuration
-#  These are for Acorn's Expansion card network interfaces
-#
-config ARM_AM79C961A
-       bool "ARM EBSA110 AM79C961A support"
-       depends on ARM && ARCH_EBSA110
-       select CRC32
-       help
-         If you wish to compile a kernel for the EBSA-110, then you should
-         always answer Y to this.
-
-config ARM_ETHER1
-       tristate "Acorn Ether1 support"
-       depends on ARM && ARCH_ACORN
-       help
-         If you have an Acorn system with one of these (AKA25) network cards,
-         you should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHER3
-       tristate "Acorn/ANT Ether3 support"
-       depends on ARM && ARCH_ACORN
-       help
-         If you have an Acorn system with one of these network cards, you
-         should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHERH
-       tristate "I-cubed EtherH/ANT EtherM support"
-       depends on ARM && ARCH_ACORN
-       select CRC32
-       help
-         If you have an Acorn system with one of these network cards, you
-         should say Y to this option if you wish to use it with Linux.
-
-config ARM_AT91_ETHER
-       tristate "AT91RM9200 Ethernet support"
-       depends on ARM && ARCH_AT91RM9200
-       select MII
-       help
-         If you wish to compile a kernel for the AT91RM9200 and enable
-         ethernet support, then you should always answer Y to this.
-
-config ARM_KS8695_ETHER
-       tristate "KS8695 Ethernet support"
-       depends on ARM && ARCH_KS8695
-       select MII
-       help
-         If you wish to compile a kernel for the KS8695 and want to
-         use the internal ethernet then you should answer Y to this.
-
-config EP93XX_ETH
-       tristate "EP93xx Ethernet support"
-       depends on ARM && ARCH_EP93XX
-       select MII
-       help
-         This is a driver for the ethernet hardware included in EP93xx CPUs.
-         Say Y if you are building a kernel for EP93xx based devices.
-
-config IXP4XX_ETH
-       tristate "Intel IXP4xx Ethernet support"
-       depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
-       select PHYLIB
-       help
-         Say Y here if you want to use built-in Ethernet ports
-         on IXP4xx processor.
-
-config W90P910_ETH
-       tristate "Nuvoton w90p910 Ethernet support"
-       depends on ARM && ARCH_W90X900
-       select PHYLIB
-       select MII
-       help
-         Say Y here if you want to use built-in Ethernet ports
-         on w90p910 processor.
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
deleted file mode 100644 (file)
index 303171f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# File: drivers/net/arm/Makefile
-#
-# Makefile for the ARM network device drivers
-#
-
-obj-$(CONFIG_ARM_AM79C961A)    += am79c961a.o
-obj-$(CONFIG_ARM_ETHERH)       += etherh.o
-obj-$(CONFIG_ARM_ETHER3)       += ether3.o
-obj-$(CONFIG_ARM_ETHER1)       += ether1.o
-obj-$(CONFIG_ARM_AT91_ETHER)   += at91_ether.o
-obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o
-obj-$(CONFIG_EP93XX_ETH)       += ep93xx_eth.o
-obj-$(CONFIG_IXP4XX_ETH)       += ixp4xx_eth.o
-obj-$(CONFIG_W90P910_ETH)      += w90p910_ether.o
diff --git a/drivers/net/benet/Kconfig b/drivers/net/benet/Kconfig
deleted file mode 100644 (file)
index 1a41a49..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-config BE2NET
-       tristate "ServerEngines' 10Gbps NIC - BladeEngine"
-       depends on PCI && INET
-       help
-       This driver implements the NIC functionality for ServerEngines'
-       10Gbps network adapter - BladeEngine.
diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h
deleted file mode 100644 (file)
index 5130d79..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Linux network driver for Brocade Converged Network Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- */
-
-/*
- * bfi_ctreg.h catapult host block register definitions
- *
- * !!! Do not edit. Auto generated. !!!
- */
-
-#ifndef __BFI_CTREG_H__
-#define __BFI_CTREG_H__
-
-#define HOSTFN0_LPU_MBOX0_0            0x00019200
-#define HOSTFN1_LPU_MBOX0_8            0x00019260
-#define LPU_HOSTFN0_MBOX0_0            0x00019280
-#define LPU_HOSTFN1_MBOX0_8            0x000192e0
-#define HOSTFN2_LPU_MBOX0_0            0x00019400
-#define HOSTFN3_LPU_MBOX0_8            0x00019460
-#define LPU_HOSTFN2_MBOX0_0            0x00019480
-#define LPU_HOSTFN3_MBOX0_8            0x000194e0
-#define HOSTFN0_INT_STATUS             0x00014000
-#define __HOSTFN0_HALT_OCCURRED                0x01000000
-#define __HOSTFN0_INT_STATUS_LVL_MK    0x00f00000
-#define __HOSTFN0_INT_STATUS_LVL_SH    20
-#define __HOSTFN0_INT_STATUS_LVL(_v)   ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
-#define __HOSTFN0_INT_STATUS_P_MK      0x000f0000
-#define __HOSTFN0_INT_STATUS_P_SH      16
-#define __HOSTFN0_INT_STATUS_P(_v)     ((_v) << __HOSTFN0_INT_STATUS_P_SH)
-#define __HOSTFN0_INT_STATUS_F         0x0000ffff
-#define HOSTFN0_INT_MSK                        0x00014004
-#define HOST_PAGE_NUM_FN0              0x00014008
-#define __HOST_PAGE_NUM_FN             0x000001ff
-#define HOST_MSIX_ERR_INDEX_FN0                0x0001400c
-#define __MSIX_ERR_INDEX_FN            0x000001ff
-#define HOSTFN1_INT_STATUS             0x00014100
-#define __HOSTFN1_HALT_OCCURRED                0x01000000
-#define __HOSTFN1_INT_STATUS_LVL_MK    0x00f00000
-#define __HOSTFN1_INT_STATUS_LVL_SH    20
-#define __HOSTFN1_INT_STATUS_LVL(_v)   ((_v) << __HOSTFN1_INT_STATUS_LVL_SH)
-#define __HOSTFN1_INT_STATUS_P_MK      0x000f0000
-#define __HOSTFN1_INT_STATUS_P_SH      16
-#define __HOSTFN1_INT_STATUS_P(_v)     ((_v) << __HOSTFN1_INT_STATUS_P_SH)
-#define __HOSTFN1_INT_STATUS_F         0x0000ffff
-#define HOSTFN1_INT_MSK                        0x00014104
-#define HOST_PAGE_NUM_FN1              0x00014108
-#define HOST_MSIX_ERR_INDEX_FN1                0x0001410c
-#define APP_PLL_425_CTL_REG            0x00014204
-#define __P_425_PLL_LOCK               0x80000000
-#define __APP_PLL_425_SRAM_USE_100MHZ  0x00100000
-#define __APP_PLL_425_RESET_TIMER_MK   0x000e0000
-#define __APP_PLL_425_RESET_TIMER_SH   17
-#define __APP_PLL_425_RESET_TIMER(_v)  ((_v) << __APP_PLL_425_RESET_TIMER_SH)
-#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000
-#define __APP_PLL_425_CNTLMT0_1_MK     0x0000c000
-#define __APP_PLL_425_CNTLMT0_1_SH     14
-#define __APP_PLL_425_CNTLMT0_1(_v)    ((_v) << __APP_PLL_425_CNTLMT0_1_SH)
-#define __APP_PLL_425_JITLMT0_1_MK     0x00003000
-#define __APP_PLL_425_JITLMT0_1_SH     12
-#define __APP_PLL_425_JITLMT0_1(_v)    ((_v) << __APP_PLL_425_JITLMT0_1_SH)
-#define __APP_PLL_425_HREF             0x00000800
-#define __APP_PLL_425_HDIV             0x00000400
-#define __APP_PLL_425_P0_1_MK          0x00000300
-#define __APP_PLL_425_P0_1_SH          8
-#define __APP_PLL_425_P0_1(_v)         ((_v) << __APP_PLL_425_P0_1_SH)
-#define __APP_PLL_425_Z0_2_MK          0x000000e0
-#define __APP_PLL_425_Z0_2_SH          5
-#define __APP_PLL_425_Z0_2(_v)         ((_v) << __APP_PLL_425_Z0_2_SH)
-#define __APP_PLL_425_RSEL200500       0x00000010
-#define __APP_PLL_425_ENARST           0x00000008
-#define __APP_PLL_425_BYPASS           0x00000004
-#define __APP_PLL_425_LRESETN          0x00000002
-#define __APP_PLL_425_ENABLE           0x00000001
-#define APP_PLL_312_CTL_REG            0x00014208
-#define __P_312_PLL_LOCK               0x80000000
-#define __ENABLE_MAC_AHB_1             0x00800000
-#define __ENABLE_MAC_AHB_0             0x00400000
-#define __ENABLE_MAC_1                 0x00200000
-#define __ENABLE_MAC_0                 0x00100000
-#define __APP_PLL_312_RESET_TIMER_MK   0x000e0000
-#define __APP_PLL_312_RESET_TIMER_SH   17
-#define __APP_PLL_312_RESET_TIMER(_v)  ((_v) << __APP_PLL_312_RESET_TIMER_SH)
-#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000
-#define __APP_PLL_312_CNTLMT0_1_MK     0x0000c000
-#define __APP_PLL_312_CNTLMT0_1_SH     14
-#define __APP_PLL_312_CNTLMT0_1(_v)    ((_v) << __APP_PLL_312_CNTLMT0_1_SH)
-#define __APP_PLL_312_JITLMT0_1_MK     0x00003000
-#define __APP_PLL_312_JITLMT0_1_SH     12
-#define __APP_PLL_312_JITLMT0_1(_v)    ((_v) << __APP_PLL_312_JITLMT0_1_SH)
-#define __APP_PLL_312_HREF             0x00000800
-#define __APP_PLL_312_HDIV             0x00000400
-#define __APP_PLL_312_P0_1_MK          0x00000300
-#define __APP_PLL_312_P0_1_SH          8
-#define __APP_PLL_312_P0_1(_v)         ((_v) << __APP_PLL_312_P0_1_SH)
-#define __APP_PLL_312_Z0_2_MK          0x000000e0
-#define __APP_PLL_312_Z0_2_SH          5
-#define __APP_PLL_312_Z0_2(_v)         ((_v) << __APP_PLL_312_Z0_2_SH)
-#define __APP_PLL_312_RSEL200500       0x00000010
-#define __APP_PLL_312_ENARST           0x00000008
-#define __APP_PLL_312_BYPASS           0x00000004
-#define __APP_PLL_312_LRESETN          0x00000002
-#define __APP_PLL_312_ENABLE           0x00000001
-#define MBIST_CTL_REG                  0x00014220
-#define __EDRAM_BISTR_START            0x00000004
-#define __MBIST_RESET                  0x00000002
-#define __MBIST_START                  0x00000001
-#define MBIST_STAT_REG                 0x00014224
-#define __EDRAM_BISTR_STATUS           0x00000008
-#define __EDRAM_BISTR_DONE             0x00000004
-#define __MEM_BIT_STATUS               0x00000002
-#define __MBIST_DONE                   0x00000001
-#define HOST_SEM0_REG                  0x00014230
-#define __HOST_SEMAPHORE               0x00000001
-#define HOST_SEM1_REG                  0x00014234
-#define HOST_SEM2_REG                  0x00014238
-#define HOST_SEM3_REG                  0x0001423c
-#define HOST_SEM0_INFO_REG             0x00014240
-#define HOST_SEM1_INFO_REG             0x00014244
-#define HOST_SEM2_INFO_REG             0x00014248
-#define HOST_SEM3_INFO_REG             0x0001424c
-#define ETH_MAC_SER_REG                        0x00014288
-#define __APP_EMS_CKBUFAMPIN           0x00000020
-#define __APP_EMS_REFCLKSEL            0x00000010
-#define __APP_EMS_CMLCKSEL             0x00000008
-#define __APP_EMS_REFCKBUFEN2          0x00000004
-#define __APP_EMS_REFCKBUFEN1          0x00000002
-#define __APP_EMS_CHANNEL_SEL          0x00000001
-#define HOSTFN2_INT_STATUS             0x00014300
-#define __HOSTFN2_HALT_OCCURRED                0x01000000
-#define __HOSTFN2_INT_STATUS_LVL_MK    0x00f00000
-#define __HOSTFN2_INT_STATUS_LVL_SH    20
-#define __HOSTFN2_INT_STATUS_LVL(_v)   ((_v) << __HOSTFN2_INT_STATUS_LVL_SH)
-#define __HOSTFN2_INT_STATUS_P_MK      0x000f0000
-#define __HOSTFN2_INT_STATUS_P_SH      16
-#define __HOSTFN2_INT_STATUS_P(_v)     ((_v) << __HOSTFN2_INT_STATUS_P_SH)
-#define __HOSTFN2_INT_STATUS_F         0x0000ffff
-#define HOSTFN2_INT_MSK                        0x00014304
-#define HOST_PAGE_NUM_FN2              0x00014308
-#define HOST_MSIX_ERR_INDEX_FN2                0x0001430c
-#define HOSTFN3_INT_STATUS             0x00014400
-#define __HALT_OCCURRED                        0x01000000
-#define __HOSTFN3_INT_STATUS_LVL_MK    0x00f00000
-#define __HOSTFN3_INT_STATUS_LVL_SH    20
-#define __HOSTFN3_INT_STATUS_LVL(_v)   ((_v) << __HOSTFN3_INT_STATUS_LVL_SH)
-#define __HOSTFN3_INT_STATUS_P_MK      0x000f0000
-#define __HOSTFN3_INT_STATUS_P_SH      16
-#define __HOSTFN3_INT_STATUS_P(_v)     ((_v) << __HOSTFN3_INT_STATUS_P_SH)
-#define __HOSTFN3_INT_STATUS_F         0x0000ffff
-#define HOSTFN3_INT_MSK                        0x00014404
-#define HOST_PAGE_NUM_FN3              0x00014408
-#define HOST_MSIX_ERR_INDEX_FN3                0x0001440c
-#define FNC_ID_REG                     0x00014600
-#define __FUNCTION_NUMBER              0x00000007
-#define FNC_PERS_REG                   0x00014604
-#define __F3_FUNCTION_ACTIVE           0x80000000
-#define __F3_FUNCTION_MODE             0x40000000
-#define __F3_PORT_MAP_MK               0x30000000
-#define __F3_PORT_MAP_SH               28
-#define __F3_PORT_MAP(_v)              ((_v) << __F3_PORT_MAP_SH)
-#define __F3_VM_MODE                   0x08000000
-#define __F3_INTX_STATUS_MK            0x07000000
-#define __F3_INTX_STATUS_SH            24
-#define __F3_INTX_STATUS(_v)           ((_v) << __F3_INTX_STATUS_SH)
-#define __F2_FUNCTION_ACTIVE           0x00800000
-#define __F2_FUNCTION_MODE             0x00400000
-#define __F2_PORT_MAP_MK               0x00300000
-#define __F2_PORT_MAP_SH               20
-#define __F2_PORT_MAP(_v)              ((_v) << __F2_PORT_MAP_SH)
-#define __F2_VM_MODE                   0x00080000
-#define __F2_INTX_STATUS_MK            0x00070000
-#define __F2_INTX_STATUS_SH            16
-#define __F2_INTX_STATUS(_v)           ((_v) << __F2_INTX_STATUS_SH)
-#define __F1_FUNCTION_ACTIVE           0x00008000
-#define __F1_FUNCTION_MODE             0x00004000
-#define __F1_PORT_MAP_MK               0x00003000
-#define __F1_PORT_MAP_SH               12
-#define __F1_PORT_MAP(_v)              ((_v) << __F1_PORT_MAP_SH)
-#define __F1_VM_MODE                   0x00000800
-#define __F1_INTX_STATUS_MK            0x00000700
-#define __F1_INTX_STATUS_SH            8
-#define __F1_INTX_STATUS(_v)           ((_v) << __F1_INTX_STATUS_SH)
-#define __F0_FUNCTION_ACTIVE           0x00000080
-#define __F0_FUNCTION_MODE             0x00000040
-#define __F0_PORT_MAP_MK               0x00000030
-#define __F0_PORT_MAP_SH               4
-#define __F0_PORT_MAP(_v)              ((_v) << __F0_PORT_MAP_SH)
-#define __F0_VM_MODE           0x00000008
-#define __F0_INTX_STATUS               0x00000007
-enum {
-       __F0_INTX_STATUS_MSIX           = 0x0,
-       __F0_INTX_STATUS_INTA           = 0x1,
-       __F0_INTX_STATUS_INTB           = 0x2,
-       __F0_INTX_STATUS_INTC           = 0x3,
-       __F0_INTX_STATUS_INTD           = 0x4,
-};
-#define OP_MODE                                0x0001460c
-#define __APP_ETH_CLK_LOWSPEED         0x00000004
-#define __GLOBAL_CORECLK_HALFSPEED     0x00000002
-#define __GLOBAL_FCOE_MODE             0x00000001
-#define HOST_SEM4_REG                  0x00014610
-#define HOST_SEM5_REG                  0x00014614
-#define HOST_SEM6_REG                  0x00014618
-#define HOST_SEM7_REG                  0x0001461c
-#define HOST_SEM4_INFO_REG             0x00014620
-#define HOST_SEM5_INFO_REG             0x00014624
-#define HOST_SEM6_INFO_REG             0x00014628
-#define HOST_SEM7_INFO_REG             0x0001462c
-#define HOSTFN0_LPU0_MBOX0_CMD_STAT    0x00019000
-#define __HOSTFN0_LPU0_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN0_LPU0_MBOX0_INFO_SH   1
-#define __HOSTFN0_LPU0_MBOX0_INFO(_v)  ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH)
-#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN0_LPU1_MBOX0_CMD_STAT    0x00019004
-#define __HOSTFN0_LPU1_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN0_LPU1_MBOX0_INFO_SH   1
-#define __HOSTFN0_LPU1_MBOX0_INFO(_v)  ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH)
-#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001
-#define LPU0_HOSTFN0_MBOX0_CMD_STAT    0x00019008
-#define __LPU0_HOSTFN0_MBOX0_INFO_MK   0xfffffffe
-#define __LPU0_HOSTFN0_MBOX0_INFO_SH   1
-#define __LPU0_HOSTFN0_MBOX0_INFO(_v)  ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH)
-#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
-#define LPU1_HOSTFN0_MBOX0_CMD_STAT    0x0001900c
-#define __LPU1_HOSTFN0_MBOX0_INFO_MK   0xfffffffe
-#define __LPU1_HOSTFN0_MBOX0_INFO_SH   1
-#define __LPU1_HOSTFN0_MBOX0_INFO(_v)  ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH)
-#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN1_LPU0_MBOX0_CMD_STAT    0x00019010
-#define __HOSTFN1_LPU0_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN1_LPU0_MBOX0_INFO_SH   1
-#define __HOSTFN1_LPU0_MBOX0_INFO(_v)  ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH)
-#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN1_LPU1_MBOX0_CMD_STAT    0x00019014
-#define __HOSTFN1_LPU1_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN1_LPU1_MBOX0_INFO_SH   1
-#define __HOSTFN1_LPU1_MBOX0_INFO(_v)  ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH)
-#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001
-#define LPU0_HOSTFN1_MBOX0_CMD_STAT    0x00019018
-#define __LPU0_HOSTFN1_MBOX0_INFO_MK   0xfffffffe
-#define __LPU0_HOSTFN1_MBOX0_INFO_SH   1
-#define __LPU0_HOSTFN1_MBOX0_INFO(_v)  ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH)
-#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
-#define LPU1_HOSTFN1_MBOX0_CMD_STAT    0x0001901c
-#define __LPU1_HOSTFN1_MBOX0_INFO_MK   0xfffffffe
-#define __LPU1_HOSTFN1_MBOX0_INFO_SH   1
-#define __LPU1_HOSTFN1_MBOX0_INFO(_v)  ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH)
-#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN2_LPU0_MBOX0_CMD_STAT    0x00019150
-#define __HOSTFN2_LPU0_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN2_LPU0_MBOX0_INFO_SH   1
-#define __HOSTFN2_LPU0_MBOX0_INFO(_v)  ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH)
-#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN2_LPU1_MBOX0_CMD_STAT    0x00019154
-#define __HOSTFN2_LPU1_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN2_LPU1_MBOX0_INFO_SH   1
-#define __HOSTFN2_LPU1_MBOX0_INFO(_v)  ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH)
-#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001
-#define LPU0_HOSTFN2_MBOX0_CMD_STAT    0x00019158
-#define __LPU0_HOSTFN2_MBOX0_INFO_MK   0xfffffffe
-#define __LPU0_HOSTFN2_MBOX0_INFO_SH   1
-#define __LPU0_HOSTFN2_MBOX0_INFO(_v)  ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH)
-#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
-#define LPU1_HOSTFN2_MBOX0_CMD_STAT    0x0001915c
-#define __LPU1_HOSTFN2_MBOX0_INFO_MK   0xfffffffe
-#define __LPU1_HOSTFN2_MBOX0_INFO_SH   1
-#define __LPU1_HOSTFN2_MBOX0_INFO(_v)  ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH)
-#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN3_LPU0_MBOX0_CMD_STAT    0x00019160
-#define __HOSTFN3_LPU0_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN3_LPU0_MBOX0_INFO_SH   1
-#define __HOSTFN3_LPU0_MBOX0_INFO(_v)  ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH)
-#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001
-#define HOSTFN3_LPU1_MBOX0_CMD_STAT    0x00019164
-#define __HOSTFN3_LPU1_MBOX0_INFO_MK   0xfffffffe
-#define __HOSTFN3_LPU1_MBOX0_INFO_SH   1
-#define __HOSTFN3_LPU1_MBOX0_INFO(_v)  ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH)
-#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001
-#define LPU0_HOSTFN3_MBOX0_CMD_STAT    0x00019168
-#define __LPU0_HOSTFN3_MBOX0_INFO_MK   0xfffffffe
-#define __LPU0_HOSTFN3_MBOX0_INFO_SH   1
-#define __LPU0_HOSTFN3_MBOX0_INFO(_v)  ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH)
-#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
-#define LPU1_HOSTFN3_MBOX0_CMD_STAT    0x0001916c
-#define __LPU1_HOSTFN3_MBOX0_INFO_MK   0xfffffffe
-#define __LPU1_HOSTFN3_MBOX0_INFO_SH   1
-#define __LPU1_HOSTFN3_MBOX0_INFO(_v)  ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH)
-#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS        0x00000001
-#define FW_INIT_HALT_P0                        0x000191ac
-#define __FW_INIT_HALT_P               0x00000001
-#define FW_INIT_HALT_P1                        0x000191bc
-#define CPE_PI_PTR_Q0                  0x00038000
-#define __CPE_PI_UNUSED_MK             0xffff0000
-#define __CPE_PI_UNUSED_SH             16
-#define __CPE_PI_UNUSED(_v)            ((_v) << __CPE_PI_UNUSED_SH)
-#define __CPE_PI_PTR                   0x0000ffff
-#define CPE_PI_PTR_Q1                  0x00038040
-#define CPE_CI_PTR_Q0                  0x00038004
-#define __CPE_CI_UNUSED_MK             0xffff0000
-#define __CPE_CI_UNUSED_SH             16
-#define __CPE_CI_UNUSED(_v)            ((_v) << __CPE_CI_UNUSED_SH)
-#define __CPE_CI_PTR                   0x0000ffff
-#define CPE_CI_PTR_Q1                  0x00038044
-#define CPE_DEPTH_Q0                   0x00038008
-#define __CPE_DEPTH_UNUSED_MK          0xf8000000
-#define __CPE_DEPTH_UNUSED_SH          27
-#define __CPE_DEPTH_UNUSED(_v)         ((_v) << __CPE_DEPTH_UNUSED_SH)
-#define __CPE_MSIX_VEC_INDEX_MK                0x07ff0000
-#define __CPE_MSIX_VEC_INDEX_SH                16
-#define __CPE_MSIX_VEC_INDEX(_v)       ((_v) << __CPE_MSIX_VEC_INDEX_SH)
-#define __CPE_DEPTH                    0x0000ffff
-#define CPE_DEPTH_Q1                   0x00038048
-#define CPE_QCTRL_Q0                   0x0003800c
-#define __CPE_CTRL_UNUSED30_MK         0xfc000000
-#define __CPE_CTRL_UNUSED30_SH         26
-#define __CPE_CTRL_UNUSED30(_v)                ((_v) << __CPE_CTRL_UNUSED30_SH)
-#define __CPE_FUNC_INT_CTRL_MK         0x03000000
-#define __CPE_FUNC_INT_CTRL_SH         24
-#define __CPE_FUNC_INT_CTRL(_v)                ((_v) << __CPE_FUNC_INT_CTRL_SH)
-enum {
-       __CPE_FUNC_INT_CTRL_DISABLE             = 0x0,
-       __CPE_FUNC_INT_CTRL_F2NF                = 0x1,
-       __CPE_FUNC_INT_CTRL_3QUART              = 0x2,
-       __CPE_FUNC_INT_CTRL_HALF                = 0x3,
-};
-#define __CPE_CTRL_UNUSED20_MK         0x00f00000
-#define __CPE_CTRL_UNUSED20_SH         20
-#define __CPE_CTRL_UNUSED20(_v)                ((_v) << __CPE_CTRL_UNUSED20_SH)
-#define __CPE_SCI_TH_MK                        0x000f0000
-#define __CPE_SCI_TH_SH                        16
-#define __CPE_SCI_TH(_v)               ((_v) << __CPE_SCI_TH_SH)
-#define __CPE_CTRL_UNUSED10_MK         0x0000c000
-#define __CPE_CTRL_UNUSED10_SH         14
-#define __CPE_CTRL_UNUSED10(_v)                ((_v) << __CPE_CTRL_UNUSED10_SH)
-#define __CPE_ACK_PENDING              0x00002000
-#define __CPE_CTRL_UNUSED40_MK         0x00001c00
-#define __CPE_CTRL_UNUSED40_SH         10
-#define __CPE_CTRL_UNUSED40(_v)                ((_v) << __CPE_CTRL_UNUSED40_SH)
-#define __CPE_PCIEID_MK                        0x00000300
-#define __CPE_PCIEID_SH                        8
-#define __CPE_PCIEID(_v)               ((_v) << __CPE_PCIEID_SH)
-#define __CPE_CTRL_UNUSED00_MK         0x000000fe
-#define __CPE_CTRL_UNUSED00_SH         1
-#define __CPE_CTRL_UNUSED00(_v)                ((_v) << __CPE_CTRL_UNUSED00_SH)
-#define __CPE_ESIZE                    0x00000001
-#define CPE_QCTRL_Q1                   0x0003804c
-#define __CPE_CTRL_UNUSED31_MK         0xfc000000
-#define __CPE_CTRL_UNUSED31_SH         26
-#define __CPE_CTRL_UNUSED31(_v)                ((_v) << __CPE_CTRL_UNUSED31_SH)
-#define __CPE_CTRL_UNUSED21_MK         0x00f00000
-#define __CPE_CTRL_UNUSED21_SH         20
-#define __CPE_CTRL_UNUSED21(_v)                ((_v) << __CPE_CTRL_UNUSED21_SH)
-#define __CPE_CTRL_UNUSED11_MK         0x0000c000
-#define __CPE_CTRL_UNUSED11_SH         14
-#define __CPE_CTRL_UNUSED11(_v)                ((_v) << __CPE_CTRL_UNUSED11_SH)
-#define __CPE_CTRL_UNUSED41_MK         0x00001c00
-#define __CPE_CTRL_UNUSED41_SH         10
-#define __CPE_CTRL_UNUSED41(_v)                ((_v) << __CPE_CTRL_UNUSED41_SH)
-#define __CPE_CTRL_UNUSED01_MK         0x000000fe
-#define __CPE_CTRL_UNUSED01_SH         1
-#define __CPE_CTRL_UNUSED01(_v)                ((_v) << __CPE_CTRL_UNUSED01_SH)
-#define RME_PI_PTR_Q0                  0x00038020
-#define __LATENCY_TIME_STAMP_MK                0xffff0000
-#define __LATENCY_TIME_STAMP_SH                16
-#define __LATENCY_TIME_STAMP(_v)       ((_v) << __LATENCY_TIME_STAMP_SH)
-#define __RME_PI_PTR                   0x0000ffff
-#define RME_PI_PTR_Q1                  0x00038060
-#define RME_CI_PTR_Q0                  0x00038024
-#define __DELAY_TIME_STAMP_MK          0xffff0000
-#define __DELAY_TIME_STAMP_SH          16
-#define __DELAY_TIME_STAMP(_v)         ((_v) << __DELAY_TIME_STAMP_SH)
-#define __RME_CI_PTR                   0x0000ffff
-#define RME_CI_PTR_Q1                  0x00038064
-#define RME_DEPTH_Q0                   0x00038028
-#define __RME_DEPTH_UNUSED_MK          0xf8000000
-#define __RME_DEPTH_UNUSED_SH          27
-#define __RME_DEPTH_UNUSED(_v)         ((_v) << __RME_DEPTH_UNUSED_SH)
-#define __RME_MSIX_VEC_INDEX_MK                0x07ff0000
-#define __RME_MSIX_VEC_INDEX_SH                16
-#define __RME_MSIX_VEC_INDEX(_v)       ((_v) << __RME_MSIX_VEC_INDEX_SH)
-#define __RME_DEPTH                    0x0000ffff
-#define RME_DEPTH_Q1                   0x00038068
-#define RME_QCTRL_Q0                   0x0003802c
-#define __RME_INT_LATENCY_TIMER_MK     0xff000000
-#define __RME_INT_LATENCY_TIMER_SH     24
-#define __RME_INT_LATENCY_TIMER(_v)    ((_v) << __RME_INT_LATENCY_TIMER_SH)
-#define __RME_INT_DELAY_TIMER_MK       0x00ff0000
-#define __RME_INT_DELAY_TIMER_SH       16
-#define __RME_INT_DELAY_TIMER(_v)      ((_v) << __RME_INT_DELAY_TIMER_SH)
-#define __RME_INT_DELAY_DISABLE                0x00008000
-#define __RME_DLY_DELAY_DISABLE                0x00004000
-#define __RME_ACK_PENDING              0x00002000
-#define __RME_FULL_INTERRUPT_DISABLE   0x00001000
-#define __RME_CTRL_UNUSED10_MK         0x00000c00
-#define __RME_CTRL_UNUSED10_SH         10
-#define __RME_CTRL_UNUSED10(_v)                ((_v) << __RME_CTRL_UNUSED10_SH)
-#define __RME_PCIEID_MK                        0x00000300
-#define __RME_PCIEID_SH                        8
-#define __RME_PCIEID(_v)               ((_v) << __RME_PCIEID_SH)
-#define __RME_CTRL_UNUSED00_MK         0x000000fe
-#define __RME_CTRL_UNUSED00_SH         1
-#define __RME_CTRL_UNUSED00(_v)                ((_v) << __RME_CTRL_UNUSED00_SH)
-#define __RME_ESIZE                    0x00000001
-#define RME_QCTRL_Q1                   0x0003806c
-#define __RME_CTRL_UNUSED11_MK         0x00000c00
-#define __RME_CTRL_UNUSED11_SH         10
-#define __RME_CTRL_UNUSED11(_v)                ((_v) << __RME_CTRL_UNUSED11_SH)
-#define __RME_CTRL_UNUSED01_MK         0x000000fe
-#define __RME_CTRL_UNUSED01_SH         1
-#define __RME_CTRL_UNUSED01(_v)                ((_v) << __RME_CTRL_UNUSED01_SH)
-#define PSS_CTL_REG                    0x00018800
-#define __PSS_I2C_CLK_DIV_MK           0x007f0000
-#define __PSS_I2C_CLK_DIV_SH           16
-#define __PSS_I2C_CLK_DIV(_v)          ((_v) << __PSS_I2C_CLK_DIV_SH)
-#define __PSS_LMEM_INIT_DONE           0x00001000
-#define __PSS_LMEM_RESET               0x00000200
-#define __PSS_LMEM_INIT_EN             0x00000100
-#define __PSS_LPU1_RESET               0x00000002
-#define __PSS_LPU0_RESET               0x00000001
-#define PSS_ERR_STATUS_REG             0x00018810
-#define __PSS_LPU1_TCM_READ_ERR                0x00200000
-#define __PSS_LPU0_TCM_READ_ERR                0x00100000
-#define __PSS_LMEM5_CORR_ERR           0x00080000
-#define __PSS_LMEM4_CORR_ERR           0x00040000
-#define __PSS_LMEM3_CORR_ERR           0x00020000
-#define __PSS_LMEM2_CORR_ERR           0x00010000
-#define __PSS_LMEM1_CORR_ERR           0x00008000
-#define __PSS_LMEM0_CORR_ERR           0x00004000
-#define __PSS_LMEM5_UNCORR_ERR         0x00002000
-#define __PSS_LMEM4_UNCORR_ERR         0x00001000
-#define __PSS_LMEM3_UNCORR_ERR         0x00000800
-#define __PSS_LMEM2_UNCORR_ERR         0x00000400
-#define __PSS_LMEM1_UNCORR_ERR         0x00000200
-#define __PSS_LMEM0_UNCORR_ERR         0x00000100
-#define __PSS_BAL_PERR                 0x00000080
-#define __PSS_DIP_IF_ERR               0x00000040
-#define __PSS_IOH_IF_ERR               0x00000020
-#define __PSS_TDS_IF_ERR               0x00000010
-#define __PSS_RDS_IF_ERR               0x00000008
-#define __PSS_SGM_IF_ERR               0x00000004
-#define __PSS_LPU1_RAM_ERR             0x00000002
-#define __PSS_LPU0_RAM_ERR             0x00000001
-#define ERR_SET_REG                    0x00018818
-#define __PSS_ERR_STATUS_SET           0x003fffff
-#define PMM_1T_RESET_REG_P0            0x0002381c
-#define __PMM_1T_RESET_P               0x00000001
-#define PMM_1T_RESET_REG_P1            0x00023c1c
-#define HQM_QSET0_RXQ_DRBL_P0          0x00038000
-#define __RXQ0_ADD_VECTORS_P           0x80000000
-#define __RXQ0_STOP_P                  0x40000000
-#define __RXQ0_PRD_PTR_P               0x0000ffff
-#define HQM_QSET1_RXQ_DRBL_P0          0x00038080
-#define __RXQ1_ADD_VECTORS_P           0x80000000
-#define __RXQ1_STOP_P                  0x40000000
-#define __RXQ1_PRD_PTR_P               0x0000ffff
-#define HQM_QSET0_RXQ_DRBL_P1          0x0003c000
-#define HQM_QSET1_RXQ_DRBL_P1          0x0003c080
-#define HQM_QSET0_TXQ_DRBL_P0          0x00038020
-#define __TXQ0_ADD_VECTORS_P           0x80000000
-#define __TXQ0_STOP_P                  0x40000000
-#define __TXQ0_PRD_PTR_P               0x0000ffff
-#define HQM_QSET1_TXQ_DRBL_P0          0x000380a0
-#define __TXQ1_ADD_VECTORS_P           0x80000000
-#define __TXQ1_STOP_P                  0x40000000
-#define __TXQ1_PRD_PTR_P               0x0000ffff
-#define HQM_QSET0_TXQ_DRBL_P1          0x0003c020
-#define HQM_QSET1_TXQ_DRBL_P1          0x0003c0a0
-#define HQM_QSET0_IB_DRBL_1_P0         0x00038040
-#define __IB1_0_ACK_P                  0x80000000
-#define __IB1_0_DISABLE_P              0x40000000
-#define __IB1_0_COALESCING_CFG_P_MK    0x00ff0000
-#define __IB1_0_COALESCING_CFG_P_SH    16
-#define __IB1_0_COALESCING_CFG_P(_v)   ((_v) << __IB1_0_COALESCING_CFG_P_SH)
-#define __IB1_0_NUM_OF_ACKED_EVENTS_P  0x0000ffff
-#define HQM_QSET1_IB_DRBL_1_P0         0x000380c0
-#define __IB1_1_ACK_P                  0x80000000
-#define __IB1_1_DISABLE_P              0x40000000
-#define __IB1_1_COALESCING_CFG_P_MK    0x00ff0000
-#define __IB1_1_COALESCING_CFG_P_SH    16
-#define __IB1_1_COALESCING_CFG_P(_v)   ((_v) << __IB1_1_COALESCING_CFG_P_SH)
-#define __IB1_1_NUM_OF_ACKED_EVENTS_P  0x0000ffff
-#define HQM_QSET0_IB_DRBL_1_P1         0x0003c040
-#define HQM_QSET1_IB_DRBL_1_P1         0x0003c0c0
-#define HQM_QSET0_IB_DRBL_2_P0         0x00038060
-#define __IB2_0_ACK_P                  0x80000000
-#define __IB2_0_DISABLE_P              0x40000000
-#define __IB2_0_COALESCING_CFG_P_MK    0x00ff0000
-#define __IB2_0_COALESCING_CFG_P_SH    16
-#define __IB2_0_COALESCING_CFG_P(_v)   ((_v) << __IB2_0_COALESCING_CFG_P_SH)
-#define __IB2_0_NUM_OF_ACKED_EVENTS_P  0x0000ffff
-#define HQM_QSET1_IB_DRBL_2_P0         0x000380e0
-#define __IB2_1_ACK_P                  0x80000000
-#define __IB2_1_DISABLE_P              0x40000000
-#define __IB2_1_COALESCING_CFG_P_MK    0x00ff0000
-#define __IB2_1_COALESCING_CFG_P_SH    16
-#define __IB2_1_COALESCING_CFG_P(_v)   ((_v) << __IB2_1_COALESCING_CFG_P_SH)
-#define __IB2_1_NUM_OF_ACKED_EVENTS_P  0x0000ffff
-#define HQM_QSET0_IB_DRBL_2_P1         0x0003c060
-#define HQM_QSET1_IB_DRBL_2_P1         0x0003c0e0
-
-/*
- * These definitions are either in error/missing in spec. Its auto-generated
- * from hard coded values in regparse.pl.
- */
-#define __EMPHPOST_AT_4G_MK_FIX                0x0000001c
-#define __EMPHPOST_AT_4G_SH_FIX                0x00000002
-#define __EMPHPRE_AT_4G_FIX            0x00000003
-#define __SFP_TXRATE_EN_FIX            0x00000100
-#define __SFP_RXRATE_EN_FIX            0x00000080
-
-/*
- * These register definitions are auto-generated from hard coded values
- * in regparse.pl.
- */
-
-/*
- * These register mapping definitions are auto-generated from mapping tables
- * in regparse.pl.
- */
-#define BFA_IOC0_HBEAT_REG             HOST_SEM0_INFO_REG
-#define BFA_IOC0_STATE_REG             HOST_SEM1_INFO_REG
-#define BFA_IOC1_HBEAT_REG             HOST_SEM2_INFO_REG
-#define BFA_IOC1_STATE_REG             HOST_SEM3_INFO_REG
-#define BFA_FW_USE_COUNT                HOST_SEM4_INFO_REG
-#define BFA_IOC_FAIL_SYNC              HOST_SEM5_INFO_REG
-
-#define CPE_DEPTH_Q(__n) \
-       (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
-#define CPE_QCTRL_Q(__n) \
-       (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0))
-#define CPE_PI_PTR_Q(__n) \
-       (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0))
-#define CPE_CI_PTR_Q(__n) \
-       (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0))
-#define RME_DEPTH_Q(__n) \
-       (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0))
-#define RME_QCTRL_Q(__n) \
-       (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0))
-#define RME_PI_PTR_Q(__n) \
-       (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
-#define RME_CI_PTR_Q(__n) \
-       (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
-#define HQM_QSET_RXQ_DRBL_P0(__n) \
-       (HQM_QSET0_RXQ_DRBL_P0 + (__n) * \
-               (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
-#define HQM_QSET_TXQ_DRBL_P0(__n) \
-       (HQM_QSET0_TXQ_DRBL_P0 + (__n) * \
-               (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
-#define HQM_QSET_IB_DRBL_1_P0(__n) \
-       (HQM_QSET0_IB_DRBL_1_P0 + (__n) * \
-               (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
-#define HQM_QSET_IB_DRBL_2_P0(__n) \
-       (HQM_QSET0_IB_DRBL_2_P0 + (__n) * \
-               (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
-#define HQM_QSET_RXQ_DRBL_P1(__n) \
-       (HQM_QSET0_RXQ_DRBL_P1 + (__n) * \
-               (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
-#define HQM_QSET_TXQ_DRBL_P1(__n) \
-       (HQM_QSET0_TXQ_DRBL_P1 + (__n) * \
-               (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
-#define HQM_QSET_IB_DRBL_1_P1(__n) \
-       (HQM_QSET0_IB_DRBL_1_P1 + (__n) * \
-               (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
-#define HQM_QSET_IB_DRBL_2_P1(__n) \
-       (HQM_QSET0_IB_DRBL_2_P1 + (__n) * \
-               (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
-
-#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
-#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
-#define CPE_Q_MASK(__q) ((__q) & 0x3)
-#define RME_Q_MASK(__q) ((__q) & 0x3)
-
-/*
- * PCI MSI-X vector defines
- */
-enum {
-       BFA_MSIX_CPE_Q0 = 0,
-       BFA_MSIX_CPE_Q1 = 1,
-       BFA_MSIX_CPE_Q2 = 2,
-       BFA_MSIX_CPE_Q3 = 3,
-       BFA_MSIX_RME_Q0 = 4,
-       BFA_MSIX_RME_Q1 = 5,
-       BFA_MSIX_RME_Q2 = 6,
-       BFA_MSIX_RME_Q3 = 7,
-       BFA_MSIX_LPU_ERR = 8,
-       BFA_MSIX_CT_MAX = 9,
-};
-
-/*
- * And corresponding host interrupt status bit field defines
- */
-#define __HFN_INT_CPE_Q0               0x00000001U
-#define __HFN_INT_CPE_Q1               0x00000002U
-#define __HFN_INT_CPE_Q2               0x00000004U
-#define __HFN_INT_CPE_Q3               0x00000008U
-#define __HFN_INT_CPE_Q4               0x00000010U
-#define __HFN_INT_CPE_Q5               0x00000020U
-#define __HFN_INT_CPE_Q6               0x00000040U
-#define __HFN_INT_CPE_Q7               0x00000080U
-#define __HFN_INT_RME_Q0               0x00000100U
-#define __HFN_INT_RME_Q1               0x00000200U
-#define __HFN_INT_RME_Q2               0x00000400U
-#define __HFN_INT_RME_Q3               0x00000800U
-#define __HFN_INT_RME_Q4               0x00001000U
-#define __HFN_INT_RME_Q5               0x00002000U
-#define __HFN_INT_RME_Q6               0x00004000U
-#define __HFN_INT_RME_Q7               0x00008000U
-#define __HFN_INT_ERR_EMC              0x00010000U
-#define __HFN_INT_ERR_LPU0             0x00020000U
-#define __HFN_INT_ERR_LPU1             0x00040000U
-#define __HFN_INT_ERR_PSS              0x00080000U
-#define __HFN_INT_MBOX_LPU0            0x00100000U
-#define __HFN_INT_MBOX_LPU1            0x00200000U
-#define __HFN_INT_MBOX1_LPU0           0x00400000U
-#define __HFN_INT_MBOX1_LPU1           0x00800000U
-#define __HFN_INT_LL_HALT              0x01000000U
-#define __HFN_INT_CPE_MASK             0x000000ffU
-#define __HFN_INT_RME_MASK             0x0000ff00U
-
-/*
- * catapult memory map.
- */
-#define LL_PGN_HQM0            0x0096
-#define LL_PGN_HQM1            0x0097
-#define PSS_SMEM_PAGE_START    0x8000
-#define PSS_SMEM_PGNUM(_pg0, _ma)      ((_pg0) + ((_ma) >> 15))
-#define PSS_SMEM_PGOFF(_ma)    ((_ma) & 0x7fff)
-
-/*
- * End of catapult memory map
- */
-
-#endif /* __BFI_CTREG_H__ */
diff --git a/drivers/net/bna/bfi_ll.h b/drivers/net/bna/bfi_ll.h
deleted file mode 100644 (file)
index bee4d05..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Linux network driver for Brocade Converged Network Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- */
-#ifndef __BFI_LL_H__
-#define __BFI_LL_H__
-
-#include "bfi.h"
-
-#pragma pack(1)
-
-/**
- * @brief
- *     "enums" for all LL mailbox messages other than IOC
- */
-enum {
-       BFI_LL_H2I_MAC_UCAST_SET_REQ = 1,
-       BFI_LL_H2I_MAC_UCAST_ADD_REQ = 2,
-       BFI_LL_H2I_MAC_UCAST_DEL_REQ = 3,
-
-       BFI_LL_H2I_MAC_MCAST_ADD_REQ = 4,
-       BFI_LL_H2I_MAC_MCAST_DEL_REQ = 5,
-       BFI_LL_H2I_MAC_MCAST_FILTER_REQ = 6,
-       BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ = 7,
-
-       BFI_LL_H2I_PORT_ADMIN_REQ = 8,
-       BFI_LL_H2I_STATS_GET_REQ = 9,
-       BFI_LL_H2I_STATS_CLEAR_REQ = 10,
-
-       BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ = 11,
-       BFI_LL_H2I_RXF_DEFAULT_SET_REQ = 12,
-
-       BFI_LL_H2I_TXQ_STOP_REQ = 13,
-       BFI_LL_H2I_RXQ_STOP_REQ = 14,
-
-       BFI_LL_H2I_DIAG_LOOPBACK_REQ = 15,
-
-       BFI_LL_H2I_SET_PAUSE_REQ = 16,
-       BFI_LL_H2I_MTU_INFO_REQ = 17,
-
-       BFI_LL_H2I_RX_REQ = 18,
-} ;
-
-enum {
-       BFI_LL_I2H_MAC_UCAST_SET_RSP = BFA_I2HM(1),
-       BFI_LL_I2H_MAC_UCAST_ADD_RSP = BFA_I2HM(2),
-       BFI_LL_I2H_MAC_UCAST_DEL_RSP = BFA_I2HM(3),
-
-       BFI_LL_I2H_MAC_MCAST_ADD_RSP = BFA_I2HM(4),
-       BFI_LL_I2H_MAC_MCAST_DEL_RSP = BFA_I2HM(5),
-       BFI_LL_I2H_MAC_MCAST_FILTER_RSP = BFA_I2HM(6),
-       BFI_LL_I2H_MAC_MCAST_DEL_ALL_RSP = BFA_I2HM(7),
-
-       BFI_LL_I2H_PORT_ADMIN_RSP = BFA_I2HM(8),
-       BFI_LL_I2H_STATS_GET_RSP = BFA_I2HM(9),
-       BFI_LL_I2H_STATS_CLEAR_RSP = BFA_I2HM(10),
-
-       BFI_LL_I2H_RXF_PROMISCUOUS_SET_RSP = BFA_I2HM(11),
-       BFI_LL_I2H_RXF_DEFAULT_SET_RSP = BFA_I2HM(12),
-
-       BFI_LL_I2H_TXQ_STOP_RSP = BFA_I2HM(13),
-       BFI_LL_I2H_RXQ_STOP_RSP = BFA_I2HM(14),
-
-       BFI_LL_I2H_DIAG_LOOPBACK_RSP = BFA_I2HM(15),
-
-       BFI_LL_I2H_SET_PAUSE_RSP = BFA_I2HM(16),
-
-       BFI_LL_I2H_MTU_INFO_RSP = BFA_I2HM(17),
-       BFI_LL_I2H_RX_RSP = BFA_I2HM(18),
-
-       BFI_LL_I2H_LINK_DOWN_AEN = BFA_I2HM(19),
-       BFI_LL_I2H_LINK_UP_AEN = BFA_I2HM(20),
-
-       BFI_LL_I2H_PORT_ENABLE_AEN = BFA_I2HM(21),
-       BFI_LL_I2H_PORT_DISABLE_AEN = BFA_I2HM(22),
-} ;
-
-/**
- * @brief bfi_ll_mac_addr_req is used by:
- *        BFI_LL_H2I_MAC_UCAST_SET_REQ
- *        BFI_LL_H2I_MAC_UCAST_ADD_REQ
- *        BFI_LL_H2I_MAC_UCAST_DEL_REQ
- *        BFI_LL_H2I_MAC_MCAST_ADD_REQ
- *        BFI_LL_H2I_MAC_MCAST_DEL_REQ
- */
-struct bfi_ll_mac_addr_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8              rxf_id;
-       u8              rsvd1[3];
-       mac_t           mac_addr;
-       u8              rsvd2[2];
-};
-
-/**
- * @brief bfi_ll_mcast_filter_req is used by:
- *       BFI_LL_H2I_MAC_MCAST_FILTER_REQ
- */
-struct bfi_ll_mcast_filter_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8              rxf_id;
-       u8              enable;
-       u8              rsvd[2];
-};
-
-/**
- * @brief bfi_ll_mcast_del_all is used by:
- *       BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ
- */
-struct bfi_ll_mcast_del_all_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8                 rxf_id;
-       u8                 rsvd[3];
-};
-
-/**
- * @brief bfi_ll_q_stop_req is used by:
- *     BFI_LL_H2I_TXQ_STOP_REQ
- *     BFI_LL_H2I_RXQ_STOP_REQ
- */
-struct bfi_ll_q_stop_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u32     q_id_mask[2];   /* !< bit-mask for queue ids */
-};
-
-/**
- * @brief bfi_ll_stats_req is used by:
- *    BFI_LL_I2H_STATS_GET_REQ
- *    BFI_LL_I2H_STATS_CLEAR_REQ
- */
-struct bfi_ll_stats_req {
-       struct bfi_mhdr mh;     /*!< common msg header */
-       u16 stats_mask; /* !< bit-mask for non-function statistics */
-       u8      rsvd[2];
-       u32 rxf_id_mask[2];     /* !< bit-mask for RxF Statistics */
-       u32 txf_id_mask[2];     /* !< bit-mask for TxF Statistics */
-       union bfi_addr_u  host_buffer;  /* !< where statistics are returned */
-};
-
-/**
- * @brief defines for "stats_mask" above.
- */
-#define BFI_LL_STATS_MAC       (1 << 0)        /* !< MAC Statistics */
-#define BFI_LL_STATS_BPC       (1 << 1)        /* !< Pause Stats from BPC */
-#define BFI_LL_STATS_RAD       (1 << 2)        /* !< Rx Admission Statistics */
-#define BFI_LL_STATS_RX_FC     (1 << 3)        /* !< Rx FC Stats from RxA */
-#define BFI_LL_STATS_TX_FC     (1 << 4)        /* !< Tx FC Stats from TxA */
-
-#define BFI_LL_STATS_ALL       0x1f
-
-/**
- * @brief bfi_ll_port_admin_req
- */
-struct bfi_ll_port_admin_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8               up;
-       u8               rsvd[3];
-};
-
-/**
- * @brief bfi_ll_rxf_req is used by:
- *      BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ
- *      BFI_LL_H2I_RXF_DEFAULT_SET_REQ
- */
-struct bfi_ll_rxf_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8              rxf_id;
-       u8              enable;
-       u8              rsvd[2];
-};
-
-/**
- * @brief bfi_ll_rxf_multi_req is used by:
- *     BFI_LL_H2I_RX_REQ
- */
-struct bfi_ll_rxf_multi_req {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u32     rxf_id_mask[2];
-       u8              enable;
-       u8              rsvd[3];
-};
-
-/**
- * @brief enum for Loopback opmodes
- */
-enum {
-       BFI_LL_DIAG_LB_OPMODE_EXT = 0,
-       BFI_LL_DIAG_LB_OPMODE_CBL = 1,
-};
-
-/**
- * @brief bfi_ll_set_pause_req is used by:
- *     BFI_LL_H2I_SET_PAUSE_REQ
- */
-struct bfi_ll_set_pause_req {
-       struct bfi_mhdr mh;
-       u8              tx_pause; /* 1 = enable, 0 =  disable */
-       u8              rx_pause; /* 1 = enable, 0 =  disable */
-       u8              rsvd[2];
-};
-
-/**
- * @brief bfi_ll_mtu_info_req is used by:
- *     BFI_LL_H2I_MTU_INFO_REQ
- */
-struct bfi_ll_mtu_info_req {
-       struct bfi_mhdr mh;
-       u16     mtu;
-       u8              rsvd[2];
-};
-
-/**
- * @brief
- *       Response header format used by all responses
- *       For both responses and asynchronous notifications
- */
-struct bfi_ll_rsp {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8              error;
-       u8              rsvd[3];
-};
-
-/**
- * @brief bfi_ll_cee_aen is used by:
- *     BFI_LL_I2H_LINK_DOWN_AEN
- *     BFI_LL_I2H_LINK_UP_AEN
- */
-struct bfi_ll_aen {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u32     reason;
-       u8              cee_linkup;
-       u8              prio_map;    /*!< LL priority bit-map */
-       u8              rsvd[2];
-};
-
-/**
- * @brief
- *     The following error codes can be returned
- *     by the mbox commands
- */
-enum {
-       BFI_LL_CMD_OK           = 0,
-       BFI_LL_CMD_FAIL         = 1,
-       BFI_LL_CMD_DUP_ENTRY    = 2,    /* !< Duplicate entry in CAM */
-       BFI_LL_CMD_CAM_FULL     = 3,    /* !< CAM is full */
-       BFI_LL_CMD_NOT_OWNER    = 4,    /* !< Not permitted, b'cos not owner */
-       BFI_LL_CMD_NOT_EXEC     = 5,    /* !< Was not sent to f/w at all */
-       BFI_LL_CMD_WAITING      = 6,    /* !< Waiting for completion (VMware) */
-       BFI_LL_CMD_PORT_DISABLED        = 7,    /* !< port in disabled state */
-} ;
-
-/* Statistics */
-#define BFI_LL_TXF_ID_MAX      64
-#define BFI_LL_RXF_ID_MAX      64
-
-/* TxF Frame Statistics */
-struct bfi_ll_stats_txf {
-       u64 ucast_octets;
-       u64 ucast;
-       u64 ucast_vlan;
-
-       u64 mcast_octets;
-       u64 mcast;
-       u64 mcast_vlan;
-
-       u64 bcast_octets;
-       u64 bcast;
-       u64 bcast_vlan;
-
-       u64 errors;
-       u64 filter_vlan;      /* frames filtered due to VLAN */
-       u64 filter_mac_sa;    /* frames filtered due to SA check */
-};
-
-/* RxF Frame Statistics */
-struct bfi_ll_stats_rxf {
-       u64 ucast_octets;
-       u64 ucast;
-       u64 ucast_vlan;
-
-       u64 mcast_octets;
-       u64 mcast;
-       u64 mcast_vlan;
-
-       u64 bcast_octets;
-       u64 bcast;
-       u64 bcast_vlan;
-       u64 frame_drops;
-};
-
-/* FC Tx Frame Statistics */
-struct bfi_ll_stats_fc_tx {
-       u64 txf_ucast_octets;
-       u64 txf_ucast;
-       u64 txf_ucast_vlan;
-
-       u64 txf_mcast_octets;
-       u64 txf_mcast;
-       u64 txf_mcast_vlan;
-
-       u64 txf_bcast_octets;
-       u64 txf_bcast;
-       u64 txf_bcast_vlan;
-
-       u64 txf_parity_errors;
-       u64 txf_timeout;
-       u64 txf_fid_parity_errors;
-};
-
-/* FC Rx Frame Statistics */
-struct bfi_ll_stats_fc_rx {
-       u64 rxf_ucast_octets;
-       u64 rxf_ucast;
-       u64 rxf_ucast_vlan;
-
-       u64 rxf_mcast_octets;
-       u64 rxf_mcast;
-       u64 rxf_mcast_vlan;
-
-       u64 rxf_bcast_octets;
-       u64 rxf_bcast;
-       u64 rxf_bcast_vlan;
-};
-
-/* RAD Frame Statistics */
-struct bfi_ll_stats_rad {
-       u64 rx_frames;
-       u64 rx_octets;
-       u64 rx_vlan_frames;
-
-       u64 rx_ucast;
-       u64 rx_ucast_octets;
-       u64 rx_ucast_vlan;
-
-       u64 rx_mcast;
-       u64 rx_mcast_octets;
-       u64 rx_mcast_vlan;
-
-       u64 rx_bcast;
-       u64 rx_bcast_octets;
-       u64 rx_bcast_vlan;
-
-       u64 rx_drops;
-};
-
-/* BPC Tx Registers */
-struct bfi_ll_stats_bpc {
-       /* transmit stats */
-       u64 tx_pause[8];
-       u64 tx_zero_pause[8];   /*!< Pause cancellation */
-       /*!<Pause initiation rather than retention */
-       u64 tx_first_pause[8];
-
-       /* receive stats */
-       u64 rx_pause[8];
-       u64 rx_zero_pause[8];   /*!< Pause cancellation */
-       /*!<Pause initiation rather than retention */
-       u64 rx_first_pause[8];
-};
-
-/* MAC Rx Statistics */
-struct bfi_ll_stats_mac {
-       u64 frame_64;           /* both rx and tx counter */
-       u64 frame_65_127;               /* both rx and tx counter */
-       u64 frame_128_255;              /* both rx and tx counter */
-       u64 frame_256_511;              /* both rx and tx counter */
-       u64 frame_512_1023;     /* both rx and tx counter */
-       u64 frame_1024_1518;    /* both rx and tx counter */
-       u64 frame_1519_1522;    /* both rx and tx counter */
-
-       /* receive stats */
-       u64 rx_bytes;
-       u64 rx_packets;
-       u64 rx_fcs_error;
-       u64 rx_multicast;
-       u64 rx_broadcast;
-       u64 rx_control_frames;
-       u64 rx_pause;
-       u64 rx_unknown_opcode;
-       u64 rx_alignment_error;
-       u64 rx_frame_length_error;
-       u64 rx_code_error;
-       u64 rx_carrier_sense_error;
-       u64 rx_undersize;
-       u64 rx_oversize;
-       u64 rx_fragments;
-       u64 rx_jabber;
-       u64 rx_drop;
-
-       /* transmit stats */
-       u64 tx_bytes;
-       u64 tx_packets;
-       u64 tx_multicast;
-       u64 tx_broadcast;
-       u64 tx_pause;
-       u64 tx_deferral;
-       u64 tx_excessive_deferral;
-       u64 tx_single_collision;
-       u64 tx_muliple_collision;
-       u64 tx_late_collision;
-       u64 tx_excessive_collision;
-       u64 tx_total_collision;
-       u64 tx_pause_honored;
-       u64 tx_drop;
-       u64 tx_jabber;
-       u64 tx_fcs_error;
-       u64 tx_control_frame;
-       u64 tx_oversize;
-       u64 tx_undersize;
-       u64 tx_fragments;
-};
-
-/* Complete statistics */
-struct bfi_ll_stats {
-       struct bfi_ll_stats_mac         mac_stats;
-       struct bfi_ll_stats_bpc         bpc_stats;
-       struct bfi_ll_stats_rad         rad_stats;
-       struct bfi_ll_stats_fc_rx       fc_rx_stats;
-       struct bfi_ll_stats_fc_tx       fc_tx_stats;
-       struct bfi_ll_stats_rxf rxf_stats[BFI_LL_RXF_ID_MAX];
-       struct bfi_ll_stats_txf txf_stats[BFI_LL_TXF_ID_MAX];
-};
-
-#pragma pack()
-
-#endif  /* __BFI_LL_H__ */
diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c
deleted file mode 100644 (file)
index cb2594c..0000000
+++ /dev/null
@@ -1,3076 +0,0 @@
-/*
- * Linux network driver for Brocade Converged Network Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- */
-#include "bna.h"
-#include "bfa_cs.h"
-
-static void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status);
-
-static void
-bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen,
-                       int status)
-{
-       int i;
-       u8 prio_map;
-
-       port->llport.link_status = BNA_LINK_UP;
-       if (aen->cee_linkup)
-               port->llport.link_status = BNA_CEE_UP;
-
-       /* Compute the priority */
-       prio_map = aen->prio_map;
-       if (prio_map) {
-               for (i = 0; i < 8; i++) {
-                       if ((prio_map >> i) & 0x1)
-                               break;
-               }
-               port->priority = i;
-       } else
-               port->priority = 0;
-
-       /* Dispatch events */
-       bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup);
-       bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority);
-       port->link_cbfn(port->bna->bnad, port->llport.link_status);
-}
-
-static void
-bna_port_cb_link_down(struct bna_port *port, int status)
-{
-       port->llport.link_status = BNA_LINK_DOWN;
-
-       /* Dispatch events */
-       bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN);
-       port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN);
-}
-
-static inline int
-llport_can_be_up(struct bna_llport *llport)
-{
-       int ready = 0;
-       if (llport->type == BNA_PORT_T_REGULAR)
-               ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) &&
-                        (llport->flags & BNA_LLPORT_F_RX_STARTED) &&
-                        (llport->flags & BNA_LLPORT_F_PORT_ENABLED));
-       else
-               ready = ((llport->flags & BNA_LLPORT_F_ADMIN_UP) &&
-                        (llport->flags & BNA_LLPORT_F_RX_STARTED) &&
-                        !(llport->flags & BNA_LLPORT_F_PORT_ENABLED));
-       return ready;
-}
-
-#define llport_is_up llport_can_be_up
-
-enum bna_llport_event {
-       LLPORT_E_START                  = 1,
-       LLPORT_E_STOP                   = 2,
-       LLPORT_E_FAIL                   = 3,
-       LLPORT_E_UP                     = 4,
-       LLPORT_E_DOWN                   = 5,
-       LLPORT_E_FWRESP_UP_OK           = 6,
-       LLPORT_E_FWRESP_UP_FAIL         = 7,
-       LLPORT_E_FWRESP_DOWN            = 8
-};
-
-static void
-bna_llport_cb_port_enabled(struct bna_llport *llport)
-{
-       llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
-
-       if (llport_can_be_up(llport))
-               bfa_fsm_send_event(llport, LLPORT_E_UP);
-}
-
-static void
-bna_llport_cb_port_disabled(struct bna_llport *llport)
-{
-       int llport_up = llport_is_up(llport);
-
-       llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
-
-       if (llport_up)
-               bfa_fsm_send_event(llport, LLPORT_E_DOWN);
-}
-
-/**
- * MBOX
- */
-static int
-bna_is_aen(u8 msg_id)
-{
-       switch (msg_id) {
-       case BFI_LL_I2H_LINK_DOWN_AEN:
-       case BFI_LL_I2H_LINK_UP_AEN:
-       case BFI_LL_I2H_PORT_ENABLE_AEN:
-       case BFI_LL_I2H_PORT_DISABLE_AEN:
-               return 1;
-
-       default:
-               return 0;
-       }
-}
-
-static void
-bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg)
-{
-       struct bfi_ll_aen *aen = (struct bfi_ll_aen *)(msg);
-
-       switch (aen->mh.msg_id) {
-       case BFI_LL_I2H_LINK_UP_AEN:
-               bna_port_cb_link_up(&bna->port, aen, aen->reason);
-               break;
-       case BFI_LL_I2H_LINK_DOWN_AEN:
-               bna_port_cb_link_down(&bna->port, aen->reason);
-               break;
-       case BFI_LL_I2H_PORT_ENABLE_AEN:
-               bna_llport_cb_port_enabled(&bna->port.llport);
-               break;
-       case BFI_LL_I2H_PORT_DISABLE_AEN:
-               bna_llport_cb_port_disabled(&bna->port.llport);
-               break;
-       default:
-               break;
-       }
-}
-
-static void
-bna_ll_isr(void *llarg, struct bfi_mbmsg *msg)
-{
-       struct bna *bna = (struct bna *)(llarg);
-       struct bfi_ll_rsp *mb_rsp = (struct bfi_ll_rsp *)(msg);
-       struct bfi_mhdr *cmd_h, *rsp_h;
-       struct bna_mbox_qe *mb_qe = NULL;
-       int to_post = 0;
-       u8 aen = 0;
-       char message[BNA_MESSAGE_SIZE];
-
-       aen = bna_is_aen(mb_rsp->mh.msg_id);
-
-       if (!aen) {
-               mb_qe = bfa_q_first(&bna->mbox_mod.posted_q);
-               cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
-               rsp_h = (struct bfi_mhdr *)(&mb_rsp->mh);
-
-               if ((BFA_I2HM(cmd_h->msg_id) == rsp_h->msg_id) &&
-                   (cmd_h->mtag.i2htok == rsp_h->mtag.i2htok)) {
-                       /* Remove the request from posted_q, update state  */
-                       list_del(&mb_qe->qe);
-                       bna->mbox_mod.msg_pending--;
-                       if (list_empty(&bna->mbox_mod.posted_q))
-                               bna->mbox_mod.state = BNA_MBOX_FREE;
-                       else
-                               to_post = 1;
-
-                       /* Dispatch the cbfn */
-                       if (mb_qe->cbfn)
-                               mb_qe->cbfn(mb_qe->cbarg, mb_rsp->error);
-
-                       /* Post the next entry, if needed */
-                       if (to_post) {
-                               mb_qe = bfa_q_first(&bna->mbox_mod.posted_q);
-                               bfa_nw_ioc_mbox_queue(&bna->device.ioc,
-                                                       &mb_qe->cmd);
-                       }
-               } else {
-                       snprintf(message, BNA_MESSAGE_SIZE,
-                                      "No matching rsp for [%d:%d:%d]\n",
-                                      mb_rsp->mh.msg_class, mb_rsp->mh.msg_id,
-                                      mb_rsp->mh.mtag.i2htok);
-               pr_info("%s", message);
-               }
-
-       } else
-               bna_mbox_aen_callback(bna, msg);
-}
-
-static void
-bna_err_handler(struct bna *bna, u32 intr_status)
-{
-       u32 init_halt;
-
-       if (intr_status & __HALT_STATUS_BITS) {
-               init_halt = readl(bna->device.ioc.ioc_regs.ll_halt);
-               init_halt &= ~__FW_INIT_HALT_P;
-               writel(init_halt, bna->device.ioc.ioc_regs.ll_halt);
-       }
-
-       bfa_nw_ioc_error_isr(&bna->device.ioc);
-}
-
-void
-bna_mbox_handler(struct bna *bna, u32 intr_status)
-{
-       if (BNA_IS_ERR_INTR(intr_status)) {
-               bna_err_handler(bna, intr_status);
-               return;
-       }
-       if (BNA_IS_MBOX_INTR(intr_status))
-               bfa_nw_ioc_mbox_isr(&bna->device.ioc);
-}
-
-void
-bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe)
-{
-       struct bfi_mhdr *mh;
-
-       mh = (struct bfi_mhdr *)(&mbox_qe->cmd.msg[0]);
-
-       mh->mtag.i2htok = htons(bna->mbox_mod.msg_ctr);
-       bna->mbox_mod.msg_ctr++;
-       bna->mbox_mod.msg_pending++;
-       if (bna->mbox_mod.state == BNA_MBOX_FREE) {
-               list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q);
-               bfa_nw_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd);
-               bna->mbox_mod.state = BNA_MBOX_POSTED;
-       } else {
-               list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q);
-       }
-}
-
-static void
-bna_mbox_flush_q(struct bna *bna, struct list_head *q)
-{
-       struct bna_mbox_qe *mb_qe = NULL;
-       struct list_head                        *mb_q;
-       void                    (*cbfn)(void *arg, int status);
-       void                    *cbarg;
-
-       mb_q = &bna->mbox_mod.posted_q;
-
-       while (!list_empty(mb_q)) {
-               bfa_q_deq(mb_q, &mb_qe);
-               cbfn = mb_qe->cbfn;
-               cbarg = mb_qe->cbarg;
-               bfa_q_qe_init(mb_qe);
-               bna->mbox_mod.msg_pending--;
-
-               if (cbfn)
-                       cbfn(cbarg, BNA_CB_NOT_EXEC);
-       }
-
-       bna->mbox_mod.state = BNA_MBOX_FREE;
-}
-
-static void
-bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod)
-{
-}
-
-static void
-bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod)
-{
-       bna_mbox_flush_q(mbox_mod->bna, &mbox_mod->posted_q);
-}
-
-static void
-bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna)
-{
-       bfa_nw_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna);
-       mbox_mod->state = BNA_MBOX_FREE;
-       mbox_mod->msg_ctr = mbox_mod->msg_pending = 0;
-       INIT_LIST_HEAD(&mbox_mod->posted_q);
-       mbox_mod->bna = bna;
-}
-
-static void
-bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod)
-{
-       mbox_mod->bna = NULL;
-}
-
-/**
- * LLPORT
- */
-#define call_llport_stop_cbfn(llport, status)\
-do {\
-       if ((llport)->stop_cbfn)\
-               (llport)->stop_cbfn(&(llport)->bna->port, status);\
-       (llport)->stop_cbfn = NULL;\
-} while (0)
-
-static void bna_fw_llport_up(struct bna_llport *llport);
-static void bna_fw_cb_llport_up(void *arg, int status);
-static void bna_fw_llport_down(struct bna_llport *llport);
-static void bna_fw_cb_llport_down(void *arg, int status);
-static void bna_llport_start(struct bna_llport *llport);
-static void bna_llport_stop(struct bna_llport *llport);
-static void bna_llport_fail(struct bna_llport *llport);
-
-enum bna_llport_state {
-       BNA_LLPORT_STOPPED              = 1,
-       BNA_LLPORT_DOWN                 = 2,
-       BNA_LLPORT_UP_RESP_WAIT         = 3,
-       BNA_LLPORT_DOWN_RESP_WAIT       = 4,
-       BNA_LLPORT_UP                   = 5,
-       BNA_LLPORT_LAST_RESP_WAIT       = 6
-};
-
-bfa_fsm_state_decl(bna_llport, stopped, struct bna_llport,
-                       enum bna_llport_event);
-bfa_fsm_state_decl(bna_llport, down, struct bna_llport,
-                       enum bna_llport_event);
-bfa_fsm_state_decl(bna_llport, up_resp_wait, struct bna_llport,
-                       enum bna_llport_event);
-bfa_fsm_state_decl(bna_llport, down_resp_wait, struct bna_llport,
-                       enum bna_llport_event);
-bfa_fsm_state_decl(bna_llport, up, struct bna_llport,
-                       enum bna_llport_event);
-bfa_fsm_state_decl(bna_llport, last_resp_wait, struct bna_llport,
-                       enum bna_llport_event);
-
-static struct bfa_sm_table llport_sm_table[] = {
-       {BFA_SM(bna_llport_sm_stopped), BNA_LLPORT_STOPPED},
-       {BFA_SM(bna_llport_sm_down), BNA_LLPORT_DOWN},
-       {BFA_SM(bna_llport_sm_up_resp_wait), BNA_LLPORT_UP_RESP_WAIT},
-       {BFA_SM(bna_llport_sm_down_resp_wait), BNA_LLPORT_DOWN_RESP_WAIT},
-       {BFA_SM(bna_llport_sm_up), BNA_LLPORT_UP},
-       {BFA_SM(bna_llport_sm_last_resp_wait), BNA_LLPORT_LAST_RESP_WAIT}
-};
-
-static void
-bna_llport_sm_stopped_entry(struct bna_llport *llport)
-{
-       llport->bna->port.link_cbfn((llport)->bna->bnad, BNA_LINK_DOWN);
-       call_llport_stop_cbfn(llport, BNA_CB_SUCCESS);
-}
-
-static void
-bna_llport_sm_stopped(struct bna_llport *llport,
-                       enum bna_llport_event event)
-{
-       switch (event) {
-       case LLPORT_E_START:
-               bfa_fsm_set_state(llport, bna_llport_sm_down);
-               break;
-
-       case LLPORT_E_STOP:
-               call_llport_stop_cbfn(llport, BNA_CB_SUCCESS);
-               break;
-
-       case LLPORT_E_FAIL:
-               break;
-
-       case LLPORT_E_DOWN:
-               /* This event is received due to Rx objects failing */
-               /* No-op */
-               break;
-
-       case LLPORT_E_FWRESP_UP_OK:
-       case LLPORT_E_FWRESP_DOWN:
-               /**
-                * These events are received due to flushing of mbox when
-                * device fails
-                */
-               /* No-op */
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_llport_sm_down_entry(struct bna_llport *llport)
-{
-       bnad_cb_port_link_status((llport)->bna->bnad, BNA_LINK_DOWN);
-}
-
-static void
-bna_llport_sm_down(struct bna_llport *llport,
-                       enum bna_llport_event event)
-{
-       switch (event) {
-       case LLPORT_E_STOP:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       case LLPORT_E_FAIL:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       case LLPORT_E_UP:
-               bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
-               bna_fw_llport_up(llport);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport)
-{
-       BUG_ON(!llport_can_be_up(llport));
-       /**
-        * NOTE: Do not call bna_fw_llport_up() here. That will over step
-        * mbox due to down_resp_wait -> up_resp_wait transition on event
-        * LLPORT_E_UP
-        */
-}
-
-static void
-bna_llport_sm_up_resp_wait(struct bna_llport *llport,
-                       enum bna_llport_event event)
-{
-       switch (event) {
-       case LLPORT_E_STOP:
-               bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
-               break;
-
-       case LLPORT_E_FAIL:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       case LLPORT_E_DOWN:
-               bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
-               break;
-
-       case LLPORT_E_FWRESP_UP_OK:
-               bfa_fsm_set_state(llport, bna_llport_sm_up);
-               break;
-
-       case LLPORT_E_FWRESP_UP_FAIL:
-               bfa_fsm_set_state(llport, bna_llport_sm_down);
-               break;
-
-       case LLPORT_E_FWRESP_DOWN:
-               /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */
-               bna_fw_llport_up(llport);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_llport_sm_down_resp_wait_entry(struct bna_llport *llport)
-{
-       /**
-        * NOTE: Do not call bna_fw_llport_down() here. That will over step
-        * mbox due to up_resp_wait -> down_resp_wait transition on event
-        * LLPORT_E_DOWN
-        */
-}
-
-static void
-bna_llport_sm_down_resp_wait(struct bna_llport *llport,
-                       enum bna_llport_event event)
-{
-       switch (event) {
-       case LLPORT_E_STOP:
-               bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
-               break;
-
-       case LLPORT_E_FAIL:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       case LLPORT_E_UP:
-               bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
-               break;
-
-       case LLPORT_E_FWRESP_UP_OK:
-               /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */
-               bna_fw_llport_down(llport);
-               break;
-
-       case LLPORT_E_FWRESP_UP_FAIL:
-       case LLPORT_E_FWRESP_DOWN:
-               bfa_fsm_set_state(llport, bna_llport_sm_down);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_llport_sm_up_entry(struct bna_llport *llport)
-{
-}
-
-static void
-bna_llport_sm_up(struct bna_llport *llport,
-                       enum bna_llport_event event)
-{
-       switch (event) {
-       case LLPORT_E_STOP:
-               bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
-               bna_fw_llport_down(llport);
-               break;
-
-       case LLPORT_E_FAIL:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       case LLPORT_E_DOWN:
-               bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
-               bna_fw_llport_down(llport);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_llport_sm_last_resp_wait_entry(struct bna_llport *llport)
-{
-}
-
-static void
-bna_llport_sm_last_resp_wait(struct bna_llport *llport,
-                       enum bna_llport_event event)
-{
-       switch (event) {
-       case LLPORT_E_FAIL:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       case LLPORT_E_DOWN:
-               /**
-                * This event is received due to Rx objects stopping in
-                * parallel to llport
-                */
-               /* No-op */
-               break;
-
-       case LLPORT_E_FWRESP_UP_OK:
-               /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */
-               bna_fw_llport_down(llport);
-               break;
-
-       case LLPORT_E_FWRESP_UP_FAIL:
-       case LLPORT_E_FWRESP_DOWN:
-               bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_fw_llport_admin_up(struct bna_llport *llport)
-{
-       struct bfi_ll_port_admin_req ll_req;
-
-       memset(&ll_req, 0, sizeof(ll_req));
-       ll_req.mh.msg_class = BFI_MC_LL;
-       ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
-       ll_req.mh.mtag.h2i.lpu_id = 0;
-
-       ll_req.up = BNA_STATUS_T_ENABLED;
-
-       bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req),
-                       bna_fw_cb_llport_up, llport);
-
-       bna_mbox_send(llport->bna, &llport->mbox_qe);
-}
-
-static void
-bna_fw_llport_up(struct bna_llport *llport)
-{
-       if (llport->type == BNA_PORT_T_REGULAR)
-               bna_fw_llport_admin_up(llport);
-}
-
-static void
-bna_fw_cb_llport_up(void *arg, int status)
-{
-       struct bna_llport *llport = (struct bna_llport *)arg;
-
-       bfa_q_qe_init(&llport->mbox_qe.qe);
-       if (status == BFI_LL_CMD_FAIL) {
-               if (llport->type == BNA_PORT_T_REGULAR)
-                       llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
-               else
-                       llport->flags &= ~BNA_LLPORT_F_ADMIN_UP;
-               bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_FAIL);
-       } else
-               bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP_OK);
-}
-
-static void
-bna_fw_llport_admin_down(struct bna_llport *llport)
-{
-       struct bfi_ll_port_admin_req ll_req;
-
-       memset(&ll_req, 0, sizeof(ll_req));
-       ll_req.mh.msg_class = BFI_MC_LL;
-       ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
-       ll_req.mh.mtag.h2i.lpu_id = 0;
-
-       ll_req.up = BNA_STATUS_T_DISABLED;
-
-       bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req),
-                       bna_fw_cb_llport_down, llport);
-
-       bna_mbox_send(llport->bna, &llport->mbox_qe);
-}
-
-static void
-bna_fw_llport_down(struct bna_llport *llport)
-{
-       if (llport->type == BNA_PORT_T_REGULAR)
-               bna_fw_llport_admin_down(llport);
-}
-
-static void
-bna_fw_cb_llport_down(void *arg, int status)
-{
-       struct bna_llport *llport = (struct bna_llport *)arg;
-
-       bfa_q_qe_init(&llport->mbox_qe.qe);
-       bfa_fsm_send_event(llport, LLPORT_E_FWRESP_DOWN);
-}
-
-static void
-bna_port_cb_llport_stopped(struct bna_port *port,
-                               enum bna_cb_status status)
-{
-       bfa_wc_down(&port->chld_stop_wc);
-}
-
-static void
-bna_llport_init(struct bna_llport *llport, struct bna *bna)
-{
-       llport->flags |= BNA_LLPORT_F_ADMIN_UP;
-       llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
-       llport->type = BNA_PORT_T_REGULAR;
-       llport->bna = bna;
-
-       llport->link_status = BNA_LINK_DOWN;
-
-       llport->rx_started_count = 0;
-
-       llport->stop_cbfn = NULL;
-
-       bfa_q_qe_init(&llport->mbox_qe.qe);
-
-       bfa_fsm_set_state(llport, bna_llport_sm_stopped);
-}
-
-static void
-bna_llport_uninit(struct bna_llport *llport)
-{
-       llport->flags &= ~BNA_LLPORT_F_ADMIN_UP;
-       llport->flags &= ~BNA_LLPORT_F_PORT_ENABLED;
-
-       llport->bna = NULL;
-}
-
-static void
-bna_llport_start(struct bna_llport *llport)
-{
-       bfa_fsm_send_event(llport, LLPORT_E_START);
-}
-
-static void
-bna_llport_stop(struct bna_llport *llport)
-{
-       llport->stop_cbfn = bna_port_cb_llport_stopped;
-
-       bfa_fsm_send_event(llport, LLPORT_E_STOP);
-}
-
-static void
-bna_llport_fail(struct bna_llport *llport)
-{
-       /* Reset the physical port status to enabled */
-       llport->flags |= BNA_LLPORT_F_PORT_ENABLED;
-       bfa_fsm_send_event(llport, LLPORT_E_FAIL);
-}
-
-static int
-bna_llport_state_get(struct bna_llport *llport)
-{
-       return bfa_sm_to_state(llport_sm_table, llport->fsm);
-}
-
-void
-bna_llport_rx_started(struct bna_llport *llport)
-{
-       llport->rx_started_count++;
-
-       if (llport->rx_started_count == 1) {
-
-               llport->flags |= BNA_LLPORT_F_RX_STARTED;
-
-               if (llport_can_be_up(llport))
-                       bfa_fsm_send_event(llport, LLPORT_E_UP);
-       }
-}
-
-void
-bna_llport_rx_stopped(struct bna_llport *llport)
-{
-       int llport_up = llport_is_up(llport);
-
-       llport->rx_started_count--;
-
-       if (llport->rx_started_count == 0) {
-
-               llport->flags &= ~BNA_LLPORT_F_RX_STARTED;
-
-               if (llport_up)
-                       bfa_fsm_send_event(llport, LLPORT_E_DOWN);
-       }
-}
-
-/**
- * PORT
- */
-#define bna_port_chld_start(port)\
-do {\
-       enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
-                                       BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\
-       enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
-                                       BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
-       bna_llport_start(&(port)->llport);\
-       bna_tx_mod_start(&(port)->bna->tx_mod, tx_type);\
-       bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\
-} while (0)
-
-#define bna_port_chld_stop(port)\
-do {\
-       enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
-                                       BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\
-       enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
-                                       BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
-       bfa_wc_up(&(port)->chld_stop_wc);\
-       bfa_wc_up(&(port)->chld_stop_wc);\
-       bfa_wc_up(&(port)->chld_stop_wc);\
-       bna_llport_stop(&(port)->llport);\
-       bna_tx_mod_stop(&(port)->bna->tx_mod, tx_type);\
-       bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\
-} while (0)
-
-#define bna_port_chld_fail(port)\
-do {\
-       bna_llport_fail(&(port)->llport);\
-       bna_tx_mod_fail(&(port)->bna->tx_mod);\
-       bna_rx_mod_fail(&(port)->bna->rx_mod);\
-} while (0)
-
-#define bna_port_rx_start(port)\
-do {\
-       enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
-                                       BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
-       bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\
-} while (0)
-
-#define bna_port_rx_stop(port)\
-do {\
-       enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
-                                       BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
-       bfa_wc_up(&(port)->chld_stop_wc);\
-       bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\
-} while (0)
-
-#define call_port_stop_cbfn(port, status)\
-do {\
-       if ((port)->stop_cbfn)\
-               (port)->stop_cbfn((port)->stop_cbarg, status);\
-       (port)->stop_cbfn = NULL;\
-       (port)->stop_cbarg = NULL;\
-} while (0)
-
-#define call_port_pause_cbfn(port, status)\
-do {\
-       if ((port)->pause_cbfn)\
-               (port)->pause_cbfn((port)->bna->bnad, status);\
-       (port)->pause_cbfn = NULL;\
-} while (0)
-
-#define call_port_mtu_cbfn(port, status)\
-do {\
-       if ((port)->mtu_cbfn)\
-               (port)->mtu_cbfn((port)->bna->bnad, status);\
-       (port)->mtu_cbfn = NULL;\
-} while (0)
-
-static void bna_fw_pause_set(struct bna_port *port);
-static void bna_fw_cb_pause_set(void *arg, int status);
-static void bna_fw_mtu_set(struct bna_port *port);
-static void bna_fw_cb_mtu_set(void *arg, int status);
-
-enum bna_port_event {
-       PORT_E_START                    = 1,
-       PORT_E_STOP                     = 2,
-       PORT_E_FAIL                     = 3,
-       PORT_E_PAUSE_CFG                = 4,
-       PORT_E_MTU_CFG                  = 5,
-       PORT_E_CHLD_STOPPED             = 6,
-       PORT_E_FWRESP_PAUSE             = 7,
-       PORT_E_FWRESP_MTU               = 8
-};
-
-enum bna_port_state {
-       BNA_PORT_STOPPED                = 1,
-       BNA_PORT_MTU_INIT_WAIT          = 2,
-       BNA_PORT_PAUSE_INIT_WAIT        = 3,
-       BNA_PORT_LAST_RESP_WAIT         = 4,
-       BNA_PORT_STARTED                = 5,
-       BNA_PORT_PAUSE_CFG_WAIT         = 6,
-       BNA_PORT_RX_STOP_WAIT           = 7,
-       BNA_PORT_MTU_CFG_WAIT           = 8,
-       BNA_PORT_CHLD_STOP_WAIT         = 9
-};
-
-bfa_fsm_state_decl(bna_port, stopped, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, mtu_init_wait, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, pause_init_wait, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, last_resp_wait, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, started, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, pause_cfg_wait, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, rx_stop_wait, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, mtu_cfg_wait, struct bna_port,
-                       enum bna_port_event);
-bfa_fsm_state_decl(bna_port, chld_stop_wait, struct bna_port,
-                       enum bna_port_event);
-
-static struct bfa_sm_table port_sm_table[] = {
-       {BFA_SM(bna_port_sm_stopped), BNA_PORT_STOPPED},
-       {BFA_SM(bna_port_sm_mtu_init_wait), BNA_PORT_MTU_INIT_WAIT},
-       {BFA_SM(bna_port_sm_pause_init_wait), BNA_PORT_PAUSE_INIT_WAIT},
-       {BFA_SM(bna_port_sm_last_resp_wait), BNA_PORT_LAST_RESP_WAIT},
-       {BFA_SM(bna_port_sm_started), BNA_PORT_STARTED},
-       {BFA_SM(bna_port_sm_pause_cfg_wait), BNA_PORT_PAUSE_CFG_WAIT},
-       {BFA_SM(bna_port_sm_rx_stop_wait), BNA_PORT_RX_STOP_WAIT},
-       {BFA_SM(bna_port_sm_mtu_cfg_wait), BNA_PORT_MTU_CFG_WAIT},
-       {BFA_SM(bna_port_sm_chld_stop_wait), BNA_PORT_CHLD_STOP_WAIT}
-};
-
-static void
-bna_port_sm_stopped_entry(struct bna_port *port)
-{
-       call_port_pause_cbfn(port, BNA_CB_SUCCESS);
-       call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
-       call_port_stop_cbfn(port, BNA_CB_SUCCESS);
-}
-
-static void
-bna_port_sm_stopped(struct bna_port *port, enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_START:
-               bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait);
-               break;
-
-       case PORT_E_STOP:
-               call_port_stop_cbfn(port, BNA_CB_SUCCESS);
-               break;
-
-       case PORT_E_FAIL:
-               /* No-op */
-               break;
-
-       case PORT_E_PAUSE_CFG:
-               call_port_pause_cbfn(port, BNA_CB_SUCCESS);
-               break;
-
-       case PORT_E_MTU_CFG:
-               call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
-               break;
-
-       case PORT_E_CHLD_STOPPED:
-               /**
-                * This event is received due to LLPort, Tx and Rx objects
-                * failing
-                */
-               /* No-op */
-               break;
-
-       case PORT_E_FWRESP_PAUSE:
-       case PORT_E_FWRESP_MTU:
-               /**
-                * These events are received due to flushing of mbox when
-                * device fails
-                */
-               /* No-op */
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_mtu_init_wait_entry(struct bna_port *port)
-{
-       bna_fw_mtu_set(port);
-}
-
-static void
-bna_port_sm_mtu_init_wait(struct bna_port *port, enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_STOP:
-               bfa_fsm_set_state(port, bna_port_sm_last_resp_wait);
-               break;
-
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               break;
-
-       case PORT_E_PAUSE_CFG:
-               /* No-op */
-               break;
-
-       case PORT_E_MTU_CFG:
-               port->flags |= BNA_PORT_F_MTU_CHANGED;
-               break;
-
-       case PORT_E_FWRESP_MTU:
-               if (port->flags & BNA_PORT_F_MTU_CHANGED) {
-                       port->flags &= ~BNA_PORT_F_MTU_CHANGED;
-                       bna_fw_mtu_set(port);
-               } else {
-                       bfa_fsm_set_state(port, bna_port_sm_pause_init_wait);
-               }
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_pause_init_wait_entry(struct bna_port *port)
-{
-       bna_fw_pause_set(port);
-}
-
-static void
-bna_port_sm_pause_init_wait(struct bna_port *port,
-                               enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_STOP:
-               bfa_fsm_set_state(port, bna_port_sm_last_resp_wait);
-               break;
-
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               break;
-
-       case PORT_E_PAUSE_CFG:
-               port->flags |= BNA_PORT_F_PAUSE_CHANGED;
-               break;
-
-       case PORT_E_MTU_CFG:
-               port->flags |= BNA_PORT_F_MTU_CHANGED;
-               break;
-
-       case PORT_E_FWRESP_PAUSE:
-               if (port->flags & BNA_PORT_F_PAUSE_CHANGED) {
-                       port->flags &= ~BNA_PORT_F_PAUSE_CHANGED;
-                       bna_fw_pause_set(port);
-               } else if (port->flags & BNA_PORT_F_MTU_CHANGED) {
-                       port->flags &= ~BNA_PORT_F_MTU_CHANGED;
-                       bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait);
-               } else {
-                       bfa_fsm_set_state(port, bna_port_sm_started);
-                       bna_port_chld_start(port);
-               }
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_last_resp_wait_entry(struct bna_port *port)
-{
-}
-
-static void
-bna_port_sm_last_resp_wait(struct bna_port *port,
-                               enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_FAIL:
-       case PORT_E_FWRESP_PAUSE:
-       case PORT_E_FWRESP_MTU:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_started_entry(struct bna_port *port)
-{
-       /**
-        * NOTE: Do not call bna_port_chld_start() here, since it will be
-        * inadvertently called during pause_cfg_wait->started transition
-        * as well
-        */
-       call_port_pause_cbfn(port, BNA_CB_SUCCESS);
-       call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
-}
-
-static void
-bna_port_sm_started(struct bna_port *port,
-                       enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_STOP:
-               bfa_fsm_set_state(port, bna_port_sm_chld_stop_wait);
-               break;
-
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               bna_port_chld_fail(port);
-               break;
-
-       case PORT_E_PAUSE_CFG:
-               bfa_fsm_set_state(port, bna_port_sm_pause_cfg_wait);
-               break;
-
-       case PORT_E_MTU_CFG:
-               bfa_fsm_set_state(port, bna_port_sm_rx_stop_wait);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_pause_cfg_wait_entry(struct bna_port *port)
-{
-       bna_fw_pause_set(port);
-}
-
-static void
-bna_port_sm_pause_cfg_wait(struct bna_port *port,
-                               enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               bna_port_chld_fail(port);
-               break;
-
-       case PORT_E_FWRESP_PAUSE:
-               bfa_fsm_set_state(port, bna_port_sm_started);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_rx_stop_wait_entry(struct bna_port *port)
-{
-       bna_port_rx_stop(port);
-}
-
-static void
-bna_port_sm_rx_stop_wait(struct bna_port *port,
-                               enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               bna_port_chld_fail(port);
-               break;
-
-       case PORT_E_CHLD_STOPPED:
-               bfa_fsm_set_state(port, bna_port_sm_mtu_cfg_wait);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_mtu_cfg_wait_entry(struct bna_port *port)
-{
-       bna_fw_mtu_set(port);
-}
-
-static void
-bna_port_sm_mtu_cfg_wait(struct bna_port *port, enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               bna_port_chld_fail(port);
-               break;
-
-       case PORT_E_FWRESP_MTU:
-               bfa_fsm_set_state(port, bna_port_sm_started);
-               bna_port_rx_start(port);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_port_sm_chld_stop_wait_entry(struct bna_port *port)
-{
-       bna_port_chld_stop(port);
-}
-
-static void
-bna_port_sm_chld_stop_wait(struct bna_port *port,
-                               enum bna_port_event event)
-{
-       switch (event) {
-       case PORT_E_FAIL:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               bna_port_chld_fail(port);
-               break;
-
-       case PORT_E_CHLD_STOPPED:
-               bfa_fsm_set_state(port, bna_port_sm_stopped);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_fw_pause_set(struct bna_port *port)
-{
-       struct bfi_ll_set_pause_req ll_req;
-
-       memset(&ll_req, 0, sizeof(ll_req));
-       ll_req.mh.msg_class = BFI_MC_LL;
-       ll_req.mh.msg_id = BFI_LL_H2I_SET_PAUSE_REQ;
-       ll_req.mh.mtag.h2i.lpu_id = 0;
-
-       ll_req.tx_pause = port->pause_config.tx_pause;
-       ll_req.rx_pause = port->pause_config.rx_pause;
-
-       bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req),
-                       bna_fw_cb_pause_set, port);
-
-       bna_mbox_send(port->bna, &port->mbox_qe);
-}
-
-static void
-bna_fw_cb_pause_set(void *arg, int status)
-{
-       struct bna_port *port = (struct bna_port *)arg;
-
-       bfa_q_qe_init(&port->mbox_qe.qe);
-       bfa_fsm_send_event(port, PORT_E_FWRESP_PAUSE);
-}
-
-void
-bna_fw_mtu_set(struct bna_port *port)
-{
-       struct bfi_ll_mtu_info_req ll_req;
-
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_MTU_INFO_REQ, 0);
-       ll_req.mtu = htons((u16)port->mtu);
-
-       bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req),
-                               bna_fw_cb_mtu_set, port);
-       bna_mbox_send(port->bna, &port->mbox_qe);
-}
-
-void
-bna_fw_cb_mtu_set(void *arg, int status)
-{
-       struct bna_port *port = (struct bna_port *)arg;
-
-       bfa_q_qe_init(&port->mbox_qe.qe);
-       bfa_fsm_send_event(port, PORT_E_FWRESP_MTU);
-}
-
-static void
-bna_port_cb_chld_stopped(void *arg)
-{
-       struct bna_port *port = (struct bna_port *)arg;
-
-       bfa_fsm_send_event(port, PORT_E_CHLD_STOPPED);
-}
-
-static void
-bna_port_init(struct bna_port *port, struct bna *bna)
-{
-       port->bna = bna;
-       port->flags = 0;
-       port->mtu = 0;
-       port->type = BNA_PORT_T_REGULAR;
-
-       port->link_cbfn = bnad_cb_port_link_status;
-
-       port->chld_stop_wc.wc_resume = bna_port_cb_chld_stopped;
-       port->chld_stop_wc.wc_cbarg = port;
-       port->chld_stop_wc.wc_count = 0;
-
-       port->stop_cbfn = NULL;
-       port->stop_cbarg = NULL;
-
-       port->pause_cbfn = NULL;
-
-       port->mtu_cbfn = NULL;
-
-       bfa_q_qe_init(&port->mbox_qe.qe);
-
-       bfa_fsm_set_state(port, bna_port_sm_stopped);
-
-       bna_llport_init(&port->llport, bna);
-}
-
-static void
-bna_port_uninit(struct bna_port *port)
-{
-       bna_llport_uninit(&port->llport);
-
-       port->flags = 0;
-
-       port->bna = NULL;
-}
-
-static int
-bna_port_state_get(struct bna_port *port)
-{
-       return bfa_sm_to_state(port_sm_table, port->fsm);
-}
-
-static void
-bna_port_start(struct bna_port *port)
-{
-       port->flags |= BNA_PORT_F_DEVICE_READY;
-       if (port->flags & BNA_PORT_F_ENABLED)
-               bfa_fsm_send_event(port, PORT_E_START);
-}
-
-static void
-bna_port_stop(struct bna_port *port)
-{
-       port->stop_cbfn = bna_device_cb_port_stopped;
-       port->stop_cbarg = &port->bna->device;
-
-       port->flags &= ~BNA_PORT_F_DEVICE_READY;
-       bfa_fsm_send_event(port, PORT_E_STOP);
-}
-
-static void
-bna_port_fail(struct bna_port *port)
-{
-       port->flags &= ~BNA_PORT_F_DEVICE_READY;
-       bfa_fsm_send_event(port, PORT_E_FAIL);
-}
-
-void
-bna_port_cb_tx_stopped(struct bna_port *port, enum bna_cb_status status)
-{
-       bfa_wc_down(&port->chld_stop_wc);
-}
-
-void
-bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status)
-{
-       bfa_wc_down(&port->chld_stop_wc);
-}
-
-int
-bna_port_mtu_get(struct bna_port *port)
-{
-       return port->mtu;
-}
-
-void
-bna_port_enable(struct bna_port *port)
-{
-       if (port->fsm != (bfa_sm_t)bna_port_sm_stopped)
-               return;
-
-       port->flags |= BNA_PORT_F_ENABLED;
-
-       if (port->flags & BNA_PORT_F_DEVICE_READY)
-               bfa_fsm_send_event(port, PORT_E_START);
-}
-
-void
-bna_port_disable(struct bna_port *port, enum bna_cleanup_type type,
-                void (*cbfn)(void *, enum bna_cb_status))
-{
-       if (type == BNA_SOFT_CLEANUP) {
-               (*cbfn)(port->bna->bnad, BNA_CB_SUCCESS);
-               return;
-       }
-
-       port->stop_cbfn = cbfn;
-       port->stop_cbarg = port->bna->bnad;
-
-       port->flags &= ~BNA_PORT_F_ENABLED;
-
-       bfa_fsm_send_event(port, PORT_E_STOP);
-}
-
-void
-bna_port_pause_config(struct bna_port *port,
-                     struct bna_pause_config *pause_config,
-                     void (*cbfn)(struct bnad *, enum bna_cb_status))
-{
-       port->pause_config = *pause_config;
-
-       port->pause_cbfn = cbfn;
-
-       bfa_fsm_send_event(port, PORT_E_PAUSE_CFG);
-}
-
-void
-bna_port_mtu_set(struct bna_port *port, int mtu,
-                void (*cbfn)(struct bnad *, enum bna_cb_status))
-{
-       port->mtu = mtu;
-
-       port->mtu_cbfn = cbfn;
-
-       bfa_fsm_send_event(port, PORT_E_MTU_CFG);
-}
-
-void
-bna_port_mac_get(struct bna_port *port, mac_t *mac)
-{
-       *mac = bfa_nw_ioc_get_mac(&port->bna->device.ioc);
-}
-
-/**
- * DEVICE
- */
-#define enable_mbox_intr(_device)\
-do {\
-       u32 intr_status;\
-       bna_intr_status_get((_device)->bna, intr_status);\
-       bnad_cb_device_enable_mbox_intr((_device)->bna->bnad);\
-       bna_mbox_intr_enable((_device)->bna);\
-} while (0)
-
-#define disable_mbox_intr(_device)\
-do {\
-       bna_mbox_intr_disable((_device)->bna);\
-       bnad_cb_device_disable_mbox_intr((_device)->bna->bnad);\
-} while (0)
-
-static const struct bna_chip_regs_offset reg_offset[] =
-{{HOST_PAGE_NUM_FN0, HOSTFN0_INT_STATUS,
-       HOSTFN0_INT_MASK, HOST_MSIX_ERR_INDEX_FN0},
-{HOST_PAGE_NUM_FN1, HOSTFN1_INT_STATUS,
-       HOSTFN1_INT_MASK, HOST_MSIX_ERR_INDEX_FN1},
-{HOST_PAGE_NUM_FN2, HOSTFN2_INT_STATUS,
-       HOSTFN2_INT_MASK, HOST_MSIX_ERR_INDEX_FN2},
-{HOST_PAGE_NUM_FN3, HOSTFN3_INT_STATUS,
-       HOSTFN3_INT_MASK, HOST_MSIX_ERR_INDEX_FN3},
-};
-
-enum bna_device_event {
-       DEVICE_E_ENABLE                 = 1,
-       DEVICE_E_DISABLE                = 2,
-       DEVICE_E_IOC_READY              = 3,
-       DEVICE_E_IOC_FAILED             = 4,
-       DEVICE_E_IOC_DISABLED           = 5,
-       DEVICE_E_IOC_RESET              = 6,
-       DEVICE_E_PORT_STOPPED           = 7,
-};
-
-enum bna_device_state {
-       BNA_DEVICE_STOPPED              = 1,
-       BNA_DEVICE_IOC_READY_WAIT       = 2,
-       BNA_DEVICE_READY                = 3,
-       BNA_DEVICE_PORT_STOP_WAIT       = 4,
-       BNA_DEVICE_IOC_DISABLE_WAIT     = 5,
-       BNA_DEVICE_FAILED               = 6
-};
-
-bfa_fsm_state_decl(bna_device, stopped, struct bna_device,
-                       enum bna_device_event);
-bfa_fsm_state_decl(bna_device, ioc_ready_wait, struct bna_device,
-                       enum bna_device_event);
-bfa_fsm_state_decl(bna_device, ready, struct bna_device,
-                       enum bna_device_event);
-bfa_fsm_state_decl(bna_device, port_stop_wait, struct bna_device,
-                       enum bna_device_event);
-bfa_fsm_state_decl(bna_device, ioc_disable_wait, struct bna_device,
-                       enum bna_device_event);
-bfa_fsm_state_decl(bna_device, failed, struct bna_device,
-                       enum bna_device_event);
-
-static struct bfa_sm_table device_sm_table[] = {
-       {BFA_SM(bna_device_sm_stopped), BNA_DEVICE_STOPPED},
-       {BFA_SM(bna_device_sm_ioc_ready_wait), BNA_DEVICE_IOC_READY_WAIT},
-       {BFA_SM(bna_device_sm_ready), BNA_DEVICE_READY},
-       {BFA_SM(bna_device_sm_port_stop_wait), BNA_DEVICE_PORT_STOP_WAIT},
-       {BFA_SM(bna_device_sm_ioc_disable_wait), BNA_DEVICE_IOC_DISABLE_WAIT},
-       {BFA_SM(bna_device_sm_failed), BNA_DEVICE_FAILED},
-};
-
-static void
-bna_device_sm_stopped_entry(struct bna_device *device)
-{
-       if (device->stop_cbfn)
-               device->stop_cbfn(device->stop_cbarg, BNA_CB_SUCCESS);
-
-       device->stop_cbfn = NULL;
-       device->stop_cbarg = NULL;
-}
-
-static void
-bna_device_sm_stopped(struct bna_device *device,
-                       enum bna_device_event event)
-{
-       switch (event) {
-       case DEVICE_E_ENABLE:
-               if (device->intr_type == BNA_INTR_T_MSIX)
-                       bna_mbox_msix_idx_set(device);
-               bfa_nw_ioc_enable(&device->ioc);
-               bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait);
-               break;
-
-       case DEVICE_E_DISABLE:
-               bfa_fsm_set_state(device, bna_device_sm_stopped);
-               break;
-
-       case DEVICE_E_IOC_RESET:
-               enable_mbox_intr(device);
-               break;
-
-       case DEVICE_E_IOC_FAILED:
-               bfa_fsm_set_state(device, bna_device_sm_failed);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_device_sm_ioc_ready_wait_entry(struct bna_device *device)
-{
-       /**
-        * Do not call bfa_ioc_enable() here. It must be called in the
-        * previous state due to failed -> ioc_ready_wait transition.
-        */
-}
-
-static void
-bna_device_sm_ioc_ready_wait(struct bna_device *device,
-                               enum bna_device_event event)
-{
-       switch (event) {
-       case DEVICE_E_DISABLE:
-               if (device->ready_cbfn)
-                       device->ready_cbfn(device->ready_cbarg,
-                                               BNA_CB_INTERRUPT);
-               device->ready_cbfn = NULL;
-               device->ready_cbarg = NULL;
-               bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
-               break;
-
-       case DEVICE_E_IOC_READY:
-               bfa_fsm_set_state(device, bna_device_sm_ready);
-               break;
-
-       case DEVICE_E_IOC_FAILED:
-               bfa_fsm_set_state(device, bna_device_sm_failed);
-               break;
-
-       case DEVICE_E_IOC_RESET:
-               enable_mbox_intr(device);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_device_sm_ready_entry(struct bna_device *device)
-{
-       bna_mbox_mod_start(&device->bna->mbox_mod);
-       bna_port_start(&device->bna->port);
-
-       if (device->ready_cbfn)
-               device->ready_cbfn(device->ready_cbarg,
-                                       BNA_CB_SUCCESS);
-       device->ready_cbfn = NULL;
-       device->ready_cbarg = NULL;
-}
-
-static void
-bna_device_sm_ready(struct bna_device *device, enum bna_device_event event)
-{
-       switch (event) {
-       case DEVICE_E_DISABLE:
-               bfa_fsm_set_state(device, bna_device_sm_port_stop_wait);
-               break;
-
-       case DEVICE_E_IOC_FAILED:
-               bfa_fsm_set_state(device, bna_device_sm_failed);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_device_sm_port_stop_wait_entry(struct bna_device *device)
-{
-       bna_port_stop(&device->bna->port);
-}
-
-static void
-bna_device_sm_port_stop_wait(struct bna_device *device,
-                               enum bna_device_event event)
-{
-       switch (event) {
-       case DEVICE_E_PORT_STOPPED:
-               bna_mbox_mod_stop(&device->bna->mbox_mod);
-               bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
-               break;
-
-       case DEVICE_E_IOC_FAILED:
-               disable_mbox_intr(device);
-               bna_port_fail(&device->bna->port);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_device_sm_ioc_disable_wait_entry(struct bna_device *device)
-{
-       bfa_nw_ioc_disable(&device->ioc);
-}
-
-static void
-bna_device_sm_ioc_disable_wait(struct bna_device *device,
-                               enum bna_device_event event)
-{
-       switch (event) {
-       case DEVICE_E_IOC_DISABLED:
-               disable_mbox_intr(device);
-               bfa_fsm_set_state(device, bna_device_sm_stopped);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_device_sm_failed_entry(struct bna_device *device)
-{
-       disable_mbox_intr(device);
-       bna_port_fail(&device->bna->port);
-       bna_mbox_mod_stop(&device->bna->mbox_mod);
-
-       if (device->ready_cbfn)
-               device->ready_cbfn(device->ready_cbarg,
-                                       BNA_CB_FAIL);
-       device->ready_cbfn = NULL;
-       device->ready_cbarg = NULL;
-}
-
-static void
-bna_device_sm_failed(struct bna_device *device,
-                       enum bna_device_event event)
-{
-       switch (event) {
-       case DEVICE_E_DISABLE:
-               bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
-               break;
-
-       case DEVICE_E_IOC_RESET:
-               enable_mbox_intr(device);
-               bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-/* IOC callback functions */
-
-static void
-bna_device_cb_iocll_ready(void *dev, enum bfa_status error)
-{
-       struct bna_device *device = (struct bna_device *)dev;
-
-       if (error)
-               bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED);
-       else
-               bfa_fsm_send_event(device, DEVICE_E_IOC_READY);
-}
-
-static void
-bna_device_cb_iocll_disabled(void *dev)
-{
-       struct bna_device *device = (struct bna_device *)dev;
-
-       bfa_fsm_send_event(device, DEVICE_E_IOC_DISABLED);
-}
-
-static void
-bna_device_cb_iocll_failed(void *dev)
-{
-       struct bna_device *device = (struct bna_device *)dev;
-
-       bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED);
-}
-
-static void
-bna_device_cb_iocll_reset(void *dev)
-{
-       struct bna_device *device = (struct bna_device *)dev;
-
-       bfa_fsm_send_event(device, DEVICE_E_IOC_RESET);
-}
-
-static struct bfa_ioc_cbfn bfa_iocll_cbfn = {
-       bna_device_cb_iocll_ready,
-       bna_device_cb_iocll_disabled,
-       bna_device_cb_iocll_failed,
-       bna_device_cb_iocll_reset
-};
-
-/* device */
-static void
-bna_adv_device_init(struct bna_device *device, struct bna *bna,
-               struct bna_res_info *res_info)
-{
-       u8 *kva;
-       u64 dma;
-
-       device->bna = bna;
-
-       kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva;
-
-       /**
-        * Attach common modules (Diag, SFP, CEE, Port) and claim respective
-        * DMA memory.
-        */
-       BNA_GET_DMA_ADDR(
-               &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma);
-       kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva;
-
-       bfa_nw_cee_attach(&bna->cee, &device->ioc, bna);
-       bfa_nw_cee_mem_claim(&bna->cee, kva, dma);
-       kva += bfa_nw_cee_meminfo();
-       dma += bfa_nw_cee_meminfo();
-
-}
-
-static void
-bna_device_init(struct bna_device *device, struct bna *bna,
-               struct bna_res_info *res_info)
-{
-       u64 dma;
-
-       device->bna = bna;
-
-       /**
-        * Attach IOC and claim:
-        *      1. DMA memory for IOC attributes
-        *      2. Kernel memory for FW trace
-        */
-       bfa_nw_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn);
-       bfa_nw_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL);
-
-       BNA_GET_DMA_ADDR(
-               &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma);
-       bfa_nw_ioc_mem_claim(&device->ioc,
-               res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva,
-                         dma);
-
-       bna_adv_device_init(device, bna, res_info);
-       /*
-        * Initialize mbox_mod only after IOC, so that mbox handler
-        * registration goes through
-        */
-       device->intr_type =
-               res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type;
-       device->vector =
-               res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.idl[0].vector;
-       bna_mbox_mod_init(&bna->mbox_mod, bna);
-
-       device->ready_cbfn = device->stop_cbfn = NULL;
-       device->ready_cbarg = device->stop_cbarg = NULL;
-
-       bfa_fsm_set_state(device, bna_device_sm_stopped);
-}
-
-static void
-bna_device_uninit(struct bna_device *device)
-{
-       bna_mbox_mod_uninit(&device->bna->mbox_mod);
-
-       bfa_nw_ioc_detach(&device->ioc);
-
-       device->bna = NULL;
-}
-
-static void
-bna_device_cb_port_stopped(void *arg, enum bna_cb_status status)
-{
-       struct bna_device *device = (struct bna_device *)arg;
-
-       bfa_fsm_send_event(device, DEVICE_E_PORT_STOPPED);
-}
-
-static int
-bna_device_status_get(struct bna_device *device)
-{
-       return device->fsm == (bfa_fsm_t)bna_device_sm_ready;
-}
-
-void
-bna_device_enable(struct bna_device *device)
-{
-       if (device->fsm != (bfa_fsm_t)bna_device_sm_stopped) {
-               bnad_cb_device_enabled(device->bna->bnad, BNA_CB_BUSY);
-               return;
-       }
-
-       device->ready_cbfn = bnad_cb_device_enabled;
-       device->ready_cbarg = device->bna->bnad;
-
-       bfa_fsm_send_event(device, DEVICE_E_ENABLE);
-}
-
-void
-bna_device_disable(struct bna_device *device, enum bna_cleanup_type type)
-{
-       if (type == BNA_SOFT_CLEANUP) {
-               bnad_cb_device_disabled(device->bna->bnad, BNA_CB_SUCCESS);
-               return;
-       }
-
-       device->stop_cbfn = bnad_cb_device_disabled;
-       device->stop_cbarg = device->bna->bnad;
-
-       bfa_fsm_send_event(device, DEVICE_E_DISABLE);
-}
-
-static int
-bna_device_state_get(struct bna_device *device)
-{
-       return bfa_sm_to_state(device_sm_table, device->fsm);
-}
-
-const u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = {
-       {12, 12},
-       {6, 10},
-       {5, 10},
-       {4, 8},
-       {3, 6},
-       {3, 6},
-       {2, 4},
-       {1, 2},
-};
-
-/* utils */
-
-static void
-bna_adv_res_req(struct bna_res_info *res_info)
-{
-       /* DMA memory for COMMON_MODULE */
-       res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
-       res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
-                               bfa_nw_cee_meminfo(), PAGE_SIZE);
-
-       /* Virtual memory for retreiving fw_trc */
-       res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 0;
-       res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = 0;
-
-       /* DMA memory for retreiving stats */
-       res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
-       res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len =
-                               ALIGN(BFI_HW_STATS_SIZE, PAGE_SIZE);
-
-       /* Virtual memory for soft stats */
-       res_info[BNA_RES_MEM_T_SWSTATS].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.len =
-                               sizeof(struct bna_sw_stats);
-}
-
-static void
-bna_sw_stats_get(struct bna *bna, struct bna_sw_stats *sw_stats)
-{
-       struct bna_tx *tx;
-       struct bna_txq *txq;
-       struct bna_rx *rx;
-       struct bna_rxp *rxp;
-       struct list_head *qe;
-       struct list_head *txq_qe;
-       struct list_head *rxp_qe;
-       struct list_head *mac_qe;
-       int i;
-
-       sw_stats->device_state = bna_device_state_get(&bna->device);
-       sw_stats->port_state = bna_port_state_get(&bna->port);
-       sw_stats->port_flags = bna->port.flags;
-       sw_stats->llport_state = bna_llport_state_get(&bna->port.llport);
-       sw_stats->priority = bna->port.priority;
-
-       i = 0;
-       list_for_each(qe, &bna->tx_mod.tx_active_q) {
-               tx = (struct bna_tx *)qe;
-               sw_stats->tx_stats[i].tx_state = bna_tx_state_get(tx);
-               sw_stats->tx_stats[i].tx_flags = tx->flags;
-
-               sw_stats->tx_stats[i].num_txqs = 0;
-               sw_stats->tx_stats[i].txq_bmap[0] = 0;
-               sw_stats->tx_stats[i].txq_bmap[1] = 0;
-               list_for_each(txq_qe, &tx->txq_q) {
-                       txq = (struct bna_txq *)txq_qe;
-                       if (txq->txq_id < 32)
-                               sw_stats->tx_stats[i].txq_bmap[0] |=
-                                               ((u32)1 << txq->txq_id);
-                       else
-                               sw_stats->tx_stats[i].txq_bmap[1] |=
-                                               ((u32)
-                                                1 << (txq->txq_id - 32));
-                       sw_stats->tx_stats[i].num_txqs++;
-               }
-
-               sw_stats->tx_stats[i].txf_id = tx->txf.txf_id;
-
-               i++;
-       }
-       sw_stats->num_active_tx = i;
-
-       i = 0;
-       list_for_each(qe, &bna->rx_mod.rx_active_q) {
-               rx = (struct bna_rx *)qe;
-               sw_stats->rx_stats[i].rx_state = bna_rx_state_get(rx);
-               sw_stats->rx_stats[i].rx_flags = rx->rx_flags;
-
-               sw_stats->rx_stats[i].num_rxps = 0;
-               sw_stats->rx_stats[i].num_rxqs = 0;
-               sw_stats->rx_stats[i].rxq_bmap[0] = 0;
-               sw_stats->rx_stats[i].rxq_bmap[1] = 0;
-               sw_stats->rx_stats[i].cq_bmap[0] = 0;
-               sw_stats->rx_stats[i].cq_bmap[1] = 0;
-               list_for_each(rxp_qe, &rx->rxp_q) {
-                       rxp = (struct bna_rxp *)rxp_qe;
-
-                       sw_stats->rx_stats[i].num_rxqs += 1;
-
-                       if (rxp->type == BNA_RXP_SINGLE) {
-                               if (rxp->rxq.single.only->rxq_id < 32) {
-                                       sw_stats->rx_stats[i].rxq_bmap[0] |=
-                                       ((u32)1 <<
-                                       rxp->rxq.single.only->rxq_id);
-                               } else {
-                                       sw_stats->rx_stats[i].rxq_bmap[1] |=
-                                       ((u32)1 <<
-                                       (rxp->rxq.single.only->rxq_id - 32));
-                               }
-                       } else {
-                               if (rxp->rxq.slr.large->rxq_id < 32) {
-                                       sw_stats->rx_stats[i].rxq_bmap[0] |=
-                                       ((u32)1 <<
-                                       rxp->rxq.slr.large->rxq_id);
-                               } else {
-                                       sw_stats->rx_stats[i].rxq_bmap[1] |=
-                                       ((u32)1 <<
-                                       (rxp->rxq.slr.large->rxq_id - 32));
-                               }
-
-                               if (rxp->rxq.slr.small->rxq_id < 32) {
-                                       sw_stats->rx_stats[i].rxq_bmap[0] |=
-                                       ((u32)1 <<
-                                       rxp->rxq.slr.small->rxq_id);
-                               } else {
-                                       sw_stats->rx_stats[i].rxq_bmap[1] |=
-                               ((u32)1 <<
-                                (rxp->rxq.slr.small->rxq_id - 32));
-                               }
-                               sw_stats->rx_stats[i].num_rxqs += 1;
-                       }
-
-                       if (rxp->cq.cq_id < 32)
-                               sw_stats->rx_stats[i].cq_bmap[0] |=
-                                       (1 << rxp->cq.cq_id);
-                       else
-                               sw_stats->rx_stats[i].cq_bmap[1] |=
-                                       (1 << (rxp->cq.cq_id - 32));
-
-                       sw_stats->rx_stats[i].num_rxps++;
-               }
-
-               sw_stats->rx_stats[i].rxf_id = rx->rxf.rxf_id;
-               sw_stats->rx_stats[i].rxf_state = bna_rxf_state_get(&rx->rxf);
-               sw_stats->rx_stats[i].rxf_oper_state = rx->rxf.rxf_oper_state;
-
-               sw_stats->rx_stats[i].num_active_ucast = 0;
-               if (rx->rxf.ucast_active_mac)
-                       sw_stats->rx_stats[i].num_active_ucast++;
-               list_for_each(mac_qe, &rx->rxf.ucast_active_q)
-                       sw_stats->rx_stats[i].num_active_ucast++;
-
-               sw_stats->rx_stats[i].num_active_mcast = 0;
-               list_for_each(mac_qe, &rx->rxf.mcast_active_q)
-                       sw_stats->rx_stats[i].num_active_mcast++;
-
-               sw_stats->rx_stats[i].rxmode_active = rx->rxf.rxmode_active;
-               sw_stats->rx_stats[i].vlan_filter_status =
-                                               rx->rxf.vlan_filter_status;
-               memcpy(sw_stats->rx_stats[i].vlan_filter_table,
-                               rx->rxf.vlan_filter_table,
-                               sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32));
-
-               sw_stats->rx_stats[i].rss_status = rx->rxf.rss_status;
-               sw_stats->rx_stats[i].hds_status = rx->rxf.hds_status;
-
-               i++;
-       }
-       sw_stats->num_active_rx = i;
-}
-
-static void
-bna_fw_cb_stats_get(void *arg, int status)
-{
-       struct bna *bna = (struct bna *)arg;
-       u64 *p_stats;
-       int i, count;
-       int rxf_count, txf_count;
-       u64 rxf_bmap, txf_bmap;
-
-       bfa_q_qe_init(&bna->mbox_qe.qe);
-
-       if (status == 0) {
-               p_stats = (u64 *)bna->stats.hw_stats;
-               count = sizeof(struct bfi_ll_stats) / sizeof(u64);
-               for (i = 0; i < count; i++)
-                       p_stats[i] = cpu_to_be64(p_stats[i]);
-
-               rxf_count = 0;
-               rxf_bmap = (u64)bna->stats.rxf_bmap[0] |
-                       ((u64)bna->stats.rxf_bmap[1] << 32);
-               for (i = 0; i < BFI_LL_RXF_ID_MAX; i++)
-                       if (rxf_bmap & ((u64)1 << i))
-                               rxf_count++;
-
-               txf_count = 0;
-               txf_bmap = (u64)bna->stats.txf_bmap[0] |
-                       ((u64)bna->stats.txf_bmap[1] << 32);
-               for (i = 0; i < BFI_LL_TXF_ID_MAX; i++)
-                       if (txf_bmap & ((u64)1 << i))
-                               txf_count++;
-
-               p_stats = (u64 *)&bna->stats.hw_stats->rxf_stats[0] +
-                               ((rxf_count * sizeof(struct bfi_ll_stats_rxf) +
-                               txf_count * sizeof(struct bfi_ll_stats_txf))/
-                               sizeof(u64));
-
-               /* Populate the TXF stats from the firmware DMAed copy */
-               for (i = (BFI_LL_TXF_ID_MAX - 1); i >= 0; i--)
-                       if (txf_bmap & ((u64)1 << i)) {
-                               p_stats -= sizeof(struct bfi_ll_stats_txf)/
-                                               sizeof(u64);
-                               memcpy(&bna->stats.hw_stats->txf_stats[i],
-                                       p_stats,
-                                       sizeof(struct bfi_ll_stats_txf));
-                       }
-
-               /* Populate the RXF stats from the firmware DMAed copy */
-               for (i = (BFI_LL_RXF_ID_MAX - 1); i >= 0; i--)
-                       if (rxf_bmap & ((u64)1 << i)) {
-                               p_stats -= sizeof(struct bfi_ll_stats_rxf)/
-                                               sizeof(u64);
-                               memcpy(&bna->stats.hw_stats->rxf_stats[i],
-                                       p_stats,
-                                       sizeof(struct bfi_ll_stats_rxf));
-                       }
-
-               bna_sw_stats_get(bna, bna->stats.sw_stats);
-               bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats);
-       } else
-               bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
-}
-
-static void
-bna_fw_stats_get(struct bna *bna)
-{
-       struct bfi_ll_stats_req ll_req;
-
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_GET_REQ, 0);
-       ll_req.stats_mask = htons(BFI_LL_STATS_ALL);
-
-       ll_req.rxf_id_mask[0] = htonl(bna->rx_mod.rxf_bmap[0]);
-       ll_req.rxf_id_mask[1] = htonl(bna->rx_mod.rxf_bmap[1]);
-       ll_req.txf_id_mask[0] = htonl(bna->tx_mod.txf_bmap[0]);
-       ll_req.txf_id_mask[1] = htonl(bna->tx_mod.txf_bmap[1]);
-
-       ll_req.host_buffer.a32.addr_hi = bna->hw_stats_dma.msb;
-       ll_req.host_buffer.a32.addr_lo = bna->hw_stats_dma.lsb;
-
-       bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req),
-                               bna_fw_cb_stats_get, bna);
-       bna_mbox_send(bna, &bna->mbox_qe);
-
-       bna->stats.rxf_bmap[0] = bna->rx_mod.rxf_bmap[0];
-       bna->stats.rxf_bmap[1] = bna->rx_mod.rxf_bmap[1];
-       bna->stats.txf_bmap[0] = bna->tx_mod.txf_bmap[0];
-       bna->stats.txf_bmap[1] = bna->tx_mod.txf_bmap[1];
-}
-
-void
-bna_stats_get(struct bna *bna)
-{
-       if (bna_device_status_get(&bna->device))
-               bna_fw_stats_get(bna);
-       else
-               bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
-}
-
-/* IB */
-static void
-bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo)
-{
-       ib->ib_config.coalescing_timeo = coalescing_timeo;
-
-       if (ib->start_count)
-               ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
-                               (u32)ib->ib_config.coalescing_timeo, 0);
-}
-
-/* RxF */
-void
-bna_rxf_adv_init(struct bna_rxf *rxf,
-               struct bna_rx *rx,
-               struct bna_rx_config *q_config)
-{
-       switch (q_config->rxp_type) {
-       case BNA_RXP_SINGLE:
-               /* No-op */
-               break;
-       case BNA_RXP_SLR:
-               rxf->ctrl_flags |= BNA_RXF_CF_SM_LG_RXQ;
-               break;
-       case BNA_RXP_HDS:
-               rxf->hds_cfg.hdr_type = q_config->hds_config.hdr_type;
-               rxf->hds_cfg.header_size =
-                               q_config->hds_config.header_size;
-               rxf->forced_offset = 0;
-               break;
-       default:
-               break;
-       }
-
-       if (q_config->rss_status == BNA_STATUS_T_ENABLED) {
-               rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
-               rxf->rss_cfg.hash_type = q_config->rss_config.hash_type;
-               rxf->rss_cfg.hash_mask = q_config->rss_config.hash_mask;
-               memcpy(&rxf->rss_cfg.toeplitz_hash_key[0],
-                       &q_config->rss_config.toeplitz_hash_key[0],
-                       sizeof(rxf->rss_cfg.toeplitz_hash_key));
-       }
-}
-
-static void
-rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status)
-{
-       struct bfi_ll_rxf_req req;
-
-       bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);
-
-       req.rxf_id = rxf->rxf_id;
-       req.enable = status;
-
-       bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
-                       rxf_cb_cam_fltr_mbox_cmd, rxf);
-
-       bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
-}
-
-int
-rxf_process_packet_filter_ucast(struct bna_rxf *rxf)
-{
-       struct bna_mac *mac = NULL;
-       struct list_head *qe;
-
-       /* Add additional MAC entries */
-       if (!list_empty(&rxf->ucast_pending_add_q)) {
-               bfa_q_deq(&rxf->ucast_pending_add_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_ADD_REQ, mac);
-               list_add_tail(&mac->qe, &rxf->ucast_active_q);
-               return 1;
-       }
-
-       /* Delete MAC addresses previousely added */
-       if (!list_empty(&rxf->ucast_pending_del_q)) {
-               bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
-               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
-               return 1;
-       }
-
-       return 0;
-}
-
-int
-rxf_process_packet_filter_promisc(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-
-       /* Enable/disable promiscuous mode */
-       if (is_promisc_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* move promisc configuration from pending -> active */
-               promisc_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active |= BNA_RXMODE_PROMISC;
-
-               /* Disable VLAN filter to allow all VLANs */
-               __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED);
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
-                               BNA_STATUS_T_ENABLED);
-               return 1;
-       } else if (is_promisc_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* move promisc configuration from pending -> active */
-               promisc_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
-               bna->rxf_promisc_id = BFI_MAX_RXF;
-
-               /* Revert VLAN filter */
-               __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
-                               BNA_STATUS_T_DISABLED);
-               return 1;
-       }
-
-       return 0;
-}
-
-int
-rxf_process_packet_filter_allmulti(struct bna_rxf *rxf)
-{
-       /* Enable/disable allmulti mode */
-       if (is_allmulti_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* move allmulti configuration from pending -> active */
-               allmulti_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active |= BNA_RXMODE_ALLMULTI;
-
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
-                               BNA_STATUS_T_ENABLED);
-               return 1;
-       } else if (is_allmulti_disable(rxf->rxmode_pending,
-                                       rxf->rxmode_pending_bitmask)) {
-               /* move allmulti configuration from pending -> active */
-               allmulti_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
-
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
-                               BNA_STATUS_T_DISABLED);
-               return 1;
-       }
-
-       return 0;
-}
-
-int
-rxf_clear_packet_filter_ucast(struct bna_rxf *rxf)
-{
-       struct bna_mac *mac = NULL;
-       struct list_head *qe;
-
-       /* 1. delete pending ucast entries */
-       if (!list_empty(&rxf->ucast_pending_del_q)) {
-               bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
-               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
-               return 1;
-       }
-
-       /* 2. clear active ucast entries; move them to pending_add_q */
-       if (!list_empty(&rxf->ucast_active_q)) {
-               bfa_q_deq(&rxf->ucast_active_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
-               list_add_tail(&mac->qe, &rxf->ucast_pending_add_q);
-               return 1;
-       }
-
-       return 0;
-}
-
-int
-rxf_clear_packet_filter_promisc(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-
-       /* 6. Execute pending promisc mode disable command */
-       if (is_promisc_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* move promisc configuration from pending -> active */
-               promisc_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
-               bna->rxf_promisc_id = BFI_MAX_RXF;
-
-               /* Revert VLAN filter */
-               __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
-                               BNA_STATUS_T_DISABLED);
-               return 1;
-       }
-
-       /* 7. Clear active promisc mode; move it to pending enable */
-       if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
-               /* move promisc configuration from active -> pending */
-               promisc_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
-
-               /* Revert VLAN filter */
-               __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
-                               BNA_STATUS_T_DISABLED);
-               return 1;
-       }
-
-       return 0;
-}
-
-int
-rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf)
-{
-       /* 10. Execute pending allmulti mode disable command */
-       if (is_allmulti_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* move allmulti configuration from pending -> active */
-               allmulti_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
-                               BNA_STATUS_T_DISABLED);
-               return 1;
-       }
-
-       /* 11. Clear active allmulti mode; move it to pending enable */
-       if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
-               /* move allmulti configuration from active -> pending */
-               allmulti_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
-               rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
-                               BNA_STATUS_T_DISABLED);
-               return 1;
-       }
-
-       return 0;
-}
-
-void
-rxf_reset_packet_filter_ucast(struct bna_rxf *rxf)
-{
-       struct list_head *qe;
-       struct bna_mac *mac;
-
-       /* 1. Move active ucast entries to pending_add_q */
-       while (!list_empty(&rxf->ucast_active_q)) {
-               bfa_q_deq(&rxf->ucast_active_q, &qe);
-               bfa_q_qe_init(qe);
-               list_add_tail(qe, &rxf->ucast_pending_add_q);
-       }
-
-       /* 2. Throw away delete pending ucast entries */
-       while (!list_empty(&rxf->ucast_pending_del_q)) {
-               bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
-       }
-}
-
-void
-rxf_reset_packet_filter_promisc(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-
-       /* 6. Clear pending promisc mode disable */
-       if (is_promisc_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               promisc_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
-               bna->rxf_promisc_id = BFI_MAX_RXF;
-       }
-
-       /* 7. Move promisc mode config from active -> pending */
-       if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
-               promisc_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
-       }
-
-}
-
-void
-rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf)
-{
-       /* 10. Clear pending allmulti mode disable */
-       if (is_allmulti_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               allmulti_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
-       }
-
-       /* 11. Move allmulti mode config from active -> pending */
-       if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
-               allmulti_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
-       }
-}
-
-/**
- * Should only be called by bna_rxf_mode_set.
- * Helps deciding if h/w configuration is needed or not.
- *  Returns:
- *     0 = no h/w change
- *     1 = need h/w change
- */
-static int
-rxf_promisc_enable(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-       int ret = 0;
-
-       /* There can not be any pending disable command */
-
-       /* Do nothing if pending enable or already enabled */
-       if (is_promisc_enable(rxf->rxmode_pending,
-                       rxf->rxmode_pending_bitmask) ||
-                       (rxf->rxmode_active & BNA_RXMODE_PROMISC)) {
-               /* Schedule enable */
-       } else {
-               /* Promisc mode should not be active in the system */
-               promisc_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               bna->rxf_promisc_id = rxf->rxf_id;
-               ret = 1;
-       }
-
-       return ret;
-}
-
-/**
- * Should only be called by bna_rxf_mode_set.
- * Helps deciding if h/w configuration is needed or not.
- *  Returns:
- *     0 = no h/w change
- *     1 = need h/w change
- */
-static int
-rxf_promisc_disable(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-       int ret = 0;
-
-       /* There can not be any pending disable */
-
-       /* Turn off pending enable command , if any */
-       if (is_promisc_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* Promisc mode should not be active */
-               /* system promisc state should be pending */
-               promisc_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               /* Remove the promisc state from the system */
-               bna->rxf_promisc_id = BFI_MAX_RXF;
-
-               /* Schedule disable */
-       } else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
-               /* Promisc mode should be active in the system */
-               promisc_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               ret = 1;
-
-       /* Do nothing if already disabled */
-       } else {
-       }
-
-       return ret;
-}
-
-/**
- * Should only be called by bna_rxf_mode_set.
- * Helps deciding if h/w configuration is needed or not.
- *  Returns:
- *     0 = no h/w change
- *     1 = need h/w change
- */
-static int
-rxf_allmulti_enable(struct bna_rxf *rxf)
-{
-       int ret = 0;
-
-       /* There can not be any pending disable command */
-
-       /* Do nothing if pending enable or already enabled */
-       if (is_allmulti_enable(rxf->rxmode_pending,
-                       rxf->rxmode_pending_bitmask) ||
-                       (rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) {
-               /* Schedule enable */
-       } else {
-               allmulti_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               ret = 1;
-       }
-
-       return ret;
-}
-
-/**
- * Should only be called by bna_rxf_mode_set.
- * Helps deciding if h/w configuration is needed or not.
- *  Returns:
- *     0 = no h/w change
- *     1 = need h/w change
- */
-static int
-rxf_allmulti_disable(struct bna_rxf *rxf)
-{
-       int ret = 0;
-
-       /* There can not be any pending disable */
-
-       /* Turn off pending enable command , if any */
-       if (is_allmulti_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* Allmulti mode should not be active */
-               allmulti_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-
-       /* Schedule disable */
-       } else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
-               allmulti_disable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-               ret = 1;
-       }
-
-       return ret;
-}
-
-/* RxF <- bnad */
-enum bna_cb_status
-bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
-               enum bna_rxmode bitmask,
-               void (*cbfn)(struct bnad *, struct bna_rx *,
-                            enum bna_cb_status))
-{
-       struct bna_rxf *rxf = &rx->rxf;
-       int need_hw_config = 0;
-
-       /* Process the commands */
-
-       if (is_promisc_enable(new_mode, bitmask)) {
-               /* If promisc mode is already enabled elsewhere in the system */
-               if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) &&
-                       (rx->bna->rxf_promisc_id != rxf->rxf_id))
-                       goto err_return;
-               if (rxf_promisc_enable(rxf))
-                       need_hw_config = 1;
-       } else if (is_promisc_disable(new_mode, bitmask)) {
-               if (rxf_promisc_disable(rxf))
-                       need_hw_config = 1;
-       }
-
-       if (is_allmulti_enable(new_mode, bitmask)) {
-               if (rxf_allmulti_enable(rxf))
-                       need_hw_config = 1;
-       } else if (is_allmulti_disable(new_mode, bitmask)) {
-               if (rxf_allmulti_disable(rxf))
-                       need_hw_config = 1;
-       }
-
-       /* Trigger h/w if needed */
-
-       if (need_hw_config) {
-               rxf->cam_fltr_cbfn = cbfn;
-               rxf->cam_fltr_cbarg = rx->bna->bnad;
-               bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-       } else if (cbfn)
-               (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
-
-       return BNA_CB_SUCCESS;
-
-err_return:
-       return BNA_CB_FAIL;
-}
-
-void
-/* RxF <- bnad */
-bna_rx_vlanfilter_enable(struct bna_rx *rx)
-{
-       struct bna_rxf *rxf = &rx->rxf;
-
-       if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) {
-               rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
-               rxf->vlan_filter_status = BNA_STATUS_T_ENABLED;
-               bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-       }
-}
-
-/* Rx */
-
-/* Rx <- bnad */
-void
-bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo)
-{
-       struct bna_rxp *rxp;
-       struct list_head *qe;
-
-       list_for_each(qe, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe;
-               rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo;
-               bna_ib_coalescing_timeo_set(rxp->cq.ib, coalescing_timeo);
-       }
-}
-
-/* Rx <- bnad */
-void
-bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX])
-{
-       int i, j;
-
-       for (i = 0; i < BNA_LOAD_T_MAX; i++)
-               for (j = 0; j < BNA_BIAS_T_MAX; j++)
-                       bna->rx_mod.dim_vector[i][j] = vector[i][j];
-}
-
-/* Rx <- bnad */
-void
-bna_rx_dim_update(struct bna_ccb *ccb)
-{
-       struct bna *bna = ccb->cq->rx->bna;
-       u32 load, bias;
-       u32 pkt_rt, small_rt, large_rt;
-       u8 coalescing_timeo;
-
-       if ((ccb->pkt_rate.small_pkt_cnt == 0) &&
-               (ccb->pkt_rate.large_pkt_cnt == 0))
-               return;
-
-       /* Arrive at preconfigured coalescing timeo value based on pkt rate */
-
-       small_rt = ccb->pkt_rate.small_pkt_cnt;
-       large_rt = ccb->pkt_rate.large_pkt_cnt;
-
-       pkt_rt = small_rt + large_rt;
-
-       if (pkt_rt < BNA_PKT_RATE_10K)
-               load = BNA_LOAD_T_LOW_4;
-       else if (pkt_rt < BNA_PKT_RATE_20K)
-               load = BNA_LOAD_T_LOW_3;
-       else if (pkt_rt < BNA_PKT_RATE_30K)
-               load = BNA_LOAD_T_LOW_2;
-       else if (pkt_rt < BNA_PKT_RATE_40K)
-               load = BNA_LOAD_T_LOW_1;
-       else if (pkt_rt < BNA_PKT_RATE_50K)
-               load = BNA_LOAD_T_HIGH_1;
-       else if (pkt_rt < BNA_PKT_RATE_60K)
-               load = BNA_LOAD_T_HIGH_2;
-       else if (pkt_rt < BNA_PKT_RATE_80K)
-               load = BNA_LOAD_T_HIGH_3;
-       else
-               load = BNA_LOAD_T_HIGH_4;
-
-       if (small_rt > (large_rt << 1))
-               bias = 0;
-       else
-               bias = 1;
-
-       ccb->pkt_rate.small_pkt_cnt = 0;
-       ccb->pkt_rate.large_pkt_cnt = 0;
-
-       coalescing_timeo = bna->rx_mod.dim_vector[load][bias];
-       ccb->rx_coalescing_timeo = coalescing_timeo;
-
-       /* Set it to IB */
-       bna_ib_coalescing_timeo_set(ccb->cq->ib, coalescing_timeo);
-}
-
-/* Tx */
-/* TX <- bnad */
-void
-bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo)
-{
-       struct bna_txq *txq;
-       struct list_head *qe;
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               bna_ib_coalescing_timeo_set(txq->ib, coalescing_timeo);
-       }
-}
-
-/*
- * Private data
- */
-
-struct bna_ritseg_pool_cfg {
-       u32     pool_size;
-       u32     pool_entry_size;
-};
-init_ritseg_pool(ritseg_pool_cfg);
-
-/*
- * Private functions
- */
-static void
-bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna,
-                 struct bna_res_info *res_info)
-{
-       int i;
-
-       ucam_mod->ucmac = (struct bna_mac *)
-               res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
-
-       INIT_LIST_HEAD(&ucam_mod->free_q);
-       for (i = 0; i < BFI_MAX_UCMAC; i++) {
-               bfa_q_qe_init(&ucam_mod->ucmac[i].qe);
-               list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q);
-       }
-
-       ucam_mod->bna = bna;
-}
-
-static void
-bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod)
-{
-       struct list_head *qe;
-       int i = 0;
-
-       list_for_each(qe, &ucam_mod->free_q)
-               i++;
-
-       ucam_mod->bna = NULL;
-}
-
-static void
-bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna,
-                 struct bna_res_info *res_info)
-{
-       int i;
-
-       mcam_mod->mcmac = (struct bna_mac *)
-               res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
-
-       INIT_LIST_HEAD(&mcam_mod->free_q);
-       for (i = 0; i < BFI_MAX_MCMAC; i++) {
-               bfa_q_qe_init(&mcam_mod->mcmac[i].qe);
-               list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q);
-       }
-
-       mcam_mod->bna = bna;
-}
-
-static void
-bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod)
-{
-       struct list_head *qe;
-       int i = 0;
-
-       list_for_each(qe, &mcam_mod->free_q)
-               i++;
-
-       mcam_mod->bna = NULL;
-}
-
-static void
-bna_rit_mod_init(struct bna_rit_mod *rit_mod,
-               struct bna_res_info *res_info)
-{
-       int i;
-       int j;
-       int count;
-       int offset;
-
-       rit_mod->rit = (struct bna_rit_entry *)
-               res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mdl[0].kva;
-       rit_mod->rit_segment = (struct bna_rit_segment *)
-               res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mdl[0].kva;
-
-       count = 0;
-       offset = 0;
-       for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
-               INIT_LIST_HEAD(&rit_mod->rit_seg_pool[i]);
-               for (j = 0; j < ritseg_pool_cfg[i].pool_size; j++) {
-                       bfa_q_qe_init(&rit_mod->rit_segment[count].qe);
-                       rit_mod->rit_segment[count].max_rit_size =
-                                       ritseg_pool_cfg[i].pool_entry_size;
-                       rit_mod->rit_segment[count].rit_offset = offset;
-                       rit_mod->rit_segment[count].rit =
-                                       &rit_mod->rit[offset];
-                       list_add_tail(&rit_mod->rit_segment[count].qe,
-                               &rit_mod->rit_seg_pool[i]);
-                       count++;
-                       offset += ritseg_pool_cfg[i].pool_entry_size;
-               }
-       }
-}
-
-/*
- * Public functions
- */
-
-/* Called during probe(), before calling bna_init() */
-void
-bna_res_req(struct bna_res_info *res_info)
-{
-       bna_adv_res_req(res_info);
-
-       /* DMA memory for retrieving IOC attributes */
-       res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
-       res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len =
-                               ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE);
-
-       /* DMA memory for index segment of an IB */
-       res_info[BNA_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
-       res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.len =
-                               BFI_IBIDX_SIZE * BFI_IBIDX_MAX_SEGSIZE;
-       res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.num = BFI_MAX_IB;
-
-       /* Virtual memory for IB objects - stored by IB module */
-       res_info[BNA_RES_MEM_T_IB_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.len =
-                               BFI_MAX_IB * sizeof(struct bna_ib);
-
-       /* Virtual memory for intr objects - stored by IB module */
-       res_info[BNA_RES_MEM_T_INTR_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.len =
-                               BFI_MAX_IB * sizeof(struct bna_intr);
-
-       /* Virtual memory for idx_seg objects - stored by IB module */
-       res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.len =
-                       BFI_IBIDX_TOTAL_SEGS * sizeof(struct bna_ibidx_seg);
-
-       /* Virtual memory for Tx objects - stored by Tx module */
-       res_info[BNA_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_TXQ * sizeof(struct bna_tx);
-
-       /* Virtual memory for TxQ - stored by Tx module */
-       res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_TXQ * sizeof(struct bna_txq);
-
-       /* Virtual memory for Rx objects - stored by Rx module */
-       res_info[BNA_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_RXQ * sizeof(struct bna_rx);
-
-       /* Virtual memory for RxPath - stored by Rx module */
-       res_info[BNA_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_RXQ * sizeof(struct bna_rxp);
-
-       /* Virtual memory for RxQ - stored by Rx module */
-       res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_RXQ * sizeof(struct bna_rxq);
-
-       /* Virtual memory for Unicast MAC address - stored by ucam module */
-       res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_UCMAC * sizeof(struct bna_mac);
-
-       /* Virtual memory for Multicast MAC address - stored by mcam module */
-       res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len =
-                       BFI_MAX_MCMAC * sizeof(struct bna_mac);
-
-       /* Virtual memory for RIT entries */
-       res_info[BNA_RES_MEM_T_RIT_ENTRY].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.len =
-                       BFI_MAX_RIT_SIZE * sizeof(struct bna_rit_entry);
-
-       /* Virtual memory for RIT segment table */
-       res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_type = BNA_RES_T_MEM;
-       res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mem_type =
-                                                               BNA_MEM_T_KVA;
-       res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.num = 1;
-       res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.len =
-                       BFI_RIT_TOTAL_SEGS * sizeof(struct bna_rit_segment);
-
-       /* Interrupt resource for mailbox interrupt */
-       res_info[BNA_RES_INTR_T_MBOX].res_type = BNA_RES_T_INTR;
-       res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type =
-                                                       BNA_INTR_T_MSIX;
-       res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.num = 1;
-}
-
-/* Called during probe() */
-void
-bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev,
-               struct bna_res_info *res_info)
-{
-       bna->bnad = bnad;
-       bna->pcidev = *pcidev;
-
-       bna->stats.hw_stats = (struct bfi_ll_stats *)
-               res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva;
-       bna->hw_stats_dma.msb =
-               res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb;
-       bna->hw_stats_dma.lsb =
-               res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb;
-       bna->stats.sw_stats = (struct bna_sw_stats *)
-               res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mdl[0].kva;
-
-       bna->regs.page_addr = bna->pcidev.pci_bar_kva +
-                               reg_offset[bna->pcidev.pci_func].page_addr;
-       bna->regs.fn_int_status = bna->pcidev.pci_bar_kva +
-                               reg_offset[bna->pcidev.pci_func].fn_int_status;
-       bna->regs.fn_int_mask = bna->pcidev.pci_bar_kva +
-                               reg_offset[bna->pcidev.pci_func].fn_int_mask;
-
-       if (bna->pcidev.pci_func < 3)
-               bna->port_num = 0;
-       else
-               bna->port_num = 1;
-
-       /* Also initializes diag, cee, sfp, phy_port and mbox_mod */
-       bna_device_init(&bna->device, bna, res_info);
-
-       bna_port_init(&bna->port, bna);
-
-       bna_tx_mod_init(&bna->tx_mod, bna, res_info);
-
-       bna_rx_mod_init(&bna->rx_mod, bna, res_info);
-
-       bna_ib_mod_init(&bna->ib_mod, bna, res_info);
-
-       bna_rit_mod_init(&bna->rit_mod, res_info);
-
-       bna_ucam_mod_init(&bna->ucam_mod, bna, res_info);
-
-       bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
-
-       bna->rxf_promisc_id = BFI_MAX_RXF;
-
-       /* Mbox q element for posting stat request to f/w */
-       bfa_q_qe_init(&bna->mbox_qe.qe);
-}
-
-void
-bna_uninit(struct bna *bna)
-{
-       bna_mcam_mod_uninit(&bna->mcam_mod);
-
-       bna_ucam_mod_uninit(&bna->ucam_mod);
-
-       bna_ib_mod_uninit(&bna->ib_mod);
-
-       bna_rx_mod_uninit(&bna->rx_mod);
-
-       bna_tx_mod_uninit(&bna->tx_mod);
-
-       bna_port_uninit(&bna->port);
-
-       bna_device_uninit(&bna->device);
-
-       bna->bnad = NULL;
-}
-
-struct bna_mac *
-bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod)
-{
-       struct list_head *qe;
-
-       if (list_empty(&ucam_mod->free_q))
-               return NULL;
-
-       bfa_q_deq(&ucam_mod->free_q, &qe);
-
-       return (struct bna_mac *)qe;
-}
-
-void
-bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, struct bna_mac *mac)
-{
-       list_add_tail(&mac->qe, &ucam_mod->free_q);
-}
-
-struct bna_mac *
-bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod)
-{
-       struct list_head *qe;
-
-       if (list_empty(&mcam_mod->free_q))
-               return NULL;
-
-       bfa_q_deq(&mcam_mod->free_q, &qe);
-
-       return (struct bna_mac *)qe;
-}
-
-void
-bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, struct bna_mac *mac)
-{
-       list_add_tail(&mac->qe, &mcam_mod->free_q);
-}
-
-/**
- * Note: This should be called in the same locking context as the call to
- * bna_rit_mod_seg_get()
- */
-int
-bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size)
-{
-       int i;
-
-       /* Select the pool for seg_size */
-       for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
-               if (seg_size <= ritseg_pool_cfg[i].pool_entry_size)
-                       break;
-       }
-
-       if (i == BFI_RIT_SEG_TOTAL_POOLS)
-               return 0;
-
-       if (list_empty(&rit_mod->rit_seg_pool[i]))
-               return 0;
-
-       return 1;
-}
-
-struct bna_rit_segment *
-bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size)
-{
-       struct bna_rit_segment *seg;
-       struct list_head *qe;
-       int i;
-
-       /* Select the pool for seg_size */
-       for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
-               if (seg_size <= ritseg_pool_cfg[i].pool_entry_size)
-                       break;
-       }
-
-       if (i == BFI_RIT_SEG_TOTAL_POOLS)
-               return NULL;
-
-       if (list_empty(&rit_mod->rit_seg_pool[i]))
-               return NULL;
-
-       bfa_q_deq(&rit_mod->rit_seg_pool[i], &qe);
-       seg = (struct bna_rit_segment *)qe;
-       bfa_q_qe_init(&seg->qe);
-       seg->rit_size = seg_size;
-
-       return seg;
-}
-
-void
-bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod,
-                       struct bna_rit_segment *seg)
-{
-       int i;
-
-       /* Select the pool for seg->max_rit_size */
-       for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
-               if (seg->max_rit_size == ritseg_pool_cfg[i].pool_entry_size)
-                       break;
-       }
-
-       seg->rit_size = 0;
-       list_add_tail(&seg->qe, &rit_mod->rit_seg_pool[i]);
-}
diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h
deleted file mode 100644 (file)
index cad233d..0000000
+++ /dev/null
@@ -1,1490 +0,0 @@
-/*
- * Linux network driver for Brocade Converged Network Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * File for interrupt macros and functions
- */
-
-#ifndef __BNA_HW_H__
-#define __BNA_HW_H__
-
-#include "bfi_ctreg.h"
-
-/**
- *
- * SW imposed limits
- *
- */
-
-#ifndef BNA_BIOS_BUILD
-
-#define BFI_MAX_TXQ                    64
-#define BFI_MAX_RXQ                    64
-#define        BFI_MAX_RXF                     64
-#define BFI_MAX_IB                     128
-#define        BFI_MAX_RIT_SIZE                256
-#define        BFI_RSS_RIT_SIZE                64
-#define        BFI_NONRSS_RIT_SIZE             1
-#define BFI_MAX_UCMAC                  256
-#define BFI_MAX_MCMAC                  512
-#define BFI_IBIDX_SIZE                 4
-#define BFI_MAX_VLAN                   4095
-
-/**
- * There are 2 free IB index pools:
- *     pool1: 120 segments of 1 index each
- *     pool8: 1 segment of 8 indexes
- */
-#define BFI_IBIDX_POOL1_SIZE           116
-#define        BFI_IBIDX_POOL1_ENTRY_SIZE      1
-#define BFI_IBIDX_POOL2_SIZE           2
-#define        BFI_IBIDX_POOL2_ENTRY_SIZE      2
-#define        BFI_IBIDX_POOL8_SIZE            1
-#define        BFI_IBIDX_POOL8_ENTRY_SIZE      8
-#define        BFI_IBIDX_TOTAL_POOLS           3
-#define        BFI_IBIDX_TOTAL_SEGS            119 /* (POOL1 + POOL2 + POOL8)_SIZE */
-#define        BFI_IBIDX_MAX_SEGSIZE           8
-#define init_ibidx_pool(name)                                          \
-static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] =             \
-{                                                                      \
-       { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE },           \
-       { BFI_IBIDX_POOL2_SIZE, BFI_IBIDX_POOL2_ENTRY_SIZE },           \
-       { BFI_IBIDX_POOL8_SIZE, BFI_IBIDX_POOL8_ENTRY_SIZE }            \
-}
-
-/**
- * There are 2 free RIT segment pools:
- *     Pool1: 192 segments of 1 RIT entry each
- *     Pool2: 1 segment of 64 RIT entry
- */
-#define BFI_RIT_SEG_POOL1_SIZE         192
-#define BFI_RIT_SEG_POOL1_ENTRY_SIZE   1
-#define BFI_RIT_SEG_POOLRSS_SIZE       1
-#define BFI_RIT_SEG_POOLRSS_ENTRY_SIZE 64
-#define BFI_RIT_SEG_TOTAL_POOLS                2
-#define BFI_RIT_TOTAL_SEGS             193 /* POOL1_SIZE + POOLRSS_SIZE */
-#define init_ritseg_pool(name)                                         \
-static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] =      \
-{                                                                      \
-       { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE },       \
-       { BFI_RIT_SEG_POOLRSS_SIZE, BFI_RIT_SEG_POOLRSS_ENTRY_SIZE }    \
-}
-
-#else /* BNA_BIOS_BUILD */
-
-#define BFI_MAX_TXQ                    1
-#define BFI_MAX_RXQ                    1
-#define        BFI_MAX_RXF                     1
-#define BFI_MAX_IB                     2
-#define        BFI_MAX_RIT_SIZE                2
-#define        BFI_RSS_RIT_SIZE                64
-#define        BFI_NONRSS_RIT_SIZE             1
-#define BFI_MAX_UCMAC                  1
-#define BFI_MAX_MCMAC                  8
-#define BFI_IBIDX_SIZE                 4
-#define BFI_MAX_VLAN                   4095
-/* There is one free pool: 2 segments of 1 index each */
-#define BFI_IBIDX_POOL1_SIZE           2
-#define        BFI_IBIDX_POOL1_ENTRY_SIZE      1
-#define        BFI_IBIDX_TOTAL_POOLS           1
-#define        BFI_IBIDX_TOTAL_SEGS            2 /* POOL1_SIZE */
-#define        BFI_IBIDX_MAX_SEGSIZE           1
-#define init_ibidx_pool(name)                                          \
-static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] =             \
-{                                                                      \
-       { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE }            \
-}
-
-#define BFI_RIT_SEG_POOL1_SIZE         1
-#define BFI_RIT_SEG_POOL1_ENTRY_SIZE   1
-#define BFI_RIT_SEG_TOTAL_POOLS                1
-#define BFI_RIT_TOTAL_SEGS             1 /* POOL1_SIZE */
-#define init_ritseg_pool(name)                                         \
-static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] =      \
-{                                                                      \
-       { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE }        \
-}
-
-#endif /* BNA_BIOS_BUILD */
-
-#define BFI_RSS_HASH_KEY_LEN           10
-
-#define BFI_COALESCING_TIMER_UNIT      5       /* 5us */
-#define BFI_MAX_COALESCING_TIMEO       0xFF    /* in 5us units */
-#define BFI_MAX_INTERPKT_COUNT         0xFF
-#define BFI_MAX_INTERPKT_TIMEO         0xF     /* in 0.5us units */
-#define BFI_TX_COALESCING_TIMEO                20      /* 20 * 5 = 100us */
-#define BFI_TX_INTERPKT_COUNT          32
-#define        BFI_RX_COALESCING_TIMEO         12      /* 12 * 5 = 60us */
-#define        BFI_RX_INTERPKT_COUNT           6       /* Pkt Cnt = 6 */
-#define        BFI_RX_INTERPKT_TIMEO           3       /* 3 * 0.5 = 1.5us */
-
-#define BFI_TXQ_WI_SIZE                        64      /* bytes */
-#define BFI_RXQ_WI_SIZE                        8       /* bytes */
-#define BFI_CQ_WI_SIZE                 16      /* bytes */
-#define BFI_TX_MAX_WRR_QUOTA           0xFFF
-
-#define BFI_TX_MAX_VECTORS_PER_WI      4
-#define BFI_TX_MAX_VECTORS_PER_PKT     0xFF
-#define BFI_TX_MAX_DATA_PER_VECTOR     0xFFFF
-#define BFI_TX_MAX_DATA_PER_PKT                0xFFFFFF
-
-/* Small Q buffer size */
-#define BFI_SMALL_RXBUF_SIZE           128
-
-/* Defined separately since BFA_FLASH_DMA_BUF_SZ is in bfa_flash.c */
-#define BFI_FLASH_DMA_BUF_SZ           0x010000 /* 64K DMA */
-#define BFI_HW_STATS_SIZE              0x4000 /* 16K DMA */
-
-/**
- *
- * HW register offsets, macros
- *
- */
-
-/* DMA Block Register Host Window Start Address */
-#define DMA_BLK_REG_ADDR               0x00013000
-
-/* DMA Block Internal Registers */
-#define DMA_CTRL_REG0                  (DMA_BLK_REG_ADDR + 0x000)
-#define DMA_CTRL_REG1                  (DMA_BLK_REG_ADDR + 0x004)
-#define DMA_ERR_INT_STATUS             (DMA_BLK_REG_ADDR + 0x008)
-#define DMA_ERR_INT_ENABLE             (DMA_BLK_REG_ADDR + 0x00c)
-#define DMA_ERR_INT_STATUS_SET         (DMA_BLK_REG_ADDR + 0x010)
-
-/* APP Block Register Address Offset from BAR0 */
-#define APP_BLK_REG_ADDR               0x00014000
-
-/* Host Function Interrupt Mask Registers */
-#define HOSTFN0_INT_MASK               (APP_BLK_REG_ADDR + 0x004)
-#define HOSTFN1_INT_MASK               (APP_BLK_REG_ADDR + 0x104)
-#define HOSTFN2_INT_MASK               (APP_BLK_REG_ADDR + 0x304)
-#define HOSTFN3_INT_MASK               (APP_BLK_REG_ADDR + 0x404)
-
-/**
- * Host Function PCIe Error Registers
- * Duplicates "Correctable" & "Uncorrectable"
- * registers in PCIe Config space.
- */
-#define FN0_PCIE_ERR_REG               (APP_BLK_REG_ADDR + 0x014)
-#define FN1_PCIE_ERR_REG               (APP_BLK_REG_ADDR + 0x114)
-#define FN2_PCIE_ERR_REG               (APP_BLK_REG_ADDR + 0x314)
-#define FN3_PCIE_ERR_REG               (APP_BLK_REG_ADDR + 0x414)
-
-/* Host Function Error Type Status Registers */
-#define FN0_ERR_TYPE_STATUS_REG                (APP_BLK_REG_ADDR + 0x018)
-#define FN1_ERR_TYPE_STATUS_REG                (APP_BLK_REG_ADDR + 0x118)
-#define FN2_ERR_TYPE_STATUS_REG                (APP_BLK_REG_ADDR + 0x318)
-#define FN3_ERR_TYPE_STATUS_REG                (APP_BLK_REG_ADDR + 0x418)
-
-/* Host Function Error Type Mask Registers */
-#define FN0_ERR_TYPE_MSK_STATUS_REG    (APP_BLK_REG_ADDR + 0x01c)
-#define FN1_ERR_TYPE_MSK_STATUS_REG    (APP_BLK_REG_ADDR + 0x11c)
-#define FN2_ERR_TYPE_MSK_STATUS_REG    (APP_BLK_REG_ADDR + 0x31c)
-#define FN3_ERR_TYPE_MSK_STATUS_REG    (APP_BLK_REG_ADDR + 0x41c)
-
-/* Catapult Host Semaphore Status Registers (App block) */
-#define HOST_SEM_STS0_REG              (APP_BLK_REG_ADDR + 0x630)
-#define HOST_SEM_STS1_REG              (APP_BLK_REG_ADDR + 0x634)
-#define HOST_SEM_STS2_REG              (APP_BLK_REG_ADDR + 0x638)
-#define HOST_SEM_STS3_REG              (APP_BLK_REG_ADDR + 0x63c)
-#define HOST_SEM_STS4_REG              (APP_BLK_REG_ADDR + 0x640)
-#define HOST_SEM_STS5_REG              (APP_BLK_REG_ADDR + 0x644)
-#define HOST_SEM_STS6_REG              (APP_BLK_REG_ADDR + 0x648)
-#define HOST_SEM_STS7_REG              (APP_BLK_REG_ADDR + 0x64c)
-
-/* PCIe Misc Register */
-#define PCIE_MISC_REG                  (APP_BLK_REG_ADDR + 0x200)
-
-/* Temp Sensor Control Registers */
-#define TEMPSENSE_CNTL_REG             (APP_BLK_REG_ADDR + 0x250)
-#define TEMPSENSE_STAT_REG             (APP_BLK_REG_ADDR + 0x254)
-
-/* APP Block local error registers */
-#define APP_LOCAL_ERR_STAT             (APP_BLK_REG_ADDR + 0x258)
-#define APP_LOCAL_ERR_MSK              (APP_BLK_REG_ADDR + 0x25c)
-
-/* PCIe Link Error registers */
-#define PCIE_LNK_ERR_STAT              (APP_BLK_REG_ADDR + 0x260)
-#define PCIE_LNK_ERR_MSK               (APP_BLK_REG_ADDR + 0x264)
-
-/**
- * FCoE/FIP Ethertype Register
- * 31:16 -- Chip wide value for FIP type
- * 15:0  -- Chip wide value for FCoE type
- */
-#define FCOE_FIP_ETH_TYPE              (APP_BLK_REG_ADDR + 0x280)
-
-/**
- * Reserved Ethertype Register
- * 31:16 -- Reserved
- * 15:0  -- Other ethertype
- */
-#define RESV_ETH_TYPE                  (APP_BLK_REG_ADDR + 0x284)
-
-/**
- * Host Command Status Registers
- * Each set consists of 3 registers :
- * clear, set, cmd
- * 16 such register sets in all
- * See catapult_spec.pdf for detailed functionality
- * Put each type in a single macro accessed by _num ?
- */
-#define HOST_CMDSTS0_CLR_REG           (APP_BLK_REG_ADDR + 0x500)
-#define HOST_CMDSTS0_SET_REG           (APP_BLK_REG_ADDR + 0x504)
-#define HOST_CMDSTS0_REG               (APP_BLK_REG_ADDR + 0x508)
-#define HOST_CMDSTS1_CLR_REG           (APP_BLK_REG_ADDR + 0x510)
-#define HOST_CMDSTS1_SET_REG           (APP_BLK_REG_ADDR + 0x514)
-#define HOST_CMDSTS1_REG               (APP_BLK_REG_ADDR + 0x518)
-#define HOST_CMDSTS2_CLR_REG           (APP_BLK_REG_ADDR + 0x520)
-#define HOST_CMDSTS2_SET_REG           (APP_BLK_REG_ADDR + 0x524)
-#define HOST_CMDSTS2_REG               (APP_BLK_REG_ADDR + 0x528)
-#define HOST_CMDSTS3_CLR_REG           (APP_BLK_REG_ADDR + 0x530)
-#define HOST_CMDSTS3_SET_REG           (APP_BLK_REG_ADDR + 0x534)
-#define HOST_CMDSTS3_REG               (APP_BLK_REG_ADDR + 0x538)
-#define HOST_CMDSTS4_CLR_REG           (APP_BLK_REG_ADDR + 0x540)
-#define HOST_CMDSTS4_SET_REG           (APP_BLK_REG_ADDR + 0x544)
-#define HOST_CMDSTS4_REG               (APP_BLK_REG_ADDR + 0x548)
-#define HOST_CMDSTS5_CLR_REG           (APP_BLK_REG_ADDR + 0x550)
-#define HOST_CMDSTS5_SET_REG           (APP_BLK_REG_ADDR + 0x554)
-#define HOST_CMDSTS5_REG               (APP_BLK_REG_ADDR + 0x558)
-#define HOST_CMDSTS6_CLR_REG           (APP_BLK_REG_ADDR + 0x560)
-#define HOST_CMDSTS6_SET_REG           (APP_BLK_REG_ADDR + 0x564)
-#define HOST_CMDSTS6_REG               (APP_BLK_REG_ADDR + 0x568)
-#define HOST_CMDSTS7_CLR_REG           (APP_BLK_REG_ADDR + 0x570)
-#define HOST_CMDSTS7_SET_REG           (APP_BLK_REG_ADDR + 0x574)
-#define HOST_CMDSTS7_REG               (APP_BLK_REG_ADDR + 0x578)
-#define HOST_CMDSTS8_CLR_REG           (APP_BLK_REG_ADDR + 0x580)
-#define HOST_CMDSTS8_SET_REG           (APP_BLK_REG_ADDR + 0x584)
-#define HOST_CMDSTS8_REG               (APP_BLK_REG_ADDR + 0x588)
-#define HOST_CMDSTS9_CLR_REG           (APP_BLK_REG_ADDR + 0x590)
-#define HOST_CMDSTS9_SET_REG           (APP_BLK_REG_ADDR + 0x594)
-#define HOST_CMDSTS9_REG               (APP_BLK_REG_ADDR + 0x598)
-#define HOST_CMDSTS10_CLR_REG          (APP_BLK_REG_ADDR + 0x5A0)
-#define HOST_CMDSTS10_SET_REG          (APP_BLK_REG_ADDR + 0x5A4)
-#define HOST_CMDSTS10_REG              (APP_BLK_REG_ADDR + 0x5A8)
-#define HOST_CMDSTS11_CLR_REG          (APP_BLK_REG_ADDR + 0x5B0)
-#define HOST_CMDSTS11_SET_REG          (APP_BLK_REG_ADDR + 0x5B4)
-#define HOST_CMDSTS11_REG              (APP_BLK_REG_ADDR + 0x5B8)
-#define HOST_CMDSTS12_CLR_REG          (APP_BLK_REG_ADDR + 0x5C0)
-#define HOST_CMDSTS12_SET_REG          (APP_BLK_REG_ADDR + 0x5C4)
-#define HOST_CMDSTS12_REG              (APP_BLK_REG_ADDR + 0x5C8)
-#define HOST_CMDSTS13_CLR_REG          (APP_BLK_REG_ADDR + 0x5D0)
-#define HOST_CMDSTS13_SET_REG          (APP_BLK_REG_ADDR + 0x5D4)
-#define HOST_CMDSTS13_REG              (APP_BLK_REG_ADDR + 0x5D8)
-#define HOST_CMDSTS14_CLR_REG          (APP_BLK_REG_ADDR + 0x5E0)
-#define HOST_CMDSTS14_SET_REG          (APP_BLK_REG_ADDR + 0x5E4)
-#define HOST_CMDSTS14_REG              (APP_BLK_REG_ADDR + 0x5E8)
-#define HOST_CMDSTS15_CLR_REG          (APP_BLK_REG_ADDR + 0x5F0)
-#define HOST_CMDSTS15_SET_REG          (APP_BLK_REG_ADDR + 0x5F4)
-#define HOST_CMDSTS15_REG              (APP_BLK_REG_ADDR + 0x5F8)
-
-/**
- * LPU0 Block Register Address Offset from BAR0
- * Range 0x18000 - 0x18033
- */
-#define LPU0_BLK_REG_ADDR              0x00018000
-
-/**
- * LPU0 Registers
- * Should they be directly used from host,
- * except for diagnostics ?
- * CTL_REG : Control register
- * CMD_REG : Triggers exec. of cmd. in
- *           Mailbox memory
- */
-#define LPU0_MBOX_CTL_REG              (LPU0_BLK_REG_ADDR + 0x000)
-#define LPU0_MBOX_CMD_REG              (LPU0_BLK_REG_ADDR + 0x004)
-#define LPU0_MBOX_LINK_0REG            (LPU0_BLK_REG_ADDR + 0x008)
-#define LPU1_MBOX_LINK_0REG            (LPU0_BLK_REG_ADDR + 0x00c)
-#define LPU0_MBOX_STATUS_0REG          (LPU0_BLK_REG_ADDR + 0x010)
-#define LPU1_MBOX_STATUS_0REG          (LPU0_BLK_REG_ADDR + 0x014)
-#define LPU0_ERR_STATUS_REG            (LPU0_BLK_REG_ADDR + 0x018)
-#define LPU0_ERR_SET_REG               (LPU0_BLK_REG_ADDR + 0x020)
-
-/**
- * LPU1 Block Register Address Offset from BAR0
- * Range 0x18400 - 0x18433
- */
-#define LPU1_BLK_REG_ADDR              0x00018400
-
-/**
- * LPU1 Registers
- * Same as LPU0 registers above
- */
-#define LPU1_MBOX_CTL_REG              (LPU1_BLK_REG_ADDR + 0x000)
-#define LPU1_MBOX_CMD_REG              (LPU1_BLK_REG_ADDR + 0x004)
-#define LPU0_MBOX_LINK_1REG            (LPU1_BLK_REG_ADDR + 0x008)
-#define LPU1_MBOX_LINK_1REG            (LPU1_BLK_REG_ADDR + 0x00c)
-#define LPU0_MBOX_STATUS_1REG          (LPU1_BLK_REG_ADDR + 0x010)
-#define LPU1_MBOX_STATUS_1REG          (LPU1_BLK_REG_ADDR + 0x014)
-#define LPU1_ERR_STATUS_REG            (LPU1_BLK_REG_ADDR + 0x018)
-#define LPU1_ERR_SET_REG               (LPU1_BLK_REG_ADDR + 0x020)
-
-/**
- * PSS Block Register Address Offset from BAR0
- * Range 0x18800 - 0x188DB
- */
-#define PSS_BLK_REG_ADDR               0x00018800
-
-/**
- * PSS Registers
- * For details, see catapult_spec.pdf
- * ERR_STATUS_REG : Indicates error in PSS module
- * RAM_ERR_STATUS_REG : Indicates RAM module that detected error
- */
-#define ERR_STATUS_SET                 (PSS_BLK_REG_ADDR + 0x018)
-#define PSS_RAM_ERR_STATUS_REG         (PSS_BLK_REG_ADDR + 0x01C)
-
-/**
- * PSS Semaphore Lock Registers, total 16
- * First read when unlocked returns 0,
- * and is set to 1, atomically.
- * Subsequent reads returns 1.
- * To clear set the value to 0.
- * Range : 0x20 to 0x5c
- */
-#define PSS_SEM_LOCK_REG(_num)         \
-       (PSS_BLK_REG_ADDR + 0x020 + ((_num) << 2))
-
-/**
- * PSS Semaphore Status Registers,
- * corresponding to the lock registers above
- */
-#define PSS_SEM_STATUS_REG(_num)               \
-       (PSS_BLK_REG_ADDR + 0x060 + ((_num) << 2))
-
-/**
- * Catapult CPQ Registers
- * Defines for Mailbox Registers
- * Used to send mailbox commands to firmware from
- * host. The data part is written to the MBox
- * memory, registers are used to indicate that
- * a commnad is resident in memory.
- *
- * Note : LPU0<->LPU1 mailboxes are not listed here
- */
-#define CPQ_BLK_REG_ADDR               0x00019000
-
-#define HOSTFN0_LPU0_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x130)
-#define HOSTFN0_LPU1_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x134)
-#define LPU0_HOSTFN0_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x138)
-#define LPU1_HOSTFN0_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x13C)
-
-#define HOSTFN1_LPU0_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x140)
-#define HOSTFN1_LPU1_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x144)
-#define LPU0_HOSTFN1_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x148)
-#define LPU1_HOSTFN1_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x14C)
-
-#define HOSTFN2_LPU0_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x170)
-#define HOSTFN2_LPU1_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x174)
-#define LPU0_HOSTFN2_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x178)
-#define LPU1_HOSTFN2_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x17C)
-
-#define HOSTFN3_LPU0_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x180)
-#define HOSTFN3_LPU1_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x184)
-#define LPU0_HOSTFN3_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x188)
-#define LPU1_HOSTFN3_MBOX1_CMD_STAT    (CPQ_BLK_REG_ADDR + 0x18C)
-
-/* Host Function Force Parity Error Registers */
-#define HOSTFN0_LPU_FORCE_PERR         (CPQ_BLK_REG_ADDR + 0x120)
-#define HOSTFN1_LPU_FORCE_PERR         (CPQ_BLK_REG_ADDR + 0x124)
-#define HOSTFN2_LPU_FORCE_PERR         (CPQ_BLK_REG_ADDR + 0x128)
-#define HOSTFN3_LPU_FORCE_PERR         (CPQ_BLK_REG_ADDR + 0x12C)
-
-/* LL Port[0|1] Halt Mask Registers */
-#define LL_HALT_MSK_P0                 (CPQ_BLK_REG_ADDR + 0x1A0)
-#define LL_HALT_MSK_P1                 (CPQ_BLK_REG_ADDR + 0x1B0)
-
-/* LL Port[0|1] Error Mask Registers */
-#define LL_ERR_MSK_P0                  (CPQ_BLK_REG_ADDR + 0x1D0)
-#define LL_ERR_MSK_P1                  (CPQ_BLK_REG_ADDR + 0x1D4)
-
-/* EMC FLI (Flash Controller) Block Register Address Offset from BAR0 */
-#define FLI_BLK_REG_ADDR               0x0001D000
-
-/* EMC FLI Registers */
-#define FLI_CMD_REG                    (FLI_BLK_REG_ADDR + 0x000)
-#define FLI_ADDR_REG                   (FLI_BLK_REG_ADDR + 0x004)
-#define FLI_CTL_REG                    (FLI_BLK_REG_ADDR + 0x008)
-#define FLI_WRDATA_REG                 (FLI_BLK_REG_ADDR + 0x00C)
-#define FLI_RDDATA_REG                 (FLI_BLK_REG_ADDR + 0x010)
-#define FLI_DEV_STATUS_REG             (FLI_BLK_REG_ADDR + 0x014)
-#define FLI_SIG_WD_REG                 (FLI_BLK_REG_ADDR + 0x018)
-
-/**
- * RO register
- * 31:16 -- Vendor Id
- * 15:0  -- Device Id
- */
-#define FLI_DEV_VENDOR_REG             (FLI_BLK_REG_ADDR + 0x01C)
-#define FLI_ERR_STATUS_REG             (FLI_BLK_REG_ADDR + 0x020)
-
-/**
- * RAD (RxAdm) Block Register Address Offset from BAR0
- * RAD0 Range : 0x20000 - 0x203FF
- * RAD1 Range : 0x20400 - 0x207FF
- */
-#define RAD0_BLK_REG_ADDR              0x00020000
-#define RAD1_BLK_REG_ADDR              0x00020400
-
-/* RAD0 Registers */
-#define RAD0_CTL_REG                   (RAD0_BLK_REG_ADDR + 0x000)
-#define RAD0_PE_PARM_REG               (RAD0_BLK_REG_ADDR + 0x004)
-#define RAD0_BCN_REG                   (RAD0_BLK_REG_ADDR + 0x008)
-
-/* Default function ID register */
-#define RAD0_DEFAULT_REG               (RAD0_BLK_REG_ADDR + 0x00C)
-
-/* Default promiscuous ID register */
-#define RAD0_PROMISC_REG               (RAD0_BLK_REG_ADDR + 0x010)
-
-#define RAD0_BCNQ_REG                  (RAD0_BLK_REG_ADDR + 0x014)
-
-/*
- * This register selects 1 of 8 PM Q's using
- * VLAN pri, for non-BCN packets without a VLAN tag
- */
-#define RAD0_DEFAULTQ_REG              (RAD0_BLK_REG_ADDR + 0x018)
-
-#define RAD0_ERR_STS                   (RAD0_BLK_REG_ADDR + 0x01C)
-#define RAD0_SET_ERR_STS               (RAD0_BLK_REG_ADDR + 0x020)
-#define RAD0_ERR_INT_EN                        (RAD0_BLK_REG_ADDR + 0x024)
-#define RAD0_FIRST_ERR                 (RAD0_BLK_REG_ADDR + 0x028)
-#define RAD0_FORCE_ERR                 (RAD0_BLK_REG_ADDR + 0x02C)
-
-#define RAD0_IF_RCVD                   (RAD0_BLK_REG_ADDR + 0x030)
-#define RAD0_IF_RCVD_OCTETS_HIGH       (RAD0_BLK_REG_ADDR + 0x034)
-#define RAD0_IF_RCVD_OCTETS_LOW                (RAD0_BLK_REG_ADDR + 0x038)
-#define RAD0_IF_RCVD_VLAN              (RAD0_BLK_REG_ADDR + 0x03C)
-#define RAD0_IF_RCVD_UCAST             (RAD0_BLK_REG_ADDR + 0x040)
-#define RAD0_IF_RCVD_UCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x044)
-#define RAD0_IF_RCVD_UCAST_OCTETS_LOW   (RAD0_BLK_REG_ADDR + 0x048)
-#define RAD0_IF_RCVD_UCAST_VLAN                (RAD0_BLK_REG_ADDR + 0x04C)
-#define RAD0_IF_RCVD_MCAST             (RAD0_BLK_REG_ADDR + 0x050)
-#define RAD0_IF_RCVD_MCAST_OCTETS_HIGH  (RAD0_BLK_REG_ADDR + 0x054)
-#define RAD0_IF_RCVD_MCAST_OCTETS_LOW   (RAD0_BLK_REG_ADDR + 0x058)
-#define RAD0_IF_RCVD_MCAST_VLAN                (RAD0_BLK_REG_ADDR + 0x05C)
-#define RAD0_IF_RCVD_BCAST             (RAD0_BLK_REG_ADDR + 0x060)
-#define RAD0_IF_RCVD_BCAST_OCTETS_HIGH  (RAD0_BLK_REG_ADDR + 0x064)
-#define RAD0_IF_RCVD_BCAST_OCTETS_LOW   (RAD0_BLK_REG_ADDR + 0x068)
-#define RAD0_IF_RCVD_BCAST_VLAN                (RAD0_BLK_REG_ADDR + 0x06C)
-#define RAD0_DROPPED_FRAMES            (RAD0_BLK_REG_ADDR + 0x070)
-
-#define RAD0_MAC_MAN_1H                        (RAD0_BLK_REG_ADDR + 0x080)
-#define RAD0_MAC_MAN_1L                        (RAD0_BLK_REG_ADDR + 0x084)
-#define RAD0_MAC_MAN_2H                        (RAD0_BLK_REG_ADDR + 0x088)
-#define RAD0_MAC_MAN_2L                        (RAD0_BLK_REG_ADDR + 0x08C)
-#define RAD0_MAC_MAN_3H                        (RAD0_BLK_REG_ADDR + 0x090)
-#define RAD0_MAC_MAN_3L                        (RAD0_BLK_REG_ADDR + 0x094)
-#define RAD0_MAC_MAN_4H                        (RAD0_BLK_REG_ADDR + 0x098)
-#define RAD0_MAC_MAN_4L                        (RAD0_BLK_REG_ADDR + 0x09C)
-
-#define RAD0_LAST4_IP                  (RAD0_BLK_REG_ADDR + 0x100)
-
-/* RAD1 Registers */
-#define RAD1_CTL_REG                   (RAD1_BLK_REG_ADDR + 0x000)
-#define RAD1_PE_PARM_REG               (RAD1_BLK_REG_ADDR + 0x004)
-#define RAD1_BCN_REG                   (RAD1_BLK_REG_ADDR + 0x008)
-
-/* Default function ID register */
-#define RAD1_DEFAULT_REG               (RAD1_BLK_REG_ADDR + 0x00C)
-
-/* Promiscuous function ID register */
-#define RAD1_PROMISC_REG               (RAD1_BLK_REG_ADDR + 0x010)
-
-#define RAD1_BCNQ_REG                  (RAD1_BLK_REG_ADDR + 0x014)
-
-/*
- * This register selects 1 of 8 PM Q's using
- * VLAN pri, for non-BCN packets without a VLAN tag
- */
-#define RAD1_DEFAULTQ_REG              (RAD1_BLK_REG_ADDR + 0x018)
-
-#define RAD1_ERR_STS                   (RAD1_BLK_REG_ADDR + 0x01C)
-#define RAD1_SET_ERR_STS               (RAD1_BLK_REG_ADDR + 0x020)
-#define RAD1_ERR_INT_EN                        (RAD1_BLK_REG_ADDR + 0x024)
-
-/**
- * TXA Block Register Address Offset from BAR0
- * TXA0 Range : 0x21000 - 0x213FF
- * TXA1 Range : 0x21400 - 0x217FF
- */
-#define TXA0_BLK_REG_ADDR              0x00021000
-#define TXA1_BLK_REG_ADDR              0x00021400
-
-/* TXA Registers */
-#define TXA0_CTRL_REG                  (TXA0_BLK_REG_ADDR + 0x000)
-#define TXA1_CTRL_REG                  (TXA1_BLK_REG_ADDR + 0x000)
-
-/**
- * TSO Sequence # Registers (RO)
- * Total 8 (for 8 queues)
- * Holds the last seq.# for TSO frames
- * See catapult_spec.pdf for more details
- */
-#define TXA0_TSO_TCP_SEQ_REG(_num)             \
-       (TXA0_BLK_REG_ADDR + 0x020 + ((_num) << 2))
-
-#define TXA1_TSO_TCP_SEQ_REG(_num)             \
-       (TXA1_BLK_REG_ADDR + 0x020 + ((_num) << 2))
-
-/**
- * TSO IP ID # Registers (RO)
- * Total 8 (for 8 queues)
- * Holds the last IP ID for TSO frames
- * See catapult_spec.pdf for more details
- */
-#define TXA0_TSO_IP_INFO_REG(_num)             \
-       (TXA0_BLK_REG_ADDR + 0x040 + ((_num) << 2))
-
-#define TXA1_TSO_IP_INFO_REG(_num)             \
-       (TXA1_BLK_REG_ADDR + 0x040 + ((_num) << 2))
-
-/**
- * RXA Block Register Address Offset from BAR0
- * RXA0 Range : 0x21800 - 0x21BFF
- * RXA1 Range : 0x21C00 - 0x21FFF
- */
-#define RXA0_BLK_REG_ADDR              0x00021800
-#define RXA1_BLK_REG_ADDR              0x00021C00
-
-/* RXA Registers */
-#define RXA0_CTL_REG                   (RXA0_BLK_REG_ADDR + 0x040)
-#define RXA1_CTL_REG                   (RXA1_BLK_REG_ADDR + 0x040)
-
-/**
- * PPLB Block Register Address Offset from BAR0
- * PPLB0 Range : 0x22000 - 0x223FF
- * PPLB1 Range : 0x22400 - 0x227FF
- */
-#define PLB0_BLK_REG_ADDR              0x00022000
-#define PLB1_BLK_REG_ADDR              0x00022400
-
-/**
- * PLB Registers
- * Holds RL timer used time stamps in RLT tagged frames
- */
-#define PLB0_ECM_TIMER_REG             (PLB0_BLK_REG_ADDR + 0x05C)
-#define PLB1_ECM_TIMER_REG             (PLB1_BLK_REG_ADDR + 0x05C)
-
-/* Controls the rate-limiter on each of the priority class */
-#define PLB0_RL_CTL                    (PLB0_BLK_REG_ADDR + 0x060)
-#define PLB1_RL_CTL                    (PLB1_BLK_REG_ADDR + 0x060)
-
-/**
- * Max byte register, total 8, 0-7
- * see catapult_spec.pdf for details
- */
-#define PLB0_RL_MAX_BC(_num)                   \
-       (PLB0_BLK_REG_ADDR + 0x064 + ((_num) << 2))
-#define PLB1_RL_MAX_BC(_num)                   \
-       (PLB1_BLK_REG_ADDR + 0x064 + ((_num) << 2))
-
-/**
- * RL Time Unit Register for priority 0-7
- * 4 bits per priority
- * (2^rl_unit)*1us is the actual time period
- */
-#define PLB0_RL_TU_PRIO                        (PLB0_BLK_REG_ADDR + 0x084)
-#define PLB1_RL_TU_PRIO                        (PLB1_BLK_REG_ADDR + 0x084)
-
-/**
- * RL byte count register,
- * bytes transmitted in (rl_unit*1)us time period
- * 1 per priority, 8 in all, 0-7.
- */
-#define PLB0_RL_BYTE_CNT(_num)                 \
-       (PLB0_BLK_REG_ADDR + 0x088 + ((_num) << 2))
-#define PLB1_RL_BYTE_CNT(_num)                 \
-       (PLB1_BLK_REG_ADDR + 0x088 + ((_num) << 2))
-
-/**
- * RL Min factor register
- * 2 bits per priority,
- * 4 factors possible: 1, 0.5, 0.25, 0
- * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1
- */
-#define PLB0_RL_MIN_REG                        (PLB0_BLK_REG_ADDR + 0x0A8)
-#define PLB1_RL_MIN_REG                        (PLB1_BLK_REG_ADDR + 0x0A8)
-
-/**
- * RL Max factor register
- * 2 bits per priority,
- * 4 factors possible: 1, 0.5, 0.25, 0
- * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1
- */
-#define PLB0_RL_MAX_REG                        (PLB0_BLK_REG_ADDR + 0x0AC)
-#define PLB1_RL_MAX_REG                        (PLB1_BLK_REG_ADDR + 0x0AC)
-
-/* MAC SERDES Address Paging register */
-#define PLB0_EMS_ADD_REG               (PLB0_BLK_REG_ADDR + 0xD0)
-#define PLB1_EMS_ADD_REG               (PLB1_BLK_REG_ADDR + 0xD0)
-
-/* LL EMS Registers */
-#define LL_EMS0_BLK_REG_ADDR           0x00026800
-#define LL_EMS1_BLK_REG_ADDR           0x00026C00
-
-/**
- * BPC Block Register Address Offset from BAR0
- * BPC0 Range : 0x23000 - 0x233FF
- * BPC1 Range : 0x23400 - 0x237FF
- */
-#define BPC0_BLK_REG_ADDR              0x00023000
-#define BPC1_BLK_REG_ADDR              0x00023400
-
-/**
- * PMM Block Register Address Offset from BAR0
- * PMM0 Range : 0x23800 - 0x23BFF
- * PMM1 Range : 0x23C00 - 0x23FFF
- */
-#define PMM0_BLK_REG_ADDR              0x00023800
-#define PMM1_BLK_REG_ADDR              0x00023C00
-
-/**
- * HQM Block Register Address Offset from BAR0
- * HQM0 Range : 0x24000 - 0x243FF
- * HQM1 Range : 0x24400 - 0x247FF
- */
-#define HQM0_BLK_REG_ADDR              0x00024000
-#define HQM1_BLK_REG_ADDR              0x00024400
-
-/**
- * HQM Control Register
- * Controls some aspects of IB
- * See catapult_spec.pdf for details
- */
-#define HQM0_CTL_REG                   (HQM0_BLK_REG_ADDR + 0x000)
-#define HQM1_CTL_REG                   (HQM1_BLK_REG_ADDR + 0x000)
-
-/**
- * HQM Stop Q Semaphore Registers.
- * Only one Queue resource can be stopped at
- * any given time. This register controls access
- * to the single stop Q resource.
- * See catapult_spec.pdf for details
- */
-#define HQM0_RXQ_STOP_SEM              (HQM0_BLK_REG_ADDR + 0x028)
-#define HQM0_TXQ_STOP_SEM              (HQM0_BLK_REG_ADDR + 0x02C)
-#define HQM1_RXQ_STOP_SEM              (HQM1_BLK_REG_ADDR + 0x028)
-#define HQM1_TXQ_STOP_SEM              (HQM1_BLK_REG_ADDR + 0x02C)
-
-/**
- * LUT Block Register Address Offset from BAR0
- * LUT0 Range : 0x25800 - 0x25BFF
- * LUT1 Range : 0x25C00 - 0x25FFF
- */
-#define LUT0_BLK_REG_ADDR              0x00025800
-#define LUT1_BLK_REG_ADDR              0x00025C00
-
-/**
- * LUT Registers
- * See catapult_spec.pdf for details
- */
-#define LUT0_ERR_STS                   (LUT0_BLK_REG_ADDR + 0x000)
-#define LUT1_ERR_STS                   (LUT1_BLK_REG_ADDR + 0x000)
-#define LUT0_SET_ERR_STS               (LUT0_BLK_REG_ADDR + 0x004)
-#define LUT1_SET_ERR_STS               (LUT1_BLK_REG_ADDR + 0x004)
-
-/**
- * TRC (Debug/Trace) Register Offset from BAR0
- * Range : 0x26000 -- 0x263FFF
- */
-#define TRC_BLK_REG_ADDR               0x00026000
-
-/**
- * TRC Registers
- * See catapult_spec.pdf for details of each
- */
-#define TRC_CTL_REG                    (TRC_BLK_REG_ADDR + 0x000)
-#define TRC_MODS_REG                   (TRC_BLK_REG_ADDR + 0x004)
-#define TRC_TRGC_REG                   (TRC_BLK_REG_ADDR + 0x008)
-#define TRC_CNT1_REG                   (TRC_BLK_REG_ADDR + 0x010)
-#define TRC_CNT2_REG                   (TRC_BLK_REG_ADDR + 0x014)
-#define TRC_NXTS_REG                   (TRC_BLK_REG_ADDR + 0x018)
-#define TRC_DIRR_REG                   (TRC_BLK_REG_ADDR + 0x01C)
-
-/**
- * TRC Trigger match filters, total 10
- * Determines the trigger condition
- */
-#define TRC_TRGM_REG(_num)             \
-       (TRC_BLK_REG_ADDR + 0x040 + ((_num) << 2))
-
-/**
- * TRC Next State filters, total 10
- * Determines the next state conditions
- */
-#define TRC_NXTM_REG(_num)             \
-       (TRC_BLK_REG_ADDR + 0x080 + ((_num) << 2))
-
-/**
- * TRC Store Match filters, total 10
- * Determines the store conditions
- */
-#define TRC_STRM_REG(_num)             \
-       (TRC_BLK_REG_ADDR + 0x0C0 + ((_num) << 2))
-
-/* DOORBELLS ACCESS */
-
-/**
- * Catapult doorbells
- * Each doorbell-queue set has
- * 1 RxQ, 1 TxQ, 2 IBs in that order
- * Size of each entry in 32 bytes, even though only 1 word
- * is used. For Non-VM case each doorbell-q set is
- * separated by 128 bytes, for VM case it is separated
- * by 4K bytes
- * Non VM case Range : 0x38000 - 0x39FFF
- * VM case Range     : 0x100000 - 0x11FFFF
- * The range applies to both HQMs
- */
-#define HQM_DOORBELL_BLK_BASE_ADDR     0x00038000
-#define HQM_DOORBELL_VM_BLK_BASE_ADDR  0x00100000
-
-/* MEMORY ACCESS */
-
-/**
- * Catapult H/W Block Memory Access Address
- * To the host a memory space of 32K (page) is visible
- * at a time. The address range is from 0x08000 to 0x0FFFF
- */
-#define HW_BLK_HOST_MEM_ADDR           0x08000
-
-/**
- * Catapult LUT Memory Access Page Numbers
- * Range : LUT0 0xa0-0xa1
- *         LUT1 0xa2-0xa3
- */
-#define LUT0_MEM_BLK_BASE_PG_NUM       0x000000A0
-#define LUT1_MEM_BLK_BASE_PG_NUM       0x000000A2
-
-/**
- * Catapult RxFn Database Memory Block Base Offset
- *
- * The Rx function database exists in LUT block.
- * In PCIe space this is accessible as a 256x32
- * bit block. Each entry in this database is 4
- * (4 byte) words. Max. entries is 64.
- * Address of an entry corresponding to a function
- * = base_addr + (function_no. * 16)
- */
-#define RX_FNDB_RAM_BASE_OFFSET                0x0000B400
-
-/**
- * Catapult TxFn Database Memory Block Base Offset Address
- *
- * The Tx function database exists in LUT block.
- * In PCIe space this is accessible as a 64x32
- * bit block. Each entry in this database is 1
- * (4 byte) word. Max. entries is 64.
- * Address of an entry corresponding to a function
- * = base_addr + (function_no. * 4)
- */
-#define TX_FNDB_RAM_BASE_OFFSET                0x0000B800
-
-/**
- * Catapult Unicast CAM Base Offset Address
- *
- * Exists in LUT memory space.
- * Shared by both the LL & FCoE driver.
- * Size is 256x48 bits; mapped to PCIe space
- * 512x32 bit blocks. For each address, bits
- * are written in the order : [47:32] and then
- * [31:0].
- */
-#define UCAST_CAM_BASE_OFFSET          0x0000A800
-
-/**
- * Catapult Unicast RAM Base Offset Address
- *
- * Exists in LUT memory space.
- * Shared by both the LL & FCoE driver.
- * Size is 256x9 bits.
- */
-#define UCAST_RAM_BASE_OFFSET          0x0000B000
-
-/**
- * Catapult Mulicast CAM Base Offset Address
- *
- * Exists in LUT memory space.
- * Shared by both the LL & FCoE driver.
- * Size is 256x48 bits; mapped to PCIe space
- * 512x32 bit blocks. For each address, bits
- * are written in the order : [47:32] and then
- * [31:0].
- */
-#define MCAST_CAM_BASE_OFFSET          0x0000A000
-
-/**
- * Catapult VLAN RAM Base Offset Address
- *
- * Exists in LUT memory space.
- * Size is 4096x66 bits; mapped to PCIe space as
- * 8192x32 bit blocks.
- * All the 4K entries are within the address range
- * 0x0000 to 0x8000, so in the first LUT page.
- */
-#define VLAN_RAM_BASE_OFFSET           0x00000000
-
-/**
- * Catapult Tx Stats RAM Base Offset Address
- *
- * Exists in LUT memory space.
- * Size is 1024x33 bits;
- * Each Tx function has 64 bytes of space
- */
-#define TX_STATS_RAM_BASE_OFFSET       0x00009000
-
-/**
- * Catapult Rx Stats RAM Base Offset Address
- *
- * Exists in LUT memory space.
- * Size is 1024x33 bits;
- * Each Rx function has 64 bytes of space
- */
-#define RX_STATS_RAM_BASE_OFFSET       0x00008000
-
-/* Catapult RXA Memory Access Page Numbers */
-#define RXA0_MEM_BLK_BASE_PG_NUM       0x0000008C
-#define RXA1_MEM_BLK_BASE_PG_NUM       0x0000008D
-
-/**
- * Catapult Multicast Vector Table Base Offset Address
- *
- * Exists in RxA memory space.
- * Organized as 512x65 bit block.
- * However for each entry 16 bytes allocated (power of 2)
- * Total size 512*16 bytes.
- * There are two logical divisions, 256 entries each :
- * a) Entries 0x00 to 0xff (256) -- Approx. MVT
- *    Offset 0x000 to 0xFFF
- * b) Entries 0x100 to 0x1ff (256) -- Exact MVT
- *    Offsets 0x1000 to 0x1FFF
- */
-#define MCAST_APPROX_MVT_BASE_OFFSET   0x00000000
-#define MCAST_EXACT_MVT_BASE_OFFSET    0x00001000
-
-/**
- * Catapult RxQ Translate Table (RIT) Base Offset Address
- *
- * Exists in RxA memory space
- * Total no. of entries 64
- * Each entry is 1 (4 byte) word.
- * 31:12 -- Reserved
- * 11:0  -- Two 6 bit RxQ Ids
- */
-#define FUNCTION_TO_RXQ_TRANSLATE      0x00002000
-
-/* Catapult RxAdm (RAD) Memory Access Page Numbers */
-#define RAD0_MEM_BLK_BASE_PG_NUM       0x00000086
-#define RAD1_MEM_BLK_BASE_PG_NUM       0x00000087
-
-/**
- * Catapult RSS Table Base Offset Address
- *
- * Exists in RAD memory space.
- * Each entry is 352 bits, but aligned on
- * 64 byte (512 bit) boundary. Accessed
- * 4 byte words, the whole entry can be
- * broken into 11 word accesses.
- */
-#define RSS_TABLE_BASE_OFFSET          0x00000800
-
-/**
- * Catapult CPQ Block Page Number
- * This value is written to the page number registers
- * to access the memory associated with the mailboxes.
- */
-#define CPQ_BLK_PG_NUM                 0x00000005
-
-/**
- * Clarification :
- * LL functions are 2 & 3; can HostFn0/HostFn1
- * <-> LPU0/LPU1 memories be used ?
- */
-/**
- * Catapult HostFn0/HostFn1 to LPU0/LPU1 Mbox memory
- * Per catapult_spec.pdf, the offset of the mbox
- * memory is in the register space at an offset of 0x200
- */
-#define CPQ_BLK_REG_MBOX_ADDR          (CPQ_BLK_REG_ADDR + 0x200)
-
-#define HOSTFN_LPU_MBOX                        (CPQ_BLK_REG_MBOX_ADDR + 0x000)
-
-/* Catapult LPU0/LPU1 to HostFn0/HostFn1 Mbox memory */
-#define LPU_HOSTFN_MBOX                        (CPQ_BLK_REG_MBOX_ADDR + 0x080)
-
-/**
- * Catapult HQM Block Page Number
- * This is written to the page number register for
- * the appropriate function to access the memory
- * associated with HQM
- */
-#define HQM0_BLK_PG_NUM                        0x00000096
-#define HQM1_BLK_PG_NUM                        0x00000097
-
-/**
- * Note that TxQ and RxQ entries are interlaced
- * the HQM memory, i.e RXQ0, TXQ0, RXQ1, TXQ1.. etc.
- */
-
-#define HQM_RXTX_Q_RAM_BASE_OFFSET     0x00004000
-
-/**
- * CQ Memory
- * Exists in HQM Memory space
- * Each entry is 16 (4 byte) words of which
- * only 12 words are used for configuration
- * Total 64 entries per HQM memory space
- */
-#define HQM_CQ_RAM_BASE_OFFSET         0x00006000
-
-/**
- * Interrupt Block (IB) Memory
- * Exists in HQM Memory space
- * Each entry is 8 (4 byte) words of which
- * only 5 words are used for configuration
- * Total 128 entries per HQM memory space
- */
-#define HQM_IB_RAM_BASE_OFFSET         0x00001000
-
-/**
- * Index Table (IT) Memory
- * Exists in HQM Memory space
- * Each entry is 1 (4 byte) word which
- * is used for configuration
- * Total 128 entries per HQM memory space
- */
-#define HQM_INDX_TBL_RAM_BASE_OFFSET   0x00002000
-
-/**
- * PSS Block Memory Page Number
- * This is written to the appropriate page number
- * register to access the CPU memory.
- * Also known as the PSS secondary memory (SMEM).
- * Range : 0x180 to 0x1CF
- * See catapult_spec.pdf for details
- */
-#define PSS_BLK_PG_NUM                 0x00000180
-
-/**
- * Offsets of different instances of PSS SMEM
- * 2.5M of continuous 1T memory space : 2 blocks
- * of 1M each (32 pages each, page=32KB) and 4 smaller
- * blocks of 128K each (4 pages each, page=32KB)
- * PSS_LMEM_INST0 is used for firmware download
- */
-#define PSS_LMEM_INST0                 0x00000000
-#define PSS_LMEM_INST1                 0x00100000
-#define PSS_LMEM_INST2                 0x00200000
-#define PSS_LMEM_INST3                 0x00220000
-#define PSS_LMEM_INST4                 0x00240000
-#define PSS_LMEM_INST5                 0x00260000
-
-#define BNA_PCI_REG_CT_ADDRSZ          (0x40000)
-
-#define BNA_GET_PAGE_NUM(_base_page, _offset)   \
-       ((_base_page) + ((_offset) >> 15))
-
-#define BNA_GET_PAGE_OFFSET(_offset)    \
-       ((_offset) & 0x7fff)
-
-#define BNA_GET_MEM_BASE_ADDR(_bar0, _base_offset)     \
-       ((_bar0) + HW_BLK_HOST_MEM_ADDR         \
-         + BNA_GET_PAGE_OFFSET((_base_offset)))
-
-#define BNA_GET_VLAN_MEM_ENTRY_ADDR(_bar0, _fn_id, _vlan_id)\
-       (_bar0 + (HW_BLK_HOST_MEM_ADDR)  \
-       + (BNA_GET_PAGE_OFFSET(VLAN_RAM_BASE_OFFSET))   \
-       + (((_fn_id) & 0x3f) << 9)        \
-       + (((_vlan_id) & 0xfe0) >> 3))
-
-/**
- *
- *  Interrupt related bits, flags and macros
- *
- */
-
-#define __LPU02HOST_MBOX0_STATUS_BITS 0x00100000
-#define __LPU12HOST_MBOX0_STATUS_BITS 0x00200000
-#define __LPU02HOST_MBOX1_STATUS_BITS 0x00400000
-#define __LPU12HOST_MBOX1_STATUS_BITS 0x00800000
-
-#define __LPU02HOST_MBOX0_MASK_BITS    0x00100000
-#define __LPU12HOST_MBOX0_MASK_BITS    0x00200000
-#define __LPU02HOST_MBOX1_MASK_BITS    0x00400000
-#define __LPU12HOST_MBOX1_MASK_BITS    0x00800000
-
-#define __LPU2HOST_MBOX_MASK_BITS                       \
-       (__LPU02HOST_MBOX0_MASK_BITS | __LPU02HOST_MBOX1_MASK_BITS |    \
-         __LPU12HOST_MBOX0_MASK_BITS | __LPU12HOST_MBOX1_MASK_BITS)
-
-#define __LPU2HOST_IB_STATUS_BITS      0x0000ffff
-
-#define BNA_IS_LPU0_MBOX_INTR(_intr_status) \
-       ((_intr_status) & (__LPU02HOST_MBOX0_STATUS_BITS | \
-                       __LPU02HOST_MBOX1_STATUS_BITS))
-
-#define BNA_IS_LPU1_MBOX_INTR(_intr_status) \
-       ((_intr_status) & (__LPU12HOST_MBOX0_STATUS_BITS | \
-               __LPU12HOST_MBOX1_STATUS_BITS))
-
-#define BNA_IS_MBOX_INTR(_intr_status)         \
-       ((_intr_status) &                       \
-       (__LPU02HOST_MBOX0_STATUS_BITS |        \
-        __LPU02HOST_MBOX1_STATUS_BITS |        \
-        __LPU12HOST_MBOX0_STATUS_BITS |        \
-        __LPU12HOST_MBOX1_STATUS_BITS))
-
-#define __EMC_ERROR_STATUS_BITS                0x00010000
-#define __LPU0_ERROR_STATUS_BITS       0x00020000
-#define __LPU1_ERROR_STATUS_BITS       0x00040000
-#define __PSS_ERROR_STATUS_BITS                0x00080000
-
-#define __HALT_STATUS_BITS             0x01000000
-
-#define __EMC_ERROR_MASK_BITS          0x00010000
-#define __LPU0_ERROR_MASK_BITS         0x00020000
-#define __LPU1_ERROR_MASK_BITS         0x00040000
-#define __PSS_ERROR_MASK_BITS          0x00080000
-
-#define __HALT_MASK_BITS               0x01000000
-
-#define __ERROR_MASK_BITS              \
-       (__EMC_ERROR_MASK_BITS | __LPU0_ERROR_MASK_BITS | \
-         __LPU1_ERROR_MASK_BITS | __PSS_ERROR_MASK_BITS | \
-         __HALT_MASK_BITS)
-
-#define BNA_IS_ERR_INTR(_intr_status)  \
-       ((_intr_status) &               \
-       (__EMC_ERROR_STATUS_BITS |      \
-        __LPU0_ERROR_STATUS_BITS |     \
-        __LPU1_ERROR_STATUS_BITS |     \
-        __PSS_ERROR_STATUS_BITS  |     \
-        __HALT_STATUS_BITS))
-
-#define BNA_IS_MBOX_ERR_INTR(_intr_status)     \
-       (BNA_IS_MBOX_INTR((_intr_status)) |     \
-        BNA_IS_ERR_INTR((_intr_status)))
-
-#define BNA_IS_INTX_DATA_INTR(_intr_status)    \
-       ((_intr_status) & __LPU2HOST_IB_STATUS_BITS)
-
-#define BNA_INTR_STATUS_MBOX_CLR(_intr_status)                 \
-do {                                                           \
-       (_intr_status) &= ~(__LPU02HOST_MBOX0_STATUS_BITS |     \
-                       __LPU02HOST_MBOX1_STATUS_BITS |         \
-                       __LPU12HOST_MBOX0_STATUS_BITS |         \
-                       __LPU12HOST_MBOX1_STATUS_BITS);         \
-} while (0)
-
-#define BNA_INTR_STATUS_ERR_CLR(_intr_status)          \
-do {                                                   \
-       (_intr_status) &= ~(__EMC_ERROR_STATUS_BITS |   \
-               __LPU0_ERROR_STATUS_BITS |              \
-               __LPU1_ERROR_STATUS_BITS |              \
-               __PSS_ERROR_STATUS_BITS  |              \
-               __HALT_STATUS_BITS);                    \
-} while (0)
-
-#define bna_intx_disable(_bna, _cur_mask)              \
-{                                                      \
-       (_cur_mask) = readl((_bna)->regs.fn_int_mask);\
-       writel(0xffffffff, (_bna)->regs.fn_int_mask);\
-}
-
-#define bna_intx_enable(bna, new_mask)                 \
-       writel((new_mask), (bna)->regs.fn_int_mask)
-
-#define bna_mbox_intr_disable(bna)             \
-       writel((readl((bna)->regs.fn_int_mask) | \
-            (__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \
-            (bna)->regs.fn_int_mask)
-
-#define bna_mbox_intr_enable(bna)              \
-       writel((readl((bna)->regs.fn_int_mask) & \
-            ~(__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \
-            (bna)->regs.fn_int_mask)
-
-#define bna_intr_status_get(_bna, _status)                             \
-{                                                                      \
-       (_status) = readl((_bna)->regs.fn_int_status);          \
-       if ((_status)) {                                                \
-               writel((_status) & ~(__LPU02HOST_MBOX0_STATUS_BITS |\
-                                         __LPU02HOST_MBOX1_STATUS_BITS |\
-                                         __LPU12HOST_MBOX0_STATUS_BITS |\
-                                         __LPU12HOST_MBOX1_STATUS_BITS), \
-                             (_bna)->regs.fn_int_status);\
-       }                                                               \
-}
-
-#define bna_intr_status_get_no_clr(_bna, _status)              \
-       (_status) = readl((_bna)->regs.fn_int_status)
-
-#define bna_intr_mask_get(bna, mask)           \
-       (*mask) = readl((bna)->regs.fn_int_mask)
-
-#define bna_intr_ack(bna, intr_bmap)           \
-       writel((intr_bmap), (bna)->regs.fn_int_status)
-
-#define bna_ib_intx_disable(bna, ib_id)                \
-       writel(readl((bna)->regs.fn_int_mask) | \
-           (1 << (ib_id)), \
-           (bna)->regs.fn_int_mask)
-
-#define bna_ib_intx_enable(bna, ib_id)         \
-       writel(readl((bna)->regs.fn_int_mask) & \
-           ~(1 << (ib_id)), \
-           (bna)->regs.fn_int_mask)
-
-#define bna_mbox_msix_idx_set(_device) \
-do {\
-       writel(((_device)->vector & 0x000001FF), \
-               (_device)->bna->pcidev.pci_bar_kva + \
-               reg_offset[(_device)->bna->pcidev.pci_func].msix_idx);\
-} while (0)
-
-/**
- *
- * TxQ, RxQ, CQ related bits, offsets, macros
- *
- */
-
-#define        BNA_Q_IDLE_STATE        0x00008001
-
-#define BNA_GET_DOORBELL_BASE_ADDR(_bar0)      \
-       ((_bar0) + HQM_DOORBELL_BLK_BASE_ADDR)
-
-#define BNA_GET_DOORBELL_ENTRY_OFFSET(_entry)          \
-       ((HQM_DOORBELL_BLK_BASE_ADDR)           \
-       + (_entry << 7))
-
-#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
-               (0x80000000 | ((_timeout) << 16) | (_events))
-
-#define BNA_DOORBELL_IB_INT_DISABLE            (0x40000000)
-
-/* TxQ Entry Opcodes */
-#define BNA_TXQ_WI_SEND                        (0x402) /* Single Frame Transmission */
-#define BNA_TXQ_WI_SEND_LSO            (0x403) /* Multi-Frame Transmission */
-#define BNA_TXQ_WI_EXTENSION           (0x104) /* Extension WI */
-
-/* TxQ Entry Control Flags */
-#define BNA_TXQ_WI_CF_FCOE_CRC         (1 << 8)
-#define BNA_TXQ_WI_CF_IPID_MODE                (1 << 5)
-#define BNA_TXQ_WI_CF_INS_PRIO         (1 << 4)
-#define BNA_TXQ_WI_CF_INS_VLAN         (1 << 3)
-#define BNA_TXQ_WI_CF_UDP_CKSUM                (1 << 2)
-#define BNA_TXQ_WI_CF_TCP_CKSUM                (1 << 1)
-#define BNA_TXQ_WI_CF_IP_CKSUM         (1 << 0)
-
-#define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \
-               (((_hdr_size) << 10) | ((_offset) & 0x3FF))
-
-/*
- * Completion Q defines
- */
-/* CQ Entry Flags */
-#define        BNA_CQ_EF_MAC_ERROR     (1 <<  0)
-#define        BNA_CQ_EF_FCS_ERROR     (1 <<  1)
-#define        BNA_CQ_EF_TOO_LONG      (1 <<  2)
-#define        BNA_CQ_EF_FC_CRC_OK     (1 <<  3)
-
-#define        BNA_CQ_EF_RSVD1         (1 <<  4)
-#define        BNA_CQ_EF_L4_CKSUM_OK   (1 <<  5)
-#define        BNA_CQ_EF_L3_CKSUM_OK   (1 <<  6)
-#define        BNA_CQ_EF_HDS_HEADER    (1 <<  7)
-
-#define        BNA_CQ_EF_UDP           (1 <<  8)
-#define        BNA_CQ_EF_TCP           (1 <<  9)
-#define        BNA_CQ_EF_IP_OPTIONS    (1 << 10)
-#define        BNA_CQ_EF_IPV6          (1 << 11)
-
-#define        BNA_CQ_EF_IPV4          (1 << 12)
-#define        BNA_CQ_EF_VLAN          (1 << 13)
-#define        BNA_CQ_EF_RSS           (1 << 14)
-#define        BNA_CQ_EF_RSVD2         (1 << 15)
-
-#define        BNA_CQ_EF_MCAST_MATCH   (1 << 16)
-#define        BNA_CQ_EF_MCAST         (1 << 17)
-#define BNA_CQ_EF_BCAST                (1 << 18)
-#define        BNA_CQ_EF_REMOTE        (1 << 19)
-
-#define        BNA_CQ_EF_LOCAL         (1 << 20)
-
-/**
- *
- * Data structures
- *
- */
-
-enum txf_flags {
-       BFI_TXF_CF_ENABLE               = 1 << 0,
-       BFI_TXF_CF_VLAN_FILTER          = 1 << 8,
-       BFI_TXF_CF_VLAN_ADMIT           = 1 << 9,
-       BFI_TXF_CF_VLAN_INSERT          = 1 << 10,
-       BFI_TXF_CF_RSVD1                = 1 << 11,
-       BFI_TXF_CF_MAC_SA_CHECK         = 1 << 12,
-       BFI_TXF_CF_VLAN_WI_BASED        = 1 << 13,
-       BFI_TXF_CF_VSWITCH_MCAST        = 1 << 14,
-       BFI_TXF_CF_VSWITCH_UCAST        = 1 << 15,
-       BFI_TXF_CF_RSVD2                = 0x7F << 1
-};
-
-enum ib_flags {
-       BFI_IB_CF_MASTER_ENABLE         = (1 << 0),
-       BFI_IB_CF_MSIX_MODE             = (1 << 1),
-       BFI_IB_CF_COALESCING_MODE       = (1 << 2),
-       BFI_IB_CF_INTER_PKT_ENABLE      = (1 << 3),
-       BFI_IB_CF_INT_ENABLE            = (1 << 4),
-       BFI_IB_CF_INTER_PKT_DMA         = (1 << 5),
-       BFI_IB_CF_ACK_PENDING           = (1 << 6),
-       BFI_IB_CF_RESERVED1             = (1 << 7)
-};
-
-enum rss_hash_type {
-       BFI_RSS_T_V4_TCP                = (1 << 11),
-       BFI_RSS_T_V4_IP                 = (1 << 10),
-       BFI_RSS_T_V6_TCP                = (1 <<  9),
-       BFI_RSS_T_V6_IP                 = (1 <<  8)
-};
-enum hds_header_type {
-       BNA_HDS_T_V4_TCP        = (1 << 11),
-       BNA_HDS_T_V4_UDP        = (1 << 10),
-       BNA_HDS_T_V6_TCP        = (1 << 9),
-       BNA_HDS_T_V6_UDP        = (1 << 8),
-       BNA_HDS_FORCED          = (1 << 7),
-};
-enum rxf_flags {
-       BNA_RXF_CF_SM_LG_RXQ                    = (1 << 15),
-       BNA_RXF_CF_DEFAULT_VLAN                 = (1 << 14),
-       BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE      = (1 << 13),
-       BNA_RXF_CF_VLAN_STRIP                   = (1 << 12),
-       BNA_RXF_CF_RSS_ENABLE                   = (1 <<  8)
-};
-struct bna_chip_regs_offset {
-       u32 page_addr;
-       u32 fn_int_status;
-       u32 fn_int_mask;
-       u32 msix_idx;
-};
-
-struct bna_chip_regs {
-       void __iomem *page_addr;
-       void __iomem *fn_int_status;
-       void __iomem *fn_int_mask;
-};
-
-struct bna_txq_mem {
-       u32 pg_tbl_addr_lo;
-       u32 pg_tbl_addr_hi;
-       u32 cur_q_entry_lo;
-       u32 cur_q_entry_hi;
-       u32 reserved1;
-       u32 reserved2;
-       u32 pg_cnt_n_prd_ptr;   /* 31:16->total page count */
-                                       /* 15:0 ->producer pointer (index?) */
-       u32 entry_n_pg_size;    /* 31:16->entry size */
-                                       /* 15:0 ->page size */
-       u32 int_blk_n_cns_ptr;  /* 31:24->Int Blk Id;  */
-                                       /* 23:16->Int Blk Offset */
-                                       /* 15:0 ->consumer pointer(index?) */
-       u32 cns_ptr2_n_q_state; /* 31:16->cons. ptr 2; 15:0-> Q state */
-       u32 nxt_qid_n_fid_n_pri;        /* 17:10->next */
-                                       /* QId;9:3->FID;2:0->Priority */
-       u32 wvc_n_cquota_n_rquota; /* 31:24->WI Vector Count; */
-                                       /* 23:12->Cfg Quota; */
-                                       /* 11:0 ->Run Quota */
-       u32 reserved3[4];
-};
-
-struct bna_rxq_mem {
-       u32 pg_tbl_addr_lo;
-       u32 pg_tbl_addr_hi;
-       u32 cur_q_entry_lo;
-       u32 cur_q_entry_hi;
-       u32 reserved1;
-       u32 reserved2;
-       u32 pg_cnt_n_prd_ptr;   /* 31:16->total page count */
-                                       /* 15:0 ->producer pointer (index?) */
-       u32 entry_n_pg_size;    /* 31:16->entry size */
-                                       /* 15:0 ->page size */
-       u32 sg_n_cq_n_cns_ptr;  /* 31:28->reserved; 27:24->sg count */
-                                       /* 23:16->CQ; */
-                                       /* 15:0->consumer pointer(index?) */
-       u32 buf_sz_n_q_state;   /* 31:16->buffer size; 15:0-> Q state */
-       u32 next_qid;           /* 17:10->next QId */
-       u32 reserved3;
-       u32 reserved4[4];
-};
-
-struct bna_rxtx_q_mem {
-       struct bna_rxq_mem rxq;
-       struct bna_txq_mem txq;
-};
-
-struct bna_cq_mem {
-       u32 pg_tbl_addr_lo;
-       u32 pg_tbl_addr_hi;
-       u32 cur_q_entry_lo;
-       u32 cur_q_entry_hi;
-
-       u32 reserved1;
-       u32 reserved2;
-       u32 pg_cnt_n_prd_ptr;   /* 31:16->total page count */
-                                       /* 15:0 ->producer pointer (index?) */
-       u32 entry_n_pg_size;    /* 31:16->entry size */
-                                       /* 15:0 ->page size */
-       u32 int_blk_n_cns_ptr;  /* 31:24->Int Blk Id; */
-                                       /* 23:16->Int Blk Offset */
-                                       /* 15:0 ->consumer pointer(index?) */
-       u32 q_state;            /* 31:16->reserved; 15:0-> Q state */
-       u32 reserved3[2];
-       u32 reserved4[4];
-};
-
-struct bna_ib_blk_mem {
-       u32 host_addr_lo;
-       u32 host_addr_hi;
-       u32 clsc_n_ctrl_n_msix; /* 31:24->coalescing; */
-                                       /* 23:16->coalescing cfg; */
-                                       /* 15:8 ->control; */
-                                       /* 7:0 ->msix; */
-       u32 ipkt_n_ent_n_idxof;
-       u32 ipkt_cnt_cfg_n_unacked;
-
-       u32 reserved[3];
-};
-
-struct bna_idx_tbl_mem {
-       u32 idx;          /* !< 31:16->res;15:0->idx; */
-};
-
-struct bna_doorbell_qset {
-       u32 rxq[0x20 >> 2];
-       u32 txq[0x20 >> 2];
-       u32 ib0[0x20 >> 2];
-       u32 ib1[0x20 >> 2];
-};
-
-struct bna_rx_fndb_ram {
-       u32 rss_prop;
-       u32 size_routing_props;
-       u32 rit_hds_mcastq;
-       u32 control_flags;
-};
-
-struct bna_tx_fndb_ram {
-       u32 vlan_n_ctrl_flags;
-};
-
-/**
- * @brief
- *  Structure which maps to RxFn Indirection Table (RIT)
- *  Size : 1 word
- *  See catapult_spec.pdf, RxA for details
- */
-struct bna_rit_mem {
-       u32 rxq_ids;    /* !< 31:12->res;11:0->two 6 bit RxQ Ids */
-};
-
-/**
- * @brief
- *  Structure which maps to RSS Table entry
- *  Size : 16 words
- *  See catapult_spec.pdf, RAD for details
- */
-struct bna_rss_mem {
-       /*
-        * 31:12-> res
-        * 11:8 -> protocol type
-        *  7:0 -> hash index
-        */
-       u32 type_n_hash;
-       u32 hash_key[10];  /* !< 40 byte Toeplitz hash key */
-       u32 reserved[5];
-};
-
-/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */
-struct bna_dma_addr {
-       u32             msb;
-       u32             lsb;
-};
-
-struct bna_txq_wi_vector {
-       u16             reserved;
-       u16             length;         /* Only 14 LSB are valid */
-       struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */
-};
-
-typedef u16 bna_txq_wi_opcode_t;
-
-typedef u16 bna_txq_wi_ctrl_flag_t;
-
-/**
- *  TxQ Entry Structure
- *
- *  BEWARE:  Load values into this structure with correct endianess.
- */
-struct bna_txq_entry {
-       union {
-               struct {
-                       u8 reserved;
-                       u8 num_vectors; /* number of vectors present */
-                       bna_txq_wi_opcode_t opcode; /* Either */
-                                                   /* BNA_TXQ_WI_SEND or */
-                                                   /* BNA_TXQ_WI_SEND_LSO */
-                       bna_txq_wi_ctrl_flag_t flags; /* OR of all the flags */
-                       u16 l4_hdr_size_n_offset;
-                       u16 vlan_tag;
-                       u16 lso_mss;    /* Only 14 LSB are valid */
-                       u32 frame_length;       /* Only 24 LSB are valid */
-               } wi;
-
-               struct {
-                       u16 reserved;
-                       bna_txq_wi_opcode_t opcode; /* Must be */
-                                                   /* BNA_TXQ_WI_EXTENSION */
-                       u32 reserved2[3];       /* Place holder for */
-                                               /* removed vector (12 bytes) */
-               } wi_ext;
-       } hdr;
-       struct bna_txq_wi_vector vector[4];
-};
-#define wi_hdr         hdr.wi
-#define wi_ext_hdr  hdr.wi_ext
-
-/* RxQ Entry Structure */
-struct bna_rxq_entry {         /* Rx-Buffer */
-       struct bna_dma_addr host_addr; /* Rx-Buffer DMA address */
-};
-
-typedef u32 bna_cq_e_flag_t;
-
-/* CQ Entry Structure */
-struct bna_cq_entry {
-       bna_cq_e_flag_t flags;
-       u16 vlan_tag;
-       u16 length;
-       u32 rss_hash;
-       u8 valid;
-       u8 reserved1;
-       u8 reserved2;
-       u8 rxq_id;
-};
-
-#endif /* __BNA_HW_H__ */
diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c
deleted file mode 100644 (file)
index f0983c8..0000000
+++ /dev/null
@@ -1,4185 +0,0 @@
-/*
- * Linux network driver for Brocade Converged Network Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 as
- * published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
-  */
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- */
-#include "bna.h"
-#include "bfa_cs.h"
-#include "bfi.h"
-
-/**
- * IB
- */
-#define bna_ib_find_free_ibidx(_mask, _pos)\
-do {\
-       (_pos) = 0;\
-       while (((_pos) < (BFI_IBIDX_MAX_SEGSIZE)) &&\
-               ((1 << (_pos)) & (_mask)))\
-               (_pos)++;\
-} while (0)
-
-#define bna_ib_count_ibidx(_mask, _count)\
-do {\
-       int pos = 0;\
-       (_count) = 0;\
-       while (pos < (BFI_IBIDX_MAX_SEGSIZE)) {\
-               if ((1 << pos) & (_mask))\
-                       (_count) = pos + 1;\
-               pos++;\
-       } \
-} while (0)
-
-#define bna_ib_select_segpool(_count, _q_idx)\
-do {\
-       int i;\
-       (_q_idx) = -1;\
-       for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {\
-               if ((_count <= ibidx_pool[i].pool_entry_size)) {\
-                       (_q_idx) = i;\
-                       break;\
-               } \
-       } \
-} while (0)
-
-struct bna_ibidx_pool {
-       int     pool_size;
-       int     pool_entry_size;
-};
-init_ibidx_pool(ibidx_pool);
-
-static struct bna_intr *
-bna_intr_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type,
-               int vector)
-{
-       struct bna_intr *intr;
-       struct list_head *qe;
-
-       list_for_each(qe, &ib_mod->intr_active_q) {
-               intr = (struct bna_intr *)qe;
-
-               if ((intr->intr_type == intr_type) &&
-                       (intr->vector == vector)) {
-                       intr->ref_count++;
-                       return intr;
-               }
-       }
-
-       if (list_empty(&ib_mod->intr_free_q))
-               return NULL;
-
-       bfa_q_deq(&ib_mod->intr_free_q, &intr);
-       bfa_q_qe_init(&intr->qe);
-
-       intr->ref_count = 1;
-       intr->intr_type = intr_type;
-       intr->vector = vector;
-
-       list_add_tail(&intr->qe, &ib_mod->intr_active_q);
-
-       return intr;
-}
-
-static void
-bna_intr_put(struct bna_ib_mod *ib_mod,
-               struct bna_intr *intr)
-{
-       intr->ref_count--;
-
-       if (intr->ref_count == 0) {
-               intr->ib = NULL;
-               list_del(&intr->qe);
-               bfa_q_qe_init(&intr->qe);
-               list_add_tail(&intr->qe, &ib_mod->intr_free_q);
-       }
-}
-
-void
-bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
-               struct bna_res_info *res_info)
-{
-       int i;
-       int j;
-       int count;
-       u8 offset;
-       struct bna_doorbell_qset *qset;
-       unsigned long off;
-
-       ib_mod->bna = bna;
-
-       ib_mod->ib = (struct bna_ib *)
-               res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mdl[0].kva;
-       ib_mod->intr = (struct bna_intr *)
-               res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mdl[0].kva;
-       ib_mod->idx_seg = (struct bna_ibidx_seg *)
-               res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mdl[0].kva;
-
-       INIT_LIST_HEAD(&ib_mod->ib_free_q);
-       INIT_LIST_HEAD(&ib_mod->intr_free_q);
-       INIT_LIST_HEAD(&ib_mod->intr_active_q);
-
-       for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++)
-               INIT_LIST_HEAD(&ib_mod->ibidx_seg_pool[i]);
-
-       for (i = 0; i < BFI_MAX_IB; i++) {
-               ib_mod->ib[i].ib_id = i;
-
-               ib_mod->ib[i].ib_seg_host_addr_kva =
-               res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
-               ib_mod->ib[i].ib_seg_host_addr.lsb =
-               res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
-               ib_mod->ib[i].ib_seg_host_addr.msb =
-               res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
-
-               qset = (struct bna_doorbell_qset *)0;
-               off = (unsigned long)(&qset[i >> 1].ib0[(i & 0x1)
-                                       * (0x20 >> 2)]);
-               ib_mod->ib[i].door_bell.doorbell_addr = off +
-                       BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
-
-               bfa_q_qe_init(&ib_mod->ib[i].qe);
-               list_add_tail(&ib_mod->ib[i].qe, &ib_mod->ib_free_q);
-
-               bfa_q_qe_init(&ib_mod->intr[i].qe);
-               list_add_tail(&ib_mod->intr[i].qe, &ib_mod->intr_free_q);
-       }
-
-       count = 0;
-       offset = 0;
-       for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
-               for (j = 0; j < ibidx_pool[i].pool_size; j++) {
-                       bfa_q_qe_init(&ib_mod->idx_seg[count]);
-                       ib_mod->idx_seg[count].ib_seg_size =
-                                       ibidx_pool[i].pool_entry_size;
-                       ib_mod->idx_seg[count].ib_idx_tbl_offset = offset;
-                       list_add_tail(&ib_mod->idx_seg[count].qe,
-                               &ib_mod->ibidx_seg_pool[i]);
-                       count++;
-                       offset += ibidx_pool[i].pool_entry_size;
-               }
-       }
-}
-
-void
-bna_ib_mod_uninit(struct bna_ib_mod *ib_mod)
-{
-       int i;
-       int j;
-       struct list_head *qe;
-
-       i = 0;
-       list_for_each(qe, &ib_mod->ib_free_q)
-               i++;
-
-       i = 0;
-       list_for_each(qe, &ib_mod->intr_free_q)
-               i++;
-
-       for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
-               j = 0;
-               list_for_each(qe, &ib_mod->ibidx_seg_pool[i])
-                       j++;
-       }
-
-       ib_mod->bna = NULL;
-}
-
-static struct bna_ib *
-bna_ib_get(struct bna_ib_mod *ib_mod,
-               enum bna_intr_type intr_type,
-               int vector)
-{
-       struct bna_ib *ib;
-       struct bna_intr *intr;
-
-       if (intr_type == BNA_INTR_T_INTX)
-               vector = (1 << vector);
-
-       intr = bna_intr_get(ib_mod, intr_type, vector);
-       if (intr == NULL)
-               return NULL;
-
-       if (intr->ib) {
-               if (intr->ib->ref_count == BFI_IBIDX_MAX_SEGSIZE) {
-                       bna_intr_put(ib_mod, intr);
-                       return NULL;
-               }
-               intr->ib->ref_count++;
-               return intr->ib;
-       }
-
-       if (list_empty(&ib_mod->ib_free_q)) {
-               bna_intr_put(ib_mod, intr);
-               return NULL;
-       }
-
-       bfa_q_deq(&ib_mod->ib_free_q, &ib);
-       bfa_q_qe_init(&ib->qe);
-
-       ib->ref_count = 1;
-       ib->start_count = 0;
-       ib->idx_mask = 0;
-
-       ib->intr = intr;
-       ib->idx_seg = NULL;
-       intr->ib = ib;
-
-       ib->bna = ib_mod->bna;
-
-       return ib;
-}
-
-static void
-bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib)
-{
-       bna_intr_put(ib_mod, ib->intr);
-
-       ib->ref_count--;
-
-       if (ib->ref_count == 0) {
-               ib->intr = NULL;
-               ib->bna = NULL;
-               list_add_tail(&ib->qe, &ib_mod->ib_free_q);
-       }
-}
-
-/* Returns index offset - starting from 0 */
-static int
-bna_ib_reserve_idx(struct bna_ib *ib)
-{
-       struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
-       struct bna_ibidx_seg *idx_seg;
-       int idx;
-       int num_idx;
-       int q_idx;
-
-       /* Find the first free index position */
-       bna_ib_find_free_ibidx(ib->idx_mask, idx);
-       if (idx == BFI_IBIDX_MAX_SEGSIZE)
-               return -1;
-
-       /*
-        * Calculate the total number of indexes held by this IB,
-        * including the index newly reserved above.
-        */
-       bna_ib_count_ibidx((ib->idx_mask | (1 << idx)), num_idx);
-
-       /* See if there is a free space in the index segment held by this IB */
-       if (ib->idx_seg && (num_idx <= ib->idx_seg->ib_seg_size)) {
-               ib->idx_mask |= (1 << idx);
-               return idx;
-       }
-
-       if (ib->start_count)
-               return -1;
-
-       /* Allocate a new segment */
-       bna_ib_select_segpool(num_idx, q_idx);
-       while (1) {
-               if (q_idx == BFI_IBIDX_TOTAL_POOLS)
-                       return -1;
-               if (!list_empty(&ib_mod->ibidx_seg_pool[q_idx]))
-                       break;
-               q_idx++;
-       }
-       bfa_q_deq(&ib_mod->ibidx_seg_pool[q_idx], &idx_seg);
-       bfa_q_qe_init(&idx_seg->qe);
-
-       /* Free the old segment */
-       if (ib->idx_seg) {
-               bna_ib_select_segpool(ib->idx_seg->ib_seg_size, q_idx);
-               list_add_tail(&ib->idx_seg->qe, &ib_mod->ibidx_seg_pool[q_idx]);
-       }
-
-       ib->idx_seg = idx_seg;
-
-       ib->idx_mask |= (1 << idx);
-
-       return idx;
-}
-
-static void
-bna_ib_release_idx(struct bna_ib *ib, int idx)
-{
-       struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
-       struct bna_ibidx_seg *idx_seg;
-       int num_idx;
-       int cur_q_idx;
-       int new_q_idx;
-
-       ib->idx_mask &= ~(1 << idx);
-
-       if (ib->start_count)
-               return;
-
-       bna_ib_count_ibidx(ib->idx_mask, num_idx);
-
-       /*
-        * Free the segment, if there are no more indexes in the segment
-        * held by this IB
-        */
-       if (!num_idx) {
-               bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
-               list_add_tail(&ib->idx_seg->qe,
-                       &ib_mod->ibidx_seg_pool[cur_q_idx]);
-               ib->idx_seg = NULL;
-               return;
-       }
-
-       /* See if we can move to a smaller segment */
-       bna_ib_select_segpool(num_idx, new_q_idx);
-       bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
-       while (new_q_idx < cur_q_idx) {
-               if (!list_empty(&ib_mod->ibidx_seg_pool[new_q_idx]))
-                       break;
-               new_q_idx++;
-       }
-       if (new_q_idx < cur_q_idx) {
-               /* Select the new smaller segment */
-               bfa_q_deq(&ib_mod->ibidx_seg_pool[new_q_idx], &idx_seg);
-               bfa_q_qe_init(&idx_seg->qe);
-               /* Free the old segment */
-               list_add_tail(&ib->idx_seg->qe,
-                       &ib_mod->ibidx_seg_pool[cur_q_idx]);
-               ib->idx_seg = idx_seg;
-       }
-}
-
-static int
-bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config)
-{
-       if (ib->start_count)
-               return -1;
-
-       ib->ib_config.coalescing_timeo = ib_config->coalescing_timeo;
-       ib->ib_config.interpkt_timeo = ib_config->interpkt_timeo;
-       ib->ib_config.interpkt_count = ib_config->interpkt_count;
-       ib->ib_config.ctrl_flags = ib_config->ctrl_flags;
-
-       ib->ib_config.ctrl_flags |= BFI_IB_CF_MASTER_ENABLE;
-       if (ib->intr->intr_type == BNA_INTR_T_MSIX)
-               ib->ib_config.ctrl_flags |= BFI_IB_CF_MSIX_MODE;
-
-       return 0;
-}
-
-static void
-bna_ib_start(struct bna_ib *ib)
-{
-       struct bna_ib_blk_mem ib_cfg;
-       struct bna_ib_blk_mem *ib_mem;
-       u32 pg_num;
-       u32 intx_mask;
-       int i;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       ib->start_count++;
-
-       if (ib->start_count > 1)
-               return;
-
-       ib_cfg.host_addr_lo = (u32)(ib->ib_seg_host_addr.lsb);
-       ib_cfg.host_addr_hi = (u32)(ib->ib_seg_host_addr.msb);
-
-       ib_cfg.clsc_n_ctrl_n_msix = (((u32)
-                                    ib->ib_config.coalescing_timeo << 16) |
-                               ((u32)ib->ib_config.ctrl_flags << 8) |
-                               (ib->intr->vector));
-       ib_cfg.ipkt_n_ent_n_idxof =
-                               ((u32)
-                                (ib->ib_config.interpkt_timeo & 0xf) << 16) |
-                               ((u32)ib->idx_seg->ib_seg_size << 8) |
-                               (ib->idx_seg->ib_idx_tbl_offset);
-       ib_cfg.ipkt_cnt_cfg_n_unacked = ((u32)
-                                        ib->ib_config.interpkt_count << 24);
-
-       pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
-                               HQM_IB_RAM_BASE_OFFSET);
-       writel(pg_num, ib->bna->regs.page_addr);
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
-                                       HQM_IB_RAM_BASE_OFFSET);
-
-       ib_mem = (struct bna_ib_blk_mem *)0;
-       off = (unsigned long)&ib_mem[ib->ib_id].host_addr_lo;
-       writel(htonl(ib_cfg.host_addr_lo), base_addr + off);
-
-       off = (unsigned long)&ib_mem[ib->ib_id].host_addr_hi;
-       writel(htonl(ib_cfg.host_addr_hi), base_addr + off);
-
-       off = (unsigned long)&ib_mem[ib->ib_id].clsc_n_ctrl_n_msix;
-       writel(ib_cfg.clsc_n_ctrl_n_msix, base_addr + off);
-
-       off = (unsigned long)&ib_mem[ib->ib_id].ipkt_n_ent_n_idxof;
-       writel(ib_cfg.ipkt_n_ent_n_idxof, base_addr + off);
-
-       off = (unsigned long)&ib_mem[ib->ib_id].ipkt_cnt_cfg_n_unacked;
-       writel(ib_cfg.ipkt_cnt_cfg_n_unacked, base_addr + off);
-
-       ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
-                               (u32)ib->ib_config.coalescing_timeo, 0);
-
-       pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
-                               HQM_INDX_TBL_RAM_BASE_OFFSET);
-       writel(pg_num, ib->bna->regs.page_addr);
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
-                                       HQM_INDX_TBL_RAM_BASE_OFFSET);
-       for (i = 0; i < ib->idx_seg->ib_seg_size; i++) {
-               off = (unsigned long)
-               ((ib->idx_seg->ib_idx_tbl_offset + i) * BFI_IBIDX_SIZE);
-               writel(0, base_addr + off);
-       }
-
-       if (ib->intr->intr_type == BNA_INTR_T_INTX) {
-               bna_intx_disable(ib->bna, intx_mask);
-               intx_mask &= ~(ib->intr->vector);
-               bna_intx_enable(ib->bna, intx_mask);
-       }
-}
-
-static void
-bna_ib_stop(struct bna_ib *ib)
-{
-       u32 intx_mask;
-
-       ib->start_count--;
-
-       if (ib->start_count == 0) {
-               writel(BNA_DOORBELL_IB_INT_DISABLE,
-                               ib->door_bell.doorbell_addr);
-               if (ib->intr->intr_type == BNA_INTR_T_INTX) {
-                       bna_intx_disable(ib->bna, intx_mask);
-                       intx_mask |= (ib->intr->vector);
-                       bna_intx_enable(ib->bna, intx_mask);
-               }
-       }
-}
-
-static void
-bna_ib_fail(struct bna_ib *ib)
-{
-       ib->start_count = 0;
-}
-
-/**
- * RXF
- */
-static void rxf_enable(struct bna_rxf *rxf);
-static void rxf_disable(struct bna_rxf *rxf);
-static void __rxf_config_set(struct bna_rxf *rxf);
-static void __rxf_rit_set(struct bna_rxf *rxf);
-static void __bna_rxf_stat_clr(struct bna_rxf *rxf);
-static int rxf_process_packet_filter(struct bna_rxf *rxf);
-static int rxf_clear_packet_filter(struct bna_rxf *rxf);
-static void rxf_reset_packet_filter(struct bna_rxf *rxf);
-static void rxf_cb_enabled(void *arg, int status);
-static void rxf_cb_disabled(void *arg, int status);
-static void bna_rxf_cb_stats_cleared(void *arg, int status);
-static void __rxf_enable(struct bna_rxf *rxf);
-static void __rxf_disable(struct bna_rxf *rxf);
-
-bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, start_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, cam_fltr_mod_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, cam_fltr_clr_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, stop_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, pause_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, resume_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-bfa_fsm_state_decl(bna_rxf, stat_clr_wait, struct bna_rxf,
-                       enum bna_rxf_event);
-
-static struct bfa_sm_table rxf_sm_table[] = {
-       {BFA_SM(bna_rxf_sm_stopped), BNA_RXF_STOPPED},
-       {BFA_SM(bna_rxf_sm_start_wait), BNA_RXF_START_WAIT},
-       {BFA_SM(bna_rxf_sm_cam_fltr_mod_wait), BNA_RXF_CAM_FLTR_MOD_WAIT},
-       {BFA_SM(bna_rxf_sm_started), BNA_RXF_STARTED},
-       {BFA_SM(bna_rxf_sm_cam_fltr_clr_wait), BNA_RXF_CAM_FLTR_CLR_WAIT},
-       {BFA_SM(bna_rxf_sm_stop_wait), BNA_RXF_STOP_WAIT},
-       {BFA_SM(bna_rxf_sm_pause_wait), BNA_RXF_PAUSE_WAIT},
-       {BFA_SM(bna_rxf_sm_resume_wait), BNA_RXF_RESUME_WAIT},
-       {BFA_SM(bna_rxf_sm_stat_clr_wait), BNA_RXF_STAT_CLR_WAIT}
-};
-
-static void
-bna_rxf_sm_stopped_entry(struct bna_rxf *rxf)
-{
-       call_rxf_stop_cbfn(rxf, BNA_CB_SUCCESS);
-}
-
-static void
-bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_START:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_start_wait);
-               break;
-
-       case RXF_E_STOP:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_FAIL:
-               /* No-op */
-               break;
-
-       case RXF_E_CAM_FLTR_MOD:
-               call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
-               break;
-
-       case RXF_E_STARTED:
-       case RXF_E_STOPPED:
-       case RXF_E_CAM_FLTR_RESP:
-               /**
-                * These events are received due to flushing of mbox
-                * when device fails
-                */
-               /* No-op */
-               break;
-
-       case RXF_E_PAUSE:
-               rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
-               call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
-               break;
-
-       case RXF_E_RESUME:
-               rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
-               call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_start_wait_entry(struct bna_rxf *rxf)
-{
-       __rxf_config_set(rxf);
-       __rxf_rit_set(rxf);
-       rxf_enable(rxf);
-}
-
-static void
-bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_STOP:
-               /**
-                * STOP is originated from bnad. When this happens,
-                * it can not be waiting for filter update
-                */
-               call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
-               break;
-
-       case RXF_E_FAIL:
-               call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
-               call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_CAM_FLTR_MOD:
-               /* No-op */
-               break;
-
-       case RXF_E_STARTED:
-               /**
-                * Force rxf_process_filter() to go through initial
-                * config
-                */
-               if ((rxf->ucast_active_mac != NULL) &&
-                       (rxf->ucast_pending_set == 0))
-                       rxf->ucast_pending_set = 1;
-
-               if (rxf->rss_status == BNA_STATUS_T_ENABLED)
-                       rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;
-
-               rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
-
-               bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
-               break;
-
-       case RXF_E_PAUSE:
-       case RXF_E_RESUME:
-               rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_cam_fltr_mod_wait_entry(struct bna_rxf *rxf)
-{
-       if (!rxf_process_packet_filter(rxf)) {
-               /* No more pending CAM entries to update */
-               bfa_fsm_set_state(rxf, bna_rxf_sm_started);
-       }
-}
-
-static void
-bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_STOP:
-               /**
-                * STOP is originated from bnad. When this happens,
-                * it can not be waiting for filter update
-                */
-               call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
-               break;
-
-       case RXF_E_FAIL:
-               rxf_reset_packet_filter(rxf);
-               call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
-               call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_CAM_FLTR_MOD:
-               /* No-op */
-               break;
-
-       case RXF_E_CAM_FLTR_RESP:
-               if (!rxf_process_packet_filter(rxf)) {
-                       /* No more pending CAM entries to update */
-                       call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
-                       bfa_fsm_set_state(rxf, bna_rxf_sm_started);
-               }
-               break;
-
-       case RXF_E_PAUSE:
-       case RXF_E_RESUME:
-               rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_started_entry(struct bna_rxf *rxf)
-{
-       call_rxf_start_cbfn(rxf, BNA_CB_SUCCESS);
-
-       if (rxf->rxf_flags & BNA_RXF_FL_OPERSTATE_CHANGED) {
-               if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
-                       bfa_fsm_send_event(rxf, RXF_E_PAUSE);
-               else
-                       bfa_fsm_send_event(rxf, RXF_E_RESUME);
-       }
-
-}
-
-static void
-bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_STOP:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
-               /* Hack to get FSM start clearing CAM entries */
-               bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
-               break;
-
-       case RXF_E_FAIL:
-               rxf_reset_packet_filter(rxf);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_CAM_FLTR_MOD:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
-               break;
-
-       case RXF_E_PAUSE:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_pause_wait);
-               break;
-
-       case RXF_E_RESUME:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_resume_wait);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf)
-{
-       /**
-        *  Note: Do not add rxf_clear_packet_filter here.
-        * It will overstep mbox when this transition happens:
-        *      cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event
-        */
-}
-
-static void
-bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_FAIL:
-               /**
-                * FSM was in the process of stopping, initiated by
-                * bnad. When this happens, no one can be waiting for
-                * start or filter update
-                */
-               rxf_reset_packet_filter(rxf);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_CAM_FLTR_RESP:
-               if (!rxf_clear_packet_filter(rxf)) {
-                       /* No more pending CAM entries to clear */
-                       bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
-                       rxf_disable(rxf);
-               }
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf)
-{
-       /**
-        * NOTE: Do not add  rxf_disable here.
-        * It will overstep mbox when this transition happens:
-        *      start_wait -> stop_wait on RXF_E_STOP event
-        */
-}
-
-static void
-bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_FAIL:
-               /**
-                * FSM was in the process of stopping, initiated by
-                * bnad. When this happens, no one can be waiting for
-                * start or filter update
-                */
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_STARTED:
-               /**
-                * This event is received due to abrupt transition from
-                * bna_rxf_sm_start_wait state on receiving
-                * RXF_E_STOP event
-                */
-               rxf_disable(rxf);
-               break;
-
-       case RXF_E_STOPPED:
-               /**
-                * FSM was in the process of stopping, initiated by
-                * bnad. When this happens, no one can be waiting for
-                * start or filter update
-                */
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stat_clr_wait);
-               break;
-
-       case RXF_E_PAUSE:
-               rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
-               break;
-
-       case RXF_E_RESUME:
-               rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_pause_wait_entry(struct bna_rxf *rxf)
-{
-       rxf->rxf_flags &=
-               ~(BNA_RXF_FL_OPERSTATE_CHANGED | BNA_RXF_FL_RXF_ENABLED);
-       __rxf_disable(rxf);
-}
-
-static void
-bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_FAIL:
-               /**
-                * FSM was in the process of disabling rxf, initiated by
-                * bnad.
-                */
-               call_rxf_pause_cbfn(rxf, BNA_CB_FAIL);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_STOPPED:
-               rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
-               call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_started);
-               break;
-
-       /*
-        * Since PAUSE/RESUME can only be sent by bnad, we don't expect
-        * any other event during these states
-        */
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_resume_wait_entry(struct bna_rxf *rxf)
-{
-       rxf->rxf_flags &= ~(BNA_RXF_FL_OPERSTATE_CHANGED);
-       rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
-       __rxf_enable(rxf);
-}
-
-static void
-bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_FAIL:
-               /**
-                * FSM was in the process of disabling rxf, initiated by
-                * bnad.
-                */
-               call_rxf_resume_cbfn(rxf, BNA_CB_FAIL);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       case RXF_E_STARTED:
-               rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
-               call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
-               bfa_fsm_set_state(rxf, bna_rxf_sm_started);
-               break;
-
-       /*
-        * Since PAUSE/RESUME can only be sent by bnad, we don't expect
-        * any other event during these states
-        */
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_rxf_sm_stat_clr_wait_entry(struct bna_rxf *rxf)
-{
-       __bna_rxf_stat_clr(rxf);
-}
-
-static void
-bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
-{
-       switch (event) {
-       case RXF_E_FAIL:
-       case RXF_E_STAT_CLEARED:
-               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-__rxf_enable(struct bna_rxf *rxf)
-{
-       struct bfi_ll_rxf_multi_req ll_req;
-       u32 bm[2] = {0, 0};
-
-       if (rxf->rxf_id < 32)
-               bm[0] = 1 << rxf->rxf_id;
-       else
-               bm[1] = 1 << (rxf->rxf_id - 32);
-
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
-       ll_req.rxf_id_mask[0] = htonl(bm[0]);
-       ll_req.rxf_id_mask[1] = htonl(bm[1]);
-       ll_req.enable = 1;
-
-       bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
-                       rxf_cb_enabled, rxf);
-
-       bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
-}
-
-static void
-__rxf_disable(struct bna_rxf *rxf)
-{
-       struct bfi_ll_rxf_multi_req ll_req;
-       u32 bm[2] = {0, 0};
-
-       if (rxf->rxf_id < 32)
-               bm[0] = 1 << rxf->rxf_id;
-       else
-               bm[1] = 1 << (rxf->rxf_id - 32);
-
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
-       ll_req.rxf_id_mask[0] = htonl(bm[0]);
-       ll_req.rxf_id_mask[1] = htonl(bm[1]);
-       ll_req.enable = 0;
-
-       bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
-                       rxf_cb_disabled, rxf);
-
-       bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
-}
-
-static void
-__rxf_config_set(struct bna_rxf *rxf)
-{
-       u32 i;
-       struct bna_rss_mem *rss_mem;
-       struct bna_rx_fndb_ram *rx_fndb_ram;
-       struct bna *bna = rxf->rx->bna;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
-                       RSS_TABLE_BASE_OFFSET);
-
-       rss_mem = (struct bna_rss_mem *)0;
-
-       /* Configure RSS if required */
-       if (rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE) {
-               /* configure RSS Table */
-               writel(BNA_GET_PAGE_NUM(RAD0_MEM_BLK_BASE_PG_NUM +
-                       bna->port_num, RSS_TABLE_BASE_OFFSET),
-                                       bna->regs.page_addr);
-
-               /* temporarily disable RSS, while hash value is written */
-               off = (unsigned long)&rss_mem[0].type_n_hash;
-               writel(0, base_addr + off);
-
-               for (i = 0; i < BFI_RSS_HASH_KEY_LEN; i++) {
-                       off = (unsigned long)
-                       &rss_mem[0].hash_key[(BFI_RSS_HASH_KEY_LEN - 1) - i];
-                       writel(htonl(rxf->rss_cfg.toeplitz_hash_key[i]),
-                       base_addr + off);
-               }
-
-               off = (unsigned long)&rss_mem[0].type_n_hash;
-               writel(rxf->rss_cfg.hash_type | rxf->rss_cfg.hash_mask,
-                       base_addr + off);
-       }
-
-       /* Configure RxF */
-       writel(BNA_GET_PAGE_NUM(
-               LUT0_MEM_BLK_BASE_PG_NUM + (bna->port_num * 2),
-               RX_FNDB_RAM_BASE_OFFSET),
-               bna->regs.page_addr);
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
-               RX_FNDB_RAM_BASE_OFFSET);
-
-       rx_fndb_ram = (struct bna_rx_fndb_ram *)0;
-
-       /* We always use RSS table 0 */
-       off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rss_prop;
-       writel(rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE,
-               base_addr + off);
-
-       /* small large buffer enable/disable */
-       off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].size_routing_props;
-       writel((rxf->ctrl_flags & BNA_RXF_CF_SM_LG_RXQ) | 0x80,
-               base_addr + off);
-
-       /* RIT offset,  HDS forced offset, multicast RxQ Id */
-       off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rit_hds_mcastq;
-       writel((rxf->rit_segment->rit_offset << 16) |
-               (rxf->forced_offset << 8) |
-               (rxf->hds_cfg.hdr_type & BNA_HDS_FORCED) | rxf->mcast_rxq_id,
-               base_addr + off);
-
-       /*
-        * default vlan tag, default function enable, strip vlan bytes,
-        * HDS type, header size
-        */
-
-       off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].control_flags;
-        writel(((u32)rxf->default_vlan_tag << 16) |
-               (rxf->ctrl_flags &
-                       (BNA_RXF_CF_DEFAULT_VLAN |
-                       BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE |
-                       BNA_RXF_CF_VLAN_STRIP)) |
-               (rxf->hds_cfg.hdr_type & ~BNA_HDS_FORCED) |
-               rxf->hds_cfg.header_size,
-               base_addr + off);
-}
-
-void
-__rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status)
-{
-       struct bna *bna = rxf->rx->bna;
-       int i;
-
-       writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
-                       (bna->port_num * 2), VLAN_RAM_BASE_OFFSET),
-                       bna->regs.page_addr);
-
-       if (status == BNA_STATUS_T_ENABLED) {
-               /* enable VLAN filtering on this function */
-               for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
-                       writel(rxf->vlan_filter_table[i],
-                                       BNA_GET_VLAN_MEM_ENTRY_ADDR
-                                       (bna->pcidev.pci_bar_kva, rxf->rxf_id,
-                                               i * 32));
-               }
-       } else {
-               /* disable VLAN filtering on this function */
-               for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
-                       writel(0xffffffff,
-                                       BNA_GET_VLAN_MEM_ENTRY_ADDR
-                                       (bna->pcidev.pci_bar_kva, rxf->rxf_id,
-                                               i * 32));
-               }
-       }
-}
-
-static void
-__rxf_rit_set(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-       struct bna_rit_mem *rit_mem;
-       int i;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
-                       FUNCTION_TO_RXQ_TRANSLATE);
-
-       rit_mem = (struct bna_rit_mem *)0;
-
-       writel(BNA_GET_PAGE_NUM(RXA0_MEM_BLK_BASE_PG_NUM + bna->port_num,
-               FUNCTION_TO_RXQ_TRANSLATE),
-               bna->regs.page_addr);
-
-       for (i = 0; i < rxf->rit_segment->rit_size; i++) {
-               off = (unsigned long)&rit_mem[i + rxf->rit_segment->rit_offset];
-               writel(rxf->rit_segment->rit[i].large_rxq_id << 6 |
-                       rxf->rit_segment->rit[i].small_rxq_id,
-                       base_addr + off);
-       }
-}
-
-static void
-__bna_rxf_stat_clr(struct bna_rxf *rxf)
-{
-       struct bfi_ll_stats_req ll_req;
-       u32 bm[2] = {0, 0};
-
-       if (rxf->rxf_id < 32)
-               bm[0] = 1 << rxf->rxf_id;
-       else
-               bm[1] = 1 << (rxf->rxf_id - 32);
-
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
-       ll_req.stats_mask = 0;
-       ll_req.txf_id_mask[0] = 0;
-       ll_req.txf_id_mask[1] = 0;
-
-       ll_req.rxf_id_mask[0] = htonl(bm[0]);
-       ll_req.rxf_id_mask[1] = htonl(bm[1]);
-
-       bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
-                       bna_rxf_cb_stats_cleared, rxf);
-       bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
-}
-
-static void
-rxf_enable(struct bna_rxf *rxf)
-{
-       if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
-               bfa_fsm_send_event(rxf, RXF_E_STARTED);
-       else {
-               rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
-               __rxf_enable(rxf);
-       }
-}
-
-static void
-rxf_cb_enabled(void *arg, int status)
-{
-       struct bna_rxf *rxf = (struct bna_rxf *)arg;
-
-       bfa_q_qe_init(&rxf->mbox_qe.qe);
-       bfa_fsm_send_event(rxf, RXF_E_STARTED);
-}
-
-static void
-rxf_disable(struct bna_rxf *rxf)
-{
-       if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
-               bfa_fsm_send_event(rxf, RXF_E_STOPPED);
-       else
-               rxf->rxf_flags &= ~BNA_RXF_FL_RXF_ENABLED;
-               __rxf_disable(rxf);
-}
-
-static void
-rxf_cb_disabled(void *arg, int status)
-{
-       struct bna_rxf *rxf = (struct bna_rxf *)arg;
-
-       bfa_q_qe_init(&rxf->mbox_qe.qe);
-       bfa_fsm_send_event(rxf, RXF_E_STOPPED);
-}
-
-void
-rxf_cb_cam_fltr_mbox_cmd(void *arg, int status)
-{
-       struct bna_rxf *rxf = (struct bna_rxf *)arg;
-
-       bfa_q_qe_init(&rxf->mbox_qe.qe);
-
-       bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
-}
-
-static void
-bna_rxf_cb_stats_cleared(void *arg, int status)
-{
-       struct bna_rxf *rxf = (struct bna_rxf *)arg;
-
-       bfa_q_qe_init(&rxf->mbox_qe.qe);
-       bfa_fsm_send_event(rxf, RXF_E_STAT_CLEARED);
-}
-
-void
-rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
-               const struct bna_mac *mac_addr)
-{
-       struct bfi_ll_mac_addr_req req;
-
-       bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);
-
-       req.rxf_id = rxf->rxf_id;
-       memcpy(&req.mac_addr, (void *)&mac_addr->addr, ETH_ALEN);
-
-       bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
-                               rxf_cb_cam_fltr_mbox_cmd, rxf);
-
-       bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
-}
-
-static int
-rxf_process_packet_filter_mcast(struct bna_rxf *rxf)
-{
-       struct bna_mac *mac = NULL;
-       struct list_head *qe;
-
-       /* Add multicast entries */
-       if (!list_empty(&rxf->mcast_pending_add_q)) {
-               bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_ADD_REQ, mac);
-               list_add_tail(&mac->qe, &rxf->mcast_active_q);
-               return 1;
-       }
-
-       /* Delete multicast entries previousely added */
-       if (!list_empty(&rxf->mcast_pending_del_q)) {
-               bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
-               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
-               return 1;
-       }
-
-       return 0;
-}
-
-static int
-rxf_process_packet_filter_vlan(struct bna_rxf *rxf)
-{
-       /* Apply the VLAN filter */
-       if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) {
-               rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING;
-               if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC))
-                       __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
-       }
-
-       /* Apply RSS configuration */
-       if (rxf->rxf_flags & BNA_RXF_FL_RSS_CONFIG_PENDING) {
-               rxf->rxf_flags &= ~BNA_RXF_FL_RSS_CONFIG_PENDING;
-               if (rxf->rss_status == BNA_STATUS_T_DISABLED) {
-                       /* RSS is being disabled */
-                       rxf->ctrl_flags &= ~BNA_RXF_CF_RSS_ENABLE;
-                       __rxf_rit_set(rxf);
-                       __rxf_config_set(rxf);
-               } else {
-                       /* RSS is being enabled or reconfigured */
-                       rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
-                       __rxf_rit_set(rxf);
-                       __rxf_config_set(rxf);
-               }
-       }
-
-       return 0;
-}
-
-/**
- * Processes pending ucast, mcast entry addition/deletion and issues mailbox
- * command. Also processes pending filter configuration - promiscuous mode,
- * default mode, allmutli mode and issues mailbox command or directly applies
- * to h/w
- */
-static int
-rxf_process_packet_filter(struct bna_rxf *rxf)
-{
-       /* Set the default MAC first */
-       if (rxf->ucast_pending_set > 0) {
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_SET_REQ,
-                               rxf->ucast_active_mac);
-               rxf->ucast_pending_set--;
-               return 1;
-       }
-
-       if (rxf_process_packet_filter_ucast(rxf))
-               return 1;
-
-       if (rxf_process_packet_filter_mcast(rxf))
-               return 1;
-
-       if (rxf_process_packet_filter_promisc(rxf))
-               return 1;
-
-       if (rxf_process_packet_filter_allmulti(rxf))
-               return 1;
-
-       if (rxf_process_packet_filter_vlan(rxf))
-               return 1;
-
-       return 0;
-}
-
-static int
-rxf_clear_packet_filter_mcast(struct bna_rxf *rxf)
-{
-       struct bna_mac *mac = NULL;
-       struct list_head *qe;
-
-       /* 3. delete pending mcast entries */
-       if (!list_empty(&rxf->mcast_pending_del_q)) {
-               bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
-               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
-               return 1;
-       }
-
-       /* 4. clear active mcast entries; move them to pending_add_q */
-       if (!list_empty(&rxf->mcast_active_q)) {
-               bfa_q_deq(&rxf->mcast_active_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
-               list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
-               return 1;
-       }
-
-       return 0;
-}
-
-/**
- * In the rxf stop path, processes pending ucast/mcast delete queue and issues
- * the mailbox command. Moves the active ucast/mcast entries to pending add q,
- * so that they are added to CAM again in the rxf start path. Moves the current
- * filter settings - promiscuous, default, allmutli - to pending filter
- * configuration
- */
-static int
-rxf_clear_packet_filter(struct bna_rxf *rxf)
-{
-       if (rxf_clear_packet_filter_ucast(rxf))
-               return 1;
-
-       if (rxf_clear_packet_filter_mcast(rxf))
-               return 1;
-
-       /* 5. clear active default MAC in the CAM */
-       if (rxf->ucast_pending_set > 0)
-               rxf->ucast_pending_set = 0;
-
-       if (rxf_clear_packet_filter_promisc(rxf))
-               return 1;
-
-       if (rxf_clear_packet_filter_allmulti(rxf))
-               return 1;
-
-       return 0;
-}
-
-static void
-rxf_reset_packet_filter_mcast(struct bna_rxf *rxf)
-{
-       struct list_head *qe;
-       struct bna_mac *mac;
-
-       /* 3. Move active mcast entries to pending_add_q */
-       while (!list_empty(&rxf->mcast_active_q)) {
-               bfa_q_deq(&rxf->mcast_active_q, &qe);
-               bfa_q_qe_init(qe);
-               list_add_tail(qe, &rxf->mcast_pending_add_q);
-       }
-
-       /* 4. Throw away delete pending mcast entries */
-       while (!list_empty(&rxf->mcast_pending_del_q)) {
-               bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
-               bfa_q_qe_init(qe);
-               mac = (struct bna_mac *)qe;
-               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
-       }
-}
-
-/**
- * In the rxf fail path, throws away the ucast/mcast entries pending for
- * deletion, moves all active ucast/mcast entries to pending queue so that
- * they are added back to CAM in the rxf start path. Also moves the current
- * filter configuration to pending filter configuration.
- */
-static void
-rxf_reset_packet_filter(struct bna_rxf *rxf)
-{
-       rxf_reset_packet_filter_ucast(rxf);
-
-       rxf_reset_packet_filter_mcast(rxf);
-
-       /* 5. Turn off ucast set flag */
-       rxf->ucast_pending_set = 0;
-
-       rxf_reset_packet_filter_promisc(rxf);
-
-       rxf_reset_packet_filter_allmulti(rxf);
-}
-
-static void
-bna_rxf_init(struct bna_rxf *rxf,
-               struct bna_rx *rx,
-               struct bna_rx_config *q_config)
-{
-       struct list_head *qe;
-       struct bna_rxp *rxp;
-
-       /* rxf_id is initialized during rx_mod init */
-       rxf->rx = rx;
-
-       INIT_LIST_HEAD(&rxf->ucast_pending_add_q);
-       INIT_LIST_HEAD(&rxf->ucast_pending_del_q);
-       rxf->ucast_pending_set = 0;
-       INIT_LIST_HEAD(&rxf->ucast_active_q);
-       rxf->ucast_active_mac = NULL;
-
-       INIT_LIST_HEAD(&rxf->mcast_pending_add_q);
-       INIT_LIST_HEAD(&rxf->mcast_pending_del_q);
-       INIT_LIST_HEAD(&rxf->mcast_active_q);
-
-       bfa_q_qe_init(&rxf->mbox_qe.qe);
-
-       if (q_config->vlan_strip_status == BNA_STATUS_T_ENABLED)
-               rxf->ctrl_flags |= BNA_RXF_CF_VLAN_STRIP;
-
-       rxf->rxf_oper_state = (q_config->paused) ?
-               BNA_RXF_OPER_STATE_PAUSED : BNA_RXF_OPER_STATE_RUNNING;
-
-       bna_rxf_adv_init(rxf, rx, q_config);
-
-       rxf->rit_segment = bna_rit_mod_seg_get(&rxf->rx->bna->rit_mod,
-                                       q_config->num_paths);
-
-       list_for_each(qe, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe;
-               if (q_config->rxp_type == BNA_RXP_SINGLE)
-                       rxf->mcast_rxq_id = rxp->rxq.single.only->rxq_id;
-               else
-                       rxf->mcast_rxq_id = rxp->rxq.slr.large->rxq_id;
-               break;
-       }
-
-       rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
-       memset(rxf->vlan_filter_table, 0,
-                       (sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)));
-
-       /* Set up VLAN 0 for pure priority tagged packets */
-       rxf->vlan_filter_table[0] |= 1;
-
-       bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
-}
-
-static void
-bna_rxf_uninit(struct bna_rxf *rxf)
-{
-       struct bna *bna = rxf->rx->bna;
-       struct bna_mac *mac;
-
-       bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment);
-       rxf->rit_segment = NULL;
-
-       rxf->ucast_pending_set = 0;
-
-       while (!list_empty(&rxf->ucast_pending_add_q)) {
-               bfa_q_deq(&rxf->ucast_pending_add_q, &mac);
-               bfa_q_qe_init(&mac->qe);
-               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
-       }
-
-       if (rxf->ucast_active_mac) {
-               bfa_q_qe_init(&rxf->ucast_active_mac->qe);
-               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod,
-                       rxf->ucast_active_mac);
-               rxf->ucast_active_mac = NULL;
-       }
-
-       while (!list_empty(&rxf->mcast_pending_add_q)) {
-               bfa_q_deq(&rxf->mcast_pending_add_q, &mac);
-               bfa_q_qe_init(&mac->qe);
-               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
-       }
-
-       /* Turn off pending promisc mode */
-       if (is_promisc_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               /* system promisc state should be pending */
-               BUG_ON(!(bna->rxf_promisc_id == rxf->rxf_id));
-               promisc_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-                bna->rxf_promisc_id = BFI_MAX_RXF;
-       }
-       /* Promisc mode should not be active */
-       BUG_ON(rxf->rxmode_active & BNA_RXMODE_PROMISC);
-
-       /* Turn off pending all-multi mode */
-       if (is_allmulti_enable(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask)) {
-               allmulti_inactive(rxf->rxmode_pending,
-                               rxf->rxmode_pending_bitmask);
-       }
-       /* Allmulti mode should not be active */
-       BUG_ON(rxf->rxmode_active & BNA_RXMODE_ALLMULTI);
-
-       rxf->rx = NULL;
-}
-
-static void
-bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status)
-{
-       bfa_fsm_send_event(rx, RX_E_RXF_STARTED);
-       if (rx->rxf.rxf_id < 32)
-               rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id);
-       else
-               rx->bna->rx_mod.rxf_bmap[1] |= ((u32)
-                               1 << (rx->rxf.rxf_id - 32));
-}
-
-static void
-bna_rxf_start(struct bna_rxf *rxf)
-{
-       rxf->start_cbfn = bna_rx_cb_rxf_started;
-       rxf->start_cbarg = rxf->rx;
-       rxf->rxf_flags &= ~BNA_RXF_FL_FAILED;
-       bfa_fsm_send_event(rxf, RXF_E_START);
-}
-
-static void
-bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status)
-{
-       bfa_fsm_send_event(rx, RX_E_RXF_STOPPED);
-       if (rx->rxf.rxf_id < 32)
-               rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id;
-       else
-               rx->bna->rx_mod.rxf_bmap[1] &= ~(u32)
-                               1 << (rx->rxf.rxf_id - 32);
-}
-
-static void
-bna_rxf_stop(struct bna_rxf *rxf)
-{
-       rxf->stop_cbfn = bna_rx_cb_rxf_stopped;
-       rxf->stop_cbarg = rxf->rx;
-       bfa_fsm_send_event(rxf, RXF_E_STOP);
-}
-
-static void
-bna_rxf_fail(struct bna_rxf *rxf)
-{
-       rxf->rxf_flags |= BNA_RXF_FL_FAILED;
-       bfa_fsm_send_event(rxf, RXF_E_FAIL);
-}
-
-int
-bna_rxf_state_get(struct bna_rxf *rxf)
-{
-       return bfa_sm_to_state(rxf_sm_table, rxf->fsm);
-}
-
-enum bna_cb_status
-bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
-                void (*cbfn)(struct bnad *, struct bna_rx *,
-                             enum bna_cb_status))
-{
-       struct bna_rxf *rxf = &rx->rxf;
-
-       if (rxf->ucast_active_mac == NULL) {
-               rxf->ucast_active_mac =
-                               bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod);
-               if (rxf->ucast_active_mac == NULL)
-                       return BNA_CB_UCAST_CAM_FULL;
-               bfa_q_qe_init(&rxf->ucast_active_mac->qe);
-       }
-
-       memcpy(rxf->ucast_active_mac->addr, ucmac, ETH_ALEN);
-       rxf->ucast_pending_set++;
-       rxf->cam_fltr_cbfn = cbfn;
-       rxf->cam_fltr_cbarg = rx->bna->bnad;
-
-       bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-
-       return BNA_CB_SUCCESS;
-}
-
-enum bna_cb_status
-bna_rx_mcast_add(struct bna_rx *rx, u8 *addr,
-                void (*cbfn)(struct bnad *, struct bna_rx *,
-                             enum bna_cb_status))
-{
-       struct bna_rxf *rxf = &rx->rxf;
-       struct list_head        *qe;
-       struct bna_mac *mac;
-
-       /* Check if already added */
-       list_for_each(qe, &rxf->mcast_active_q) {
-               mac = (struct bna_mac *)qe;
-               if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
-                       if (cbfn)
-                               (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
-                       return BNA_CB_SUCCESS;
-               }
-       }
-
-       /* Check if pending addition */
-       list_for_each(qe, &rxf->mcast_pending_add_q) {
-               mac = (struct bna_mac *)qe;
-               if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
-                       if (cbfn)
-                               (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
-                       return BNA_CB_SUCCESS;
-               }
-       }
-
-       mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
-       if (mac == NULL)
-               return BNA_CB_MCAST_LIST_FULL;
-       bfa_q_qe_init(&mac->qe);
-       memcpy(mac->addr, addr, ETH_ALEN);
-       list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
-
-       rxf->cam_fltr_cbfn = cbfn;
-       rxf->cam_fltr_cbarg = rx->bna->bnad;
-
-       bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-
-       return BNA_CB_SUCCESS;
-}
-
-enum bna_cb_status
-bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist,
-                    void (*cbfn)(struct bnad *, struct bna_rx *,
-                                 enum bna_cb_status))
-{
-       struct bna_rxf *rxf = &rx->rxf;
-       struct list_head list_head;
-       struct list_head *qe;
-       u8 *mcaddr;
-       struct bna_mac *mac;
-       struct bna_mac *mac1;
-       int skip;
-       int delete;
-       int need_hw_config = 0;
-       int i;
-
-       /* Allocate nodes */
-       INIT_LIST_HEAD(&list_head);
-       for (i = 0, mcaddr = mclist; i < count; i++) {
-               mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
-               if (mac == NULL)
-                       goto err_return;
-               bfa_q_qe_init(&mac->qe);
-               memcpy(mac->addr, mcaddr, ETH_ALEN);
-               list_add_tail(&mac->qe, &list_head);
-
-               mcaddr += ETH_ALEN;
-       }
-
-       /* Schedule for addition */
-       while (!list_empty(&list_head)) {
-               bfa_q_deq(&list_head, &qe);
-               mac = (struct bna_mac *)qe;
-               bfa_q_qe_init(&mac->qe);
-
-               skip = 0;
-
-               /* Skip if already added */
-               list_for_each(qe, &rxf->mcast_active_q) {
-                       mac1 = (struct bna_mac *)qe;
-                       if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
-                               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
-                                                       mac);
-                               skip = 1;
-                               break;
-                       }
-               }
-
-               if (skip)
-                       continue;
-
-               /* Skip if pending addition */
-               list_for_each(qe, &rxf->mcast_pending_add_q) {
-                       mac1 = (struct bna_mac *)qe;
-                       if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
-                               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
-                                                       mac);
-                               skip = 1;
-                               break;
-                       }
-               }
-
-               if (skip)
-                       continue;
-
-               need_hw_config = 1;
-               list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
-       }
-
-       /**
-        * Delete the entries that are in the pending_add_q but not
-        * in the new list
-        */
-       while (!list_empty(&rxf->mcast_pending_add_q)) {
-               bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
-               mac = (struct bna_mac *)qe;
-               bfa_q_qe_init(&mac->qe);
-               for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
-                       if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
-                               delete = 0;
-                               break;
-                       }
-                       mcaddr += ETH_ALEN;
-               }
-               if (delete)
-                       bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
-               else
-                       list_add_tail(&mac->qe, &list_head);
-       }
-       while (!list_empty(&list_head)) {
-               bfa_q_deq(&list_head, &qe);
-               mac = (struct bna_mac *)qe;
-               bfa_q_qe_init(&mac->qe);
-               list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
-       }
-
-       /**
-        * Schedule entries for deletion that are in the active_q but not
-        * in the new list
-        */
-       while (!list_empty(&rxf->mcast_active_q)) {
-               bfa_q_deq(&rxf->mcast_active_q, &qe);
-               mac = (struct bna_mac *)qe;
-               bfa_q_qe_init(&mac->qe);
-               for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
-                       if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
-                               delete = 0;
-                               break;
-                       }
-                       mcaddr += ETH_ALEN;
-               }
-               if (delete) {
-                       list_add_tail(&mac->qe, &rxf->mcast_pending_del_q);
-                       need_hw_config = 1;
-               } else {
-                       list_add_tail(&mac->qe, &list_head);
-               }
-       }
-       while (!list_empty(&list_head)) {
-               bfa_q_deq(&list_head, &qe);
-               mac = (struct bna_mac *)qe;
-               bfa_q_qe_init(&mac->qe);
-               list_add_tail(&mac->qe, &rxf->mcast_active_q);
-       }
-
-       if (need_hw_config) {
-               rxf->cam_fltr_cbfn = cbfn;
-               rxf->cam_fltr_cbarg = rx->bna->bnad;
-               bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-       } else if (cbfn)
-               (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
-
-       return BNA_CB_SUCCESS;
-
-err_return:
-       while (!list_empty(&list_head)) {
-               bfa_q_deq(&list_head, &qe);
-               mac = (struct bna_mac *)qe;
-               bfa_q_qe_init(&mac->qe);
-               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
-       }
-
-       return BNA_CB_MCAST_LIST_FULL;
-}
-
-void
-bna_rx_vlan_add(struct bna_rx *rx, int vlan_id)
-{
-       struct bna_rxf *rxf = &rx->rxf;
-       int index = (vlan_id >> 5);
-       int bit = (1 << (vlan_id & 0x1F));
-
-       rxf->vlan_filter_table[index] |= bit;
-       if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
-               rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
-               bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-       }
-}
-
-void
-bna_rx_vlan_del(struct bna_rx *rx, int vlan_id)
-{
-       struct bna_rxf *rxf = &rx->rxf;
-       int index = (vlan_id >> 5);
-       int bit = (1 << (vlan_id & 0x1F));
-
-       rxf->vlan_filter_table[index] &= ~bit;
-       if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
-               rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
-               bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
-       }
-}
-
-/**
- * RX
- */
-#define        RXQ_RCB_INIT(q, rxp, qdepth, bna, _id, unmapq_mem)      do {    \
-       struct bna_doorbell_qset *_qset;                                \
-       unsigned long off;                                              \
-       (q)->rcb->producer_index = (q)->rcb->consumer_index = 0;        \
-       (q)->rcb->q_depth = (qdepth);                                   \
-       (q)->rcb->unmap_q = unmapq_mem;                                 \
-       (q)->rcb->rxq = (q);                                            \
-       (q)->rcb->cq = &(rxp)->cq;                                      \
-       (q)->rcb->bnad = (bna)->bnad;                                   \
-       _qset = (struct bna_doorbell_qset *)0;                  \
-       off = (unsigned long)&_qset[(q)->rxq_id].rxq[0];                \
-       (q)->rcb->q_dbell = off +                                       \
-               BNA_GET_DOORBELL_BASE_ADDR((bna)->pcidev.pci_bar_kva);  \
-       (q)->rcb->id = _id;                                             \
-} while (0)
-
-#define        BNA_GET_RXQS(qcfg)      (((qcfg)->rxp_type == BNA_RXP_SINGLE) ? \
-       (qcfg)->num_paths : ((qcfg)->num_paths * 2))
-
-#define        SIZE_TO_PAGES(size)     (((size) >> PAGE_SHIFT) + ((((size) &\
-       (PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
-
-#define        call_rx_stop_callback(rx, status)                               \
-       if ((rx)->stop_cbfn) {                                          \
-               (*(rx)->stop_cbfn)((rx)->stop_cbarg, rx, (status));     \
-               (rx)->stop_cbfn = NULL;                                 \
-               (rx)->stop_cbarg = NULL;                                \
-       }
-
-/*
- * Since rx_enable is synchronous callback, there is no start_cbfn required.
- * Instead, we'll call bnad_rx_post(rxp) so that bnad can post the buffers
- * for each rxpath.
- */
-
-#define        call_rx_disable_cbfn(rx, status)                                \
-               if ((rx)->disable_cbfn) {                               \
-                       (*(rx)->disable_cbfn)((rx)->disable_cbarg,      \
-                                       status);                        \
-                       (rx)->disable_cbfn = NULL;                      \
-                       (rx)->disable_cbarg = NULL;                     \
-               }                                                       \
-
-#define        rxqs_reqd(type, num_rxqs)                                       \
-       (((type) == BNA_RXP_SINGLE) ? (num_rxqs) : ((num_rxqs) * 2))
-
-#define rx_ib_fail(rx)                                         \
-do {                                                           \
-       struct bna_rxp *rxp;                                    \
-       struct list_head *qe;                                           \
-       list_for_each(qe, &(rx)->rxp_q) {                               \
-               rxp = (struct bna_rxp *)qe;                     \
-               bna_ib_fail(rxp->cq.ib);                        \
-       }                                                       \
-} while (0)
-
-static void __bna_multi_rxq_stop(struct bna_rxp *, u32 *);
-static void __bna_rxq_start(struct bna_rxq *rxq);
-static void __bna_cq_start(struct bna_cq *cq);
-static void bna_rit_create(struct bna_rx *rx);
-static void bna_rx_cb_multi_rxq_stopped(void *arg, int status);
-static void bna_rx_cb_rxq_stopped_all(void *arg);
-
-bfa_fsm_state_decl(bna_rx, stopped,
-       struct bna_rx, enum bna_rx_event);
-bfa_fsm_state_decl(bna_rx, rxf_start_wait,
-       struct bna_rx, enum bna_rx_event);
-bfa_fsm_state_decl(bna_rx, started,
-       struct bna_rx, enum bna_rx_event);
-bfa_fsm_state_decl(bna_rx, rxf_stop_wait,
-       struct bna_rx, enum bna_rx_event);
-bfa_fsm_state_decl(bna_rx, rxq_stop_wait,
-       struct bna_rx, enum bna_rx_event);
-
-static const struct bfa_sm_table rx_sm_table[] = {
-       {BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED},
-       {BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT},
-       {BFA_SM(bna_rx_sm_started), BNA_RX_STARTED},
-       {BFA_SM(bna_rx_sm_rxf_stop_wait), BNA_RX_RXF_STOP_WAIT},
-       {BFA_SM(bna_rx_sm_rxq_stop_wait), BNA_RX_RXQ_STOP_WAIT},
-};
-
-static void bna_rx_sm_stopped_entry(struct bna_rx *rx)
-{
-       struct bna_rxp *rxp;
-       struct list_head *qe_rxp;
-
-       list_for_each(qe_rxp, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe_rxp;
-               rx->rx_cleanup_cbfn(rx->bna->bnad, rxp->cq.ccb);
-       }
-
-       call_rx_stop_callback(rx, BNA_CB_SUCCESS);
-}
-
-static void bna_rx_sm_stopped(struct bna_rx *rx,
-                               enum bna_rx_event event)
-{
-       switch (event) {
-       case RX_E_START:
-               bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait);
-               break;
-       case RX_E_STOP:
-               call_rx_stop_callback(rx, BNA_CB_SUCCESS);
-               break;
-       case RX_E_FAIL:
-               /* no-op */
-               break;
-       default:
-               bfa_sm_fault(event);
-               break;
-       }
-
-}
-
-static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx)
-{
-       struct bna_rxp *rxp;
-       struct list_head *qe_rxp;
-       struct bna_rxq *q0 = NULL, *q1 = NULL;
-
-       /* Setup the RIT */
-       bna_rit_create(rx);
-
-       list_for_each(qe_rxp, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe_rxp;
-               bna_ib_start(rxp->cq.ib);
-               GET_RXQS(rxp, q0, q1);
-               q0->buffer_size = bna_port_mtu_get(&rx->bna->port);
-               __bna_rxq_start(q0);
-               rx->rx_post_cbfn(rx->bna->bnad, q0->rcb);
-               if (q1)  {
-                       __bna_rxq_start(q1);
-                       rx->rx_post_cbfn(rx->bna->bnad, q1->rcb);
-               }
-               __bna_cq_start(&rxp->cq);
-       }
-
-       bna_rxf_start(&rx->rxf);
-}
-
-static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
-                               enum bna_rx_event event)
-{
-       switch (event) {
-       case RX_E_STOP:
-               bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
-               break;
-       case RX_E_FAIL:
-               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
-               rx_ib_fail(rx);
-               bna_rxf_fail(&rx->rxf);
-               break;
-       case RX_E_RXF_STARTED:
-               bfa_fsm_set_state(rx, bna_rx_sm_started);
-               break;
-       default:
-               bfa_sm_fault(event);
-               break;
-       }
-}
-
-void
-bna_rx_sm_started_entry(struct bna_rx *rx)
-{
-       struct bna_rxp *rxp;
-       struct list_head *qe_rxp;
-
-       /* Start IB */
-       list_for_each(qe_rxp, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe_rxp;
-               bna_ib_ack(&rxp->cq.ib->door_bell, 0);
-       }
-
-       bna_llport_rx_started(&rx->bna->port.llport);
-}
-
-void
-bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
-{
-       switch (event) {
-       case RX_E_FAIL:
-               bna_llport_rx_stopped(&rx->bna->port.llport);
-               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
-               rx_ib_fail(rx);
-               bna_rxf_fail(&rx->rxf);
-               break;
-       case RX_E_STOP:
-               bna_llport_rx_stopped(&rx->bna->port.llport);
-               bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
-               break;
-       default:
-               bfa_sm_fault(event);
-               break;
-       }
-}
-
-void
-bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx)
-{
-       bna_rxf_stop(&rx->rxf);
-}
-
-void
-bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
-{
-       switch (event) {
-       case RX_E_RXF_STOPPED:
-               bfa_fsm_set_state(rx, bna_rx_sm_rxq_stop_wait);
-               break;
-       case RX_E_RXF_STARTED:
-               /**
-                * RxF was in the process of starting up when
-                * RXF_E_STOP was issued. Ignore this event
-                */
-               break;
-       case RX_E_FAIL:
-               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
-               rx_ib_fail(rx);
-               bna_rxf_fail(&rx->rxf);
-               break;
-       default:
-               bfa_sm_fault(event);
-               break;
-       }
-
-}
-
-void
-bna_rx_sm_rxq_stop_wait_entry(struct bna_rx *rx)
-{
-       struct bna_rxp *rxp = NULL;
-       struct bna_rxq *q0 = NULL;
-       struct bna_rxq *q1 = NULL;
-       struct list_head        *qe;
-       u32 rxq_mask[2] = {0, 0};
-
-       /* Only one call to multi-rxq-stop for all RXPs in this RX */
-       bfa_wc_up(&rx->rxq_stop_wc);
-       list_for_each(qe, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe;
-               GET_RXQS(rxp, q0, q1);
-               if (q0->rxq_id < 32)
-                       rxq_mask[0] |= ((u32)1 << q0->rxq_id);
-               else
-                       rxq_mask[1] |= ((u32)1 << (q0->rxq_id - 32));
-               if (q1) {
-                       if (q1->rxq_id < 32)
-                               rxq_mask[0] |= ((u32)1 << q1->rxq_id);
-                       else
-                               rxq_mask[1] |= ((u32)
-                                               1 << (q1->rxq_id - 32));
-               }
-       }
-
-       __bna_multi_rxq_stop(rxp, rxq_mask);
-}
-
-void
-bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
-{
-       struct bna_rxp *rxp = NULL;
-       struct list_head        *qe;
-
-       switch (event) {
-       case RX_E_RXQ_STOPPED:
-               list_for_each(qe, &rx->rxp_q) {
-                       rxp = (struct bna_rxp *)qe;
-                       bna_ib_stop(rxp->cq.ib);
-               }
-               /* Fall through */
-       case RX_E_FAIL:
-               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
-               break;
-       default:
-               bfa_sm_fault(event);
-               break;
-       }
-}
-
-void
-__bna_multi_rxq_stop(struct bna_rxp *rxp, u32 * rxq_id_mask)
-{
-       struct bfi_ll_q_stop_req ll_req;
-
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RXQ_STOP_REQ, 0);
-       ll_req.q_id_mask[0] = htonl(rxq_id_mask[0]);
-       ll_req.q_id_mask[1] = htonl(rxq_id_mask[1]);
-       bna_mbox_qe_fill(&rxp->mbox_qe, &ll_req, sizeof(ll_req),
-               bna_rx_cb_multi_rxq_stopped, rxp);
-       bna_mbox_send(rxp->rx->bna, &rxp->mbox_qe);
-}
-
-void
-__bna_rxq_start(struct bna_rxq *rxq)
-{
-       struct bna_rxtx_q_mem *q_mem;
-       struct bna_rxq_mem rxq_cfg, *rxq_mem;
-       struct bna_dma_addr cur_q_addr;
-       /* struct bna_doorbell_qset *qset; */
-       struct bna_qpt *qpt;
-       u32 pg_num;
-       struct bna *bna = rxq->rx->bna;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       qpt = &rxq->qpt;
-       cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));
-
-       rxq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
-       rxq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
-       rxq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
-       rxq_cfg.cur_q_entry_hi = cur_q_addr.msb;
-
-       rxq_cfg.pg_cnt_n_prd_ptr = ((u32)qpt->page_count << 16) | 0x0;
-       rxq_cfg.entry_n_pg_size = ((u32)(BFI_RXQ_WI_SIZE >> 2) << 16) |
-               (qpt->page_size >> 2);
-       rxq_cfg.sg_n_cq_n_cns_ptr =
-               ((u32)(rxq->rxp->cq.cq_id & 0xff) << 16) | 0x0;
-       rxq_cfg.buf_sz_n_q_state = ((u32)rxq->buffer_size << 16) |
-               BNA_Q_IDLE_STATE;
-       rxq_cfg.next_qid = 0x0 | (0x3 << 8);
-
-       /* Write the page number register */
-       pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
-                       HQM_RXTX_Q_RAM_BASE_OFFSET);
-       writel(pg_num, bna->regs.page_addr);
-
-       /* Write to h/w */
-       base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
-                                       HQM_RXTX_Q_RAM_BASE_OFFSET);
-
-       q_mem = (struct bna_rxtx_q_mem *)0;
-       rxq_mem = &q_mem[rxq->rxq_id].rxq;
-
-       off = (unsigned long)&rxq_mem->pg_tbl_addr_lo;
-       writel(htonl(rxq_cfg.pg_tbl_addr_lo), base_addr + off);
-
-       off = (unsigned long)&rxq_mem->pg_tbl_addr_hi;
-       writel(htonl(rxq_cfg.pg_tbl_addr_hi), base_addr + off);
-
-       off = (unsigned long)&rxq_mem->cur_q_entry_lo;
-       writel(htonl(rxq_cfg.cur_q_entry_lo), base_addr + off);
-
-       off = (unsigned long)&rxq_mem->cur_q_entry_hi;
-       writel(htonl(rxq_cfg.cur_q_entry_hi), base_addr + off);
-
-       off = (unsigned long)&rxq_mem->pg_cnt_n_prd_ptr;
-       writel(rxq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
-
-       off = (unsigned long)&rxq_mem->entry_n_pg_size;
-       writel(rxq_cfg.entry_n_pg_size, base_addr + off);
-
-       off = (unsigned long)&rxq_mem->sg_n_cq_n_cns_ptr;
-       writel(rxq_cfg.sg_n_cq_n_cns_ptr, base_addr + off);
-
-       off = (unsigned long)&rxq_mem->buf_sz_n_q_state;
-       writel(rxq_cfg.buf_sz_n_q_state, base_addr + off);
-
-       off = (unsigned long)&rxq_mem->next_qid;
-       writel(rxq_cfg.next_qid, base_addr + off);
-
-       rxq->rcb->producer_index = 0;
-       rxq->rcb->consumer_index = 0;
-}
-
-void
-__bna_cq_start(struct bna_cq *cq)
-{
-       struct bna_cq_mem cq_cfg, *cq_mem;
-       const struct bna_qpt *qpt;
-       struct bna_dma_addr cur_q_addr;
-       u32 pg_num;
-       struct bna *bna = cq->rx->bna;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       qpt = &cq->qpt;
-       cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));
-
-       /*
-        * Fill out structure, to be subsequently written
-        * to hardware
-        */
-       cq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
-       cq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
-       cq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
-       cq_cfg.cur_q_entry_hi = cur_q_addr.msb;
-
-       cq_cfg.pg_cnt_n_prd_ptr = (qpt->page_count << 16) | 0x0;
-       cq_cfg.entry_n_pg_size =
-               ((u32)(BFI_CQ_WI_SIZE >> 2) << 16) | (qpt->page_size >> 2);
-       cq_cfg.int_blk_n_cns_ptr = ((((u32)cq->ib_seg_offset) << 24) |
-                       ((u32)(cq->ib->ib_id & 0xff)  << 16) | 0x0);
-       cq_cfg.q_state = BNA_Q_IDLE_STATE;
-
-       /* Write the page number register */
-       pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
-                                 HQM_CQ_RAM_BASE_OFFSET);
-
-       writel(pg_num, bna->regs.page_addr);
-
-       /* H/W write */
-       base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
-                                       HQM_CQ_RAM_BASE_OFFSET);
-
-       cq_mem = (struct bna_cq_mem *)0;
-
-       off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_lo;
-       writel(htonl(cq_cfg.pg_tbl_addr_lo), base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_hi;
-       writel(htonl(cq_cfg.pg_tbl_addr_hi), base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_lo;
-       writel(htonl(cq_cfg.cur_q_entry_lo), base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_hi;
-       writel(htonl(cq_cfg.cur_q_entry_hi), base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].pg_cnt_n_prd_ptr;
-       writel(cq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].entry_n_pg_size;
-       writel(cq_cfg.entry_n_pg_size, base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].int_blk_n_cns_ptr;
-       writel(cq_cfg.int_blk_n_cns_ptr, base_addr + off);
-
-       off = (unsigned long)&cq_mem[cq->cq_id].q_state;
-       writel(cq_cfg.q_state, base_addr + off);
-
-       cq->ccb->producer_index = 0;
-       *(cq->ccb->hw_producer_index) = 0;
-}
-
-void
-bna_rit_create(struct bna_rx *rx)
-{
-       struct list_head        *qe_rxp;
-       struct bna_rxp *rxp;
-       struct bna_rxq *q0 = NULL;
-       struct bna_rxq *q1 = NULL;
-       int offset;
-
-       offset = 0;
-       list_for_each(qe_rxp, &rx->rxp_q) {
-               rxp = (struct bna_rxp *)qe_rxp;
-               GET_RXQS(rxp, q0, q1);
-               rx->rxf.rit_segment->rit[offset].large_rxq_id = q0->rxq_id;
-               rx->rxf.rit_segment->rit[offset].small_rxq_id =
-                                               (q1 ? q1->rxq_id : 0);
-               offset++;
-       }
-}
-
-static int
-_rx_can_satisfy(struct bna_rx_mod *rx_mod,
-               struct bna_rx_config *rx_cfg)
-{
-       if ((rx_mod->rx_free_count == 0) ||
-               (rx_mod->rxp_free_count == 0) ||
-               (rx_mod->rxq_free_count == 0))
-               return 0;
-
-       if (rx_cfg->rxp_type == BNA_RXP_SINGLE) {
-               if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
-                       (rx_mod->rxq_free_count < rx_cfg->num_paths))
-                               return 0;
-       } else {
-               if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
-                       (rx_mod->rxq_free_count < (2 * rx_cfg->num_paths)))
-                       return 0;
-       }
-
-       if (!bna_rit_mod_can_satisfy(&rx_mod->bna->rit_mod, rx_cfg->num_paths))
-               return 0;
-
-       return 1;
-}
-
-static struct bna_rxq *
-_get_free_rxq(struct bna_rx_mod *rx_mod)
-{
-       struct bna_rxq *rxq = NULL;
-       struct list_head        *qe = NULL;
-
-       bfa_q_deq(&rx_mod->rxq_free_q, &qe);
-       if (qe) {
-               rx_mod->rxq_free_count--;
-               rxq = (struct bna_rxq *)qe;
-       }
-       return rxq;
-}
-
-static void
-_put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq)
-{
-       bfa_q_qe_init(&rxq->qe);
-       list_add_tail(&rxq->qe, &rx_mod->rxq_free_q);
-       rx_mod->rxq_free_count++;
-}
-
-static struct bna_rxp *
-_get_free_rxp(struct bna_rx_mod *rx_mod)
-{
-       struct list_head        *qe = NULL;
-       struct bna_rxp *rxp = NULL;
-
-       bfa_q_deq(&rx_mod->rxp_free_q, &qe);
-       if (qe) {
-               rx_mod->rxp_free_count--;
-
-               rxp = (struct bna_rxp *)qe;
-       }
-
-       return rxp;
-}
-
-static void
-_put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp)
-{
-       bfa_q_qe_init(&rxp->qe);
-       list_add_tail(&rxp->qe, &rx_mod->rxp_free_q);
-       rx_mod->rxp_free_count++;
-}
-
-static struct bna_rx *
-_get_free_rx(struct bna_rx_mod *rx_mod)
-{
-       struct list_head        *qe = NULL;
-       struct bna_rx *rx = NULL;
-
-       bfa_q_deq(&rx_mod->rx_free_q, &qe);
-       if (qe) {
-               rx_mod->rx_free_count--;
-
-               rx = (struct bna_rx *)qe;
-               bfa_q_qe_init(qe);
-               list_add_tail(&rx->qe, &rx_mod->rx_active_q);
-       }
-
-       return rx;
-}
-
-static void
-_put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx)
-{
-       bfa_q_qe_init(&rx->qe);
-       list_add_tail(&rx->qe, &rx_mod->rx_free_q);
-       rx_mod->rx_free_count++;
-}
-
-static void
-_rx_init(struct bna_rx *rx, struct bna *bna)
-{
-       rx->bna = bna;
-       rx->rx_flags = 0;
-
-       INIT_LIST_HEAD(&rx->rxp_q);
-
-       rx->rxq_stop_wc.wc_resume = bna_rx_cb_rxq_stopped_all;
-       rx->rxq_stop_wc.wc_cbarg = rx;
-       rx->rxq_stop_wc.wc_count = 0;
-
-       rx->stop_cbfn = NULL;
-       rx->stop_cbarg = NULL;
-}
-
-static void
-_rxp_add_rxqs(struct bna_rxp *rxp,
-               struct bna_rxq *q0,
-               struct bna_rxq *q1)
-{
-       switch (rxp->type) {
-       case BNA_RXP_SINGLE:
-               rxp->rxq.single.only = q0;
-               rxp->rxq.single.reserved = NULL;
-               break;
-       case BNA_RXP_SLR:
-               rxp->rxq.slr.large = q0;
-               rxp->rxq.slr.small = q1;
-               break;
-       case BNA_RXP_HDS:
-               rxp->rxq.hds.data = q0;
-               rxp->rxq.hds.hdr = q1;
-               break;
-       default:
-               break;
-       }
-}
-
-static void
-_rxq_qpt_init(struct bna_rxq *rxq,
-               struct bna_rxp *rxp,
-               u32 page_count,
-               u32 page_size,
-               struct bna_mem_descr *qpt_mem,
-               struct bna_mem_descr *swqpt_mem,
-               struct bna_mem_descr *page_mem)
-{
-       int     i;
-
-       rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
-       rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
-       rxq->qpt.kv_qpt_ptr = qpt_mem->kva;
-       rxq->qpt.page_count = page_count;
-       rxq->qpt.page_size = page_size;
-
-       rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;
-
-       for (i = 0; i < rxq->qpt.page_count; i++) {
-               rxq->rcb->sw_qpt[i] = page_mem[i].kva;
-               ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
-                       page_mem[i].dma.lsb;
-               ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
-                       page_mem[i].dma.msb;
-
-       }
-}
-
-static void
-_rxp_cqpt_setup(struct bna_rxp *rxp,
-               u32 page_count,
-               u32 page_size,
-               struct bna_mem_descr *qpt_mem,
-               struct bna_mem_descr *swqpt_mem,
-               struct bna_mem_descr *page_mem)
-{
-       int     i;
-
-       rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
-       rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
-       rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva;
-       rxp->cq.qpt.page_count = page_count;
-       rxp->cq.qpt.page_size = page_size;
-
-       rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;
-
-       for (i = 0; i < rxp->cq.qpt.page_count; i++) {
-               rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva;
-
-               ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
-                       page_mem[i].dma.lsb;
-               ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
-                       page_mem[i].dma.msb;
-
-       }
-}
-
-static void
-_rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp)
-{
-       list_add_tail(&rxp->qe, &rx->rxp_q);
-}
-
-static void
-_init_rxmod_queues(struct bna_rx_mod *rx_mod)
-{
-       INIT_LIST_HEAD(&rx_mod->rx_free_q);
-       INIT_LIST_HEAD(&rx_mod->rxq_free_q);
-       INIT_LIST_HEAD(&rx_mod->rxp_free_q);
-       INIT_LIST_HEAD(&rx_mod->rx_active_q);
-
-       rx_mod->rx_free_count = 0;
-       rx_mod->rxq_free_count = 0;
-       rx_mod->rxp_free_count = 0;
-}
-
-static void
-_rx_ctor(struct bna_rx *rx, int id)
-{
-       bfa_q_qe_init(&rx->qe);
-       INIT_LIST_HEAD(&rx->rxp_q);
-       rx->bna = NULL;
-
-       rx->rxf.rxf_id = id;
-
-       /* FIXME: mbox_qe ctor()?? */
-       bfa_q_qe_init(&rx->mbox_qe.qe);
-
-       rx->stop_cbfn = NULL;
-       rx->stop_cbarg = NULL;
-}
-
-void
-bna_rx_cb_multi_rxq_stopped(void *arg, int status)
-{
-       struct bna_rxp *rxp = (struct bna_rxp *)arg;
-
-       bfa_wc_down(&rxp->rx->rxq_stop_wc);
-}
-
-void
-bna_rx_cb_rxq_stopped_all(void *arg)
-{
-       struct bna_rx *rx = (struct bna_rx *)arg;
-
-       bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED);
-}
-
-static void
-bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx,
-                        enum bna_cb_status status)
-{
-       struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
-
-       bfa_wc_down(&rx_mod->rx_stop_wc);
-}
-
-static void
-bna_rx_mod_cb_rx_stopped_all(void *arg)
-{
-       struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
-
-       if (rx_mod->stop_cbfn)
-               rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
-       rx_mod->stop_cbfn = NULL;
-}
-
-static void
-bna_rx_start(struct bna_rx *rx)
-{
-       rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
-       if (rx->rx_flags & BNA_RX_F_ENABLE)
-               bfa_fsm_send_event(rx, RX_E_START);
-}
-
-static void
-bna_rx_stop(struct bna_rx *rx)
-{
-       rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
-       if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped)
-               bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx, BNA_CB_SUCCESS);
-       else {
-               rx->stop_cbfn = bna_rx_mod_cb_rx_stopped;
-               rx->stop_cbarg = &rx->bna->rx_mod;
-               bfa_fsm_send_event(rx, RX_E_STOP);
-       }
-}
-
-static void
-bna_rx_fail(struct bna_rx *rx)
-{
-       /* Indicate port is not enabled, and failed */
-       rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
-       rx->rx_flags |= BNA_RX_F_PORT_FAILED;
-       bfa_fsm_send_event(rx, RX_E_FAIL);
-}
-
-void
-bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
-{
-       struct bna_rx *rx;
-       struct list_head *qe;
-
-       rx_mod->flags |= BNA_RX_MOD_F_PORT_STARTED;
-       if (type == BNA_RX_T_LOOPBACK)
-               rx_mod->flags |= BNA_RX_MOD_F_PORT_LOOPBACK;
-
-       list_for_each(qe, &rx_mod->rx_active_q) {
-               rx = (struct bna_rx *)qe;
-               if (rx->type == type)
-                       bna_rx_start(rx);
-       }
-}
-
-void
-bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
-{
-       struct bna_rx *rx;
-       struct list_head *qe;
-
-       rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
-       rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;
-
-       rx_mod->stop_cbfn = bna_port_cb_rx_stopped;
-
-       /**
-        * Before calling bna_rx_stop(), increment rx_stop_wc as many times
-        * as we are going to call bna_rx_stop
-        */
-       list_for_each(qe, &rx_mod->rx_active_q) {
-               rx = (struct bna_rx *)qe;
-               if (rx->type == type)
-                       bfa_wc_up(&rx_mod->rx_stop_wc);
-       }
-
-       if (rx_mod->rx_stop_wc.wc_count == 0) {
-               rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
-               rx_mod->stop_cbfn = NULL;
-               return;
-       }
-
-       list_for_each(qe, &rx_mod->rx_active_q) {
-               rx = (struct bna_rx *)qe;
-               if (rx->type == type)
-                       bna_rx_stop(rx);
-       }
-}
-
-void
-bna_rx_mod_fail(struct bna_rx_mod *rx_mod)
-{
-       struct bna_rx *rx;
-       struct list_head *qe;
-
-       rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
-       rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;
-
-       list_for_each(qe, &rx_mod->rx_active_q) {
-               rx = (struct bna_rx *)qe;
-               bna_rx_fail(rx);
-       }
-}
-
-void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
-                       struct bna_res_info *res_info)
-{
-       int     index;
-       struct bna_rx *rx_ptr;
-       struct bna_rxp *rxp_ptr;
-       struct bna_rxq *rxq_ptr;
-
-       rx_mod->bna = bna;
-       rx_mod->flags = 0;
-
-       rx_mod->rx = (struct bna_rx *)
-               res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva;
-       rx_mod->rxp = (struct bna_rxp *)
-               res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva;
-       rx_mod->rxq = (struct bna_rxq *)
-               res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva;
-
-       /* Initialize the queues */
-       _init_rxmod_queues(rx_mod);
-
-       /* Build RX queues */
-       for (index = 0; index < BFI_MAX_RXQ; index++) {
-               rx_ptr = &rx_mod->rx[index];
-               _rx_ctor(rx_ptr, index);
-               list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q);
-               rx_mod->rx_free_count++;
-       }
-
-       /* build RX-path queue */
-       for (index = 0; index < BFI_MAX_RXQ; index++) {
-               rxp_ptr = &rx_mod->rxp[index];
-               rxp_ptr->cq.cq_id = index;
-               bfa_q_qe_init(&rxp_ptr->qe);
-               list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q);
-               rx_mod->rxp_free_count++;
-       }
-
-       /* build RXQ queue */
-       for (index = 0; index < BFI_MAX_RXQ; index++) {
-               rxq_ptr = &rx_mod->rxq[index];
-               rxq_ptr->rxq_id = index;
-
-               bfa_q_qe_init(&rxq_ptr->qe);
-               list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q);
-               rx_mod->rxq_free_count++;
-       }
-
-       rx_mod->rx_stop_wc.wc_resume = bna_rx_mod_cb_rx_stopped_all;
-       rx_mod->rx_stop_wc.wc_cbarg = rx_mod;
-       rx_mod->rx_stop_wc.wc_count = 0;
-}
-
-void
-bna_rx_mod_uninit(struct bna_rx_mod *rx_mod)
-{
-       struct list_head                *qe;
-       int i;
-
-       i = 0;
-       list_for_each(qe, &rx_mod->rx_free_q)
-               i++;
-
-       i = 0;
-       list_for_each(qe, &rx_mod->rxp_free_q)
-               i++;
-
-       i = 0;
-       list_for_each(qe, &rx_mod->rxq_free_q)
-               i++;
-
-       rx_mod->bna = NULL;
-}
-
-int
-bna_rx_state_get(struct bna_rx *rx)
-{
-       return bfa_sm_to_state(rx_sm_table, rx->fsm);
-}
-
-void
-bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
-{
-       u32 cq_size, hq_size, dq_size;
-       u32 cpage_count, hpage_count, dpage_count;
-       struct bna_mem_info *mem_info;
-       u32 cq_depth;
-       u32 hq_depth;
-       u32 dq_depth;
-
-       dq_depth = q_cfg->q_depth;
-       hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth);
-       cq_depth = dq_depth + hq_depth;
-
-       BNA_TO_POWER_OF_2_HIGH(cq_depth);
-       cq_size = cq_depth * BFI_CQ_WI_SIZE;
-       cq_size = ALIGN(cq_size, PAGE_SIZE);
-       cpage_count = SIZE_TO_PAGES(cq_size);
-
-       BNA_TO_POWER_OF_2_HIGH(dq_depth);
-       dq_size = dq_depth * BFI_RXQ_WI_SIZE;
-       dq_size = ALIGN(dq_size, PAGE_SIZE);
-       dpage_count = SIZE_TO_PAGES(dq_size);
-
-       if (BNA_RXP_SINGLE != q_cfg->rxp_type) {
-               BNA_TO_POWER_OF_2_HIGH(hq_depth);
-               hq_size = hq_depth * BFI_RXQ_WI_SIZE;
-               hq_size = ALIGN(hq_size, PAGE_SIZE);
-               hpage_count = SIZE_TO_PAGES(hq_size);
-       } else {
-               hpage_count = 0;
-       }
-
-       /* CCB structures */
-       res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = sizeof(struct bna_ccb);
-       mem_info->num = q_cfg->num_paths;
-
-       /* RCB structures */
-       res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = sizeof(struct bna_rcb);
-       mem_info->num = BNA_GET_RXQS(q_cfg);
-
-       /* Completion QPT */
-       res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = cpage_count * sizeof(struct bna_dma_addr);
-       mem_info->num = q_cfg->num_paths;
-
-       /* Completion s/w QPT */
-       res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = cpage_count * sizeof(void *);
-       mem_info->num = q_cfg->num_paths;
-
-       /* Completion QPT pages */
-       res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = PAGE_SIZE;
-       mem_info->num = cpage_count * q_cfg->num_paths;
-
-       /* Data QPTs */
-       res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = dpage_count * sizeof(struct bna_dma_addr);
-       mem_info->num = q_cfg->num_paths;
-
-       /* Data s/w QPTs */
-       res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = dpage_count * sizeof(void *);
-       mem_info->num = q_cfg->num_paths;
-
-       /* Data QPT pages */
-       res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = PAGE_SIZE;
-       mem_info->num = dpage_count * q_cfg->num_paths;
-
-       /* Hdr QPTs */
-       res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = hpage_count * sizeof(struct bna_dma_addr);
-       mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
-
-       /* Hdr s/w QPTs */
-       res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = hpage_count * sizeof(void *);
-       mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
-
-       /* Hdr QPT pages */
-       res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = (hpage_count ? PAGE_SIZE : 0);
-       mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0);
-
-       /* RX Interrupts */
-       res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR;
-       res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX;
-       res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths;
-}
-
-struct bna_rx *
-bna_rx_create(struct bna *bna, struct bnad *bnad,
-               struct bna_rx_config *rx_cfg,
-               struct bna_rx_event_cbfn *rx_cbfn,
-               struct bna_res_info *res_info,
-               void *priv)
-{
-       struct bna_rx_mod *rx_mod = &bna->rx_mod;
-       struct bna_rx *rx;
-       struct bna_rxp *rxp;
-       struct bna_rxq *q0;
-       struct bna_rxq *q1;
-       struct bna_intr_info *intr_info;
-       u32 page_count;
-       struct bna_mem_descr *ccb_mem;
-       struct bna_mem_descr *rcb_mem;
-       struct bna_mem_descr *unmapq_mem;
-       struct bna_mem_descr *cqpt_mem;
-       struct bna_mem_descr *cswqpt_mem;
-       struct bna_mem_descr *cpage_mem;
-       struct bna_mem_descr *hqpt_mem; /* Header/Small Q qpt */
-       struct bna_mem_descr *dqpt_mem; /* Data/Large Q qpt */
-       struct bna_mem_descr *hsqpt_mem;        /* s/w qpt for hdr */
-       struct bna_mem_descr *dsqpt_mem;        /* s/w qpt for data */
-       struct bna_mem_descr *hpage_mem;        /* hdr page mem */
-       struct bna_mem_descr *dpage_mem;        /* data page mem */
-       int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0;
-       int dpage_count, hpage_count, rcb_idx;
-       struct bna_ib_config ibcfg;
-       /* Fail if we don't have enough RXPs, RXQs */
-       if (!_rx_can_satisfy(rx_mod, rx_cfg))
-               return NULL;
-
-       /* Initialize resource pointers */
-       intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
-       ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0];
-       rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0];
-       unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0];
-       cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0];
-       cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0];
-       cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0];
-       hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0];
-       dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0];
-       hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0];
-       dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0];
-       hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
-       dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];
-
-       /* Compute q depth & page count */
-       page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num /
-                       rx_cfg->num_paths;
-
-       dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num /
-                       rx_cfg->num_paths;
-
-       hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num /
-                       rx_cfg->num_paths;
-       /* Get RX pointer */
-       rx = _get_free_rx(rx_mod);
-       _rx_init(rx, bna);
-       rx->priv = priv;
-       rx->type = rx_cfg->rx_type;
-
-       rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn;
-       rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
-       rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
-       rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
-       /* Following callbacks are mandatory */
-       rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
-       rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;
-
-       if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_STARTED) {
-               switch (rx->type) {
-               case BNA_RX_T_REGULAR:
-                       if (!(rx->bna->rx_mod.flags &
-                               BNA_RX_MOD_F_PORT_LOOPBACK))
-                               rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
-                       break;
-               case BNA_RX_T_LOOPBACK:
-                       if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_LOOPBACK)
-                               rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
-                       break;
-               }
-       }
-
-       for (i = 0, rcb_idx = 0; i < rx_cfg->num_paths; i++) {
-               rxp = _get_free_rxp(rx_mod);
-               rxp->type = rx_cfg->rxp_type;
-               rxp->rx = rx;
-               rxp->cq.rx = rx;
-
-               /* Get required RXQs, and queue them to rx-path */
-               q0 = _get_free_rxq(rx_mod);
-               if (BNA_RXP_SINGLE == rx_cfg->rxp_type)
-                       q1 = NULL;
-               else
-                       q1 = _get_free_rxq(rx_mod);
-
-               /* Initialize IB */
-               if (1 == intr_info->num) {
-                       rxp->cq.ib = bna_ib_get(&bna->ib_mod,
-                                       intr_info->intr_type,
-                                       intr_info->idl[0].vector);
-                       rxp->vector = intr_info->idl[0].vector;
-               } else {
-                       rxp->cq.ib = bna_ib_get(&bna->ib_mod,
-                                       intr_info->intr_type,
-                                       intr_info->idl[i].vector);
-
-                       /* Map the MSI-x vector used for this RXP */
-                       rxp->vector = intr_info->idl[i].vector;
-               }
-
-               rxp->cq.ib_seg_offset = bna_ib_reserve_idx(rxp->cq.ib);
-
-               ibcfg.coalescing_timeo = BFI_RX_COALESCING_TIMEO;
-               ibcfg.interpkt_count = BFI_RX_INTERPKT_COUNT;
-               ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
-               ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE;
-
-               bna_ib_config(rxp->cq.ib, &ibcfg);
-
-               /* Link rxqs to rxp */
-               _rxp_add_rxqs(rxp, q0, q1);
-
-               /* Link rxp to rx */
-               _rx_add_rxp(rx, rxp);
-
-               q0->rx = rx;
-               q0->rxp = rxp;
-
-               /* Initialize RCB for the large / data q */
-               q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
-               RXQ_RCB_INIT(q0, rxp, rx_cfg->q_depth, bna, 0,
-                       (void *)unmapq_mem[rcb_idx].kva);
-               rcb_idx++;
-               (q0)->rx_packets = (q0)->rx_bytes = 0;
-               (q0)->rx_packets_with_error = (q0)->rxbuf_alloc_failed = 0;
-
-               /* Initialize RXQs */
-               _rxq_qpt_init(q0, rxp, dpage_count, PAGE_SIZE,
-                       &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]);
-               q0->rcb->page_idx = dpage_idx;
-               q0->rcb->page_count = dpage_count;
-               dpage_idx += dpage_count;
-
-               /* Call bnad to complete rcb setup */
-               if (rx->rcb_setup_cbfn)
-                       rx->rcb_setup_cbfn(bnad, q0->rcb);
-
-               if (q1) {
-                       q1->rx = rx;
-                       q1->rxp = rxp;
-
-                       q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
-                       RXQ_RCB_INIT(q1, rxp, rx_cfg->q_depth, bna, 1,
-                               (void *)unmapq_mem[rcb_idx].kva);
-                       rcb_idx++;
-                       (q1)->buffer_size = (rx_cfg)->small_buff_size;
-                       (q1)->rx_packets = (q1)->rx_bytes = 0;
-                       (q1)->rx_packets_with_error =
-                               (q1)->rxbuf_alloc_failed = 0;
-
-                       _rxq_qpt_init(q1, rxp, hpage_count, PAGE_SIZE,
-                               &hqpt_mem[i], &hsqpt_mem[i],
-                               &hpage_mem[hpage_idx]);
-                       q1->rcb->page_idx = hpage_idx;
-                       q1->rcb->page_count = hpage_count;
-                       hpage_idx += hpage_count;
-
-                       /* Call bnad to complete rcb setup */
-                       if (rx->rcb_setup_cbfn)
-                               rx->rcb_setup_cbfn(bnad, q1->rcb);
-               }
-               /* Setup RXP::CQ */
-               rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva;
-               _rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
-                       &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]);
-               rxp->cq.ccb->page_idx = cpage_idx;
-               rxp->cq.ccb->page_count = page_count;
-               cpage_idx += page_count;
-
-               rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0;
-               rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0;
-
-               rxp->cq.ccb->producer_index = 0;
-               rxp->cq.ccb->q_depth =  rx_cfg->q_depth +
-                                       ((rx_cfg->rxp_type == BNA_RXP_SINGLE) ?
-                                       0 : rx_cfg->q_depth);
-               rxp->cq.ccb->i_dbell = &rxp->cq.ib->door_bell;
-               rxp->cq.ccb->rcb[0] = q0->rcb;
-               if (q1)
-                       rxp->cq.ccb->rcb[1] = q1->rcb;
-               rxp->cq.ccb->cq = &rxp->cq;
-               rxp->cq.ccb->bnad = bna->bnad;
-               rxp->cq.ccb->hw_producer_index =
-                       ((volatile u32 *)rxp->cq.ib->ib_seg_host_addr_kva +
-                                     (rxp->cq.ib_seg_offset * BFI_IBIDX_SIZE));
-               *(rxp->cq.ccb->hw_producer_index) = 0;
-               rxp->cq.ccb->intr_type = intr_info->intr_type;
-               rxp->cq.ccb->intr_vector = (intr_info->num == 1) ?
-                                               intr_info->idl[0].vector :
-                                               intr_info->idl[i].vector;
-               rxp->cq.ccb->rx_coalescing_timeo =
-                                       rxp->cq.ib->ib_config.coalescing_timeo;
-               rxp->cq.ccb->id = i;
-
-               /* Call bnad to complete CCB setup */
-               if (rx->ccb_setup_cbfn)
-                       rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);
-
-       } /* for each rx-path */
-
-       bna_rxf_init(&rx->rxf, rx, rx_cfg);
-
-       bfa_fsm_set_state(rx, bna_rx_sm_stopped);
-
-       return rx;
-}
-
-void
-bna_rx_destroy(struct bna_rx *rx)
-{
-       struct bna_rx_mod *rx_mod = &rx->bna->rx_mod;
-       struct bna_ib_mod *ib_mod = &rx->bna->ib_mod;
-       struct bna_rxq *q0 = NULL;
-       struct bna_rxq *q1 = NULL;
-       struct bna_rxp *rxp;
-       struct list_head *qe;
-
-       bna_rxf_uninit(&rx->rxf);
-
-       while (!list_empty(&rx->rxp_q)) {
-               bfa_q_deq(&rx->rxp_q, &rxp);
-               GET_RXQS(rxp, q0, q1);
-               /* Callback to bnad for destroying RCB */
-               if (rx->rcb_destroy_cbfn)
-                       rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb);
-               q0->rcb = NULL;
-               q0->rxp = NULL;
-               q0->rx = NULL;
-               _put_free_rxq(rx_mod, q0);
-               if (q1) {
-                       /* Callback to bnad for destroying RCB */
-                       if (rx->rcb_destroy_cbfn)
-                               rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb);
-                       q1->rcb = NULL;
-                       q1->rxp = NULL;
-                       q1->rx = NULL;
-                       _put_free_rxq(rx_mod, q1);
-               }
-               rxp->rxq.slr.large = NULL;
-               rxp->rxq.slr.small = NULL;
-               if (rxp->cq.ib) {
-                       if (rxp->cq.ib_seg_offset != 0xff)
-                               bna_ib_release_idx(rxp->cq.ib,
-                                               rxp->cq.ib_seg_offset);
-                       bna_ib_put(ib_mod, rxp->cq.ib);
-                       rxp->cq.ib = NULL;
-               }
-               /* Callback to bnad for destroying CCB */
-               if (rx->ccb_destroy_cbfn)
-                       rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb);
-               rxp->cq.ccb = NULL;
-               rxp->rx = NULL;
-               _put_free_rxp(rx_mod, rxp);
-       }
-
-       list_for_each(qe, &rx_mod->rx_active_q) {
-               if (qe == &rx->qe) {
-                       list_del(&rx->qe);
-                       bfa_q_qe_init(&rx->qe);
-                       break;
-               }
-       }
-
-       rx->bna = NULL;
-       rx->priv = NULL;
-       _put_free_rx(rx_mod, rx);
-}
-
-void
-bna_rx_enable(struct bna_rx *rx)
-{
-       if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped)
-               return;
-
-       rx->rx_flags |= BNA_RX_F_ENABLE;
-       if (rx->rx_flags & BNA_RX_F_PORT_ENABLED)
-               bfa_fsm_send_event(rx, RX_E_START);
-}
-
-void
-bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
-               void (*cbfn)(void *, struct bna_rx *,
-                               enum bna_cb_status))
-{
-       if (type == BNA_SOFT_CLEANUP) {
-               /* h/w should not be accessed. Treat we're stopped */
-               (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
-       } else {
-               rx->stop_cbfn = cbfn;
-               rx->stop_cbarg = rx->bna->bnad;
-
-               rx->rx_flags &= ~BNA_RX_F_ENABLE;
-
-               bfa_fsm_send_event(rx, RX_E_STOP);
-       }
-}
-
-/**
- * TX
- */
-#define call_tx_stop_cbfn(tx, status)\
-do {\
-       if ((tx)->stop_cbfn)\
-               (tx)->stop_cbfn((tx)->stop_cbarg, (tx), status);\
-       (tx)->stop_cbfn = NULL;\
-       (tx)->stop_cbarg = NULL;\
-} while (0)
-
-#define call_tx_prio_change_cbfn(tx, status)\
-do {\
-       if ((tx)->prio_change_cbfn)\
-               (tx)->prio_change_cbfn((tx)->bna->bnad, (tx), status);\
-       (tx)->prio_change_cbfn = NULL;\
-} while (0)
-
-static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx,
-                                       enum bna_cb_status status);
-static void bna_tx_cb_txq_stopped(void *arg, int status);
-static void bna_tx_cb_stats_cleared(void *arg, int status);
-static void __bna_tx_stop(struct bna_tx *tx);
-static void __bna_tx_start(struct bna_tx *tx);
-static void __bna_txf_stat_clr(struct bna_tx *tx);
-
-enum bna_tx_event {
-       TX_E_START                      = 1,
-       TX_E_STOP                       = 2,
-       TX_E_FAIL                       = 3,
-       TX_E_TXQ_STOPPED                = 4,
-       TX_E_PRIO_CHANGE                = 5,
-       TX_E_STAT_CLEARED               = 6,
-};
-
-enum bna_tx_state {
-       BNA_TX_STOPPED                  = 1,
-       BNA_TX_STARTED                  = 2,
-       BNA_TX_TXQ_STOP_WAIT            = 3,
-       BNA_TX_PRIO_STOP_WAIT           = 4,
-       BNA_TX_STAT_CLR_WAIT            = 5,
-};
-
-bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx,
-                       enum bna_tx_event);
-bfa_fsm_state_decl(bna_tx, started, struct bna_tx,
-                       enum bna_tx_event);
-bfa_fsm_state_decl(bna_tx, txq_stop_wait, struct bna_tx,
-                       enum bna_tx_event);
-bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx,
-                       enum bna_tx_event);
-bfa_fsm_state_decl(bna_tx, stat_clr_wait, struct bna_tx,
-                       enum bna_tx_event);
-
-static struct bfa_sm_table tx_sm_table[] = {
-       {BFA_SM(bna_tx_sm_stopped), BNA_TX_STOPPED},
-       {BFA_SM(bna_tx_sm_started), BNA_TX_STARTED},
-       {BFA_SM(bna_tx_sm_txq_stop_wait), BNA_TX_TXQ_STOP_WAIT},
-       {BFA_SM(bna_tx_sm_prio_stop_wait), BNA_TX_PRIO_STOP_WAIT},
-       {BFA_SM(bna_tx_sm_stat_clr_wait), BNA_TX_STAT_CLR_WAIT},
-};
-
-static void
-bna_tx_sm_stopped_entry(struct bna_tx *tx)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
-       }
-
-       call_tx_stop_cbfn(tx, BNA_CB_SUCCESS);
-}
-
-static void
-bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
-{
-       switch (event) {
-       case TX_E_START:
-               bfa_fsm_set_state(tx, bna_tx_sm_started);
-               break;
-
-       case TX_E_STOP:
-               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
-               break;
-
-       case TX_E_FAIL:
-               /* No-op */
-               break;
-
-       case TX_E_PRIO_CHANGE:
-               call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
-               break;
-
-       case TX_E_TXQ_STOPPED:
-               /**
-                * This event is received due to flushing of mbox when
-                * device fails
-                */
-               /* No-op */
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_tx_sm_started_entry(struct bna_tx *tx)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       __bna_tx_start(tx);
-
-       /* Start IB */
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               bna_ib_ack(&txq->ib->door_bell, 0);
-       }
-}
-
-static void
-bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       switch (event) {
-       case TX_E_STOP:
-               bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
-               __bna_tx_stop(tx);
-               break;
-
-       case TX_E_FAIL:
-               list_for_each(qe, &tx->txq_q) {
-                       txq = (struct bna_txq *)qe;
-                       bna_ib_fail(txq->ib);
-                       (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
-               }
-               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
-               break;
-
-       case TX_E_PRIO_CHANGE:
-               bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_tx_sm_txq_stop_wait_entry(struct bna_tx *tx)
-{
-}
-
-static void
-bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       switch (event) {
-       case TX_E_FAIL:
-               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
-               break;
-
-       case TX_E_TXQ_STOPPED:
-               list_for_each(qe, &tx->txq_q) {
-                       txq = (struct bna_txq *)qe;
-                       bna_ib_stop(txq->ib);
-               }
-               bfa_fsm_set_state(tx, bna_tx_sm_stat_clr_wait);
-               break;
-
-       case TX_E_PRIO_CHANGE:
-               /* No-op */
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx)
-{
-       __bna_tx_stop(tx);
-}
-
-static void
-bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       switch (event) {
-       case TX_E_STOP:
-               bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
-               break;
-
-       case TX_E_FAIL:
-               call_tx_prio_change_cbfn(tx, BNA_CB_FAIL);
-               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
-               break;
-
-       case TX_E_TXQ_STOPPED:
-               list_for_each(qe, &tx->txq_q) {
-                       txq = (struct bna_txq *)qe;
-                       bna_ib_stop(txq->ib);
-                       (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
-               }
-               call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
-               bfa_fsm_set_state(tx, bna_tx_sm_started);
-               break;
-
-       case TX_E_PRIO_CHANGE:
-               /* No-op */
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-bna_tx_sm_stat_clr_wait_entry(struct bna_tx *tx)
-{
-       __bna_txf_stat_clr(tx);
-}
-
-static void
-bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event)
-{
-       switch (event) {
-       case TX_E_FAIL:
-       case TX_E_STAT_CLEARED:
-               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
-               break;
-
-       default:
-               bfa_sm_fault(event);
-       }
-}
-
-static void
-__bna_txq_start(struct bna_tx *tx, struct bna_txq *txq)
-{
-       struct bna_rxtx_q_mem *q_mem;
-       struct bna_txq_mem txq_cfg;
-       struct bna_txq_mem *txq_mem;
-       struct bna_dma_addr cur_q_addr;
-       u32 pg_num;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       /* Fill out structure, to be subsequently written to hardware */
-       txq_cfg.pg_tbl_addr_lo = txq->qpt.hw_qpt_ptr.lsb;
-       txq_cfg.pg_tbl_addr_hi = txq->qpt.hw_qpt_ptr.msb;
-       cur_q_addr = *((struct bna_dma_addr *)(txq->qpt.kv_qpt_ptr));
-       txq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
-       txq_cfg.cur_q_entry_hi = cur_q_addr.msb;
-
-       txq_cfg.pg_cnt_n_prd_ptr = (txq->qpt.page_count << 16) | 0x0;
-
-       txq_cfg.entry_n_pg_size = ((u32)(BFI_TXQ_WI_SIZE >> 2) << 16) |
-                       (txq->qpt.page_size >> 2);
-       txq_cfg.int_blk_n_cns_ptr = ((((u32)txq->ib_seg_offset) << 24) |
-                       ((u32)(txq->ib->ib_id & 0xff) << 16) | 0x0);
-
-       txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE;
-       txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) |
-                       (txq->priority & 0x7));
-       txq_cfg.wvc_n_cquota_n_rquota =
-                       ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) |
-                       (BFI_TX_MAX_WRR_QUOTA & 0xfff));
-
-       /* Setup the page and write to H/W */
-
-       pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + tx->bna->port_num,
-                       HQM_RXTX_Q_RAM_BASE_OFFSET);
-       writel(pg_num, tx->bna->regs.page_addr);
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
-                                       HQM_RXTX_Q_RAM_BASE_OFFSET);
-       q_mem = (struct bna_rxtx_q_mem *)0;
-       txq_mem = &q_mem[txq->txq_id].txq;
-
-       /*
-        * The following 4 lines, is a hack b'cos the H/W needs to read
-        * these DMA addresses as little endian
-        */
-
-       off = (unsigned long)&txq_mem->pg_tbl_addr_lo;
-       writel(htonl(txq_cfg.pg_tbl_addr_lo), base_addr + off);
-
-       off = (unsigned long)&txq_mem->pg_tbl_addr_hi;
-       writel(htonl(txq_cfg.pg_tbl_addr_hi), base_addr + off);
-
-       off = (unsigned long)&txq_mem->cur_q_entry_lo;
-       writel(htonl(txq_cfg.cur_q_entry_lo), base_addr + off);
-
-       off = (unsigned long)&txq_mem->cur_q_entry_hi;
-       writel(htonl(txq_cfg.cur_q_entry_hi), base_addr + off);
-
-       off = (unsigned long)&txq_mem->pg_cnt_n_prd_ptr;
-       writel(txq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
-
-       off = (unsigned long)&txq_mem->entry_n_pg_size;
-       writel(txq_cfg.entry_n_pg_size, base_addr + off);
-
-       off = (unsigned long)&txq_mem->int_blk_n_cns_ptr;
-       writel(txq_cfg.int_blk_n_cns_ptr, base_addr + off);
-
-       off = (unsigned long)&txq_mem->cns_ptr2_n_q_state;
-       writel(txq_cfg.cns_ptr2_n_q_state, base_addr + off);
-
-       off = (unsigned long)&txq_mem->nxt_qid_n_fid_n_pri;
-       writel(txq_cfg.nxt_qid_n_fid_n_pri, base_addr + off);
-
-       off = (unsigned long)&txq_mem->wvc_n_cquota_n_rquota;
-       writel(txq_cfg.wvc_n_cquota_n_rquota, base_addr + off);
-
-       txq->tcb->producer_index = 0;
-       txq->tcb->consumer_index = 0;
-       *(txq->tcb->hw_consumer_index) = 0;
-
-}
-
-static void
-__bna_txq_stop(struct bna_tx *tx, struct bna_txq *txq)
-{
-       struct bfi_ll_q_stop_req ll_req;
-       u32 bit_mask[2] = {0, 0};
-       if (txq->txq_id < 32)
-               bit_mask[0] = (u32)1 << txq->txq_id;
-       else
-               bit_mask[1] = (u32)1 << (txq->txq_id - 32);
-
-       memset(&ll_req, 0, sizeof(ll_req));
-       ll_req.mh.msg_class = BFI_MC_LL;
-       ll_req.mh.msg_id = BFI_LL_H2I_TXQ_STOP_REQ;
-       ll_req.mh.mtag.h2i.lpu_id = 0;
-       ll_req.q_id_mask[0] = htonl(bit_mask[0]);
-       ll_req.q_id_mask[1] = htonl(bit_mask[1]);
-
-       bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
-                       bna_tx_cb_txq_stopped, tx);
-
-       bna_mbox_send(tx->bna, &tx->mbox_qe);
-}
-
-static void
-__bna_txf_start(struct bna_tx *tx)
-{
-       struct bna_tx_fndb_ram *tx_fndb;
-       struct bna_txf *txf = &tx->txf;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
-                       (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET),
-                       tx->bna->regs.page_addr);
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
-                                       TX_FNDB_RAM_BASE_OFFSET);
-
-       tx_fndb = (struct bna_tx_fndb_ram *)0;
-       off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;
-
-       writel(((u32)txf->vlan << 16) | txf->ctrl_flags,
-                       base_addr + off);
-
-       if (tx->txf.txf_id < 32)
-               tx->bna->tx_mod.txf_bmap[0] |= ((u32)1 << tx->txf.txf_id);
-       else
-               tx->bna->tx_mod.txf_bmap[1] |= ((u32)
-                                                1 << (tx->txf.txf_id - 32));
-}
-
-static void
-__bna_txf_stop(struct bna_tx *tx)
-{
-       struct bna_tx_fndb_ram *tx_fndb;
-       u32 page_num;
-       u32 ctl_flags;
-       struct bna_txf *txf = &tx->txf;
-       void __iomem *base_addr;
-       unsigned long off;
-
-       /* retrieve the running txf_flags & turn off enable bit */
-       page_num = BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
-                       (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET);
-       writel(page_num, tx->bna->regs.page_addr);
-
-       base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
-                                       TX_FNDB_RAM_BASE_OFFSET);
-       tx_fndb = (struct bna_tx_fndb_ram *)0;
-       off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;
-
-       ctl_flags = readl(base_addr + off);
-       ctl_flags &= ~BFI_TXF_CF_ENABLE;
-
-       writel(ctl_flags, base_addr + off);
-
-       if (tx->txf.txf_id < 32)
-               tx->bna->tx_mod.txf_bmap[0] &= ~((u32)1 << tx->txf.txf_id);
-       else
-               tx->bna->tx_mod.txf_bmap[0] &= ~((u32)
-                                                1 << (tx->txf.txf_id - 32));
-}
-
-static void
-__bna_txf_stat_clr(struct bna_tx *tx)
-{
-       struct bfi_ll_stats_req ll_req;
-       u32 txf_bmap[2] = {0, 0};
-       if (tx->txf.txf_id < 32)
-               txf_bmap[0] = ((u32)1 << tx->txf.txf_id);
-       else
-               txf_bmap[1] = ((u32)1 << (tx->txf.txf_id - 32));
-       bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
-       ll_req.stats_mask = 0;
-       ll_req.rxf_id_mask[0] = 0;
-       ll_req.rxf_id_mask[1] = 0;
-       ll_req.txf_id_mask[0] = htonl(txf_bmap[0]);
-       ll_req.txf_id_mask[1] = htonl(txf_bmap[1]);
-
-       bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
-                       bna_tx_cb_stats_cleared, tx);
-       bna_mbox_send(tx->bna, &tx->mbox_qe);
-}
-
-static void
-__bna_tx_start(struct bna_tx *tx)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               bna_ib_start(txq->ib);
-               __bna_txq_start(tx, txq);
-       }
-
-       __bna_txf_start(tx);
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               txq->tcb->priority = txq->priority;
-               (tx->tx_resume_cbfn)(tx->bna->bnad, txq->tcb);
-       }
-}
-
-static void
-__bna_tx_stop(struct bna_tx *tx)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
-       }
-
-       __bna_txf_stop(tx);
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               bfa_wc_up(&tx->txq_stop_wc);
-       }
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               __bna_txq_stop(tx, txq);
-       }
-}
-
-static void
-bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
-               struct bna_mem_descr *qpt_mem,
-               struct bna_mem_descr *swqpt_mem,
-               struct bna_mem_descr *page_mem)
-{
-       int i;
-
-       txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
-       txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
-       txq->qpt.kv_qpt_ptr = qpt_mem->kva;
-       txq->qpt.page_count = page_count;
-       txq->qpt.page_size = page_size;
-
-       txq->tcb->sw_qpt = (void **) swqpt_mem->kva;
-
-       for (i = 0; i < page_count; i++) {
-               txq->tcb->sw_qpt[i] = page_mem[i].kva;
-
-               ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
-                       page_mem[i].dma.lsb;
-               ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
-                       page_mem[i].dma.msb;
-
-       }
-}
-
-static void
-bna_tx_free(struct bna_tx *tx)
-{
-       struct bna_tx_mod *tx_mod = &tx->bna->tx_mod;
-       struct bna_txq *txq;
-       struct bna_ib_mod *ib_mod = &tx->bna->ib_mod;
-       struct list_head *qe;
-
-       while (!list_empty(&tx->txq_q)) {
-               bfa_q_deq(&tx->txq_q, &txq);
-               bfa_q_qe_init(&txq->qe);
-               if (txq->ib) {
-                       if (txq->ib_seg_offset != -1)
-                               bna_ib_release_idx(txq->ib,
-                                               txq->ib_seg_offset);
-                       bna_ib_put(ib_mod, txq->ib);
-                       txq->ib = NULL;
-               }
-               txq->tcb = NULL;
-               txq->tx = NULL;
-               list_add_tail(&txq->qe, &tx_mod->txq_free_q);
-       }
-
-       list_for_each(qe, &tx_mod->tx_active_q) {
-               if (qe == &tx->qe) {
-                       list_del(&tx->qe);
-                       bfa_q_qe_init(&tx->qe);
-                       break;
-               }
-       }
-
-       tx->bna = NULL;
-       tx->priv = NULL;
-       list_add_tail(&tx->qe, &tx_mod->tx_free_q);
-}
-
-static void
-bna_tx_cb_txq_stopped(void *arg, int status)
-{
-       struct bna_tx *tx = (struct bna_tx *)arg;
-
-       bfa_q_qe_init(&tx->mbox_qe.qe);
-       bfa_wc_down(&tx->txq_stop_wc);
-}
-
-static void
-bna_tx_cb_txq_stopped_all(void *arg)
-{
-       struct bna_tx *tx = (struct bna_tx *)arg;
-
-       bfa_fsm_send_event(tx, TX_E_TXQ_STOPPED);
-}
-
-static void
-bna_tx_cb_stats_cleared(void *arg, int status)
-{
-       struct bna_tx *tx = (struct bna_tx *)arg;
-
-       bfa_q_qe_init(&tx->mbox_qe.qe);
-
-       bfa_fsm_send_event(tx, TX_E_STAT_CLEARED);
-}
-
-static void
-bna_tx_start(struct bna_tx *tx)
-{
-       tx->flags |= BNA_TX_F_PORT_STARTED;
-       if (tx->flags & BNA_TX_F_ENABLED)
-               bfa_fsm_send_event(tx, TX_E_START);
-}
-
-static void
-bna_tx_stop(struct bna_tx *tx)
-{
-       tx->stop_cbfn = bna_tx_mod_cb_tx_stopped;
-       tx->stop_cbarg = &tx->bna->tx_mod;
-
-       tx->flags &= ~BNA_TX_F_PORT_STARTED;
-       bfa_fsm_send_event(tx, TX_E_STOP);
-}
-
-static void
-bna_tx_fail(struct bna_tx *tx)
-{
-       tx->flags &= ~BNA_TX_F_PORT_STARTED;
-       bfa_fsm_send_event(tx, TX_E_FAIL);
-}
-
-static void
-bna_tx_prio_changed(struct bna_tx *tx, int prio)
-{
-       struct bna_txq *txq;
-       struct list_head                 *qe;
-
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               txq->priority = prio;
-       }
-
-       bfa_fsm_send_event(tx, TX_E_PRIO_CHANGE);
-}
-
-static void
-bna_tx_cee_link_status(struct bna_tx *tx, int cee_link)
-{
-       if (cee_link)
-               tx->flags |= BNA_TX_F_PRIO_LOCK;
-       else
-               tx->flags &= ~BNA_TX_F_PRIO_LOCK;
-}
-
-static void
-bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx,
-                       enum bna_cb_status status)
-{
-       struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
-
-       bfa_wc_down(&tx_mod->tx_stop_wc);
-}
-
-static void
-bna_tx_mod_cb_tx_stopped_all(void *arg)
-{
-       struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
-
-       if (tx_mod->stop_cbfn)
-               tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
-       tx_mod->stop_cbfn = NULL;
-}
-
-void
-bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
-{
-       u32 q_size;
-       u32 page_count;
-       struct bna_mem_info *mem_info;
-
-       res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = sizeof(struct bna_tcb);
-       mem_info->num = num_txq;
-
-       q_size = txq_depth * BFI_TXQ_WI_SIZE;
-       q_size = ALIGN(q_size, PAGE_SIZE);
-       page_count = q_size >> PAGE_SHIFT;
-
-       res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = page_count * sizeof(struct bna_dma_addr);
-       mem_info->num = num_txq;
-
-       res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_KVA;
-       mem_info->len = page_count * sizeof(void *);
-       mem_info->num = num_txq;
-
-       res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
-       mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
-       mem_info->mem_type = BNA_MEM_T_DMA;
-       mem_info->len = PAGE_SIZE;
-       mem_info->num = num_txq * page_count;
-
-       res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR;
-       res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type =
-                       BNA_INTR_T_MSIX;
-       res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq;
-}
-
-struct bna_tx *
-bna_tx_create(struct bna *bna, struct bnad *bnad,
-               struct bna_tx_config *tx_cfg,
-               struct bna_tx_event_cbfn *tx_cbfn,
-               struct bna_res_info *res_info, void *priv)
-{
-       struct bna_intr_info *intr_info;
-       struct bna_tx_mod *tx_mod = &bna->tx_mod;
-       struct bna_tx *tx;
-       struct bna_txq *txq;
-       struct list_head *qe;
-       struct bna_ib_mod *ib_mod = &bna->ib_mod;
-       struct bna_doorbell_qset *qset;
-       struct bna_ib_config ib_config;
-       int page_count;
-       int page_size;
-       int page_idx;
-       int i;
-       unsigned long off;
-
-       intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
-       page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) /
-                       tx_cfg->num_txq;
-       page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len;
-
-       /**
-        * Get resources
-        */
-
-       if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq))
-               return NULL;
-
-       /* Tx */
-
-       if (list_empty(&tx_mod->tx_free_q))
-               return NULL;
-       bfa_q_deq(&tx_mod->tx_free_q, &tx);
-       bfa_q_qe_init(&tx->qe);
-
-       /* TxQs */
-
-       INIT_LIST_HEAD(&tx->txq_q);
-       for (i = 0; i < tx_cfg->num_txq; i++) {
-               if (list_empty(&tx_mod->txq_free_q))
-                       goto err_return;
-
-               bfa_q_deq(&tx_mod->txq_free_q, &txq);
-               bfa_q_qe_init(&txq->qe);
-               list_add_tail(&txq->qe, &tx->txq_q);
-               txq->ib = NULL;
-               txq->ib_seg_offset = -1;
-               txq->tx = tx;
-       }
-
-       /* IBs */
-       i = 0;
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-
-               if (intr_info->num == 1)
-                       txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
-                                               intr_info->idl[0].vector);
-               else
-                       txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
-                                               intr_info->idl[i].vector);
-
-               if (txq->ib == NULL)
-                       goto err_return;
-
-               txq->ib_seg_offset = bna_ib_reserve_idx(txq->ib);
-               if (txq->ib_seg_offset == -1)
-                       goto err_return;
-
-               i++;
-       }
-
-       /*
-        * Initialize
-        */
-
-       /* Tx */
-
-       tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn;
-       tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn;
-       /* Following callbacks are mandatory */
-       tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn;
-       tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn;
-       tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn;
-
-       list_add_tail(&tx->qe, &tx_mod->tx_active_q);
-       tx->bna = bna;
-       tx->priv = priv;
-       tx->txq_stop_wc.wc_resume = bna_tx_cb_txq_stopped_all;
-       tx->txq_stop_wc.wc_cbarg = tx;
-       tx->txq_stop_wc.wc_count = 0;
-
-       tx->type = tx_cfg->tx_type;
-
-       tx->flags = 0;
-       if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_STARTED) {
-               switch (tx->type) {
-               case BNA_TX_T_REGULAR:
-                       if (!(tx->bna->tx_mod.flags &
-                               BNA_TX_MOD_F_PORT_LOOPBACK))
-                               tx->flags |= BNA_TX_F_PORT_STARTED;
-                       break;
-               case BNA_TX_T_LOOPBACK:
-                       if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_LOOPBACK)
-                               tx->flags |= BNA_TX_F_PORT_STARTED;
-                       break;
-               }
-       }
-       if (tx->bna->tx_mod.cee_link)
-               tx->flags |= BNA_TX_F_PRIO_LOCK;
-
-       /* TxQ */
-
-       i = 0;
-       page_idx = 0;
-       list_for_each(qe, &tx->txq_q) {
-               txq = (struct bna_txq *)qe;
-               txq->priority = tx_mod->priority;
-               txq->tcb = (struct bna_tcb *)
-                 res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva;
-               txq->tx_packets = 0;
-               txq->tx_bytes = 0;
-
-               /* IB */
-
-               ib_config.coalescing_timeo = BFI_TX_COALESCING_TIMEO;
-               ib_config.interpkt_timeo = 0; /* Not used */
-               ib_config.interpkt_count = BFI_TX_INTERPKT_COUNT;
-               ib_config.ctrl_flags = (BFI_IB_CF_INTER_PKT_DMA |
-                                       BFI_IB_CF_INT_ENABLE |
-                                       BFI_IB_CF_COALESCING_MODE);
-               bna_ib_config(txq->ib, &ib_config);
-
-               /* TCB */
-
-               txq->tcb->producer_index = 0;
-               txq->tcb->consumer_index = 0;
-               txq->tcb->hw_consumer_index = (volatile u32 *)
-                       ((volatile u8 *)txq->ib->ib_seg_host_addr_kva +
-                        (txq->ib_seg_offset * BFI_IBIDX_SIZE));
-               *(txq->tcb->hw_consumer_index) = 0;
-               txq->tcb->q_depth = tx_cfg->txq_depth;
-               txq->tcb->unmap_q = (void *)
-               res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva;
-               qset = (struct bna_doorbell_qset *)0;
-               off = (unsigned long)&qset[txq->txq_id].txq[0];
-               txq->tcb->q_dbell = off +
-                       BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
-               txq->tcb->i_dbell = &txq->ib->door_bell;
-               txq->tcb->intr_type = intr_info->intr_type;
-               txq->tcb->intr_vector = (intr_info->num == 1) ?
-                                       intr_info->idl[0].vector :
-                                       intr_info->idl[i].vector;
-               txq->tcb->txq = txq;
-               txq->tcb->bnad = bnad;
-               txq->tcb->id = i;
-
-               /* QPT, SWQPT, Pages */
-               bna_txq_qpt_setup(txq, page_count, page_size,
-                       &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
-                       &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
-                       &res_info[BNA_TX_RES_MEM_T_PAGE].
-                                 res_u.mem_info.mdl[page_idx]);
-               txq->tcb->page_idx = page_idx;
-               txq->tcb->page_count = page_count;
-               page_idx += page_count;
-
-               /* Callback to bnad for setting up TCB */
-               if (tx->tcb_setup_cbfn)
-                       (tx->tcb_setup_cbfn)(bna->bnad, txq->tcb);
-
-               i++;
-       }
-
-       /* TxF */
-
-       tx->txf.ctrl_flags = BFI_TXF_CF_ENABLE | BFI_TXF_CF_VLAN_WI_BASED;
-       tx->txf.vlan = 0;
-
-       /* Mbox element */
-       bfa_q_qe_init(&tx->mbox_qe.qe);
-
-       bfa_fsm_set_state(tx, bna_tx_sm_stopped);
-
-       return tx;
-
-err_return:
-       bna_tx_free(tx);
-       return NULL;
-}
-
-void
-bna_tx_destroy(struct bna_tx *tx)
-{
-       /* Callback to bnad for destroying TCB */
-       if (tx->tcb_destroy_cbfn) {
-               struct bna_txq *txq;
-               struct list_head *qe;
-
-               list_for_each(qe, &tx->txq_q) {
-                       txq = (struct bna_txq *)qe;
-                       (tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb);
-               }
-       }
-
-       bna_tx_free(tx);
-}
-
-void
-bna_tx_enable(struct bna_tx *tx)
-{
-       if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped)
-               return;
-
-       tx->flags |= BNA_TX_F_ENABLED;
-
-       if (tx->flags & BNA_TX_F_PORT_STARTED)
-               bfa_fsm_send_event(tx, TX_E_START);
-}
-
-void
-bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
-               void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status))
-{
-       if (type == BNA_SOFT_CLEANUP) {
-               (*cbfn)(tx->bna->bnad, tx, BNA_CB_SUCCESS);
-               return;
-       }
-
-       tx->stop_cbfn = cbfn;
-       tx->stop_cbarg = tx->bna->bnad;
-
-       tx->flags &= ~BNA_TX_F_ENABLED;
-
-       bfa_fsm_send_event(tx, TX_E_STOP);
-}
-
-int
-bna_tx_state_get(struct bna_tx *tx)
-{
-       return bfa_sm_to_state(tx_sm_table, tx->fsm);
-}
-
-void
-bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
-               struct bna_res_info *res_info)
-{
-       int i;
-
-       tx_mod->bna = bna;
-       tx_mod->flags = 0;
-
-       tx_mod->tx = (struct bna_tx *)
-               res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva;
-       tx_mod->txq = (struct bna_txq *)
-               res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva;
-
-       INIT_LIST_HEAD(&tx_mod->tx_free_q);
-       INIT_LIST_HEAD(&tx_mod->tx_active_q);
-
-       INIT_LIST_HEAD(&tx_mod->txq_free_q);
-
-       for (i = 0; i < BFI_MAX_TXQ; i++) {
-               tx_mod->tx[i].txf.txf_id = i;
-               bfa_q_qe_init(&tx_mod->tx[i].qe);
-               list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q);
-
-               tx_mod->txq[i].txq_id = i;
-               bfa_q_qe_init(&tx_mod->txq[i].qe);
-               list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q);
-       }
-
-       tx_mod->tx_stop_wc.wc_resume = bna_tx_mod_cb_tx_stopped_all;
-       tx_mod->tx_stop_wc.wc_cbarg = tx_mod;
-       tx_mod->tx_stop_wc.wc_count = 0;
-}
-
-void
-bna_tx_mod_uninit(struct bna_tx_mod *tx_mod)
-{
-       struct list_head                *qe;
-       int i;
-
-       i = 0;
-       list_for_each(qe, &tx_mod->tx_free_q)
-               i++;
-
-       i = 0;
-       list_for_each(qe, &tx_mod->txq_free_q)
-               i++;
-
-       tx_mod->bna = NULL;
-}
-
-void
-bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
-{
-       struct bna_tx *tx;
-       struct list_head                *qe;
-
-       tx_mod->flags |= BNA_TX_MOD_F_PORT_STARTED;
-       if (type == BNA_TX_T_LOOPBACK)
-               tx_mod->flags |= BNA_TX_MOD_F_PORT_LOOPBACK;
-
-       list_for_each(qe, &tx_mod->tx_active_q) {
-               tx = (struct bna_tx *)qe;
-               if (tx->type == type)
-                       bna_tx_start(tx);
-       }
-}
-
-void
-bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
-{
-       struct bna_tx *tx;
-       struct list_head                *qe;
-
-       tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
-       tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;
-
-       tx_mod->stop_cbfn = bna_port_cb_tx_stopped;
-
-       /**
-        * Before calling bna_tx_stop(), increment tx_stop_wc as many times
-        * as we are going to call bna_tx_stop
-        */
-       list_for_each(qe, &tx_mod->tx_active_q) {
-               tx = (struct bna_tx *)qe;
-               if (tx->type == type)
-                       bfa_wc_up(&tx_mod->tx_stop_wc);
-       }
-
-       if (tx_mod->tx_stop_wc.wc_count == 0) {
-               tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
-               tx_mod->stop_cbfn = NULL;
-               return;
-       }
-
-       list_for_each(qe, &tx_mod->tx_active_q) {
-               tx = (struct bna_tx *)qe;
-               if (tx->type == type)
-                       bna_tx_stop(tx);
-       }
-}
-
-void
-bna_tx_mod_fail(struct bna_tx_mod *tx_mod)
-{
-       struct bna_tx *tx;
-       struct list_head                *qe;
-
-       tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
-       tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;
-
-       list_for_each(qe, &tx_mod->tx_active_q) {
-               tx = (struct bna_tx *)qe;
-               bna_tx_fail(tx);
-       }
-}
-
-void
-bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio)
-{
-       struct bna_tx *tx;
-       struct list_head                *qe;
-
-       if (prio != tx_mod->priority) {
-               tx_mod->priority = prio;
-
-               list_for_each(qe, &tx_mod->tx_active_q) {
-                       tx = (struct bna_tx *)qe;
-                       bna_tx_prio_changed(tx, prio);
-               }
-       }
-}
-
-void
-bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link)
-{
-       struct bna_tx *tx;
-       struct list_head                *qe;
-
-       tx_mod->cee_link = cee_link;
-
-       list_for_each(qe, &tx_mod->tx_active_q) {
-               tx = (struct bna_tx *)qe;
-               bna_tx_cee_link_status(tx, cee_link);
-       }
-}
index 38a83acd502e6395f06257cff0fa39cde757fa40..8cb75a6efec35337830f08c74ccb1a9f4f1d8e1c 100644 (file)
@@ -3419,9 +3419,27 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count)
 static int bond_open(struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
+       struct slave *slave;
+       int i;
 
        bond->kill_timers = 0;
 
+       /* reset slave->backup and slave->inactive */
+       read_lock(&bond->lock);
+       if (bond->slave_cnt > 0) {
+               read_lock(&bond->curr_slave_lock);
+               bond_for_each_slave(bond, slave, i) {
+                       if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+                               && (slave != bond->curr_active_slave)) {
+                               bond_set_slave_inactive_flags(slave);
+                       } else {
+                               bond_set_slave_active_flags(slave);
+                       }
+               }
+               read_unlock(&bond->curr_slave_lock);
+       }
+       read_unlock(&bond->lock);
+
        INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);
 
        if (bond_is_lb(bond)) {
@@ -3686,44 +3704,27 @@ static bool bond_addr_in_mc_list(unsigned char *addr,
        return false;
 }
 
-static void bond_set_multicast_list(struct net_device *bond_dev)
+static void bond_change_rx_flags(struct net_device *bond_dev, int change)
 {
        struct bonding *bond = netdev_priv(bond_dev);
-       struct netdev_hw_addr *ha;
-       bool found;
 
-       /*
-        * Do promisc before checking multicast_mode
-        */
-       if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC))
-               /*
-                * FIXME: Need to handle the error when one of the multi-slaves
-                * encounters error.
-                */
-               bond_set_promiscuity(bond, 1);
+       if (change & IFF_PROMISC)
+               bond_set_promiscuity(bond,
+                                    bond_dev->flags & IFF_PROMISC ? 1 : -1);
 
+       if (change & IFF_ALLMULTI)
+               bond_set_allmulti(bond,
+                                 bond_dev->flags & IFF_ALLMULTI ? 1 : -1);
+}
 
-       if (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC))
-               bond_set_promiscuity(bond, -1);
-
-
-       /* set allmulti flag to slaves */
-       if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI))
-               /*
-                * FIXME: Need to handle the error when one of the multi-slaves
-                * encounters error.
-                */
-               bond_set_allmulti(bond, 1);
-
-
-       if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI))
-               bond_set_allmulti(bond, -1);
-
+static void bond_set_multicast_list(struct net_device *bond_dev)
+{
+       struct bonding *bond = netdev_priv(bond_dev);
+       struct netdev_hw_addr *ha;
+       bool found;
 
        read_lock(&bond->lock);
 
-       bond->flags = bond_dev->flags;
-
        /* looking for addresses to add to slaves' mc list */
        netdev_for_each_mc_addr(ha, bond_dev) {
                found = bond_addr_in_mc_list(ha->addr, &bond->mc_list,
@@ -4282,7 +4283,8 @@ static const struct net_device_ops bond_netdev_ops = {
        .ndo_select_queue       = bond_select_queue,
        .ndo_get_stats64        = bond_get_stats,
        .ndo_do_ioctl           = bond_do_ioctl,
-       .ndo_set_multicast_list = bond_set_multicast_list,
+       .ndo_change_rx_flags    = bond_change_rx_flags,
+       .ndo_set_rx_mode        = bond_set_multicast_list,
        .ndo_change_mtu         = bond_change_mtu,
        .ndo_set_mac_address    = bond_set_mac_address,
        .ndo_neigh_setup        = bond_neigh_setup,
@@ -4828,11 +4830,20 @@ static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
        return 0;
 }
 
+static int bond_get_tx_queues(struct net *net, struct nlattr *tb[],
+                             unsigned int *num_queues,
+                             unsigned int *real_num_queues)
+{
+       *num_queues = tx_queues;
+       return 0;
+}
+
 static struct rtnl_link_ops bond_link_ops __read_mostly = {
        .kind           = "bond",
        .priv_size      = sizeof(struct bonding),
        .setup          = bond_setup,
        .validate       = bond_validate,
+       .get_tx_queues  = bond_get_tx_queues,
 };
 
 /* Create a new bond based on the specified name and bonding parameters.
index 43526a2d275cf23240612da5f2621409fe629ebe..e82336615600fb99af65f64b49ef0f92bece71e2 100644 (file)
@@ -234,7 +234,6 @@ struct bonding {
        struct   netdev_hw_addr_list mc_list;
        int      (*xmit_hash_policy)(struct sk_buff *, int);
        __be32   master_ip;
-       u16      flags;
        u16      rr_tx_counter;
        struct   ad_bond_info ad_info;
        struct   alb_bond_info alb_info;
index 17678117ed69dba42d02339ec76b962bf25f1695..e02337953f41b93b3c8f8e300e26adef196ef6f6 100644 (file)
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 
-#include <mach/clock.h>
-
 #define DRV_NAME                       "flexcan"
 
 /* 8 for RX fifo and 2 error handling */
@@ -191,6 +190,31 @@ static struct can_bittiming_const flexcan_bittiming_const = {
        .brp_inc = 1,
 };
 
+/*
+ * Abstract off the read/write for arm versus ppc.
+ */
+#if defined(__BIG_ENDIAN)
+static inline u32 flexcan_read(void __iomem *addr)
+{
+       return in_be32(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+       out_be32(addr, val);
+}
+#else
+static inline u32 flexcan_read(void __iomem *addr)
+{
+       return readl(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+       writel(val, addr);
+}
+#endif
+
 /*
  * Swtich transceiver on or off
  */
@@ -212,9 +236,9 @@ static inline void flexcan_chip_enable(struct flexcan_priv *priv)
        struct flexcan_regs __iomem *regs = priv->base;
        u32 reg;
 
-       reg = readl(&regs->mcr);
+       reg = flexcan_read(&regs->mcr);
        reg &= ~FLEXCAN_MCR_MDIS;
-       writel(reg, &regs->mcr);
+       flexcan_write(reg, &regs->mcr);
 
        udelay(10);
 }
@@ -224,9 +248,9 @@ static inline void flexcan_chip_disable(struct flexcan_priv *priv)
        struct flexcan_regs __iomem *regs = priv->base;
        u32 reg;
 
-       reg = readl(&regs->mcr);
+       reg = flexcan_read(&regs->mcr);
        reg |= FLEXCAN_MCR_MDIS;
-       writel(reg, &regs->mcr);
+       flexcan_write(reg, &regs->mcr);
 }
 
 static int flexcan_get_berr_counter(const struct net_device *dev,
@@ -234,7 +258,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
 {
        const struct flexcan_priv *priv = netdev_priv(dev);
        struct flexcan_regs __iomem *regs = priv->base;
-       u32 reg = readl(&regs->ecr);
+       u32 reg = flexcan_read(&regs->ecr);
 
        bec->txerr = (reg >> 0) & 0xff;
        bec->rxerr = (reg >> 8) & 0xff;
@@ -268,15 +292,15 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (cf->can_dlc > 0) {
                u32 data = be32_to_cpup((__be32 *)&cf->data[0]);
-               writel(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
+               flexcan_write(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
        }
        if (cf->can_dlc > 3) {
                u32 data = be32_to_cpup((__be32 *)&cf->data[4]);
-               writel(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
+               flexcan_write(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
        }
 
-       writel(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
-       writel(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
+       flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
+       flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
 
        kfree_skb(skb);
 
@@ -464,8 +488,8 @@ static void flexcan_read_fifo(const struct net_device *dev,
        struct flexcan_mb __iomem *mb = &regs->cantxfg[0];
        u32 reg_ctrl, reg_id;
 
-       reg_ctrl = readl(&mb->can_ctrl);
-       reg_id = readl(&mb->can_id);
+       reg_ctrl = flexcan_read(&mb->can_ctrl);
+       reg_id = flexcan_read(&mb->can_id);
        if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
                cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
        else
@@ -475,12 +499,12 @@ static void flexcan_read_fifo(const struct net_device *dev,
                cf->can_id |= CAN_RTR_FLAG;
        cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
 
-       *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
-       *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
+       *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
+       *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
 
        /* mark as read */
-       writel(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
-       readl(&regs->timer);
+       flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
+       flexcan_read(&regs->timer);
 }
 
 static int flexcan_read_frame(struct net_device *dev)
@@ -516,17 +540,17 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
         * The error bits are cleared on read,
         * use saved value from irq handler.
         */
-       reg_esr = readl(&regs->esr) | priv->reg_esr;
+       reg_esr = flexcan_read(&regs->esr) | priv->reg_esr;
 
        /* handle state changes */
        work_done += flexcan_poll_state(dev, reg_esr);
 
        /* handle RX-FIFO */
-       reg_iflag1 = readl(&regs->iflag1);
+       reg_iflag1 = flexcan_read(&regs->iflag1);
        while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
               work_done < quota) {
                work_done += flexcan_read_frame(dev);
-               reg_iflag1 = readl(&regs->iflag1);
+               reg_iflag1 = flexcan_read(&regs->iflag1);
        }
 
        /* report bus errors */
@@ -536,8 +560,8 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
        if (work_done < quota) {
                napi_complete(napi);
                /* enable IRQs */
-               writel(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
-               writel(priv->reg_ctrl_default, &regs->ctrl);
+               flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
+               flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
        }
 
        return work_done;
@@ -551,9 +575,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
        struct flexcan_regs __iomem *regs = priv->base;
        u32 reg_iflag1, reg_esr;
 
-       reg_iflag1 = readl(&regs->iflag1);
-       reg_esr = readl(&regs->esr);
-       writel(FLEXCAN_ESR_ERR_INT, &regs->esr);        /* ACK err IRQ */
+       reg_iflag1 = flexcan_read(&regs->iflag1);
+       reg_esr = flexcan_read(&regs->esr);
+       flexcan_write(FLEXCAN_ESR_ERR_INT, &regs->esr); /* ACK err IRQ */
 
        /*
         * schedule NAPI in case of:
@@ -569,16 +593,16 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
                 * save them for later use.
                 */
                priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
-               writel(FLEXCAN_IFLAG_DEFAULT & ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE,
-                      &regs->imask1);
-               writel(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+               flexcan_write(FLEXCAN_IFLAG_DEFAULT &
+                       ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->imask1);
+               flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
                       &regs->ctrl);
                napi_schedule(&priv->napi);
        }
 
        /* FIFO overflow */
        if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
-               writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
+               flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
                dev->stats.rx_over_errors++;
                dev->stats.rx_errors++;
        }
@@ -587,7 +611,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
        if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
                /* tx_bytes is incremented in flexcan_start_xmit */
                stats->tx_packets++;
-               writel((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
+               flexcan_write((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
                netif_wake_queue(dev);
        }
 
@@ -601,7 +625,7 @@ static void flexcan_set_bittiming(struct net_device *dev)
        struct flexcan_regs __iomem *regs = priv->base;
        u32 reg;
 
-       reg = readl(&regs->ctrl);
+       reg = flexcan_read(&regs->ctrl);
        reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
                 FLEXCAN_CTRL_RJW(0x3) |
                 FLEXCAN_CTRL_PSEG1(0x7) |
@@ -625,11 +649,11 @@ static void flexcan_set_bittiming(struct net_device *dev)
                reg |= FLEXCAN_CTRL_SMP;
 
        dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg);
-       writel(reg, &regs->ctrl);
+       flexcan_write(reg, &regs->ctrl);
 
        /* print chip status */
        dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
-               readl(&regs->mcr), readl(&regs->ctrl));
+               flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
 }
 
 /*
@@ -650,10 +674,10 @@ static int flexcan_chip_start(struct net_device *dev)
        flexcan_chip_enable(priv);
 
        /* soft reset */
-       writel(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+       flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
        udelay(10);
 
-       reg_mcr = readl(&regs->mcr);
+       reg_mcr = flexcan_read(&regs->mcr);
        if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
                dev_err(dev->dev.parent,
                        "Failed to softreset can module (mcr=0x%08x)\n",
@@ -675,12 +699,12 @@ static int flexcan_chip_start(struct net_device *dev)
         * choose format C
         *
         */
-       reg_mcr = readl(&regs->mcr);
+       reg_mcr = flexcan_read(&regs->mcr);
        reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
                FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
                FLEXCAN_MCR_IDAM_C;
        dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
-       writel(reg_mcr, &regs->mcr);
+       flexcan_write(reg_mcr, &regs->mcr);
 
        /*
         * CTRL
@@ -698,7 +722,7 @@ static int flexcan_chip_start(struct net_device *dev)
         * (FLEXCAN_CTRL_ERR_MSK), too. Otherwise we don't get any
         * warning or bus passive interrupts.
         */
-       reg_ctrl = readl(&regs->ctrl);
+       reg_ctrl = flexcan_read(&regs->ctrl);
        reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
        reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
                FLEXCAN_CTRL_ERR_STATE | FLEXCAN_CTRL_ERR_MSK;
@@ -706,38 +730,39 @@ static int flexcan_chip_start(struct net_device *dev)
        /* save for later use */
        priv->reg_ctrl_default = reg_ctrl;
        dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
-       writel(reg_ctrl, &regs->ctrl);
+       flexcan_write(reg_ctrl, &regs->ctrl);
 
        for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) {
-               writel(0, &regs->cantxfg[i].can_ctrl);
-               writel(0, &regs->cantxfg[i].can_id);
-               writel(0, &regs->cantxfg[i].data[0]);
-               writel(0, &regs->cantxfg[i].data[1]);
+               flexcan_write(0, &regs->cantxfg[i].can_ctrl);
+               flexcan_write(0, &regs->cantxfg[i].can_id);
+               flexcan_write(0, &regs->cantxfg[i].data[0]);
+               flexcan_write(0, &regs->cantxfg[i].data[1]);
 
                /* put MB into rx queue */
-               writel(FLEXCAN_MB_CNT_CODE(0x4), &regs->cantxfg[i].can_ctrl);
+               flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
+                       &regs->cantxfg[i].can_ctrl);
        }
 
        /* acceptance mask/acceptance code (accept everything) */
-       writel(0x0, &regs->rxgmask);
-       writel(0x0, &regs->rx14mask);
-       writel(0x0, &regs->rx15mask);
+       flexcan_write(0x0, &regs->rxgmask);
+       flexcan_write(0x0, &regs->rx14mask);
+       flexcan_write(0x0, &regs->rx15mask);
 
        flexcan_transceiver_switch(priv, 1);
 
        /* synchronize with the can bus */
-       reg_mcr = readl(&regs->mcr);
+       reg_mcr = flexcan_read(&regs->mcr);
        reg_mcr &= ~FLEXCAN_MCR_HALT;
-       writel(reg_mcr, &regs->mcr);
+       flexcan_write(reg_mcr, &regs->mcr);
 
        priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
        /* enable FIFO interrupts */
-       writel(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
+       flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
 
        /* print chip status */
        dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n",
-               __func__, readl(&regs->mcr), readl(&regs->ctrl));
+               __func__, flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
 
        return 0;
 
@@ -759,12 +784,12 @@ static void flexcan_chip_stop(struct net_device *dev)
        u32 reg;
 
        /* Disable all interrupts */
-       writel(0, &regs->imask1);
+       flexcan_write(0, &regs->imask1);
 
        /* Disable + halt module */
-       reg = readl(&regs->mcr);
+       reg = flexcan_read(&regs->mcr);
        reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
-       writel(reg, &regs->mcr);
+       flexcan_write(reg, &regs->mcr);
 
        flexcan_transceiver_switch(priv, 0);
        priv->can.state = CAN_STATE_STOPPED;
@@ -856,24 +881,24 @@ static int __devinit register_flexcandev(struct net_device *dev)
 
        /* select "bus clock", chip must be disabled */
        flexcan_chip_disable(priv);
-       reg = readl(&regs->ctrl);
+       reg = flexcan_read(&regs->ctrl);
        reg |= FLEXCAN_CTRL_CLK_SRC;
-       writel(reg, &regs->ctrl);
+       flexcan_write(reg, &regs->ctrl);
 
        flexcan_chip_enable(priv);
 
        /* set freeze, halt and activate FIFO, restrict register access */
-       reg = readl(&regs->mcr);
+       reg = flexcan_read(&regs->mcr);
        reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
                FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
-       writel(reg, &regs->mcr);
+       flexcan_write(reg, &regs->mcr);
 
        /*
         * Currently we only support newer versions of this core
         * featuring a RX FIFO. Older cores found on some Coldfire
         * derivates are not yet supported.
         */
-       reg = readl(&regs->mcr);
+       reg = flexcan_read(&regs->mcr);
        if (!(reg & FLEXCAN_MCR_FEN)) {
                dev_err(dev->dev.parent,
                        "Could not enable RX FIFO, unsupported core\n");
@@ -901,16 +926,29 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
        struct net_device *dev;
        struct flexcan_priv *priv;
        struct resource *mem;
-       struct clk *clk;
+       struct clk *clk = NULL;
        void __iomem *base;
        resource_size_t mem_size;
        int err, irq;
+       u32 clock_freq = 0;
+
+       if (pdev->dev.of_node) {
+               const u32 *clock_freq_p;
 
-       clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(clk)) {
-               dev_err(&pdev->dev, "no clock defined\n");
-               err = PTR_ERR(clk);
-               goto failed_clock;
+               clock_freq_p = of_get_property(pdev->dev.of_node,
+                                               "clock-frequency", NULL);
+               if (clock_freq_p)
+                       clock_freq = *clock_freq_p;
+       }
+
+       if (!clock_freq) {
+               clk = clk_get(&pdev->dev, NULL);
+               if (IS_ERR(clk)) {
+                       dev_err(&pdev->dev, "no clock defined\n");
+                       err = PTR_ERR(clk);
+                       goto failed_clock;
+               }
+               clock_freq = clk_get_rate(clk);
        }
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -943,7 +981,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
        dev->flags |= IFF_ECHO; /* we support local echo in hardware */
 
        priv = netdev_priv(dev);
-       priv->can.clock.freq = clk_get_rate(clk);
+       priv->can.clock.freq = clock_freq;
        priv->can.bittiming_const = &flexcan_bittiming_const;
        priv->can.do_set_mode = flexcan_set_mode;
        priv->can.do_get_berr_counter = flexcan_get_berr_counter;
@@ -978,7 +1016,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
  failed_map:
        release_mem_region(mem->start, mem_size);
  failed_get:
-       clk_put(clk);
+       if (clk)
+               clk_put(clk);
  failed_clock:
        return err;
 }
@@ -996,15 +1035,27 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(mem->start, resource_size(mem));
 
-       clk_put(priv->clk);
+       if (priv->clk)
+               clk_put(priv->clk);
 
        free_candev(dev);
 
        return 0;
 }
 
+static struct of_device_id flexcan_of_match[] = {
+       {
+               .compatible = "fsl,p1010-flexcan",
+       },
+       {},
+};
+
 static struct platform_driver flexcan_driver = {
-       .driver.name = DRV_NAME,
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = flexcan_of_match,
+       },
        .probe = flexcan_probe,
        .remove = __devexit_p(flexcan_remove),
 };
index 92feac68b66e725fbe8865d688d0fdabeb8ec1ae..ac42f5da91b5f50ee4aea72032414e3b1995d135 100644 (file)
@@ -62,7 +62,7 @@ static enum can_state state_map[] = {
 static int mscan_set_mode(struct net_device *dev, u8 mode)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        int ret = 0;
        int i;
        u8 canctl1;
@@ -138,7 +138,7 @@ static int mscan_set_mode(struct net_device *dev, u8 mode)
 static int mscan_start(struct net_device *dev)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        u8 canrflg;
        int err;
 
@@ -178,7 +178,7 @@ static int mscan_restart(struct net_device *dev)
        struct mscan_priv *priv = netdev_priv(dev);
 
        if (priv->type == MSCAN_TYPE_MPC5121) {
-               struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+               struct mscan_regs __iomem *regs = priv->reg_base;
 
                priv->can.state = CAN_STATE_ERROR_ACTIVE;
                WARN(!(in_8(&regs->canmisc) & MSCAN_BOHOLD),
@@ -199,7 +199,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct can_frame *frame = (struct can_frame *)skb->data;
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        int i, rtr, buf_id;
        u32 can_id;
 
@@ -305,7 +305,7 @@ static enum can_state check_set_state(struct net_device *dev, u8 canrflg)
 static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        u32 can_id;
        int i;
 
@@ -343,7 +343,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
                                u8 canrflg)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        struct net_device_stats *stats = &dev->stats;
        enum can_state old_state;
 
@@ -406,7 +406,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)
 {
        struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi);
        struct net_device *dev = napi->dev;
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        struct net_device_stats *stats = &dev->stats;
        int npackets = 0;
        int ret = 1;
@@ -453,7 +453,7 @@ static irqreturn_t mscan_isr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        struct net_device_stats *stats = &dev->stats;
        u8 cantier, cantflg, canrflg;
        irqreturn_t ret = IRQ_NONE;
@@ -537,7 +537,7 @@ static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
 static int mscan_do_set_bittiming(struct net_device *dev)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        struct can_bittiming *bt = &priv->can.bittiming;
        u8 btr0, btr1;
 
@@ -559,7 +559,7 @@ static int mscan_open(struct net_device *dev)
 {
        int ret;
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
 
        /* common open */
        ret = open_candev(dev);
@@ -598,7 +598,7 @@ exit_napi_disable:
 static int mscan_close(struct net_device *dev)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
 
        netif_stop_queue(dev);
        napi_disable(&priv->napi);
@@ -622,7 +622,7 @@ static const struct net_device_ops mscan_netdev_ops = {
 int register_mscandev(struct net_device *dev, int mscan_clksrc)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        u8 ctl1;
 
        ctl1 = in_8(&regs->canctl1);
@@ -659,7 +659,7 @@ int register_mscandev(struct net_device *dev, int mscan_clksrc)
 void unregister_mscandev(struct net_device *dev)
 {
        struct mscan_priv *priv = netdev_priv(dev);
-       struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+       struct mscan_regs __iomem *regs = priv->reg_base;
        mscan_set_mode(dev, MSCAN_INIT_MODE);
        clrbits8(&regs->canctl1, MSCAN_CANE);
        unregister_candev(dev);
index 231385b8e08faa38bfab0850080109d256cf6c2d..c7f3d4ea11672761cf7c9241db738e463cbb00ca 100644 (file)
@@ -408,7 +408,7 @@ static void plx_pci_del_card(struct pci_dev *pdev)
        struct sja1000_priv *priv;
        int i = 0;
 
-       for (i = 0; i < card->channels; i++) {
+       for (i = 0; i < PLX_PCI_MAX_CHAN; i++) {
                dev = card->net_dev[i];
                if (!dev)
                        continue;
@@ -536,7 +536,6 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,
                        if (err) {
                                dev_err(&pdev->dev, "Registering device failed "
                                        "(err=%d)\n", err);
-                               free_sja1000dev(dev);
                                goto failure_cleanup;
                        }
 
@@ -549,6 +548,7 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,
                        dev_err(&pdev->dev, "Channel #%d not detected\n",
                                i + 1);
                        free_sja1000dev(dev);
+                       card->net_dev[i] = NULL;
                }
        }
 
index e66aceb57cef37c99d25895b1869a43f34b497f3..c7e1df9910fa4df9cd3074b873a2ddba357cfb1c 100644 (file)
@@ -261,7 +261,7 @@ static const struct net_device_ops e100_netdev_ops = {
        .ndo_start_xmit         = e100_send_packet,
        .ndo_tx_timeout         = e100_tx_timeout,
        .ndo_get_stats          = e100_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_do_ioctl           = e100_ioctl,
        .ndo_set_mac_address    = e100_set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
@@ -1132,7 +1132,6 @@ static irqreturn_t
 e100rxtx_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
-       struct net_local *np = netdev_priv(dev);
        unsigned long irqbits;
 
        /*
index 417e143856237c8927c3a093e8f60ac0c055b4d4..4ad80f7710995ba831e94800eb4be0b4f07c7f69 100644 (file)
@@ -483,7 +483,7 @@ static const struct net_device_ops dfx_netdev_ops = {
        .ndo_stop               = dfx_close,
        .ndo_start_xmit         = dfx_xmt_queue_pkt,
        .ndo_get_stats          = dfx_ctl_get_stats,
-       .ndo_set_multicast_list = dfx_ctl_set_multicast_list,
+       .ndo_set_rx_mode        = dfx_ctl_set_multicast_list,
        .ndo_set_mac_address    = dfx_ctl_set_mac_address,
 };
 
index 39cf9b9bd673cdd0d46aed0c970ca58cccbedc88..a7c5e8831e8c0f3a5a01e5adc53b29b2bc85129d 100644 (file)
@@ -116,7 +116,7 @@ static const struct net_device_ops dummy_netdev_ops = {
        .ndo_init               = dummy_dev_init,
        .ndo_start_xmit         = dummy_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_set_mac_address    = dummy_set_address,
        .ndo_get_stats64        = dummy_get_stats64,
 };
similarity index 99%
rename from drivers/net/3c501.c
rename to drivers/net/ethernet/3com/3c501.c
index 5420f6de27dfa1bdd9ee4fb626e7c6537792b854..68da81d476f3b7e5888457507fa7ea4830f16ed6 100644 (file)
@@ -201,7 +201,7 @@ static const struct net_device_ops el_netdev_ops = {
        .ndo_stop               = el1_close,
        .ndo_start_xmit         = el_start_xmit,
        .ndo_tx_timeout         = el_timeout,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/3c509.c
rename to drivers/net/ethernet/3com/3c509.c
index 44b28b2d70039e959811a4c9cfa173ed5c6b7b43..92053e6fc980a95b6ae6f5836ff1fdce5d1f79e2 100644 (file)
@@ -545,7 +545,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_stop               = el3_close,
        .ndo_start_xmit         = el3_start_xmit,
        .ndo_get_stats          = el3_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = el3_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/3c515.c
rename to drivers/net/ethernet/3com/3c515.c
index d2bb4b254c57ddf0c4e51bd0eebd33960732892b..f67a5d3a200c45c43242a89395c55b16b8cff8c1 100644 (file)
@@ -569,7 +569,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_start_xmit         = corkscrew_start_xmit,
        .ndo_tx_timeout         = corkscrew_timeout,
        .ndo_get_stats          = corkscrew_get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/pcmcia/3c574_cs.c
rename to drivers/net/ethernet/3com/3c574_cs.c
index 34c5e1cbf65d30aa2f7491be4eb493375ac6482c..9c01bc9235b36cc7c1c5acfd857e6d4b1f5ab1b9 100644 (file)
@@ -255,7 +255,7 @@ static const struct net_device_ops el3_netdev_ops = {
        .ndo_tx_timeout         = el3_tx_timeout,
        .ndo_get_stats          = el3_get_stats,
        .ndo_do_ioctl           = el3_ioctl,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/pcmcia/3c589_cs.c
rename to drivers/net/ethernet/3com/3c589_cs.c
index 4a1a358098075341d27d6e8de596bfb6428ba193..972f80ecc510a7346c5ca364535faed2a8e1bbea 100644 (file)
@@ -184,7 +184,7 @@ static const struct net_device_ops el3_netdev_ops = {
        .ndo_tx_timeout         = el3_tx_timeout,
        .ndo_set_config         = el3_config,
        .ndo_get_stats          = el3_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/3c59x.c
rename to drivers/net/ethernet/3com/3c59x.c
index 8cc22568ebd3429282b8674b912cb8fe80eb7a03..6e1f5959a6549b6ab94fef88468e5b2898f2f23e 100644 (file)
@@ -1055,7 +1055,7 @@ static const struct net_device_ops boomrang_netdev_ops = {
 #ifdef CONFIG_PCI
        .ndo_do_ioctl           = vortex_ioctl,
 #endif
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
@@ -1073,7 +1073,7 @@ static const struct net_device_ops vortex_netdev_ops = {
 #ifdef CONFIG_PCI
        .ndo_do_ioctl           = vortex_ioctl,
 #endif
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig
new file mode 100644 (file)
index 0000000..65cc129
--- /dev/null
@@ -0,0 +1,120 @@
+#
+# 3Com Ethernet device configuration
+#
+
+config NET_VENDOR_3COM
+       bool "3Com devices"
+       depends on ISA || EISA || MCA || PCI || PCMCIA
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about 3Com cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_3COM
+
+config EL1
+       tristate "3c501 \"EtherLink\" support"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.  Also, consider buying a
+         new card, since the 3c501 is slow, broken, and obsolete: you will
+         have problems.  Some people suggest to ping ("man ping") a nearby
+         machine every minute ("man cron") when using this card.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c501.
+
+config EL3
+       tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support"
+       depends on (ISA || EISA || MCA)
+       ---help---
+         If you have a network (Ethernet) card belonging to the 3Com
+         EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
+         from <http://www.tldp.org/docs.html#howto>.
+
+         If your card is not working you may need to use the DOS
+         setup disk to disable Plug & Play mode, and to select the default
+         media type.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c509.
+
+config 3C515
+       tristate "3c515 ISA \"Fast EtherLink\""
+       depends on (ISA || EISA) && ISA_DMA_API
+       ---help---
+         If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
+         network card, say Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c515.
+
+config PCMCIA_3C574
+       tristate "3Com 3c574 PCMCIA support"
+       depends on PCMCIA
+       ---help---
+         Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
+         (PC-card) Fast Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called 3c574_cs.  If unsure, say N.
+
+config PCMCIA_3C589
+       tristate "3Com 3c589 PCMCIA support"
+       depends on PCMCIA
+       ---help---
+         Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
+         (PC-card) Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called 3c589_cs.  If unsure, say N.
+
+config VORTEX
+       tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
+       depends on (PCI || EISA)
+       select MII
+       ---help---
+         This option enables driver support for a large number of 10Mbps and
+         10/100Mbps EISA, PCI and PCMCIA 3Com network cards:
+
+         "Vortex"    (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
+         "Boomerang" (EtherLink XL 3c900 or 3c905)            PCI
+         "Cyclone"   (3c540/3c900/3c905/3c980/3c575/3c656)    PCI and Cardbus
+         "Tornado"   (3c905)                                  PCI
+         "Hurricane" (3c555/3cSOHO)                           PCI
+
+         If you have such a card, say Y and read the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>. More
+         specific information is in
+         <file:Documentation/networking/vortex.txt> and in the comments at
+         the beginning of <file:drivers/net/3c59x.c>.
+
+         To compile this support as a module, choose M here.
+
+config TYPHOON
+       tristate "3cr990 series \"Typhoon\" support"
+       depends on PCI
+       select CRC32
+       ---help---
+         This option enables driver support for the 3cr990 series of cards:
+
+         3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
+         3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
+         3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
+
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called typhoon.
+
+endif # NET_VENDOR_3COM
diff --git a/drivers/net/ethernet/3com/Makefile b/drivers/net/ethernet/3com/Makefile
new file mode 100644 (file)
index 0000000..1e5382a
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the 3Com Ethernet device drivers
+#
+
+obj-$(CONFIG_EL1) += 3c501.o
+obj-$(CONFIG_EL3) += 3c509.o
+obj-$(CONFIG_3C515) += 3c515.o
+obj-$(CONFIG_PCMCIA_3C589) += 3c589_cs.o
+obj-$(CONFIG_PCMCIA_3C574) += 3c574_cs.o
+obj-$(CONFIG_VORTEX) += 3c59x.o
+obj-$(CONFIG_TYPHOON) += typhoon.o
similarity index 99%
rename from drivers/net/typhoon.c
rename to drivers/net/ethernet/3com/typhoon.c
index 1d5091a1e49a441c383a140432290cc351ecd29f..f1dc9acf61055a1c8681311721ed1c3cf8eb953a 100644 (file)
@@ -2266,7 +2266,7 @@ static const struct net_device_ops typhoon_netdev_ops = {
        .ndo_open               = typhoon_open,
        .ndo_stop               = typhoon_close,
        .ndo_start_xmit         = typhoon_start_tx,
-       .ndo_set_multicast_list = typhoon_set_rx_mode,
+       .ndo_set_rx_mode        = typhoon_set_rx_mode,
        .ndo_tx_timeout         = typhoon_tx_timeout,
        .ndo_get_stats          = typhoon_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/3c503.c
rename to drivers/net/ethernet/8390/3c503.c
index 84e68f1b9adf7fd81291806f8692c65987c89862..fbab1367505f028be3ec1845b2b94e07bf139f8b 100644 (file)
@@ -176,7 +176,7 @@ static const struct net_device_ops el2_netdev_ops = {
        .ndo_start_xmit         = eip_start_xmit,
        .ndo_tx_timeout         = eip_tx_timeout,
        .ndo_get_stats          = eip_get_stats,
-       .ndo_set_multicast_list = eip_set_multicast_list,
+       .ndo_set_rx_mode        = eip_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 97%
rename from drivers/net/8390.c
rename to drivers/net/ethernet/8390/8390.c
index 7c7518be1756e22cec90aac3b330562d4e959bb9..5db1f55abef44fe9bf155d577c7aabcc521fadb8 100644 (file)
@@ -61,7 +61,7 @@ const struct net_device_ops ei_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 97%
rename from drivers/net/8390p.c
rename to drivers/net/ethernet/8390/8390p.c
index a2a64ea0b691347d095ed70d7d8af9aad068494b..e8fc2e87e840f40e73b1cc14434342e1cbace64e 100644 (file)
@@ -66,7 +66,7 @@ const struct net_device_ops eip_netdev_ops = {
        .ndo_start_xmit         = eip_start_xmit,
        .ndo_tx_timeout         = eip_tx_timeout,
        .ndo_get_stats          = eip_get_stats,
-       .ndo_set_multicast_list = eip_set_multicast_list,
+       .ndo_set_rx_mode        = eip_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
new file mode 100644 (file)
index 0000000..5d21698
--- /dev/null
@@ -0,0 +1,336 @@
+#
+# 8390 device configuration
+#
+
+config NET_VENDOR_8390
+       bool "National Semi-conductor 8390 devices"
+       depends on NET_VENDOR_NATSEMI && (AMIGA_PCMCIA || PCI || SUPERH || \
+                  ISA || MCA || EISA || MAC || M32R || MACH_TX49XX || \
+                  MCA_LEGACY || H8300 || ARM || MIPS || ZORRO || PCMCIA || \
+                  EXPERIMENTAL)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Western Digital cards. If you say Y, you will be
+         asked for your specific card in the following questions.
+
+if NET_VENDOR_8390
+
+config EL2
+       tristate "3c503 \"EtherLink II\" support"
+       depends on ISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c503.
+
+config AC3200
+       tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
+       depends on PCI && (ISA || EISA) && EXPERIMENTAL
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ac3200.
+
+config PCMCIA_AXNET
+       tristate "Asix AX88190 PCMCIA support"
+       depends on PCMCIA
+       ---help---
+         Say Y here if you intend to attach an Asix AX88190-based PCMCIA
+         (PC-card) Fast Ethernet card to your computer.  These cards are
+         nearly NE2000 compatible but need a separate driver due to a few
+         misfeatures.
+
+         To compile this driver as a module, choose M here: the module will be
+         called axnet_cs.  If unsure, say N.
+
+config AX88796
+       tristate "ASIX AX88796 NE2000 clone support"
+       depends on (ARM || MIPS || SUPERH)
+       select PHYLIB
+       select MDIO_BITBANG
+       ---help---
+         AX88796 driver, using platform bus to provide
+         chip detection and resources
+
+config AX88796_93CX6
+       bool "ASIX AX88796 external 93CX6 eeprom support"
+       depends on AX88796
+       select EEPROM_93CX6
+       ---help---
+         Select this if your platform comes with an external 93CX6 eeprom.
+
+config E2100
+       tristate "Cabletron E21xx support"
+       depends on ISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called e2100.
+
+config ES3210
+       tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)"
+       depends on PCI && EISA && EXPERIMENTAL
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called es3210.
+
+config HPLAN_PLUS
+       tristate "HP PCLAN+ (27247B and 27252A) support"
+       depends on ISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called hp-plus.
+
+config HPLAN
+       tristate "HP PCLAN (27245 and other 27xxx series) support"
+       depends on ISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called hp.
+
+config HYDRA
+       tristate "Hydra support"
+       depends on ZORRO
+       select CRC32
+       ---help---
+         If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
+
+         To compile this driver as a module, choose M here: the module
+         will be called hydra.
+
+config ARM_ETHERH
+       tristate "I-cubed EtherH/ANT EtherM support"
+       depends on ARM && ARCH_ACORN
+       select CRC32
+       ---help---
+         If you have an Acorn system with one of these network cards, you
+         should say Y to this option if you wish to use it with Linux.
+
+config LNE390
+       tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
+       depends on PCI && EISA && EXPERIMENTAL
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called lne390.
+
+config MAC8390
+       bool "Macintosh NS 8390 based ethernet cards"
+       depends on MAC
+       select CRC32
+       ---help---
+         If you want to include a driver to support Nubus or LC-PDS
+         Ethernet cards using an NS8390 chipset or its equivalent, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+config NE2000
+       tristate "NE2000/NE1000 support"
+       depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX)
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.  Many Ethernet cards
+         without a specific driver are compatible with NE2000.
+
+         If you have a PCI NE2000 card however, say N here and Y to "PCI
+         NE2000 and clone support" under "EISA, VLB, PCI and on board
+         controllers" below. If you have a NE2000 card and are running on
+         an MCA system (a bus system used on some IBM PS/2 computers and
+         laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
+         below.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ne.
+
+config NE2_MCA
+       tristate "NE/2 (ne2000 MCA version) support"
+       depends on MCA_LEGACY
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ne2.
+
+config NE2K_PCI
+       tristate "PCI NE2000 and clones support (see help)"
+       depends on PCI
+       select CRC32
+       ---help---
+         This driver is for NE2000 compatible PCI cards. It will not work
+         with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
+         support" below). If you have a PCI NE2000 network (Ethernet) card,
+         say Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         This driver also works for the following NE2000 clone cards:
+         RealTek RTL-8029  Winbond 89C940  Compex RL2000  KTI ET32P2
+         NetVin NV5000SC   Via 86C926      SureCom NE34   Winbond
+         Holtek HT80232    Holtek HT80229
+
+         To compile this driver as a module, choose M here. The module
+         will be called ne2k-pci.
+
+config APNE
+       tristate "PCMCIA NE2000 support"
+       depends on AMIGA_PCMCIA
+       select CRC32
+       ---help---
+         If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
+         say N.
+
+         To compile this driver as a module, choose M here: the module
+         will be called apne.
+
+config NE3210
+       tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)"
+       depends on PCI && EISA && EXPERIMENTAL
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.  Note that this driver
+         will NOT WORK for NE3200 cards as they are completely different.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ne3210.
+
+config PCMCIA_PCNET
+       tristate "NE2000 compatible PCMCIA support"
+       depends on PCMCIA
+       select CRC32
+       ---help---
+         Say Y here if you intend to attach an NE2000 compatible PCMCIA
+         (PC-card) Ethernet or Fast Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called pcnet_cs.  If unsure, say N.
+
+config NE_H8300
+       tristate "NE2000 compatible support for H8/300"
+       depends on H8300
+       ---help---
+         Say Y here if you want to use the NE2000 compatible
+         controller on the Renesas H8/300 processor.
+
+config STNIC
+       tristate "National DP83902AV  support"
+       depends on SUPERH
+       select CRC32
+       ---help---
+         Support for cards based on the National Semiconductor DP83902AV
+         ST-NIC Serial Network Interface Controller for Twisted Pair.  This
+         is a 10Mbit/sec Ethernet controller.  Product overview and specs at
+         <http://www.national.com/pf/DP/DP83902A.html>.
+
+         If unsure, say N.
+
+config ULTRAMCA
+       tristate "SMC Ultra MCA support"
+       depends on MCA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type and are running
+         an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called smc-mca.
+
+config ULTRA
+       tristate "SMC Ultra support"
+       depends on ISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Important: There have been many reports that, with some motherboards
+         mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
+         such as some BusLogic models) causes corruption problems with many
+         operating systems. The Linux smc-ultra driver has a work-around for
+         this but keep it in mind if you have such a SCSI card and have
+         problems.
+
+         To compile this driver as a module, choose M here. The module
+         will be called smc-ultra.
+
+config ULTRA32
+       tristate "SMC Ultra32 EISA support"
+       depends on EISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called smc-ultra32.
+
+config WD80x3
+       tristate "WD80*3 support"
+       depends on ISA
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called wd.
+
+config ZORRO8390
+       tristate "Zorro NS8390-based Ethernet support"
+       depends on ZORRO
+       select CRC32
+       ---help---
+         This driver is for Zorro Ethernet cards using an NS8390-compatible
+         chipset, like the Village Tronic Ariadne II and the Individual
+         Computers X-Surf Ethernet cards. If you have such a card, say Y.
+         Otherwise, say N.
+
+         To compile this driver as a module, choose M here: the module
+         will be called zorro8390.
+
+endif # NET_VENDOR_8390
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile
new file mode 100644 (file)
index 0000000..3337d7f
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Makefile for the 8390 network device drivers.
+#
+
+obj-$(CONFIG_MAC8390) += mac8390.o
+obj-$(CONFIG_AC3200) += ac3200.o 8390.o
+obj-$(CONFIG_APNE) += apne.o 8390.o
+obj-$(CONFIG_ARM_ETHERH) += etherh.o
+obj-$(CONFIG_AX88796) += ax88796.o
+obj-$(CONFIG_E2100) += e2100.o 8390.o
+obj-$(CONFIG_EL2) += 3c503.o 8390p.o
+obj-$(CONFIG_ES3210) += es3210.o 8390.o
+obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o
+obj-$(CONFIG_HPLAN) += hp.o 8390p.o
+obj-$(CONFIG_HYDRA) += hydra.o 8390.o
+obj-$(CONFIG_LNE390) += lne390.o 8390.o
+obj-$(CONFIG_NE2000) += ne.o 8390p.o
+obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o
+obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
+obj-$(CONFIG_NE3210) += ne3210.o 8390.o
+obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o
+obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o
+obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
+obj-$(CONFIG_STNIC) += stnic.o 8390.o
+obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
+obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
+obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
+obj-$(CONFIG_WD80x3) += wd.o 8390.o
+obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
similarity index 99%
rename from drivers/net/ac3200.c
rename to drivers/net/ethernet/8390/ac3200.c
index f07b2e980fbc9b1f300ff9164a78c6f1b418014c..5337dd0a59b08086b8d89bd0f7081d6504afa96e 100644 (file)
@@ -151,7 +151,7 @@ static const struct net_device_ops ac_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/ax88796.c
rename to drivers/net/ethernet/8390/ax88796.c
index e7cb8c8b9776441a58040c1e2b8ec9bb17cd1f21..e9f8432f55b461f388be8643386b948a5b08ca45 100644 (file)
@@ -543,7 +543,7 @@ static const struct net_device_ops ax_netdev_ops = {
        .ndo_start_xmit         = ax_ei_start_xmit,
        .ndo_tx_timeout         = ax_ei_tx_timeout,
        .ndo_get_stats          = ax_ei_get_stats,
-       .ndo_set_multicast_list = ax_ei_set_multicast_list,
+       .ndo_set_rx_mode        = ax_ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/pcmcia/axnet_cs.c
rename to drivers/net/ethernet/8390/axnet_cs.c
index 9953db71196993c9eb6d7515a131a5d370e657c6..bba51cdc74a1a37dfc7560dc0fa0f5ad5db5b8cc 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/etherdevice.h>
 #include <linux/crc32.h>
 #include <linux/mii.h>
-#include "../8390.h"
+#include "8390.h"
 
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -134,7 +134,7 @@ static const struct net_device_ops axnet_netdev_ops = {
        .ndo_start_xmit         = axnet_start_xmit,
        .ndo_tx_timeout         = axnet_tx_timeout,
        .ndo_get_stats          = get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/e2100.c
rename to drivers/net/ethernet/8390/e2100.c
index d50a9998ae77f04951c9f4250e4eb4e2ebf2c078..d16dc53c181317b4d2567039012693f336a0483f 100644 (file)
@@ -168,7 +168,7 @@ static const struct net_device_ops e21_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/arm/etherh.c
rename to drivers/net/ethernet/8390/etherh.c
index 03e217a868d457e16ee0262a9e40a2f9351d42d0..48c4948750d1df3c01133c1221b24a11711e2444 100644 (file)
@@ -65,7 +65,7 @@
 static char version[] __initdata =
        "EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n";
 
-#include "../lib8390.c"
+#include "lib8390.c"
 
 static unsigned int net_debug = NET_DEBUG;
 
@@ -644,7 +644,7 @@ static const struct net_device_ops etherh_netdev_ops = {
        .ndo_start_xmit         = __ei_start_xmit,
        .ndo_tx_timeout         = __ei_tx_timeout,
        .ndo_get_stats          = __ei_get_stats,
-       .ndo_set_multicast_list = __ei_set_multicast_list,
+       .ndo_set_rx_mode        = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/hp-plus.c
rename to drivers/net/ethernet/8390/hp-plus.c
index 29917363ebfb04d534c293703df69964f987b6b0..eeac843dcd2df9f6298ca12e6e60aecfdff18975 100644 (file)
@@ -165,7 +165,7 @@ static const struct net_device_ops hpp_netdev_ops = {
        .ndo_start_xmit         = eip_start_xmit,
        .ndo_tx_timeout         = eip_tx_timeout,
        .ndo_get_stats          = eip_get_stats,
-       .ndo_set_multicast_list = eip_set_multicast_list,
+       .ndo_set_rx_mode        = eip_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/hydra.c
rename to drivers/net/ethernet/8390/hydra.c
index 1cd481c04202fac3c0df0f93047772a3b789ec6c..3dac937a67c4d0c184fb434b26e973d432f34518 100644 (file)
@@ -101,7 +101,7 @@ static const struct net_device_ops hydra_netdev_ops = {
        .ndo_start_xmit         = __ei_start_xmit,
        .ndo_tx_timeout         = __ei_tx_timeout,
        .ndo_get_stats          = __ei_get_stats,
-       .ndo_set_multicast_list = __ei_set_multicast_list,
+       .ndo_set_rx_mode        = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/mac8390.c
rename to drivers/net/ethernet/8390/mac8390.c
index f84f5e6ededbe168173644d842b7b9c26ef21911..af5d9822cad969125c824c160a829f6b137768b9 100644 (file)
@@ -494,7 +494,7 @@ static const struct net_device_ops mac8390_netdev_ops = {
        .ndo_start_xmit         = __ei_start_xmit,
        .ndo_tx_timeout         = __ei_tx_timeout,
        .ndo_get_stats          = __ei_get_stats,
-       .ndo_set_multicast_list = __ei_set_multicast_list,
+       .ndo_set_rx_mode        = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/ne-h8300.c
rename to drivers/net/ethernet/8390/ne-h8300.c
index 7298a34bc7951d733f4de4071acc14aa5eab42e4..cd36a6a5f4081390fc6a5af810e864f93a55ec67 100644 (file)
@@ -200,7 +200,7 @@ static const struct net_device_ops ne_netdev_ops = {
        .ndo_start_xmit         = __ei_start_xmit,
        .ndo_tx_timeout         = __ei_tx_timeout,
        .ndo_get_stats          = __ei_get_stats,
-       .ndo_set_multicast_list = __ei_set_multicast_list,
+       .ndo_set_rx_mode        = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/ne2k-pci.c
rename to drivers/net/ethernet/8390/ne2k-pci.c
index 3c333cb5d34efd9b28cb78482b483f5499a3506b..39923425ba2547f56fc4d02306ebac2848030635 100644 (file)
@@ -207,7 +207,7 @@ static const struct net_device_ops ne2k_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/pcmcia/pcnet_cs.c
rename to drivers/net/ethernet/8390/pcnet_cs.c
index b4fd7c3ed07792dc6a88816c72946ee9c424f1ca..053b2551a72d43f013ea3aa357f151fed6579d51 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/log2.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
-#include "../8390.h"
+#include "8390.h"
 
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
@@ -227,7 +227,7 @@ static const struct net_device_ops pcnet_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_get_stats          = ei_get_stats,
        .ndo_do_ioctl           = ei_ioctl,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/smc-mca.c
rename to drivers/net/ethernet/8390/smc-mca.c
index 34934fb23b97ca74902a3b99970c353a1a77f512..77efec44fea0caa8cf11a8380b71b609c8f302d8 100644 (file)
@@ -191,7 +191,7 @@ static const struct net_device_ops ultramca_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/smc-ultra.c
rename to drivers/net/ethernet/8390/smc-ultra.c
index ba44ede2919820c0c54c2810eaac52c041cc3085..1cc306a83ff7d2f6760b4d7073893d343c311926 100644 (file)
@@ -192,7 +192,7 @@ static const struct net_device_ops ultra_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/smc-ultra32.c
rename to drivers/net/ethernet/8390/smc-ultra32.c
index e459c3b2510a57257efe95143cf633e2d4db883d..bb87053eb3da9aa2764966ed4c3d2df0bb646512 100644 (file)
@@ -160,7 +160,7 @@ static const struct net_device_ops ultra32_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/wd.c
rename to drivers/net/ethernet/8390/wd.c
index 8831a3393ecf7bf60dfa02efbc2a0271ca531185..c175fadb597bf12949d9cfaa8b976d0ad40fc57d 100644 (file)
@@ -153,7 +153,7 @@ static const struct net_device_ops wd_netdev_ops = {
        .ndo_start_xmit         = ei_start_xmit,
        .ndo_tx_timeout         = ei_tx_timeout,
        .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_set_rx_mode        = ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/zorro8390.c
rename to drivers/net/ethernet/8390/zorro8390.c
index 15e7751a273c1514f28b3f6ee930946e705c17fd..3aa9fe9999b5c5c6a34639fa8a1768234d75af1c 100644 (file)
@@ -278,7 +278,7 @@ static const struct net_device_ops zorro8390_netdev_ops = {
        .ndo_start_xmit         = __ei_start_xmit,
        .ndo_tx_timeout         = __ei_tx_timeout,
        .ndo_get_stats          = __ei_get_stats,
-       .ndo_set_multicast_list = __ei_set_multicast_list,
+       .ndo_set_rx_mode        = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
new file mode 100644 (file)
index 0000000..1f64747
--- /dev/null
@@ -0,0 +1,173 @@
+#
+# Ethernet LAN device configuration
+#
+
+menuconfig ETHERNET
+       bool "Ethernet driver support"
+       depends on NET
+       default y
+       ---help---
+         This section contains all the Ethernet device drivers.
+
+if ETHERNET
+
+config MDIO
+       tristate
+
+config SUNGEM_PHY
+       tristate
+
+source "drivers/net/ethernet/3com/Kconfig"
+source "drivers/net/ethernet/adaptec/Kconfig"
+source "drivers/net/ethernet/aeroflex/Kconfig"
+source "drivers/net/ethernet/alteon/Kconfig"
+source "drivers/net/ethernet/amd/Kconfig"
+source "drivers/net/ethernet/apple/Kconfig"
+source "drivers/net/ethernet/atheros/Kconfig"
+source "drivers/net/ethernet/cadence/Kconfig"
+source "drivers/net/ethernet/adi/Kconfig"
+source "drivers/net/ethernet/broadcom/Kconfig"
+source "drivers/net/ethernet/brocade/Kconfig"
+source "drivers/net/ethernet/chelsio/Kconfig"
+source "drivers/net/ethernet/cirrus/Kconfig"
+source "drivers/net/ethernet/cisco/Kconfig"
+source "drivers/net/ethernet/davicom/Kconfig"
+
+config DNET
+       tristate "Dave ethernet support (DNET)"
+       depends on HAS_IOMEM
+       select PHYLIB
+       ---help---
+         The Dave ethernet interface (DNET) is found on Qong Board FPGA.
+         Say Y to include support for the DNET chip.
+
+         To compile this driver as a module, choose M here: the module
+         will be called dnet.
+
+source "drivers/net/ethernet/dec/Kconfig"
+source "drivers/net/ethernet/dlink/Kconfig"
+source "drivers/net/ethernet/emulex/Kconfig"
+source "drivers/net/ethernet/neterion/Kconfig"
+source "drivers/net/ethernet/faraday/Kconfig"
+source "drivers/net/ethernet/freescale/Kconfig"
+source "drivers/net/ethernet/fujitsu/Kconfig"
+source "drivers/net/ethernet/hp/Kconfig"
+source "drivers/net/ethernet/ibm/Kconfig"
+source "drivers/net/ethernet/intel/Kconfig"
+source "drivers/net/ethernet/i825xx/Kconfig"
+source "drivers/net/ethernet/xscale/Kconfig"
+source "drivers/net/ethernet/icplus/Kconfig"
+
+config JME
+       tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the PCI-Express gigabit ethernet adapters
+         based on JMicron JMC250 chipset.
+
+         To compile this driver as a module, choose M here. The module
+         will be called jme.
+
+config KORINA
+       tristate "Korina (IDT RC32434) Ethernet support"
+       depends on MIKROTIK_RB532
+       ---help---
+         If you have a Mikrotik RouterBoard 500 or IDT RC32434
+         based system say Y. Otherwise say N.
+
+config LANTIQ_ETOP
+       tristate "Lantiq SoC ETOP driver"
+       depends on SOC_TYPE_XWAY
+       ---help---
+         Support for the MII0 inside the Lantiq SoC
+
+source "drivers/net/ethernet/marvell/Kconfig"
+source "drivers/net/ethernet/mellanox/Kconfig"
+source "drivers/net/ethernet/micrel/Kconfig"
+source "drivers/net/ethernet/microchip/Kconfig"
+
+config MIPS_SIM_NET
+       tristate "MIPS simulator Network device"
+       depends on MIPS_SIM
+       ---help---
+         The MIPSNET device is a simple Ethernet network device which is
+         emulated by the MIPS Simulator.
+         If you are not using a MIPSsim or are unsure, say N.
+
+source "drivers/net/ethernet/myricom/Kconfig"
+
+config FEALNX
+       tristate "Myson MTD-8xx PCI Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         Say Y here to support the Myson MTD-800 family of PCI-based Ethernet
+         cards. <http://www.myson.com.tw/>
+
+source "drivers/net/ethernet/natsemi/Kconfig"
+source "drivers/net/ethernet/8390/Kconfig"
+
+config NET_NETX
+       tristate "NetX Ethernet support"
+       select MII
+       depends on ARCH_NETX
+       ---help---
+         This is support for the Hilscher netX builtin Ethernet ports
+
+         To compile this driver as a module, choose M here. The module
+         will be called netx-eth.
+
+source "drivers/net/ethernet/nuvoton/Kconfig"
+source "drivers/net/ethernet/nvidia/Kconfig"
+source "drivers/net/ethernet/octeon/Kconfig"
+source "drivers/net/ethernet/oki-semi/Kconfig"
+
+config ETHOC
+       tristate "OpenCores 10/100 Mbps Ethernet MAC support"
+       depends on HAS_IOMEM && HAS_DMA
+       select MII
+       select PHYLIB
+       select CRC32
+       select BITREVERSE
+       ---help---
+         Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
+
+source "drivers/net/ethernet/packetengines/Kconfig"
+source "drivers/net/ethernet/pasemi/Kconfig"
+source "drivers/net/ethernet/qlogic/Kconfig"
+source "drivers/net/ethernet/racal/Kconfig"
+source "drivers/net/ethernet/realtek/Kconfig"
+source "drivers/net/ethernet/renesas/Kconfig"
+source "drivers/net/ethernet/rdc/Kconfig"
+
+config S6GMAC
+       tristate "S6105 GMAC ethernet support"
+       depends on XTENSA_VARIANT_S6000
+       select PHYLIB
+       ---help---
+         This driver supports the on chip ethernet device on the
+         S6105 xtensa processor.
+
+         To compile this driver as a module, choose M here. The module
+         will be called s6gmac.
+
+source "drivers/net/ethernet/seeq/Kconfig"
+source "drivers/net/ethernet/sis/Kconfig"
+source "drivers/net/ethernet/sfc/Kconfig"
+source "drivers/net/ethernet/sgi/Kconfig"
+source "drivers/net/ethernet/smsc/Kconfig"
+source "drivers/net/ethernet/stmicro/Kconfig"
+source "drivers/net/ethernet/sun/Kconfig"
+source "drivers/net/ethernet/tehuti/Kconfig"
+source "drivers/net/ethernet/ti/Kconfig"
+source "drivers/net/ethernet/tile/Kconfig"
+source "drivers/net/ethernet/toshiba/Kconfig"
+source "drivers/net/ethernet/tundra/Kconfig"
+source "drivers/net/ethernet/via/Kconfig"
+source "drivers/net/ethernet/xilinx/Kconfig"
+source "drivers/net/ethernet/xircom/Kconfig"
+
+endif # ETHERNET
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
new file mode 100644 (file)
index 0000000..c53ad3a
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# Makefile for the Linux network Ethernet device drivers.
+#
+
+obj-$(CONFIG_NET_VENDOR_3COM) += 3com/
+obj-$(CONFIG_NET_VENDOR_8390) += 8390/
+obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
+obj-$(CONFIG_GRETH) += aeroflex/
+obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
+obj-$(CONFIG_NET_VENDOR_AMD) += amd/
+obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
+obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
+obj-$(CONFIG_NET_ATMEL) += cadence/
+obj-$(CONFIG_NET_BFIN) += adi/
+obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
+obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/
+obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
+obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/
+obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/
+obj-$(CONFIG_DM9000) += davicom/
+obj-$(CONFIG_DNET) += dnet.o
+obj-$(CONFIG_NET_VENDOR_DEC) += dec/
+obj-$(CONFIG_NET_VENDOR_DLINK) += dlink/
+obj-$(CONFIG_NET_VENDOR_EMULEX) += emulex/
+obj-$(CONFIG_NET_VENDOR_EXAR) += neterion/
+obj-$(CONFIG_NET_VENDOR_FARADAY) += faraday/
+obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/
+obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/
+obj-$(CONFIG_NET_VENDOR_HP) += hp/
+obj-$(CONFIG_NET_VENDOR_IBM) += ibm/
+obj-$(CONFIG_NET_VENDOR_INTEL) += intel/
+obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/
+obj-$(CONFIG_NET_VENDOR_XSCALE) += xscale/
+obj-$(CONFIG_IP1000) += icplus/
+obj-$(CONFIG_JME) += jme.o
+obj-$(CONFIG_KORINA) += korina.o
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
+obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/
+obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
+obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
+obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
+obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
+obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
+obj-$(CONFIG_FEALNX) += fealnx.o
+obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/
+obj-$(CONFIG_NET_NETX) += netx-eth.o
+obj-$(CONFIG_NET_VENDOR_NUVOTON) += nuvoton/
+obj-$(CONFIG_NET_VENDOR_NVIDIA) += nvidia/
+obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
+obj-$(CONFIG_NET_VENDOR_OKI) += oki-semi/
+obj-$(CONFIG_ETHOC) += ethoc.o
+obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/
+obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
+obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
+obj-$(CONFIG_NET_VENDOR_RACAL) += racal/
+obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
+obj-$(CONFIG_SH_ETH) += renesas/
+obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
+obj-$(CONFIG_S6GMAC) += s6gmac.o
+obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
+obj-$(CONFIG_NET_VENDOR_SIS) += sis/
+obj-$(CONFIG_SFC) += sfc/
+obj-$(CONFIG_NET_VENDOR_SGI) += sgi/
+obj-$(CONFIG_NET_VENDOR_SMSC) += smsc/
+obj-$(CONFIG_NET_VENDOR_STMICRO) += stmicro/
+obj-$(CONFIG_NET_VENDOR_SUN) += sun/
+obj-$(CONFIG_NET_VENDOR_TEHUTI) += tehuti/
+obj-$(CONFIG_NET_VENDOR_TI) += ti/
+obj-$(CONFIG_TILE_NET) += tile/
+obj-$(CONFIG_NET_VENDOR_TOSHIBA) += toshiba/
+obj-$(CONFIG_NET_VENDOR_TUNDRA) += tundra/
+obj-$(CONFIG_NET_VENDOR_VIA) += via/
+obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
+obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
diff --git a/drivers/net/ethernet/adaptec/Kconfig b/drivers/net/ethernet/adaptec/Kconfig
new file mode 100644 (file)
index 0000000..5e9dbe9
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Adaptec network device configuration
+#
+
+config NET_VENDOR_ADAPTEC
+       bool "Adaptec devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Adaptec cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_ADAPTEC
+
+config ADAPTEC_STARFIRE
+       tristate "Adaptec Starfire/DuraLAN support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
+         adapter. The DuraLAN chip is used on the 64 bit PCI boards from
+         Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
+         driver.
+
+         To compile this driver as a module, choose M here: the module
+         will be called starfire.  This is recommended.
+
+endif # NET_VENDOR_ADAPTEC
diff --git a/drivers/net/ethernet/adaptec/Makefile b/drivers/net/ethernet/adaptec/Makefile
new file mode 100644 (file)
index 0000000..6c07b75
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Adaptec network device drivers.
+#
+
+obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
similarity index 99%
rename from drivers/net/starfire.c
rename to drivers/net/ethernet/adaptec/starfire.c
index 7ae1f990a98e1034ee8e851189537a6674c8b50f..df51fdd7235371d246de7109af703089c6a2cd77 100644 (file)
@@ -639,7 +639,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_start_xmit         = start_tx,
        .ndo_tx_timeout         = tx_timeout,
        .ndo_get_stats          = get_stats,
-       .ndo_set_multicast_list = &set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig
new file mode 100644 (file)
index 0000000..6de9851
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Blackfin device configuration
+#
+
+config NET_BFIN
+       bool "Blackfin devices"
+       depends on BF516 || BF518 || BF526 || BF527 || BF536 || BF537
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y.
+         Make sure you know the name of your card. Read the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         If unsure, say Y.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the remaining Blackfin card questions. If you say Y, you will be
+         asked for your specific card in the following questions.
+
+if NET_BFIN
+
+config BFIN_MAC
+       tristate "Blackfin on-chip MAC support"
+       depends on (BF516 || BF518 || BF526 || BF527 || BF536 || BF537)
+       select CRC32
+       select MII
+       select PHYLIB
+       select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
+       ---help---
+         This is the driver for Blackfin on-chip mac device. Say Y if you want
+         it compiled into the kernel. This driver is also available as a
+         module ( = code which can be inserted in and removed from the running
+         kernel whenever you want). The module will be called bfin_mac.
+
+config BFIN_MAC_USE_L1
+       bool "Use L1 memory for rx/tx packets"
+       depends on BFIN_MAC && (BF527 || BF537)
+       default y
+       ---help---
+         To get maximum network performance, you should use L1 memory as rx/tx
+         buffers. Say N here if you want to reserve L1 memory for other uses.
+
+config BFIN_TX_DESC_NUM
+       int "Number of transmit buffer packets"
+       depends on BFIN_MAC
+       range 6 10 if BFIN_MAC_USE_L1
+       range 10 100
+       default "10"
+       ---help---
+         Set the number of buffer packets used in driver.
+
+config BFIN_RX_DESC_NUM
+       int "Number of receive buffer packets"
+       depends on BFIN_MAC
+       range 20 100 if BFIN_MAC_USE_L1
+       range 20 800
+       default "20"
+       ---help---
+         Set the number of buffer packets used in driver.
+
+config BFIN_MAC_USE_HWSTAMP
+       bool "Use IEEE 1588 hwstamp"
+       depends on BFIN_MAC && BF518
+       default y
+       ---help---
+         To support the IEEE 1588 Precision Time Protocol (PTP), select y here
+
+endif # NET_BFIN
diff --git a/drivers/net/ethernet/adi/Makefile b/drivers/net/ethernet/adi/Makefile
new file mode 100644 (file)
index 0000000..b1fbe19
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Blackfin device drivers.
+#
+
+obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
similarity index 99%
rename from drivers/net/bfin_mac.c
rename to drivers/net/ethernet/adi/bfin_mac.c
index 6c019e14854691ab70ebece126dcf0e8cf0d4195..b6d69c91db96dcf89af8a3e414c91cd39a7b7664 100644 (file)
@@ -1449,7 +1449,7 @@ static const struct net_device_ops bfin_mac_netdev_ops = {
        .ndo_start_xmit         = bfin_mac_hard_start_xmit,
        .ndo_set_mac_address    = bfin_mac_set_mac_address,
        .ndo_tx_timeout         = bfin_mac_timeout,
-       .ndo_set_multicast_list = bfin_mac_set_multicast_list,
+       .ndo_set_rx_mode        = bfin_mac_set_multicast_list,
        .ndo_do_ioctl           = bfin_mac_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
diff --git a/drivers/net/ethernet/aeroflex/Kconfig b/drivers/net/ethernet/aeroflex/Kconfig
new file mode 100644 (file)
index 0000000..4f4a8d7
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Aeroflex Gaisler network device configuration
+#
+
+config GRETH
+       tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
+       depends on SPARC
+       select PHYLIB
+       select CRC32
+       ---help---
+         Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
diff --git a/drivers/net/ethernet/aeroflex/Makefile b/drivers/net/ethernet/aeroflex/Makefile
new file mode 100644 (file)
index 0000000..6e62a67
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Aeroflex Gaisler network device drivers.
+#
+
+obj-$(CONFIG_GRETH) += greth.o
similarity index 99%
rename from drivers/net/greth.c
rename to drivers/net/ethernet/aeroflex/greth.c
index 16ce45c1193419fc7193f59de18049708ef3a2e2..a5f6b07f8f3ee4fd0fa30147c2e9e90fa645ef23 100644 (file)
@@ -1539,7 +1539,7 @@ static int __devinit greth_of_probe(struct platform_device *ofdev)
        }
 
        if (greth->multicast) {
-               greth_netdev_ops.ndo_set_multicast_list = greth_set_multicast_list;
+               greth_netdev_ops.ndo_set_rx_mode = greth_set_multicast_list;
                dev->flags |= IFF_MULTICAST;
        } else {
                dev->flags &= ~IFF_MULTICAST;
diff --git a/drivers/net/ethernet/alteon/Kconfig b/drivers/net/ethernet/alteon/Kconfig
new file mode 100644 (file)
index 0000000..68862e4
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Alteon network device configuration
+#
+
+config NET_VENDOR_ALTEON
+       bool "Alteon devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Alteon cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_ALTEON
+
+config ACENIC
+       tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
+       depends on PCI
+       ---help---
+         Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
+         GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
+         adapter. The driver allows for using the Jumbo Frame option (9000
+         bytes/frame) however it requires that your switches can handle this
+         as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig
+         line.
+
+         To compile this driver as a module, choose M here: the
+         module will be called acenic.
+
+config ACENIC_OMIT_TIGON_I
+       bool "Omit support for old Tigon I based AceNICs"
+       depends on ACENIC
+       ---help---
+         Say Y here if you only have Tigon II based AceNICs and want to leave
+         out support for the older Tigon I based cards which are no longer
+         being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
+         version)).  This will reduce the size of the driver object by
+         app. 100KB.  If you are not sure whether your card is a Tigon I or a
+         Tigon II, say N here.
+
+         The safe and default value for this is N.
+
+endif # NET_VENDOR_ALTEON
diff --git a/drivers/net/ethernet/alteon/Makefile b/drivers/net/ethernet/alteon/Makefile
new file mode 100644 (file)
index 0000000..a2ca173
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Alteon network device drivers.
+#
+
+obj-$(CONFIG_ACENIC) += acenic.o
similarity index 99%
rename from drivers/net/acenic.c
rename to drivers/net/ethernet/alteon/acenic.c
index 31798f5f5d0601ffdc7f6522edb33f6b8a7cda47..1d6f2db794fd82b4de09c85654687ef0138d44a3 100644 (file)
@@ -449,7 +449,7 @@ static const struct net_device_ops ace_netdev_ops = {
        .ndo_tx_timeout         = ace_watchdog,
        .ndo_get_stats          = ace_get_stats,
        .ndo_start_xmit         = ace_start_xmit,
-       .ndo_set_multicast_list = ace_set_multicast_list,
+       .ndo_set_rx_mode        = ace_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ace_set_mac_addr,
        .ndo_change_mtu         = ace_change_mtu,
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
new file mode 100644 (file)
index 0000000..0513940
--- /dev/null
@@ -0,0 +1,192 @@
+#
+# AMD network device configuration
+#
+
+config NET_VENDOR_AMD
+       bool "AMD devices"
+       depends on DIO || MACH_DECSTATION || MVME147 || ATARI || SUN3 || \
+                  SUN3X || SBUS || PCI || ZORRO || (ISA && ISA_DMA_API) || \
+                  (ARM && ARCH_EBSA110) || ISA || EISA || MCA || PCMCIA
+       ---help---
+         If you have a network (Ethernet) chipset belonging to this class,
+         say Y.
+
+         Note that the answer to this question does not directly affect
+         the kernel: saying N will just case the configurator to skip all
+         the questions regarding AMD chipsets. If you say Y, you will be asked
+         for your specific chipset/driver in the following questions.
+
+if NET_VENDOR_AMD
+
+config A2065
+       tristate "A2065 support"
+       depends on ZORRO
+       select CRC32
+       ---help---
+         If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
+         say N.
+
+         To compile this driver as a module, choose M here: the module
+         will be called a2065.
+
+config AMD8111_ETH
+       tristate "AMD 8111 (new PCI LANCE) support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         If you have an AMD 8111-based PCI LANCE ethernet card,
+         answer Y here and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called amd8111e.
+
+config LANCE
+       tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
+       depends on ISA && ISA_DMA_API
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
+         of this type.
+
+         To compile this driver as a module, choose M here: the module
+         will be called lance.  This is recommended.
+
+config PCNET32
+       tristate "AMD PCnet32 PCI support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
+         answer Y here and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called pcnet32.
+
+config ARIADNE
+       tristate "Ariadne support"
+       depends on ZORRO
+       ---help---
+         If you have a Village Tronic Ariadne Ethernet adapter, say Y.
+         Otherwise, say N.
+
+         To compile this driver as a module, choose M here: the module
+         will be called ariadne.
+
+config ARM_AM79C961A
+       bool "ARM EBSA110 AM79C961A support"
+       depends on ARM && ARCH_EBSA110
+       select CRC32
+       ---help---
+         If you wish to compile a kernel for the EBSA-110, then you should
+         always answer Y to this.
+
+config ATARILANCE
+       tristate "Atari LANCE support"
+       depends on ATARI
+       ---help---
+         Say Y to include support for several Atari Ethernet adapters based
+         on the AMD LANCE chipset: RieblCard (with or without battery), or
+         PAMCard VME (also the version by Rhotron, with different addresses).
+
+config DECLANCE
+       tristate "DEC LANCE ethernet controller support"
+       depends on MACH_DECSTATION
+       select CRC32
+       ---help---
+         This driver is for the series of Ethernet controllers produced by
+         DEC (now Compaq) based on the AMD LANCE chipset, including the
+         DEPCA series.  (This chipset is better known via the NE2100 cards.)
+
+config DEPCA
+       tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
+       depends on (ISA || EISA || MCA)
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto> as well as
+         <file:drivers/net/depca.c>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called depca.
+
+config HPLANCE
+       bool "HP on-board LANCE support"
+       depends on DIO
+       select CRC32
+       ---help---
+         If you want to use the builtin "LANCE" Ethernet controller on an
+         HP300 machine, say Y here.
+
+config MIPS_AU1X00_ENET
+       tristate "MIPS AU1000 Ethernet support"
+       depends on MIPS_ALCHEMY
+       select PHYLIB
+       select CRC32
+       ---help---
+         If you have an Alchemy Semi AU1X00 based system
+         say Y.  Otherwise, say N.
+
+config MVME147_NET
+       tristate "MVME147 (LANCE) Ethernet support"
+       depends on MVME147
+       select CRC32
+       ---help---
+         Support for the on-board Ethernet interface on the Motorola MVME147
+         single-board computer.  Say Y here to include the
+         driver for this chip in your kernel.
+         To compile this driver as a module, choose M here.
+
+config PCMCIA_NMCLAN
+       tristate "New Media PCMCIA support"
+       depends on PCMCIA
+       help
+         Say Y here if you intend to attach a New Media Ethernet or LiveWire
+         PCMCIA (PC-card) Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called nmclan_cs.  If unsure, say N.
+
+config NI65
+       tristate "NI6510 support"
+       depends on ISA && ISA_DMA_API
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ni65.
+
+config SUN3LANCE
+       tristate "Sun3/Sun3x on-board LANCE support"
+       depends on (SUN3 || SUN3X)
+       ---help---
+         Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
+         featured an AMD LANCE 10Mbit Ethernet controller on board; say Y
+         here to compile in the Linux driver for this and enable Ethernet.
+         General Linux information on the Sun 3 and 3x series (now
+         discontinued) is at
+         <http://www.angelfire.com/ca2/tech68k/sun3.html>.
+
+         If you're not building a kernel for a Sun 3, say N.
+
+config SUNLANCE
+       tristate "Sun LANCE support"
+       depends on SBUS
+       select CRC32
+       ---help---
+         This driver supports the "le" interface present on all 32-bit Sparc
+         systems, on some older Ultra systems and as an Sbus option.  These
+         cards are based on the AMD LANCE chipset, which is better known
+         via the NE2100 cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sunlance.
+
+endif # NET_VENDOR_AMD
diff --git a/drivers/net/ethernet/amd/Makefile b/drivers/net/ethernet/amd/Makefile
new file mode 100644 (file)
index 0000000..175caa5
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Makefile for the AMD network device drivers.
+#
+
+obj-$(CONFIG_A2065) += a2065.o
+obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
+obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
+obj-$(CONFIG_ARIADNE) += ariadne.o
+obj-$(CONFIG_ATARILANCE) += atarilance.o
+obj-$(CONFIG_DECLANCE) += declance.o
+obj-$(CONFIG_DEPCA) += depca.o
+obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
+obj-$(CONFIG_LANCE) += lance.o
+obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
+obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
+obj-$(CONFIG_PCMCIA_NMCLAN) += nmclan_cs.o
+obj-$(CONFIG_NI65) += ni65.o
+obj-$(CONFIG_PCNET32) += pcnet32.o
+obj-$(CONFIG_SUN3LANCE) += sun3lance.o
+obj-$(CONFIG_SUNLANCE) += sunlance.o
similarity index 99%
rename from drivers/net/a2065.c
rename to drivers/net/ethernet/amd/a2065.c
index e1e1b07d9b8d5ba1fc34bdacc201dcef1b4e9bda..825e5d4ef4c3ba739640186f8f8b57f5fb5f56b8 100644 (file)
@@ -664,7 +664,7 @@ static const struct net_device_ops lance_netdev_ops = {
        .ndo_stop               = lance_close,
        .ndo_start_xmit         = lance_start_xmit,
        .ndo_tx_timeout         = lance_tx_timeout,
-       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_set_rx_mode        = lance_set_multicast,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/arm/am79c961a.c
rename to drivers/net/ethernet/amd/am79c961a.c
index 52fe21e1e2cd11b20f50d3c59c7672818ac485bc..c2b630c5e852ce6198a6e5d3baaf61e96a577ade 100644 (file)
@@ -659,7 +659,7 @@ static const struct net_device_ops am79c961_netdev_ops = {
        .ndo_open               = am79c961_open,
        .ndo_stop               = am79c961_close,
        .ndo_start_xmit         = am79c961_sendpacket,
-       .ndo_set_multicast_list = am79c961_setmulticastlist,
+       .ndo_set_rx_mode        = am79c961_setmulticastlist,
        .ndo_tx_timeout         = am79c961_timeout,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/amd8111e.c
rename to drivers/net/ethernet/amd/amd8111e.c
index 78002ef9c0e56f13a7bcc0a0a5fce56fc4bbb2ad..a9745f4ddbfe11ad06573f2aa1043f2e6f249a53 100644 (file)
@@ -1798,7 +1798,7 @@ static const struct net_device_ops amd8111e_netdev_ops = {
        .ndo_start_xmit         = amd8111e_start_xmit,
        .ndo_tx_timeout         = amd8111e_tx_timeout,
        .ndo_get_stats          = amd8111e_get_stats,
-       .ndo_set_multicast_list = amd8111e_set_multicast_list,
+       .ndo_set_rx_mode        = amd8111e_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = amd8111e_set_mac_address,
        .ndo_do_ioctl           = amd8111e_ioctl,
similarity index 99%
rename from drivers/net/ariadne.c
rename to drivers/net/ethernet/amd/ariadne.c
index 7ed78f4020428dd203233c3ba1f95a8f43de04a0..eb18e1fe65c89ef88296b3eec49b22b76ad91aee 100644 (file)
@@ -704,7 +704,7 @@ static const struct net_device_ops ariadne_netdev_ops = {
        .ndo_start_xmit         = ariadne_start_xmit,
        .ndo_tx_timeout         = ariadne_tx_timeout,
        .ndo_get_stats          = ariadne_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/atarilance.c
rename to drivers/net/ethernet/amd/atarilance.c
index 1264d781b5549e7dd1ed8f9d56b339cd96a44ebc..15bfa28d6c53a0ef36eede8105eb7703b397ba91 100644 (file)
@@ -456,7 +456,7 @@ static const struct net_device_ops lance_netdev_ops = {
        .ndo_open               = lance_open,
        .ndo_stop               = lance_close,
        .ndo_start_xmit         = lance_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_set_mac_address    = lance_set_mac_address,
        .ndo_tx_timeout         = lance_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/au1000_eth.c
rename to drivers/net/ethernet/amd/au1000_eth.c
index b9debcfb61a01640bc11a413d8bf62d6636d9761..82386677bb8c48f5549d9328fd8e835dc383325e 100644 (file)
@@ -1010,7 +1010,7 @@ static const struct net_device_ops au1000_netdev_ops = {
        .ndo_open               = au1000_open,
        .ndo_stop               = au1000_close,
        .ndo_start_xmit         = au1000_tx,
-       .ndo_set_multicast_list = au1000_multicast_list,
+       .ndo_set_rx_mode        = au1000_multicast_list,
        .ndo_do_ioctl           = au1000_ioctl,
        .ndo_tx_timeout         = au1000_tx_timeout,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/declance.c
rename to drivers/net/ethernet/amd/declance.c
index d5598f6584a3c64a7d6af59695564def992eb512..73f8d4fa682dabfff623cbfddaca87dcf56190de 100644 (file)
@@ -1015,7 +1015,7 @@ static const struct net_device_ops lance_netdev_ops = {
        .ndo_stop               = lance_close,
        .ndo_start_xmit         = lance_start_xmit,
        .ndo_tx_timeout         = lance_tx_timeout,
-       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_set_rx_mode        = lance_set_multicast,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/depca.c
rename to drivers/net/ethernet/amd/depca.c
index f2015a851977e6f36e936d01455b66c314d6782a..681970c07f22337ba70acdcd7ef59f290b09b155 100644 (file)
@@ -572,7 +572,7 @@ static const struct net_device_ops depca_netdev_ops = {
        .ndo_open               = depca_open,
        .ndo_start_xmit         = depca_start_xmit,
        .ndo_stop               = depca_close,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_do_ioctl           = depca_ioctl,
        .ndo_tx_timeout         = depca_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/hplance.c
rename to drivers/net/ethernet/amd/hplance.c
index a900d5bf294889578df802c280ca4388bce57631..86aa0d546a5b09f697c0ded4d73926214d013eec 100644 (file)
@@ -74,7 +74,7 @@ static const struct net_device_ops hplance_netdev_ops = {
        .ndo_open               = hplance_open,
        .ndo_stop               = hplance_close,
        .ndo_start_xmit         = lance_start_xmit,
-       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_set_rx_mode        = lance_set_multicast,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/lance.c
rename to drivers/net/ethernet/amd/lance.c
index 02336edce748db5b4e959d8b83e637d48c20aac4..a6e2e840884ecc1bf04084ddb02012b046b8cc4d 100644 (file)
@@ -459,7 +459,7 @@ static const struct net_device_ops lance_netdev_ops = {
        .ndo_start_xmit         = lance_start_xmit,
        .ndo_stop               = lance_close,
        .ndo_get_stats          = lance_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = lance_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/mvme147.c
rename to drivers/net/ethernet/amd/mvme147.c
index 3a7ad840d5b5b36c54f676bd97b66d60417f4e1d..56bc47a94186aa746f445a426017dd2ed6f05255 100644 (file)
@@ -61,7 +61,7 @@ static const struct net_device_ops lance_netdev_ops = {
        .ndo_open               = m147lance_open,
        .ndo_stop               = m147lance_close,
        .ndo_start_xmit         = lance_start_xmit,
-       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_set_rx_mode        = lance_set_multicast,
        .ndo_tx_timeout         = lance_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/ni65.c
rename to drivers/net/ethernet/amd/ni65.c
index c75ae85eb918c92cd61dc2cc2d1269e303b355a7..6e6aa7213aab50a7c6118819b5cf83c862510922 100644 (file)
@@ -406,7 +406,7 @@ static const struct net_device_ops ni65_netdev_ops = {
        .ndo_stop               = ni65_close,
        .ndo_start_xmit         = ni65_send_packet,
        .ndo_tx_timeout         = ni65_timeout,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/pcmcia/nmclan_cs.c
rename to drivers/net/ethernet/amd/nmclan_cs.c
index 9d70b65952201c646d90f0e21bd9658d34ad2502..3accd5d21b08ff1bb5a423485d1bf775273501ce 100644 (file)
@@ -430,7 +430,7 @@ static const struct net_device_ops mace_netdev_ops = {
        .ndo_tx_timeout         = mace_tx_timeout,
        .ndo_set_config         = mace_config,
        .ndo_get_stats          = mace_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/pcnet32.c
rename to drivers/net/ethernet/amd/pcnet32.c
index 80b6f36a807406ef759b01df1c5de4902cb0b77f..c90fe917090bed66b345f27aabc792fd85b313af 100644 (file)
@@ -1505,7 +1505,7 @@ static const struct net_device_ops pcnet32_netdev_ops = {
        .ndo_start_xmit         = pcnet32_start_xmit,
        .ndo_tx_timeout         = pcnet32_tx_timeout,
        .ndo_get_stats          = pcnet32_get_stats,
-       .ndo_set_multicast_list = pcnet32_set_multicast_list,
+       .ndo_set_rx_mode        = pcnet32_set_multicast_list,
        .ndo_do_ioctl           = pcnet32_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/sun3lance.c
rename to drivers/net/ethernet/amd/sun3lance.c
index 7d9ec23aabf6b22be99a01d2d7526d5e6cc23cda..080b71fcc6833d41a12c5fffa48e57812ce51a96 100644 (file)
@@ -297,7 +297,7 @@ static const struct net_device_ops lance_netdev_ops = {
        .ndo_open               = lance_open,
        .ndo_stop               = lance_close,
        .ndo_start_xmit         = lance_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_set_mac_address    = NULL,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/sunlance.c
rename to drivers/net/ethernet/amd/sunlance.c
index 06f2d4382dc4f7811f7d6700d6ff720a97821526..8fda457f94cf809d82793a659359e78ab0876b7a 100644 (file)
@@ -1298,7 +1298,7 @@ static const struct net_device_ops sparc_lance_ops = {
        .ndo_open               = lance_open,
        .ndo_stop               = lance_close,
        .ndo_start_xmit         = lance_start_xmit,
-       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_set_rx_mode        = lance_set_multicast,
        .ndo_tx_timeout         = lance_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/apple/Kconfig b/drivers/net/ethernet/apple/Kconfig
new file mode 100644 (file)
index 0000000..fc796bc
--- /dev/null
@@ -0,0 +1,96 @@
+#
+# Apple device configuration
+#
+
+config NET_VENDOR_APPLE
+       bool "Apple devices"
+       depends on (PPC_PMAC && PPC32) || MAC || ISA || EISA || MACH_IXDP2351 \
+                  || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about IBM devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_APPLE
+
+config MACE
+       tristate "MACE (Power Mac ethernet) support"
+       depends on PPC_PMAC && PPC32
+       select CRC32
+       ---help---
+         Power Macintoshes and clones with Ethernet built-in on the
+         motherboard will usually use a MACE (Medium Access Control for
+         Ethernet) interface. Say Y to include support for the MACE chip.
+
+         To compile this driver as a module, choose M here: the module
+         will be called mace.
+
+config MACE_AAUI_PORT
+       bool "Use AAUI port instead of TP by default"
+       depends on MACE
+       ---help---
+         Some Apple machines (notably the Apple Network Server) which use the
+         MACE ethernet chip have an Apple AUI port (small 15-pin connector),
+         instead of an 8-pin RJ45 connector for twisted-pair ethernet.  Say
+         Y here if you have such a machine.  If unsure, say N.
+         The driver will default to AAUI on ANS anyway, and if you use it as
+         a module, you can provide the port_aaui=0|1 to force the driver.
+
+config BMAC
+       tristate "BMAC (G3 ethernet) support"
+       depends on PPC_PMAC && PPC32
+       select CRC32
+       ---help---
+         Say Y for support of BMAC Ethernet interfaces. These are used on G3
+         computers.
+
+         To compile this driver as a module, choose M here: the module
+         will be called bmac.
+
+config MAC89x0
+       tristate "Macintosh CS89x0 based ethernet cards"
+       depends on MAC
+       ---help---
+         Support for CS89x0 chipset based Ethernet cards.  If you have a
+         Nubus or LC-PDS network (Ethernet) card of this type, say Y and
+         read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. This module will
+         be called mac89x0.
+
+config MACMACE
+       bool "Macintosh (AV) onboard MACE ethernet"
+       depends on MAC
+       select CRC32
+       ---help---
+         Support for the onboard AMD 79C940 MACE Ethernet controller used in
+         the 660AV and 840AV Macintosh.  If you have one of these Macintoshes
+         say Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+config CS89x0
+       tristate "CS89x0 support"
+       depends on (ISA || EISA || MACH_IXDP2351 \
+               || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
+       ---help---
+         Support for CS89x0 chipset based Ethernet cards. If you have a
+         network (Ethernet) card of this type, say Y and read the
+         Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto> as well as
+         <file:Documentation/networking/cs89x0.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called cs89x0.
+
+config CS89x0_NONISA_IRQ
+       def_bool y
+       depends on CS89x0 != n
+       depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
+
+endif # NET_VENDOR_APPLE
diff --git a/drivers/net/ethernet/apple/Makefile b/drivers/net/ethernet/apple/Makefile
new file mode 100644 (file)
index 0000000..9d30086
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for the Apple network device drivers.
+#
+
+obj-$(CONFIG_MACE) += mace.o
+obj-$(CONFIG_BMAC) += bmac.o
+obj-$(CONFIG_MAC89x0) += mac89x0.o
+obj-$(CONFIG_CS89x0) += cs89x0.o
+obj-$(CONFIG_MACMACE) += macmace.o
similarity index 99%
rename from drivers/net/bmac.c
rename to drivers/net/ethernet/apple/bmac.c
index 45e45e8d3d66f86f2c886a88678c56a27302f032..d070b229dbf753b9f59afeef69f7391ec32f71a3 100644 (file)
@@ -1237,7 +1237,7 @@ static const struct net_device_ops bmac_netdev_ops = {
        .ndo_open               = bmac_open,
        .ndo_stop               = bmac_close,
        .ndo_start_xmit         = bmac_output,
-       .ndo_set_multicast_list = bmac_set_multicast,
+       .ndo_set_rx_mode        = bmac_set_multicast,
        .ndo_set_mac_address    = bmac_set_address,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/cs89x0.c
rename to drivers/net/ethernet/apple/cs89x0.c
index 537a4b2e2020032a2d11cfeff92dfdd0c39d71a2..f328da24c8fa5b66266d0c9e3b374424161b50a2 100644 (file)
@@ -488,7 +488,7 @@ static const struct net_device_ops net_ops = {
        .ndo_tx_timeout         = net_timeout,
        .ndo_start_xmit         = net_send_packet,
        .ndo_get_stats          = net_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_set_mac_address    = set_mac_address,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = net_poll_controller,
similarity index 99%
rename from drivers/net/mac89x0.c
rename to drivers/net/ethernet/apple/mac89x0.c
index 669b317974a88a74a65d76865316d78cbfd17140..83781f316d1f7e91eebbbb739f35a352b149c9e8 100644 (file)
@@ -170,7 +170,7 @@ static const struct net_device_ops mac89x0_netdev_ops = {
        .ndo_stop               = net_close,
        .ndo_start_xmit         = net_send_packet,
        .ndo_get_stats          = net_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_set_mac_address    = set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/mace.c
rename to drivers/net/ethernet/apple/mace.c
index 2074e9724ba3f2a231d632899b6b14fbe767a39f..bec87bd9195c018872cd3e1c218b893962e3f7a3 100644 (file)
@@ -100,7 +100,7 @@ static const struct net_device_ops mace_netdev_ops = {
        .ndo_open               = mace_open,
        .ndo_stop               = mace_close,
        .ndo_start_xmit         = mace_xmit_start,
-       .ndo_set_multicast_list = mace_set_multicast,
+       .ndo_set_rx_mode        = mace_set_multicast,
        .ndo_set_mac_address    = mace_set_address,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/macmace.c
rename to drivers/net/ethernet/apple/macmace.c
index 4286e67f9634dc1f2126fe63130bfda026773c15..6cd3f8646dcddf9e1377e16e60c2c3653e5f7c72 100644 (file)
@@ -185,7 +185,7 @@ static const struct net_device_ops mace_netdev_ops = {
        .ndo_stop               = mace_close,
        .ndo_start_xmit         = mace_xmit_start,
        .ndo_tx_timeout         = mace_tx_timeout,
-       .ndo_set_multicast_list = mace_set_multicast,
+       .ndo_set_rx_mode        = mace_set_multicast,
        .ndo_set_mac_address    = mace_set_address,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig
new file mode 100644 (file)
index 0000000..966c6c7
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# Atheros device configuration
+#
+
+config NET_VENDOR_ATHEROS
+       bool "Atheros devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Atheros devices. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_ATHEROS
+
+config ATL2
+       tristate "Atheros L2 Fast Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros L2 fast ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl2.
+
+config ATL1
+       tristate "Atheros/Attansic L1 Gigabit Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros/Attansic L1 gigabit ethernet
+         adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1.
+
+config ATL1E
+       tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros L1E gigabit ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1e.
+
+config ATL1C
+       tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros L1C gigabit ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1c.
+
+endif # NET_VENDOR_ATHEROS
diff --git a/drivers/net/ethernet/atheros/Makefile b/drivers/net/ethernet/atheros/Makefile
new file mode 100644 (file)
index 0000000..e7e76fb
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the Atheros network device drivers.
+#
+
+obj-$(CONFIG_ATL1) += atlx/
+obj-$(CONFIG_ATL2) += atlx/
+obj-$(CONFIG_ATL1E) += atl1e/
+obj-$(CONFIG_ATL1C) += atl1c/
similarity index 99%
rename from drivers/net/atl1c/atl1c_main.c
rename to drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 972244218408e5db5f8a33f983d34ec5e5a82b5c..acb4c1098cae8640c8a2d9f59682567f47146433 100644 (file)
@@ -2600,7 +2600,7 @@ static const struct net_device_ops atl1c_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_start_xmit         = atl1c_xmit_frame,
        .ndo_set_mac_address    = atl1c_set_mac_addr,
-       .ndo_set_multicast_list = atl1c_set_multi,
+       .ndo_set_rx_mode        = atl1c_set_multi,
        .ndo_change_mtu         = atl1c_change_mtu,
        .ndo_fix_features       = atl1c_fix_features,
        .ndo_set_features       = atl1c_set_features,
similarity index 99%
rename from drivers/net/atl1e/atl1e_main.c
rename to drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index d8d411998fa332f8d951371ff4676836ca4e9152..1b5dc799348d45ef9f4987cb2eded2fb675e2d89 100644 (file)
@@ -2212,7 +2212,7 @@ static const struct net_device_ops atl1e_netdev_ops = {
        .ndo_stop               = atl1e_close,
        .ndo_start_xmit         = atl1e_xmit_frame,
        .ndo_get_stats          = atl1e_get_stats,
-       .ndo_set_multicast_list = atl1e_set_multi,
+       .ndo_set_rx_mode        = atl1e_set_multi,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = atl1e_set_mac_addr,
        .ndo_fix_features       = atl1e_fix_features,
similarity index 99%
rename from drivers/net/atlx/atl1.c
rename to drivers/net/ethernet/atheros/atlx/atl1.c
index 97e6954304eab6aa502384e5febe7bbc76b1274c..c34e82391f754ccd59edc9000e5240ab97a6175b 100644 (file)
@@ -2869,7 +2869,7 @@ static const struct net_device_ops atl1_netdev_ops = {
        .ndo_open               = atl1_open,
        .ndo_stop               = atl1_close,
        .ndo_start_xmit         = atl1_xmit_frame,
-       .ndo_set_multicast_list = atlx_set_multi,
+       .ndo_set_rx_mode        = atlx_set_multi,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = atl1_set_mac,
        .ndo_change_mtu         = atl1_change_mtu,
similarity index 99%
rename from drivers/net/atlx/atl2.c
rename to drivers/net/ethernet/atheros/atlx/atl2.c
index d4f7dda397217e30063b91246902c942702ece8a..1feae5928a4b0060707c1f8b6111caed46ea66f5 100644 (file)
@@ -1325,7 +1325,7 @@ static const struct net_device_ops atl2_netdev_ops = {
        .ndo_open               = atl2_open,
        .ndo_stop               = atl2_close,
        .ndo_start_xmit         = atl2_xmit_frame,
-       .ndo_set_multicast_list = atl2_set_multi,
+       .ndo_set_rx_mode        = atl2_set_multi,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = atl2_set_mac,
        .ndo_change_mtu         = atl2_change_mtu,
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
new file mode 100644 (file)
index 0000000..8986e57
--- /dev/null
@@ -0,0 +1,119 @@
+#
+# Broadcom device configuration
+#
+
+config NET_VENDOR_BROADCOM
+       bool "Broadcom devices"
+       depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \
+                  SIBYTE_SB1xxx_SOC
+       ---help---
+         If you have a network (Ethernet) chipset belonging to this class,
+         say Y.
+
+         Note that the answer to this question does not directly affect
+         the kernel: saying N will just case the configurator to skip all
+         the questions regarding AMD chipsets. If you say Y, you will be asked
+         for your specific chipset/driver in the following questions.
+
+if NET_VENDOR_BROADCOM
+
+config B44
+       tristate "Broadcom 440x/47xx ethernet support"
+       depends on SSB_POSSIBLE && HAS_DMA
+       select SSB
+       select MII
+       ---help---
+         If you have a network (Ethernet) controller of this type, say Y
+         or M and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called b44.
+
+# Auto-select SSB PCI-HOST support, if possible
+config B44_PCI_AUTOSELECT
+       bool
+       depends on B44 && SSB_PCIHOST_POSSIBLE
+       select SSB_PCIHOST
+       default y
+
+# Auto-select SSB PCICORE driver, if possible
+config B44_PCICORE_AUTOSELECT
+       bool
+       depends on B44 && SSB_DRIVER_PCICORE_POSSIBLE
+       select SSB_DRIVER_PCICORE
+       default y
+
+config B44_PCI
+       bool
+       depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
+       default y
+
+config BCM63XX_ENET
+       tristate "Broadcom 63xx internal mac support"
+       depends on BCM63XX
+       select MII
+       select PHYLIB
+       help
+         This driver supports the ethernet MACs in the Broadcom 63xx
+         MIPS chipset family (BCM63XX).
+
+config BNX2
+       tristate "Broadcom NetXtremeII support"
+       depends on PCI
+       select CRC32
+       select FW_LOADER
+       ---help---
+         This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called bnx2.  This is recommended.
+
+config CNIC
+       tristate "Broadcom CNIC support"
+       depends on PCI
+       select BNX2
+       select UIO
+       ---help---
+         This driver supports offload features of Broadcom NetXtremeII
+         gigabit Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called cnic.  This is recommended.
+
+config SB1250_MAC
+       tristate "SB1250 Gigabit Ethernet support"
+       depends on SIBYTE_SB1xxx_SOC
+       select PHYLIB
+       ---help---
+         This driver supports Gigabit Ethernet interfaces based on the
+         Broadcom SiByte family of System-On-a-Chip parts.  They include
+         the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
+         and BCM1480 chips.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sb1250-mac.
+
+config TIGON3
+       tristate "Broadcom Tigon3 support"
+       depends on PCI
+       select PHYLIB
+       ---help---
+         This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called tg3.  This is recommended.
+
+config BNX2X
+       tristate "Broadcom NetXtremeII 10Gb support"
+       depends on PCI
+       select FW_LOADER
+       select ZLIB_INFLATE
+       select LIBCRC32C
+       select MDIO
+       ---help---
+         This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
+         To compile this driver as a module, choose M here: the module
+         will be called bnx2x.  This is recommended.
+
+endif # NET_VENDOR_BROADCOM
diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile
new file mode 100644 (file)
index 0000000..b789605
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the Broadcom network device drivers.
+#
+
+obj-$(CONFIG_B44) += b44.o
+obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
+obj-$(CONFIG_BNX2) += bnx2.o
+obj-$(CONFIG_CNIC) += cnic.o
+obj-$(CONFIG_BNX2X) += bnx2x/
+obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
+obj-$(CONFIG_TIGON3) += tg3.o
similarity index 99%
rename from drivers/net/b44.c
rename to drivers/net/ethernet/broadcom/b44.c
index 41ea84e3f69c60fc9785254a254bd14ecfea1da7..4cf835dbc1222f6c90154b601bc02b76d6efbbb6 100644 (file)
@@ -2114,7 +2114,7 @@ static const struct net_device_ops b44_netdev_ops = {
        .ndo_stop               = b44_close,
        .ndo_start_xmit         = b44_start_xmit,
        .ndo_get_stats          = b44_get_stats,
-       .ndo_set_multicast_list = b44_set_rx_mode,
+       .ndo_set_rx_mode        = b44_set_rx_mode,
        .ndo_set_mac_address    = b44_set_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = b44_ioctl,
similarity index 99%
rename from drivers/net/bcm63xx_enet.c
rename to drivers/net/ethernet/broadcom/bcm63xx_enet.c
index 1d9b9858067cfb25cb62dd2622a9a7bdf3eb9e56..05b02286607623e37e8b8b4e65c1c32d34bfd567 100644 (file)
@@ -1603,7 +1603,7 @@ static const struct net_device_ops bcm_enet_ops = {
        .ndo_stop               = bcm_enet_stop,
        .ndo_start_xmit         = bcm_enet_start_xmit,
        .ndo_set_mac_address    = bcm_enet_set_mac_address,
-       .ndo_set_multicast_list = bcm_enet_set_multicast_list,
+       .ndo_set_rx_mode        = bcm_enet_set_multicast_list,
        .ndo_do_ioctl           = bcm_enet_ioctl,
        .ndo_change_mtu         = bcm_enet_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
similarity index 99%
rename from drivers/net/bnx2.c
rename to drivers/net/ethernet/broadcom/bnx2.c
index 4b2b57018a02bdf85b9510bf1e6a96006b4bac7e..4a9a8c8184d8e6390aa7b93986d9550924b3f7f2 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/time.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <net/tcp.h>
@@ -8370,6 +8371,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->vlan_features = dev->hw_features;
        dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->features |= dev->hw_features;
+       dev->priv_flags |= IFF_UNICAST_FLT;
 
        if ((rc = register_netdev(dev))) {
                dev_err(&pdev->dev, "Cannot register net device\n");
similarity index 98%
rename from drivers/net/bnx2x/bnx2x.h
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index c423504a755f555703c88bbe303820eb532ea1a2..f127768e4e833d036b324c3f8c0212a3c960de61 100644 (file)
 #define BNX2X_MSG_SP                   0x100000 /* was: NETIF_MSG_INTR */
 #define BNX2X_MSG_FP                   0x200000 /* was: NETIF_MSG_INTR */
 
-#define DP_LEVEL                       KERN_NOTICE     /* was: KERN_DEBUG */
-
 /* regular debug print */
-#define DP(__mask, __fmt, __args...)                           \
+#define DP(__mask, fmt, ...)                                   \
 do {                                                           \
        if (bp->msg_enable & (__mask))                          \
-               printk(DP_LEVEL "[%s:%d(%s)]" __fmt,            \
-                      __func__, __LINE__,                      \
-                      bp->dev ? (bp->dev->name) : "?",         \
-                      ##__args);                               \
+               pr_notice("[%s:%d(%s)]" fmt,                    \
+                         __func__, __LINE__,                   \
+                         bp->dev ? (bp->dev->name) : "?",      \
+                         ##__VA_ARGS__);                       \
 } while (0)
 
-#define DP_CONT(__mask, __fmt, __args...)                      \
+#define DP_CONT(__mask, fmt, ...)                              \
 do {                                                           \
        if (bp->msg_enable & (__mask))                          \
-               pr_cont(__fmt, ##__args);                       \
+               pr_cont(fmt, ##__VA_ARGS__);                    \
 } while (0)
 
 /* errors debug print */
-#define BNX2X_DBG_ERR(__fmt, __args...)                                \
+#define BNX2X_DBG_ERR(fmt, ...)                                        \
 do {                                                           \
        if (netif_msg_probe(bp))                                \
-               pr_err("[%s:%d(%s)]" __fmt,                     \
+               pr_err("[%s:%d(%s)]" fmt,                       \
                       __func__, __LINE__,                      \
                       bp->dev ? (bp->dev->name) : "?",         \
-                      ##__args);                               \
+                      ##__VA_ARGS__);                          \
 } while (0)
 
 /* for errors (never masked) */
-#define BNX2X_ERR(__fmt, __args...)                            \
+#define BNX2X_ERR(fmt, ...)                                    \
 do {                                                           \
-       pr_err("[%s:%d(%s)]" __fmt,                             \
+       pr_err("[%s:%d(%s)]" fmt,                               \
               __func__, __LINE__,                              \
               bp->dev ? (bp->dev->name) : "?",                 \
-              ##__args);                                       \
-       } while (0)
+              ##__VA_ARGS__);                                  \
+} while (0)
 
-#define BNX2X_ERROR(__fmt, __args...) do { \
-       pr_err("[%s:%d]" __fmt, __func__, __LINE__, ##__args); \
-       } while (0)
+#define BNX2X_ERROR(fmt, ...)                                  \
+       pr_err("[%s:%d]" fmt, __func__, __LINE__, ##__VA_ARGS__)
 
 
 /* before we have a dev->name use dev_info() */
-#define BNX2X_DEV_INFO(__fmt, __args...)                        \
+#define BNX2X_DEV_INFO(fmt, ...)                                \
 do {                                                            \
        if (netif_msg_probe(bp))                                 \
-               dev_info(&bp->pdev->dev, __fmt, ##__args);       \
+               dev_info(&bp->pdev->dev, fmt, ##__VA_ARGS__);    \
 } while (0)
 
-#define BNX2X_MAC_FMT          "%pM"
-#define BNX2X_MAC_PRN_LIST(mac)        (mac)
-
-
 #ifdef BNX2X_STOP_ON_ERROR
 void bnx2x_int_disable(struct bnx2x *bp);
-#define bnx2x_panic() do { \
-               bp->panic = 1; \
-               BNX2X_ERR("driver assert\n"); \
-               bnx2x_int_disable(bp); \
-               bnx2x_panic_dump(bp); \
-       } while (0)
+#define bnx2x_panic()                          \
+do {                                           \
+       bp->panic = 1;                          \
+       BNX2X_ERR("driver assert\n");           \
+       bnx2x_int_disable(bp);                  \
+       bnx2x_panic_dump(bp);                   \
+} while (0)
 #else
-#define bnx2x_panic() do { \
-               bp->panic = 1; \
-               BNX2X_ERR("driver assert\n"); \
-               bnx2x_panic_dump(bp); \
-       } while (0)
+#define bnx2x_panic()                          \
+do {                                           \
+       bp->panic = 1;                          \
+       BNX2X_ERR("driver assert\n");           \
+       bnx2x_panic_dump(bp);                   \
+} while (0)
 #endif
 
 #define bnx2x_mc_addr(ha)      ((ha)->addr)
similarity index 98%
rename from drivers/net/bnx2x/bnx2x_cmn.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 37e5790681ad19e413a44293ecc0a9b4f40da5ff..93bff08c87ad1e749ac09e4ec58229db8876bb5c 100644 (file)
@@ -15,6 +15,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
 #include <linux/interrupt.h>
@@ -954,15 +956,16 @@ void __bnx2x_link_report(struct bnx2x *bp)
                netdev_err(bp->dev, "NIC Link is Down\n");
                return;
        } else {
+               const char *duplex;
+               const char *flow;
+
                netif_carrier_on(bp->dev);
-               netdev_info(bp->dev, "NIC Link is Up, ");
-               pr_cont("%d Mbps ", cur_data.line_speed);
 
                if (test_and_clear_bit(BNX2X_LINK_REPORT_FD,
                                       &cur_data.link_report_flags))
-                       pr_cont("full duplex");
+                       duplex = "full";
                else
-                       pr_cont("half duplex");
+                       duplex = "half";
 
                /* Handle the FC at the end so that only these flags would be
                 * possibly set. This way we may easily check if there is no FC
@@ -971,16 +974,19 @@ void __bnx2x_link_report(struct bnx2x *bp)
                if (cur_data.link_report_flags) {
                        if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
                                     &cur_data.link_report_flags)) {
-                               pr_cont(", receive ");
                                if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
                                     &cur_data.link_report_flags))
-                                       pr_cont("& transmit ");
+                                       flow = "ON - receive & transmit";
+                               else
+                                       flow = "ON - receive";
                        } else {
-                               pr_cont(", transmit ");
+                               flow = "ON - transmit";
                        }
-                       pr_cont("flow control ON");
+               } else {
+                       flow = "none";
                }
-               pr_cont("\n");
+               netdev_info(bp->dev, "NIC Link is Up, %d Mbps %s duplex, Flow control: %s\n",
+                           cur_data.line_speed, duplex, flow);
        }
 }
 
@@ -2605,7 +2611,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
 
        /* enable this debug print to view the transmission queue being used
-       DP(BNX2X_MSG_FP, "indices: txq %d, fp %d, txdata %d",
+       DP(BNX2X_MSG_FP, "indices: txq %d, fp %d, txdata %d\n",
           txq_index, fp_index, txdata_index); */
 
        /* locate the fastpath and the txdata */
@@ -2614,7 +2620,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* enable this debug print to view the tranmission details
        DP(BNX2X_MSG_FP,"transmitting packet cid %d fp index %d txdata_index %d"
-                       " tx_data ptr %p fp pointer %p",
+                       " tx_data ptr %p fp pointer %p\n",
           txdata->cid, fp_index, txdata_index, txdata, fp); */
 
        if (unlikely(bnx2x_tx_avail(bp, txdata) <
@@ -2931,14 +2937,14 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
        /* requested to support too many traffic classes */
        if (num_tc > bp->max_cos) {
                DP(NETIF_MSG_TX_ERR, "support for too many traffic classes"
-                                    " requested: %d. max supported is %d",
+                                    " requested: %d. max supported is %d\n",
                                     num_tc, bp->max_cos);
                return -EINVAL;
        }
 
        /* declare amount of supported traffic classes */
        if (netdev_set_num_tc(dev, num_tc)) {
-               DP(NETIF_MSG_TX_ERR, "failed to declare %d traffic classes",
+               DP(NETIF_MSG_TX_ERR, "failed to declare %d traffic classes\n",
                                     num_tc);
                return -EINVAL;
        }
@@ -2946,7 +2952,7 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
        /* configure priority to traffic class mapping */
        for (prio = 0; prio < BNX2X_MAX_PRIORITY; prio++) {
                netdev_set_prio_tc_map(dev, prio, bp->prio_to_cos[prio]);
-               DP(BNX2X_MSG_SP, "mapping priority %d to tc %d",
+               DP(BNX2X_MSG_SP, "mapping priority %d to tc %d\n",
                   prio, bp->prio_to_cos[prio]);
        }
 
@@ -2955,10 +2961,10 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
           This can be used for ets or pfc, and save the effort of setting
           up a multio class queue disc or negotiating DCBX with a switch
        netdev_set_prio_tc_map(dev, 0, 0);
-       DP(BNX2X_MSG_SP, "mapping priority %d to tc %d", 0, 0);
+       DP(BNX2X_MSG_SP, "mapping priority %d to tc %d\n", 0, 0);
        for (prio = 1; prio < 16; prio++) {
                netdev_set_prio_tc_map(dev, prio, 1);
-               DP(BNX2X_MSG_SP, "mapping priority %d to tc %d", prio, 1);
+               DP(BNX2X_MSG_SP, "mapping priority %d to tc %d\n", prio, 1);
        } */
 
        /* configure traffic class to transmission queue mapping */
@@ -2966,7 +2972,7 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
                count = BNX2X_NUM_ETH_QUEUES(bp);
                offset = cos * MAX_TXQS_PER_COS;
                netdev_set_tc_queue(dev, cos, count, offset);
-               DP(BNX2X_MSG_SP, "mapping tc %d to offset %d count %d",
+               DP(BNX2X_MSG_SP, "mapping tc %d to offset %d count %d\n",
                   cos, offset, count);
        }
 
@@ -3054,7 +3060,7 @@ static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index)
                        struct bnx2x_fp_txdata *txdata = &fp->txdata[cos];
 
                        DP(BNX2X_MSG_SP,
-                          "freeing tx memory of fp %d cos %d cid %d",
+                          "freeing tx memory of fp %d cos %d cid %d\n",
                           fp_index, cos, txdata->cid);
 
                        BNX2X_FREE(txdata->tx_buf_ring);
@@ -3136,7 +3142,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
                        struct bnx2x_fp_txdata *txdata = &fp->txdata[cos];
 
                        DP(BNX2X_MSG_SP, "allocating tx memory of "
-                                        "fp %d cos %d",
+                                        "fp %d cos %d\n",
                           index, cos);
 
                        BNX2X_ALLOC(txdata->tx_buf_ring,
@@ -3386,7 +3392,7 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
        struct bnx2x *bp = netdev_priv(dev);
 
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-               printk(KERN_ERR "Handling parity error recovery. Try again later\n");
+               pr_err("Handling parity error recovery. Try again later\n");
                return -EAGAIN;
        }
 
@@ -3512,7 +3518,7 @@ int bnx2x_resume(struct pci_dev *pdev)
        bp = netdev_priv(dev);
 
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-               printk(KERN_ERR "Handling parity error recovery. Try again later\n");
+               pr_err("Handling parity error recovery. Try again later\n");
                return -EAGAIN;
        }
 
similarity index 99%
rename from drivers/net/bnx2x/bnx2x_cmn.h
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 223bfeebc59798bd76fd2861bd8e87fc003a41b3..f290b23e57e7d95533544b0314d77202338ee9dc 100644 (file)
@@ -1289,7 +1289,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp,
        txdata->txq_index = txq_index;
        txdata->tx_cons_sb = tx_cons_sb;
 
-       DP(BNX2X_MSG_SP, "created tx data cid %d, txq %d",
+       DP(BNX2X_MSG_SP, "created tx data cid %d, txq %d\n",
           txdata->cid, txdata->txq_index);
 }
 
@@ -1333,7 +1333,7 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
        bnx2x_init_txdata(bp, &bnx2x_fcoe(bp, txdata[0]),
                          fp->cid, FCOE_TXQ_IDX(bp), BNX2X_FCOE_L2_TX_INDEX);
 
-       DP(BNX2X_MSG_SP, "created fcoe tx data (fp index %d)", fp->index);
+       DP(BNX2X_MSG_SP, "created fcoe tx data (fp index %d)\n", fp->index);
 
        /* qZone id equals to FW (per path) client id */
        bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fp_qzone_id(fp);
@@ -1481,8 +1481,8 @@ static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
        u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
                              FUNC_MF_CFG_MAX_BW_SHIFT;
        if (!max_cfg) {
-               BNX2X_ERR("Illegal configuration detected for Max BW - "
-                         "using 100 instead\n");
+               DP(NETIF_MSG_LINK,
+                  "Max BW configured to 0 - using 100 instead\n");
                max_cfg = 100;
        }
        return max_cfg;
similarity index 99%
rename from drivers/net/bnx2x/bnx2x_dcb.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
index a1e004a82f7ae92ae8250684352132892a4ced02..0b9bd551580bce9f5270f397afb6b4783bc1e80f 100644 (file)
@@ -16,6 +16,9 @@
  * Written by: Dmitry Kravkov
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -350,7 +353,7 @@ static void bnx2x_dcbx_map_nw(struct bnx2x *bp)
                if (cos_params[i].pri_bitmask & nw_prio) {
                        /* extend the bitmask with unmapped */
                        DP(NETIF_MSG_LINK,
-                          "cos %d extended with 0x%08x", i, unmapped);
+                          "cos %d extended with 0x%08x\n", i, unmapped);
                        cos_params[i].pri_bitmask |= unmapped;
                        break;
                }
similarity index 99%
rename from drivers/net/bnx2x/bnx2x_ethtool.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 221863059dae850e96d824e8eb4994ea2a93923d..767c22983c178229884bb681b4c317939d8100c5 100644 (file)
@@ -14,6 +14,9 @@
  * Statistics and Link management by Yitchak Gertner
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/types.h>
@@ -239,9 +242,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        cmd->maxrxpkt = 0;
 
        DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
-          DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %u\n"
-          DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
-          DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
+          "  supported 0x%x  advertising 0x%x  speed %u\n"
+          "  duplex %d  port %d  phy_address %d  transceiver %d\n"
+          "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
           cmd->cmd, cmd->supported, cmd->advertising,
           ethtool_cmd_speed(cmd),
           cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
@@ -482,7 +485,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        }
 
        DP(NETIF_MSG_LINK, "req_line_speed %d\n"
-          DP_LEVEL "  req_duplex %d  advertising 0x%x\n",
+          "  req_duplex %d  advertising 0x%x\n",
           bp->link_params.req_line_speed[cfg_idx],
           bp->link_params.req_duplex[cfg_idx],
           bp->port.advertising[cfg_idx]);
@@ -1028,7 +1031,7 @@ static int bnx2x_get_eeprom(struct net_device *dev,
                return -EAGAIN;
 
        DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
-          DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
+          "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
           eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
           eeprom->len, eeprom->len);
 
@@ -1199,7 +1202,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
                return -EAGAIN;
 
        DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
-          DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
+          "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
           eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
           eeprom->len, eeprom->len);
 
@@ -1328,7 +1331,7 @@ static int bnx2x_set_ringparam(struct net_device *dev,
        struct bnx2x *bp = netdev_priv(dev);
 
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-               printk(KERN_ERR "Handling parity error recovery. Try again later\n");
+               pr_err("Handling parity error recovery. Try again later\n");
                return -EAGAIN;
        }
 
@@ -1359,7 +1362,7 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
                            BNX2X_FLOW_CTRL_TX);
 
        DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
-          DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
+          "  autoneg %d  rx_pause %d  tx_pause %d\n",
           epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
 }
 
@@ -1372,7 +1375,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
                return 0;
 
        DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
-          DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
+          "  autoneg %d  rx_pause %d  tx_pause %d\n",
           epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
 
        bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO;
@@ -1970,7 +1973,7 @@ static void bnx2x_self_test(struct net_device *dev,
        struct bnx2x *bp = netdev_priv(dev);
        u8 is_serdes;
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-               printk(KERN_ERR "Handling parity error recovery. Try again later\n");
+               pr_err("Handling parity error recovery. Try again later\n");
                etest->flags |= ETH_TEST_FL_FAILED;
                return;
        }
similarity index 99%
rename from drivers/net/bnx2x/bnx2x_link.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index d45b1555a6022a39d10270ed53393755b382af3a..e3de6fedf218e52d3607982f0b32c1ce02da33cc 100644 (file)
@@ -694,8 +694,8 @@ static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
        struct bnx2x *bp = params->bp;
 
        if (!CHIP_IS_E3B0(bp)) {
-               DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_disabled the chip isn't E3B0"
-                                  "\n");
+               DP(NETIF_MSG_LINK,
+                  "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
                return -EINVAL;
        }
 
@@ -854,8 +854,8 @@ static int bnx2x_ets_e3b0_get_total_bw(
                if (bnx2x_cos_state_bw == ets_params->cos[cos_idx].state) {
 
                        if (0 == ets_params->cos[cos_idx].params.bw_params.bw) {
-                               DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
-                                                  "was set to 0\n");
+                               DP(NETIF_MSG_LINK,
+                                  "bnx2x_ets_E3B0_config BW was set to 0\n");
                        return -EINVAL;
                }
                *total_bw +=
@@ -866,12 +866,12 @@ static int bnx2x_ets_e3b0_get_total_bw(
        /*Check taotl BW is valid */
        if ((100 != *total_bw) || (0 == *total_bw)) {
                if (0 == *total_bw) {
-                       DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW"
-                                          "shouldn't be 0\n");
+                       DP(NETIF_MSG_LINK,
+                          "bnx2x_ets_E3B0_config toatl BW shouldn't be 0\n");
                        return -EINVAL;
                }
-               DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW should be"
-                                  "100\n");
+               DP(NETIF_MSG_LINK,
+                  "bnx2x_ets_E3B0_config toatl BW should be 100\n");
                /**
                *   We can handle a case whre the BW isn't 100 this can happen
                *   if the TC are joined.
@@ -908,13 +908,13 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
 
        if (DCBX_INVALID_COS != sp_pri_to_cos[pri]) {
                DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
-                                  "parameter There can't be two COS's with"
+                                  "parameter There can't be two COS's with "
                                   "the same strict pri\n");
                return -EINVAL;
        }
 
        if (pri > max_num_of_cos) {
-               DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid"
+               DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
                               "parameter Illegal strict priority\n");
            return -EINVAL;
        }
@@ -1090,8 +1090,8 @@ int bnx2x_ets_e3b0_config(const struct link_params *params,
        u8 cos_entry = 0;
 
        if (!CHIP_IS_E3B0(bp)) {
-               DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_disabled the chip isn't E3B0"
-                                  "\n");
+               DP(NETIF_MSG_LINK,
+                  "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
                return -EINVAL;
        }
 
@@ -1108,8 +1108,8 @@ int bnx2x_ets_e3b0_config(const struct link_params *params,
        bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
                                                   &total_bw);
        if (0 != bnx2x_status) {
-               DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config get_total_bw failed "
-                                  "\n");
+               DP(NETIF_MSG_LINK,
+                  "bnx2x_ets_E3B0_config get_total_bw failed\n");
                return -EINVAL;
        }
 
@@ -1144,13 +1144,13 @@ int bnx2x_ets_e3b0_config(const struct link_params *params,
                                cos_entry);
 
                } else {
-                       DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_config cos state not"
-                                          " valid\n");
+                       DP(NETIF_MSG_LINK,
+                          "bnx2x_ets_e3b0_config cos state not valid\n");
                        return -EINVAL;
                }
                if (0 != bnx2x_status) {
-                       DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_config set cos bw "
-                                          "failed\n");
+                       DP(NETIF_MSG_LINK,
+                          "bnx2x_ets_e3b0_config set cos bw failed\n");
                        return bnx2x_status;
                }
        }
@@ -1160,8 +1160,8 @@ int bnx2x_ets_e3b0_config(const struct link_params *params,
                                                         sp_pri_to_cos);
 
        if (0 != bnx2x_status) {
-               DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config set_pri_cli_reg "
-                                  "failed\n");
+               DP(NETIF_MSG_LINK,
+                  "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
                return bnx2x_status;
        }
 
@@ -1618,8 +1618,8 @@ static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
 
        if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) &
             MISC_REGISTERS_RESET_REG_2_XMAC)) {
-               DP(NETIF_MSG_LINK, "XMAC already out of reset"
-                                  " in 4-port mode\n");
+               DP(NETIF_MSG_LINK,
+                  "XMAC already out of reset in 4-port mode\n");
                return;
        }
 
@@ -1642,13 +1642,13 @@ static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
                /*  Set the number of ports on the system side to 1 */
                REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
                if (max_speed == SPEED_10000) {
-                       DP(NETIF_MSG_LINK, "Init XMAC to 10G x 1"
-                                          " port per path\n");
+                       DP(NETIF_MSG_LINK,
+                          "Init XMAC to 10G x 1 port per path\n");
                        /* Set the number of ports on the Warp Core to 10G */
                        REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
                } else {
-                       DP(NETIF_MSG_LINK, "Init XMAC to 20G x 2 ports"
-                                          " per path\n");
+                       DP(NETIF_MSG_LINK,
+                          "Init XMAC to 20G x 2 ports per path\n");
                        /* Set the number of ports on the Warp Core to 20G */
                        REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
                }
@@ -3959,8 +3959,8 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
                        val16 |= 0x0040;
                        break;
                default:
-                       DP(NETIF_MSG_LINK, "Speed not supported: 0x%x"
-                                          "\n", phy->req_line_speed);
+                       DP(NETIF_MSG_LINK,
+                          "Speed not supported: 0x%x\n", phy->req_line_speed);
                        return;
                }
 
@@ -4092,9 +4092,9 @@ static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
                 */
                if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
                    (cfg_pin > PIN_CFG_GPIO3_P1)) {
-                       DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for "
-                                          "module detect indication\n",
-                                      cfg_pin);
+                       DP(NETIF_MSG_LINK,
+                          "ERROR: Invalid cfg pin %x for module detect indication\n",
+                          cfg_pin);
                        return -EINVAL;
                }
 
@@ -4222,8 +4222,9 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
                        break;
 
                default:
-                       DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface "
-                                          "0x%x\n", serdes_net_if);
+                       DP(NETIF_MSG_LINK,
+                          "Unsupported Serdes Net Interface 0x%x\n",
+                          serdes_net_if);
                        return;
                }
        }
@@ -6127,8 +6128,8 @@ static int bnx2x_link_initialize(struct link_params *params,
                        if (phy_index == EXT_PHY2 &&
                            (bnx2x_phy_selection(params) ==
                             PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
-                               DP(NETIF_MSG_LINK, "Not initializing"
-                                               " second phy\n");
+                               DP(NETIF_MSG_LINK,
+                                  "Not initializing second phy\n");
                                continue;
                        }
                        params->phy[phy_index].config_init(
@@ -6447,8 +6448,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
                 */
                if (active_external_phy == EXT_PHY1) {
                        if (params->phy[EXT_PHY2].phy_specific_func) {
-                               DP(NETIF_MSG_LINK, "Disabling TX on"
-                                                  " EXT_PHY2\n");
+                               DP(NETIF_MSG_LINK,
+                                  "Disabling TX on EXT_PHY2\n");
                                params->phy[EXT_PHY2].phy_specific_func(
                                        &params->phy[EXT_PHY2],
                                        params, DISABLE_TX);
@@ -7341,8 +7342,8 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
        u16 val = 0;
        u16 i;
        if (byte_cnt > 16) {
-               DP(NETIF_MSG_LINK, "Reading from eeprom is"
-                           " is limited to 0xf\n");
+               DP(NETIF_MSG_LINK,
+                  "Reading from eeprom is limited to 0xf\n");
                return -EINVAL;
        }
        /* Set the read command byte count */
@@ -7413,8 +7414,8 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
                                        " addr %d, cnt %d\n",
                                        addr, byte_cnt);*/
        if (byte_cnt > 16) {
-               DP(NETIF_MSG_LINK, "Reading from eeprom is"
-                           " is limited to 16 bytes\n");
+               DP(NETIF_MSG_LINK,
+                  "Reading from eeprom is limited to 16 bytes\n");
                return -EINVAL;
        }
 
@@ -7443,8 +7444,8 @@ static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
        u16 val, i;
 
        if (byte_cnt > 16) {
-               DP(NETIF_MSG_LINK, "Reading from eeprom is"
-                           " is limited to 0xf\n");
+               DP(NETIF_MSG_LINK,
+                  "Reading from eeprom is limited to 0xf\n");
                return -EINVAL;
        }
 
@@ -7591,13 +7592,14 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
                        check_limiting_mode = 1;
                } else if (copper_module_type &
                        SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
-                               DP(NETIF_MSG_LINK, "Passive Copper"
-                                           " cable detected\n");
+                               DP(NETIF_MSG_LINK,
+                                  "Passive Copper cable detected\n");
                                *edc_mode =
                                      EDC_MODE_PASSIVE_DAC;
                } else {
-                       DP(NETIF_MSG_LINK, "Unknown copper-cable-"
-                                    "type 0x%x !!!\n", copper_module_type);
+                       DP(NETIF_MSG_LINK,
+                          "Unknown copper-cable-type 0x%x !!!\n",
+                          copper_module_type);
                        return -EINVAL;
                }
                break;
@@ -7635,8 +7637,8 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
                                                 SFP_EEPROM_OPTIONS_ADDR,
                                                 SFP_EEPROM_OPTIONS_SIZE,
                                                 options) != 0) {
-                       DP(NETIF_MSG_LINK, "Failed to read Option"
-                               " field from module EEPROM\n");
+                       DP(NETIF_MSG_LINK,
+                          "Failed to read Option field from module EEPROM\n");
                        return -EINVAL;
                }
                if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
@@ -7677,15 +7679,15 @@ static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
                   FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
                /* Use first phy request only in case of non-dual media*/
                if (DUAL_MEDIA(params)) {
-                       DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
-                          "verification\n");
+                       DP(NETIF_MSG_LINK,
+                          "FW does not support OPT MDL verification\n");
                        return -EINVAL;
                }
                cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
        } else {
                /* No support in OPT MDL detection */
-               DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
-                         "verification\n");
+               DP(NETIF_MSG_LINK,
+                  "FW does not support OPT MDL verification\n");
                return -EINVAL;
        }
 
@@ -7736,8 +7738,9 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
        for (timeout = 0; timeout < 60; timeout++) {
                if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
                    == 0) {
-                       DP(NETIF_MSG_LINK, "SFP+ module initialization "
-                                    "took %d ms\n", timeout * 5);
+                       DP(NETIF_MSG_LINK,
+                          "SFP+ module initialization took %d ms\n",
+                          timeout * 5);
                        return 0;
                }
                msleep(5);
@@ -8506,8 +8509,8 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
        /* Set TX PreEmphasis if needed */
        if ((params->feature_config_flags &
             FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
-               DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
-                        "TX_CTRL2 0x%x\n",
+               DP(NETIF_MSG_LINK,
+                  "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
                         phy->tx_preemphasis[0],
                         phy->tx_preemphasis[1]);
                bnx2x_cl45_write(bp, phy,
@@ -8788,8 +8791,8 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
        if (mod_abs & (1<<8)) {
 
                /* Module is absent */
-               DP(NETIF_MSG_LINK, "MOD_ABS indication "
-                           "show module is absent\n");
+               DP(NETIF_MSG_LINK,
+                  "MOD_ABS indication show module is absent\n");
                phy->media_type = ETH_PHY_NOT_PRESENT;
                /*
                 * 1. Set mod_abs to detect next module
@@ -8816,8 +8819,8 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
 
        } else {
                /* Module is present */
-               DP(NETIF_MSG_LINK, "MOD_ABS indication "
-                           "show module is present\n");
+               DP(NETIF_MSG_LINK,
+                  "MOD_ABS indication show module is present\n");
                /*
                 * First disable transmitter, and if the module is ok, the
                 * module_detection will enable it
@@ -8908,8 +8911,9 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
                if ((val1 & (1<<8)) == 0) {
                        if (!CHIP_IS_E1x(bp))
                                oc_port = BP_PATH(bp) + (params->port << 1);
-                       DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
-                                      " on port %d\n", oc_port);
+                       DP(NETIF_MSG_LINK,
+                          "8727 Power fault has been detected on port %d\n",
+                          oc_port);
                        netdev_err(bp->dev, "Error:  Power fault on Port %d has"
                                            " been detected and the power to "
                                            "that SFP+ module has been removed"
@@ -9690,8 +9694,8 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
                                MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
                                &legacy_status);
 
-               DP(NETIF_MSG_LINK, "Legacy speed status"
-                            " = 0x%x\n", legacy_status);
+               DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n",
+                  legacy_status);
                link_up = ((legacy_status & (1<<11)) == (1<<11));
                if (link_up) {
                        legacy_speed = (legacy_status & (3<<9));
@@ -9709,9 +9713,10 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
                        else
                                vars->duplex = DUPLEX_HALF;
 
-                       DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
-                                  " is_duplex_full= %d\n", vars->line_speed,
-                                  (vars->duplex == DUPLEX_FULL));
+                       DP(NETIF_MSG_LINK,
+                          "Link is up in %dMbps, is_duplex_full= %d\n",
+                          vars->line_speed,
+                          (vars->duplex == DUPLEX_FULL));
                        /* Check legacy speed AN resolution */
                        bnx2x_cl45_read(bp, phy,
                                        MDIO_AN_DEVAD,
@@ -10286,9 +10291,10 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
                } else /* Should not happen */
                        vars->line_speed = 0;
 
-               DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
-                          " is_duplex_full= %d\n", vars->line_speed,
-                          (vars->duplex == DUPLEX_FULL));
+               DP(NETIF_MSG_LINK,
+                  "Link is up in %dMbps, is_duplex_full= %d\n",
+                  vars->line_speed,
+                  (vars->duplex == DUPLEX_FULL));
 
                /* Check legacy speed AN resolution */
                bnx2x_cl22_read(bp, phy,
@@ -11336,8 +11342,9 @@ static void bnx2x_phy_def_cfg(struct link_params *params,
                                                      dev_info.
                        port_hw_config[params->port].speed_capability_mask));
        }
-       DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
-                      " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
+       DP(NETIF_MSG_LINK,
+          "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
+          phy_index, link_config, phy->speed_cap_mask);
 
        phy->req_duplex = DUPLEX_FULL;
        switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
similarity index 99%
rename from drivers/net/bnx2x/bnx2x_main.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index f74582a22c68a803985437989e6c0dd53652201a..720478993950ebf6e57932439f05ee1c6f7403f0 100644 (file)
@@ -15,6 +15,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -37,6 +39,7 @@
 #include <linux/time.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -350,17 +353,15 @@ static void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae,
        default:
                if (src_type == DMAE_CMD_SRC_PCI)
                        DP(msglvl, "DMAE: opcode 0x%08x\n"
-                          DP_LEVEL "src_addr [%x:%08x]  len [%d * 4]  "
-                                   "dst_addr [none]\n"
-                          DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
+                          "src_addr [%x:%08x]  len [%d * 4]  dst_addr [none]\n"
+                          "comp_addr [%x:%08x]  comp_val 0x%08x\n",
                           dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
                           dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo,
                           dmae->comp_val);
                else
                        DP(msglvl, "DMAE: opcode 0x%08x\n"
-                          DP_LEVEL "src_addr [%08x]  len [%d * 4]  "
-                                   "dst_addr [none]\n"
-                          DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
+                          "src_addr [%08x]  len [%d * 4]  dst_addr [none]\n"
+                          "comp_addr [%x:%08x]  comp_val 0x%08x\n",
                           dmae->opcode, dmae->src_addr_lo >> 2,
                           dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo,
                           dmae->comp_val);
@@ -789,18 +790,15 @@ void bnx2x_panic_dump(struct bnx2x *bp)
        BNX2X_ERR("     def (");
        for (i = 0; i < HC_SP_SB_MAX_INDICES; i++)
                pr_cont("0x%x%s",
-                      bp->def_status_blk->sp_sb.index_values[i],
-                      (i == HC_SP_SB_MAX_INDICES - 1) ? ")  " : " ");
+                       bp->def_status_blk->sp_sb.index_values[i],
+                       (i == HC_SP_SB_MAX_INDICES - 1) ? ")  " : " ");
 
        for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++)
                *((u32 *)&sp_sb_data + i) = REG_RD(bp, BAR_CSTRORM_INTMEM +
                        CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) +
                        i*sizeof(u32));
 
-       pr_cont("igu_sb_id(0x%x)  igu_seg_id(0x%x) "
-                        "pf_id(0x%x)  vnic_id(0x%x)  "
-                        "vf_id(0x%x)  vf_valid (0x%x) "
-                        "state(0x%x)\n",
+       pr_cont("igu_sb_id(0x%x)  igu_seg_id(0x%x) pf_id(0x%x)  vnic_id(0x%x)  vf_id(0x%x)  vf_valid (0x%x) state(0x%x)\n",
               sp_sb_data.igu_sb_id,
               sp_sb_data.igu_seg_id,
               sp_sb_data.p_func.pf_id,
@@ -3721,9 +3719,7 @@ static inline void bnx2x_clear_load_cnt(struct bnx2x *bp)
 
 static inline void _print_next_block(int idx, const char *blk)
 {
-       if (idx)
-               pr_cont(", ");
-       pr_cont("%s", blk);
+       pr_cont("%s%s", idx ? ", " : "", blk);
 }
 
 static inline int bnx2x_check_blocks_with_parity0(u32 sig, int par_num,
@@ -4388,7 +4384,7 @@ static inline void bnx2x_handle_rx_mode_eqe(struct bnx2x *bp)
 static inline struct bnx2x_queue_sp_obj *bnx2x_cid_to_q_obj(
        struct bnx2x *bp, u32 cid)
 {
-       DP(BNX2X_MSG_SP, "retrieving fp from cid %d", cid);
+       DP(BNX2X_MSG_SP, "retrieving fp from cid %d\n", cid);
 #ifdef BCM_CNIC
        if (cid == BNX2X_FCOE_ETH_CID)
                return &bnx2x_fcoe(bp, q_obj);
@@ -7184,7 +7180,7 @@ static inline void bnx2x_pf_q_prep_init(struct bnx2x *bp,
        /* set maximum number of COSs supported by this queue */
        init_params->max_cos = fp->max_cos;
 
-       DP(BNX2X_MSG_SP, "fp: %d setting queue params max cos to: %d",
+       DP(BNX2X_MSG_SP, "fp: %d setting queue params max cos to: %d\n",
            fp->index, init_params->max_cos);
 
        /* set the context pointers queue object */
@@ -7217,7 +7213,7 @@ int bnx2x_setup_tx_only(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 
        DP(BNX2X_MSG_SP, "preparing to send tx-only ramrod for connection:"
                         "cos %d, primary cid %d, cid %d, "
-                        "client id %d, sp-client id %d, flags %lx",
+                        "client id %d, sp-client id %d, flags %lx\n",
           tx_index, q_params->q_obj->cids[FIRST_TX_COS_INDEX],
           q_params->q_obj->cids[tx_index], q_params->q_obj->cl_id,
           tx_only_params->gen_params.spcl_id, tx_only_params->flags);
@@ -7249,7 +7245,7 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
        int rc;
        u8 tx_index;
 
-       DP(BNX2X_MSG_SP, "setting up queue %d", fp->index);
+       DP(BNX2X_MSG_SP, "setting up queue %d\n", fp->index);
 
        /* reset IGU state skip FCoE L2 queue */
        if (!IS_FCOE_FP(fp))
@@ -7273,7 +7269,7 @@ int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
                return rc;
        }
 
-       DP(BNX2X_MSG_SP, "init complete");
+       DP(BNX2X_MSG_SP, "init complete\n");
 
 
        /* Now move the Queue to the SETUP state... */
@@ -7327,7 +7323,7 @@ static int bnx2x_stop_queue(struct bnx2x *bp, int index)
        struct bnx2x_queue_state_params q_params = {0};
        int rc, tx_index;
 
-       DP(BNX2X_MSG_SP, "stopping queue %d cid %d", index, fp->cid);
+       DP(BNX2X_MSG_SP, "stopping queue %d cid %d\n", index, fp->cid);
 
        q_params.q_obj = &fp->q_obj;
        /* We want to wait for completion in this context */
@@ -7342,7 +7338,7 @@ static int bnx2x_stop_queue(struct bnx2x *bp, int index)
                /* ascertain this is a normal queue*/
                txdata = &fp->txdata[tx_index];
 
-               DP(BNX2X_MSG_SP, "stopping tx-only queue %d",
+               DP(BNX2X_MSG_SP, "stopping tx-only queue %d\n",
                                                        txdata->txq_index);
 
                /* send halt terminate on tx-only connection */
@@ -9323,9 +9319,8 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
                                val = MF_CFG_RD(bp, func_ext_config[func].
                                                    iscsi_mac_addr_lower);
                                bnx2x_set_mac_buf(iscsi_mac, val, val2);
-                               BNX2X_DEV_INFO("Read iSCSI MAC: "
-                                              BNX2X_MAC_FMT"\n",
-                                              BNX2X_MAC_PRN_LIST(iscsi_mac));
+                               BNX2X_DEV_INFO("Read iSCSI MAC: %pM\n",
+                                              iscsi_mac);
                        } else
                                bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
 
@@ -9335,9 +9330,8 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
                                val = MF_CFG_RD(bp, func_ext_config[func].
                                                    fcoe_mac_addr_lower);
                                bnx2x_set_mac_buf(fip_mac, val, val2);
-                               BNX2X_DEV_INFO("Read FCoE L2 MAC to "
-                                              BNX2X_MAC_FMT"\n",
-                                              BNX2X_MAC_PRN_LIST(fip_mac));
+                               BNX2X_DEV_INFO("Read FCoE L2 MAC to %pM\n",
+                                              fip_mac);
 
                        } else
                                bp->flags |= NO_FCOE_FLAG;
@@ -9392,9 +9386,9 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
        if (!is_valid_ether_addr(bp->dev->dev_addr))
                dev_err(&bp->pdev->dev,
                        "bad Ethernet MAC address configuration: "
-                       BNX2X_MAC_FMT", change it manually before bringing up "
+                       "%pM, change it manually before bringing up "
                        "the appropriate network interface\n",
-                       BNX2X_MAC_PRN_LIST(bp->dev->dev_addr));
+                       bp->dev->dev_addr);
 }
 
 static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
@@ -10288,6 +10282,8 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
        dev->netdev_ops = &bnx2x_netdev_ops;
        bnx2x_set_ethtool_ops(dev);
 
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
                NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
                NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX;
@@ -10721,7 +10717,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
                return rc;
        }
 
-       DP(NETIF_MSG_DRV, "max_non_def_sbs %d", max_non_def_sbs);
+       DP(NETIF_MSG_DRV, "max_non_def_sbs %d\n", max_non_def_sbs);
 
        rc = bnx2x_init_bp(bp);
        if (rc)
@@ -10776,15 +10772,14 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
 
        bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
 
-       netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx,"
-              " IRQ %d, ", board_info[ent->driver_data].name,
-              (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
-              pcie_width,
-              ((!CHIP_IS_E2(bp) && pcie_speed == 2) ||
-                (CHIP_IS_E2(bp) && pcie_speed == 1)) ?
-                                               "5GHz (Gen2)" : "2.5GHz",
-              dev->base_addr, bp->pdev->irq);
-       pr_cont("node addr %pM\n", dev->dev_addr);
+       netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n",
+                   board_info[ent->driver_data].name,
+                   (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
+                   pcie_width,
+                   ((!CHIP_IS_E2(bp) && pcie_speed == 2) ||
+                    (CHIP_IS_E2(bp) && pcie_speed == 1)) ?
+                   "5GHz (Gen2)" : "2.5GHz",
+                   dev->base_addr, bp->pdev->irq, dev->dev_addr);
 
        return 0;
 
similarity index 98%
rename from drivers/net/bnx2x/bnx2x_sp.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index df52f110c6c524d1186a8c5d57eaa39f8870e647..0440425c83d6820e3ba2ad12ec57430ec9896492 100644 (file)
@@ -16,6 +16,9 @@
  * Written by: Vladislav Zolotarov
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/crc32.h>
 #include <linux/netdevice.h>
@@ -707,9 +710,8 @@ static void bnx2x_set_one_mac_e2(struct bnx2x *bp,
        bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_MAC,
                                      &rule_entry->mac.header);
 
-       DP(BNX2X_MSG_SP, "About to %s MAC "BNX2X_MAC_FMT" for "
-                        "Queue %d\n", (add ? "add" : "delete"),
-                        BNX2X_MAC_PRN_LIST(mac), raw->cl_id);
+       DP(BNX2X_MSG_SP, "About to %s MAC %pM for Queue %d\n",
+                        add ? "add" : "delete", mac, raw->cl_id);
 
        /* Set a MAC itself */
        bnx2x_set_fw_mac_addr(&rule_entry->mac.mac_msb,
@@ -801,9 +803,9 @@ static inline void bnx2x_vlan_mac_set_rdata_e1x(struct bnx2x *bp,
        bnx2x_vlan_mac_set_cfg_entry_e1x(bp, o, add, opcode, mac, vlan_id,
                                         cfg_entry);
 
-       DP(BNX2X_MSG_SP, "%s MAC "BNX2X_MAC_FMT" CLID %d CAM offset %d\n",
-                        (add ? "setting" : "clearing"),
-                        BNX2X_MAC_PRN_LIST(mac), raw->cl_id, cam_offset);
+       DP(BNX2X_MSG_SP, "%s MAC %pM CLID %d CAM offset %d\n",
+                        add ? "setting" : "clearing",
+                        mac, raw->cl_id, cam_offset);
 }
 
 /**
@@ -2579,9 +2581,8 @@ static inline void bnx2x_mcast_hdl_pending_add_e2(struct bnx2x *bp,
 
                cnt++;
 
-               DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT
-                                " mcast MAC\n",
-                                BNX2X_MAC_PRN_LIST(pmac_pos->mac));
+               DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n",
+                                pmac_pos->mac);
 
                list_del(&pmac_pos->link);
 
@@ -2702,9 +2703,8 @@ static inline void bnx2x_mcast_hdl_add(struct bnx2x *bp,
 
                cnt++;
 
-               DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT
-                                " mcast MAC\n",
-                                BNX2X_MAC_PRN_LIST(mlist_pos->mac));
+               DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n",
+                                mlist_pos->mac);
        }
 
        *line_idx = cnt;
@@ -2998,9 +2998,8 @@ static inline void bnx2x_mcast_hdl_add_e1h(struct bnx2x *bp,
                bit = bnx2x_mcast_bin_from_mac(mlist_pos->mac);
                BNX2X_57711_SET_MC_FILTER(mc_filter, bit);
 
-               DP(BNX2X_MSG_SP, "About to configure "
-                                BNX2X_MAC_FMT" mcast MAC, bin %d\n",
-                                BNX2X_MAC_PRN_LIST(mlist_pos->mac), bit);
+               DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC, bin %d\n",
+                                mlist_pos->mac, bit);
 
                /* bookkeeping... */
                BIT_VEC64_SET_BIT(o->registry.aprox_match.vec,
@@ -3049,8 +3048,8 @@ static int bnx2x_mcast_setup_e1h(struct bnx2x *bp,
                        break;
 
                case BNX2X_MCAST_CMD_DEL:
-                       DP(BNX2X_MSG_SP, "Invalidating multicast "
-                                        "MACs configuration\n");
+                       DP(BNX2X_MSG_SP,
+                          "Invalidating multicast MACs configuration\n");
 
                        /* clear the registry */
                        memset(o->registry.aprox_match.vec, 0,
@@ -3233,9 +3232,8 @@ static inline int bnx2x_mcast_handle_restore_cmd_e1(
 
                i++;
 
-                 DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT
-                                  " mcast MAC\n",
-                                  BNX2X_MAC_PRN_LIST(cfg_data.mac));
+                 DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n",
+                                  cfg_data.mac);
        }
 
        *rdata_idx = i;
@@ -3270,9 +3268,8 @@ static inline int bnx2x_mcast_handle_pending_cmds_e1(
 
                        cnt++;
 
-                       DP(BNX2X_MSG_SP, "About to configure "BNX2X_MAC_FMT
-                                        " mcast MAC\n",
-                                        BNX2X_MAC_PRN_LIST(pmac_pos->mac));
+                       DP(BNX2X_MSG_SP, "About to configure %pM mcast MAC\n",
+                                        pmac_pos->mac);
                }
                break;
 
@@ -3357,9 +3354,8 @@ static inline int bnx2x_mcast_refresh_registry_e1(struct bnx2x *bp,
                                &data->config_table[i].middle_mac_addr,
                                &data->config_table[i].lsb_mac_addr,
                                elem->mac);
-                       DP(BNX2X_MSG_SP, "Adding registry entry for ["
-                                        BNX2X_MAC_FMT"]\n",
-                                  BNX2X_MAC_PRN_LIST(elem->mac));
+                       DP(BNX2X_MSG_SP, "Adding registry entry for [%pM]\n",
+                                        elem->mac);
                        list_add_tail(&elem->link,
                                      &o->registry.exact_match.macs);
                }
@@ -4246,7 +4242,7 @@ static int bnx2x_queue_comp_cmd(struct bnx2x *bp,
                         o->cids[BNX2X_PRIMARY_CID_INDEX], o->next_state);
 
        if (o->next_tx_only)  /* print num tx-only if any exist */
-               DP(BNX2X_MSG_SP, "primary cid %d: num tx-only cons %d",
+               DP(BNX2X_MSG_SP, "primary cid %d: num tx-only cons %d\n",
                           o->cids[BNX2X_PRIMARY_CID_INDEX], o->next_tx_only);
 
        o->state = o->next_state;
@@ -4308,7 +4304,7 @@ static void bnx2x_q_fill_init_general_data(struct bnx2x *bp,
                test_bit(BNX2X_Q_FLG_FCOE, flags) ?
                LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW;
 
-       DP(BNX2X_MSG_SP, "flags: active %d, cos %d, stats en %d",
+       DP(BNX2X_MSG_SP, "flags: active %d, cos %d, stats en %d\n",
           gen_data->activate_flg, gen_data->cos, gen_data->statistics_en_flg);
 }
 
@@ -4461,7 +4457,7 @@ static void bnx2x_q_fill_setup_tx_only(struct bnx2x *bp,
                                  &data->tx,
                                  &cmd_params->params.tx_only.flags);
 
-       DP(BNX2X_MSG_SP, "cid %d, tx bd page lo %x hi %x",cmd_params->q_obj->cids[0],
+       DP(BNX2X_MSG_SP, "cid %d, tx bd page lo %x hi %x\n",cmd_params->q_obj->cids[0],
           data->tx.tx_bd_page_base.lo, data->tx.tx_bd_page_base.hi);
 }
 
@@ -4508,9 +4504,9 @@ static inline int bnx2x_q_init(struct bnx2x *bp,
 
        /* Set CDU context validation values */
        for (cos = 0; cos < o->max_cos; cos++) {
-               DP(BNX2X_MSG_SP, "setting context validation. cid %d, cos %d",
+               DP(BNX2X_MSG_SP, "setting context validation. cid %d, cos %d\n",
                                 o->cids[cos], cos);
-               DP(BNX2X_MSG_SP, "context pointer %p", init->cxts[cos]);
+               DP(BNX2X_MSG_SP, "context pointer %p\n", init->cxts[cos]);
                bnx2x_set_ctx_validation(bp, init->cxts[cos], o->cids[cos]);
        }
 
@@ -4599,7 +4595,7 @@ static inline int bnx2x_q_send_setup_tx_only(struct bnx2x *bp,
                return -EINVAL;
        }
 
-       DP(BNX2X_MSG_SP, "parameters received: cos: %d sp-id: %d",
+       DP(BNX2X_MSG_SP, "parameters received: cos: %d sp-id: %d\n",
                         tx_only_params->gen_params.cos,
                         tx_only_params->gen_params.spcl_id);
 
@@ -4610,7 +4606,7 @@ static inline int bnx2x_q_send_setup_tx_only(struct bnx2x *bp,
        bnx2x_q_fill_setup_tx_only(bp, params, rdata);
 
        DP(BNX2X_MSG_SP, "sending tx-only ramrod: cid %d, client-id %d,"
-                        "sp-client id %d, cos %d",
+                        "sp-client id %d, cos %d\n",
                         o->cids[cid_index],
                         rdata->general.client_id,
                         rdata->general.sp_client_id, rdata->general.cos);
@@ -5167,8 +5163,9 @@ static inline int bnx2x_func_state_change_comp(struct bnx2x *bp,
                return -EINVAL;
        }
 
-       DP(BNX2X_MSG_SP, "Completing command %d for func %d, setting state to "
-                        "%d\n", cmd, BP_FUNC(bp), o->next_state);
+       DP(BNX2X_MSG_SP,
+          "Completing command %d for func %d, setting state to %d\n",
+          cmd, BP_FUNC(bp), o->next_state);
 
        o->state = o->next_state;
        o->next_state = BNX2X_F_STATE_MAX;
similarity index 98%
rename from drivers/net/bnx2x/bnx2x_stats.c
rename to drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 771f6803b23856f7ffe928a4d23545d6ac4be896..628f7b99614f962ed9e8e3ef8f67f0794691c575 100644 (file)
@@ -14,6 +14,9 @@
  * Statistics and Link management by Yitchak Gertner
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "bnx2x_stats.h"
 #include "bnx2x_cmn.h"
 
@@ -1194,14 +1197,13 @@ static void bnx2x_stats_update(struct bnx2x *bp)
                        struct bnx2x_fastpath *fp = &bp->fp[i];
                        struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
 
-                       printk(KERN_DEBUG "%s: rx usage(%4u)  *rx_cons_sb(%u)"
-                                         "  rx pkt(%lu)  rx calls(%lu %lu)\n",
-                              fp->name, (le16_to_cpu(*fp->rx_cons_sb) -
-                              fp->rx_comp_cons),
-                              le16_to_cpu(*fp->rx_cons_sb),
-                              bnx2x_hilo(&qstats->
-                                         total_unicast_packets_received_hi),
-                              fp->rx_calls, fp->rx_pkt);
+                       pr_debug("%s: rx usage(%4u)  *rx_cons_sb(%u)  rx pkt(%lu)  rx calls(%lu %lu)\n",
+                                fp->name, (le16_to_cpu(*fp->rx_cons_sb) -
+                                           fp->rx_comp_cons),
+                                le16_to_cpu(*fp->rx_cons_sb),
+                                bnx2x_hilo(&qstats->
+                                           total_unicast_packets_received_hi),
+                                fp->rx_calls, fp->rx_pkt);
                }
 
                for_each_eth_queue(bp, i) {
@@ -1210,27 +1212,25 @@ static void bnx2x_stats_update(struct bnx2x *bp)
                        struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
                        struct netdev_queue *txq;
 
-                       printk(KERN_DEBUG "%s: tx pkt(%lu) (Xoff events %u)",
-                               fp->name, bnx2x_hilo(
-                               &qstats->total_unicast_packets_transmitted_hi),
-                               qstats->driver_xoff);
+                       pr_debug("%s: tx pkt(%lu) (Xoff events %u)",
+                                fp->name,
+                                bnx2x_hilo(
+                                        &qstats->total_unicast_packets_transmitted_hi),
+                                qstats->driver_xoff);
 
                        for_each_cos_in_tx_queue(fp, cos) {
                                txdata = &fp->txdata[cos];
                                txq = netdev_get_tx_queue(bp->dev,
                                                FP_COS_TO_TXQ(fp, cos));
 
-                               printk(KERN_DEBUG "%d: tx avail(%4u)"
-                                      "  *tx_cons_sb(%u)"
-                                      "  tx calls (%lu)"
-                                      "  %s\n",
-                                      cos,
-                                      bnx2x_tx_avail(bp, txdata),
-                                      le16_to_cpu(*txdata->tx_cons_sb),
-                                      txdata->tx_pkt,
-                                      (netif_tx_queue_stopped(txq) ?
-                                       "Xoff" : "Xon")
-                                      );
+                               pr_debug("%d: tx avail(%4u)  *tx_cons_sb(%u)  tx calls (%lu)  %s\n",
+                                        cos,
+                                        bnx2x_tx_avail(bp, txdata),
+                                        le16_to_cpu(*txdata->tx_cons_sb),
+                                        txdata->tx_pkt,
+                                        (netif_tx_queue_stopped(txq) ?
+                                         "Xoff" : "Xon")
+                                       );
                        }
                }
        }
similarity index 99%
rename from drivers/net/cnic.c
rename to drivers/net/ethernet/broadcom/cnic.c
index 94a2e541006d8ff158f218baefec24e2c94ca511..769816104a6d34e62cfdaa08864ed5b667db36fc 100644 (file)
@@ -45,8 +45,8 @@
 #include "bnx2x/bnx2x_reg.h"
 #include "bnx2x/bnx2x_fw_defs.h"
 #include "bnx2x/bnx2x_hsi.h"
-#include "../scsi/bnx2i/57xx_iscsi_constants.h"
-#include "../scsi/bnx2i/57xx_iscsi_hsi.h"
+#include "../../../scsi/bnx2i/57xx_iscsi_constants.h"
+#include "../../../scsi/bnx2i/57xx_iscsi_hsi.h"
 #include "cnic.h"
 #include "cnic_defs.h"
 
similarity index 99%
rename from drivers/net/sb1250-mac.c
rename to drivers/net/ethernet/broadcom/sb1250-mac.c
index ea65f7ec360a346259583505fb998ce8406b6b3b..0a1d7f279fc8fd83565915a2daaed7bcc3df2621 100644 (file)
@@ -2176,7 +2176,7 @@ static const struct net_device_ops sbmac_netdev_ops = {
        .ndo_open               = sbmac_open,
        .ndo_stop               = sbmac_close,
        .ndo_start_xmit         = sbmac_start_tx,
-       .ndo_set_multicast_list = sbmac_set_rx_mode,
+       .ndo_set_rx_mode        = sbmac_set_rx_mode,
        .ndo_tx_timeout         = sbmac_tx_timeout,
        .ndo_do_ioctl           = sbmac_mii_ioctl,
        .ndo_change_mtu         = sb1250_change_mtu,
similarity index 98%
rename from drivers/net/tg3.c
rename to drivers/net/ethernet/broadcom/tg3.c
index dc3fbf61910b562bdaa2686e8bb3f861a4cc499b..0f811115fe2ab674ec8f2c9d0edc70e77cd82f31 100644 (file)
@@ -89,12 +89,11 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
 
 #define DRV_MODULE_NAME                "tg3"
 #define TG3_MAJ_NUM                    3
-#define TG3_MIN_NUM                    119
+#define TG3_MIN_NUM                    120
 #define DRV_MODULE_VERSION     \
        __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE     "May 18, 2011"
+#define DRV_MODULE_RELDATE     "August 18, 2011"
 
-#define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
 #define TG3_DEF_TX_MODE                0
 #define TG3_DEF_MSG_ENABLE       \
@@ -391,12 +390,14 @@ static const struct {
 static const struct {
        const char string[ETH_GSTRING_LEN];
 } ethtool_test_keys[] = {
-       { "nvram test     (online) " },
-       { "link test      (online) " },
-       { "register test  (offline)" },
-       { "memory test    (offline)" },
-       { "loopback test  (offline)" },
-       { "interrupt test (offline)" },
+       { "nvram test        (online) " },
+       { "link test         (online) " },
+       { "register test     (offline)" },
+       { "memory test       (offline)" },
+       { "mac loopback test (offline)" },
+       { "phy loopback test (offline)" },
+       { "ext loopback test (offline)" },
+       { "interrupt test    (offline)" },
 };
 
 #define TG3_NUM_TEST   ARRAY_SIZE(ethtool_test_keys)
@@ -1680,6 +1681,36 @@ static void tg3_phy_fini(struct tg3 *tp)
        }
 }
 
+static int tg3_phy_set_extloopbk(struct tg3 *tp)
+{
+       int err;
+       u32 val;
+
+       if (tp->phy_flags & TG3_PHYFLG_IS_FET)
+               return 0;
+
+       if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
+               /* Cannot do read-modify-write on 5401 */
+               err = tg3_phy_auxctl_write(tp,
+                                          MII_TG3_AUXCTL_SHDWSEL_AUXCTL,
+                                          MII_TG3_AUXCTL_ACTL_EXTLOOPBK |
+                                          0x4c20);
+               goto done;
+       }
+
+       err = tg3_phy_auxctl_read(tp,
+                                 MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val);
+       if (err)
+               return err;
+
+       val |= MII_TG3_AUXCTL_ACTL_EXTLOOPBK;
+       err = tg3_phy_auxctl_write(tp,
+                                  MII_TG3_AUXCTL_SHDWSEL_AUXCTL, val);
+
+done:
+       return err;
+}
+
 static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
 {
        u32 phytest;
@@ -6343,6 +6374,127 @@ dma_error:
        return NETDEV_TX_OK;
 }
 
+static void tg3_mac_loopback(struct tg3 *tp, bool enable)
+{
+       if (enable) {
+               tp->mac_mode &= ~(MAC_MODE_HALF_DUPLEX |
+                                 MAC_MODE_PORT_MODE_MASK);
+
+               tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
+
+               if (!tg3_flag(tp, 5705_PLUS))
+                       tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+
+               if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+                       tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+               else
+                       tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+       } else {
+               tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
+
+               if (tg3_flag(tp, 5705_PLUS) ||
+                   (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+                       tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
+       }
+
+       tw32(MAC_MODE, tp->mac_mode);
+       udelay(40);
+}
+
+static int tg3_phy_lpbk_set(struct tg3 *tp, u32 speed, bool extlpbk)
+{
+       u32 val, bmcr, mac_mode, ptest = 0;
+
+       tg3_phy_toggle_apd(tp, false);
+       tg3_phy_toggle_automdix(tp, 0);
+
+       if (extlpbk && tg3_phy_set_extloopbk(tp))
+               return -EIO;
+
+       bmcr = BMCR_FULLDPLX;
+       switch (speed) {
+       case SPEED_10:
+               break;
+       case SPEED_100:
+               bmcr |= BMCR_SPEED100;
+               break;
+       case SPEED_1000:
+       default:
+               if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
+                       speed = SPEED_100;
+                       bmcr |= BMCR_SPEED100;
+               } else {
+                       speed = SPEED_1000;
+                       bmcr |= BMCR_SPEED1000;
+               }
+       }
+
+       if (extlpbk) {
+               if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
+                       tg3_readphy(tp, MII_CTRL1000, &val);
+                       val |= CTL1000_AS_MASTER |
+                              CTL1000_ENABLE_MASTER;
+                       tg3_writephy(tp, MII_CTRL1000, val);
+               } else {
+                       ptest = MII_TG3_FET_PTEST_TRIM_SEL |
+                               MII_TG3_FET_PTEST_TRIM_2;
+                       tg3_writephy(tp, MII_TG3_FET_PTEST, ptest);
+               }
+       } else
+               bmcr |= BMCR_LOOPBACK;
+
+       tg3_writephy(tp, MII_BMCR, bmcr);
+
+       /* The write needs to be flushed for the FETs */
+       if (tp->phy_flags & TG3_PHYFLG_IS_FET)
+               tg3_readphy(tp, MII_BMCR, &bmcr);
+
+       udelay(40);
+
+       if ((tp->phy_flags & TG3_PHYFLG_IS_FET) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+               tg3_writephy(tp, MII_TG3_FET_PTEST, ptest |
+                            MII_TG3_FET_PTEST_FRC_TX_LINK |
+                            MII_TG3_FET_PTEST_FRC_TX_LOCK);
+
+               /* The write needs to be flushed for the AC131 */
+               tg3_readphy(tp, MII_TG3_FET_PTEST, &val);
+       }
+
+       /* Reset to prevent losing 1st rx packet intermittently */
+       if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
+           tg3_flag(tp, 5780_CLASS)) {
+               tw32_f(MAC_RX_MODE, RX_MODE_RESET);
+               udelay(10);
+               tw32_f(MAC_RX_MODE, tp->rx_mode);
+       }
+
+       mac_mode = tp->mac_mode &
+                  ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+       if (speed == SPEED_1000)
+               mac_mode |= MAC_MODE_PORT_MODE_GMII;
+       else
+               mac_mode |= MAC_MODE_PORT_MODE_MII;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+               u32 masked_phy_id = tp->phy_id & TG3_PHY_ID_MASK;
+
+               if (masked_phy_id == TG3_PHY_ID_BCM5401)
+                       mac_mode &= ~MAC_MODE_LINK_POLARITY;
+               else if (masked_phy_id == TG3_PHY_ID_BCM5411)
+                       mac_mode |= MAC_MODE_LINK_POLARITY;
+
+               tg3_writephy(tp, MII_TG3_EXT_CTRL,
+                            MII_TG3_EXT_CTRL_LNK3_LED_MODE);
+       }
+
+       tw32(MAC_MODE, mac_mode);
+       udelay(40);
+
+       return 0;
+}
+
 static void tg3_set_loopback(struct net_device *dev, u32 features)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -6351,16 +6503,8 @@ static void tg3_set_loopback(struct net_device *dev, u32 features)
                if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)
                        return;
 
-               /*
-                * Clear MAC_MODE_HALF_DUPLEX or you won't get packets back in
-                * loopback mode if Half-Duplex mode was negotiated earlier.
-                */
-               tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
-
-               /* Enable internal MAC loopback mode */
-               tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
                spin_lock_bh(&tp->lock);
-               tw32(MAC_MODE, tp->mac_mode);
+               tg3_mac_loopback(tp, true);
                netif_carrier_on(tp->dev);
                spin_unlock_bh(&tp->lock);
                netdev_info(dev, "Internal MAC loopback mode enabled.\n");
@@ -6368,10 +6512,8 @@ static void tg3_set_loopback(struct net_device *dev, u32 features)
                if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
                        return;
 
-               /* Disable internal MAC loopback mode */
-               tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
                spin_lock_bh(&tp->lock);
-               tw32(MAC_MODE, tp->mac_mode);
+               tg3_mac_loopback(tp, false);
                /* Force link status check */
                tg3_setup_phy(tp, 1);
                spin_unlock_bh(&tp->lock);
@@ -11219,10 +11361,6 @@ static int tg3_test_memory(struct tg3 *tp)
        return err;
 }
 
-#define TG3_MAC_LOOPBACK       0
-#define TG3_PHY_LOOPBACK       1
-#define TG3_TSO_LOOPBACK       2
-
 #define TG3_TSO_MSS            500
 
 #define TG3_TSO_IP_HDR_LEN     20
@@ -11246,9 +11384,9 @@ static const u8 tg3_tso_header[] = {
 0x11, 0x11, 0x11, 0x11,
 };
 
-static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
+static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback)
 {
-       u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key;
+       u32 rx_start_idx, rx_idx, tx_idx, opaque_key;
        u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val;
        u32 budget;
        struct sk_buff *skb, *rx_skb;
@@ -11269,76 +11407,6 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
        }
        coal_now = tnapi->coal_now | rnapi->coal_now;
 
-       if (loopback_mode == TG3_MAC_LOOPBACK) {
-               /* HW errata - mac loopback fails in some cases on 5780.
-                * Normal traffic and PHY loopback are not affected by
-                * errata.  Also, the MAC loopback test is deprecated for
-                * all newer ASIC revisions.
-                */
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
-                   tg3_flag(tp, CPMU_PRESENT))
-                       return 0;
-
-               mac_mode = tp->mac_mode &
-                          ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
-               mac_mode |= MAC_MODE_PORT_INT_LPBACK;
-               if (!tg3_flag(tp, 5705_PLUS))
-                       mac_mode |= MAC_MODE_LINK_POLARITY;
-               if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
-                       mac_mode |= MAC_MODE_PORT_MODE_MII;
-               else
-                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
-               tw32(MAC_MODE, mac_mode);
-       } else {
-               if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
-                       tg3_phy_fet_toggle_apd(tp, false);
-                       val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
-               } else
-                       val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
-
-               tg3_phy_toggle_automdix(tp, 0);
-
-               tg3_writephy(tp, MII_BMCR, val);
-               udelay(40);
-
-               mac_mode = tp->mac_mode &
-                          ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
-               if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
-                       tg3_writephy(tp, MII_TG3_FET_PTEST,
-                                    MII_TG3_FET_PTEST_FRC_TX_LINK |
-                                    MII_TG3_FET_PTEST_FRC_TX_LOCK);
-                       /* The write needs to be flushed for the AC131 */
-                       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-                               tg3_readphy(tp, MII_TG3_FET_PTEST, &val);
-                       mac_mode |= MAC_MODE_PORT_MODE_MII;
-               } else
-                       mac_mode |= MAC_MODE_PORT_MODE_GMII;
-
-               /* reset to prevent losing 1st rx packet intermittently */
-               if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
-                       tw32_f(MAC_RX_MODE, RX_MODE_RESET);
-                       udelay(10);
-                       tw32_f(MAC_RX_MODE, tp->rx_mode);
-               }
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-                       u32 masked_phy_id = tp->phy_id & TG3_PHY_ID_MASK;
-                       if (masked_phy_id == TG3_PHY_ID_BCM5401)
-                               mac_mode &= ~MAC_MODE_LINK_POLARITY;
-                       else if (masked_phy_id == TG3_PHY_ID_BCM5411)
-                               mac_mode |= MAC_MODE_LINK_POLARITY;
-                       tg3_writephy(tp, MII_TG3_EXT_CTRL,
-                                    MII_TG3_EXT_CTRL_LNK3_LED_MODE);
-               }
-               tw32(MAC_MODE, mac_mode);
-
-               /* Wait for link */
-               for (i = 0; i < 100; i++) {
-                       if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
-                               break;
-                       mdelay(1);
-               }
-       }
-
        err = -EIO;
 
        tx_len = pktsz;
@@ -11352,7 +11420,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
 
        tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN);
 
-       if (loopback_mode == TG3_TSO_LOOPBACK) {
+       if (tso_loopback) {
                struct iphdr *iph = (struct iphdr *)&tx_data[ETH_HLEN];
 
                u32 hdr_len = TG3_TSO_IP_HDR_LEN + TG3_TSO_TCP_HDR_LEN +
@@ -11472,7 +11540,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
                rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT)
                         - ETH_FCS_LEN;
 
-               if (loopback_mode != TG3_TSO_LOOPBACK) {
+               if (!tso_loopback) {
                        if (rx_len != tx_len)
                                goto out;
 
@@ -11519,25 +11587,33 @@ out:
 #define TG3_STD_LOOPBACK_FAILED                1
 #define TG3_JMB_LOOPBACK_FAILED                2
 #define TG3_TSO_LOOPBACK_FAILED                4
+#define TG3_LOOPBACK_FAILED \
+       (TG3_STD_LOOPBACK_FAILED | \
+        TG3_JMB_LOOPBACK_FAILED | \
+        TG3_TSO_LOOPBACK_FAILED)
 
-#define TG3_MAC_LOOPBACK_SHIFT         0
-#define TG3_PHY_LOOPBACK_SHIFT         4
-#define TG3_LOOPBACK_FAILED            0x00000077
-
-static int tg3_test_loopback(struct tg3 *tp)
+static int tg3_test_loopback(struct tg3 *tp, u64 *data, bool do_extlpbk)
 {
-       int err = 0;
-       u32 eee_cap, cpmuctrl = 0;
-
-       if (!netif_running(tp->dev))
-               return TG3_LOOPBACK_FAILED;
+       int err = -EIO;
+       u32 eee_cap;
 
        eee_cap = tp->phy_flags & TG3_PHYFLG_EEE_CAP;
        tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP;
 
+       if (!netif_running(tp->dev)) {
+               data[0] = TG3_LOOPBACK_FAILED;
+               data[1] = TG3_LOOPBACK_FAILED;
+               if (do_extlpbk)
+                       data[2] = TG3_LOOPBACK_FAILED;
+               goto done;
+       }
+
        err = tg3_reset_hw(tp, 1);
        if (err) {
-               err = TG3_LOOPBACK_FAILED;
+               data[0] = TG3_LOOPBACK_FAILED;
+               data[1] = TG3_LOOPBACK_FAILED;
+               if (do_extlpbk)
+                       data[2] = TG3_LOOPBACK_FAILED;
                goto done;
        }
 
@@ -11550,68 +11626,72 @@ static int tg3_test_loopback(struct tg3 *tp)
                        tw32(i, 0x0);
        }
 
-       /* Turn off gphy autopowerdown. */
-       if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
-               tg3_phy_toggle_apd(tp, false);
+       /* HW errata - mac loopback fails in some cases on 5780.
+        * Normal traffic and PHY loopback are not affected by
+        * errata.  Also, the MAC loopback test is deprecated for
+        * all newer ASIC revisions.
+        */
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780 &&
+           !tg3_flag(tp, CPMU_PRESENT)) {
+               tg3_mac_loopback(tp, true);
 
-       if (tg3_flag(tp, CPMU_PRESENT)) {
+               if (tg3_run_loopback(tp, ETH_FRAME_LEN, false))
+                       data[0] |= TG3_STD_LOOPBACK_FAILED;
+
+               if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+                   tg3_run_loopback(tp, 9000 + ETH_HLEN, false))
+                       data[0] |= TG3_JMB_LOOPBACK_FAILED;
+
+               tg3_mac_loopback(tp, false);
+       }
+
+       if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
+           !tg3_flag(tp, USE_PHYLIB)) {
                int i;
-               u32 status;
 
-               tw32(TG3_CPMU_MUTEX_REQ, CPMU_MUTEX_REQ_DRIVER);
+               tg3_phy_lpbk_set(tp, 0, false);
 
-               /* Wait for up to 40 microseconds to acquire lock. */
-               for (i = 0; i < 4; i++) {
-                       status = tr32(TG3_CPMU_MUTEX_GNT);
-                       if (status == CPMU_MUTEX_GNT_DRIVER)
+               /* Wait for link */
+               for (i = 0; i < 100; i++) {
+                       if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
                                break;
-                       udelay(10);
-               }
-
-               if (status != CPMU_MUTEX_GNT_DRIVER) {
-                       err = TG3_LOOPBACK_FAILED;
-                       goto done;
+                       mdelay(1);
                }
 
-               /* Turn off link-based power management. */
-               cpmuctrl = tr32(TG3_CPMU_CTRL);
-               tw32(TG3_CPMU_CTRL,
-                    cpmuctrl & ~(CPMU_CTRL_LINK_SPEED_MODE |
-                                 CPMU_CTRL_LINK_AWARE_MODE));
-       }
-
-       if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_MAC_LOOPBACK))
-               err |= TG3_STD_LOOPBACK_FAILED << TG3_MAC_LOOPBACK_SHIFT;
+               if (tg3_run_loopback(tp, ETH_FRAME_LEN, false))
+                       data[1] |= TG3_STD_LOOPBACK_FAILED;
+               if (tg3_flag(tp, TSO_CAPABLE) &&
+                   tg3_run_loopback(tp, ETH_FRAME_LEN, true))
+                       data[1] |= TG3_TSO_LOOPBACK_FAILED;
+               if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+                   tg3_run_loopback(tp, 9000 + ETH_HLEN, false))
+                       data[1] |= TG3_JMB_LOOPBACK_FAILED;
 
-       if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
-           tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_MAC_LOOPBACK))
-               err |= TG3_JMB_LOOPBACK_FAILED << TG3_MAC_LOOPBACK_SHIFT;
+               if (do_extlpbk) {
+                       tg3_phy_lpbk_set(tp, 0, true);
 
-       if (tg3_flag(tp, CPMU_PRESENT)) {
-               tw32(TG3_CPMU_CTRL, cpmuctrl);
+                       /* All link indications report up, but the hardware
+                        * isn't really ready for about 20 msec.  Double it
+                        * to be sure.
+                        */
+                       mdelay(40);
 
-               /* Release the mutex */
-               tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER);
-       }
+                       if (tg3_run_loopback(tp, ETH_FRAME_LEN, false))
+                               data[2] |= TG3_STD_LOOPBACK_FAILED;
+                       if (tg3_flag(tp, TSO_CAPABLE) &&
+                           tg3_run_loopback(tp, ETH_FRAME_LEN, true))
+                               data[2] |= TG3_TSO_LOOPBACK_FAILED;
+                       if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+                           tg3_run_loopback(tp, 9000 + ETH_HLEN, false))
+                               data[2] |= TG3_JMB_LOOPBACK_FAILED;
+               }
 
-       if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
-           !tg3_flag(tp, USE_PHYLIB)) {
-               if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_PHY_LOOPBACK))
-                       err |= TG3_STD_LOOPBACK_FAILED <<
-                              TG3_PHY_LOOPBACK_SHIFT;
-               if (tg3_flag(tp, TSO_CAPABLE) &&
-                   tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_TSO_LOOPBACK))
-                       err |= TG3_TSO_LOOPBACK_FAILED <<
-                              TG3_PHY_LOOPBACK_SHIFT;
-               if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
-                   tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_PHY_LOOPBACK))
-                       err |= TG3_JMB_LOOPBACK_FAILED <<
-                              TG3_PHY_LOOPBACK_SHIFT;
+               /* Re-enable gphy autopowerdown. */
+               if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
+                       tg3_phy_toggle_apd(tp, true);
        }
 
-       /* Re-enable gphy autopowerdown. */
-       if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
-               tg3_phy_toggle_apd(tp, true);
+       err = (data[0] | data[1] | data[2]) ? -EIO : 0;
 
 done:
        tp->phy_flags |= eee_cap;
@@ -11623,6 +11703,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                          u64 *data)
 {
        struct tg3 *tp = netdev_priv(dev);
+       bool doextlpbk = etest->flags & ETH_TEST_FL_EXTERNAL_LB;
 
        if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) &&
            tg3_power_up(tp)) {
@@ -11637,7 +11718,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                etest->flags |= ETH_TEST_FL_FAILED;
                data[0] = 1;
        }
-       if (tg3_test_link(tp) != 0) {
+       if (!doextlpbk && tg3_test_link(tp)) {
                etest->flags |= ETH_TEST_FL_FAILED;
                data[1] = 1;
        }
@@ -11667,18 +11748,23 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                        etest->flags |= ETH_TEST_FL_FAILED;
                        data[2] = 1;
                }
+
                if (tg3_test_memory(tp) != 0) {
                        etest->flags |= ETH_TEST_FL_FAILED;
                        data[3] = 1;
                }
-               if ((data[4] = tg3_test_loopback(tp)) != 0)
+
+               if (doextlpbk)
+                       etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
+
+               if (tg3_test_loopback(tp, &data[4], doextlpbk))
                        etest->flags |= ETH_TEST_FL_FAILED;
 
                tg3_full_unlock(tp);
 
                if (tg3_test_interrupt(tp) != 0) {
                        etest->flags |= ETH_TEST_FL_FAILED;
-                       data[5] = 1;
+                       data[7] = 1;
                }
 
                tg3_full_lock(tp, 0);
@@ -14368,7 +14454,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (tg3_flag(tp, ENABLE_APE))
                tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
        else
-               tp->mac_mode = TG3_DEF_MAC_MODE;
+               tp->mac_mode = 0;
 
        /* these are limited to 10/100 only */
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
@@ -15177,7 +15263,7 @@ static const struct net_device_ops tg3_netdev_ops = {
        .ndo_start_xmit         = tg3_start_xmit,
        .ndo_get_stats64        = tg3_get_stats64,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = tg3_set_rx_mode,
+       .ndo_set_rx_mode        = tg3_set_rx_mode,
        .ndo_set_mac_address    = tg3_set_mac_addr,
        .ndo_do_ioctl           = tg3_ioctl,
        .ndo_tx_timeout         = tg3_tx_timeout,
similarity index 99%
rename from drivers/net/tg3.h
rename to drivers/net/ethernet/broadcom/tg3.h
index 2ea456dd588082e4fc8a2fc845eb85e5d36b52d1..d2976f39b2fcf62720bab86cb5e8408e8fb514a9 100644 (file)
 #define MII_TG3_AUXCTL_ACTL_TX_6DB     0x0400
 #define MII_TG3_AUXCTL_ACTL_SMDSP_ENA  0x0800
 #define MII_TG3_AUXCTL_ACTL_EXTPKTLEN  0x4000
+#define MII_TG3_AUXCTL_ACTL_EXTLOOPBK  0x8000
 
 #define MII_TG3_AUXCTL_SHDWSEL_PWRCTL  0x0002
 #define MII_TG3_AUXCTL_PCTL_WOL_EN     0x0008
 
 /* Fast Ethernet Tranceiver definitions */
 #define MII_TG3_FET_PTEST              0x17
+#define  MII_TG3_FET_PTEST_TRIM_SEL    0x0010
+#define  MII_TG3_FET_PTEST_TRIM_2      0x0002
 #define  MII_TG3_FET_PTEST_FRC_TX_LINK 0x1000
 #define  MII_TG3_FET_PTEST_FRC_TX_LOCK 0x0800
 
diff --git a/drivers/net/ethernet/brocade/Kconfig b/drivers/net/ethernet/brocade/Kconfig
new file mode 100644 (file)
index 0000000..03f0b17
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Brocade device configuration
+#
+
+config NET_VENDOR_BROCADE
+       bool "Brocade devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Brocade cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_BROCADE
+
+source "drivers/net/ethernet/brocade/bna/Kconfig"
+
+endif # NET_VENDOR_BROCADE
diff --git a/drivers/net/ethernet/brocade/Makefile b/drivers/net/ethernet/brocade/Makefile
new file mode 100644 (file)
index 0000000..b58238d
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Brocade device drivers.
+#
+
+obj-$(CONFIG_BNA) += bna/
diff --git a/drivers/net/ethernet/brocade/bna/Kconfig b/drivers/net/ethernet/brocade/bna/Kconfig
new file mode 100644 (file)
index 0000000..dc2eb52
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Brocade network device configuration
+#
+
+config BNA
+       tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
+       depends on PCI
+       ---help---
+         This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
+         cards.
+         To compile this driver as a module, choose M here: the module
+         will be called bna.
+
+         For general information and support, go to the Brocade support
+         website at:
+
+         <http://support.brocade.com>
similarity index 52%
rename from drivers/net/bna/Makefile
rename to drivers/net/ethernet/brocade/bna/Makefile
index a5d604de7fea7cad94af3306f9f5905b6972f743..74d3abca1960119fe681d2155d190828845b2009 100644 (file)
@@ -5,7 +5,8 @@
 
 obj-$(CONFIG_BNA) += bna.o
 
-bna-objs := bnad.o bnad_ethtool.o bna_ctrl.o bna_txrx.o
-bna-objs += bfa_ioc.o bfa_ioc_ct.o bfa_cee.o cna_fwimg.o
+bna-objs := bnad.o bnad_ethtool.o bna_enet.o bna_tx_rx.o
+bna-objs += bfa_msgq.o bfa_ioc.o bfa_ioc_ct.o bfa_cee.o
+bna-objs += cna_fwimg.o
 
 EXTRA_CFLAGS := -Idrivers/net/bna
similarity index 98%
rename from drivers/net/bna/bfa_cee.c
rename to drivers/net/ethernet/brocade/bna/bfa_cee.c
index 39e5ab9fde5981429e58ecccc5dce636fdde3953..b45b8eb3b9b05fab5d4f4b2035ff28ab36e770bf 100644 (file)
@@ -22,9 +22,6 @@
 #include "bfi_cna.h"
 #include "bfa_ioc.h"
 
-#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
-#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
-
 static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg);
 static void bfa_cee_format_cee_cfg(void *buffer);
 
similarity index 92%
rename from drivers/net/bna/bfa_defs.h
rename to drivers/net/ethernet/brocade/bna/bfa_defs.h
index b080b3698f48958d9f73c007be215a25bb6f2fdc..205b92b3709c6f8d1c131c48f0f8af8cddc0e12e 100644 (file)
@@ -124,6 +124,7 @@ enum bfa_ioc_state {
        BFA_IOC_DISABLED        = 10,   /*!< IOC is disabled */
        BFA_IOC_FWMISMATCH      = 11,   /*!< IOC f/w different from drivers */
        BFA_IOC_ENABLING        = 12,   /*!< IOC is being enabled */
+       BFA_IOC_HWFAIL          = 13,   /*!< PCI mapping doesn't exist */
 };
 
 /**
@@ -179,8 +180,19 @@ struct bfa_ioc_attr {
        struct bfa_adapter_attr adapter_attr;   /*!< HBA attributes */
        struct bfa_ioc_driver_attr driver_attr; /*!< driver attr    */
        struct bfa_ioc_pci_attr pci_attr;
-       u8                              port_id;        /*!< port number    */
-       u8                              rsvd[7];        /*!< 64bit align    */
+       u8                              port_id;        /*!< port number */
+       u8                              port_mode;      /*!< enum bfa_mode */
+       u8                              cap_bm;         /*!< capability */
+       u8                              port_mode_cfg;  /*!< enum bfa_mode */
+       u8                              rsvd[4];        /*!< 64bit align */
+};
+
+/**
+ * Adapter capability mask definition
+ */
+enum {
+       BFA_CM_HBA      =       0x01,
+       BFA_CM_CNA      =       0x02,
 };
 
 /**
@@ -228,7 +240,7 @@ struct bfa_mfg_block {
        mac_t           mfg_mac;        /*!< mac address */
        u8              num_mac;        /*!< number of mac addresses */
        u8              rsv2;
-       u32     mfg_type;       /*!< card type */
+       u32             card_type;      /*!< card type */
        u8              rsv3[108];
        u8              md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */
 };
@@ -242,5 +254,12 @@ struct bfa_mfg_block {
 #define bfa_asic_id_ct(devid)                  \
        ((devid) == PCI_DEVICE_ID_BROCADE_CT || \
        (devid) == PCI_DEVICE_ID_BROCADE_CT_FC)
+#define bfa_asic_id_ctc(devid) (bfa_asic_id_ct(devid))
+
+enum bfa_mode {
+       BFA_MODE_HBA            = 1,
+       BFA_MODE_CNA            = 2,
+       BFA_MODE_NIC            = 3
+};
 
 #endif /* __BFA_DEFS_H__ */
similarity index 89%
rename from drivers/net/bna/bfa_defs_mfg_comm.h
rename to drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h
index 885ef3afdd4e79936b6aa4d4f13e704d1c7f5b20..7ddd16f819f96a7ffc620873aa0a109515be1836 100644 (file)
 #define __BFA_DEFS_MFG_COMM_H__
 
 #include "cna.h"
+#include "bfa_defs.h"
 
 /**
  * Manufacturing block version
  */
-#define BFA_MFG_VERSION                                2
+#define BFA_MFG_VERSION                                3
 #define BFA_MFG_VERSION_UNINIT                 0xFF
 
 /**
@@ -65,14 +66,6 @@ enum {
 
 #pragma pack(1)
 
-/**
- * Check if 1-port card
- */
-#define bfa_mfg_is_1port(type) (( \
-       (type) == BFA_MFG_TYPE_FC8P1 || \
-       (type) == BFA_MFG_TYPE_FC4P1 || \
-       (type) == BFA_MFG_TYPE_CNA10P1))
-
 /**
  * Check if Mezz card
  */
@@ -95,27 +88,14 @@ enum {
        (type) == BFA_MFG_TYPE_CNA10P1 || \
        bfa_mfg_is_mezz(type)))
 
-#define bfa_mfg_adapter_prop_init_flash(card_type, prop)       \
+#define bfa_mfg_adapter_prop_init_flash_ct(mfgblk, prop)       \
 do {                                                           \
-       switch ((card_type)) {                                  \
-       case BFA_MFG_TYPE_FC8P2:                                \
+       switch ((mfgblk)->card_type) {                          \
        case BFA_MFG_TYPE_JAYHAWK:                              \
        case BFA_MFG_TYPE_ASTRA:                                \
                (prop) = BFI_ADAPTER_SETP(NPORTS, 2) |          \
                        BFI_ADAPTER_SETP(SPEED, 8);             \
                break;                                          \
-       case BFA_MFG_TYPE_FC8P1:                                \
-               (prop) = BFI_ADAPTER_SETP(NPORTS, 1) |          \
-                       BFI_ADAPTER_SETP(SPEED, 8);             \
-               break;                                          \
-       case BFA_MFG_TYPE_FC4P2:                                \
-               (prop) = BFI_ADAPTER_SETP(NPORTS, 2) |          \
-                       BFI_ADAPTER_SETP(SPEED, 4);             \
-               break;                                          \
-       case BFA_MFG_TYPE_FC4P1:                                \
-               (prop) = BFI_ADAPTER_SETP(NPORTS, 1) |          \
-                       BFI_ADAPTER_SETP(SPEED, 4);             \
-               break;                                          \
        case BFA_MFG_TYPE_CNA10P2:                              \
        case BFA_MFG_TYPE_WANCHESE:                             \
        case BFA_MFG_TYPE_LIGHTNING_P0:                         \
similarity index 87%
rename from drivers/net/bna/bfa_ioc.c
rename to drivers/net/ethernet/brocade/bna/bfa_ioc.c
index 126b0aac9f941f6cd85e082ed84d2b0cbcd7d9ba..029fb527e80d349c67e1b124f40f87baf1fb94a7 100644 (file)
@@ -19,7 +19,7 @@
 #include "bfa_ioc.h"
 #include "cna.h"
 #include "bfi.h"
-#include "bfi_ctreg.h"
+#include "bfi_reg.h"
 #include "bfa_defs.h"
 
 /**
@@ -62,6 +62,7 @@ static void bfa_ioc_hw_sem_init(struct bfa_ioc *ioc);
 static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
 static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
 static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
+static void bfa_ioc_poll_fwinit(struct bfa_ioc *ioc);
 static void bfa_ioc_send_enable(struct bfa_ioc *ioc);
 static void bfa_ioc_send_disable(struct bfa_ioc *ioc);
 static void bfa_ioc_send_getattr(struct bfa_ioc *ioc);
@@ -78,8 +79,8 @@ static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
 static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
 static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc);
 static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc);
-static void bfa_ioc_pf_initfailed(struct bfa_ioc *ioc);
 static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
+static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc);
 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
 static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
                         u32 boot_param);
@@ -108,11 +109,11 @@ enum ioc_event {
        IOC_E_ENABLED           = 5,    /*!< f/w enabled                */
        IOC_E_FWRSP_GETATTR     = 6,    /*!< IOC get attribute response */
        IOC_E_DISABLED          = 7,    /*!< f/w disabled               */
-       IOC_E_INITFAILED        = 8,    /*!< failure notice by iocpf sm */
-       IOC_E_PFFAILED          = 9,    /*!< failure notice by iocpf sm */
-       IOC_E_HBFAIL            = 10,   /*!< heartbeat failure          */
-       IOC_E_HWERROR           = 11,   /*!< hardware error interrupt   */
-       IOC_E_TIMEOUT           = 12,   /*!< timeout                    */
+       IOC_E_PFFAILED          = 8,    /*!< failure notice by iocpf sm */
+       IOC_E_HBFAIL            = 9,    /*!< heartbeat failure          */
+       IOC_E_HWERROR           = 10,   /*!< hardware error interrupt   */
+       IOC_E_TIMEOUT           = 11,   /*!< timeout                    */
+       IOC_E_HWFAILED          = 12,   /*!< PCI mapping failure notice */
 };
 
 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event);
@@ -124,6 +125,7 @@ bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc, enum ioc_event);
 
 static struct bfa_sm_table ioc_sm_table[] = {
        {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
@@ -135,6 +137,7 @@ static struct bfa_sm_table ioc_sm_table[] = {
        {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
        {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
        {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
+       {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
 };
 
 /**
@@ -166,6 +169,7 @@ enum iocpf_event {
        IOCPF_E_GETATTRFAIL     = 9,    /*!< init fail notice by ioc sm */
        IOCPF_E_SEMLOCKED       = 10,   /*!< h/w semaphore is locked    */
        IOCPF_E_TIMEOUT         = 11,   /*!< f/w response timeout       */
+       IOCPF_E_SEM_ERROR       = 12,   /*!< h/w sem mapping error      */
 };
 
 /**
@@ -300,11 +304,16 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
                /* !!! fall through !!! */
        case IOC_E_HWERROR:
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
                if (event != IOC_E_PFFAILED)
                        bfa_iocpf_initfail(ioc);
                break;
 
+       case IOC_E_HWFAILED:
+               ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
+               break;
+
        case IOC_E_DISABLE:
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
                break;
@@ -343,6 +352,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
        case IOC_E_FWRSP_GETATTR:
                del_timer(&ioc->ioc_timer);
                bfa_ioc_check_attr_wwns(ioc);
+               bfa_ioc_hb_monitor(ioc);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
                break;
 
@@ -352,7 +362,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
                /* fall through */
        case IOC_E_TIMEOUT:
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
                if (event != IOC_E_PFFAILED)
                        bfa_iocpf_getattrfail(ioc);
                break;
@@ -374,7 +384,7 @@ static void
 bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
 {
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
-       bfa_ioc_hb_monitor(ioc);
+       bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
 }
 
 static void
@@ -394,12 +404,13 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
                bfa_ioc_hb_stop(ioc);
                /* !!! fall through !!! */
        case IOC_E_HBFAIL:
-               bfa_ioc_fail_notify(ioc);
                if (ioc->iocpf.auto_recover)
                        bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
                else
                        bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
 
+               bfa_ioc_fail_notify(ioc);
+
                if (event != IOC_E_PFFAILED)
                        bfa_iocpf_fail(ioc);
                break;
@@ -435,6 +446,11 @@ bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
                bfa_iocpf_fail(ioc);
                break;
 
+       case IOC_E_HWFAILED:
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
+               bfa_ioc_disable_comp(ioc);
+               break;
+
        default:
                bfa_sm_fault(event);
        }
@@ -493,12 +509,14 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
                 * Initialization retry failed.
                 */
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
                if (event != IOC_E_PFFAILED)
                        bfa_iocpf_initfail(ioc);
                break;
 
-       case IOC_E_INITFAILED:
-               bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
+       case IOC_E_HWFAILED:
+               ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
                break;
 
        case IOC_E_ENABLE:
@@ -552,6 +570,36 @@ bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
        }
 }
 
+static void
+bfa_ioc_sm_hwfail_entry(struct bfa_ioc *ioc)
+{
+}
+
+/**
+ * IOC failure.
+ */
+static void
+bfa_ioc_sm_hwfail(struct bfa_ioc *ioc, enum ioc_event event)
+{
+       switch (event) {
+
+       case IOC_E_ENABLE:
+               ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+               break;
+
+       case IOC_E_DISABLE:
+               ioc->cbfn->disable_cbfn(ioc->bfa);
+               break;
+
+       case IOC_E_DETACH:
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
 /**
  * IOCPF State Machine
  */
@@ -562,7 +610,7 @@ bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
 static void
 bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf)
 {
-       iocpf->retry_count = 0;
+       iocpf->fw_mismatch_notified = false;
        iocpf->auto_recover = bfa_nw_auto_recover;
 }
 
@@ -607,7 +655,6 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
        case IOCPF_E_SEMLOCKED:
                if (bfa_ioc_firmware_lock(ioc)) {
                        if (bfa_ioc_sync_start(ioc)) {
-                               iocpf->retry_count = 0;
                                bfa_ioc_sync_join(ioc);
                                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
                        } else {
@@ -622,6 +669,11 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
                }
                break;
 
+       case IOCPF_E_SEM_ERROR:
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               bfa_ioc_pf_hwfailed(ioc);
+               break;
+
        case IOCPF_E_DISABLE:
                bfa_ioc_hw_sem_get_cancel(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
@@ -645,10 +697,10 @@ static void
 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf)
 {
        /* Call only the first time sm enters fwmismatch state. */
-       if (iocpf->retry_count == 0)
+       if (iocpf->fw_mismatch_notified == false)
                bfa_ioc_pf_fwmismatch(iocpf->ioc);
 
-       iocpf->retry_count++;
+       iocpf->fw_mismatch_notified = true;
        mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
                msecs_to_jiffies(BFA_IOC_TOV));
 }
@@ -711,6 +763,11 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
                }
                break;
 
+       case IOCPF_E_SEM_ERROR:
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               bfa_ioc_pf_hwfailed(ioc);
+               break;
+
        case IOCPF_E_DISABLE:
                bfa_ioc_hw_sem_get_cancel(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -724,8 +781,7 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
 static void
 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf)
 {
-       mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
-               msecs_to_jiffies(BFA_IOC_TOV));
+       iocpf->poll_time = 0;
        bfa_ioc_reset(iocpf->ioc, 0);
 }
 
@@ -740,19 +796,11 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_FWREADY:
-               del_timer(&ioc->iocpf_timer);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
                break;
 
-       case IOCPF_E_INITFAIL:
-               del_timer(&ioc->iocpf_timer);
-               /*
-                * !!! fall through !!!
-                */
-
        case IOCPF_E_TIMEOUT:
                bfa_nw_ioc_hw_sem_release(ioc);
-               if (event == IOCPF_E_TIMEOUT)
                        bfa_ioc_pf_failed(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
                break;
@@ -774,6 +822,10 @@ bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf)
 {
        mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies +
                msecs_to_jiffies(BFA_IOC_TOV));
+       /**
+        * Enable Interrupts before sending fw IOC ENABLE cmd.
+        */
+       iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
        bfa_ioc_send_enable(iocpf->ioc);
 }
 
@@ -811,21 +863,11 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
                break;
 
-       case IOCPF_E_FWREADY:
-               bfa_ioc_send_enable(ioc);
-               break;
-
        default:
                bfa_sm_fault(event);
        }
 }
 
-static bool
-bfa_nw_ioc_is_operational(struct bfa_ioc *ioc)
-{
-       return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
-}
-
 static void
 bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf)
 {
@@ -835,8 +877,6 @@ bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf)
 static void
 bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
 {
-       struct bfa_ioc *ioc = iocpf->ioc;
-
        switch (event) {
        case IOCPF_E_DISABLE:
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
@@ -850,14 +890,6 @@ bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
                break;
 
-       case IOCPF_E_FWREADY:
-               bfa_ioc_pf_failed(ioc);
-               if (bfa_nw_ioc_is_operational(ioc))
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
-               else
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
-               break;
-
        default:
                bfa_sm_fault(event);
        }
@@ -881,7 +913,6 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_FWRSP_DISABLE:
-       case IOCPF_E_FWREADY:
                del_timer(&ioc->iocpf_timer);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
                break;
@@ -926,6 +957,11 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
                break;
 
+       case IOCPF_E_SEM_ERROR:
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               bfa_ioc_pf_hwfailed(ioc);
+               break;
+
        case IOCPF_E_FAIL:
                break;
 
@@ -951,7 +987,6 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_ENABLE:
-               iocpf->retry_count = 0;
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
                break;
 
@@ -982,20 +1017,15 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
        switch (event) {
        case IOCPF_E_SEMLOCKED:
                bfa_ioc_notify_fail(ioc);
-               bfa_ioc_sync_ack(ioc);
-               iocpf->retry_count++;
-               if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) {
-                       bfa_ioc_sync_leave(ioc);
-                       bfa_nw_ioc_hw_sem_release(ioc);
-                       bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
-               } else {
-                       if (bfa_ioc_sync_complete(ioc))
-                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
-                       else {
-                               bfa_nw_ioc_hw_sem_release(ioc);
-                               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
-                       }
-               }
+               bfa_ioc_sync_leave(ioc);
+               writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+               bfa_nw_ioc_hw_sem_release(ioc);
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
+               break;
+
+       case IOCPF_E_SEM_ERROR:
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               bfa_ioc_pf_hwfailed(ioc);
                break;
 
        case IOCPF_E_DISABLE:
@@ -1020,7 +1050,6 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
 static void
 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf)
 {
-       bfa_ioc_pf_initfailed(iocpf->ioc);
 }
 
 /**
@@ -1071,11 +1100,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
 
        switch (event) {
        case IOCPF_E_SEMLOCKED:
-               iocpf->retry_count = 0;
                bfa_ioc_sync_ack(ioc);
                bfa_ioc_notify_fail(ioc);
                if (!iocpf->auto_recover) {
                        bfa_ioc_sync_leave(ioc);
+                       writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
                        bfa_nw_ioc_hw_sem_release(ioc);
                        bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
                } else {
@@ -1088,6 +1117,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
                }
                break;
 
+       case IOCPF_E_SEM_ERROR:
+               bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
+               bfa_ioc_pf_hwfailed(ioc);
+               break;
+
        case IOCPF_E_DISABLE:
                bfa_ioc_hw_sem_get_cancel(ioc);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
@@ -1158,13 +1192,13 @@ bfa_nw_ioc_sem_get(void __iomem *sem_reg)
 
        r32 = readl(sem_reg);
 
-       while (r32 && (cnt < BFA_SEM_SPINCNT)) {
+       while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) {
                cnt++;
                udelay(2);
                r32 = readl(sem_reg);
        }
 
-       if (r32 == 0)
+       if (!(r32 & 1))
                return true;
 
        BUG_ON(!(cnt < BFA_SEM_SPINCNT));
@@ -1210,7 +1244,11 @@ bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
         * will return 1. Semaphore is released by writing 1 to the register
         */
        r32 = readl(ioc->ioc_regs.ioc_sem_reg);
-       if (r32 == 0) {
+       if (r32 == ~0) {
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
+               return;
+       }
+       if (!(r32 & 1)) {
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
                return;
        }
@@ -1331,7 +1369,7 @@ bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
        int i;
 
        drv_fwhdr = (struct bfi_ioc_image_hdr *)
-               bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+               bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
 
        for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
                if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i])
@@ -1352,12 +1390,12 @@ bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env)
 
        bfa_nw_ioc_fwver_get(ioc, &fwhdr);
        drv_fwhdr = (struct bfi_ioc_image_hdr *)
-               bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+               bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
 
        if (fwhdr.signature != drv_fwhdr->signature)
                return false;
 
-       if (swab32(fwhdr.param) != boot_env)
+       if (swab32(fwhdr.bootenv) != boot_env)
                return false;
 
        return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr);
@@ -1388,11 +1426,11 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
 
        ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
 
-       boot_env = BFI_BOOT_LOADER_OS;
-
        if (force)
                ioc_fwstate = BFI_IOC_UNINIT;
 
+       boot_env = BFI_FWBOOT_ENV_OS;
+
        /**
         * check if firmware is valid
         */
@@ -1400,7 +1438,8 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
                false : bfa_ioc_fwver_valid(ioc, boot_env);
 
        if (!fwvalid) {
-               bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, boot_env);
+               bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env);
+               bfa_ioc_poll_fwinit(ioc);
                return;
        }
 
@@ -1409,7 +1448,7 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
         * just wait for an initialization completion interrupt.
         */
        if (ioc_fwstate == BFI_IOC_INITING) {
-               ioc->cbfn->reset_cbfn(ioc->bfa);
+               bfa_ioc_poll_fwinit(ioc);
                return;
        }
 
@@ -1423,7 +1462,6 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
                 * be flushed. Otherwise MSI-X interrupts are not delivered.
                 */
                bfa_ioc_msgflush(ioc);
-               ioc->cbfn->reset_cbfn(ioc->bfa);
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
                return;
        }
@@ -1431,7 +1469,8 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
        /**
         * Initialize the h/w for any other states.
         */
-       bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, boot_env);
+       bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env);
+       bfa_ioc_poll_fwinit(ioc);
 }
 
 void
@@ -1475,7 +1514,7 @@ bfa_ioc_send_enable(struct bfa_ioc *ioc)
 
        bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
                    bfa_ioc_portid(ioc));
-       enable_req.ioc_class = ioc->ioc_mc;
+       enable_req.clscode = htons(ioc->clscode);
        do_gettimeofday(&tv);
        enable_req.tv_sec = ntohl(tv.tv_sec);
        bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req));
@@ -1548,22 +1587,23 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
        u32 loff = 0;
        u32 chunkno = 0;
        u32 i;
+       u32 asicmode;
 
        /**
         * Initialize LMEM first before code download
         */
        bfa_ioc_lmem_init(ioc);
 
-       fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
+       fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
 
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
 
        writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
-       for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
+       for (i = 0; i < bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); i++) {
                if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
                        chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
-                       fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc),
+                       fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
                                        BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
                }
 
@@ -1590,12 +1630,16 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
                      ioc->ioc_regs.host_page_num_fn);
 
        /*
-        * Set boot type and boot param at the end.
+        * Set boot type, env and device mode at the end.
        */
+       asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
+                                       ioc->port0_mode, ioc->port1_mode);
+       writel(asicmode, ((ioc->ioc_regs.smem_page_start)
+                       + BFI_FWBOOT_DEVMODE_OFF));
        writel(boot_type, ((ioc->ioc_regs.smem_page_start)
-                       + (BFI_BOOT_TYPE_OFF)));
+                       + (BFI_FWBOOT_TYPE_OFF)));
        writel(boot_env, ((ioc->ioc_regs.smem_page_start)
-                       + (BFI_BOOT_LOADER_OFF)));
+                       + (BFI_FWBOOT_ENV_OFF)));
 }
 
 static void
@@ -1604,6 +1648,20 @@ bfa_ioc_reset(struct bfa_ioc *ioc, bool force)
        bfa_ioc_hwinit(ioc, force);
 }
 
+/**
+ * BFA ioc enable reply by firmware
+ */
+static void
+bfa_ioc_enable_reply(struct bfa_ioc *ioc, enum bfa_mode port_mode,
+                       u8 cap_bm)
+{
+       struct bfa_iocpf *iocpf = &ioc->iocpf;
+
+       ioc->port_mode = ioc->port_mode_cfg = port_mode;
+       ioc->ad_cap_bm = cap_bm;
+       bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
+}
+
 /**
  * @brief
  * Update BFA configuration from firmware configuration.
@@ -1644,7 +1702,9 @@ bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
 {
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
        struct bfa_mbox_cmd *cmd;
-       u32                     stat;
+       bfa_mbox_cmd_cbfn_t cbfn;
+       void *cbarg;
+       u32 stat;
 
        /**
         * If no command pending, do nothing
@@ -1664,6 +1724,16 @@ bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
         */
        bfa_q_deq(&mod->cmd_q, &cmd);
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+
+       /**
+        * Give a callback to the client, indicating that the command is sent
+        */
+       if (cmd->cbfn) {
+               cbfn = cmd->cbfn;
+               cbarg = cmd->cbarg;
+               cmd->cbfn = NULL;
+               cbfn(cbarg);
+       }
 }
 
 /**
@@ -1702,15 +1772,15 @@ bfa_ioc_pf_disabled(struct bfa_ioc *ioc)
 }
 
 static void
-bfa_ioc_pf_initfailed(struct bfa_ioc *ioc)
+bfa_ioc_pf_failed(struct bfa_ioc *ioc)
 {
-       bfa_fsm_send_event(ioc, IOC_E_INITFAILED);
+       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
 }
 
 static void
-bfa_ioc_pf_failed(struct bfa_ioc *ioc)
+bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc)
 {
-       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
+       bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
 }
 
 static void
@@ -1749,10 +1819,9 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc)
  * as the entry vector.
  */
 static void
-bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_env)
+bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
+               u32 boot_env)
 {
-       void __iomem *rb;
-
        bfa_ioc_stats(ioc, ioc_boots);
 
        if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
@@ -1761,22 +1830,16 @@ bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_env)
        /**
         * Initialize IOC state of all functions on a chip reset.
         */
-       rb = ioc->pcidev.pci_bar_kva;
-       if (boot_type == BFI_BOOT_TYPE_MEMTEST) {
-               writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG));
-               writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG));
+       if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) {
+               writel(BFI_IOC_MEMTEST, ioc->ioc_regs.ioc_fwstate);
+               writel(BFI_IOC_MEMTEST, ioc->ioc_regs.alt_ioc_fwstate);
        } else {
-               writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG));
-               writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG));
+               writel(BFI_IOC_INITING, ioc->ioc_regs.ioc_fwstate);
+               writel(BFI_IOC_INITING, ioc->ioc_regs.alt_ioc_fwstate);
        }
 
        bfa_ioc_msgflush(ioc);
        bfa_ioc_download_fw(ioc, boot_type, boot_env);
-
-       /**
-        * Enable interrupts just before starting LPU
-        */
-       ioc->cbfn->reset_cbfn(ioc->bfa);
        bfa_ioc_lpu_start(ioc);
 }
 
@@ -1789,13 +1852,17 @@ bfa_nw_ioc_auto_recover(bool auto_recover)
        bfa_nw_auto_recover = auto_recover;
 }
 
-static void
+static bool
 bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg)
 {
        u32     *msgp = mbmsg;
        u32     r32;
        int             i;
 
+       r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
+       if ((r32 & 1) == 0)
+               return false;
+
        /**
         * read the MBOX msg
         */
@@ -1811,6 +1878,8 @@ bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg)
         */
        writel(1, ioc->ioc_regs.lpu_mbox_cmd);
        readl(ioc->ioc_regs.lpu_mbox_cmd);
+
+       return true;
 }
 
 static void
@@ -1827,12 +1896,10 @@ bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
        case BFI_IOC_I2H_HBEAT:
                break;
 
-       case BFI_IOC_I2H_READY_EVENT:
-               bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY);
-               break;
-
        case BFI_IOC_I2H_ENABLE_REPLY:
-               bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
+               bfa_ioc_enable_reply(ioc,
+                       (enum bfa_mode)msg->fw_event.port_mode,
+                       msg->fw_event.cap_bm);
                break;
 
        case BFI_IOC_I2H_DISABLE_REPLY:
@@ -1878,6 +1945,9 @@ void
 bfa_nw_ioc_detach(struct bfa_ioc *ioc)
 {
        bfa_fsm_send_event(ioc, IOC_E_DETACH);
+
+       /* Done with detach, empty the notify_q. */
+       INIT_LIST_HEAD(&ioc->notify_q);
 }
 
 /**
@@ -1887,12 +1957,29 @@ bfa_nw_ioc_detach(struct bfa_ioc *ioc)
  */
 void
 bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
-                enum bfi_mclass mc)
+                enum bfi_pcifn_class clscode)
 {
-       ioc->ioc_mc     = mc;
+       ioc->clscode    = clscode;
        ioc->pcidev     = *pcidev;
-       ioc->ctdev      = bfa_asic_id_ct(ioc->pcidev.device_id);
-       ioc->cna        = ioc->ctdev && !ioc->fcmode;
+
+       /**
+        * Initialize IOC and device personality
+        */
+       ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC;
+       ioc->asic_mode  = BFI_ASIC_MODE_FC;
+
+       switch (pcidev->device_id) {
+       case PCI_DEVICE_ID_BROCADE_CT:
+               ioc->asic_gen = BFI_ASIC_GEN_CT;
+               ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
+               ioc->asic_mode  = BFI_ASIC_MODE_ETH;
+               ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
+               ioc->ad_cap_bm = BFA_CM_CNA;
+               break;
+
+       default:
+               BUG_ON(1);
+       }
 
        bfa_nw_ioc_set_ct_hwif(ioc);
 
@@ -1968,18 +2055,22 @@ bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
  * @param[in]  ioc     IOC instance
  * @param[i]   cmd     Mailbox command
  */
-void
-bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
+bool
+bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd,
+                       bfa_mbox_cmd_cbfn_t cbfn, void *cbarg)
 {
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
        u32                     stat;
 
+       cmd->cbfn = cbfn;
+       cmd->cbarg = cbarg;
+
        /**
         * If a previous command is pending, queue new command
         */
        if (!list_empty(&mod->cmd_q)) {
                list_add_tail(&cmd->qe, &mod->cmd_q);
-               return;
+               return true;
        }
 
        /**
@@ -1988,7 +2079,7 @@ bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
        stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
        if (stat) {
                list_add_tail(&cmd->qe, &mod->cmd_q);
-               return;
+               return true;
        }
 
        /**
@@ -1996,7 +2087,7 @@ bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
         */
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
 
-       return;
+       return false;
 }
 
 /**
@@ -2009,21 +2100,28 @@ bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
        struct bfi_mbmsg m;
        int                             mc;
 
-       bfa_ioc_msgget(ioc, &m);
+       if (bfa_ioc_msgget(ioc, &m)) {
+               /**
+                * Treat IOC message class as special.
+                */
+               mc = m.mh.msg_class;
+               if (mc == BFI_MC_IOC) {
+                       bfa_ioc_isr(ioc, &m);
+                       return;
+               }
 
-       /**
-        * Treat IOC message class as special.
-        */
-       mc = m.mh.msg_class;
-       if (mc == BFI_MC_IOC) {
-               bfa_ioc_isr(ioc, &m);
-               return;
+               if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
+                       return;
+
+               mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
        }
 
-       if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
-               return;
+       bfa_ioc_lpu_read_stat(ioc);
 
-       mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
+       /**
+        * Try to send pending mailbox commands
+        */
+       bfa_ioc_mbox_poll(ioc);
 }
 
 void
@@ -2095,24 +2193,18 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc,
        ad_attr->asic_rev = ioc_attr->asic_rev;
 
        bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
-
-       ad_attr->cna_capable = ioc->cna;
-       ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna;
 }
 
 static enum bfa_ioc_type
 bfa_ioc_get_type(struct bfa_ioc *ioc)
 {
-       if (!ioc->ctdev || ioc->fcmode)
-               return BFA_IOC_TYPE_FC;
-       else if (ioc->ioc_mc == BFI_MC_IOCFC)
-               return BFA_IOC_TYPE_FCoE;
-       else if (ioc->ioc_mc == BFI_MC_LL)
-               return BFA_IOC_TYPE_LL;
-       else {
-               BUG_ON(!(ioc->ioc_mc == BFI_MC_LL));
+       if (ioc->clscode == BFI_PCIFN_CLASS_ETH)
                return BFA_IOC_TYPE_LL;
-       }
+
+       BUG_ON(!(ioc->clscode == BFI_PCIFN_CLASS_FC));
+
+       return (ioc->attr->port_mode == BFI_PORT_MODE_FC)
+               ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE;
 }
 
 static void
@@ -2224,6 +2316,10 @@ bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr)
 
        ioc_attr->state = bfa_ioc_get_state(ioc);
        ioc_attr->port_id = ioc->port_id;
+       ioc_attr->port_mode = ioc->port_mode;
+
+       ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
+       ioc_attr->cap_bm = ioc->ad_cap_bm;
 
        ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
 
@@ -2313,8 +2409,14 @@ void
 bfa_nw_iocpf_timeout(void *ioc_arg)
 {
        struct bfa_ioc  *ioc = (struct bfa_ioc *) ioc_arg;
+       enum bfa_iocpf_state iocpf_st;
+
+       iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
 
-       bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
+       if (iocpf_st == BFA_IOCPF_HWINIT)
+               bfa_ioc_poll_fwinit(ioc);
+       else
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
 }
 
 void
@@ -2324,3 +2426,22 @@ bfa_nw_iocpf_sem_timeout(void *ioc_arg)
 
        bfa_ioc_hw_sem_get(ioc);
 }
+
+static void
+bfa_ioc_poll_fwinit(struct bfa_ioc *ioc)
+{
+       u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+       if (fwstate == BFI_IOC_DISABLED) {
+               bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
+               return;
+       }
+
+       if (ioc->iocpf.poll_time >= BFA_IOC_TOV) {
+               bfa_nw_iocpf_timeout(ioc);
+       } else {
+               ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
+               mod_timer(&ioc->iocpf_timer, jiffies +
+                       msecs_to_jiffies(BFA_IOC_POLL_TOV));
+       }
+}
similarity index 88%
rename from drivers/net/bna/bfa_ioc.h
rename to drivers/net/ethernet/brocade/bna/bfa_ioc.h
index bda866ba6e905acb23212bfdd54fe3051dd1a5ef..f5a3d4e8207846346d968c3fd6bdc16faaaf20b2 100644 (file)
@@ -26,7 +26,7 @@
 #define BFA_IOC_TOV            3000    /* msecs */
 #define BFA_IOC_HWSEM_TOV      500     /* msecs */
 #define BFA_IOC_HB_TOV         500     /* msecs */
-#define BFA_IOC_HWINIT_MAX     5
+#define BFA_IOC_POLL_TOV       200     /* msecs */
 
 /**
  * PCI device information required by IOC
@@ -169,8 +169,9 @@ struct bfa_ioc_hbfail_notify {
 struct bfa_iocpf {
        bfa_fsm_t               fsm;
        struct bfa_ioc          *ioc;
-       u32                     retry_count;
+       bool                    fw_mismatch_notified;
        bool                    auto_recover;
+       u32                     poll_time;
 };
 
 struct bfa_ioc {
@@ -186,12 +187,10 @@ struct bfa_ioc {
        void                    *dbg_fwsave;
        int                     dbg_fwsave_len;
        bool                    dbg_fwsave_once;
-       enum bfi_mclass         ioc_mc;
+       enum bfi_pcifn_class    clscode;
        struct bfa_ioc_regs     ioc_regs;
        struct bfa_ioc_drv_stats stats;
        bool                    fcmode;
-       bool                    ctdev;
-       bool                    cna;
        bool                    pllinit;
        bool                    stats_busy;     /*!< outstanding stats */
        u8                      port_id;
@@ -202,10 +201,18 @@ struct bfa_ioc {
        struct bfa_ioc_mbox_mod mbox_mod;
        struct bfa_ioc_hwif     *ioc_hwif;
        struct bfa_iocpf        iocpf;
+       enum bfi_asic_gen       asic_gen;
+       enum bfi_asic_mode      asic_mode;
+       enum bfi_port_mode      port0_mode;
+       enum bfi_port_mode      port1_mode;
+       enum bfa_mode           port_mode;
+       u8                      ad_cap_bm;      /*!< adapter cap bit mask */
+       u8                      port_mode_cfg;  /*!< config port mode */
 };
 
 struct bfa_ioc_hwif {
-       enum bfa_status (*ioc_pll_init) (void __iomem *rb, bool fcmode);
+       enum bfa_status (*ioc_pll_init) (void __iomem *rb,
+                                               enum bfi_asic_mode m);
        bool            (*ioc_firmware_lock)    (struct bfa_ioc *ioc);
        void            (*ioc_firmware_unlock)  (struct bfa_ioc *ioc);
        void            (*ioc_reg_init) (struct bfa_ioc *ioc);
@@ -219,12 +226,14 @@ struct bfa_ioc_hwif {
        void            (*ioc_sync_leave)       (struct bfa_ioc *ioc);
        void            (*ioc_sync_ack)         (struct bfa_ioc *ioc);
        bool            (*ioc_sync_complete)    (struct bfa_ioc *ioc);
+       bool            (*ioc_lpu_read_stat)    (struct bfa_ioc *ioc);
 };
 
 #define bfa_ioc_pcifn(__ioc)           ((__ioc)->pcidev.pci_func)
 #define bfa_ioc_devid(__ioc)           ((__ioc)->pcidev.device_id)
 #define bfa_ioc_bar0(__ioc)            ((__ioc)->pcidev.pci_bar_kva)
 #define bfa_ioc_portid(__ioc)          ((__ioc)->port_id)
+#define bfa_ioc_asic_gen(__ioc)                ((__ioc)->asic_gen)
 #define bfa_ioc_fetch_stats(__ioc, __stats) \
                (((__stats)->drv_stats) = (__ioc)->stats)
 #define bfa_ioc_clr_stats(__ioc)       \
@@ -240,12 +249,9 @@ struct bfa_ioc_hwif {
 #define bfa_ioc_stats_hb_count(_ioc, _hb_count)        \
        ((_ioc)->stats.hb_count = (_hb_count))
 #define BFA_IOC_FWIMG_MINSZ    (16 * 1024)
-#define BFA_IOC_FWIMG_TYPE(__ioc)                                      \
-       (((__ioc)->ctdev) ?                                             \
-        (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) :     \
-        BFI_IMAGE_CB_FC)
 #define BFA_IOC_FW_SMEM_SIZE(__ioc)                                    \
-       (((__ioc)->ctdev) ? BFI_SMEM_CT_SIZE : BFI_SMEM_CB_SIZE)
+       ((bfa_ioc_asic_gen(__ioc) == BFI_ASIC_GEN_CB)                   \
+       ? BFI_SMEM_CB_SIZE : BFI_SMEM_CT_SIZE)
 #define BFA_IOC_FLASH_CHUNK_NO(off)            (off / BFI_FLASH_CHUNK_SZ_WORDS)
 #define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)     (off % BFI_FLASH_CHUNK_SZ_WORDS)
 #define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
@@ -253,7 +259,9 @@ struct bfa_ioc_hwif {
 /**
  * IOC mailbox interface
  */
-void bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd);
+bool bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc,
+                       struct bfa_mbox_cmd *cmd,
+                       bfa_mbox_cmd_cbfn_t cbfn, void *cbarg);
 void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc);
 void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
                bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);
@@ -264,13 +272,18 @@ void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
 
 #define bfa_ioc_pll_init_asic(__ioc) \
        ((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \
-                          (__ioc)->fcmode))
+                          (__ioc)->asic_mode))
 
 #define        bfa_ioc_isr_mode_set(__ioc, __msix)                     \
                        ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
 #define        bfa_ioc_ownership_reset(__ioc)                          \
                        ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
 
+#define bfa_ioc_lpu_read_stat(__ioc) do {                              \
+               if ((__ioc)->ioc_hwif->ioc_lpu_read_stat)               \
+                       ((__ioc)->ioc_hwif->ioc_lpu_read_stat(__ioc));  \
+} while (0)
+
 void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc);
 
 void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa,
@@ -278,7 +291,7 @@ void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa,
 void bfa_nw_ioc_auto_recover(bool auto_recover);
 void bfa_nw_ioc_detach(struct bfa_ioc *ioc);
 void bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
-               enum bfi_mclass mc);
+               enum bfi_pcifn_class clscode);
 u32 bfa_nw_ioc_meminfo(void);
 void bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc,  u8 *dm_kva, u64 dm_pa);
 void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
@@ -309,7 +322,7 @@ void bfa_nw_iocpf_sem_timeout(void *ioc);
 /*
  * F/W Image Size & Chunk
  */
-u32 *bfa_cb_image_get_chunk(int type, u32 off);
-u32 bfa_cb_image_get_size(int type);
+u32 *bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off);
+u32 bfa_cb_image_get_size(enum bfi_asic_gen asic_gen);
 
 #endif /* __BFA_IOC_H__ */
similarity index 76%
rename from drivers/net/bna/bfa_ioc_ct.c
rename to drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
index 87aecdf22cf9c29adf4379685d9813bbbebd2cd5..b4429bc67c34e2f53c42744b6f9d9817cecbec04 100644 (file)
@@ -19,7 +19,7 @@
 #include "bfa_ioc.h"
 #include "cna.h"
 #include "bfi.h"
-#include "bfi_ctreg.h"
+#include "bfi_reg.h"
 #include "bfa_defs.h"
 
 #define bfa_ioc_ct_sync_pos(__ioc)     \
@@ -46,30 +46,37 @@ static void bfa_ioc_ct_sync_join(struct bfa_ioc *ioc);
 static void bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc);
 static void bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc);
 static bool bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc);
-static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode);
+static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb,
+                               enum bfi_asic_mode asic_mode);
 
 static struct bfa_ioc_hwif nw_hwif_ct;
 
+static void
+bfa_ioc_set_ctx_hwif(struct bfa_ioc *ioc, struct bfa_ioc_hwif *hwif)
+{
+       hwif->ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
+       hwif->ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
+       hwif->ioc_notify_fail = bfa_ioc_ct_notify_fail;
+       hwif->ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+       hwif->ioc_sync_start = bfa_ioc_ct_sync_start;
+       hwif->ioc_sync_join = bfa_ioc_ct_sync_join;
+       hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave;
+       hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack;
+       hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete;
+}
+
 /**
  * Called from bfa_ioc_attach() to map asic specific calls.
  */
 void
 bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc)
 {
+       bfa_ioc_set_ctx_hwif(ioc, &nw_hwif_ct);
+
        nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
-       nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
-       nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
        nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
        nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
        nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
-       nw_hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail;
-       nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
-       nw_hwif_ct.ioc_sync_start = bfa_ioc_ct_sync_start;
-       nw_hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join;
-       nw_hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave;
-       nw_hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack;
-       nw_hwif_ct.ioc_sync_complete = bfa_ioc_ct_sync_complete;
-
        ioc->ioc_hwif = &nw_hwif_ct;
 }
 
@@ -83,16 +90,10 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc)
        u32 usecnt;
        struct bfi_ioc_image_hdr fwhdr;
 
-       /**
-        * Firmware match check is relevant only for CNA.
-        */
-       if (!ioc->cna)
-               return true;
-
        /**
         * If bios boot (flash based) -- do not increment usage count
         */
-       if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
+       if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
                                                BFA_IOC_FWIMG_MINSZ)
                return true;
 
@@ -139,16 +140,10 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
 {
        u32 usecnt;
 
-       /**
-        * Firmware lock is relevant only for CNA.
-        */
-       if (!ioc->cna)
-               return;
-
        /**
         * If bios boot (flash based) -- do not decrement usage count
         */
-       if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
+       if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
                                                BFA_IOC_FWIMG_MINSZ)
                return;
 
@@ -171,22 +166,17 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
 static void
 bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc)
 {
-       if (ioc->cna) {
-               writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
-               writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
-               /* Wait for halt to take effect */
-               readl(ioc->ioc_regs.ll_halt);
-               readl(ioc->ioc_regs.alt_ll_halt);
-       } else {
-               writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
-               readl(ioc->ioc_regs.err_set);
-       }
+       writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
+       writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
+       /* Wait for halt to take effect */
+       readl(ioc->ioc_regs.ll_halt);
+       readl(ioc->ioc_regs.alt_ll_halt);
 }
 
 /**
  * Host to LPU mailbox message addresses
  */
-static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } ct_fnreg[] = {
        { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
        { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
        { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
@@ -196,21 +186,21 @@ static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
 /**
  * Host <-> LPU mailbox command/status registers - port 0
  */
-static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
-       { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
-       { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
-       { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
-       { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+static struct { u32 hfn, lpu; } ct_p0reg[] = {
+       { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
+       { HOSTFN1_LPU0_CMD_STAT, LPU0_HOSTFN1_CMD_STAT },
+       { HOSTFN2_LPU0_CMD_STAT, LPU0_HOSTFN2_CMD_STAT },
+       { HOSTFN3_LPU0_CMD_STAT, LPU0_HOSTFN3_CMD_STAT }
 };
 
 /**
  * Host <-> LPU mailbox command/status registers - port 1
  */
-static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
-       { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
-       { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
-       { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
-       { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+static struct { u32 hfn, lpu; } ct_p1reg[] = {
+       { HOSTFN0_LPU1_CMD_STAT, LPU1_HOSTFN0_CMD_STAT },
+       { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT },
+       { HOSTFN2_LPU1_CMD_STAT, LPU1_HOSTFN2_CMD_STAT },
+       { HOSTFN3_LPU1_CMD_STAT, LPU1_HOSTFN3_CMD_STAT }
 };
 
 static void
@@ -221,24 +211,24 @@ bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
 
        rb = bfa_ioc_bar0(ioc);
 
-       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
-       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
-       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+       ioc->ioc_regs.hfn_mbox = rb + ct_fnreg[pcifn].hfn_mbox;
+       ioc->ioc_regs.lpu_mbox = rb + ct_fnreg[pcifn].lpu_mbox;
+       ioc->ioc_regs.host_page_num_fn = rb + ct_fnreg[pcifn].hfn_pgn;
 
        if (ioc->port_id == 0) {
                ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
                ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
                ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
-               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
-               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+               ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p0reg[pcifn].hfn;
+               ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p0reg[pcifn].lpu;
                ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
                ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
        } else {
                ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
                ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
                ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG;
-               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
-               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+               ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p1reg[pcifn].hfn;
+               ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p1reg[pcifn].lpu;
                ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
                ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
        }
@@ -248,8 +238,8 @@ bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
         */
        ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
        ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
-       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
-       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_LCLK_CTL_REG);
+       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_SCLK_CTL_REG);
 
        /*
         * IOC semaphore registers and serialization
@@ -309,7 +299,7 @@ bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix)
        /**
         * If already in desired mode, do not change anything
         */
-       if (!msix && mode)
+       if ((!msix && mode) || (msix && !mode))
                return;
 
        if (msix)
@@ -329,11 +319,9 @@ bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix)
 static void
 bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc)
 {
-       if (ioc->cna) {
-               bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
-               writel(0, ioc->ioc_regs.ioc_usage_reg);
-               bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
-       }
+       bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+       writel(0, ioc->ioc_regs.ioc_usage_reg);
+       bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
 
        /*
         * Read the hw sem reg to make sure that it is locked
@@ -442,18 +430,20 @@ bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc)
 }
 
 static enum bfa_status
-bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode)
+bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode asic_mode)
 {
        u32     pll_sclk, pll_fclk, r32;
+       bool fcmode = (asic_mode == BFI_ASIC_MODE_FC);
+
+       pll_sclk = __APP_PLL_SCLK_LRESETN | __APP_PLL_SCLK_ENARST |
+               __APP_PLL_SCLK_RSEL200500 | __APP_PLL_SCLK_P0_1(3U) |
+               __APP_PLL_SCLK_JITLMT0_1(3U) |
+               __APP_PLL_SCLK_CNTLMT0_1(1U);
+       pll_fclk = __APP_PLL_LCLK_LRESETN | __APP_PLL_LCLK_ENARST |
+               __APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) |
+               __APP_PLL_LCLK_JITLMT0_1(3U) |
+               __APP_PLL_LCLK_CNTLMT0_1(1U);
 
-       pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
-               __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
-               __APP_PLL_312_JITLMT0_1(3U) |
-               __APP_PLL_312_CNTLMT0_1(1U);
-       pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
-               __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
-               __APP_PLL_425_JITLMT0_1(3U) |
-               __APP_PLL_425_CNTLMT0_1(1U);
        if (fcmode) {
                writel(0, (rb + OP_MODE));
                writel(__APP_EMS_CMLCKSEL |
@@ -474,27 +464,28 @@ bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode)
        writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
        writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
        writel(pll_sclk |
-               __APP_PLL_312_LOGIC_SOFT_RESET,
-               rb + APP_PLL_312_CTL_REG);
+               __APP_PLL_SCLK_LOGIC_SOFT_RESET,
+               rb + APP_PLL_SCLK_CTL_REG);
        writel(pll_fclk |
-               __APP_PLL_425_LOGIC_SOFT_RESET,
-               rb + APP_PLL_425_CTL_REG);
+               __APP_PLL_LCLK_LOGIC_SOFT_RESET,
+               rb + APP_PLL_LCLK_CTL_REG);
        writel(pll_sclk |
-               __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE,
-               rb + APP_PLL_312_CTL_REG);
+               __APP_PLL_SCLK_LOGIC_SOFT_RESET | __APP_PLL_SCLK_ENABLE,
+               rb + APP_PLL_SCLK_CTL_REG);
        writel(pll_fclk |
-               __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE,
-               rb + APP_PLL_425_CTL_REG);
+               __APP_PLL_LCLK_LOGIC_SOFT_RESET | __APP_PLL_LCLK_ENABLE,
+               rb + APP_PLL_LCLK_CTL_REG);
        readl(rb + HOSTFN0_INT_MSK);
        udelay(2000);
        writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
        writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
        writel(pll_sclk |
-               __APP_PLL_312_ENABLE,
-               rb + APP_PLL_312_CTL_REG);
+               __APP_PLL_SCLK_ENABLE,
+               rb + APP_PLL_SCLK_CTL_REG);
        writel(pll_fclk |
-               __APP_PLL_425_ENABLE,
-               rb + APP_PLL_425_CTL_REG);
+               __APP_PLL_LCLK_ENABLE,
+               rb + APP_PLL_LCLK_CTL_REG);
+
        if (!fcmode) {
                writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
                writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
diff --git a/drivers/net/ethernet/brocade/bna/bfa_msgq.c b/drivers/net/ethernet/brocade/bna/bfa_msgq.c
new file mode 100644 (file)
index 0000000..ed52187
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * @file bfa_msgq.c MSGQ module source file.
+ */
+
+#include "bfi.h"
+#include "bfa_msgq.h"
+#include "bfa_ioc.h"
+
+#define call_cmdq_ent_cbfn(_cmdq_ent, _status)                         \
+{                                                                      \
+       bfa_msgq_cmdcbfn_t cbfn;                                        \
+       void *cbarg;                                                    \
+       cbfn = (_cmdq_ent)->cbfn;                                       \
+       cbarg = (_cmdq_ent)->cbarg;                                     \
+       (_cmdq_ent)->cbfn = NULL;                                       \
+       (_cmdq_ent)->cbarg = NULL;                                      \
+       if (cbfn) {                                                     \
+               cbfn(cbarg, (_status));                                 \
+       }                                                               \
+}
+
+static void bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq);
+static void bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq);
+
+enum cmdq_event {
+       CMDQ_E_START                    = 1,
+       CMDQ_E_STOP                     = 2,
+       CMDQ_E_FAIL                     = 3,
+       CMDQ_E_POST                     = 4,
+       CMDQ_E_INIT_RESP                = 5,
+       CMDQ_E_DB_READY                 = 6,
+};
+
+bfa_fsm_state_decl(cmdq, stopped, struct bfa_msgq_cmdq, enum cmdq_event);
+bfa_fsm_state_decl(cmdq, init_wait, struct bfa_msgq_cmdq, enum cmdq_event);
+bfa_fsm_state_decl(cmdq, ready, struct bfa_msgq_cmdq, enum cmdq_event);
+bfa_fsm_state_decl(cmdq, dbell_wait, struct bfa_msgq_cmdq,
+                       enum cmdq_event);
+
+static void
+cmdq_sm_stopped_entry(struct bfa_msgq_cmdq *cmdq)
+{
+       struct bfa_msgq_cmd_entry *cmdq_ent;
+
+       cmdq->producer_index = 0;
+       cmdq->consumer_index = 0;
+       cmdq->flags = 0;
+       cmdq->token = 0;
+       cmdq->offset = 0;
+       cmdq->bytes_to_copy = 0;
+       while (!list_empty(&cmdq->pending_q)) {
+               bfa_q_deq(&cmdq->pending_q, &cmdq_ent);
+               bfa_q_qe_init(&cmdq_ent->qe);
+               call_cmdq_ent_cbfn(cmdq_ent, BFA_STATUS_FAILED);
+       }
+}
+
+static void
+cmdq_sm_stopped(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
+{
+       switch (event) {
+       case CMDQ_E_START:
+               bfa_fsm_set_state(cmdq, cmdq_sm_init_wait);
+               break;
+
+       case CMDQ_E_STOP:
+       case CMDQ_E_FAIL:
+               /* No-op */
+               break;
+
+       case CMDQ_E_POST:
+               cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+cmdq_sm_init_wait_entry(struct bfa_msgq_cmdq *cmdq)
+{
+       bfa_wc_down(&cmdq->msgq->init_wc);
+}
+
+static void
+cmdq_sm_init_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
+{
+       switch (event) {
+       case CMDQ_E_STOP:
+       case CMDQ_E_FAIL:
+               bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
+               break;
+
+       case CMDQ_E_POST:
+               cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
+               break;
+
+       case CMDQ_E_INIT_RESP:
+               if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
+                       cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
+                       bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
+               } else
+                       bfa_fsm_set_state(cmdq, cmdq_sm_ready);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+cmdq_sm_ready_entry(struct bfa_msgq_cmdq *cmdq)
+{
+}
+
+static void
+cmdq_sm_ready(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
+{
+       switch (event) {
+       case CMDQ_E_STOP:
+       case CMDQ_E_FAIL:
+               bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
+               break;
+
+       case CMDQ_E_POST:
+               bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+cmdq_sm_dbell_wait_entry(struct bfa_msgq_cmdq *cmdq)
+{
+       bfa_msgq_cmdq_dbell(cmdq);
+}
+
+static void
+cmdq_sm_dbell_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
+{
+       switch (event) {
+       case CMDQ_E_STOP:
+       case CMDQ_E_FAIL:
+               bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
+               break;
+
+       case CMDQ_E_POST:
+               cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
+               break;
+
+       case CMDQ_E_DB_READY:
+               if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
+                       cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
+                       bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
+               } else
+                       bfa_fsm_set_state(cmdq, cmdq_sm_ready);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bfa_msgq_cmdq_dbell_ready(void *arg)
+{
+       struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
+       bfa_fsm_send_event(cmdq, CMDQ_E_DB_READY);
+}
+
+static void
+bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq)
+{
+       struct bfi_msgq_h2i_db *dbell =
+               (struct bfi_msgq_h2i_db *)(&cmdq->dbell_mb.msg[0]);
+
+       memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
+       bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_PI, 0);
+       dbell->mh.mtag.i2htok = 0;
+       dbell->idx.cmdq_pi = htons(cmdq->producer_index);
+
+       if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->dbell_mb,
+                               bfa_msgq_cmdq_dbell_ready, cmdq)) {
+               bfa_msgq_cmdq_dbell_ready(cmdq);
+       }
+}
+
+static void
+__cmd_copy(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq_cmd_entry *cmd)
+{
+       size_t len = cmd->msg_size;
+       int num_entries = 0;
+       size_t to_copy;
+       u8 *src, *dst;
+
+       src = (u8 *)cmd->msg_hdr;
+       dst = (u8 *)cmdq->addr.kva;
+       dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
+
+       while (len) {
+               to_copy = (len < BFI_MSGQ_CMD_ENTRY_SIZE) ?
+                               len : BFI_MSGQ_CMD_ENTRY_SIZE;
+               memcpy(dst, src, to_copy);
+               len -= to_copy;
+               src += BFI_MSGQ_CMD_ENTRY_SIZE;
+               BFA_MSGQ_INDX_ADD(cmdq->producer_index, 1, cmdq->depth);
+               dst = (u8 *)cmdq->addr.kva;
+               dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
+               num_entries++;
+       }
+
+}
+
+static void
+bfa_msgq_cmdq_ci_update(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
+{
+       struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
+       struct bfa_msgq_cmd_entry *cmd;
+       int posted = 0;
+
+       cmdq->consumer_index = ntohs(dbell->idx.cmdq_ci);
+
+       /* Walk through pending list to see if the command can be posted */
+       while (!list_empty(&cmdq->pending_q)) {
+               cmd =
+               (struct bfa_msgq_cmd_entry *)bfa_q_first(&cmdq->pending_q);
+               if (ntohs(cmd->msg_hdr->num_entries) <=
+                       BFA_MSGQ_FREE_CNT(cmdq)) {
+                       list_del(&cmd->qe);
+                       __cmd_copy(cmdq, cmd);
+                       posted = 1;
+                       call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
+               } else {
+                       break;
+               }
+       }
+
+       if (posted)
+               bfa_fsm_send_event(cmdq, CMDQ_E_POST);
+}
+
+static void
+bfa_msgq_cmdq_copy_next(void *arg)
+{
+       struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
+
+       if (cmdq->bytes_to_copy)
+               bfa_msgq_cmdq_copy_rsp(cmdq);
+}
+
+static void
+bfa_msgq_cmdq_copy_req(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
+{
+       struct bfi_msgq_i2h_cmdq_copy_req *req =
+               (struct bfi_msgq_i2h_cmdq_copy_req *)mb;
+
+       cmdq->token = 0;
+       cmdq->offset = ntohs(req->offset);
+       cmdq->bytes_to_copy = ntohs(req->len);
+       bfa_msgq_cmdq_copy_rsp(cmdq);
+}
+
+static void
+bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq)
+{
+       struct bfi_msgq_h2i_cmdq_copy_rsp *rsp =
+               (struct bfi_msgq_h2i_cmdq_copy_rsp *)&cmdq->copy_mb.msg[0];
+       int copied;
+       u8 *addr = (u8 *)cmdq->addr.kva;
+
+       memset(rsp, 0, sizeof(struct bfi_msgq_h2i_cmdq_copy_rsp));
+       bfi_h2i_set(rsp->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_CMDQ_COPY_RSP, 0);
+       rsp->mh.mtag.i2htok = htons(cmdq->token);
+       copied = (cmdq->bytes_to_copy >= BFI_CMD_COPY_SZ) ? BFI_CMD_COPY_SZ :
+               cmdq->bytes_to_copy;
+       addr += cmdq->offset;
+       memcpy(rsp->data, addr, copied);
+
+       cmdq->token++;
+       cmdq->offset += copied;
+       cmdq->bytes_to_copy -= copied;
+
+       if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->copy_mb,
+                               bfa_msgq_cmdq_copy_next, cmdq)) {
+               bfa_msgq_cmdq_copy_next(cmdq);
+       }
+}
+
+static void
+bfa_msgq_cmdq_attach(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq *msgq)
+{
+       cmdq->depth = BFA_MSGQ_CMDQ_NUM_ENTRY;
+       INIT_LIST_HEAD(&cmdq->pending_q);
+       cmdq->msgq = msgq;
+       bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
+}
+
+static void bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq);
+
+enum rspq_event {
+       RSPQ_E_START                    = 1,
+       RSPQ_E_STOP                     = 2,
+       RSPQ_E_FAIL                     = 3,
+       RSPQ_E_RESP                     = 4,
+       RSPQ_E_INIT_RESP                = 5,
+       RSPQ_E_DB_READY                 = 6,
+};
+
+bfa_fsm_state_decl(rspq, stopped, struct bfa_msgq_rspq, enum rspq_event);
+bfa_fsm_state_decl(rspq, init_wait, struct bfa_msgq_rspq,
+                       enum rspq_event);
+bfa_fsm_state_decl(rspq, ready, struct bfa_msgq_rspq, enum rspq_event);
+bfa_fsm_state_decl(rspq, dbell_wait, struct bfa_msgq_rspq,
+                       enum rspq_event);
+
+static void
+rspq_sm_stopped_entry(struct bfa_msgq_rspq *rspq)
+{
+       rspq->producer_index = 0;
+       rspq->consumer_index = 0;
+       rspq->flags = 0;
+}
+
+static void
+rspq_sm_stopped(struct bfa_msgq_rspq *rspq, enum rspq_event event)
+{
+       switch (event) {
+       case RSPQ_E_START:
+               bfa_fsm_set_state(rspq, rspq_sm_init_wait);
+               break;
+
+       case RSPQ_E_STOP:
+       case RSPQ_E_FAIL:
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+rspq_sm_init_wait_entry(struct bfa_msgq_rspq *rspq)
+{
+       bfa_wc_down(&rspq->msgq->init_wc);
+}
+
+static void
+rspq_sm_init_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
+{
+       switch (event) {
+       case RSPQ_E_FAIL:
+       case RSPQ_E_STOP:
+               bfa_fsm_set_state(rspq, rspq_sm_stopped);
+               break;
+
+       case RSPQ_E_INIT_RESP:
+               bfa_fsm_set_state(rspq, rspq_sm_ready);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+rspq_sm_ready_entry(struct bfa_msgq_rspq *rspq)
+{
+}
+
+static void
+rspq_sm_ready(struct bfa_msgq_rspq *rspq, enum rspq_event event)
+{
+       switch (event) {
+       case RSPQ_E_STOP:
+       case RSPQ_E_FAIL:
+               bfa_fsm_set_state(rspq, rspq_sm_stopped);
+               break;
+
+       case RSPQ_E_RESP:
+               bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+rspq_sm_dbell_wait_entry(struct bfa_msgq_rspq *rspq)
+{
+       if (!bfa_nw_ioc_is_disabled(rspq->msgq->ioc))
+               bfa_msgq_rspq_dbell(rspq);
+}
+
+static void
+rspq_sm_dbell_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
+{
+       switch (event) {
+       case RSPQ_E_STOP:
+       case RSPQ_E_FAIL:
+               bfa_fsm_set_state(rspq, rspq_sm_stopped);
+               break;
+
+       case RSPQ_E_RESP:
+               rspq->flags |= BFA_MSGQ_RSPQ_F_DB_UPDATE;
+               break;
+
+       case RSPQ_E_DB_READY:
+               if (rspq->flags & BFA_MSGQ_RSPQ_F_DB_UPDATE) {
+                       rspq->flags &= ~BFA_MSGQ_RSPQ_F_DB_UPDATE;
+                       bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
+               } else
+                       bfa_fsm_set_state(rspq, rspq_sm_ready);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bfa_msgq_rspq_dbell_ready(void *arg)
+{
+       struct bfa_msgq_rspq *rspq = (struct bfa_msgq_rspq *)arg;
+       bfa_fsm_send_event(rspq, RSPQ_E_DB_READY);
+}
+
+static void
+bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq)
+{
+       struct bfi_msgq_h2i_db *dbell =
+               (struct bfi_msgq_h2i_db *)(&rspq->dbell_mb.msg[0]);
+
+       memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
+       bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_CI, 0);
+       dbell->mh.mtag.i2htok = 0;
+       dbell->idx.rspq_ci = htons(rspq->consumer_index);
+
+       if (!bfa_nw_ioc_mbox_queue(rspq->msgq->ioc, &rspq->dbell_mb,
+                               bfa_msgq_rspq_dbell_ready, rspq)) {
+               bfa_msgq_rspq_dbell_ready(rspq);
+       }
+}
+
+static void
+bfa_msgq_rspq_pi_update(struct bfa_msgq_rspq *rspq, struct bfi_mbmsg *mb)
+{
+       struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
+       struct bfi_msgq_mhdr *msghdr;
+       int num_entries;
+       int mc;
+       u8 *rspq_qe;
+
+       rspq->producer_index = ntohs(dbell->idx.rspq_pi);
+
+       while (rspq->consumer_index != rspq->producer_index) {
+               rspq_qe = (u8 *)rspq->addr.kva;
+               rspq_qe += (rspq->consumer_index * BFI_MSGQ_RSP_ENTRY_SIZE);
+               msghdr = (struct bfi_msgq_mhdr *)rspq_qe;
+
+               mc = msghdr->msg_class;
+               num_entries = ntohs(msghdr->num_entries);
+
+               if ((mc > BFI_MC_MAX) || (rspq->rsphdlr[mc].cbfn == NULL))
+                       break;
+
+               (rspq->rsphdlr[mc].cbfn)(rspq->rsphdlr[mc].cbarg, msghdr);
+
+               BFA_MSGQ_INDX_ADD(rspq->consumer_index, num_entries,
+                               rspq->depth);
+       }
+
+       bfa_fsm_send_event(rspq, RSPQ_E_RESP);
+}
+
+static void
+bfa_msgq_rspq_attach(struct bfa_msgq_rspq *rspq, struct bfa_msgq *msgq)
+{
+       rspq->depth = BFA_MSGQ_RSPQ_NUM_ENTRY;
+       rspq->msgq = msgq;
+       bfa_fsm_set_state(rspq, rspq_sm_stopped);
+}
+
+static void
+bfa_msgq_init_rsp(struct bfa_msgq *msgq,
+                struct bfi_mbmsg *mb)
+{
+       bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_INIT_RESP);
+       bfa_fsm_send_event(&msgq->rspq, RSPQ_E_INIT_RESP);
+}
+
+static void
+bfa_msgq_init(void *arg)
+{
+       struct bfa_msgq *msgq = (struct bfa_msgq *)arg;
+       struct bfi_msgq_cfg_req *msgq_cfg =
+               (struct bfi_msgq_cfg_req *)&msgq->init_mb.msg[0];
+
+       memset(msgq_cfg, 0, sizeof(struct bfi_msgq_cfg_req));
+       bfi_h2i_set(msgq_cfg->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_INIT_REQ, 0);
+       msgq_cfg->mh.mtag.i2htok = 0;
+
+       bfa_dma_be_addr_set(msgq_cfg->cmdq.addr, msgq->cmdq.addr.pa);
+       msgq_cfg->cmdq.q_depth = htons(msgq->cmdq.depth);
+       bfa_dma_be_addr_set(msgq_cfg->rspq.addr, msgq->rspq.addr.pa);
+       msgq_cfg->rspq.q_depth = htons(msgq->rspq.depth);
+
+       bfa_nw_ioc_mbox_queue(msgq->ioc, &msgq->init_mb, NULL, NULL);
+}
+
+static void
+bfa_msgq_isr(void *cbarg, struct bfi_mbmsg *msg)
+{
+       struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
+
+       switch (msg->mh.msg_id) {
+       case BFI_MSGQ_I2H_INIT_RSP:
+               bfa_msgq_init_rsp(msgq, msg);
+               break;
+
+       case BFI_MSGQ_I2H_DOORBELL_PI:
+               bfa_msgq_rspq_pi_update(&msgq->rspq, msg);
+               break;
+
+       case BFI_MSGQ_I2H_DOORBELL_CI:
+               bfa_msgq_cmdq_ci_update(&msgq->cmdq, msg);
+               break;
+
+       case BFI_MSGQ_I2H_CMDQ_COPY_REQ:
+               bfa_msgq_cmdq_copy_req(&msgq->cmdq, msg);
+               break;
+
+       default:
+               BUG_ON(1);
+       }
+}
+
+static void
+bfa_msgq_notify(void *cbarg, enum bfa_ioc_event event)
+{
+       struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
+
+       switch (event) {
+       case BFA_IOC_E_ENABLED:
+               bfa_wc_init(&msgq->init_wc, bfa_msgq_init, msgq);
+               bfa_wc_up(&msgq->init_wc);
+               bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_START);
+               bfa_wc_up(&msgq->init_wc);
+               bfa_fsm_send_event(&msgq->rspq, RSPQ_E_START);
+               bfa_wc_wait(&msgq->init_wc);
+               break;
+
+       case BFA_IOC_E_DISABLED:
+               bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_STOP);
+               bfa_fsm_send_event(&msgq->rspq, RSPQ_E_STOP);
+               break;
+
+       case BFA_IOC_E_FAILED:
+               bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_FAIL);
+               bfa_fsm_send_event(&msgq->rspq, RSPQ_E_FAIL);
+               break;
+
+       default:
+               break;
+       }
+}
+
+u32
+bfa_msgq_meminfo(void)
+{
+       return roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ) +
+               roundup(BFA_MSGQ_RSPQ_SIZE, BFA_DMA_ALIGN_SZ);
+}
+
+void
+bfa_msgq_memclaim(struct bfa_msgq *msgq, u8 *kva, u64 pa)
+{
+       msgq->cmdq.addr.kva = kva;
+       msgq->cmdq.addr.pa  = pa;
+
+       kva += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
+       pa += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
+
+       msgq->rspq.addr.kva = kva;
+       msgq->rspq.addr.pa = pa;
+}
+
+void
+bfa_msgq_attach(struct bfa_msgq *msgq, struct bfa_ioc *ioc)
+{
+       msgq->ioc    = ioc;
+
+       bfa_msgq_cmdq_attach(&msgq->cmdq, msgq);
+       bfa_msgq_rspq_attach(&msgq->rspq, msgq);
+
+       bfa_nw_ioc_mbox_regisr(msgq->ioc, BFI_MC_MSGQ, bfa_msgq_isr, msgq);
+       bfa_q_qe_init(&msgq->ioc_notify);
+       bfa_ioc_notify_init(&msgq->ioc_notify, bfa_msgq_notify, msgq);
+       bfa_nw_ioc_notify_register(msgq->ioc, &msgq->ioc_notify);
+}
+
+void
+bfa_msgq_regisr(struct bfa_msgq *msgq, enum bfi_mclass mc,
+               bfa_msgq_mcfunc_t cbfn, void *cbarg)
+{
+       msgq->rspq.rsphdlr[mc].cbfn     = cbfn;
+       msgq->rspq.rsphdlr[mc].cbarg    = cbarg;
+}
+
+void
+bfa_msgq_cmd_post(struct bfa_msgq *msgq,  struct bfa_msgq_cmd_entry *cmd)
+{
+       if (ntohs(cmd->msg_hdr->num_entries) <=
+               BFA_MSGQ_FREE_CNT(&msgq->cmdq)) {
+               __cmd_copy(&msgq->cmdq, cmd);
+               call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
+               bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_POST);
+       } else {
+               list_add_tail(&cmd->qe, &msgq->cmdq.pending_q);
+       }
+}
+
+void
+bfa_msgq_rsp_copy(struct bfa_msgq *msgq, u8 *buf, size_t buf_len)
+{
+       struct bfa_msgq_rspq *rspq = &msgq->rspq;
+       size_t len = buf_len;
+       size_t to_copy;
+       int ci;
+       u8 *src, *dst;
+
+       ci = rspq->consumer_index;
+       src = (u8 *)rspq->addr.kva;
+       src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
+       dst = buf;
+
+       while (len) {
+               to_copy = (len < BFI_MSGQ_RSP_ENTRY_SIZE) ?
+                               len : BFI_MSGQ_RSP_ENTRY_SIZE;
+               memcpy(dst, src, to_copy);
+               len -= to_copy;
+               dst += BFI_MSGQ_RSP_ENTRY_SIZE;
+               BFA_MSGQ_INDX_ADD(ci, 1, rspq->depth);
+               src = (u8 *)rspq->addr.kva;
+               src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
+       }
+}
diff --git a/drivers/net/ethernet/brocade/bna/bfa_msgq.h b/drivers/net/ethernet/brocade/bna/bfa_msgq.h
new file mode 100644 (file)
index 0000000..a6a565a
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_MSGQ_H__
+#define __BFA_MSGQ_H__
+
+#include "bfa_defs.h"
+#include "bfi.h"
+#include "bfa_ioc.h"
+#include "bfa_cs.h"
+
+#define BFA_MSGQ_FREE_CNT(_q)                                          \
+       (((_q)->consumer_index - (_q)->producer_index - 1) & ((_q)->depth - 1))
+
+#define BFA_MSGQ_INDX_ADD(_q_indx, _qe_num, _q_depth)                  \
+       ((_q_indx) = (((_q_indx) + (_qe_num)) & ((_q_depth) - 1)))
+
+#define BFA_MSGQ_CMDQ_NUM_ENTRY                128
+#define BFA_MSGQ_CMDQ_SIZE                                             \
+       (BFI_MSGQ_CMD_ENTRY_SIZE * BFA_MSGQ_CMDQ_NUM_ENTRY)
+
+#define BFA_MSGQ_RSPQ_NUM_ENTRY                128
+#define BFA_MSGQ_RSPQ_SIZE                                             \
+       (BFI_MSGQ_RSP_ENTRY_SIZE * BFA_MSGQ_RSPQ_NUM_ENTRY)
+
+#define bfa_msgq_cmd_set(_cmd, _cbfn, _cbarg, _msg_size, _msg_hdr)     \
+do {                                                                   \
+       (_cmd)->cbfn = (_cbfn);                                         \
+       (_cmd)->cbarg = (_cbarg);                                       \
+       (_cmd)->msg_size = (_msg_size);                                 \
+       (_cmd)->msg_hdr = (_msg_hdr);                                   \
+} while (0)
+
+struct bfa_msgq;
+
+typedef void (*bfa_msgq_cmdcbfn_t)(void *cbarg, enum bfa_status status);
+
+struct bfa_msgq_cmd_entry {
+       struct list_head                                qe;
+       bfa_msgq_cmdcbfn_t              cbfn;
+       void                            *cbarg;
+       size_t                          msg_size;
+       struct bfi_msgq_mhdr *msg_hdr;
+};
+
+enum bfa_msgq_cmdq_flags {
+       BFA_MSGQ_CMDQ_F_DB_UPDATE       = 1,
+};
+
+struct bfa_msgq_cmdq {
+       bfa_fsm_t                       fsm;
+       enum bfa_msgq_cmdq_flags flags;
+
+       u16                     producer_index;
+       u16                     consumer_index;
+       u16                     depth; /* FW Q depth is 16 bits */
+       struct bfa_dma addr;
+       struct bfa_mbox_cmd dbell_mb;
+
+       u16                     token;
+       int                             offset;
+       int                             bytes_to_copy;
+       struct bfa_mbox_cmd copy_mb;
+
+       struct list_head                pending_q; /* pending command queue */
+
+       struct bfa_msgq *msgq;
+};
+
+enum bfa_msgq_rspq_flags {
+       BFA_MSGQ_RSPQ_F_DB_UPDATE       = 1,
+};
+
+typedef void (*bfa_msgq_mcfunc_t)(void *cbarg, struct bfi_msgq_mhdr *mhdr);
+
+struct bfa_msgq_rspq {
+       bfa_fsm_t                       fsm;
+       enum bfa_msgq_rspq_flags flags;
+
+       u16                     producer_index;
+       u16                     consumer_index;
+       u16                     depth; /* FW Q depth is 16 bits */
+       struct bfa_dma addr;
+       struct bfa_mbox_cmd dbell_mb;
+
+       int                             nmclass;
+       struct {
+               bfa_msgq_mcfunc_t       cbfn;
+               void                    *cbarg;
+       } rsphdlr[BFI_MC_MAX];
+
+       struct bfa_msgq *msgq;
+};
+
+struct bfa_msgq {
+       struct bfa_msgq_cmdq cmdq;
+       struct bfa_msgq_rspq rspq;
+
+       struct bfa_wc                   init_wc;
+       struct bfa_mbox_cmd init_mb;
+
+       struct bfa_ioc_notify ioc_notify;
+       struct bfa_ioc *ioc;
+};
+
+u32 bfa_msgq_meminfo(void);
+void bfa_msgq_memclaim(struct bfa_msgq *msgq, u8 *kva, u64 pa);
+void bfa_msgq_attach(struct bfa_msgq *msgq, struct bfa_ioc *ioc);
+void bfa_msgq_regisr(struct bfa_msgq *msgq, enum bfi_mclass mc,
+                    bfa_msgq_mcfunc_t cbfn, void *cbarg);
+void bfa_msgq_cmd_post(struct bfa_msgq *msgq,
+                      struct bfa_msgq_cmd_entry *cmd);
+void bfa_msgq_rsp_copy(struct bfa_msgq *msgq, u8 *buf, size_t buf_len);
+
+#endif
similarity index 70%
rename from drivers/net/bna/bfi.h
rename to drivers/net/ethernet/brocade/bna/bfi.h
index 088211c2724fe10b800df4f686af3c561d24a8d1..19654cc7abab0e0a77866ea5e0fa3a4c7fab513f 100644 (file)
@@ -15,7 +15,6 @@
  * All rights reserved
  * www.brocade.com
  */
-
 #ifndef __BFI_H__
 #define __BFI_H__
 
  */
 #define        BFI_FLASH_CHUNK_SZ                      256     /*!< Flash chunk size */
 #define        BFI_FLASH_CHUNK_SZ_WORDS        (BFI_FLASH_CHUNK_SZ/sizeof(u32))
-enum {
-       BFI_IMAGE_CB_FC,
-       BFI_IMAGE_CT_FC,
-       BFI_IMAGE_CT_CNA,
-       BFI_IMAGE_MAX,
-};
 
 /**
  * Msg header common to all msgs
@@ -43,17 +36,21 @@ struct bfi_mhdr {
        u8              msg_id;         /*!< msg opcode with in the class   */
        union {
                struct {
-                       u8      rsvd;
-                       u8      lpu_id; /*!< msg destination                */
+                       u8      qid;
+                       u8      fn_lpu; /*!< msg destination                */
                } h2i;
                u16     i2htok; /*!< token in msgs to host          */
        } mtag;
 };
 
-#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do {                \
+#define bfi_fn_lpu(__fn, __lpu)        ((__fn) << 1 | (__lpu))
+#define bfi_mhdr_2_fn(_mh)     ((_mh)->mtag.h2i.fn_lpu >> 1)
+#define bfi_mhdr_2_qid(_mh)    ((_mh)->mtag.h2i.qid)
+
+#define bfi_h2i_set(_mh, _mc, _op, _fn_lpu) do {               \
        (_mh).msg_class                 = (_mc);                \
        (_mh).msg_id                    = (_op);                \
-       (_mh).mtag.h2i.lpu_id   = (_lpuid);                     \
+       (_mh).mtag.h2i.fn_lpu   = (_fn_lpu);                    \
 } while (0)
 
 #define bfi_i2h_set(_mh, _mc, _op, _i2htok) do {               \
@@ -148,6 +145,14 @@ struct bfi_mbmsg {
        u32             pl[BFI_MBMSG_SZ];
 };
 
+/**
+ * Supported PCI function class codes (personality)
+ */
+enum bfi_pcifn_class {
+       BFI_PCIFN_CLASS_FC      = 0x0c04,
+       BFI_PCIFN_CLASS_ETH     = 0x0200,
+};
+
 /**
  * Message Classes
  */
@@ -183,14 +188,7 @@ enum bfi_mclass {
 #define BFI_IOC_MAX_CQS_ASIC   8
 #define BFI_IOC_MSGLEN_MAX     32      /* 32 bytes */
 
-#define BFI_BOOT_TYPE_OFF              8
-#define BFI_BOOT_LOADER_OFF            12
-
-#define BFI_BOOT_TYPE_NORMAL           0
-#define        BFI_BOOT_TYPE_FLASH             1
-#define        BFI_BOOT_TYPE_MEMTEST           2
-
-#define BFI_BOOT_LOADER_OS             0
+#define BFI_FWBOOT_ENV_OS              0
 
 #define BFI_BOOT_MEMTEST_RES_ADDR   0x900
 #define BFI_BOOT_MEMTEST_RES_SIG    0xA0A1A2A3
@@ -201,6 +199,21 @@ enum bfi_mclass {
  *----------------------------------------------------------------------
  */
 
+/**
+ * Different asic generations
+ */
+enum bfi_asic_gen {
+       BFI_ASIC_GEN_CB         = 1,
+       BFI_ASIC_GEN_CT         = 2,
+};
+
+enum bfi_asic_mode {
+       BFI_ASIC_MODE_FC        = 1,    /* FC upto 8G speed             */
+       BFI_ASIC_MODE_FC16      = 2,    /* FC upto 16G speed            */
+       BFI_ASIC_MODE_ETH       = 3,    /* Ethernet ports               */
+       BFI_ASIC_MODE_COMBO     = 4,    /* FC 16G and Ethernet 10G port */
+};
+
 enum bfi_ioc_h2i_msgs {
        BFI_IOC_H2I_ENABLE_REQ          = 1,
        BFI_IOC_H2I_DISABLE_REQ         = 2,
@@ -213,8 +226,7 @@ enum bfi_ioc_i2h_msgs {
        BFI_IOC_I2H_ENABLE_REPLY        = BFA_I2HM(1),
        BFI_IOC_I2H_DISABLE_REPLY       = BFA_I2HM(2),
        BFI_IOC_I2H_GETATTR_REPLY       = BFA_I2HM(3),
-       BFI_IOC_I2H_READY_EVENT         = BFA_I2HM(4),
-       BFI_IOC_I2H_HBEAT               = BFA_I2HM(5),
+       BFI_IOC_I2H_HBEAT               = BFA_I2HM(4),
 };
 
 /**
@@ -229,7 +241,8 @@ struct bfi_ioc_attr {
        u64             mfg_pwwn;       /*!< Mfg port wwn          */
        u64             mfg_nwwn;       /*!< Mfg node wwn          */
        mac_t           mfg_mac;        /*!< Mfg mac               */
-       u16     rsvd_a;
+       u8              port_mode;      /* enum bfi_port_mode      */
+       u8              rsvd_a;
        u64             pwwn;
        u64             nwwn;
        mac_t           mac;            /*!< PBC or Mfg mac        */
@@ -282,28 +295,39 @@ struct bfi_ioc_getattr_reply {
 #define BFI_IOC_MD5SUM_SZ      4
 struct bfi_ioc_image_hdr {
        u32     signature;      /*!< constant signature */
-       u32     rsvd_a;
+       u8      asic_gen;       /*!< asic generation */
+       u8      asic_mode;
+       u8      port0_mode;     /*!< device mode for port 0 */
+       u8      port1_mode;     /*!< device mode for port 1 */
        u32     exec;           /*!< exec vector        */
-       u32     param;          /*!< parameters         */
+       u32     bootenv;        /*!< firmware boot env */
        u32     rsvd_b[4];
        u32     md5sum[BFI_IOC_MD5SUM_SZ];
 };
 
+#define BFI_FWBOOT_DEVMODE_OFF         4
+#define BFI_FWBOOT_TYPE_OFF            8
+#define BFI_FWBOOT_ENV_OFF             12
+#define BFI_FWBOOT_DEVMODE(__asic_gen, __asic_mode, __p0_mode, __p1_mode) \
+       (((u32)(__asic_gen)) << 24 |    \
+        ((u32)(__asic_mode)) << 16 |   \
+        ((u32)(__p0_mode)) << 8 |      \
+        ((u32)(__p1_mode)))
+
 enum bfi_fwboot_type {
        BFI_FWBOOT_TYPE_NORMAL  = 0,
        BFI_FWBOOT_TYPE_FLASH   = 1,
        BFI_FWBOOT_TYPE_MEMTEST = 2,
 };
 
+enum bfi_port_mode {
+       BFI_PORT_MODE_FC        = 1,
+       BFI_PORT_MODE_ETH       = 2,
+};
+
 /**
  *  BFI_IOC_I2H_READY_EVENT message
  */
-struct bfi_ioc_rdy_event {
-       struct bfi_mhdr mh;             /*!< common msg header */
-       u8                      init_status;    /*!< init event status */
-       u8                      rsvd[3];
-};
-
 struct bfi_ioc_hbeat {
        struct bfi_mhdr mh;             /*!< common msg header          */
        u32        hb_count;    /*!< current heart beat count   */
@@ -360,8 +384,8 @@ enum {
  */
 struct bfi_ioc_ctrl_req {
        struct bfi_mhdr mh;
-       u8                      ioc_class;
-       u8                      rsvd[3];
+       u16                     clscode;
+       u16                     rsvd;
        u32             tv_sec;
 };
 
@@ -369,9 +393,11 @@ struct bfi_ioc_ctrl_req {
  * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
  */
 struct bfi_ioc_ctrl_reply {
-       struct bfi_mhdr mh;             /*!< Common msg header     */
+       struct bfi_mhdr mh;                     /*!< Common msg header     */
        u8                      status;         /*!< enable/disable status */
-       u8                      rsvd[3];
+       u8                      port_mode;      /*!< enum bfa_mode */
+       u8                      cap_bm;         /*!< capability bit mask */
+       u8                      rsvd;
 };
 
 #define BFI_IOC_MSGSZ   8
@@ -391,10 +417,109 @@ union bfi_ioc_h2i_msg_u {
  */
 union bfi_ioc_i2h_msg_u {
        struct bfi_mhdr mh;
-       struct bfi_ioc_rdy_event rdy_event;
+       struct bfi_ioc_ctrl_reply fw_event;
        u32                     mboxmsg[BFI_IOC_MSGSZ];
 };
 
+/**
+ *----------------------------------------------------------------------
+ *                             MSGQ
+ *----------------------------------------------------------------------
+ */
+
+enum bfi_msgq_h2i_msgs {
+       BFI_MSGQ_H2I_INIT_REQ      = 1,
+       BFI_MSGQ_H2I_DOORBELL_PI        = 2,
+       BFI_MSGQ_H2I_DOORBELL_CI        = 3,
+       BFI_MSGQ_H2I_CMDQ_COPY_RSP      = 4,
+};
+
+enum bfi_msgq_i2h_msgs {
+       BFI_MSGQ_I2H_INIT_RSP      = BFA_I2HM(BFI_MSGQ_H2I_INIT_REQ),
+       BFI_MSGQ_I2H_DOORBELL_PI        = BFA_I2HM(BFI_MSGQ_H2I_DOORBELL_PI),
+       BFI_MSGQ_I2H_DOORBELL_CI        = BFA_I2HM(BFI_MSGQ_H2I_DOORBELL_CI),
+       BFI_MSGQ_I2H_CMDQ_COPY_REQ      = BFA_I2HM(BFI_MSGQ_H2I_CMDQ_COPY_RSP),
+};
+
+/* Messages(commands/responsed/AENS will have the following header */
+struct bfi_msgq_mhdr {
+       u8      msg_class;
+       u8      msg_id;
+       u16     msg_token;
+       u16     num_entries;
+       u8      enet_id;
+       u8      rsvd[1];
+};
+
+#define bfi_msgq_mhdr_set(_mh, _mc, _mid, _tok, _enet_id) do { \
+       (_mh).msg_class  = (_mc);       \
+       (_mh).msg_id        = (_mid);       \
+       (_mh).msg_token  = (_tok);       \
+       (_mh).enet_id      = (_enet_id);   \
+} while (0)
+
+/*
+ * Mailbox  for messaging interface
+ */
+#define BFI_MSGQ_CMD_ENTRY_SIZE         (64)    /* TBD */
+#define BFI_MSGQ_RSP_ENTRY_SIZE         (64)    /* TBD */
+
+#define bfi_msgq_num_cmd_entries(_size)                                 \
+       (((_size) + BFI_MSGQ_CMD_ENTRY_SIZE - 1) / BFI_MSGQ_CMD_ENTRY_SIZE)
+
+struct bfi_msgq {
+       union bfi_addr_u addr;
+       u16 q_depth;     /* Total num of entries in the queue */
+       u8 rsvd[2];
+};
+
+/* BFI_ENET_MSGQ_CFG_REQ TBD init or cfg? */
+struct bfi_msgq_cfg_req {
+       struct bfi_mhdr mh;
+       struct bfi_msgq cmdq;
+       struct bfi_msgq rspq;
+};
+
+/* BFI_ENET_MSGQ_CFG_RSP */
+struct bfi_msgq_cfg_rsp {
+       struct bfi_mhdr mh;
+       u8 cmd_status;
+       u8 rsvd[3];
+};
+
+/* BFI_MSGQ_H2I_DOORBELL */
+struct bfi_msgq_h2i_db {
+       struct bfi_mhdr mh;
+       union {
+               u16 cmdq_pi;
+               u16 rspq_ci;
+       } idx;
+};
+
+/* BFI_MSGQ_I2H_DOORBELL */
+struct bfi_msgq_i2h_db {
+       struct bfi_mhdr mh;
+       union {
+               u16 rspq_pi;
+               u16 cmdq_ci;
+       } idx;
+};
+
+#define BFI_CMD_COPY_SZ 28
+
+/* BFI_MSGQ_H2I_CMD_COPY_RSP */
+struct bfi_msgq_h2i_cmdq_copy_rsp {
+       struct bfi_mhdr mh;
+       u8            data[BFI_CMD_COPY_SZ];
+};
+
+/* BFI_MSGQ_I2H_CMD_COPY_REQ */
+struct bfi_msgq_i2h_cmdq_copy_req {
+       struct bfi_mhdr mh;
+       u16     offset;
+       u16     len;
+};
+
 #pragma pack()
 
 #endif /* __BFI_H__ */
diff --git a/drivers/net/ethernet/brocade/bna/bfi_enet.h b/drivers/net/ethernet/brocade/bna/bfi_enet.h
new file mode 100644 (file)
index 0000000..a90f1cf
--- /dev/null
@@ -0,0 +1,901 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * @file bfi_enet.h BNA Hardware and Firmware Interface
+ */
+
+/**
+ * Skipping statistics collection to avoid clutter.
+ * Command is no longer needed:
+ *     MTU
+ *     TxQ Stop
+ *     RxQ Stop
+ *     RxF Enable/Disable
+ *
+ * HDS-off request is dynamic
+ * keep structures as multiple of 32-bit fields for alignment.
+ * All values must be written in big-endian.
+ */
+#ifndef __BFI_ENET_H__
+#define __BFI_ENET_H__
+
+#include "bfa_defs.h"
+#include "bfi.h"
+
+#pragma pack(1)
+
+#define BFI_ENET_CFG_MAX               32      /* Max resources per PF */
+
+#define BFI_ENET_TXQ_PRIO_MAX          8
+#define BFI_ENET_RX_QSET_MAX           16
+#define BFI_ENET_TXQ_WI_VECT_MAX       4
+
+#define BFI_ENET_VLAN_ID_MAX           4096
+#define BFI_ENET_VLAN_BLOCK_SIZE       512     /* in bits */
+#define BFI_ENET_VLAN_BLOCKS_MAX                                       \
+       (BFI_ENET_VLAN_ID_MAX / BFI_ENET_VLAN_BLOCK_SIZE)
+#define BFI_ENET_VLAN_WORD_SIZE                32      /* in bits */
+#define BFI_ENET_VLAN_WORDS_MAX                                                \
+       (BFI_ENET_VLAN_BLOCK_SIZE / BFI_ENET_VLAN_WORD_SIZE)
+
+#define BFI_ENET_RSS_RIT_MAX           64      /* entries */
+#define BFI_ENET_RSS_KEY_LEN           10      /* 32-bit words */
+
+union bfi_addr_be_u {
+       struct {
+               u32     addr_hi;        /* Most Significant 32-bits */
+               u32     addr_lo;        /* Least Significant 32-Bits */
+       } a32;
+};
+
+/**
+ *     T X   Q U E U E   D E F I N E S
+ */
+/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */
+/* TxQ Entry Opcodes */
+#define BFI_ENET_TXQ_WI_SEND           (0x402) /* Single Frame Transmission */
+#define BFI_ENET_TXQ_WI_SEND_LSO       (0x403) /* Multi-Frame Transmission */
+#define BFI_ENET_TXQ_WI_EXTENSION      (0x104) /* Extension WI */
+
+/* TxQ Entry Control Flags */
+#define BFI_ENET_TXQ_WI_CF_FCOE_CRC    (1 << 8)
+#define BFI_ENET_TXQ_WI_CF_IPID_MODE   (1 << 5)
+#define BFI_ENET_TXQ_WI_CF_INS_PRIO    (1 << 4)
+#define BFI_ENET_TXQ_WI_CF_INS_VLAN    (1 << 3)
+#define BFI_ENET_TXQ_WI_CF_UDP_CKSUM   (1 << 2)
+#define BFI_ENET_TXQ_WI_CF_TCP_CKSUM   (1 << 1)
+#define BFI_ENET_TXQ_WI_CF_IP_CKSUM    (1 << 0)
+
+struct bfi_enet_txq_wi_base {
+       u8                      reserved;
+       u8                      num_vectors;    /* number of vectors present */
+       u16                     opcode;
+                       /* BFI_ENET_TXQ_WI_SEND or BFI_ENET_TXQ_WI_SEND_LSO */
+       u16                     flags;          /* OR of all the flags */
+       u16                     l4_hdr_size_n_offset;
+       u16                     vlan_tag;
+       u16                     lso_mss;        /* Only 14 LSB are valid */
+       u32                     frame_length;   /* Only 24 LSB are valid */
+};
+
+struct bfi_enet_txq_wi_ext {
+       u16                     reserved;
+       u16                     opcode;         /* BFI_ENET_TXQ_WI_EXTENSION */
+       u32                     reserved2[3];
+};
+
+struct bfi_enet_txq_wi_vector {                        /* Tx Buffer Descriptor */
+       u16                     reserved;
+       u16                     length;         /* Only 14 LSB are valid */
+       union bfi_addr_be_u     addr;
+};
+
+/**
+ *  TxQ Entry Structure
+ *
+ */
+struct bfi_enet_txq_entry {
+       union {
+               struct bfi_enet_txq_wi_base     base;
+               struct bfi_enet_txq_wi_ext      ext;
+       } wi;
+       struct bfi_enet_txq_wi_vector vector[BFI_ENET_TXQ_WI_VECT_MAX];
+};
+
+#define wi_hdr         wi.base
+#define wi_ext_hdr     wi.ext
+
+#define BFI_ENET_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \
+               (((_hdr_size) << 10) | ((_offset) & 0x3FF))
+
+/**
+ *   R X   Q U E U E   D E F I N E S
+ */
+struct bfi_enet_rxq_entry {
+       union bfi_addr_be_u  rx_buffer;
+};
+
+/**
+ *   R X   C O M P L E T I O N   Q U E U E   D E F I N E S
+ */
+/* CQ Entry Flags */
+#define        BFI_ENET_CQ_EF_MAC_ERROR        (1 <<  0)
+#define        BFI_ENET_CQ_EF_FCS_ERROR        (1 <<  1)
+#define        BFI_ENET_CQ_EF_TOO_LONG         (1 <<  2)
+#define        BFI_ENET_CQ_EF_FC_CRC_OK        (1 <<  3)
+
+#define        BFI_ENET_CQ_EF_RSVD1            (1 <<  4)
+#define        BFI_ENET_CQ_EF_L4_CKSUM_OK      (1 <<  5)
+#define        BFI_ENET_CQ_EF_L3_CKSUM_OK      (1 <<  6)
+#define        BFI_ENET_CQ_EF_HDS_HEADER       (1 <<  7)
+
+#define        BFI_ENET_CQ_EF_UDP              (1 <<  8)
+#define        BFI_ENET_CQ_EF_TCP              (1 <<  9)
+#define        BFI_ENET_CQ_EF_IP_OPTIONS       (1 << 10)
+#define        BFI_ENET_CQ_EF_IPV6             (1 << 11)
+
+#define        BFI_ENET_CQ_EF_IPV4             (1 << 12)
+#define        BFI_ENET_CQ_EF_VLAN             (1 << 13)
+#define        BFI_ENET_CQ_EF_RSS              (1 << 14)
+#define        BFI_ENET_CQ_EF_RSVD2            (1 << 15)
+
+#define        BFI_ENET_CQ_EF_MCAST_MATCH      (1 << 16)
+#define        BFI_ENET_CQ_EF_MCAST            (1 << 17)
+#define BFI_ENET_CQ_EF_BCAST           (1 << 18)
+#define        BFI_ENET_CQ_EF_REMOTE           (1 << 19)
+
+#define        BFI_ENET_CQ_EF_LOCAL            (1 << 20)
+
+/* CQ Entry Structure */
+struct bfi_enet_cq_entry {
+       u32 flags;
+       u16     vlan_tag;
+       u16     length;
+       u32     rss_hash;
+       u8      valid;
+       u8      reserved1;
+       u8      reserved2;
+       u8      rxq_id;
+};
+
+/**
+ *   E N E T   C O N T R O L   P A T H   C O M M A N D S
+ */
+struct bfi_enet_q {
+       union bfi_addr_u        pg_tbl;
+       union bfi_addr_u        first_entry;
+       u16             pages;  /* # of pages */
+       u16             page_sz;
+};
+
+struct bfi_enet_txq {
+       struct bfi_enet_q       q;
+       u8                      priority;
+       u8                      rsvd[3];
+};
+
+struct bfi_enet_rxq {
+       struct bfi_enet_q       q;
+       u16             rx_buffer_size;
+       u16             rsvd;
+};
+
+struct bfi_enet_cq {
+       struct bfi_enet_q       q;
+};
+
+struct bfi_enet_ib_cfg {
+       u8              int_pkt_dma;
+       u8              int_enabled;
+       u8              int_pkt_enabled;
+       u8              continuous_coalescing;
+       u8              msix;
+       u8              rsvd[3];
+       u32     coalescing_timeout;
+       u32     inter_pkt_timeout;
+       u8              inter_pkt_count;
+       u8              rsvd1[3];
+};
+
+struct bfi_enet_ib {
+       union bfi_addr_u        index_addr;
+       union {
+               u16     msix_index;
+               u16     intx_bitmask;
+       } intr;
+       u16             rsvd;
+};
+
+/**
+ * ENET command messages
+ */
+enum bfi_enet_h2i_msgs {
+       /* Rx Commands */
+       BFI_ENET_H2I_RX_CFG_SET_REQ = 1,
+       BFI_ENET_H2I_RX_CFG_CLR_REQ = 2,
+
+       BFI_ENET_H2I_RIT_CFG_REQ = 3,
+       BFI_ENET_H2I_RSS_CFG_REQ = 4,
+       BFI_ENET_H2I_RSS_ENABLE_REQ = 5,
+       BFI_ENET_H2I_RX_PROMISCUOUS_REQ = 6,
+       BFI_ENET_H2I_RX_DEFAULT_REQ = 7,
+
+       BFI_ENET_H2I_MAC_UCAST_SET_REQ = 8,
+       BFI_ENET_H2I_MAC_UCAST_CLR_REQ = 9,
+       BFI_ENET_H2I_MAC_UCAST_ADD_REQ = 10,
+       BFI_ENET_H2I_MAC_UCAST_DEL_REQ = 11,
+
+       BFI_ENET_H2I_MAC_MCAST_ADD_REQ = 12,
+       BFI_ENET_H2I_MAC_MCAST_DEL_REQ = 13,
+       BFI_ENET_H2I_MAC_MCAST_FILTER_REQ = 14,
+
+       BFI_ENET_H2I_RX_VLAN_SET_REQ = 15,
+       BFI_ENET_H2I_RX_VLAN_STRIP_ENABLE_REQ = 16,
+
+       /* Tx Commands */
+       BFI_ENET_H2I_TX_CFG_SET_REQ = 17,
+       BFI_ENET_H2I_TX_CFG_CLR_REQ = 18,
+
+       /* Port Commands */
+       BFI_ENET_H2I_PORT_ADMIN_UP_REQ = 19,
+       BFI_ENET_H2I_SET_PAUSE_REQ = 20,
+       BFI_ENET_H2I_DIAG_LOOPBACK_REQ = 21,
+
+       /* Get Attributes Command */
+       BFI_ENET_H2I_GET_ATTR_REQ = 22,
+
+       /*  Statistics Commands */
+       BFI_ENET_H2I_STATS_GET_REQ = 23,
+       BFI_ENET_H2I_STATS_CLR_REQ = 24,
+
+       BFI_ENET_H2I_WOL_MAGIC_REQ = 25,
+       BFI_ENET_H2I_WOL_FRAME_REQ = 26,
+
+       BFI_ENET_H2I_MAX = 27,
+};
+
+enum bfi_enet_i2h_msgs {
+       /* Rx Responses */
+       BFI_ENET_I2H_RX_CFG_SET_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RX_CFG_SET_REQ),
+       BFI_ENET_I2H_RX_CFG_CLR_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RX_CFG_CLR_REQ),
+
+       BFI_ENET_I2H_RIT_CFG_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RIT_CFG_REQ),
+       BFI_ENET_I2H_RSS_CFG_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RSS_CFG_REQ),
+       BFI_ENET_I2H_RSS_ENABLE_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RSS_ENABLE_REQ),
+       BFI_ENET_I2H_RX_PROMISCUOUS_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RX_PROMISCUOUS_REQ),
+       BFI_ENET_I2H_RX_DEFAULT_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RX_DEFAULT_REQ),
+
+       BFI_ENET_I2H_MAC_UCAST_SET_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_UCAST_SET_REQ),
+       BFI_ENET_I2H_MAC_UCAST_CLR_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_UCAST_CLR_REQ),
+       BFI_ENET_I2H_MAC_UCAST_ADD_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_UCAST_ADD_REQ),
+       BFI_ENET_I2H_MAC_UCAST_DEL_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_UCAST_DEL_REQ),
+
+       BFI_ENET_I2H_MAC_MCAST_ADD_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_MCAST_ADD_REQ),
+       BFI_ENET_I2H_MAC_MCAST_DEL_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_MCAST_DEL_REQ),
+       BFI_ENET_I2H_MAC_MCAST_FILTER_RSP =
+               BFA_I2HM(BFI_ENET_H2I_MAC_MCAST_FILTER_REQ),
+
+       BFI_ENET_I2H_RX_VLAN_SET_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RX_VLAN_SET_REQ),
+
+       BFI_ENET_I2H_RX_VLAN_STRIP_ENABLE_RSP =
+               BFA_I2HM(BFI_ENET_H2I_RX_VLAN_STRIP_ENABLE_REQ),
+
+       /* Tx Responses */
+       BFI_ENET_I2H_TX_CFG_SET_RSP =
+               BFA_I2HM(BFI_ENET_H2I_TX_CFG_SET_REQ),
+       BFI_ENET_I2H_TX_CFG_CLR_RSP =
+               BFA_I2HM(BFI_ENET_H2I_TX_CFG_CLR_REQ),
+
+       /* Port Responses */
+       BFI_ENET_I2H_PORT_ADMIN_RSP =
+               BFA_I2HM(BFI_ENET_H2I_PORT_ADMIN_UP_REQ),
+
+       BFI_ENET_I2H_SET_PAUSE_RSP =
+               BFA_I2HM(BFI_ENET_H2I_SET_PAUSE_REQ),
+       BFI_ENET_I2H_DIAG_LOOPBACK_RSP =
+               BFA_I2HM(BFI_ENET_H2I_DIAG_LOOPBACK_REQ),
+
+       /*  Attributes Response */
+       BFI_ENET_I2H_GET_ATTR_RSP =
+               BFA_I2HM(BFI_ENET_H2I_GET_ATTR_REQ),
+
+       /* Statistics Responses */
+       BFI_ENET_I2H_STATS_GET_RSP =
+               BFA_I2HM(BFI_ENET_H2I_STATS_GET_REQ),
+       BFI_ENET_I2H_STATS_CLR_RSP =
+               BFA_I2HM(BFI_ENET_H2I_STATS_CLR_REQ),
+
+       BFI_ENET_I2H_WOL_MAGIC_RSP =
+               BFA_I2HM(BFI_ENET_H2I_WOL_MAGIC_REQ),
+       BFI_ENET_I2H_WOL_FRAME_RSP =
+               BFA_I2HM(BFI_ENET_H2I_WOL_FRAME_REQ),
+
+       /* AENs */
+       BFI_ENET_I2H_LINK_DOWN_AEN = BFA_I2HM(BFI_ENET_H2I_MAX),
+       BFI_ENET_I2H_LINK_UP_AEN = BFA_I2HM(BFI_ENET_H2I_MAX + 1),
+
+       BFI_ENET_I2H_PORT_ENABLE_AEN = BFA_I2HM(BFI_ENET_H2I_MAX + 2),
+       BFI_ENET_I2H_PORT_DISABLE_AEN = BFA_I2HM(BFI_ENET_H2I_MAX + 3),
+
+       BFI_ENET_I2H_BW_UPDATE_AEN = BFA_I2HM(BFI_ENET_H2I_MAX + 4),
+};
+
+/**
+ *  The following error codes can be returned by the enet commands
+ */
+enum bfi_enet_err {
+       BFI_ENET_CMD_OK         = 0,
+       BFI_ENET_CMD_FAIL       = 1,
+       BFI_ENET_CMD_DUP_ENTRY  = 2,    /* !< Duplicate entry in CAM */
+       BFI_ENET_CMD_CAM_FULL   = 3,    /* !< CAM is full */
+       BFI_ENET_CMD_NOT_OWNER  = 4,    /* !< Not permitted, b'cos not owner */
+       BFI_ENET_CMD_NOT_EXEC   = 5,    /* !< Was not sent to f/w at all */
+       BFI_ENET_CMD_WAITING    = 6,    /* !< Waiting for completion */
+       BFI_ENET_CMD_PORT_DISABLED = 7, /* !< port in disabled state */
+};
+
+/**
+ * Generic Request
+ *
+ * bfi_enet_req is used by:
+ *     BFI_ENET_H2I_RX_CFG_CLR_REQ
+ *     BFI_ENET_H2I_TX_CFG_CLR_REQ
+ */
+struct bfi_enet_req {
+       struct bfi_msgq_mhdr mh;
+};
+
+/**
+ * Enable/Disable Request
+ *
+ * bfi_enet_enable_req is used by:
+ *     BFI_ENET_H2I_RSS_ENABLE_REQ     (enet_id must be zero)
+ *     BFI_ENET_H2I_RX_PROMISCUOUS_REQ (enet_id must be zero)
+ *     BFI_ENET_H2I_RX_DEFAULT_REQ     (enet_id must be zero)
+ *     BFI_ENET_H2I_RX_MAC_MCAST_FILTER_REQ
+ *     BFI_ENET_H2I_PORT_ADMIN_UP_REQ  (enet_id must be zero)
+ */
+struct bfi_enet_enable_req {
+       struct          bfi_msgq_mhdr mh;
+       u8              enable;         /* 1 = enable;  0 = disable */
+       u8              rsvd[3];
+};
+
+/**
+ * Generic Response
+ */
+struct bfi_enet_rsp {
+       struct bfi_msgq_mhdr mh;
+       u8              error;          /*!< if error see cmd_offset */
+       u8              rsvd;
+       u16             cmd_offset;     /*!< offset to invalid parameter */
+};
+
+/**
+ * GLOBAL CONFIGURATION
+ */
+
+/**
+ * bfi_enet_attr_req is used by:
+ *     BFI_ENET_H2I_GET_ATTR_REQ
+ */
+struct bfi_enet_attr_req {
+       struct bfi_msgq_mhdr    mh;
+};
+
+/**
+ * bfi_enet_attr_rsp is used by:
+ *     BFI_ENET_I2H_GET_ATTR_RSP
+ */
+struct bfi_enet_attr_rsp {
+       struct bfi_msgq_mhdr mh;
+       u8              error;          /*!< if error see cmd_offset */
+       u8              rsvd;
+       u16             cmd_offset;     /*!< offset to invalid parameter */
+       u32             max_cfg;
+       u32             max_ucmac;
+       u32             rit_size;
+};
+
+/**
+ * Tx Configuration
+ *
+ * bfi_enet_tx_cfg is used by:
+ *     BFI_ENET_H2I_TX_CFG_SET_REQ
+ */
+enum bfi_enet_tx_vlan_mode {
+       BFI_ENET_TX_VLAN_NOP    = 0,
+       BFI_ENET_TX_VLAN_INS    = 1,
+       BFI_ENET_TX_VLAN_WI     = 2,
+};
+
+struct bfi_enet_tx_cfg {
+       u8              vlan_mode;      /*!< processing mode */
+       u8              rsvd;
+       u16             vlan_id;
+       u8              admit_tagged_frame;
+       u8              apply_vlan_filter;
+       u8              add_to_vswitch;
+       u8              rsvd1[1];
+};
+
+struct bfi_enet_tx_cfg_req {
+       struct bfi_msgq_mhdr mh;
+       u8                      num_queues;     /* # of Tx Queues */
+       u8                      rsvd[3];
+
+       struct {
+               struct bfi_enet_txq     q;
+               struct bfi_enet_ib      ib;
+       } q_cfg[BFI_ENET_TXQ_PRIO_MAX];
+
+       struct bfi_enet_ib_cfg  ib_cfg;
+
+       struct bfi_enet_tx_cfg  tx_cfg;
+};
+
+struct bfi_enet_tx_cfg_rsp {
+       struct          bfi_msgq_mhdr mh;
+       u8              error;
+       u8              hw_id;          /* For debugging */
+       u8              rsvd[2];
+       struct {
+               u32     q_dbell;        /* PCI base address offset */
+               u32     i_dbell;        /* PCI base address offset */
+               u8      hw_qid;         /* For debugging */
+               u8      rsvd[3];
+       } q_handles[BFI_ENET_TXQ_PRIO_MAX];
+};
+
+/**
+ * Rx Configuration
+ *
+ * bfi_enet_rx_cfg is used by:
+ *     BFI_ENET_H2I_RX_CFG_SET_REQ
+ */
+enum bfi_enet_rxq_type {
+       BFI_ENET_RXQ_SINGLE             = 1,
+       BFI_ENET_RXQ_LARGE_SMALL        = 2,
+       BFI_ENET_RXQ_HDS                = 3,
+       BFI_ENET_RXQ_HDS_OPT_BASED      = 4,
+};
+
+enum bfi_enet_hds_type {
+       BFI_ENET_HDS_FORCED     = 0x01,
+       BFI_ENET_HDS_IPV6_UDP   = 0x02,
+       BFI_ENET_HDS_IPV6_TCP   = 0x04,
+       BFI_ENET_HDS_IPV4_TCP   = 0x08,
+       BFI_ENET_HDS_IPV4_UDP   = 0x10,
+};
+
+struct bfi_enet_rx_cfg {
+       u8              rxq_type;
+       u8              rsvd[3];
+
+       struct {
+               u8                      max_header_size;
+               u8                      force_offset;
+               u8                      type;
+               u8                      rsvd1;
+       } hds;
+
+       u8              multi_buffer;
+       u8              strip_vlan;
+       u8              drop_untagged;
+       u8              rsvd2;
+};
+
+/*
+ * Multicast frames are received on the ql of q-set index zero.
+ * On the completion queue.  RxQ ID = even is for large/data buffer queues
+ * and RxQ ID = odd is for small/header buffer queues.
+ */
+struct bfi_enet_rx_cfg_req {
+       struct bfi_msgq_mhdr mh;
+       u8                      num_queue_sets; /* # of Rx Queue Sets */
+       u8                      rsvd[3];
+
+       struct {
+               struct bfi_enet_rxq     ql;     /* large/data/single buffers */
+               struct bfi_enet_rxq     qs;     /* small/header buffers */
+               struct bfi_enet_cq      cq;
+               struct bfi_enet_ib      ib;
+       } q_cfg[BFI_ENET_RX_QSET_MAX];
+
+       struct bfi_enet_ib_cfg  ib_cfg;
+
+       struct bfi_enet_rx_cfg  rx_cfg;
+};
+
+struct bfi_enet_rx_cfg_rsp {
+       struct bfi_msgq_mhdr mh;
+       u8              error;
+       u8              hw_id;   /* For debugging */
+       u8              rsvd[2];
+       struct {
+               u32     ql_dbell; /* PCI base address offset */
+               u32     qs_dbell; /* PCI base address offset */
+               u32     i_dbell;  /* PCI base address offset */
+               u8              hw_lqid;  /* For debugging */
+               u8              hw_sqid;  /* For debugging */
+               u8              hw_cqid;  /* For debugging */
+               u8              rsvd;
+       } q_handles[BFI_ENET_RX_QSET_MAX];
+};
+
+/**
+ * RIT
+ *
+ * bfi_enet_rit_req is used by:
+ *     BFI_ENET_H2I_RIT_CFG_REQ
+ */
+struct bfi_enet_rit_req {
+       struct  bfi_msgq_mhdr mh;
+       u16     size;                   /* number of table-entries used */
+       u8      rsvd[2];
+       u8      table[BFI_ENET_RSS_RIT_MAX];
+};
+
+/**
+ * RSS
+ *
+ * bfi_enet_rss_cfg_req is used by:
+ *     BFI_ENET_H2I_RSS_CFG_REQ
+ */
+enum bfi_enet_rss_type {
+       BFI_ENET_RSS_IPV6       = 0x01,
+       BFI_ENET_RSS_IPV6_TCP   = 0x02,
+       BFI_ENET_RSS_IPV4       = 0x04,
+       BFI_ENET_RSS_IPV4_TCP   = 0x08
+};
+
+struct bfi_enet_rss_cfg {
+       u8      type;
+       u8      mask;
+       u8      rsvd[2];
+       u32     key[BFI_ENET_RSS_KEY_LEN];
+};
+
+struct bfi_enet_rss_cfg_req {
+       struct bfi_msgq_mhdr    mh;
+       struct bfi_enet_rss_cfg cfg;
+};
+
+/**
+ * MAC Unicast
+ *
+ * bfi_enet_rx_vlan_req is used by:
+ *     BFI_ENET_H2I_MAC_UCAST_SET_REQ
+ *     BFI_ENET_H2I_MAC_UCAST_CLR_REQ
+ *     BFI_ENET_H2I_MAC_UCAST_ADD_REQ
+ *     BFI_ENET_H2I_MAC_UCAST_DEL_REQ
+ */
+struct bfi_enet_ucast_req {
+       struct bfi_msgq_mhdr    mh;
+       mac_t                   mac_addr;
+       u8                      rsvd[2];
+};
+
+/**
+ * MAC Unicast + VLAN
+ */
+struct bfi_enet_mac_n_vlan_req {
+       struct bfi_msgq_mhdr    mh;
+       u16                     vlan_id;
+       mac_t                   mac_addr;
+};
+
+/**
+ * MAC Multicast
+ *
+ * bfi_enet_mac_mfilter_add_req is used by:
+ *     BFI_ENET_H2I_MAC_MCAST_ADD_REQ
+ */
+struct bfi_enet_mcast_add_req {
+       struct bfi_msgq_mhdr    mh;
+       mac_t                   mac_addr;
+       u8                      rsvd[2];
+};
+
+/**
+ * bfi_enet_mac_mfilter_add_rsp is used by:
+ *     BFI_ENET_I2H_MAC_MCAST_ADD_RSP
+ */
+struct bfi_enet_mcast_add_rsp {
+       struct bfi_msgq_mhdr    mh;
+       u8                      error;
+       u8                      rsvd;
+       u16                     cmd_offset;
+       u16                     handle;
+       u8                      rsvd1[2];
+};
+
+/**
+ * bfi_enet_mac_mfilter_del_req is used by:
+ *     BFI_ENET_H2I_MAC_MCAST_DEL_REQ
+ */
+struct bfi_enet_mcast_del_req {
+       struct bfi_msgq_mhdr    mh;
+       u16                     handle;
+       u8                      rsvd[2];
+};
+
+/**
+ * VLAN
+ *
+ * bfi_enet_rx_vlan_req is used by:
+ *     BFI_ENET_H2I_RX_VLAN_SET_REQ
+ */
+struct bfi_enet_rx_vlan_req {
+       struct bfi_msgq_mhdr    mh;
+       u8                      block_idx;
+       u8                      rsvd[3];
+       u32                     bit_mask[BFI_ENET_VLAN_WORDS_MAX];
+};
+
+/**
+ * PAUSE
+ *
+ * bfi_enet_set_pause_req is used by:
+ *     BFI_ENET_H2I_SET_PAUSE_REQ
+ */
+struct bfi_enet_set_pause_req {
+       struct bfi_msgq_mhdr    mh;
+       u8                      rsvd[2];
+       u8                      tx_pause;       /* 1 = enable;  0 = disable */
+       u8                      rx_pause;       /* 1 = enable;  0 = disable */
+};
+
+/**
+ * DIAGNOSTICS
+ *
+ * bfi_enet_diag_lb_req is used by:
+ *      BFI_ENET_H2I_DIAG_LOOPBACK
+ */
+struct bfi_enet_diag_lb_req {
+       struct bfi_msgq_mhdr    mh;
+       u8                      rsvd[2];
+       u8                      mode;           /* cable or Serdes */
+       u8                      enable;         /* 1 = enable;  0 = disable */
+};
+
+/**
+ * enum for Loopback opmodes
+ */
+enum {
+       BFI_ENET_DIAG_LB_OPMODE_EXT = 0,
+       BFI_ENET_DIAG_LB_OPMODE_CBL = 1,
+};
+
+/**
+ * STATISTICS
+ *
+ * bfi_enet_stats_req is used by:
+ *    BFI_ENET_H2I_STATS_GET_REQ
+ *    BFI_ENET_I2H_STATS_CLR_REQ
+ */
+struct bfi_enet_stats_req {
+       struct bfi_msgq_mhdr    mh;
+       u16                     stats_mask;
+       u8                      rsvd[2];
+       u32                     rx_enet_mask;
+       u32                     tx_enet_mask;
+       union bfi_addr_u        host_buffer;
+};
+
+/**
+ * defines for "stats_mask" above.
+ */
+#define BFI_ENET_STATS_MAC    (1 << 0)    /* !< MAC Statistics */
+#define BFI_ENET_STATS_BPC    (1 << 1)    /* !< Pause Stats from BPC */
+#define BFI_ENET_STATS_RAD    (1 << 2)    /* !< Rx Admission Statistics */
+#define BFI_ENET_STATS_RX_FC  (1 << 3)    /* !< Rx FC Stats from RxA */
+#define BFI_ENET_STATS_TX_FC  (1 << 4)    /* !< Tx FC Stats from TxA */
+
+#define BFI_ENET_STATS_ALL    0x1f
+
+/* TxF Frame Statistics */
+struct bfi_enet_stats_txf {
+       u64 ucast_octets;
+       u64 ucast;
+       u64 ucast_vlan;
+
+       u64 mcast_octets;
+       u64 mcast;
+       u64 mcast_vlan;
+
+       u64 bcast_octets;
+       u64 bcast;
+       u64 bcast_vlan;
+
+       u64 errors;
+       u64 filter_vlan;      /* frames filtered due to VLAN */
+       u64 filter_mac_sa;    /* frames filtered due to SA check */
+};
+
+/* RxF Frame Statistics */
+struct bfi_enet_stats_rxf {
+       u64 ucast_octets;
+       u64 ucast;
+       u64 ucast_vlan;
+
+       u64 mcast_octets;
+       u64 mcast;
+       u64 mcast_vlan;
+
+       u64 bcast_octets;
+       u64 bcast;
+       u64 bcast_vlan;
+       u64 frame_drops;
+};
+
+/* FC Tx Frame Statistics */
+struct bfi_enet_stats_fc_tx {
+       u64 txf_ucast_octets;
+       u64 txf_ucast;
+       u64 txf_ucast_vlan;
+
+       u64 txf_mcast_octets;
+       u64 txf_mcast;
+       u64 txf_mcast_vlan;
+
+       u64 txf_bcast_octets;
+       u64 txf_bcast;
+       u64 txf_bcast_vlan;
+
+       u64 txf_parity_errors;
+       u64 txf_timeout;
+       u64 txf_fid_parity_errors;
+};
+
+/* FC Rx Frame Statistics */
+struct bfi_enet_stats_fc_rx {
+       u64 rxf_ucast_octets;
+       u64 rxf_ucast;
+       u64 rxf_ucast_vlan;
+
+       u64 rxf_mcast_octets;
+       u64 rxf_mcast;
+       u64 rxf_mcast_vlan;
+
+       u64 rxf_bcast_octets;
+       u64 rxf_bcast;
+       u64 rxf_bcast_vlan;
+};
+
+/* RAD Frame Statistics */
+struct bfi_enet_stats_rad {
+       u64 rx_frames;
+       u64 rx_octets;
+       u64 rx_vlan_frames;
+
+       u64 rx_ucast;
+       u64 rx_ucast_octets;
+       u64 rx_ucast_vlan;
+
+       u64 rx_mcast;
+       u64 rx_mcast_octets;
+       u64 rx_mcast_vlan;
+
+       u64 rx_bcast;
+       u64 rx_bcast_octets;
+       u64 rx_bcast_vlan;
+
+       u64 rx_drops;
+};
+
+/* BPC Tx Registers */
+struct bfi_enet_stats_bpc {
+       /* transmit stats */
+       u64 tx_pause[8];
+       u64 tx_zero_pause[8];   /*!< Pause cancellation */
+       /*!<Pause initiation rather than retention */
+       u64 tx_first_pause[8];
+
+       /* receive stats */
+       u64 rx_pause[8];
+       u64 rx_zero_pause[8];   /*!< Pause cancellation */
+       /*!<Pause initiation rather than retention */
+       u64 rx_first_pause[8];
+};
+
+/* MAC Rx Statistics */
+struct bfi_enet_stats_mac {
+       u64 frame_64;           /* both rx and tx counter */
+       u64 frame_65_127;               /* both rx and tx counter */
+       u64 frame_128_255;              /* both rx and tx counter */
+       u64 frame_256_511;              /* both rx and tx counter */
+       u64 frame_512_1023;     /* both rx and tx counter */
+       u64 frame_1024_1518;    /* both rx and tx counter */
+       u64 frame_1519_1522;    /* both rx and tx counter */
+
+       /* receive stats */
+       u64 rx_bytes;
+       u64 rx_packets;
+       u64 rx_fcs_error;
+       u64 rx_multicast;
+       u64 rx_broadcast;
+       u64 rx_control_frames;
+       u64 rx_pause;
+       u64 rx_unknown_opcode;
+       u64 rx_alignment_error;
+       u64 rx_frame_length_error;
+       u64 rx_code_error;
+       u64 rx_carrier_sense_error;
+       u64 rx_undersize;
+       u64 rx_oversize;
+       u64 rx_fragments;
+       u64 rx_jabber;
+       u64 rx_drop;
+
+       /* transmit stats */
+       u64 tx_bytes;
+       u64 tx_packets;
+       u64 tx_multicast;
+       u64 tx_broadcast;
+       u64 tx_pause;
+       u64 tx_deferral;
+       u64 tx_excessive_deferral;
+       u64 tx_single_collision;
+       u64 tx_muliple_collision;
+       u64 tx_late_collision;
+       u64 tx_excessive_collision;
+       u64 tx_total_collision;
+       u64 tx_pause_honored;
+       u64 tx_drop;
+       u64 tx_jabber;
+       u64 tx_fcs_error;
+       u64 tx_control_frame;
+       u64 tx_oversize;
+       u64 tx_undersize;
+       u64 tx_fragments;
+};
+
+/**
+ * Complete statistics, DMAed from fw to host followed by
+ * BFI_ENET_I2H_STATS_GET_RSP
+ */
+struct bfi_enet_stats {
+       struct bfi_enet_stats_mac       mac_stats;
+       struct bfi_enet_stats_bpc       bpc_stats;
+       struct bfi_enet_stats_rad       rad_stats;
+       struct bfi_enet_stats_rad       rlb_stats;
+       struct bfi_enet_stats_fc_rx     fc_rx_stats;
+       struct bfi_enet_stats_fc_tx     fc_tx_stats;
+       struct bfi_enet_stats_rxf       rxf_stats[BFI_ENET_CFG_MAX];
+       struct bfi_enet_stats_txf       txf_stats[BFI_ENET_CFG_MAX];
+};
+
+#pragma pack()
+
+#endif  /* __BFI_ENET_H__ */
diff --git a/drivers/net/ethernet/brocade/bna/bfi_reg.h b/drivers/net/ethernet/brocade/bna/bfi_reg.h
new file mode 100644 (file)
index 0000000..efacff3
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/*
+ * bfi_reg.h ASIC register defines for all Brocade adapter ASICs
+ */
+
+#ifndef __BFI_REG_H__
+#define __BFI_REG_H__
+
+#define HOSTFN0_INT_STATUS             0x00014000      /* cb/ct        */
+#define HOSTFN1_INT_STATUS             0x00014100      /* cb/ct        */
+#define HOSTFN2_INT_STATUS             0x00014300      /* ct           */
+#define HOSTFN3_INT_STATUS             0x00014400      /* ct           */
+#define HOSTFN0_INT_MSK                        0x00014004      /* cb/ct        */
+#define HOSTFN1_INT_MSK                        0x00014104      /* cb/ct        */
+#define HOSTFN2_INT_MSK                        0x00014304      /* ct           */
+#define HOSTFN3_INT_MSK                        0x00014404      /* ct           */
+
+#define HOST_PAGE_NUM_FN0              0x00014008      /* cb/ct        */
+#define HOST_PAGE_NUM_FN1              0x00014108      /* cb/ct        */
+#define HOST_PAGE_NUM_FN2              0x00014308      /* ct           */
+#define HOST_PAGE_NUM_FN3              0x00014408      /* ct           */
+
+#define APP_PLL_LCLK_CTL_REG           0x00014204      /* cb/ct        */
+#define __P_LCLK_PLL_LOCK              0x80000000
+#define __APP_PLL_LCLK_SRAM_USE_100MHZ 0x00100000
+#define __APP_PLL_LCLK_RESET_TIMER_MK  0x000e0000
+#define __APP_PLL_LCLK_RESET_TIMER_SH  17
+#define __APP_PLL_LCLK_RESET_TIMER(_v) ((_v) << __APP_PLL_LCLK_RESET_TIMER_SH)
+#define __APP_PLL_LCLK_LOGIC_SOFT_RESET        0x00010000
+#define __APP_PLL_LCLK_CNTLMT0_1_MK    0x0000c000
+#define __APP_PLL_LCLK_CNTLMT0_1_SH    14
+#define __APP_PLL_LCLK_CNTLMT0_1(_v)   ((_v) << __APP_PLL_LCLK_CNTLMT0_1_SH)
+#define __APP_PLL_LCLK_JITLMT0_1_MK    0x00003000
+#define __APP_PLL_LCLK_JITLMT0_1_SH    12
+#define __APP_PLL_LCLK_JITLMT0_1(_v)   ((_v) << __APP_PLL_LCLK_JITLMT0_1_SH)
+#define __APP_PLL_LCLK_HREF            0x00000800
+#define __APP_PLL_LCLK_HDIV            0x00000400
+#define __APP_PLL_LCLK_P0_1_MK         0x00000300
+#define __APP_PLL_LCLK_P0_1_SH         8
+#define __APP_PLL_LCLK_P0_1(_v)                ((_v) << __APP_PLL_LCLK_P0_1_SH)
+#define __APP_PLL_LCLK_Z0_2_MK         0x000000e0
+#define __APP_PLL_LCLK_Z0_2_SH         5
+#define __APP_PLL_LCLK_Z0_2(_v)                ((_v) << __APP_PLL_LCLK_Z0_2_SH)
+#define __APP_PLL_LCLK_RSEL200500      0x00000010
+#define __APP_PLL_LCLK_ENARST          0x00000008
+#define __APP_PLL_LCLK_BYPASS          0x00000004
+#define __APP_PLL_LCLK_LRESETN         0x00000002
+#define __APP_PLL_LCLK_ENABLE          0x00000001
+#define APP_PLL_SCLK_CTL_REG           0x00014208      /* cb/ct        */
+#define __P_SCLK_PLL_LOCK              0x80000000
+#define __APP_PLL_SCLK_RESET_TIMER_MK  0x000e0000
+#define __APP_PLL_SCLK_RESET_TIMER_SH  17
+#define __APP_PLL_SCLK_RESET_TIMER(_v) ((_v) << __APP_PLL_SCLK_RESET_TIMER_SH)
+#define __APP_PLL_SCLK_LOGIC_SOFT_RESET        0x00010000
+#define __APP_PLL_SCLK_CNTLMT0_1_MK    0x0000c000
+#define __APP_PLL_SCLK_CNTLMT0_1_SH    14
+#define __APP_PLL_SCLK_CNTLMT0_1(_v)   ((_v) << __APP_PLL_SCLK_CNTLMT0_1_SH)
+#define __APP_PLL_SCLK_JITLMT0_1_MK    0x00003000
+#define __APP_PLL_SCLK_JITLMT0_1_SH    12
+#define __APP_PLL_SCLK_JITLMT0_1(_v)   ((_v) << __APP_PLL_SCLK_JITLMT0_1_SH)
+#define __APP_PLL_SCLK_HREF            0x00000800
+#define __APP_PLL_SCLK_HDIV            0x00000400
+#define __APP_PLL_SCLK_P0_1_MK         0x00000300
+#define __APP_PLL_SCLK_P0_1_SH         8
+#define __APP_PLL_SCLK_P0_1(_v)                ((_v) << __APP_PLL_SCLK_P0_1_SH)
+#define __APP_PLL_SCLK_Z0_2_MK         0x000000e0
+#define __APP_PLL_SCLK_Z0_2_SH         5
+#define __APP_PLL_SCLK_Z0_2(_v)                ((_v) << __APP_PLL_SCLK_Z0_2_SH)
+#define __APP_PLL_SCLK_RSEL200500      0x00000010
+#define __APP_PLL_SCLK_ENARST          0x00000008
+#define __APP_PLL_SCLK_BYPASS          0x00000004
+#define __APP_PLL_SCLK_LRESETN         0x00000002
+#define __APP_PLL_SCLK_ENABLE          0x00000001
+#define __ENABLE_MAC_AHB_1             0x00800000      /* ct           */
+#define __ENABLE_MAC_AHB_0             0x00400000      /* ct           */
+#define __ENABLE_MAC_1                 0x00200000      /* ct           */
+#define __ENABLE_MAC_0                 0x00100000      /* ct           */
+
+#define HOST_SEM0_REG                  0x00014230      /* cb/ct        */
+#define HOST_SEM1_REG                  0x00014234      /* cb/ct        */
+#define HOST_SEM2_REG                  0x00014238      /* cb/ct        */
+#define HOST_SEM3_REG                  0x0001423c      /* cb/ct        */
+#define HOST_SEM4_REG                  0x00014610      /* cb/ct        */
+#define HOST_SEM5_REG                  0x00014614      /* cb/ct        */
+#define HOST_SEM6_REG                  0x00014618      /* cb/ct        */
+#define HOST_SEM7_REG                  0x0001461c      /* cb/ct        */
+#define HOST_SEM0_INFO_REG             0x00014240      /* cb/ct        */
+#define HOST_SEM1_INFO_REG             0x00014244      /* cb/ct        */
+#define HOST_SEM2_INFO_REG             0x00014248      /* cb/ct        */
+#define HOST_SEM3_INFO_REG             0x0001424c      /* cb/ct        */
+#define HOST_SEM4_INFO_REG             0x00014620      /* cb/ct        */
+#define HOST_SEM5_INFO_REG             0x00014624      /* cb/ct        */
+#define HOST_SEM6_INFO_REG             0x00014628      /* cb/ct        */
+#define HOST_SEM7_INFO_REG             0x0001462c      /* cb/ct        */
+
+#define HOSTFN0_LPU0_CMD_STAT          0x00019000      /* cb/ct        */
+#define HOSTFN0_LPU1_CMD_STAT          0x00019004      /* cb/ct        */
+#define HOSTFN1_LPU0_CMD_STAT          0x00019010      /* cb/ct        */
+#define HOSTFN1_LPU1_CMD_STAT          0x00019014      /* cb/ct        */
+#define HOSTFN2_LPU0_CMD_STAT          0x00019150      /* ct           */
+#define HOSTFN2_LPU1_CMD_STAT          0x00019154      /* ct           */
+#define HOSTFN3_LPU0_CMD_STAT          0x00019160      /* ct           */
+#define HOSTFN3_LPU1_CMD_STAT          0x00019164      /* ct           */
+#define LPU0_HOSTFN0_CMD_STAT          0x00019008      /* cb/ct        */
+#define LPU1_HOSTFN0_CMD_STAT          0x0001900c      /* cb/ct        */
+#define LPU0_HOSTFN1_CMD_STAT          0x00019018      /* cb/ct        */
+#define LPU1_HOSTFN1_CMD_STAT          0x0001901c      /* cb/ct        */
+#define LPU0_HOSTFN2_CMD_STAT          0x00019158      /* ct           */
+#define LPU1_HOSTFN2_CMD_STAT          0x0001915c      /* ct           */
+#define LPU0_HOSTFN3_CMD_STAT          0x00019168      /* ct           */
+#define LPU1_HOSTFN3_CMD_STAT          0x0001916c      /* ct           */
+
+#define PSS_CTL_REG                    0x00018800      /* cb/ct        */
+#define __PSS_I2C_CLK_DIV_MK           0x007f0000
+#define __PSS_I2C_CLK_DIV_SH           16
+#define __PSS_I2C_CLK_DIV(_v)          ((_v) << __PSS_I2C_CLK_DIV_SH)
+#define __PSS_LMEM_INIT_DONE           0x00001000
+#define __PSS_LMEM_RESET               0x00000200
+#define __PSS_LMEM_INIT_EN             0x00000100
+#define __PSS_LPU1_RESET               0x00000002
+#define __PSS_LPU0_RESET               0x00000001
+#define PSS_ERR_STATUS_REG             0x00018810      /* cb/ct        */
+#define ERR_SET_REG                    0x00018818      /* cb/ct        */
+#define PSS_GPIO_OUT_REG               0x000188c0      /* cb/ct        */
+#define __PSS_GPIO_OUT_REG             0x00000fff
+#define PSS_GPIO_OE_REG                        0x000188c8      /* cb/ct        */
+#define __PSS_GPIO_OE_REG              0x000000ff
+
+#define HOSTFN0_LPU_MBOX0_0            0x00019200      /* cb/ct        */
+#define HOSTFN1_LPU_MBOX0_8            0x00019260      /* cb/ct        */
+#define LPU_HOSTFN0_MBOX0_0            0x00019280      /* cb/ct        */
+#define LPU_HOSTFN1_MBOX0_8            0x000192e0      /* cb/ct        */
+#define HOSTFN2_LPU_MBOX0_0            0x00019400      /* ct           */
+#define HOSTFN3_LPU_MBOX0_8            0x00019460      /* ct           */
+#define LPU_HOSTFN2_MBOX0_0            0x00019480      /* ct           */
+#define LPU_HOSTFN3_MBOX0_8            0x000194e0      /* ct           */
+
+#define HOST_MSIX_ERR_INDEX_FN0                0x0001400c      /* ct           */
+#define HOST_MSIX_ERR_INDEX_FN1                0x0001410c      /* ct           */
+#define HOST_MSIX_ERR_INDEX_FN2                0x0001430c      /* ct           */
+#define HOST_MSIX_ERR_INDEX_FN3                0x0001440c      /* ct           */
+
+#define MBIST_CTL_REG                  0x00014220      /* ct           */
+#define __EDRAM_BISTR_START            0x00000004
+#define MBIST_STAT_REG                 0x00014224      /* ct           */
+#define ETH_MAC_SER_REG                        0x00014288      /* ct           */
+#define __APP_EMS_CKBUFAMPIN           0x00000020
+#define __APP_EMS_REFCLKSEL            0x00000010
+#define __APP_EMS_CMLCKSEL             0x00000008
+#define __APP_EMS_REFCKBUFEN2          0x00000004
+#define __APP_EMS_REFCKBUFEN1          0x00000002
+#define __APP_EMS_CHANNEL_SEL          0x00000001
+#define FNC_PERS_REG                   0x00014604      /* ct           */
+#define __F3_FUNCTION_ACTIVE           0x80000000
+#define __F3_FUNCTION_MODE             0x40000000
+#define __F3_PORT_MAP_MK               0x30000000
+#define __F3_PORT_MAP_SH               28
+#define __F3_PORT_MAP(_v)              ((_v) << __F3_PORT_MAP_SH)
+#define __F3_VM_MODE                   0x08000000
+#define __F3_INTX_STATUS_MK            0x07000000
+#define __F3_INTX_STATUS_SH            24
+#define __F3_INTX_STATUS(_v)           ((_v) << __F3_INTX_STATUS_SH)
+#define __F2_FUNCTION_ACTIVE           0x00800000
+#define __F2_FUNCTION_MODE             0x00400000
+#define __F2_PORT_MAP_MK               0x00300000
+#define __F2_PORT_MAP_SH               20
+#define __F2_PORT_MAP(_v)              ((_v) << __F2_PORT_MAP_SH)
+#define __F2_VM_MODE                   0x00080000
+#define __F2_INTX_STATUS_MK            0x00070000
+#define __F2_INTX_STATUS_SH            16
+#define __F2_INTX_STATUS(_v)           ((_v) << __F2_INTX_STATUS_SH)
+#define __F1_FUNCTION_ACTIVE           0x00008000
+#define __F1_FUNCTION_MODE             0x00004000
+#define __F1_PORT_MAP_MK               0x00003000
+#define __F1_PORT_MAP_SH               12
+#define __F1_PORT_MAP(_v)              ((_v) << __F1_PORT_MAP_SH)
+#define __F1_VM_MODE                   0x00000800
+#define __F1_INTX_STATUS_MK            0x00000700
+#define __F1_INTX_STATUS_SH            8
+#define __F1_INTX_STATUS(_v)           ((_v) << __F1_INTX_STATUS_SH)
+#define __F0_FUNCTION_ACTIVE           0x00000080
+#define __F0_FUNCTION_MODE             0x00000040
+#define __F0_PORT_MAP_MK               0x00000030
+#define __F0_PORT_MAP_SH               4
+#define __F0_PORT_MAP(_v)              ((_v) << __F0_PORT_MAP_SH)
+#define __F0_VM_MODE                   0x00000008
+#define __F0_INTX_STATUS               0x00000007
+enum {
+       __F0_INTX_STATUS_MSIX = 0x0,
+       __F0_INTX_STATUS_INTA = 0x1,
+       __F0_INTX_STATUS_INTB = 0x2,
+       __F0_INTX_STATUS_INTC = 0x3,
+       __F0_INTX_STATUS_INTD = 0x4,
+};
+
+#define OP_MODE                                0x0001460c
+#define __APP_ETH_CLK_LOWSPEED         0x00000004
+#define __GLOBAL_CORECLK_HALFSPEED     0x00000002
+#define __GLOBAL_FCOE_MODE             0x00000001
+#define FW_INIT_HALT_P0                        0x000191ac
+#define __FW_INIT_HALT_P               0x00000001
+#define FW_INIT_HALT_P1                        0x000191bc
+#define PMM_1T_RESET_REG_P0            0x0002381c
+#define __PMM_1T_RESET_P               0x00000001
+#define PMM_1T_RESET_REG_P1            0x00023c1c
+
+/**
+ * Brocade 1860 Adapter specific defines
+ */
+#define CT2_PCI_CPQ_BASE               0x00030000
+#define CT2_PCI_APP_BASE               0x00030100
+#define CT2_PCI_ETH_BASE               0x00030400
+
+/*
+ * APP block registers
+ */
+#define CT2_HOSTFN_INT_STATUS          (CT2_PCI_APP_BASE + 0x00)
+#define CT2_HOSTFN_INTR_MASK           (CT2_PCI_APP_BASE + 0x04)
+#define CT2_HOSTFN_PERSONALITY0                (CT2_PCI_APP_BASE + 0x08)
+#define __PME_STATUS_                  0x00200000
+#define __PF_VF_BAR_SIZE_MODE__MK      0x00180000
+#define __PF_VF_BAR_SIZE_MODE__SH      19
+#define __PF_VF_BAR_SIZE_MODE_(_v)     ((_v) << __PF_VF_BAR_SIZE_MODE__SH)
+#define __FC_LL_PORT_MAP__MK           0x00060000
+#define __FC_LL_PORT_MAP__SH           17
+#define __FC_LL_PORT_MAP_(_v)          ((_v) << __FC_LL_PORT_MAP__SH)
+#define __PF_VF_ACTIVE_                        0x00010000
+#define __PF_VF_CFG_RDY_               0x00008000
+#define __PF_VF_ENABLE_                        0x00004000
+#define __PF_DRIVER_ACTIVE_            0x00002000
+#define __PF_PME_SEND_ENABLE_          0x00001000
+#define __PF_EXROM_OFFSET__MK          0x00000ff0
+#define __PF_EXROM_OFFSET__SH          4
+#define __PF_EXROM_OFFSET_(_v)         ((_v) << __PF_EXROM_OFFSET__SH)
+#define __FC_LL_MODE_                  0x00000008
+#define __PF_INTX_PIN_                 0x00000007
+#define CT2_HOSTFN_PERSONALITY1                (CT2_PCI_APP_BASE + 0x0C)
+#define __PF_NUM_QUEUES1__MK           0xff000000
+#define __PF_NUM_QUEUES1__SH           24
+#define __PF_NUM_QUEUES1_(_v)          ((_v) << __PF_NUM_QUEUES1__SH)
+#define __PF_VF_QUE_OFFSET1__MK                0x00ff0000
+#define __PF_VF_QUE_OFFSET1__SH                16
+#define __PF_VF_QUE_OFFSET1_(_v)       ((_v) << __PF_VF_QUE_OFFSET1__SH)
+#define __PF_VF_NUM_QUEUES__MK         0x0000ff00
+#define __PF_VF_NUM_QUEUES__SH         8
+#define __PF_VF_NUM_QUEUES_(_v)                ((_v) << __PF_VF_NUM_QUEUES__SH)
+#define __PF_VF_QUE_OFFSET_            0x000000ff
+#define CT2_HOSTFN_PAGE_NUM            (CT2_PCI_APP_BASE + 0x18)
+#define CT2_HOSTFN_MSIX_VT_INDEX_MBOX_ERR      (CT2_PCI_APP_BASE + 0x38)
+
+/*
+ * Brocade 1860 adapter CPQ block registers
+ */
+#define CT2_HOSTFN_LPU0_MBOX0          (CT2_PCI_CPQ_BASE + 0x00)
+#define CT2_HOSTFN_LPU1_MBOX0          (CT2_PCI_CPQ_BASE + 0x20)
+#define CT2_LPU0_HOSTFN_MBOX0          (CT2_PCI_CPQ_BASE + 0x40)
+#define CT2_LPU1_HOSTFN_MBOX0          (CT2_PCI_CPQ_BASE + 0x60)
+#define CT2_HOSTFN_LPU0_CMD_STAT       (CT2_PCI_CPQ_BASE + 0x80)
+#define CT2_HOSTFN_LPU1_CMD_STAT       (CT2_PCI_CPQ_BASE + 0x84)
+#define CT2_LPU0_HOSTFN_CMD_STAT       (CT2_PCI_CPQ_BASE + 0x88)
+#define CT2_LPU1_HOSTFN_CMD_STAT       (CT2_PCI_CPQ_BASE + 0x8c)
+#define CT2_HOSTFN_LPU0_READ_STAT      (CT2_PCI_CPQ_BASE + 0x90)
+#define CT2_HOSTFN_LPU1_READ_STAT      (CT2_PCI_CPQ_BASE + 0x94)
+#define CT2_LPU0_HOSTFN_MBOX0_MSK      (CT2_PCI_CPQ_BASE + 0x98)
+#define CT2_LPU1_HOSTFN_MBOX0_MSK      (CT2_PCI_CPQ_BASE + 0x9C)
+#define CT2_HOST_SEM0_REG              0x000148f0
+#define CT2_HOST_SEM1_REG              0x000148f4
+#define CT2_HOST_SEM2_REG              0x000148f8
+#define CT2_HOST_SEM3_REG              0x000148fc
+#define CT2_HOST_SEM4_REG              0x00014900
+#define CT2_HOST_SEM5_REG              0x00014904
+#define CT2_HOST_SEM6_REG              0x00014908
+#define CT2_HOST_SEM7_REG              0x0001490c
+#define CT2_HOST_SEM0_INFO_REG         0x000148b0
+#define CT2_HOST_SEM1_INFO_REG         0x000148b4
+#define CT2_HOST_SEM2_INFO_REG         0x000148b8
+#define CT2_HOST_SEM3_INFO_REG         0x000148bc
+#define CT2_HOST_SEM4_INFO_REG         0x000148c0
+#define CT2_HOST_SEM5_INFO_REG         0x000148c4
+#define CT2_HOST_SEM6_INFO_REG         0x000148c8
+#define CT2_HOST_SEM7_INFO_REG         0x000148cc
+
+#define CT2_APP_PLL_LCLK_CTL_REG       0x00014808
+#define __APP_LPUCLK_HALFSPEED         0x40000000
+#define __APP_PLL_LCLK_LOAD            0x20000000
+#define __APP_PLL_LCLK_FBCNT_MK                0x1fe00000
+#define __APP_PLL_LCLK_FBCNT_SH                21
+#define __APP_PLL_LCLK_FBCNT(_v)       ((_v) << __APP_PLL_SCLK_FBCNT_SH)
+enum {
+       __APP_PLL_LCLK_FBCNT_425_MHZ = 6,
+       __APP_PLL_LCLK_FBCNT_468_MHZ = 4,
+};
+#define __APP_PLL_LCLK_EXTFB           0x00000800
+#define __APP_PLL_LCLK_ENOUTS          0x00000400
+#define __APP_PLL_LCLK_RATE            0x00000010
+#define CT2_APP_PLL_SCLK_CTL_REG       0x0001480c
+#define __P_SCLK_PLL_LOCK              0x80000000
+#define __APP_PLL_SCLK_REFCLK_SEL      0x40000000
+#define __APP_PLL_SCLK_CLK_DIV2                0x20000000
+#define __APP_PLL_SCLK_LOAD            0x10000000
+#define __APP_PLL_SCLK_FBCNT_MK                0x0ff00000
+#define __APP_PLL_SCLK_FBCNT_SH                20
+#define __APP_PLL_SCLK_FBCNT(_v)       ((_v) << __APP_PLL_SCLK_FBCNT_SH)
+enum {
+       __APP_PLL_SCLK_FBCNT_NORM = 6,
+       __APP_PLL_SCLK_FBCNT_10G_FC = 10,
+};
+#define __APP_PLL_SCLK_EXTFB           0x00000800
+#define __APP_PLL_SCLK_ENOUTS          0x00000400
+#define __APP_PLL_SCLK_RATE            0x00000010
+#define CT2_PCIE_MISC_REG              0x00014804
+#define __ETH_CLK_ENABLE_PORT1         0x00000010
+#define CT2_CHIP_MISC_PRG              0x000148a4
+#define __ETH_CLK_ENABLE_PORT0         0x00004000
+#define __APP_LPU_SPEED                        0x00000002
+#define CT2_MBIST_STAT_REG             0x00014818
+#define CT2_MBIST_CTL_REG              0x0001481c
+#define CT2_PMM_1T_CONTROL_REG_P0      0x0002381c
+#define __PMM_1T_PNDB_P                        0x00000002
+#define CT2_PMM_1T_CONTROL_REG_P1      0x00023c1c
+#define CT2_WGN_STATUS                 0x00014990
+#define __A2T_AHB_LOAD                 0x00000800
+#define __WGN_READY                    0x00000400
+#define __GLBL_PF_VF_CFG_RDY           0x00000200
+#define CT2_NFC_CSR_SET_REG            0x00027424
+#define __HALT_NFC_CONTROLLER          0x00000002
+#define __NFC_CONTROLLER_HALTED                0x00001000
+
+#define CT2_CSI_MAC0_CONTROL_REG       0x000270d0
+#define __CSI_MAC_RESET                        0x00000010
+#define __CSI_MAC_AHB_RESET            0x00000008
+#define CT2_CSI_MAC1_CONTROL_REG       0x000270d4
+#define CT2_CSI_MAC_CONTROL_REG(__n) \
+       (CT2_CSI_MAC0_CONTROL_REG + \
+       (__n) * (CT2_CSI_MAC1_CONTROL_REG - CT2_CSI_MAC0_CONTROL_REG))
+
+/*
+ * Name semaphore registers based on usage
+ */
+#define BFA_IOC0_HBEAT_REG             HOST_SEM0_INFO_REG
+#define BFA_IOC0_STATE_REG             HOST_SEM1_INFO_REG
+#define BFA_IOC1_HBEAT_REG             HOST_SEM2_INFO_REG
+#define BFA_IOC1_STATE_REG             HOST_SEM3_INFO_REG
+#define BFA_FW_USE_COUNT               HOST_SEM4_INFO_REG
+#define BFA_IOC_FAIL_SYNC              HOST_SEM5_INFO_REG
+
+/*
+ * CT2 semaphore register locations changed
+ */
+#define CT2_BFA_IOC0_HBEAT_REG         CT2_HOST_SEM0_INFO_REG
+#define CT2_BFA_IOC0_STATE_REG         CT2_HOST_SEM1_INFO_REG
+#define CT2_BFA_IOC1_HBEAT_REG         CT2_HOST_SEM2_INFO_REG
+#define CT2_BFA_IOC1_STATE_REG         CT2_HOST_SEM3_INFO_REG
+#define CT2_BFA_FW_USE_COUNT           CT2_HOST_SEM4_INFO_REG
+#define CT2_BFA_IOC_FAIL_SYNC          CT2_HOST_SEM5_INFO_REG
+
+#define CPE_Q_NUM(__fn, __q)   (((__fn) << 2) + (__q))
+#define RME_Q_NUM(__fn, __q)   (((__fn) << 2) + (__q))
+
+/*
+ * And corresponding host interrupt status bit field defines
+ */
+#define __HFN_INT_CPE_Q0       0x00000001U
+#define __HFN_INT_CPE_Q1       0x00000002U
+#define __HFN_INT_CPE_Q2       0x00000004U
+#define __HFN_INT_CPE_Q3       0x00000008U
+#define __HFN_INT_CPE_Q4       0x00000010U
+#define __HFN_INT_CPE_Q5       0x00000020U
+#define __HFN_INT_CPE_Q6       0x00000040U
+#define __HFN_INT_CPE_Q7       0x00000080U
+#define __HFN_INT_RME_Q0       0x00000100U
+#define __HFN_INT_RME_Q1       0x00000200U
+#define __HFN_INT_RME_Q2       0x00000400U
+#define __HFN_INT_RME_Q3       0x00000800U
+#define __HFN_INT_RME_Q4       0x00001000U
+#define __HFN_INT_RME_Q5       0x00002000U
+#define __HFN_INT_RME_Q6       0x00004000U
+#define __HFN_INT_RME_Q7       0x00008000U
+#define __HFN_INT_ERR_EMC      0x00010000U
+#define __HFN_INT_ERR_LPU0     0x00020000U
+#define __HFN_INT_ERR_LPU1     0x00040000U
+#define __HFN_INT_ERR_PSS      0x00080000U
+#define __HFN_INT_MBOX_LPU0    0x00100000U
+#define __HFN_INT_MBOX_LPU1    0x00200000U
+#define __HFN_INT_MBOX1_LPU0   0x00400000U
+#define __HFN_INT_MBOX1_LPU1   0x00800000U
+#define __HFN_INT_LL_HALT      0x01000000U
+#define __HFN_INT_CPE_MASK     0x000000ffU
+#define __HFN_INT_RME_MASK     0x0000ff00U
+#define __HFN_INT_ERR_MASK     \
+       (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | \
+        __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT)
+#define __HFN_INT_FN0_MASK     \
+       (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | __HFN_INT_CPE_Q2 | \
+        __HFN_INT_CPE_Q3 | __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 | \
+        __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 | __HFN_INT_MBOX_LPU0)
+#define __HFN_INT_FN1_MASK     \
+       (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 | __HFN_INT_CPE_Q6 | \
+        __HFN_INT_CPE_Q7 | __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 | \
+        __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 | __HFN_INT_MBOX_LPU1)
+
+/*
+ * Host interrupt status defines for 1860
+ */
+#define __HFN_INT_MBOX_LPU0_CT2        0x00010000U
+#define __HFN_INT_MBOX_LPU1_CT2        0x00020000U
+#define __HFN_INT_ERR_PSS_CT2  0x00040000U
+#define __HFN_INT_ERR_LPU0_CT2 0x00080000U
+#define __HFN_INT_ERR_LPU1_CT2 0x00100000U
+#define __HFN_INT_CPQ_HALT_CT2 0x00200000U
+#define __HFN_INT_ERR_WGN_CT2  0x00400000U
+#define __HFN_INT_ERR_LEHRX_CT2        0x00800000U
+#define __HFN_INT_ERR_LEHTX_CT2        0x01000000U
+#define __HFN_INT_ERR_MASK_CT2 \
+       (__HFN_INT_ERR_PSS_CT2 | __HFN_INT_ERR_LPU0_CT2 | \
+        __HFN_INT_ERR_LPU1_CT2 | __HFN_INT_CPQ_HALT_CT2 | \
+        __HFN_INT_ERR_WGN_CT2 | __HFN_INT_ERR_LEHRX_CT2 | \
+        __HFN_INT_ERR_LEHTX_CT2)
+#define __HFN_INT_FN0_MASK_CT2 \
+       (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | __HFN_INT_CPE_Q2 | \
+        __HFN_INT_CPE_Q3 | __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 | \
+        __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 | __HFN_INT_MBOX_LPU0_CT2)
+#define __HFN_INT_FN1_MASK_CT2 \
+       (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 | __HFN_INT_CPE_Q6 | \
+        __HFN_INT_CPE_Q7 | __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 | \
+        __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 | __HFN_INT_MBOX_LPU1_CT2)
+
+/*
+ * asic memory map.
+ */
+#define PSS_SMEM_PAGE_START            0x8000
+#define PSS_SMEM_PGNUM(_pg0, _ma)      ((_pg0) + ((_ma) >> 15))
+#define PSS_SMEM_PGOFF(_ma)            ((_ma) & 0x7fff)
+
+#endif /* __BFI_REG_H__ */
similarity index 67%
rename from drivers/net/bna/bna.h
rename to drivers/net/ethernet/brocade/bna/bna.h
index 21e9155d6e56a9100791df49056b1b0c98540b08..2a587c5fdc2032895bb30ff8fe3b17db35c27494 100644 (file)
@@ -16,7 +16,6 @@
 #include "bfa_cs.h"
 #include "bfa_ioc.h"
 #include "cna.h"
-#include "bfi_ll.h"
 #include "bna_types.h"
 
 extern const u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX];
@@ -32,15 +31,7 @@ extern const u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX];
 /* Log string size */
 #define BNA_MESSAGE_SIZE               256
 
-/* MBOX API for PORT, TX, RX */
-#define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg)           \
-do {                                                                   \
-       memcpy(&((_qe)->cmd.msg[0]), (_cmd), (_cmd_len));       \
-       (_qe)->cbfn = (_cbfn);                                          \
-       (_qe)->cbarg = (_cbarg);                                        \
-} while (0)
-
-#define bna_is_small_rxq(rcb) ((rcb)->id == 1)
+#define bna_is_small_rxq(_id) ((_id) & 0x1)
 
 #define BNA_MAC_IS_EQUAL(_mac1, _mac2)                                 \
        (!memcmp((_mac1), (_mac2), sizeof(mac_t)))
@@ -177,32 +168,6 @@ do {                                                               \
 #define BNA_Q_IN_USE_COUNT(_q_ptr)                                     \
        (BNA_QE_IN_USE_CNT(&(_q_ptr)->q, (_q_ptr)->q.q_depth))
 
-/* These macros build the data portion of the TxQ/RxQ doorbell */
-#define BNA_DOORBELL_Q_PRD_IDX(_pi)    (0x80000000 | (_pi))
-#define BNA_DOORBELL_Q_STOP            (0x40000000)
-
-/* These macros build the data portion of the IB doorbell */
-#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
-       (0x80000000 | ((_timeout) << 16) | (_events))
-#define BNA_DOORBELL_IB_INT_DISABLE    (0x40000000)
-
-/* Set the coalescing timer for the given ib */
-#define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer)              \
-       ((_i_dbell)->doorbell_ack = BNA_DOORBELL_IB_INT_ACK((_cls_timer), 0));
-
-/* Acks 'events' # of events for a given ib */
-#define bna_ib_ack(_i_dbell, _events)                                  \
-       (writel(((_i_dbell)->doorbell_ack | (_events)), \
-               (_i_dbell)->doorbell_addr));
-
-#define bna_txq_prod_indx_doorbell(_tcb)                               \
-       (writel(BNA_DOORBELL_Q_PRD_IDX((_tcb)->producer_index), \
-               (_tcb)->q_dbell));
-
-#define bna_rxq_prod_indx_doorbell(_rcb)                               \
-       (writel(BNA_DOORBELL_Q_PRD_IDX((_rcb)->producer_index), \
-               (_rcb)->q_dbell));
-
 #define BNA_LARGE_PKT_SIZE             1000
 
 #define BNA_UPDATE_PKT_CNT(_pkt, _len)                                 \
@@ -214,38 +179,59 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
-#define        call_rxf_stop_cbfn(rxf, status)                                 \
+#define        call_rxf_stop_cbfn(rxf)                                         \
+do {                                                                   \
        if ((rxf)->stop_cbfn) {                                         \
-               (*(rxf)->stop_cbfn)((rxf)->stop_cbarg, (status));       \
+               void (*cbfn)(struct bna_rx *);                  \
+               struct bna_rx *cbarg;                                   \
+               cbfn = (rxf)->stop_cbfn;                                \
+               cbarg = (rxf)->stop_cbarg;                              \
                (rxf)->stop_cbfn = NULL;                                \
                (rxf)->stop_cbarg = NULL;                               \
-       }
+               cbfn(cbarg);                                            \
+       }                                                               \
+} while (0)
 
-#define        call_rxf_start_cbfn(rxf, status)                                \
+#define        call_rxf_start_cbfn(rxf)                                        \
+do {                                                                   \
        if ((rxf)->start_cbfn) {                                        \
-               (*(rxf)->start_cbfn)((rxf)->start_cbarg, (status));     \
+               void (*cbfn)(struct bna_rx *);                  \
+               struct bna_rx *cbarg;                                   \
+               cbfn = (rxf)->start_cbfn;                               \
+               cbarg = (rxf)->start_cbarg;                             \
                (rxf)->start_cbfn = NULL;                               \
                (rxf)->start_cbarg = NULL;                              \
-       }
+               cbfn(cbarg);                                            \
+       }                                                               \
+} while (0)
 
-#define        call_rxf_cam_fltr_cbfn(rxf, status)                             \
+#define        call_rxf_cam_fltr_cbfn(rxf)                                     \
+do {                                                                   \
        if ((rxf)->cam_fltr_cbfn) {                                     \
-               (*(rxf)->cam_fltr_cbfn)((rxf)->cam_fltr_cbarg, rxf->rx, \
-                                       (status));                      \
+               void (*cbfn)(struct bnad *, struct bna_rx *);   \
+               struct bnad *cbarg;                                     \
+               cbfn = (rxf)->cam_fltr_cbfn;                            \
+               cbarg = (rxf)->cam_fltr_cbarg;                          \
                (rxf)->cam_fltr_cbfn = NULL;                            \
                (rxf)->cam_fltr_cbarg = NULL;                           \
-       }
+               cbfn(cbarg, rxf->rx);                                   \
+       }                                                               \
+} while (0)
 
-#define        call_rxf_pause_cbfn(rxf, status)                                \
+#define        call_rxf_pause_cbfn(rxf)                                        \
+do {                                                                   \
        if ((rxf)->oper_state_cbfn) {                                   \
-               (*(rxf)->oper_state_cbfn)((rxf)->oper_state_cbarg, rxf->rx,\
-                                       (status));                      \
-               (rxf)->rxf_flags &= ~BNA_RXF_FL_OPERSTATE_CHANGED;      \
+               void (*cbfn)(struct bnad *, struct bna_rx *);   \
+               struct bnad *cbarg;                                     \
+               cbfn = (rxf)->oper_state_cbfn;                          \
+               cbarg = (rxf)->oper_state_cbarg;                        \
                (rxf)->oper_state_cbfn = NULL;                          \
                (rxf)->oper_state_cbarg = NULL;                         \
-       }
+               cbfn(cbarg, rxf->rx);                                   \
+       }                                                               \
+} while (0)
 
-#define        call_rxf_resume_cbfn(rxf, status) call_rxf_pause_cbfn(rxf, status)
+#define        call_rxf_resume_cbfn(rxf) call_rxf_pause_cbfn(rxf)
 
 #define is_xxx_enable(mode, bitmask, xxx) ((bitmask & xxx) && (mode & xxx))
 
@@ -331,6 +317,61 @@ do {                                                                       \
        }                                                               \
 } while (0)
 
+#define bna_tx_rid_mask(_bna) ((_bna)->tx_mod.rid_mask)
+
+#define bna_rx_rid_mask(_bna) ((_bna)->rx_mod.rid_mask)
+
+#define bna_tx_from_rid(_bna, _rid, _tx)                               \
+do {                                                               \
+       struct bna_tx_mod *__tx_mod = &(_bna)->tx_mod;    \
+       struct bna_tx *__tx;                                        \
+       struct list_head *qe;                                      \
+       _tx = NULL;                                                  \
+       list_for_each(qe, &__tx_mod->tx_active_q) {                  \
+               __tx = (struct bna_tx *)qe;                          \
+               if (__tx->rid == (_rid)) {                            \
+                       (_tx) = __tx;                              \
+                       break;                                    \
+               }                                                      \
+       }                                                              \
+} while (0)
+
+#define bna_rx_from_rid(_bna, _rid, _rx)                               \
+do {                                                                   \
+       struct bna_rx_mod *__rx_mod = &(_bna)->rx_mod;                  \
+       struct bna_rx *__rx;                                            \
+       struct list_head *qe;                                           \
+       _rx = NULL;                                                     \
+       list_for_each(qe, &__rx_mod->rx_active_q) {                     \
+               __rx = (struct bna_rx *)qe;                             \
+               if (__rx->rid == (_rid)) {                              \
+                       (_rx) = __rx;                                   \
+                       break;                                          \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+/**
+ *
+ *  Inline functions
+ *
+ */
+
+static inline struct bna_mac *bna_mac_find(struct list_head *q, u8 *addr)
+{
+       struct bna_mac *mac = NULL;
+       struct list_head *qe;
+       list_for_each(qe, q) {
+               if (BNA_MAC_IS_EQUAL(((struct bna_mac *)qe)->addr, addr)) {
+                       mac = (struct bna_mac *)qe;
+                       break;
+               }
+       }
+       return mac;
+}
+
+#define bna_attr(_bna) (&(_bna)->ioceth.attr)
+
 /**
  *
  * Function prototypes
@@ -341,17 +382,24 @@ do {                                                                      \
  * BNA
  */
 
+/* FW response handlers */
+void bna_bfi_stats_clr_rsp(struct bna *bna, struct bfi_msgq_mhdr *msghdr);
+
 /* APIs for BNAD */
 void bna_res_req(struct bna_res_info *res_info);
+void bna_mod_res_req(struct bna *bna, struct bna_res_info *res_info);
 void bna_init(struct bna *bna, struct bnad *bnad,
                        struct bfa_pcidev *pcidev,
                        struct bna_res_info *res_info);
+void bna_mod_init(struct bna *bna, struct bna_res_info *res_info);
 void bna_uninit(struct bna *bna);
+int bna_num_txq_set(struct bna *bna, int num_txq);
+int bna_num_rxp_set(struct bna *bna, int num_rxp);
 void bna_stats_get(struct bna *bna);
 void bna_get_perm_mac(struct bna *bna, u8 *mac);
+void bna_hw_stats_get(struct bna *bna);
 
 /* APIs for Rx */
-int bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size);
 
 /* APIs for RxF */
 struct bna_mac *bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod);
@@ -360,79 +408,44 @@ void bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod,
 struct bna_mac *bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod);
 void bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod,
                          struct bna_mac *mac);
-struct bna_rit_segment *
-bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size);
-void bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod,
-                       struct bna_rit_segment *seg);
-
-/**
- * DEVICE
- */
-
-/* APIs for BNAD */
-void bna_device_enable(struct bna_device *device);
-void bna_device_disable(struct bna_device *device,
-                       enum bna_cleanup_type type);
+struct bna_mcam_handle *bna_mcam_mod_handle_get(struct bna_mcam_mod *mod);
+void bna_mcam_mod_handle_put(struct bna_mcam_mod *mcam_mod,
+                         struct bna_mcam_handle *handle);
 
 /**
  * MBOX
  */
 
-/* APIs for PORT, TX, RX */
-void bna_mbox_handler(struct bna *bna, u32 intr_status);
-void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe);
-
-/**
- * PORT
- */
-
-/* API for RX */
-int bna_port_mtu_get(struct bna_port *port);
-void bna_llport_rx_started(struct bna_llport *llport);
-void bna_llport_rx_stopped(struct bna_llport *llport);
-
 /* API for BNAD */
-void bna_port_enable(struct bna_port *port);
-void bna_port_disable(struct bna_port *port, enum bna_cleanup_type type,
-                     void (*cbfn)(void *, enum bna_cb_status));
-void bna_port_pause_config(struct bna_port *port,
-                          struct bna_pause_config *pause_config,
-                          void (*cbfn)(struct bnad *, enum bna_cb_status));
-void bna_port_mtu_set(struct bna_port *port, int mtu,
-                     void (*cbfn)(struct bnad *, enum bna_cb_status));
-void bna_port_mac_get(struct bna_port *port, mac_t *mac);
-
-/* Callbacks for TX, RX */
-void bna_port_cb_tx_stopped(struct bna_port *port,
-                           enum bna_cb_status status);
-void bna_port_cb_rx_stopped(struct bna_port *port,
-                           enum bna_cb_status status);
+void bna_mbox_handler(struct bna *bna, u32 intr_status);
 
 /**
- * IB
+ * ETHPORT
  */
 
-/* APIs for BNA */
-void bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
-                    struct bna_res_info *res_info);
-void bna_ib_mod_uninit(struct bna_ib_mod *ib_mod);
+/* Callbacks for RX */
+void bna_ethport_cb_rx_started(struct bna_ethport *ethport);
+void bna_ethport_cb_rx_stopped(struct bna_ethport *ethport);
 
 /**
  * TX MODULE AND TX
  */
+/* FW response handelrs */
+void bna_bfi_tx_enet_start_rsp(struct bna_tx *tx,
+                              struct bfi_msgq_mhdr *msghdr);
+void bna_bfi_tx_enet_stop_rsp(struct bna_tx *tx,
+                             struct bfi_msgq_mhdr *msghdr);
+void bna_bfi_bw_update_aen(struct bna_tx_mod *tx_mod);
 
 /* APIs for BNA */
 void bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
                     struct bna_res_info *res_info);
 void bna_tx_mod_uninit(struct bna_tx_mod *tx_mod);
-int bna_tx_state_get(struct bna_tx *tx);
 
-/* APIs for PORT */
+/* APIs for ENET */
 void bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type);
 void bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type);
 void bna_tx_mod_fail(struct bna_tx_mod *tx_mod);
-void bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio);
-void bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link);
 
 /* APIs for BNAD */
 void bna_tx_res_req(int num_txq, int txq_depth,
@@ -444,43 +457,29 @@ struct bna_tx *bna_tx_create(struct bna *bna, struct bnad *bnad,
 void bna_tx_destroy(struct bna_tx *tx);
 void bna_tx_enable(struct bna_tx *tx);
 void bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
-                   void (*cbfn)(void *, struct bna_tx *,
-                                enum bna_cb_status));
+                   void (*cbfn)(void *, struct bna_tx *));
+void bna_tx_cleanup_complete(struct bna_tx *tx);
 void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo);
 
 /**
  * RX MODULE, RX, RXF
  */
 
-/* Internal APIs */
-void rxf_cb_cam_fltr_mbox_cmd(void *arg, int status);
-void rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
-               const struct bna_mac *mac_addr);
-void __rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status);
-void bna_rxf_adv_init(struct bna_rxf *rxf,
-               struct bna_rx *rx,
-               struct bna_rx_config *q_config);
-int rxf_process_packet_filter_ucast(struct bna_rxf *rxf);
-int rxf_process_packet_filter_promisc(struct bna_rxf *rxf);
-int rxf_process_packet_filter_default(struct bna_rxf *rxf);
-int rxf_process_packet_filter_allmulti(struct bna_rxf *rxf);
-int rxf_clear_packet_filter_ucast(struct bna_rxf *rxf);
-int rxf_clear_packet_filter_promisc(struct bna_rxf *rxf);
-int rxf_clear_packet_filter_default(struct bna_rxf *rxf);
-int rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf);
-void rxf_reset_packet_filter_ucast(struct bna_rxf *rxf);
-void rxf_reset_packet_filter_promisc(struct bna_rxf *rxf);
-void rxf_reset_packet_filter_default(struct bna_rxf *rxf);
-void rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf);
+/* FW response handlers */
+void bna_bfi_rx_enet_start_rsp(struct bna_rx *rx,
+                              struct bfi_msgq_mhdr *msghdr);
+void bna_bfi_rx_enet_stop_rsp(struct bna_rx *rx,
+                             struct bfi_msgq_mhdr *msghdr);
+void bna_bfi_rxf_cfg_rsp(struct bna_rxf *rxf, struct bfi_msgq_mhdr *msghdr);
+void bna_bfi_rxf_mcast_add_rsp(struct bna_rxf *rxf,
+                              struct bfi_msgq_mhdr *msghdr);
 
 /* APIs for BNA */
 void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
                     struct bna_res_info *res_info);
 void bna_rx_mod_uninit(struct bna_rx_mod *rx_mod);
-int bna_rx_state_get(struct bna_rx *rx);
-int bna_rxf_state_get(struct bna_rxf *rxf);
 
-/* APIs for PORT */
+/* APIs for ENET */
 void bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type);
 void bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type);
 void bna_rx_mod_fail(struct bna_rx_mod *rx_mod);
@@ -495,54 +494,86 @@ struct bna_rx *bna_rx_create(struct bna *bna, struct bnad *bnad,
 void bna_rx_destroy(struct bna_rx *rx);
 void bna_rx_enable(struct bna_rx *rx);
 void bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
-                   void (*cbfn)(void *, struct bna_rx *,
-                                enum bna_cb_status));
+                   void (*cbfn)(void *, struct bna_rx *));
+void bna_rx_cleanup_complete(struct bna_rx *rx);
 void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo);
 void bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX]);
 void bna_rx_dim_update(struct bna_ccb *ccb);
 enum bna_cb_status
 bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
-                void (*cbfn)(struct bnad *, struct bna_rx *,
-                             enum bna_cb_status));
+                void (*cbfn)(struct bnad *, struct bna_rx *));
+enum bna_cb_status
+bna_rx_ucast_add(struct bna_rx *rx, u8* ucmac,
+                void (*cbfn)(struct bnad *, struct bna_rx *));
+enum bna_cb_status
+bna_rx_ucast_del(struct bna_rx *rx, u8 *ucmac,
+                void (*cbfn)(struct bnad *, struct bna_rx *));
 enum bna_cb_status
 bna_rx_mcast_add(struct bna_rx *rx, u8 *mcmac,
-                void (*cbfn)(struct bnad *, struct bna_rx *,
-                             enum bna_cb_status));
+                void (*cbfn)(struct bnad *, struct bna_rx *));
 enum bna_cb_status
 bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mcmac,
-                    void (*cbfn)(struct bnad *, struct bna_rx *,
-                                 enum bna_cb_status));
+                    void (*cbfn)(struct bnad *, struct bna_rx *));
 enum bna_cb_status
 bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode,
                enum bna_rxmode bitmask,
-               void (*cbfn)(struct bnad *, struct bna_rx *,
-                            enum bna_cb_status));
+               void (*cbfn)(struct bnad *, struct bna_rx *));
 void bna_rx_vlan_add(struct bna_rx *rx, int vlan_id);
 void bna_rx_vlan_del(struct bna_rx *rx, int vlan_id);
 void bna_rx_vlanfilter_enable(struct bna_rx *rx);
-void bna_rx_hds_enable(struct bna_rx *rx, struct bna_rxf_hds *hds_config,
-                      void (*cbfn)(struct bnad *, struct bna_rx *,
-                                   enum bna_cb_status));
+void bna_rx_hds_enable(struct bna_rx *rx, struct bna_hds_config *hds_config,
+                      void (*cbfn)(struct bnad *, struct bna_rx *));
 void bna_rx_hds_disable(struct bna_rx *rx,
-                       void (*cbfn)(struct bnad *, struct bna_rx *,
-                                    enum bna_cb_status));
+                       void (*cbfn)(struct bnad *, struct bna_rx *));
+
+/**
+ * ENET
+ */
+
+/* API for RX */
+int bna_enet_mtu_get(struct bna_enet *enet);
+
+/* Callbacks for TX, RX */
+void bna_enet_cb_tx_stopped(struct bna_enet *enet);
+void bna_enet_cb_rx_stopped(struct bna_enet *enet);
+
+/* API for BNAD */
+void bna_enet_enable(struct bna_enet *enet);
+void bna_enet_disable(struct bna_enet *enet, enum bna_cleanup_type type,
+                     void (*cbfn)(void *));
+void bna_enet_pause_config(struct bna_enet *enet,
+                          struct bna_pause_config *pause_config,
+                          void (*cbfn)(struct bnad *));
+void bna_enet_mtu_set(struct bna_enet *enet, int mtu,
+                     void (*cbfn)(struct bnad *));
+void bna_enet_perm_mac_get(struct bna_enet *enet, mac_t *mac);
+
+/**
+ * IOCETH
+ */
+
+/* APIs for BNAD */
+void bna_ioceth_enable(struct bna_ioceth *ioceth);
+void bna_ioceth_disable(struct bna_ioceth *ioceth,
+                       enum bna_cleanup_type type);
 
 /**
  * BNAD
  */
 
+/* Callbacks for ENET */
+void bnad_cb_ethport_link_status(struct bnad *bnad,
+                             enum bna_link_status status);
+
+/* Callbacks for IOCETH */
+void bnad_cb_ioceth_ready(struct bnad *bnad);
+void bnad_cb_ioceth_failed(struct bnad *bnad);
+void bnad_cb_ioceth_disabled(struct bnad *bnad);
+void bnad_cb_mbox_intr_enable(struct bnad *bnad);
+void bnad_cb_mbox_intr_disable(struct bnad *bnad);
+
 /* Callbacks for BNA */
 void bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
                       struct bna_stats *stats);
 
-/* Callbacks for DEVICE */
-void bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status);
-void bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status);
-void bnad_cb_device_enable_mbox_intr(struct bnad *bnad);
-void bnad_cb_device_disable_mbox_intr(struct bnad *bnad);
-
-/* Callbacks for port */
-void bnad_cb_port_link_status(struct bnad *bnad,
-                             enum bna_link_status status);
-
 #endif  /* __BNA_H__ */
diff --git a/drivers/net/ethernet/brocade/bna/bna_enet.c b/drivers/net/ethernet/brocade/bna/bna_enet.c
new file mode 100644 (file)
index 0000000..68a275d
--- /dev/null
@@ -0,0 +1,2129 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include "bna.h"
+
+static inline int
+ethport_can_be_up(struct bna_ethport *ethport)
+{
+       int ready = 0;
+       if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
+               ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) &&
+                        (ethport->flags & BNA_ETHPORT_F_RX_STARTED) &&
+                        (ethport->flags & BNA_ETHPORT_F_PORT_ENABLED));
+       else
+               ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) &&
+                        (ethport->flags & BNA_ETHPORT_F_RX_STARTED) &&
+                        !(ethport->flags & BNA_ETHPORT_F_PORT_ENABLED));
+       return ready;
+}
+
+#define ethport_is_up ethport_can_be_up
+
+enum bna_ethport_event {
+       ETHPORT_E_START                 = 1,
+       ETHPORT_E_STOP                  = 2,
+       ETHPORT_E_FAIL                  = 3,
+       ETHPORT_E_UP                    = 4,
+       ETHPORT_E_DOWN                  = 5,
+       ETHPORT_E_FWRESP_UP_OK          = 6,
+       ETHPORT_E_FWRESP_DOWN           = 7,
+       ETHPORT_E_FWRESP_UP_FAIL        = 8,
+};
+
+enum bna_enet_event {
+       ENET_E_START                    = 1,
+       ENET_E_STOP                     = 2,
+       ENET_E_FAIL                     = 3,
+       ENET_E_PAUSE_CFG                = 4,
+       ENET_E_MTU_CFG                  = 5,
+       ENET_E_FWRESP_PAUSE             = 6,
+       ENET_E_CHLD_STOPPED             = 7,
+};
+
+enum bna_ioceth_event {
+       IOCETH_E_ENABLE                 = 1,
+       IOCETH_E_DISABLE                = 2,
+       IOCETH_E_IOC_RESET              = 3,
+       IOCETH_E_IOC_FAILED             = 4,
+       IOCETH_E_IOC_READY              = 5,
+       IOCETH_E_ENET_ATTR_RESP         = 6,
+       IOCETH_E_ENET_STOPPED           = 7,
+       IOCETH_E_IOC_DISABLED           = 8,
+};
+
+#define bna_stats_copy(_name, _type)                                   \
+do {                                                                   \
+       count = sizeof(struct bfi_enet_stats_ ## _type) / sizeof(u64);  \
+       stats_src = (u64 *)&bna->stats.hw_stats_kva->_name ## _stats;   \
+       stats_dst = (u64 *)&bna->stats.hw_stats._name ## _stats;        \
+       for (i = 0; i < count; i++)                                     \
+               stats_dst[i] = be64_to_cpu(stats_src[i]);               \
+} while (0)                                                            \
+
+/*
+ * FW response handlers
+ */
+
+static void
+bna_bfi_ethport_enable_aen(struct bna_ethport *ethport,
+                               struct bfi_msgq_mhdr *msghdr)
+{
+       ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED;
+
+       if (ethport_can_be_up(ethport))
+               bfa_fsm_send_event(ethport, ETHPORT_E_UP);
+}
+
+static void
+bna_bfi_ethport_disable_aen(struct bna_ethport *ethport,
+                               struct bfi_msgq_mhdr *msghdr)
+{
+       int ethport_up = ethport_is_up(ethport);
+
+       ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
+
+       if (ethport_up)
+               bfa_fsm_send_event(ethport, ETHPORT_E_DOWN);
+}
+
+static void
+bna_bfi_ethport_admin_rsp(struct bna_ethport *ethport,
+                               struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_enable_req *admin_req =
+               &ethport->bfi_enet_cmd.admin_req;
+       struct bfi_enet_rsp *rsp = (struct bfi_enet_rsp *)msghdr;
+
+       switch (admin_req->enable) {
+       case BNA_STATUS_T_ENABLED:
+               if (rsp->error == BFI_ENET_CMD_OK)
+                       bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK);
+               else {
+                       ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
+                       bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL);
+               }
+               break;
+
+       case BNA_STATUS_T_DISABLED:
+               bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN);
+               ethport->link_status = BNA_LINK_DOWN;
+               ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
+               break;
+       }
+}
+
+static void
+bna_bfi_ethport_lpbk_rsp(struct bna_ethport *ethport,
+                               struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_diag_lb_req *diag_lb_req =
+               &ethport->bfi_enet_cmd.lpbk_req;
+       struct bfi_enet_rsp *rsp = (struct bfi_enet_rsp *)msghdr;
+
+       switch (diag_lb_req->enable) {
+       case BNA_STATUS_T_ENABLED:
+               if (rsp->error == BFI_ENET_CMD_OK)
+                       bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK);
+               else {
+                       ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP;
+                       bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL);
+               }
+               break;
+
+       case BNA_STATUS_T_DISABLED:
+               bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN);
+               break;
+       }
+}
+
+static void
+bna_bfi_pause_set_rsp(struct bna_enet *enet, struct bfi_msgq_mhdr *msghdr)
+{
+       bfa_fsm_send_event(enet, ENET_E_FWRESP_PAUSE);
+}
+
+static void
+bna_bfi_attr_get_rsp(struct bna_ioceth *ioceth,
+                       struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_attr_rsp *rsp = (struct bfi_enet_attr_rsp *)msghdr;
+
+       /**
+        * Store only if not set earlier, since BNAD can override the HW
+        * attributes
+        */
+       if (!ioceth->attr.num_txq)
+               ioceth->attr.num_txq = ntohl(rsp->max_cfg);
+       if (!ioceth->attr.num_rxp)
+               ioceth->attr.num_rxp = ntohl(rsp->max_cfg);
+       ioceth->attr.num_ucmac = ntohl(rsp->max_ucmac);
+       ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM;
+       ioceth->attr.max_rit_size = ntohl(rsp->rit_size);
+
+       bfa_fsm_send_event(ioceth, IOCETH_E_ENET_ATTR_RESP);
+}
+
+static void
+bna_bfi_stats_get_rsp(struct bna *bna, struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get;
+       u64 *stats_src;
+       u64 *stats_dst;
+       u32 tx_enet_mask = ntohl(stats_req->tx_enet_mask);
+       u32 rx_enet_mask = ntohl(stats_req->rx_enet_mask);
+       int count;
+       int i;
+
+       bna_stats_copy(mac, mac);
+       bna_stats_copy(bpc, bpc);
+       bna_stats_copy(rad, rad);
+       bna_stats_copy(rlb, rad);
+       bna_stats_copy(fc_rx, fc_rx);
+       bna_stats_copy(fc_tx, fc_tx);
+
+       stats_src = (u64 *)&(bna->stats.hw_stats_kva->rxf_stats[0]);
+
+       /* Copy Rxf stats to SW area, scatter them while copying */
+       for (i = 0; i < BFI_ENET_CFG_MAX; i++) {
+               stats_dst = (u64 *)&(bna->stats.hw_stats.rxf_stats[i]);
+               memset(stats_dst, 0, sizeof(struct bfi_enet_stats_rxf));
+               if (rx_enet_mask & ((u32)(1 << i))) {
+                       int k;
+                       count = sizeof(struct bfi_enet_stats_rxf) /
+                               sizeof(u64);
+                       for (k = 0; k < count; k++) {
+                               stats_dst[k] = be64_to_cpu(*stats_src);
+                               stats_src++;
+                       }
+               }
+       }
+
+       /* Copy Txf stats to SW area, scatter them while copying */
+       for (i = 0; i < BFI_ENET_CFG_MAX; i++) {
+               stats_dst = (u64 *)&(bna->stats.hw_stats.txf_stats[i]);
+               memset(stats_dst, 0, sizeof(struct bfi_enet_stats_txf));
+               if (tx_enet_mask & ((u32)(1 << i))) {
+                       int k;
+                       count = sizeof(struct bfi_enet_stats_txf) /
+                               sizeof(u64);
+                       for (k = 0; k < count; k++) {
+                               stats_dst[k] = be64_to_cpu(*stats_src);
+                               stats_src++;
+                       }
+               }
+       }
+
+       bna->stats_mod.stats_get_busy = false;
+       bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats);
+}
+
+static void
+bna_bfi_ethport_linkup_aen(struct bna_ethport *ethport,
+                       struct bfi_msgq_mhdr *msghdr)
+{
+       ethport->link_status = BNA_LINK_UP;
+
+       /* Dispatch events */
+       ethport->link_cbfn(ethport->bna->bnad, ethport->link_status);
+}
+
+static void
+bna_bfi_ethport_linkdown_aen(struct bna_ethport *ethport,
+                               struct bfi_msgq_mhdr *msghdr)
+{
+       ethport->link_status = BNA_LINK_DOWN;
+
+       /* Dispatch events */
+       ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
+}
+
+static void
+bna_err_handler(struct bna *bna, u32 intr_status)
+{
+       if (BNA_IS_HALT_INTR(bna, intr_status))
+               bna_halt_clear(bna);
+
+       bfa_nw_ioc_error_isr(&bna->ioceth.ioc);
+}
+
+void
+bna_mbox_handler(struct bna *bna, u32 intr_status)
+{
+       if (BNA_IS_ERR_INTR(bna, intr_status)) {
+               bna_err_handler(bna, intr_status);
+               return;
+       }
+       if (BNA_IS_MBOX_INTR(bna, intr_status))
+               bfa_nw_ioc_mbox_isr(&bna->ioceth.ioc);
+}
+
+static void
+bna_msgq_rsp_handler(void *arg, struct bfi_msgq_mhdr *msghdr)
+{
+       struct bna *bna = (struct bna *)arg;
+       struct bna_tx *tx;
+       struct bna_rx *rx;
+
+       switch (msghdr->msg_id) {
+       case BFI_ENET_I2H_RX_CFG_SET_RSP:
+               bna_rx_from_rid(bna, msghdr->enet_id, rx);
+               if (rx)
+                       bna_bfi_rx_enet_start_rsp(rx, msghdr);
+               break;
+
+       case BFI_ENET_I2H_RX_CFG_CLR_RSP:
+               bna_rx_from_rid(bna, msghdr->enet_id, rx);
+               if (rx)
+                       bna_bfi_rx_enet_stop_rsp(rx, msghdr);
+               break;
+
+       case BFI_ENET_I2H_RIT_CFG_RSP:
+       case BFI_ENET_I2H_RSS_CFG_RSP:
+       case BFI_ENET_I2H_RSS_ENABLE_RSP:
+       case BFI_ENET_I2H_RX_PROMISCUOUS_RSP:
+       case BFI_ENET_I2H_RX_DEFAULT_RSP:
+       case BFI_ENET_I2H_MAC_UCAST_SET_RSP:
+       case BFI_ENET_I2H_MAC_UCAST_CLR_RSP:
+       case BFI_ENET_I2H_MAC_UCAST_ADD_RSP:
+       case BFI_ENET_I2H_MAC_UCAST_DEL_RSP:
+       case BFI_ENET_I2H_MAC_MCAST_DEL_RSP:
+       case BFI_ENET_I2H_MAC_MCAST_FILTER_RSP:
+       case BFI_ENET_I2H_RX_VLAN_SET_RSP:
+       case BFI_ENET_I2H_RX_VLAN_STRIP_ENABLE_RSP:
+               bna_rx_from_rid(bna, msghdr->enet_id, rx);
+               if (rx)
+                       bna_bfi_rxf_cfg_rsp(&rx->rxf, msghdr);
+               break;
+
+       case BFI_ENET_I2H_MAC_MCAST_ADD_RSP:
+               bna_rx_from_rid(bna, msghdr->enet_id, rx);
+               if (rx)
+                       bna_bfi_rxf_mcast_add_rsp(&rx->rxf, msghdr);
+               break;
+
+       case BFI_ENET_I2H_TX_CFG_SET_RSP:
+               bna_tx_from_rid(bna, msghdr->enet_id, tx);
+               if (tx)
+                       bna_bfi_tx_enet_start_rsp(tx, msghdr);
+               break;
+
+       case BFI_ENET_I2H_TX_CFG_CLR_RSP:
+               bna_tx_from_rid(bna, msghdr->enet_id, tx);
+               if (tx)
+                       bna_bfi_tx_enet_stop_rsp(tx, msghdr);
+               break;
+
+       case BFI_ENET_I2H_PORT_ADMIN_RSP:
+               bna_bfi_ethport_admin_rsp(&bna->ethport, msghdr);
+               break;
+
+       case BFI_ENET_I2H_DIAG_LOOPBACK_RSP:
+               bna_bfi_ethport_lpbk_rsp(&bna->ethport, msghdr);
+               break;
+
+       case BFI_ENET_I2H_SET_PAUSE_RSP:
+               bna_bfi_pause_set_rsp(&bna->enet, msghdr);
+               break;
+
+       case BFI_ENET_I2H_GET_ATTR_RSP:
+               bna_bfi_attr_get_rsp(&bna->ioceth, msghdr);
+               break;
+
+       case BFI_ENET_I2H_STATS_GET_RSP:
+               bna_bfi_stats_get_rsp(bna, msghdr);
+               break;
+
+       case BFI_ENET_I2H_STATS_CLR_RSP:
+               /* No-op */
+               break;
+
+       case BFI_ENET_I2H_LINK_UP_AEN:
+               bna_bfi_ethport_linkup_aen(&bna->ethport, msghdr);
+               break;
+
+       case BFI_ENET_I2H_LINK_DOWN_AEN:
+               bna_bfi_ethport_linkdown_aen(&bna->ethport, msghdr);
+               break;
+
+       case BFI_ENET_I2H_PORT_ENABLE_AEN:
+               bna_bfi_ethport_enable_aen(&bna->ethport, msghdr);
+               break;
+
+       case BFI_ENET_I2H_PORT_DISABLE_AEN:
+               bna_bfi_ethport_disable_aen(&bna->ethport, msghdr);
+               break;
+
+       case BFI_ENET_I2H_BW_UPDATE_AEN:
+               bna_bfi_bw_update_aen(&bna->tx_mod);
+               break;
+
+       default:
+               break;
+       }
+}
+
+/**
+ * ETHPORT
+ */
+#define call_ethport_stop_cbfn(_ethport)                               \
+do {                                                                   \
+       if ((_ethport)->stop_cbfn) {                                    \
+               void (*cbfn)(struct bna_enet *);                        \
+               cbfn = (_ethport)->stop_cbfn;                           \
+               (_ethport)->stop_cbfn = NULL;                           \
+               cbfn(&(_ethport)->bna->enet);                           \
+       }                                                               \
+} while (0)
+
+#define call_ethport_adminup_cbfn(ethport, status)                     \
+do {                                                                   \
+       if ((ethport)->adminup_cbfn) {                                  \
+               void (*cbfn)(struct bnad *, enum bna_cb_status);        \
+               cbfn = (ethport)->adminup_cbfn;                         \
+               (ethport)->adminup_cbfn = NULL;                         \
+               cbfn((ethport)->bna->bnad, status);                     \
+       }                                                               \
+} while (0)
+
+static void
+bna_bfi_ethport_admin_up(struct bna_ethport *ethport)
+{
+       struct bfi_enet_enable_req *admin_up_req =
+               &ethport->bfi_enet_cmd.admin_req;
+
+       bfi_msgq_mhdr_set(admin_up_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0);
+       admin_up_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
+       admin_up_req->enable = BNA_STATUS_T_ENABLED;
+
+       bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_enable_req), &admin_up_req->mh);
+       bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
+}
+
+static void
+bna_bfi_ethport_admin_down(struct bna_ethport *ethport)
+{
+       struct bfi_enet_enable_req *admin_down_req =
+               &ethport->bfi_enet_cmd.admin_req;
+
+       bfi_msgq_mhdr_set(admin_down_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0);
+       admin_down_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
+       admin_down_req->enable = BNA_STATUS_T_DISABLED;
+
+       bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_enable_req), &admin_down_req->mh);
+       bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
+}
+
+static void
+bna_bfi_ethport_lpbk_up(struct bna_ethport *ethport)
+{
+       struct bfi_enet_diag_lb_req *lpbk_up_req =
+               &ethport->bfi_enet_cmd.lpbk_req;
+
+       bfi_msgq_mhdr_set(lpbk_up_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0);
+       lpbk_up_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req)));
+       lpbk_up_req->mode = (ethport->bna->enet.type ==
+                               BNA_ENET_T_LOOPBACK_INTERNAL) ?
+                               BFI_ENET_DIAG_LB_OPMODE_EXT :
+                               BFI_ENET_DIAG_LB_OPMODE_CBL;
+       lpbk_up_req->enable = BNA_STATUS_T_ENABLED;
+
+       bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_diag_lb_req), &lpbk_up_req->mh);
+       bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
+}
+
+static void
+bna_bfi_ethport_lpbk_down(struct bna_ethport *ethport)
+{
+       struct bfi_enet_diag_lb_req *lpbk_down_req =
+               &ethport->bfi_enet_cmd.lpbk_req;
+
+       bfi_msgq_mhdr_set(lpbk_down_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0);
+       lpbk_down_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req)));
+       lpbk_down_req->enable = BNA_STATUS_T_DISABLED;
+
+       bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_diag_lb_req), &lpbk_down_req->mh);
+       bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
+}
+
+static void
+bna_bfi_ethport_up(struct bna_ethport *ethport)
+{
+       if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
+               bna_bfi_ethport_admin_up(ethport);
+       else
+               bna_bfi_ethport_lpbk_up(ethport);
+}
+
+static void
+bna_bfi_ethport_down(struct bna_ethport *ethport)
+{
+       if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
+               bna_bfi_ethport_admin_down(ethport);
+       else
+               bna_bfi_ethport_lpbk_down(ethport);
+}
+
+bfa_fsm_state_decl(bna_ethport, stopped, struct bna_ethport,
+                       enum bna_ethport_event);
+bfa_fsm_state_decl(bna_ethport, down, struct bna_ethport,
+                       enum bna_ethport_event);
+bfa_fsm_state_decl(bna_ethport, up_resp_wait, struct bna_ethport,
+                       enum bna_ethport_event);
+bfa_fsm_state_decl(bna_ethport, down_resp_wait, struct bna_ethport,
+                       enum bna_ethport_event);
+bfa_fsm_state_decl(bna_ethport, up, struct bna_ethport,
+                       enum bna_ethport_event);
+bfa_fsm_state_decl(bna_ethport, last_resp_wait, struct bna_ethport,
+                       enum bna_ethport_event);
+
+static void
+bna_ethport_sm_stopped_entry(struct bna_ethport *ethport)
+{
+       call_ethport_stop_cbfn(ethport);
+}
+
+static void
+bna_ethport_sm_stopped(struct bna_ethport *ethport,
+                       enum bna_ethport_event event)
+{
+       switch (event) {
+       case ETHPORT_E_START:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_down);
+               break;
+
+       case ETHPORT_E_STOP:
+               call_ethport_stop_cbfn(ethport);
+               break;
+
+       case ETHPORT_E_FAIL:
+               /* No-op */
+               break;
+
+       case ETHPORT_E_DOWN:
+               /* This event is received due to Rx objects failing */
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ethport_sm_down_entry(struct bna_ethport *ethport)
+{
+}
+
+static void
+bna_ethport_sm_down(struct bna_ethport *ethport,
+                       enum bna_ethport_event event)
+{
+       switch (event) {
+       case ETHPORT_E_STOP:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       case ETHPORT_E_FAIL:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       case ETHPORT_E_UP:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait);
+               bna_bfi_ethport_up(ethport);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ethport_sm_up_resp_wait_entry(struct bna_ethport *ethport)
+{
+}
+
+static void
+bna_ethport_sm_up_resp_wait(struct bna_ethport *ethport,
+                       enum bna_ethport_event event)
+{
+       switch (event) {
+       case ETHPORT_E_STOP:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
+               break;
+
+       case ETHPORT_E_FAIL:
+               call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL);
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       case ETHPORT_E_DOWN:
+               call_ethport_adminup_cbfn(ethport, BNA_CB_INTERRUPT);
+               bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait);
+               break;
+
+       case ETHPORT_E_FWRESP_UP_OK:
+               call_ethport_adminup_cbfn(ethport, BNA_CB_SUCCESS);
+               bfa_fsm_set_state(ethport, bna_ethport_sm_up);
+               break;
+
+       case ETHPORT_E_FWRESP_UP_FAIL:
+               call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL);
+               bfa_fsm_set_state(ethport, bna_ethport_sm_down);
+               break;
+
+       case ETHPORT_E_FWRESP_DOWN:
+               /* down_resp_wait -> up_resp_wait transition on ETHPORT_E_UP */
+               bna_bfi_ethport_up(ethport);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ethport_sm_down_resp_wait_entry(struct bna_ethport *ethport)
+{
+       /**
+        * NOTE: Do not call bna_bfi_ethport_down() here. That will over step
+        * mbox due to up_resp_wait -> down_resp_wait transition on event
+        * ETHPORT_E_DOWN
+        */
+}
+
+static void
+bna_ethport_sm_down_resp_wait(struct bna_ethport *ethport,
+                       enum bna_ethport_event event)
+{
+       switch (event) {
+       case ETHPORT_E_STOP:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
+               break;
+
+       case ETHPORT_E_FAIL:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       case ETHPORT_E_UP:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait);
+               break;
+
+       case ETHPORT_E_FWRESP_UP_OK:
+               /* up_resp_wait->down_resp_wait transition on ETHPORT_E_DOWN */
+               bna_bfi_ethport_down(ethport);
+               break;
+
+       case ETHPORT_E_FWRESP_UP_FAIL:
+       case ETHPORT_E_FWRESP_DOWN:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_down);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ethport_sm_up_entry(struct bna_ethport *ethport)
+{
+}
+
+static void
+bna_ethport_sm_up(struct bna_ethport *ethport,
+                       enum bna_ethport_event event)
+{
+       switch (event) {
+       case ETHPORT_E_STOP:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
+               bna_bfi_ethport_down(ethport);
+               break;
+
+       case ETHPORT_E_FAIL:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       case ETHPORT_E_DOWN:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait);
+               bna_bfi_ethport_down(ethport);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ethport_sm_last_resp_wait_entry(struct bna_ethport *ethport)
+{
+}
+
+static void
+bna_ethport_sm_last_resp_wait(struct bna_ethport *ethport,
+                       enum bna_ethport_event event)
+{
+       switch (event) {
+       case ETHPORT_E_FAIL:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       case ETHPORT_E_DOWN:
+               /**
+                * This event is received due to Rx objects stopping in
+                * parallel to ethport
+                */
+               /* No-op */
+               break;
+
+       case ETHPORT_E_FWRESP_UP_OK:
+               /* up_resp_wait->last_resp_wait transition on ETHPORT_T_STOP */
+               bna_bfi_ethport_down(ethport);
+               break;
+
+       case ETHPORT_E_FWRESP_UP_FAIL:
+       case ETHPORT_E_FWRESP_DOWN:
+               bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ethport_init(struct bna_ethport *ethport, struct bna *bna)
+{
+       ethport->flags |= (BNA_ETHPORT_F_ADMIN_UP | BNA_ETHPORT_F_PORT_ENABLED);
+       ethport->bna = bna;
+
+       ethport->link_status = BNA_LINK_DOWN;
+       ethport->link_cbfn = bnad_cb_ethport_link_status;
+
+       ethport->rx_started_count = 0;
+
+       ethport->stop_cbfn = NULL;
+       ethport->adminup_cbfn = NULL;
+
+       bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
+}
+
+static void
+bna_ethport_uninit(struct bna_ethport *ethport)
+{
+       ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP;
+       ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
+
+       ethport->bna = NULL;
+}
+
+static void
+bna_ethport_start(struct bna_ethport *ethport)
+{
+       bfa_fsm_send_event(ethport, ETHPORT_E_START);
+}
+
+static void
+bna_enet_cb_ethport_stopped(struct bna_enet *enet)
+{
+       bfa_wc_down(&enet->chld_stop_wc);
+}
+
+static void
+bna_ethport_stop(struct bna_ethport *ethport)
+{
+       ethport->stop_cbfn = bna_enet_cb_ethport_stopped;
+       bfa_fsm_send_event(ethport, ETHPORT_E_STOP);
+}
+
+static void
+bna_ethport_fail(struct bna_ethport *ethport)
+{
+       /* Reset the physical port status to enabled */
+       ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED;
+
+       if (ethport->link_status != BNA_LINK_DOWN) {
+               ethport->link_status = BNA_LINK_DOWN;
+               ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
+       }
+       bfa_fsm_send_event(ethport, ETHPORT_E_FAIL);
+}
+
+/* Should be called only when ethport is disabled */
+void
+bna_ethport_cb_rx_started(struct bna_ethport *ethport)
+{
+       ethport->rx_started_count++;
+
+       if (ethport->rx_started_count == 1) {
+               ethport->flags |= BNA_ETHPORT_F_RX_STARTED;
+
+               if (ethport_can_be_up(ethport))
+                       bfa_fsm_send_event(ethport, ETHPORT_E_UP);
+       }
+}
+
+void
+bna_ethport_cb_rx_stopped(struct bna_ethport *ethport)
+{
+       int ethport_up = ethport_is_up(ethport);
+
+       ethport->rx_started_count--;
+
+       if (ethport->rx_started_count == 0) {
+               ethport->flags &= ~BNA_ETHPORT_F_RX_STARTED;
+
+               if (ethport_up)
+                       bfa_fsm_send_event(ethport, ETHPORT_E_DOWN);
+       }
+}
+
+/**
+ * ENET
+ */
+#define bna_enet_chld_start(enet)                                      \
+do {                                                                   \
+       enum bna_tx_type tx_type =                                      \
+               ((enet)->type == BNA_ENET_T_REGULAR) ?                  \
+               BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;                   \
+       enum bna_rx_type rx_type =                                      \
+               ((enet)->type == BNA_ENET_T_REGULAR) ?                  \
+               BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;                   \
+       bna_ethport_start(&(enet)->bna->ethport);                       \
+       bna_tx_mod_start(&(enet)->bna->tx_mod, tx_type);                \
+       bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type);                \
+} while (0)
+
+#define bna_enet_chld_stop(enet)                                       \
+do {                                                                   \
+       enum bna_tx_type tx_type =                                      \
+               ((enet)->type == BNA_ENET_T_REGULAR) ?                  \
+               BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;                   \
+       enum bna_rx_type rx_type =                                      \
+               ((enet)->type == BNA_ENET_T_REGULAR) ?                  \
+               BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;                   \
+       bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\
+       bfa_wc_up(&(enet)->chld_stop_wc);                               \
+       bna_ethport_stop(&(enet)->bna->ethport);                        \
+       bfa_wc_up(&(enet)->chld_stop_wc);                               \
+       bna_tx_mod_stop(&(enet)->bna->tx_mod, tx_type);                 \
+       bfa_wc_up(&(enet)->chld_stop_wc);                               \
+       bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type);                 \
+       bfa_wc_wait(&(enet)->chld_stop_wc);                             \
+} while (0)
+
+#define bna_enet_chld_fail(enet)                                       \
+do {                                                                   \
+       bna_ethport_fail(&(enet)->bna->ethport);                        \
+       bna_tx_mod_fail(&(enet)->bna->tx_mod);                          \
+       bna_rx_mod_fail(&(enet)->bna->rx_mod);                          \
+} while (0)
+
+#define bna_enet_rx_start(enet)                                                \
+do {                                                                   \
+       enum bna_rx_type rx_type =                                      \
+               ((enet)->type == BNA_ENET_T_REGULAR) ?                  \
+               BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;                   \
+       bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type);                \
+} while (0)
+
+#define bna_enet_rx_stop(enet)                                         \
+do {                                                                   \
+       enum bna_rx_type rx_type =                                      \
+               ((enet)->type == BNA_ENET_T_REGULAR) ?                  \
+               BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;                   \
+       bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\
+       bfa_wc_up(&(enet)->chld_stop_wc);                               \
+       bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type);                 \
+       bfa_wc_wait(&(enet)->chld_stop_wc);                             \
+} while (0)
+
+#define call_enet_stop_cbfn(enet)                                      \
+do {                                                                   \
+       if ((enet)->stop_cbfn) {                                        \
+               void (*cbfn)(void *);                                   \
+               void *cbarg;                                            \
+               cbfn = (enet)->stop_cbfn;                               \
+               cbarg = (enet)->stop_cbarg;                             \
+               (enet)->stop_cbfn = NULL;                               \
+               (enet)->stop_cbarg = NULL;                              \
+               cbfn(cbarg);                                            \
+       }                                                               \
+} while (0)
+
+#define call_enet_pause_cbfn(enet)                                     \
+do {                                                                   \
+       if ((enet)->pause_cbfn) {                                       \
+               void (*cbfn)(struct bnad *);                            \
+               cbfn = (enet)->pause_cbfn;                              \
+               (enet)->pause_cbfn = NULL;                              \
+               cbfn((enet)->bna->bnad);                                \
+       }                                                               \
+} while (0)
+
+#define call_enet_mtu_cbfn(enet)                                       \
+do {                                                                   \
+       if ((enet)->mtu_cbfn) {                                         \
+               void (*cbfn)(struct bnad *);                            \
+               cbfn = (enet)->mtu_cbfn;                                \
+               (enet)->mtu_cbfn = NULL;                                \
+               cbfn((enet)->bna->bnad);                                \
+       }                                                               \
+} while (0)
+
+static void bna_enet_cb_chld_stopped(void *arg);
+static void bna_bfi_pause_set(struct bna_enet *enet);
+
+bfa_fsm_state_decl(bna_enet, stopped, struct bna_enet,
+                       enum bna_enet_event);
+bfa_fsm_state_decl(bna_enet, pause_init_wait, struct bna_enet,
+                       enum bna_enet_event);
+bfa_fsm_state_decl(bna_enet, last_resp_wait, struct bna_enet,
+                       enum bna_enet_event);
+bfa_fsm_state_decl(bna_enet, started, struct bna_enet,
+                       enum bna_enet_event);
+bfa_fsm_state_decl(bna_enet, cfg_wait, struct bna_enet,
+                       enum bna_enet_event);
+bfa_fsm_state_decl(bna_enet, cfg_stop_wait, struct bna_enet,
+                       enum bna_enet_event);
+bfa_fsm_state_decl(bna_enet, chld_stop_wait, struct bna_enet,
+                       enum bna_enet_event);
+
+static void
+bna_enet_sm_stopped_entry(struct bna_enet *enet)
+{
+       call_enet_pause_cbfn(enet);
+       call_enet_mtu_cbfn(enet);
+       call_enet_stop_cbfn(enet);
+}
+
+static void
+bna_enet_sm_stopped(struct bna_enet *enet, enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_START:
+               bfa_fsm_set_state(enet, bna_enet_sm_pause_init_wait);
+               break;
+
+       case ENET_E_STOP:
+               call_enet_stop_cbfn(enet);
+               break;
+
+       case ENET_E_FAIL:
+               /* No-op */
+               break;
+
+       case ENET_E_PAUSE_CFG:
+               call_enet_pause_cbfn(enet);
+               break;
+
+       case ENET_E_MTU_CFG:
+               call_enet_mtu_cbfn(enet);
+               break;
+
+       case ENET_E_CHLD_STOPPED:
+               /**
+                * This event is received due to Ethport, Tx and Rx objects
+                * failing
+                */
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_enet_sm_pause_init_wait_entry(struct bna_enet *enet)
+{
+       bna_bfi_pause_set(enet);
+}
+
+static void
+bna_enet_sm_pause_init_wait(struct bna_enet *enet,
+                               enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_STOP:
+               enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+               bfa_fsm_set_state(enet, bna_enet_sm_last_resp_wait);
+               break;
+
+       case ENET_E_FAIL:
+               enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               break;
+
+       case ENET_E_PAUSE_CFG:
+               enet->flags |= BNA_ENET_F_PAUSE_CHANGED;
+               break;
+
+       case ENET_E_MTU_CFG:
+               /* No-op */
+               break;
+
+       case ENET_E_FWRESP_PAUSE:
+               if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) {
+                       enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+                       bna_bfi_pause_set(enet);
+               } else {
+                       bfa_fsm_set_state(enet, bna_enet_sm_started);
+                       bna_enet_chld_start(enet);
+               }
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_enet_sm_last_resp_wait_entry(struct bna_enet *enet)
+{
+       enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+}
+
+static void
+bna_enet_sm_last_resp_wait(struct bna_enet *enet,
+                               enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_FAIL:
+       case ENET_E_FWRESP_PAUSE:
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_enet_sm_started_entry(struct bna_enet *enet)
+{
+       /**
+        * NOTE: Do not call bna_enet_chld_start() here, since it will be
+        * inadvertently called during cfg_wait->started transition as well
+        */
+       call_enet_pause_cbfn(enet);
+       call_enet_mtu_cbfn(enet);
+}
+
+static void
+bna_enet_sm_started(struct bna_enet *enet,
+                       enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_STOP:
+               bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait);
+               break;
+
+       case ENET_E_FAIL:
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               bna_enet_chld_fail(enet);
+               break;
+
+       case ENET_E_PAUSE_CFG:
+               bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait);
+               bna_bfi_pause_set(enet);
+               break;
+
+       case ENET_E_MTU_CFG:
+               bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait);
+               bna_enet_rx_stop(enet);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_enet_sm_cfg_wait_entry(struct bna_enet *enet)
+{
+}
+
+static void
+bna_enet_sm_cfg_wait(struct bna_enet *enet,
+                       enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_STOP:
+               enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+               enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
+               bfa_fsm_set_state(enet, bna_enet_sm_cfg_stop_wait);
+               break;
+
+       case ENET_E_FAIL:
+               enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+               enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               bna_enet_chld_fail(enet);
+               break;
+
+       case ENET_E_PAUSE_CFG:
+               enet->flags |= BNA_ENET_F_PAUSE_CHANGED;
+               break;
+
+       case ENET_E_MTU_CFG:
+               enet->flags |= BNA_ENET_F_MTU_CHANGED;
+               break;
+
+       case ENET_E_CHLD_STOPPED:
+               bna_enet_rx_start(enet);
+               /* Fall through */
+       case ENET_E_FWRESP_PAUSE:
+               if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) {
+                       enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+                       bna_bfi_pause_set(enet);
+               } else if (enet->flags & BNA_ENET_F_MTU_CHANGED) {
+                       enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
+                       bna_enet_rx_stop(enet);
+               } else {
+                       bfa_fsm_set_state(enet, bna_enet_sm_started);
+               }
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_enet_sm_cfg_stop_wait_entry(struct bna_enet *enet)
+{
+       enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
+       enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
+}
+
+static void
+bna_enet_sm_cfg_stop_wait(struct bna_enet *enet,
+                               enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_FAIL:
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               bna_enet_chld_fail(enet);
+               break;
+
+       case ENET_E_FWRESP_PAUSE:
+       case ENET_E_CHLD_STOPPED:
+               bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_enet_sm_chld_stop_wait_entry(struct bna_enet *enet)
+{
+       bna_enet_chld_stop(enet);
+}
+
+static void
+bna_enet_sm_chld_stop_wait(struct bna_enet *enet,
+                               enum bna_enet_event event)
+{
+       switch (event) {
+       case ENET_E_FAIL:
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               bna_enet_chld_fail(enet);
+               break;
+
+       case ENET_E_CHLD_STOPPED:
+               bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_bfi_pause_set(struct bna_enet *enet)
+{
+       struct bfi_enet_set_pause_req *pause_req = &enet->pause_req;
+
+       bfi_msgq_mhdr_set(pause_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_SET_PAUSE_REQ, 0, 0);
+       pause_req->mh.num_entries = htons(
+       bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_set_pause_req)));
+       pause_req->tx_pause = enet->pause_config.tx_pause;
+       pause_req->rx_pause = enet->pause_config.rx_pause;
+
+       bfa_msgq_cmd_set(&enet->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_set_pause_req), &pause_req->mh);
+       bfa_msgq_cmd_post(&enet->bna->msgq, &enet->msgq_cmd);
+}
+
+static void
+bna_enet_cb_chld_stopped(void *arg)
+{
+       struct bna_enet *enet = (struct bna_enet *)arg;
+
+       bfa_fsm_send_event(enet, ENET_E_CHLD_STOPPED);
+}
+
+static void
+bna_enet_init(struct bna_enet *enet, struct bna *bna)
+{
+       enet->bna = bna;
+       enet->flags = 0;
+       enet->mtu = 0;
+       enet->type = BNA_ENET_T_REGULAR;
+
+       enet->stop_cbfn = NULL;
+       enet->stop_cbarg = NULL;
+
+       enet->pause_cbfn = NULL;
+
+       enet->mtu_cbfn = NULL;
+
+       bfa_fsm_set_state(enet, bna_enet_sm_stopped);
+}
+
+static void
+bna_enet_uninit(struct bna_enet *enet)
+{
+       enet->flags = 0;
+
+       enet->bna = NULL;
+}
+
+static void
+bna_enet_start(struct bna_enet *enet)
+{
+       enet->flags |= BNA_ENET_F_IOCETH_READY;
+       if (enet->flags & BNA_ENET_F_ENABLED)
+               bfa_fsm_send_event(enet, ENET_E_START);
+}
+
+static void
+bna_ioceth_cb_enet_stopped(void *arg)
+{
+       struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
+
+       bfa_fsm_send_event(ioceth, IOCETH_E_ENET_STOPPED);
+}
+
+static void
+bna_enet_stop(struct bna_enet *enet)
+{
+       enet->stop_cbfn = bna_ioceth_cb_enet_stopped;
+       enet->stop_cbarg = &enet->bna->ioceth;
+
+       enet->flags &= ~BNA_ENET_F_IOCETH_READY;
+       bfa_fsm_send_event(enet, ENET_E_STOP);
+}
+
+static void
+bna_enet_fail(struct bna_enet *enet)
+{
+       enet->flags &= ~BNA_ENET_F_IOCETH_READY;
+       bfa_fsm_send_event(enet, ENET_E_FAIL);
+}
+
+void
+bna_enet_cb_tx_stopped(struct bna_enet *enet)
+{
+       bfa_wc_down(&enet->chld_stop_wc);
+}
+
+void
+bna_enet_cb_rx_stopped(struct bna_enet *enet)
+{
+       bfa_wc_down(&enet->chld_stop_wc);
+}
+
+int
+bna_enet_mtu_get(struct bna_enet *enet)
+{
+       return enet->mtu;
+}
+
+void
+bna_enet_enable(struct bna_enet *enet)
+{
+       if (enet->fsm != (bfa_sm_t)bna_enet_sm_stopped)
+               return;
+
+       enet->flags |= BNA_ENET_F_ENABLED;
+
+       if (enet->flags & BNA_ENET_F_IOCETH_READY)
+               bfa_fsm_send_event(enet, ENET_E_START);
+}
+
+void
+bna_enet_disable(struct bna_enet *enet, enum bna_cleanup_type type,
+                void (*cbfn)(void *))
+{
+       if (type == BNA_SOFT_CLEANUP) {
+               (*cbfn)(enet->bna->bnad);
+               return;
+       }
+
+       enet->stop_cbfn = cbfn;
+       enet->stop_cbarg = enet->bna->bnad;
+
+       enet->flags &= ~BNA_ENET_F_ENABLED;
+
+       bfa_fsm_send_event(enet, ENET_E_STOP);
+}
+
+void
+bna_enet_pause_config(struct bna_enet *enet,
+                     struct bna_pause_config *pause_config,
+                     void (*cbfn)(struct bnad *))
+{
+       enet->pause_config = *pause_config;
+
+       enet->pause_cbfn = cbfn;
+
+       bfa_fsm_send_event(enet, ENET_E_PAUSE_CFG);
+}
+
+void
+bna_enet_mtu_set(struct bna_enet *enet, int mtu,
+                void (*cbfn)(struct bnad *))
+{
+       enet->mtu = mtu;
+
+       enet->mtu_cbfn = cbfn;
+
+       bfa_fsm_send_event(enet, ENET_E_MTU_CFG);
+}
+
+void
+bna_enet_perm_mac_get(struct bna_enet *enet, mac_t *mac)
+{
+       *mac = bfa_nw_ioc_get_mac(&enet->bna->ioceth.ioc);
+}
+
+/**
+ * IOCETH
+ */
+#define enable_mbox_intr(_ioceth)                                      \
+do {                                                                   \
+       u32 intr_status;                                                \
+       bna_intr_status_get((_ioceth)->bna, intr_status);               \
+       bnad_cb_mbox_intr_enable((_ioceth)->bna->bnad);                 \
+       bna_mbox_intr_enable((_ioceth)->bna);                           \
+} while (0)
+
+#define disable_mbox_intr(_ioceth)                                     \
+do {                                                                   \
+       bna_mbox_intr_disable((_ioceth)->bna);                          \
+       bnad_cb_mbox_intr_disable((_ioceth)->bna->bnad);                \
+} while (0)
+
+#define call_ioceth_stop_cbfn(_ioceth)                                 \
+do {                                                                   \
+       if ((_ioceth)->stop_cbfn) {                                     \
+               void (*cbfn)(struct bnad *);                            \
+               struct bnad *cbarg;                                     \
+               cbfn = (_ioceth)->stop_cbfn;                            \
+               cbarg = (_ioceth)->stop_cbarg;                          \
+               (_ioceth)->stop_cbfn = NULL;                            \
+               (_ioceth)->stop_cbarg = NULL;                           \
+               cbfn(cbarg);                                            \
+       }                                                               \
+} while (0)
+
+#define bna_stats_mod_uninit(_stats_mod)                               \
+do {                                                                   \
+} while (0)
+
+#define bna_stats_mod_start(_stats_mod)                                        \
+do {                                                                   \
+       (_stats_mod)->ioc_ready = true;                                 \
+} while (0)
+
+#define bna_stats_mod_stop(_stats_mod)                                 \
+do {                                                                   \
+       (_stats_mod)->ioc_ready = false;                                \
+} while (0)
+
+#define bna_stats_mod_fail(_stats_mod)                                 \
+do {                                                                   \
+       (_stats_mod)->ioc_ready = false;                                \
+       (_stats_mod)->stats_get_busy = false;                           \
+       (_stats_mod)->stats_clr_busy = false;                           \
+} while (0)
+
+static void bna_bfi_attr_get(struct bna_ioceth *ioceth);
+
+bfa_fsm_state_decl(bna_ioceth, stopped, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, ioc_ready_wait, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, enet_attr_wait, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, ready, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, last_resp_wait, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, enet_stop_wait, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, ioc_disable_wait, struct bna_ioceth,
+                       enum bna_ioceth_event);
+bfa_fsm_state_decl(bna_ioceth, failed, struct bna_ioceth,
+                       enum bna_ioceth_event);
+
+static void
+bna_ioceth_sm_stopped_entry(struct bna_ioceth *ioceth)
+{
+       call_ioceth_stop_cbfn(ioceth);
+}
+
+static void
+bna_ioceth_sm_stopped(struct bna_ioceth *ioceth,
+                       enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_ENABLE:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait);
+               bfa_nw_ioc_enable(&ioceth->ioc);
+               break;
+
+       case IOCETH_E_DISABLE:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
+               break;
+
+       case IOCETH_E_IOC_RESET:
+               enable_mbox_intr(ioceth);
+               break;
+
+       case IOCETH_E_IOC_FAILED:
+               disable_mbox_intr(ioceth);
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_ioc_ready_wait_entry(struct bna_ioceth *ioceth)
+{
+       /**
+        * Do not call bfa_nw_ioc_enable() here. It must be called in the
+        * previous state due to failed -> ioc_ready_wait transition.
+        */
+}
+
+static void
+bna_ioceth_sm_ioc_ready_wait(struct bna_ioceth *ioceth,
+                               enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_DISABLE:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
+               bfa_nw_ioc_disable(&ioceth->ioc);
+               break;
+
+       case IOCETH_E_IOC_RESET:
+               enable_mbox_intr(ioceth);
+               break;
+
+       case IOCETH_E_IOC_FAILED:
+               disable_mbox_intr(ioceth);
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
+               break;
+
+       case IOCETH_E_IOC_READY:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_attr_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_enet_attr_wait_entry(struct bna_ioceth *ioceth)
+{
+       bna_bfi_attr_get(ioceth);
+}
+
+static void
+bna_ioceth_sm_enet_attr_wait(struct bna_ioceth *ioceth,
+                               enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_DISABLE:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_last_resp_wait);
+               break;
+
+       case IOCETH_E_IOC_FAILED:
+               disable_mbox_intr(ioceth);
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
+               break;
+
+       case IOCETH_E_ENET_ATTR_RESP:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ready);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_ready_entry(struct bna_ioceth *ioceth)
+{
+       bna_enet_start(&ioceth->bna->enet);
+       bna_stats_mod_start(&ioceth->bna->stats_mod);
+       bnad_cb_ioceth_ready(ioceth->bna->bnad);
+}
+
+static void
+bna_ioceth_sm_ready(struct bna_ioceth *ioceth, enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_DISABLE:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_stop_wait);
+               break;
+
+       case IOCETH_E_IOC_FAILED:
+               disable_mbox_intr(ioceth);
+               bna_enet_fail(&ioceth->bna->enet);
+               bna_stats_mod_fail(&ioceth->bna->stats_mod);
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_last_resp_wait_entry(struct bna_ioceth *ioceth)
+{
+}
+
+static void
+bna_ioceth_sm_last_resp_wait(struct bna_ioceth *ioceth,
+                               enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_IOC_FAILED:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
+               disable_mbox_intr(ioceth);
+               bfa_nw_ioc_disable(&ioceth->ioc);
+               break;
+
+       case IOCETH_E_ENET_ATTR_RESP:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
+               bfa_nw_ioc_disable(&ioceth->ioc);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_enet_stop_wait_entry(struct bna_ioceth *ioceth)
+{
+       bna_stats_mod_stop(&ioceth->bna->stats_mod);
+       bna_enet_stop(&ioceth->bna->enet);
+}
+
+static void
+bna_ioceth_sm_enet_stop_wait(struct bna_ioceth *ioceth,
+                               enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_IOC_FAILED:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
+               disable_mbox_intr(ioceth);
+               bna_enet_fail(&ioceth->bna->enet);
+               bna_stats_mod_fail(&ioceth->bna->stats_mod);
+               bfa_nw_ioc_disable(&ioceth->ioc);
+               break;
+
+       case IOCETH_E_ENET_STOPPED:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
+               bfa_nw_ioc_disable(&ioceth->ioc);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_ioc_disable_wait_entry(struct bna_ioceth *ioceth)
+{
+}
+
+static void
+bna_ioceth_sm_ioc_disable_wait(struct bna_ioceth *ioceth,
+                               enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_IOC_DISABLED:
+               disable_mbox_intr(ioceth);
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
+               break;
+
+       case IOCETH_E_ENET_STOPPED:
+               /* This event is received due to enet failing */
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_ioceth_sm_failed_entry(struct bna_ioceth *ioceth)
+{
+       bnad_cb_ioceth_failed(ioceth->bna->bnad);
+}
+
+static void
+bna_ioceth_sm_failed(struct bna_ioceth *ioceth,
+                       enum bna_ioceth_event event)
+{
+       switch (event) {
+       case IOCETH_E_DISABLE:
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
+               bfa_nw_ioc_disable(&ioceth->ioc);
+               break;
+
+       case IOCETH_E_IOC_RESET:
+               enable_mbox_intr(ioceth);
+               bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait);
+               break;
+
+       case IOCETH_E_IOC_FAILED:
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_bfi_attr_get(struct bna_ioceth *ioceth)
+{
+       struct bfi_enet_attr_req *attr_req = &ioceth->attr_req;
+
+       bfi_msgq_mhdr_set(attr_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_GET_ATTR_REQ, 0, 0);
+       attr_req->mh.num_entries = htons(
+       bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_attr_req)));
+       bfa_msgq_cmd_set(&ioceth->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_attr_req), &attr_req->mh);
+       bfa_msgq_cmd_post(&ioceth->bna->msgq, &ioceth->msgq_cmd);
+}
+
+/* IOC callback functions */
+
+static void
+bna_cb_ioceth_enable(void *arg, enum bfa_status error)
+{
+       struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
+
+       if (error)
+               bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED);
+       else
+               bfa_fsm_send_event(ioceth, IOCETH_E_IOC_READY);
+}
+
+static void
+bna_cb_ioceth_disable(void *arg)
+{
+       struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
+
+       bfa_fsm_send_event(ioceth, IOCETH_E_IOC_DISABLED);
+}
+
+static void
+bna_cb_ioceth_hbfail(void *arg)
+{
+       struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
+
+       bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED);
+}
+
+static void
+bna_cb_ioceth_reset(void *arg)
+{
+       struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
+
+       bfa_fsm_send_event(ioceth, IOCETH_E_IOC_RESET);
+}
+
+static struct bfa_ioc_cbfn bna_ioceth_cbfn = {
+       bna_cb_ioceth_enable,
+       bna_cb_ioceth_disable,
+       bna_cb_ioceth_hbfail,
+       bna_cb_ioceth_reset
+};
+
+static void
+bna_ioceth_init(struct bna_ioceth *ioceth, struct bna *bna,
+               struct bna_res_info *res_info)
+{
+       u64 dma;
+       u8 *kva;
+
+       ioceth->bna = bna;
+
+       /**
+        * Attach IOC and claim:
+        *      1. DMA memory for IOC attributes
+        *      2. Kernel memory for FW trace
+        */
+       bfa_nw_ioc_attach(&ioceth->ioc, ioceth, &bna_ioceth_cbfn);
+       bfa_nw_ioc_pci_init(&ioceth->ioc, &bna->pcidev, BFI_PCIFN_CLASS_ETH);
+
+       BNA_GET_DMA_ADDR(
+               &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma);
+       kva = res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva;
+       bfa_nw_ioc_mem_claim(&ioceth->ioc, kva, dma);
+
+       kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva;
+
+       /**
+        * Attach common modules (Diag, SFP, CEE, Port) and claim respective
+        * DMA memory.
+        */
+       BNA_GET_DMA_ADDR(
+               &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma);
+       kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva;
+       bfa_nw_cee_attach(&bna->cee, &ioceth->ioc, bna);
+       bfa_nw_cee_mem_claim(&bna->cee, kva, dma);
+       kva += bfa_nw_cee_meminfo();
+       dma += bfa_nw_cee_meminfo();
+
+       bfa_msgq_attach(&bna->msgq, &ioceth->ioc);
+       bfa_msgq_memclaim(&bna->msgq, kva, dma);
+       bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna);
+       kva += bfa_msgq_meminfo();
+       dma += bfa_msgq_meminfo();
+
+       ioceth->stop_cbfn = NULL;
+       ioceth->stop_cbarg = NULL;
+
+       bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
+}
+
+static void
+bna_ioceth_uninit(struct bna_ioceth *ioceth)
+{
+       bfa_nw_ioc_detach(&ioceth->ioc);
+
+       ioceth->bna = NULL;
+}
+
+void
+bna_ioceth_enable(struct bna_ioceth *ioceth)
+{
+       if (ioceth->fsm == (bfa_fsm_t)bna_ioceth_sm_ready) {
+               bnad_cb_ioceth_ready(ioceth->bna->bnad);
+               return;
+       }
+
+       if (ioceth->fsm == (bfa_fsm_t)bna_ioceth_sm_stopped)
+               bfa_fsm_send_event(ioceth, IOCETH_E_ENABLE);
+}
+
+void
+bna_ioceth_disable(struct bna_ioceth *ioceth, enum bna_cleanup_type type)
+{
+       if (type == BNA_SOFT_CLEANUP) {
+               bnad_cb_ioceth_disabled(ioceth->bna->bnad);
+               return;
+       }
+
+       ioceth->stop_cbfn = bnad_cb_ioceth_disabled;
+       ioceth->stop_cbarg = ioceth->bna->bnad;
+
+       bfa_fsm_send_event(ioceth, IOCETH_E_DISABLE);
+}
+
+static void
+bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna,
+                 struct bna_res_info *res_info)
+{
+       int i;
+
+       ucam_mod->ucmac = (struct bna_mac *)
+       res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
+
+       INIT_LIST_HEAD(&ucam_mod->free_q);
+       for (i = 0; i < bna->ioceth.attr.num_ucmac; i++) {
+               bfa_q_qe_init(&ucam_mod->ucmac[i].qe);
+               list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q);
+       }
+
+       ucam_mod->bna = bna;
+}
+
+static void
+bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod)
+{
+       struct list_head *qe;
+       int i = 0;
+
+       list_for_each(qe, &ucam_mod->free_q)
+               i++;
+
+       ucam_mod->bna = NULL;
+}
+
+static void
+bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna,
+                 struct bna_res_info *res_info)
+{
+       int i;
+
+       mcam_mod->mcmac = (struct bna_mac *)
+       res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
+
+       INIT_LIST_HEAD(&mcam_mod->free_q);
+       for (i = 0; i < bna->ioceth.attr.num_mcmac; i++) {
+               bfa_q_qe_init(&mcam_mod->mcmac[i].qe);
+               list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q);
+       }
+
+       mcam_mod->mchandle = (struct bna_mcam_handle *)
+       res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mdl[0].kva;
+
+       INIT_LIST_HEAD(&mcam_mod->free_handle_q);
+       for (i = 0; i < bna->ioceth.attr.num_mcmac; i++) {
+               bfa_q_qe_init(&mcam_mod->mchandle[i].qe);
+               list_add_tail(&mcam_mod->mchandle[i].qe,
+                               &mcam_mod->free_handle_q);
+       }
+
+       mcam_mod->bna = bna;
+}
+
+static void
+bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod)
+{
+       struct list_head *qe;
+       int i;
+
+       i = 0;
+       list_for_each(qe, &mcam_mod->free_q) i++;
+
+       i = 0;
+       list_for_each(qe, &mcam_mod->free_handle_q) i++;
+
+       mcam_mod->bna = NULL;
+}
+
+static void
+bna_bfi_stats_get(struct bna *bna)
+{
+       struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get;
+
+       bna->stats_mod.stats_get_busy = true;
+
+       bfi_msgq_mhdr_set(stats_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_STATS_GET_REQ, 0, 0);
+       stats_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_stats_req)));
+       stats_req->stats_mask = htons(BFI_ENET_STATS_ALL);
+       stats_req->tx_enet_mask = htonl(bna->tx_mod.rid_mask);
+       stats_req->rx_enet_mask = htonl(bna->rx_mod.rid_mask);
+       stats_req->host_buffer.a32.addr_hi = bna->stats.hw_stats_dma.msb;
+       stats_req->host_buffer.a32.addr_lo = bna->stats.hw_stats_dma.lsb;
+
+       bfa_msgq_cmd_set(&bna->stats_mod.stats_get_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_stats_req), &stats_req->mh);
+       bfa_msgq_cmd_post(&bna->msgq, &bna->stats_mod.stats_get_cmd);
+}
+
+void
+bna_res_req(struct bna_res_info *res_info)
+{
+       /* DMA memory for COMMON_MODULE */
+       res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM;
+       res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+       res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
+       res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
+                               (bfa_nw_cee_meminfo() +
+                               bfa_msgq_meminfo()), PAGE_SIZE);
+
+       /* DMA memory for retrieving IOC attributes */
+       res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM;
+       res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+       res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1;
+       res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len =
+                               ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE);
+
+       /* Virtual memory for retreiving fw_trc */
+       res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM;
+       res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
+       res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 0;
+       res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = 0;
+
+       /* DMA memory for retreiving stats */
+       res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM;
+       res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+       res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1;
+       res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len =
+                               ALIGN(sizeof(struct bfi_enet_stats),
+                                       PAGE_SIZE);
+}
+
+void
+bna_mod_res_req(struct bna *bna, struct bna_res_info *res_info)
+{
+       struct bna_attr *attr = &bna->ioceth.attr;
+
+       /* Virtual memory for Tx objects - stored by Tx module */
+       res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.len =
+               attr->num_txq * sizeof(struct bna_tx);
+
+       /* Virtual memory for TxQ - stored by Tx module */
+       res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len =
+               attr->num_txq * sizeof(struct bna_txq);
+
+       /* Virtual memory for Rx objects - stored by Rx module */
+       res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.len =
+               attr->num_rxp * sizeof(struct bna_rx);
+
+       /* Virtual memory for RxPath - stored by Rx module */
+       res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len =
+               attr->num_rxp * sizeof(struct bna_rxp);
+
+       /* Virtual memory for RxQ - stored by Rx module */
+       res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len =
+               (attr->num_rxp * 2) * sizeof(struct bna_rxq);
+
+       /* Virtual memory for Unicast MAC address - stored by ucam module */
+       res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len =
+               attr->num_ucmac * sizeof(struct bna_mac);
+
+       /* Virtual memory for Multicast MAC address - stored by mcam module */
+       res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len =
+               attr->num_mcmac * sizeof(struct bna_mac);
+
+       /* Virtual memory for Multicast handle - stored by mcam module */
+       res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_type = BNA_RES_T_MEM;
+       res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mem_type =
+               BNA_MEM_T_KVA;
+       res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.num = 1;
+       res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.len =
+               attr->num_mcmac * sizeof(struct bna_mcam_handle);
+}
+
+void
+bna_init(struct bna *bna, struct bnad *bnad,
+               struct bfa_pcidev *pcidev, struct bna_res_info *res_info)
+{
+       bna->bnad = bnad;
+       bna->pcidev = *pcidev;
+
+       bna->stats.hw_stats_kva = (struct bfi_enet_stats *)
+               res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva;
+       bna->stats.hw_stats_dma.msb =
+               res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb;
+       bna->stats.hw_stats_dma.lsb =
+               res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb;
+
+       bna_reg_addr_init(bna, &bna->pcidev);
+
+       /* Also initializes diag, cee, sfp, phy_port, msgq */
+       bna_ioceth_init(&bna->ioceth, bna, res_info);
+
+       bna_enet_init(&bna->enet, bna);
+       bna_ethport_init(&bna->ethport, bna);
+}
+
+void
+bna_mod_init(struct bna *bna, struct bna_res_info *res_info)
+{
+       bna_tx_mod_init(&bna->tx_mod, bna, res_info);
+
+       bna_rx_mod_init(&bna->rx_mod, bna, res_info);
+
+       bna_ucam_mod_init(&bna->ucam_mod, bna, res_info);
+
+       bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
+
+       bna->default_mode_rid = BFI_INVALID_RID;
+       bna->promisc_rid = BFI_INVALID_RID;
+
+       bna->mod_flags |= BNA_MOD_F_INIT_DONE;
+}
+
+void
+bna_uninit(struct bna *bna)
+{
+       if (bna->mod_flags & BNA_MOD_F_INIT_DONE) {
+               bna_mcam_mod_uninit(&bna->mcam_mod);
+               bna_ucam_mod_uninit(&bna->ucam_mod);
+               bna_rx_mod_uninit(&bna->rx_mod);
+               bna_tx_mod_uninit(&bna->tx_mod);
+               bna->mod_flags &= ~BNA_MOD_F_INIT_DONE;
+       }
+
+       bna_stats_mod_uninit(&bna->stats_mod);
+       bna_ethport_uninit(&bna->ethport);
+       bna_enet_uninit(&bna->enet);
+
+       bna_ioceth_uninit(&bna->ioceth);
+
+       bna->bnad = NULL;
+}
+
+int
+bna_num_txq_set(struct bna *bna, int num_txq)
+{
+       if (num_txq > 0 && (num_txq <= bna->ioceth.attr.num_txq)) {
+               bna->ioceth.attr.num_txq = num_txq;
+               return BNA_CB_SUCCESS;
+       }
+
+       return BNA_CB_FAIL;
+}
+
+int
+bna_num_rxp_set(struct bna *bna, int num_rxp)
+{
+       if (num_rxp > 0 && (num_rxp <= bna->ioceth.attr.num_rxp)) {
+               bna->ioceth.attr.num_rxp = num_rxp;
+               return BNA_CB_SUCCESS;
+       }
+
+       return BNA_CB_FAIL;
+}
+
+struct bna_mac *
+bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod)
+{
+       struct list_head *qe;
+
+       if (list_empty(&ucam_mod->free_q))
+               return NULL;
+
+       bfa_q_deq(&ucam_mod->free_q, &qe);
+
+       return (struct bna_mac *)qe;
+}
+
+void
+bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, struct bna_mac *mac)
+{
+       list_add_tail(&mac->qe, &ucam_mod->free_q);
+}
+
+struct bna_mac *
+bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod)
+{
+       struct list_head *qe;
+
+       if (list_empty(&mcam_mod->free_q))
+               return NULL;
+
+       bfa_q_deq(&mcam_mod->free_q, &qe);
+
+       return (struct bna_mac *)qe;
+}
+
+void
+bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, struct bna_mac *mac)
+{
+       list_add_tail(&mac->qe, &mcam_mod->free_q);
+}
+
+struct bna_mcam_handle *
+bna_mcam_mod_handle_get(struct bna_mcam_mod *mcam_mod)
+{
+       struct list_head *qe;
+
+       if (list_empty(&mcam_mod->free_handle_q))
+               return NULL;
+
+       bfa_q_deq(&mcam_mod->free_handle_q, &qe);
+
+       return (struct bna_mcam_handle *)qe;
+}
+
+void
+bna_mcam_mod_handle_put(struct bna_mcam_mod *mcam_mod,
+                       struct bna_mcam_handle *handle)
+{
+       list_add_tail(&handle->qe, &mcam_mod->free_handle_q);
+}
+
+void
+bna_hw_stats_get(struct bna *bna)
+{
+       if (!bna->stats_mod.ioc_ready) {
+               bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
+               return;
+       }
+       if (bna->stats_mod.stats_get_busy) {
+               bnad_cb_stats_get(bna->bnad, BNA_CB_BUSY, &bna->stats);
+               return;
+       }
+
+       bna_bfi_stats_get(bna);
+}
diff --git a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h
new file mode 100644 (file)
index 0000000..07bb792
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * File for interrupt macros and functions
+ */
+
+#ifndef __BNA_HW_DEFS_H__
+#define __BNA_HW_DEFS_H__
+
+#include "bfi_reg.h"
+
+/**
+ *
+ * SW imposed limits
+ *
+ */
+
+#define BFI_ENET_MAX_MCAM              256
+
+#define BFI_INVALID_RID                        -1
+
+#define BFI_IBIDX_SIZE                 4
+
+#define BFI_VLAN_WORD_SHIFT            5       /* 32 bits */
+#define BFI_VLAN_WORD_MASK             0x1F
+#define BFI_VLAN_BLOCK_SHIFT           9       /* 512 bits */
+#define BFI_VLAN_BMASK_ALL             0xFF
+
+#define BFI_COALESCING_TIMER_UNIT      5       /* 5us */
+#define BFI_MAX_COALESCING_TIMEO       0xFF    /* in 5us units */
+#define BFI_MAX_INTERPKT_COUNT         0xFF
+#define BFI_MAX_INTERPKT_TIMEO         0xF     /* in 0.5us units */
+#define BFI_TX_COALESCING_TIMEO                20      /* 20 * 5 = 100us */
+#define BFI_TX_INTERPKT_COUNT          32
+#define        BFI_RX_COALESCING_TIMEO         12      /* 12 * 5 = 60us */
+#define        BFI_RX_INTERPKT_COUNT           6       /* Pkt Cnt = 6 */
+#define        BFI_RX_INTERPKT_TIMEO           3       /* 3 * 0.5 = 1.5us */
+
+#define BFI_TXQ_WI_SIZE                        64      /* bytes */
+#define BFI_RXQ_WI_SIZE                        8       /* bytes */
+#define BFI_CQ_WI_SIZE                 16      /* bytes */
+#define BFI_TX_MAX_WRR_QUOTA           0xFFF
+
+#define BFI_TX_MAX_VECTORS_PER_WI      4
+#define BFI_TX_MAX_VECTORS_PER_PKT     0xFF
+#define BFI_TX_MAX_DATA_PER_VECTOR     0xFFFF
+#define BFI_TX_MAX_DATA_PER_PKT                0xFFFFFF
+
+/* Small Q buffer size */
+#define BFI_SMALL_RXBUF_SIZE           128
+
+#define BFI_TX_MAX_PRIO                        8
+#define BFI_TX_PRIO_MAP_ALL            0xFF
+
+/*
+ *
+ * Register definitions and macros
+ *
+ */
+
+#define BNA_PCI_REG_CT_ADDRSZ          (0x40000)
+
+#define ct_reg_addr_init(_bna, _pcidev)                                        \
+{                                                                      \
+       struct bna_reg_offset reg_offset[] =                            \
+       {{HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},                         \
+        {HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK},                         \
+        {HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK},                         \
+        {HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK} };                       \
+                                                                       \
+       (_bna)->regs.fn_int_status = (_pcidev)->pci_bar_kva +           \
+                               reg_offset[(_pcidev)->pci_func].fn_int_status;\
+       (_bna)->regs.fn_int_mask = (_pcidev)->pci_bar_kva +             \
+                               reg_offset[(_pcidev)->pci_func].fn_int_mask;\
+}
+
+#define ct_bit_defn_init(_bna, _pcidev)                                        \
+{                                                                      \
+       (_bna)->bits.mbox_status_bits = (__HFN_INT_MBOX_LPU0 |          \
+                                       __HFN_INT_MBOX_LPU1);           \
+       (_bna)->bits.mbox_mask_bits = (__HFN_INT_MBOX_LPU0 |            \
+                                       __HFN_INT_MBOX_LPU1);           \
+       (_bna)->bits.error_status_bits = (__HFN_INT_ERR_MASK);          \
+       (_bna)->bits.error_mask_bits = (__HFN_INT_ERR_MASK);            \
+       (_bna)->bits.halt_status_bits = __HFN_INT_LL_HALT;              \
+}
+
+#define ct2_reg_addr_init(_bna, _pcidev)                               \
+{                                                                      \
+       (_bna)->regs.fn_int_status = (_pcidev)->pci_bar_kva +           \
+                               CT2_HOSTFN_INT_STATUS;                  \
+       (_bna)->regs.fn_int_mask = (_pcidev)->pci_bar_kva +             \
+                               CT2_HOSTFN_INTR_MASK;                   \
+}
+
+#define ct2_bit_defn_init(_bna, _pcidev)                               \
+{                                                                      \
+       (_bna)->bits.mbox_status_bits = (__HFN_INT_MBOX_LPU0_CT2 |      \
+                                       __HFN_INT_MBOX_LPU1_CT2);       \
+       (_bna)->bits.mbox_mask_bits = (__HFN_INT_MBOX_LPU0_CT2 |        \
+                                       __HFN_INT_MBOX_LPU1_CT2);       \
+       (_bna)->bits.error_status_bits = (__HFN_INT_ERR_MASK_CT2);      \
+       (_bna)->bits.error_mask_bits = (__HFN_INT_ERR_MASK_CT2);        \
+       (_bna)->bits.halt_status_bits = __HFN_INT_CPQ_HALT_CT2;         \
+       (_bna)->bits.halt_mask_bits = __HFN_INT_CPQ_HALT_CT2;           \
+}
+
+#define bna_reg_addr_init(_bna, _pcidev)                               \
+{                                                                      \
+       switch ((_pcidev)->device_id) {                                 \
+       case PCI_DEVICE_ID_BROCADE_CT:                                  \
+               ct_reg_addr_init((_bna), (_pcidev));                    \
+               ct_bit_defn_init((_bna), (_pcidev));                    \
+               break;                                                  \
+       }                                                               \
+}
+
+#define bna_port_id_get(_bna) ((_bna)->ioceth.ioc.port_id)
+/**
+ *
+ *  Interrupt related bits, flags and macros
+ *
+ */
+
+#define IB_STATUS_BITS         0x0000ffff
+
+#define BNA_IS_MBOX_INTR(_bna, _intr_status)                           \
+       ((_intr_status) & (_bna)->bits.mbox_status_bits)
+
+#define BNA_IS_HALT_INTR(_bna, _intr_status)                           \
+       ((_intr_status) & (_bna)->bits.halt_status_bits)
+
+#define BNA_IS_ERR_INTR(_bna, _intr_status)    \
+       ((_intr_status) & (_bna)->bits.error_status_bits)
+
+#define BNA_IS_MBOX_ERR_INTR(_bna, _intr_status)       \
+       (BNA_IS_MBOX_INTR(_bna, _intr_status) |         \
+       BNA_IS_ERR_INTR(_bna, _intr_status))
+
+#define BNA_IS_INTX_DATA_INTR(_intr_status)            \
+               ((_intr_status) & IB_STATUS_BITS)
+
+#define bna_halt_clear(_bna)                                           \
+do {                                                                   \
+       u32 init_halt;                                          \
+       init_halt = readl((_bna)->ioceth.ioc.ioc_regs.ll_halt); \
+       init_halt &= ~__FW_INIT_HALT_P;                                 \
+       writel(init_halt, (_bna)->ioceth.ioc.ioc_regs.ll_halt); \
+       init_halt = readl((_bna)->ioceth.ioc.ioc_regs.ll_halt); \
+} while (0)
+
+#define bna_intx_disable(_bna, _cur_mask)                              \
+{                                                                      \
+       (_cur_mask) = readl((_bna)->regs.fn_int_mask);          \
+       writel(0xffffffff, (_bna)->regs.fn_int_mask);           \
+}
+
+#define bna_intx_enable(bna, new_mask)                                 \
+       writel((new_mask), (bna)->regs.fn_int_mask)
+#define bna_mbox_intr_disable(bna)                                     \
+do {                                                                   \
+       u32 mask;                                                       \
+       mask = readl((bna)->regs.fn_int_mask);                          \
+       writel((mask | (bna)->bits.mbox_mask_bits |                     \
+               (bna)->bits.error_mask_bits), (bna)->regs.fn_int_mask); \
+       mask = readl((bna)->regs.fn_int_mask);                          \
+} while (0)
+
+#define bna_mbox_intr_enable(bna)                                      \
+do {                                                                   \
+       u32 mask;                                                       \
+       mask = readl((bna)->regs.fn_int_mask);                          \
+       writel((mask & ~((bna)->bits.mbox_mask_bits |                   \
+               (bna)->bits.error_mask_bits)), (bna)->regs.fn_int_mask);\
+       mask = readl((bna)->regs.fn_int_mask);                          \
+} while (0)
+
+#define bna_intr_status_get(_bna, _status)                             \
+{                                                                      \
+       (_status) = readl((_bna)->regs.fn_int_status);                  \
+       if (_status) {                                                  \
+               writel(((_status) & ~(_bna)->bits.mbox_status_bits),    \
+                       (_bna)->regs.fn_int_status);                    \
+       }                                                               \
+}
+
+/*
+ * MAX ACK EVENTS : No. of acks that can be accumulated in driver,
+ * before acking to h/w. The no. of bits is 16 in the doorbell register,
+ * however we keep this limited to 15 bits.
+ * This is because around the edge of 64K boundary (16 bits), one
+ * single poll can make the accumulated ACK counter cross the 64K boundary,
+ * causing problems, when we try to ack with a value greater than 64K.
+ * 15 bits (32K) should  be large enough to accumulate, anyways, and the max.
+ * acked events to h/w can be (32K + max poll weight) (currently 64).
+ */
+#define        BNA_IB_MAX_ACK_EVENTS           (1 << 15)
+
+/* These macros build the data portion of the TxQ/RxQ doorbell */
+#define BNA_DOORBELL_Q_PRD_IDX(_pi)    (0x80000000 | (_pi))
+#define BNA_DOORBELL_Q_STOP            (0x40000000)
+
+/* These macros build the data portion of the IB doorbell */
+#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events)                     \
+       (0x80000000 | ((_timeout) << 16) | (_events))
+#define BNA_DOORBELL_IB_INT_DISABLE    (0x40000000)
+
+/* Set the coalescing timer for the given ib */
+#define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer)              \
+       ((_i_dbell)->doorbell_ack = BNA_DOORBELL_IB_INT_ACK((_cls_timer), 0));
+
+/* Acks 'events' # of events for a given ib while disabling interrupts */
+#define bna_ib_ack_disable_irq(_i_dbell, _events)                      \
+       (writel(BNA_DOORBELL_IB_INT_ACK(0, (_events)), \
+               (_i_dbell)->doorbell_addr));
+
+/* Acks 'events' # of events for a given ib */
+#define bna_ib_ack(_i_dbell, _events)                                  \
+       (writel(((_i_dbell)->doorbell_ack | (_events)), \
+               (_i_dbell)->doorbell_addr));
+
+#define bna_ib_start(_bna, _ib, _is_regular)                           \
+{                                                                      \
+       u32 intx_mask;                                          \
+       struct bna_ib *ib = _ib;                                        \
+       if ((ib->intr_type == BNA_INTR_T_INTX)) {                       \
+               bna_intx_disable((_bna), intx_mask);                    \
+               intx_mask &= ~(ib->intr_vector);                        \
+               bna_intx_enable((_bna), intx_mask);                     \
+       }                                                               \
+       bna_ib_coalescing_timer_set(&ib->door_bell,                     \
+                       ib->coalescing_timeo);                          \
+       if (_is_regular)                                                \
+               bna_ib_ack(&ib->door_bell, 0);                          \
+}
+
+#define bna_ib_stop(_bna, _ib)                                         \
+{                                                                      \
+       u32 intx_mask;                                          \
+       struct bna_ib *ib = _ib;                                        \
+       writel(BNA_DOORBELL_IB_INT_DISABLE,                             \
+               ib->door_bell.doorbell_addr);                           \
+       if (ib->intr_type == BNA_INTR_T_INTX) {                         \
+               bna_intx_disable((_bna), intx_mask);                    \
+               intx_mask |= ib->intr_vector;                           \
+               bna_intx_enable((_bna), intx_mask);                     \
+       }                                                               \
+}
+
+#define bna_txq_prod_indx_doorbell(_tcb)                               \
+       (writel(BNA_DOORBELL_Q_PRD_IDX((_tcb)->producer_index), \
+               (_tcb)->q_dbell));
+
+#define bna_rxq_prod_indx_doorbell(_rcb)                               \
+       (writel(BNA_DOORBELL_Q_PRD_IDX((_rcb)->producer_index), \
+               (_rcb)->q_dbell));
+
+/**
+ *
+ * TxQ, RxQ, CQ related bits, offsets, macros
+ *
+ */
+
+/* TxQ Entry Opcodes */
+#define BNA_TXQ_WI_SEND                        (0x402) /* Single Frame Transmission */
+#define BNA_TXQ_WI_SEND_LSO            (0x403) /* Multi-Frame Transmission */
+#define BNA_TXQ_WI_EXTENSION           (0x104) /* Extension WI */
+
+/* TxQ Entry Control Flags */
+#define BNA_TXQ_WI_CF_FCOE_CRC         (1 << 8)
+#define BNA_TXQ_WI_CF_IPID_MODE                (1 << 5)
+#define BNA_TXQ_WI_CF_INS_PRIO         (1 << 4)
+#define BNA_TXQ_WI_CF_INS_VLAN         (1 << 3)
+#define BNA_TXQ_WI_CF_UDP_CKSUM                (1 << 2)
+#define BNA_TXQ_WI_CF_TCP_CKSUM                (1 << 1)
+#define BNA_TXQ_WI_CF_IP_CKSUM         (1 << 0)
+
+#define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \
+               (((_hdr_size) << 10) | ((_offset) & 0x3FF))
+
+/*
+ * Completion Q defines
+ */
+/* CQ Entry Flags */
+#define        BNA_CQ_EF_MAC_ERROR     (1 <<  0)
+#define        BNA_CQ_EF_FCS_ERROR     (1 <<  1)
+#define        BNA_CQ_EF_TOO_LONG      (1 <<  2)
+#define        BNA_CQ_EF_FC_CRC_OK     (1 <<  3)
+
+#define        BNA_CQ_EF_RSVD1         (1 <<  4)
+#define        BNA_CQ_EF_L4_CKSUM_OK   (1 <<  5)
+#define        BNA_CQ_EF_L3_CKSUM_OK   (1 <<  6)
+#define        BNA_CQ_EF_HDS_HEADER    (1 <<  7)
+
+#define        BNA_CQ_EF_UDP           (1 <<  8)
+#define        BNA_CQ_EF_TCP           (1 <<  9)
+#define        BNA_CQ_EF_IP_OPTIONS    (1 << 10)
+#define        BNA_CQ_EF_IPV6          (1 << 11)
+
+#define        BNA_CQ_EF_IPV4          (1 << 12)
+#define        BNA_CQ_EF_VLAN          (1 << 13)
+#define        BNA_CQ_EF_RSS           (1 << 14)
+#define        BNA_CQ_EF_RSVD2         (1 << 15)
+
+#define        BNA_CQ_EF_MCAST_MATCH   (1 << 16)
+#define        BNA_CQ_EF_MCAST         (1 << 17)
+#define BNA_CQ_EF_BCAST                (1 << 18)
+#define        BNA_CQ_EF_REMOTE        (1 << 19)
+
+#define        BNA_CQ_EF_LOCAL         (1 << 20)
+
+/**
+ *
+ * Data structures
+ *
+ */
+
+struct bna_reg_offset {
+       u32 fn_int_status;
+       u32 fn_int_mask;
+};
+
+struct bna_bit_defn {
+       u32 mbox_status_bits;
+       u32 mbox_mask_bits;
+       u32 error_status_bits;
+       u32 error_mask_bits;
+       u32 halt_status_bits;
+       u32 halt_mask_bits;
+};
+
+struct bna_reg {
+       void __iomem *fn_int_status;
+       void __iomem *fn_int_mask;
+};
+
+/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */
+struct bna_dma_addr {
+       u32             msb;
+       u32             lsb;
+};
+
+struct bna_txq_wi_vector {
+       u16             reserved;
+       u16             length;         /* Only 14 LSB are valid */
+       struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */
+};
+
+/**
+ *  TxQ Entry Structure
+ *
+ *  BEWARE:  Load values into this structure with correct endianess.
+ */
+struct bna_txq_entry {
+       union {
+               struct {
+                       u8 reserved;
+                       u8 num_vectors; /* number of vectors present */
+                       u16 opcode; /* Either */
+                                                   /* BNA_TXQ_WI_SEND or */
+                                                   /* BNA_TXQ_WI_SEND_LSO */
+                       u16 flags; /* OR of all the flags */
+                       u16 l4_hdr_size_n_offset;
+                       u16 vlan_tag;
+                       u16 lso_mss;    /* Only 14 LSB are valid */
+                       u32 frame_length;       /* Only 24 LSB are valid */
+               } wi;
+
+               struct {
+                       u16 reserved;
+                       u16 opcode; /* Must be */
+                                                   /* BNA_TXQ_WI_EXTENSION */
+                       u32 reserved2[3];       /* Place holder for */
+                                               /* removed vector (12 bytes) */
+               } wi_ext;
+       } hdr;
+       struct bna_txq_wi_vector vector[4];
+};
+
+/* RxQ Entry Structure */
+struct bna_rxq_entry {         /* Rx-Buffer */
+       struct bna_dma_addr host_addr; /* Rx-Buffer DMA address */
+};
+
+/* CQ Entry Structure */
+struct bna_cq_entry {
+       u32 flags;
+       u16 vlan_tag;
+       u16 length;
+       u32 rss_hash;
+       u8 valid;
+       u8 reserved1;
+       u8 reserved2;
+       u8 rxq_id;
+};
+
+#endif /* __BNA_HW_DEFS_H__ */
diff --git a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
new file mode 100644 (file)
index 0000000..9221413
--- /dev/null
@@ -0,0 +1,3787 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+  */
+/*
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include "bna.h"
+#include "bfi.h"
+
+/**
+ * IB
+ */
+static void
+bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo)
+{
+       ib->coalescing_timeo = coalescing_timeo;
+       ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
+                               (u32)ib->coalescing_timeo, 0);
+}
+
+/**
+ * RXF
+ */
+
+#define bna_rxf_vlan_cfg_soft_reset(rxf)                               \
+do {                                                                   \
+       (rxf)->vlan_pending_bitmask = (u8)BFI_VLAN_BMASK_ALL;           \
+       (rxf)->vlan_strip_pending = true;                               \
+} while (0)
+
+#define bna_rxf_rss_cfg_soft_reset(rxf)                                        \
+do {                                                                   \
+       if ((rxf)->rss_status == BNA_STATUS_T_ENABLED)                  \
+               (rxf)->rss_pending = (BNA_RSS_F_RIT_PENDING |           \
+                               BNA_RSS_F_CFG_PENDING |                 \
+                               BNA_RSS_F_STATUS_PENDING);              \
+} while (0)
+
+static int bna_rxf_cfg_apply(struct bna_rxf *rxf);
+static void bna_rxf_cfg_reset(struct bna_rxf *rxf);
+static int bna_rxf_fltr_clear(struct bna_rxf *rxf);
+static int bna_rxf_ucast_cfg_apply(struct bna_rxf *rxf);
+static int bna_rxf_promisc_cfg_apply(struct bna_rxf *rxf);
+static int bna_rxf_allmulti_cfg_apply(struct bna_rxf *rxf);
+static int bna_rxf_vlan_strip_cfg_apply(struct bna_rxf *rxf);
+static int bna_rxf_ucast_cfg_reset(struct bna_rxf *rxf,
+                                       enum bna_cleanup_type cleanup);
+static int bna_rxf_promisc_cfg_reset(struct bna_rxf *rxf,
+                                       enum bna_cleanup_type cleanup);
+static int bna_rxf_allmulti_cfg_reset(struct bna_rxf *rxf,
+                                       enum bna_cleanup_type cleanup);
+
+bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf,
+                       enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, paused, struct bna_rxf,
+                       enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, cfg_wait, struct bna_rxf,
+                       enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf,
+                       enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, fltr_clr_wait, struct bna_rxf,
+                       enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, last_resp_wait, struct bna_rxf,
+                       enum bna_rxf_event);
+
+static void
+bna_rxf_sm_stopped_entry(struct bna_rxf *rxf)
+{
+       call_rxf_stop_cbfn(rxf);
+}
+
+static void
+bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+       switch (event) {
+       case RXF_E_START:
+               if (rxf->flags & BNA_RXF_F_PAUSED) {
+                       bfa_fsm_set_state(rxf, bna_rxf_sm_paused);
+                       call_rxf_start_cbfn(rxf);
+               } else
+                       bfa_fsm_set_state(rxf, bna_rxf_sm_cfg_wait);
+               break;
+
+       case RXF_E_STOP:
+               call_rxf_stop_cbfn(rxf);
+               break;
+
+       case RXF_E_FAIL:
+               /* No-op */
+               break;
+
+       case RXF_E_CONFIG:
+               call_rxf_cam_fltr_cbfn(rxf);
+               break;
+
+       case RXF_E_PAUSE:
+               rxf->flags |= BNA_RXF_F_PAUSED;
+               call_rxf_pause_cbfn(rxf);
+               break;
+
+       case RXF_E_RESUME:
+               rxf->flags &= ~BNA_RXF_F_PAUSED;
+               call_rxf_resume_cbfn(rxf);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_rxf_sm_paused_entry(struct bna_rxf *rxf)
+{
+       call_rxf_pause_cbfn(rxf);
+}
+
+static void
+bna_rxf_sm_paused(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+       switch (event) {
+       case RXF_E_STOP:
+       case RXF_E_FAIL:
+               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+               break;
+
+       case RXF_E_CONFIG:
+               call_rxf_cam_fltr_cbfn(rxf);
+               break;
+
+       case RXF_E_RESUME:
+               rxf->flags &= ~BNA_RXF_F_PAUSED;
+               bfa_fsm_set_state(rxf, bna_rxf_sm_cfg_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_rxf_sm_cfg_wait_entry(struct bna_rxf *rxf)
+{
+       if (!bna_rxf_cfg_apply(rxf)) {
+               /* No more pending config updates */
+               bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+       }
+}
+
+static void
+bna_rxf_sm_cfg_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+       switch (event) {
+       case RXF_E_STOP:
+               bfa_fsm_set_state(rxf, bna_rxf_sm_last_resp_wait);
+               break;
+
+       case RXF_E_FAIL:
+               bna_rxf_cfg_reset(rxf);
+               call_rxf_start_cbfn(rxf);
+               call_rxf_cam_fltr_cbfn(rxf);
+               call_rxf_resume_cbfn(rxf);
+               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+               break;
+
+       case RXF_E_CONFIG:
+               /* No-op */
+               break;
+
+       case RXF_E_PAUSE:
+               rxf->flags |= BNA_RXF_F_PAUSED;
+               call_rxf_start_cbfn(rxf);
+               bfa_fsm_set_state(rxf, bna_rxf_sm_fltr_clr_wait);
+               break;
+
+       case RXF_E_FW_RESP:
+               if (!bna_rxf_cfg_apply(rxf)) {
+                       /* No more pending config updates */
+                       bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+               }
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_rxf_sm_started_entry(struct bna_rxf *rxf)
+{
+       call_rxf_start_cbfn(rxf);
+       call_rxf_cam_fltr_cbfn(rxf);
+       call_rxf_resume_cbfn(rxf);
+}
+
+static void
+bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+       switch (event) {
+       case RXF_E_STOP:
+       case RXF_E_FAIL:
+               bna_rxf_cfg_reset(rxf);
+               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+               break;
+
+       case RXF_E_CONFIG:
+               bfa_fsm_set_state(rxf, bna_rxf_sm_cfg_wait);
+               break;
+
+       case RXF_E_PAUSE:
+               rxf->flags |= BNA_RXF_F_PAUSED;
+               if (!bna_rxf_fltr_clear(rxf))
+                       bfa_fsm_set_state(rxf, bna_rxf_sm_paused);
+               else
+                       bfa_fsm_set_state(rxf, bna_rxf_sm_fltr_clr_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_rxf_sm_fltr_clr_wait_entry(struct bna_rxf *rxf)
+{
+}
+
+static void
+bna_rxf_sm_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+       switch (event) {
+       case RXF_E_FAIL:
+               bna_rxf_cfg_reset(rxf);
+               call_rxf_pause_cbfn(rxf);
+               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+               break;
+
+       case RXF_E_FW_RESP:
+               if (!bna_rxf_fltr_clear(rxf)) {
+                       /* No more pending CAM entries to clear */
+                       bfa_fsm_set_state(rxf, bna_rxf_sm_paused);
+               }
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_rxf_sm_last_resp_wait_entry(struct bna_rxf *rxf)
+{
+}
+
+static void
+bna_rxf_sm_last_resp_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+       switch (event) {
+       case RXF_E_FAIL:
+       case RXF_E_FW_RESP:
+               bna_rxf_cfg_reset(rxf);
+               bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_bfi_ucast_req(struct bna_rxf *rxf, struct bna_mac *mac,
+               enum bfi_enet_h2i_msgs req_type)
+{
+       struct bfi_enet_ucast_req *req = &rxf->bfi_enet_cmd.ucast_req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET, req_type, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+       bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_ucast_req)));
+       memcpy(&req->mac_addr, &mac->addr, sizeof(mac_t));
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_ucast_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_mcast_add_req(struct bna_rxf *rxf, struct bna_mac *mac)
+{
+       struct bfi_enet_mcast_add_req *req =
+               &rxf->bfi_enet_cmd.mcast_add_req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET, BFI_ENET_H2I_MAC_MCAST_ADD_REQ,
+               0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+       bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_mcast_add_req)));
+       memcpy(&req->mac_addr, &mac->addr, sizeof(mac_t));
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_mcast_add_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_mcast_del_req(struct bna_rxf *rxf, u16 handle)
+{
+       struct bfi_enet_mcast_del_req *req =
+               &rxf->bfi_enet_cmd.mcast_del_req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET, BFI_ENET_H2I_MAC_MCAST_DEL_REQ,
+               0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+       bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_mcast_del_req)));
+       req->handle = htons(handle);
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_mcast_del_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_mcast_filter_req(struct bna_rxf *rxf, enum bna_status status)
+{
+       struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_MAC_MCAST_FILTER_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
+       req->enable = status;
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_enable_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_rx_promisc_req(struct bna_rxf *rxf, enum bna_status status)
+{
+       struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RX_PROMISCUOUS_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
+       req->enable = status;
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_enable_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_rx_vlan_filter_set(struct bna_rxf *rxf, u8 block_idx)
+{
+       struct bfi_enet_rx_vlan_req *req = &rxf->bfi_enet_cmd.vlan_req;
+       int i;
+       int j;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RX_VLAN_SET_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rx_vlan_req)));
+       req->block_idx = block_idx;
+       for (i = 0; i < (BFI_ENET_VLAN_BLOCK_SIZE / 32); i++) {
+               j = (block_idx * (BFI_ENET_VLAN_BLOCK_SIZE / 32)) + i;
+               if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED)
+                       req->bit_mask[i] =
+                               htonl(rxf->vlan_filter_table[j]);
+               else
+                       req->bit_mask[i] = 0xFFFFFFFF;
+       }
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_rx_vlan_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_vlan_strip_enable(struct bna_rxf *rxf)
+{
+       struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RX_VLAN_STRIP_ENABLE_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
+       req->enable = rxf->vlan_strip_status;
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_enable_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_rit_cfg(struct bna_rxf *rxf)
+{
+       struct bfi_enet_rit_req *req = &rxf->bfi_enet_cmd.rit_req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RIT_CFG_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rit_req)));
+       req->size = htons(rxf->rit_size);
+       memcpy(&req->table[0], rxf->rit, rxf->rit_size);
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_rit_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_rss_cfg(struct bna_rxf *rxf)
+{
+       struct bfi_enet_rss_cfg_req *req = &rxf->bfi_enet_cmd.rss_req;
+       int i;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RSS_CFG_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rss_cfg_req)));
+       req->cfg.type = rxf->rss_cfg.hash_type;
+       req->cfg.mask = rxf->rss_cfg.hash_mask;
+       for (i = 0; i < BFI_ENET_RSS_KEY_LEN; i++)
+               req->cfg.key[i] =
+                       htonl(rxf->rss_cfg.toeplitz_hash_key[i]);
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_rss_cfg_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+static void
+bna_bfi_rss_enable(struct bna_rxf *rxf)
+{
+       struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RSS_ENABLE_REQ, 0, rxf->rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
+       req->enable = rxf->rss_status;
+       bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_enable_req), &req->mh);
+       bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
+}
+
+/* This function gets the multicast MAC that has already been added to CAM */
+static struct bna_mac *
+bna_rxf_mcmac_get(struct bna_rxf *rxf, u8 *mac_addr)
+{
+       struct bna_mac *mac;
+       struct list_head *qe;
+
+       list_for_each(qe, &rxf->mcast_active_q) {
+               mac = (struct bna_mac *)qe;
+               if (BNA_MAC_IS_EQUAL(&mac->addr, mac_addr))
+                       return mac;
+       }
+
+       list_for_each(qe, &rxf->mcast_pending_del_q) {
+               mac = (struct bna_mac *)qe;
+               if (BNA_MAC_IS_EQUAL(&mac->addr, mac_addr))
+                       return mac;
+       }
+
+       return NULL;
+}
+
+static struct bna_mcam_handle *
+bna_rxf_mchandle_get(struct bna_rxf *rxf, int handle)
+{
+       struct bna_mcam_handle *mchandle;
+       struct list_head *qe;
+
+       list_for_each(qe, &rxf->mcast_handle_q) {
+               mchandle = (struct bna_mcam_handle *)qe;
+               if (mchandle->handle == handle)
+                       return mchandle;
+       }
+
+       return NULL;
+}
+
+static void
+bna_rxf_mchandle_attach(struct bna_rxf *rxf, u8 *mac_addr, int handle)
+{
+       struct bna_mac *mcmac;
+       struct bna_mcam_handle *mchandle;
+
+       mcmac = bna_rxf_mcmac_get(rxf, mac_addr);
+       mchandle = bna_rxf_mchandle_get(rxf, handle);
+       if (mchandle == NULL) {
+               mchandle = bna_mcam_mod_handle_get(&rxf->rx->bna->mcam_mod);
+               mchandle->handle = handle;
+               mchandle->refcnt = 0;
+               list_add_tail(&mchandle->qe, &rxf->mcast_handle_q);
+       }
+       mchandle->refcnt++;
+       mcmac->handle = mchandle;
+}
+
+static int
+bna_rxf_mcast_del(struct bna_rxf *rxf, struct bna_mac *mac,
+               enum bna_cleanup_type cleanup)
+{
+       struct bna_mcam_handle *mchandle;
+       int ret = 0;
+
+       mchandle = mac->handle;
+       if (mchandle == NULL)
+               return ret;
+
+       mchandle->refcnt--;
+       if (mchandle->refcnt == 0) {
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       bna_bfi_mcast_del_req(rxf, mchandle->handle);
+                       ret = 1;
+               }
+               list_del(&mchandle->qe);
+               bfa_q_qe_init(&mchandle->qe);
+               bna_mcam_mod_handle_put(&rxf->rx->bna->mcam_mod, mchandle);
+       }
+       mac->handle = NULL;
+
+       return ret;
+}
+
+static int
+bna_rxf_mcast_cfg_apply(struct bna_rxf *rxf)
+{
+       struct bna_mac *mac = NULL;
+       struct list_head *qe;
+       int ret;
+
+       /* Delete multicast entries previousely added */
+       while (!list_empty(&rxf->mcast_pending_del_q)) {
+               bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               ret = bna_rxf_mcast_del(rxf, mac, BNA_HARD_CLEANUP);
+               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+               if (ret)
+                       return ret;
+       }
+
+       /* Add multicast entries */
+       if (!list_empty(&rxf->mcast_pending_add_q)) {
+               bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               list_add_tail(&mac->qe, &rxf->mcast_active_q);
+               bna_bfi_mcast_add_req(rxf, mac);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_vlan_cfg_apply(struct bna_rxf *rxf)
+{
+       u8 vlan_pending_bitmask;
+       int block_idx = 0;
+
+       if (rxf->vlan_pending_bitmask) {
+               vlan_pending_bitmask = rxf->vlan_pending_bitmask;
+               while (!(vlan_pending_bitmask & 0x1)) {
+                       block_idx++;
+                       vlan_pending_bitmask >>= 1;
+               }
+               rxf->vlan_pending_bitmask &= ~(1 << block_idx);
+               bna_bfi_rx_vlan_filter_set(rxf, block_idx);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_mcast_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
+{
+       struct list_head *qe;
+       struct bna_mac *mac;
+       int ret;
+
+       /* Throw away delete pending mcast entries */
+       while (!list_empty(&rxf->mcast_pending_del_q)) {
+               bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               ret = bna_rxf_mcast_del(rxf, mac, cleanup);
+               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+               if (ret)
+                       return ret;
+       }
+
+       /* Move active mcast entries to pending_add_q */
+       while (!list_empty(&rxf->mcast_active_q)) {
+               bfa_q_deq(&rxf->mcast_active_q, &qe);
+               bfa_q_qe_init(qe);
+               list_add_tail(qe, &rxf->mcast_pending_add_q);
+               mac = (struct bna_mac *)qe;
+               if (bna_rxf_mcast_del(rxf, mac, cleanup))
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_rss_cfg_apply(struct bna_rxf *rxf)
+{
+       if (rxf->rss_pending) {
+               if (rxf->rss_pending & BNA_RSS_F_RIT_PENDING) {
+                       rxf->rss_pending &= ~BNA_RSS_F_RIT_PENDING;
+                       bna_bfi_rit_cfg(rxf);
+                       return 1;
+               }
+
+               if (rxf->rss_pending & BNA_RSS_F_CFG_PENDING) {
+                       rxf->rss_pending &= ~BNA_RSS_F_CFG_PENDING;
+                       bna_bfi_rss_cfg(rxf);
+                       return 1;
+               }
+
+               if (rxf->rss_pending & BNA_RSS_F_STATUS_PENDING) {
+                       rxf->rss_pending &= ~BNA_RSS_F_STATUS_PENDING;
+                       bna_bfi_rss_enable(rxf);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_cfg_apply(struct bna_rxf *rxf)
+{
+       if (bna_rxf_ucast_cfg_apply(rxf))
+               return 1;
+
+       if (bna_rxf_mcast_cfg_apply(rxf))
+               return 1;
+
+       if (bna_rxf_promisc_cfg_apply(rxf))
+               return 1;
+
+       if (bna_rxf_allmulti_cfg_apply(rxf))
+               return 1;
+
+       if (bna_rxf_vlan_cfg_apply(rxf))
+               return 1;
+
+       if (bna_rxf_vlan_strip_cfg_apply(rxf))
+               return 1;
+
+       if (bna_rxf_rss_cfg_apply(rxf))
+               return 1;
+
+       return 0;
+}
+
+/* Only software reset */
+static int
+bna_rxf_fltr_clear(struct bna_rxf *rxf)
+{
+       if (bna_rxf_ucast_cfg_reset(rxf, BNA_HARD_CLEANUP))
+               return 1;
+
+       if (bna_rxf_mcast_cfg_reset(rxf, BNA_HARD_CLEANUP))
+               return 1;
+
+       if (bna_rxf_promisc_cfg_reset(rxf, BNA_HARD_CLEANUP))
+               return 1;
+
+       if (bna_rxf_allmulti_cfg_reset(rxf, BNA_HARD_CLEANUP))
+               return 1;
+
+       return 0;
+}
+
+static void
+bna_rxf_cfg_reset(struct bna_rxf *rxf)
+{
+       bna_rxf_ucast_cfg_reset(rxf, BNA_SOFT_CLEANUP);
+       bna_rxf_mcast_cfg_reset(rxf, BNA_SOFT_CLEANUP);
+       bna_rxf_promisc_cfg_reset(rxf, BNA_SOFT_CLEANUP);
+       bna_rxf_allmulti_cfg_reset(rxf, BNA_SOFT_CLEANUP);
+       bna_rxf_vlan_cfg_soft_reset(rxf);
+       bna_rxf_rss_cfg_soft_reset(rxf);
+}
+
+static void
+bna_rit_init(struct bna_rxf *rxf, int rit_size)
+{
+       struct bna_rx *rx = rxf->rx;
+       struct bna_rxp *rxp;
+       struct list_head *qe;
+       int offset = 0;
+
+       rxf->rit_size = rit_size;
+       list_for_each(qe, &rx->rxp_q) {
+               rxp = (struct bna_rxp *)qe;
+               rxf->rit[offset] = rxp->cq.ccb->id;
+               offset++;
+       }
+
+}
+
+void
+bna_bfi_rxf_cfg_rsp(struct bna_rxf *rxf, struct bfi_msgq_mhdr *msghdr)
+{
+       bfa_fsm_send_event(rxf, RXF_E_FW_RESP);
+}
+
+void
+bna_bfi_rxf_mcast_add_rsp(struct bna_rxf *rxf,
+                       struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_mcast_add_req *req =
+               &rxf->bfi_enet_cmd.mcast_add_req;
+       struct bfi_enet_mcast_add_rsp *rsp =
+               (struct bfi_enet_mcast_add_rsp *)msghdr;
+
+       bna_rxf_mchandle_attach(rxf, (u8 *)&req->mac_addr,
+               ntohs(rsp->handle));
+       bfa_fsm_send_event(rxf, RXF_E_FW_RESP);
+}
+
+static void
+bna_rxf_init(struct bna_rxf *rxf,
+               struct bna_rx *rx,
+               struct bna_rx_config *q_config,
+               struct bna_res_info *res_info)
+{
+       rxf->rx = rx;
+
+       INIT_LIST_HEAD(&rxf->ucast_pending_add_q);
+       INIT_LIST_HEAD(&rxf->ucast_pending_del_q);
+       rxf->ucast_pending_set = 0;
+       rxf->ucast_active_set = 0;
+       INIT_LIST_HEAD(&rxf->ucast_active_q);
+       rxf->ucast_pending_mac = NULL;
+
+       INIT_LIST_HEAD(&rxf->mcast_pending_add_q);
+       INIT_LIST_HEAD(&rxf->mcast_pending_del_q);
+       INIT_LIST_HEAD(&rxf->mcast_active_q);
+       INIT_LIST_HEAD(&rxf->mcast_handle_q);
+
+       if (q_config->paused)
+               rxf->flags |= BNA_RXF_F_PAUSED;
+
+       rxf->rit = (u8 *)
+               res_info[BNA_RX_RES_MEM_T_RIT].res_u.mem_info.mdl[0].kva;
+       bna_rit_init(rxf, q_config->num_paths);
+
+       rxf->rss_status = q_config->rss_status;
+       if (rxf->rss_status == BNA_STATUS_T_ENABLED) {
+               rxf->rss_cfg = q_config->rss_config;
+               rxf->rss_pending |= BNA_RSS_F_CFG_PENDING;
+               rxf->rss_pending |= BNA_RSS_F_RIT_PENDING;
+               rxf->rss_pending |= BNA_RSS_F_STATUS_PENDING;
+       }
+
+       rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
+       memset(rxf->vlan_filter_table, 0,
+                       (sizeof(u32) * (BFI_ENET_VLAN_ID_MAX / 32)));
+       rxf->vlan_filter_table[0] |= 1; /* for pure priority tagged frames */
+       rxf->vlan_pending_bitmask = (u8)BFI_VLAN_BMASK_ALL;
+
+       rxf->vlan_strip_status = q_config->vlan_strip_status;
+
+       bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+}
+
+static void
+bna_rxf_uninit(struct bna_rxf *rxf)
+{
+       struct bna_mac *mac;
+
+       rxf->ucast_pending_set = 0;
+       rxf->ucast_active_set = 0;
+
+       while (!list_empty(&rxf->ucast_pending_add_q)) {
+               bfa_q_deq(&rxf->ucast_pending_add_q, &mac);
+               bfa_q_qe_init(&mac->qe);
+               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+       }
+
+       if (rxf->ucast_pending_mac) {
+               bfa_q_qe_init(&rxf->ucast_pending_mac->qe);
+               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod,
+                       rxf->ucast_pending_mac);
+               rxf->ucast_pending_mac = NULL;
+       }
+
+       while (!list_empty(&rxf->mcast_pending_add_q)) {
+               bfa_q_deq(&rxf->mcast_pending_add_q, &mac);
+               bfa_q_qe_init(&mac->qe);
+               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+       }
+
+       rxf->rxmode_pending = 0;
+       rxf->rxmode_pending_bitmask = 0;
+       if (rxf->rx->bna->promisc_rid == rxf->rx->rid)
+               rxf->rx->bna->promisc_rid = BFI_INVALID_RID;
+       if (rxf->rx->bna->default_mode_rid == rxf->rx->rid)
+               rxf->rx->bna->default_mode_rid = BFI_INVALID_RID;
+
+       rxf->rss_pending = 0;
+       rxf->vlan_strip_pending = false;
+
+       rxf->flags = 0;
+
+       rxf->rx = NULL;
+}
+
+static void
+bna_rx_cb_rxf_started(struct bna_rx *rx)
+{
+       bfa_fsm_send_event(rx, RX_E_RXF_STARTED);
+}
+
+static void
+bna_rxf_start(struct bna_rxf *rxf)
+{
+       rxf->start_cbfn = bna_rx_cb_rxf_started;
+       rxf->start_cbarg = rxf->rx;
+       bfa_fsm_send_event(rxf, RXF_E_START);
+}
+
+static void
+bna_rx_cb_rxf_stopped(struct bna_rx *rx)
+{
+       bfa_fsm_send_event(rx, RX_E_RXF_STOPPED);
+}
+
+static void
+bna_rxf_stop(struct bna_rxf *rxf)
+{
+       rxf->stop_cbfn = bna_rx_cb_rxf_stopped;
+       rxf->stop_cbarg = rxf->rx;
+       bfa_fsm_send_event(rxf, RXF_E_STOP);
+}
+
+static void
+bna_rxf_fail(struct bna_rxf *rxf)
+{
+       bfa_fsm_send_event(rxf, RXF_E_FAIL);
+}
+
+enum bna_cb_status
+bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
+                void (*cbfn)(struct bnad *, struct bna_rx *))
+{
+       struct bna_rxf *rxf = &rx->rxf;
+
+       if (rxf->ucast_pending_mac == NULL) {
+               rxf->ucast_pending_mac =
+                               bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod);
+               if (rxf->ucast_pending_mac == NULL)
+                       return BNA_CB_UCAST_CAM_FULL;
+               bfa_q_qe_init(&rxf->ucast_pending_mac->qe);
+       }
+
+       memcpy(rxf->ucast_pending_mac->addr, ucmac, ETH_ALEN);
+       rxf->ucast_pending_set = 1;
+       rxf->cam_fltr_cbfn = cbfn;
+       rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+       bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+
+       return BNA_CB_SUCCESS;
+}
+
+enum bna_cb_status
+bna_rx_mcast_add(struct bna_rx *rx, u8 *addr,
+                void (*cbfn)(struct bnad *, struct bna_rx *))
+{
+       struct bna_rxf *rxf = &rx->rxf;
+       struct bna_mac *mac;
+
+       /* Check if already added or pending addition */
+       if (bna_mac_find(&rxf->mcast_active_q, addr) ||
+               bna_mac_find(&rxf->mcast_pending_add_q, addr)) {
+               if (cbfn)
+                       cbfn(rx->bna->bnad, rx);
+               return BNA_CB_SUCCESS;
+       }
+
+       mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
+       if (mac == NULL)
+               return BNA_CB_MCAST_LIST_FULL;
+       bfa_q_qe_init(&mac->qe);
+       memcpy(mac->addr, addr, ETH_ALEN);
+       list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+
+       rxf->cam_fltr_cbfn = cbfn;
+       rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+       bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+
+       return BNA_CB_SUCCESS;
+}
+
+enum bna_cb_status
+bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist,
+                    void (*cbfn)(struct bnad *, struct bna_rx *))
+{
+       struct bna_rxf *rxf = &rx->rxf;
+       struct list_head list_head;
+       struct list_head *qe;
+       u8 *mcaddr;
+       struct bna_mac *mac;
+       int i;
+
+       /* Allocate nodes */
+       INIT_LIST_HEAD(&list_head);
+       for (i = 0, mcaddr = mclist; i < count; i++) {
+               mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
+               if (mac == NULL)
+                       goto err_return;
+               bfa_q_qe_init(&mac->qe);
+               memcpy(mac->addr, mcaddr, ETH_ALEN);
+               list_add_tail(&mac->qe, &list_head);
+
+               mcaddr += ETH_ALEN;
+       }
+
+       /* Purge the pending_add_q */
+       while (!list_empty(&rxf->mcast_pending_add_q)) {
+               bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+       }
+
+       /* Schedule active_q entries for deletion */
+       while (!list_empty(&rxf->mcast_active_q)) {
+               bfa_q_deq(&rxf->mcast_active_q, &qe);
+               mac = (struct bna_mac *)qe;
+               bfa_q_qe_init(&mac->qe);
+               list_add_tail(&mac->qe, &rxf->mcast_pending_del_q);
+       }
+
+       /* Add the new entries */
+       while (!list_empty(&list_head)) {
+               bfa_q_deq(&list_head, &qe);
+               mac = (struct bna_mac *)qe;
+               bfa_q_qe_init(&mac->qe);
+               list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+       }
+
+       rxf->cam_fltr_cbfn = cbfn;
+       rxf->cam_fltr_cbarg = rx->bna->bnad;
+       bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+
+       return BNA_CB_SUCCESS;
+
+err_return:
+       while (!list_empty(&list_head)) {
+               bfa_q_deq(&list_head, &qe);
+               mac = (struct bna_mac *)qe;
+               bfa_q_qe_init(&mac->qe);
+               bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+       }
+
+       return BNA_CB_MCAST_LIST_FULL;
+}
+
+void
+bna_rx_vlan_add(struct bna_rx *rx, int vlan_id)
+{
+       struct bna_rxf *rxf = &rx->rxf;
+       int index = (vlan_id >> BFI_VLAN_WORD_SHIFT);
+       int bit = (1 << (vlan_id & BFI_VLAN_WORD_MASK));
+       int group_id = (vlan_id >> BFI_VLAN_BLOCK_SHIFT);
+
+       rxf->vlan_filter_table[index] |= bit;
+       if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+               rxf->vlan_pending_bitmask |= (1 << group_id);
+               bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+       }
+}
+
+void
+bna_rx_vlan_del(struct bna_rx *rx, int vlan_id)
+{
+       struct bna_rxf *rxf = &rx->rxf;
+       int index = (vlan_id >> BFI_VLAN_WORD_SHIFT);
+       int bit = (1 << (vlan_id & BFI_VLAN_WORD_MASK));
+       int group_id = (vlan_id >> BFI_VLAN_BLOCK_SHIFT);
+
+       rxf->vlan_filter_table[index] &= ~bit;
+       if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+               rxf->vlan_pending_bitmask |= (1 << group_id);
+               bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+       }
+}
+
+static int
+bna_rxf_ucast_cfg_apply(struct bna_rxf *rxf)
+{
+       struct bna_mac *mac = NULL;
+       struct list_head *qe;
+
+       /* Delete MAC addresses previousely added */
+       if (!list_empty(&rxf->ucast_pending_del_q)) {
+               bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               bna_bfi_ucast_req(rxf, mac, BFI_ENET_H2I_MAC_UCAST_DEL_REQ);
+               bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+               return 1;
+       }
+
+       /* Set default unicast MAC */
+       if (rxf->ucast_pending_set) {
+               rxf->ucast_pending_set = 0;
+               memcpy(rxf->ucast_active_mac.addr,
+                       rxf->ucast_pending_mac->addr, ETH_ALEN);
+               rxf->ucast_active_set = 1;
+               bna_bfi_ucast_req(rxf, &rxf->ucast_active_mac,
+                       BFI_ENET_H2I_MAC_UCAST_SET_REQ);
+               return 1;
+       }
+
+       /* Add additional MAC entries */
+       if (!list_empty(&rxf->ucast_pending_add_q)) {
+               bfa_q_deq(&rxf->ucast_pending_add_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               list_add_tail(&mac->qe, &rxf->ucast_active_q);
+               bna_bfi_ucast_req(rxf, mac, BFI_ENET_H2I_MAC_UCAST_ADD_REQ);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_ucast_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
+{
+       struct list_head *qe;
+       struct bna_mac *mac;
+
+       /* Throw away delete pending ucast entries */
+       while (!list_empty(&rxf->ucast_pending_del_q)) {
+               bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+               bfa_q_qe_init(qe);
+               mac = (struct bna_mac *)qe;
+               if (cleanup == BNA_SOFT_CLEANUP)
+                       bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+               else {
+                       bna_bfi_ucast_req(rxf, mac,
+                               BFI_ENET_H2I_MAC_UCAST_DEL_REQ);
+                       bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+                       return 1;
+               }
+       }
+
+       /* Move active ucast entries to pending_add_q */
+       while (!list_empty(&rxf->ucast_active_q)) {
+               bfa_q_deq(&rxf->ucast_active_q, &qe);
+               bfa_q_qe_init(qe);
+               list_add_tail(qe, &rxf->ucast_pending_add_q);
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       mac = (struct bna_mac *)qe;
+                       bna_bfi_ucast_req(rxf, mac,
+                               BFI_ENET_H2I_MAC_UCAST_DEL_REQ);
+                       return 1;
+               }
+       }
+
+       if (rxf->ucast_active_set) {
+               rxf->ucast_pending_set = 1;
+               rxf->ucast_active_set = 0;
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       bna_bfi_ucast_req(rxf, &rxf->ucast_active_mac,
+                               BFI_ENET_H2I_MAC_UCAST_CLR_REQ);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_promisc_cfg_apply(struct bna_rxf *rxf)
+{
+       struct bna *bna = rxf->rx->bna;
+
+       /* Enable/disable promiscuous mode */
+       if (is_promisc_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask)) {
+               /* move promisc configuration from pending -> active */
+               promisc_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active |= BNA_RXMODE_PROMISC;
+               bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_ENABLED);
+               return 1;
+       } else if (is_promisc_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask)) {
+               /* move promisc configuration from pending -> active */
+               promisc_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+               bna->promisc_rid = BFI_INVALID_RID;
+               bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_DISABLED);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_promisc_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
+{
+       struct bna *bna = rxf->rx->bna;
+
+       /* Clear pending promisc mode disable */
+       if (is_promisc_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask)) {
+               promisc_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+               bna->promisc_rid = BFI_INVALID_RID;
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_DISABLED);
+                       return 1;
+               }
+       }
+
+       /* Move promisc mode config from active -> pending */
+       if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+               promisc_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_DISABLED);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_allmulti_cfg_apply(struct bna_rxf *rxf)
+{
+       /* Enable/disable allmulti mode */
+       if (is_allmulti_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask)) {
+               /* move allmulti configuration from pending -> active */
+               allmulti_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active |= BNA_RXMODE_ALLMULTI;
+               bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_DISABLED);
+               return 1;
+       } else if (is_allmulti_disable(rxf->rxmode_pending,
+                                       rxf->rxmode_pending_bitmask)) {
+               /* move allmulti configuration from pending -> active */
+               allmulti_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+               bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_ENABLED);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_allmulti_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
+{
+       /* Clear pending allmulti mode disable */
+       if (is_allmulti_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask)) {
+               allmulti_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_ENABLED);
+                       return 1;
+               }
+       }
+
+       /* Move allmulti mode config from active -> pending */
+       if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+               allmulti_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+               if (cleanup == BNA_HARD_CLEANUP) {
+                       bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_ENABLED);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int
+bna_rxf_promisc_enable(struct bna_rxf *rxf)
+{
+       struct bna *bna = rxf->rx->bna;
+       int ret = 0;
+
+       if (is_promisc_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask) ||
+               (rxf->rxmode_active & BNA_RXMODE_PROMISC)) {
+               /* Do nothing if pending enable or already enabled */
+       } else if (is_promisc_disable(rxf->rxmode_pending,
+                                       rxf->rxmode_pending_bitmask)) {
+               /* Turn off pending disable command */
+               promisc_inactive(rxf->rxmode_pending,
+                       rxf->rxmode_pending_bitmask);
+       } else {
+               /* Schedule enable */
+               promisc_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               bna->promisc_rid = rxf->rx->rid;
+               ret = 1;
+       }
+
+       return ret;
+}
+
+static int
+bna_rxf_promisc_disable(struct bna_rxf *rxf)
+{
+       struct bna *bna = rxf->rx->bna;
+       int ret = 0;
+
+       if (is_promisc_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask) ||
+               (!(rxf->rxmode_active & BNA_RXMODE_PROMISC))) {
+               /* Do nothing if pending disable or already disabled */
+       } else if (is_promisc_enable(rxf->rxmode_pending,
+                                       rxf->rxmode_pending_bitmask)) {
+               /* Turn off pending enable command */
+               promisc_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               bna->promisc_rid = BFI_INVALID_RID;
+       } else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+               /* Schedule disable */
+               promisc_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               ret = 1;
+       }
+
+       return ret;
+}
+
+static int
+bna_rxf_allmulti_enable(struct bna_rxf *rxf)
+{
+       int ret = 0;
+
+       if (is_allmulti_enable(rxf->rxmode_pending,
+                       rxf->rxmode_pending_bitmask) ||
+                       (rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) {
+               /* Do nothing if pending enable or already enabled */
+       } else if (is_allmulti_disable(rxf->rxmode_pending,
+                                       rxf->rxmode_pending_bitmask)) {
+               /* Turn off pending disable command */
+               allmulti_inactive(rxf->rxmode_pending,
+                       rxf->rxmode_pending_bitmask);
+       } else {
+               /* Schedule enable */
+               allmulti_enable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               ret = 1;
+       }
+
+       return ret;
+}
+
+static int
+bna_rxf_allmulti_disable(struct bna_rxf *rxf)
+{
+       int ret = 0;
+
+       if (is_allmulti_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask) ||
+               (!(rxf->rxmode_active & BNA_RXMODE_ALLMULTI))) {
+               /* Do nothing if pending disable or already disabled */
+       } else if (is_allmulti_enable(rxf->rxmode_pending,
+                                       rxf->rxmode_pending_bitmask)) {
+               /* Turn off pending enable command */
+               allmulti_inactive(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+       } else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+               /* Schedule disable */
+               allmulti_disable(rxf->rxmode_pending,
+                               rxf->rxmode_pending_bitmask);
+               ret = 1;
+       }
+
+       return ret;
+}
+
+static int
+bna_rxf_vlan_strip_cfg_apply(struct bna_rxf *rxf)
+{
+       if (rxf->vlan_strip_pending) {
+                       rxf->vlan_strip_pending = false;
+                       bna_bfi_vlan_strip_enable(rxf);
+                       return 1;
+       }
+
+       return 0;
+}
+
+/**
+ * RX
+ */
+
+#define        BNA_GET_RXQS(qcfg)      (((qcfg)->rxp_type == BNA_RXP_SINGLE) ? \
+       (qcfg)->num_paths : ((qcfg)->num_paths * 2))
+
+#define        SIZE_TO_PAGES(size)     (((size) >> PAGE_SHIFT) + ((((size) &\
+       (PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
+
+#define        call_rx_stop_cbfn(rx)                                           \
+do {                                                               \
+       if ((rx)->stop_cbfn) {                                          \
+               void (*cbfn)(void *, struct bna_rx *);    \
+               void *cbarg;                                        \
+               cbfn = (rx)->stop_cbfn;                          \
+               cbarg = (rx)->stop_cbarg;                              \
+               (rx)->stop_cbfn = NULL;                                 \
+               (rx)->stop_cbarg = NULL;                                \
+               cbfn(cbarg, rx);                                        \
+       }                                                              \
+} while (0)
+
+#define bfi_enet_datapath_q_init(bfi_q, bna_qpt)                       \
+do {                                                                   \
+       struct bna_dma_addr cur_q_addr =                                \
+               *((struct bna_dma_addr *)((bna_qpt)->kv_qpt_ptr));      \
+       (bfi_q)->pg_tbl.a32.addr_lo = (bna_qpt)->hw_qpt_ptr.lsb;        \
+       (bfi_q)->pg_tbl.a32.addr_hi = (bna_qpt)->hw_qpt_ptr.msb;        \
+       (bfi_q)->first_entry.a32.addr_lo = cur_q_addr.lsb;              \
+       (bfi_q)->first_entry.a32.addr_hi = cur_q_addr.msb;              \
+       (bfi_q)->pages = htons((u16)(bna_qpt)->page_count);     \
+       (bfi_q)->page_sz = htons((u16)(bna_qpt)->page_size);\
+} while (0)
+
+static void bna_bfi_rx_enet_start(struct bna_rx *rx);
+static void bna_rx_enet_stop(struct bna_rx *rx);
+static void bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx);
+
+bfa_fsm_state_decl(bna_rx, stopped,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, start_wait,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxf_start_wait,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, started,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxf_stop_wait,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, stop_wait,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, cleanup_wait,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, failed,
+       struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, quiesce_wait,
+       struct bna_rx, enum bna_rx_event);
+
+static void bna_rx_sm_stopped_entry(struct bna_rx *rx)
+{
+       call_rx_stop_cbfn(rx);
+}
+
+static void bna_rx_sm_stopped(struct bna_rx *rx,
+                               enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_START:
+               bfa_fsm_set_state(rx, bna_rx_sm_start_wait);
+               break;
+
+       case RX_E_STOP:
+               call_rx_stop_cbfn(rx);
+               break;
+
+       case RX_E_FAIL:
+               /* no-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+static void bna_rx_sm_start_wait_entry(struct bna_rx *rx)
+{
+       bna_bfi_rx_enet_start(rx);
+}
+
+void
+bna_rx_sm_stop_wait_entry(struct bna_rx *rx)
+{
+}
+
+static void
+bna_rx_sm_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_FAIL:
+       case RX_E_STOPPED:
+               bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
+               rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
+               break;
+
+       case RX_E_STARTED:
+               bna_rx_enet_stop(rx);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+static void bna_rx_sm_start_wait(struct bna_rx *rx,
+                               enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_STOP:
+               bfa_fsm_set_state(rx, bna_rx_sm_stop_wait);
+               break;
+
+       case RX_E_FAIL:
+               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+               break;
+
+       case RX_E_STARTED:
+               bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx)
+{
+       rx->rx_post_cbfn(rx->bna->bnad, rx);
+       bna_rxf_start(&rx->rxf);
+}
+
+void
+bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx)
+{
+}
+
+static void
+bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_FAIL:
+               bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
+               bna_rxf_fail(&rx->rxf);
+               rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
+               break;
+
+       case RX_E_RXF_STARTED:
+               bna_rxf_stop(&rx->rxf);
+               break;
+
+       case RX_E_RXF_STOPPED:
+               bfa_fsm_set_state(rx, bna_rx_sm_stop_wait);
+               bna_rx_enet_stop(rx);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+
+}
+
+void
+bna_rx_sm_started_entry(struct bna_rx *rx)
+{
+       struct bna_rxp *rxp;
+       struct list_head *qe_rxp;
+       int is_regular = (rx->type == BNA_RX_T_REGULAR);
+
+       /* Start IB */
+       list_for_each(qe_rxp, &rx->rxp_q) {
+               rxp = (struct bna_rxp *)qe_rxp;
+               bna_ib_start(rx->bna, &rxp->cq.ib, is_regular);
+       }
+
+       bna_ethport_cb_rx_started(&rx->bna->ethport);
+}
+
+static void
+bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_STOP:
+               bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
+               bna_ethport_cb_rx_stopped(&rx->bna->ethport);
+               bna_rxf_stop(&rx->rxf);
+               break;
+
+       case RX_E_FAIL:
+               bfa_fsm_set_state(rx, bna_rx_sm_failed);
+               bna_ethport_cb_rx_stopped(&rx->bna->ethport);
+               bna_rxf_fail(&rx->rxf);
+               rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
+                               enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_STOP:
+               bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
+               break;
+
+       case RX_E_FAIL:
+               bfa_fsm_set_state(rx, bna_rx_sm_failed);
+               bna_rxf_fail(&rx->rxf);
+               rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
+               break;
+
+       case RX_E_RXF_STARTED:
+               bfa_fsm_set_state(rx, bna_rx_sm_started);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+void
+bna_rx_sm_cleanup_wait_entry(struct bna_rx *rx)
+{
+}
+
+void
+bna_rx_sm_cleanup_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_FAIL:
+       case RX_E_RXF_STOPPED:
+               /* No-op */
+               break;
+
+       case RX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+static void
+bna_rx_sm_failed_entry(struct bna_rx *rx)
+{
+}
+
+static void
+bna_rx_sm_failed(struct bna_rx *rx, enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_START:
+               bfa_fsm_set_state(rx, bna_rx_sm_quiesce_wait);
+               break;
+
+       case RX_E_STOP:
+               bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
+               break;
+
+       case RX_E_FAIL:
+       case RX_E_RXF_STARTED:
+       case RX_E_RXF_STOPPED:
+               /* No-op */
+               break;
+
+       case RX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+}      }
+
+static void
+bna_rx_sm_quiesce_wait_entry(struct bna_rx *rx)
+{
+}
+
+static void
+bna_rx_sm_quiesce_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+       switch (event) {
+       case RX_E_STOP:
+               bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
+               break;
+
+       case RX_E_FAIL:
+               bfa_fsm_set_state(rx, bna_rx_sm_failed);
+               break;
+
+       case RX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(rx, bna_rx_sm_start_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+               break;
+       }
+}
+
+static void
+bna_bfi_rx_enet_start(struct bna_rx *rx)
+{
+       struct bfi_enet_rx_cfg_req *cfg_req = &rx->bfi_enet_cmd.cfg_req;
+       struct bna_rxp *rxp = NULL;
+       struct bna_rxq *q0 = NULL, *q1 = NULL;
+       struct list_head *rxp_qe;
+       int i;
+
+       bfi_msgq_mhdr_set(cfg_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RX_CFG_SET_REQ, 0, rx->rid);
+       cfg_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rx_cfg_req)));
+
+       cfg_req->num_queue_sets = rx->num_paths;
+       for (i = 0, rxp_qe = bfa_q_first(&rx->rxp_q);
+               i < rx->num_paths;
+               i++, rxp_qe = bfa_q_next(rxp_qe)) {
+               rxp = (struct bna_rxp *)rxp_qe;
+
+               GET_RXQS(rxp, q0, q1);
+               switch (rxp->type) {
+               case BNA_RXP_SLR:
+               case BNA_RXP_HDS:
+                       /* Small RxQ */
+                       bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].qs.q,
+                                               &q1->qpt);
+                       cfg_req->q_cfg[i].qs.rx_buffer_size =
+                               htons((u16)q1->buffer_size);
+                       /* Fall through */
+
+               case BNA_RXP_SINGLE:
+                       /* Large/Single RxQ */
+                       bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].ql.q,
+                                               &q0->qpt);
+                       q0->buffer_size =
+                               bna_enet_mtu_get(&rx->bna->enet);
+                       cfg_req->q_cfg[i].ql.rx_buffer_size =
+                               htons((u16)q0->buffer_size);
+                       break;
+
+               default:
+                       BUG_ON(1);
+               }
+
+               bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].cq.q,
+                                       &rxp->cq.qpt);
+
+               cfg_req->q_cfg[i].ib.index_addr.a32.addr_lo =
+                       rxp->cq.ib.ib_seg_host_addr.lsb;
+               cfg_req->q_cfg[i].ib.index_addr.a32.addr_hi =
+                       rxp->cq.ib.ib_seg_host_addr.msb;
+               cfg_req->q_cfg[i].ib.intr.msix_index =
+                       htons((u16)rxp->cq.ib.intr_vector);
+       }
+
+       cfg_req->ib_cfg.int_pkt_dma = BNA_STATUS_T_DISABLED;
+       cfg_req->ib_cfg.int_enabled = BNA_STATUS_T_ENABLED;
+       cfg_req->ib_cfg.int_pkt_enabled = BNA_STATUS_T_DISABLED;
+       cfg_req->ib_cfg.continuous_coalescing = BNA_STATUS_T_DISABLED;
+       cfg_req->ib_cfg.msix = (rxp->cq.ib.intr_type == BNA_INTR_T_MSIX)
+                               ? BNA_STATUS_T_ENABLED :
+                               BNA_STATUS_T_DISABLED;
+       cfg_req->ib_cfg.coalescing_timeout =
+                       htonl((u32)rxp->cq.ib.coalescing_timeo);
+       cfg_req->ib_cfg.inter_pkt_timeout =
+                       htonl((u32)rxp->cq.ib.interpkt_timeo);
+       cfg_req->ib_cfg.inter_pkt_count = (u8)rxp->cq.ib.interpkt_count;
+
+       switch (rxp->type) {
+       case BNA_RXP_SLR:
+               cfg_req->rx_cfg.rxq_type = BFI_ENET_RXQ_LARGE_SMALL;
+               break;
+
+       case BNA_RXP_HDS:
+               cfg_req->rx_cfg.rxq_type = BFI_ENET_RXQ_HDS;
+               cfg_req->rx_cfg.hds.type = rx->hds_cfg.hdr_type;
+               cfg_req->rx_cfg.hds.force_offset = rx->hds_cfg.forced_offset;
+               cfg_req->rx_cfg.hds.max_header_size = rx->hds_cfg.forced_offset;
+               break;
+
+       case BNA_RXP_SINGLE:
+               cfg_req->rx_cfg.rxq_type = BFI_ENET_RXQ_SINGLE;
+               break;
+
+       default:
+               BUG_ON(1);
+       }
+       cfg_req->rx_cfg.strip_vlan = rx->rxf.vlan_strip_status;
+
+       bfa_msgq_cmd_set(&rx->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_rx_cfg_req), &cfg_req->mh);
+       bfa_msgq_cmd_post(&rx->bna->msgq, &rx->msgq_cmd);
+}
+
+static void
+bna_bfi_rx_enet_stop(struct bna_rx *rx)
+{
+       struct bfi_enet_req *req = &rx->bfi_enet_cmd.req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_RX_CFG_CLR_REQ, 0, rx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_req)));
+       bfa_msgq_cmd_set(&rx->msgq_cmd, NULL, NULL, sizeof(struct bfi_enet_req),
+               &req->mh);
+       bfa_msgq_cmd_post(&rx->bna->msgq, &rx->msgq_cmd);
+}
+
+static void
+bna_rx_enet_stop(struct bna_rx *rx)
+{
+       struct bna_rxp *rxp;
+       struct list_head                 *qe_rxp;
+
+       /* Stop IB */
+       list_for_each(qe_rxp, &rx->rxp_q) {
+               rxp = (struct bna_rxp *)qe_rxp;
+               bna_ib_stop(rx->bna, &rxp->cq.ib);
+       }
+
+       bna_bfi_rx_enet_stop(rx);
+}
+
+static int
+bna_rx_res_check(struct bna_rx_mod *rx_mod, struct bna_rx_config *rx_cfg)
+{
+       if ((rx_mod->rx_free_count == 0) ||
+               (rx_mod->rxp_free_count == 0) ||
+               (rx_mod->rxq_free_count == 0))
+               return 0;
+
+       if (rx_cfg->rxp_type == BNA_RXP_SINGLE) {
+               if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
+                       (rx_mod->rxq_free_count < rx_cfg->num_paths))
+                               return 0;
+       } else {
+               if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
+                       (rx_mod->rxq_free_count < (2 * rx_cfg->num_paths)))
+                       return 0;
+       }
+
+       return 1;
+}
+
+static struct bna_rxq *
+bna_rxq_get(struct bna_rx_mod *rx_mod)
+{
+       struct bna_rxq *rxq = NULL;
+       struct list_head        *qe = NULL;
+
+       bfa_q_deq(&rx_mod->rxq_free_q, &qe);
+       rx_mod->rxq_free_count--;
+       rxq = (struct bna_rxq *)qe;
+       bfa_q_qe_init(&rxq->qe);
+
+       return rxq;
+}
+
+static void
+bna_rxq_put(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq)
+{
+       bfa_q_qe_init(&rxq->qe);
+       list_add_tail(&rxq->qe, &rx_mod->rxq_free_q);
+       rx_mod->rxq_free_count++;
+}
+
+static struct bna_rxp *
+bna_rxp_get(struct bna_rx_mod *rx_mod)
+{
+       struct list_head        *qe = NULL;
+       struct bna_rxp *rxp = NULL;
+
+       bfa_q_deq(&rx_mod->rxp_free_q, &qe);
+       rx_mod->rxp_free_count--;
+       rxp = (struct bna_rxp *)qe;
+       bfa_q_qe_init(&rxp->qe);
+
+       return rxp;
+}
+
+static void
+bna_rxp_put(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp)
+{
+       bfa_q_qe_init(&rxp->qe);
+       list_add_tail(&rxp->qe, &rx_mod->rxp_free_q);
+       rx_mod->rxp_free_count++;
+}
+
+static struct bna_rx *
+bna_rx_get(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+       struct list_head        *qe = NULL;
+       struct bna_rx *rx = NULL;
+
+       if (type == BNA_RX_T_REGULAR) {
+               bfa_q_deq(&rx_mod->rx_free_q, &qe);
+       } else
+               bfa_q_deq_tail(&rx_mod->rx_free_q, &qe);
+
+       rx_mod->rx_free_count--;
+       rx = (struct bna_rx *)qe;
+       bfa_q_qe_init(&rx->qe);
+       list_add_tail(&rx->qe, &rx_mod->rx_active_q);
+       rx->type = type;
+
+       return rx;
+}
+
+static void
+bna_rx_put(struct bna_rx_mod *rx_mod, struct bna_rx *rx)
+{
+       struct list_head *prev_qe = NULL;
+       struct list_head *qe;
+
+       bfa_q_qe_init(&rx->qe);
+
+       list_for_each(qe, &rx_mod->rx_free_q) {
+               if (((struct bna_rx *)qe)->rid < rx->rid)
+                       prev_qe = qe;
+               else
+                       break;
+       }
+
+       if (prev_qe == NULL) {
+               /* This is the first entry */
+               bfa_q_enq_head(&rx_mod->rx_free_q, &rx->qe);
+       } else if (bfa_q_next(prev_qe) == &rx_mod->rx_free_q) {
+               /* This is the last entry */
+               list_add_tail(&rx->qe, &rx_mod->rx_free_q);
+       } else {
+               /* Somewhere in the middle */
+               bfa_q_next(&rx->qe) = bfa_q_next(prev_qe);
+               bfa_q_prev(&rx->qe) = prev_qe;
+               bfa_q_next(prev_qe) = &rx->qe;
+               bfa_q_prev(bfa_q_next(&rx->qe)) = &rx->qe;
+       }
+
+       rx_mod->rx_free_count++;
+}
+
+static void
+bna_rxp_add_rxqs(struct bna_rxp *rxp, struct bna_rxq *q0,
+               struct bna_rxq *q1)
+{
+       switch (rxp->type) {
+       case BNA_RXP_SINGLE:
+               rxp->rxq.single.only = q0;
+               rxp->rxq.single.reserved = NULL;
+               break;
+       case BNA_RXP_SLR:
+               rxp->rxq.slr.large = q0;
+               rxp->rxq.slr.small = q1;
+               break;
+       case BNA_RXP_HDS:
+               rxp->rxq.hds.data = q0;
+               rxp->rxq.hds.hdr = q1;
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+bna_rxq_qpt_setup(struct bna_rxq *rxq,
+               struct bna_rxp *rxp,
+               u32 page_count,
+               u32 page_size,
+               struct bna_mem_descr *qpt_mem,
+               struct bna_mem_descr *swqpt_mem,
+               struct bna_mem_descr *page_mem)
+{
+       int     i;
+
+       rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+       rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+       rxq->qpt.kv_qpt_ptr = qpt_mem->kva;
+       rxq->qpt.page_count = page_count;
+       rxq->qpt.page_size = page_size;
+
+       rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;
+
+       for (i = 0; i < rxq->qpt.page_count; i++) {
+               rxq->rcb->sw_qpt[i] = page_mem[i].kva;
+               ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
+                       page_mem[i].dma.lsb;
+               ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
+                       page_mem[i].dma.msb;
+       }
+}
+
+static void
+bna_rxp_cqpt_setup(struct bna_rxp *rxp,
+               u32 page_count,
+               u32 page_size,
+               struct bna_mem_descr *qpt_mem,
+               struct bna_mem_descr *swqpt_mem,
+               struct bna_mem_descr *page_mem)
+{
+       int     i;
+
+       rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+       rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+       rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva;
+       rxp->cq.qpt.page_count = page_count;
+       rxp->cq.qpt.page_size = page_size;
+
+       rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;
+
+       for (i = 0; i < rxp->cq.qpt.page_count; i++) {
+               rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva;
+
+               ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
+                       page_mem[i].dma.lsb;
+               ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
+                       page_mem[i].dma.msb;
+       }
+}
+
+static void
+bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx)
+{
+       struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
+
+       bfa_wc_down(&rx_mod->rx_stop_wc);
+}
+
+static void
+bna_rx_mod_cb_rx_stopped_all(void *arg)
+{
+       struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
+
+       if (rx_mod->stop_cbfn)
+               rx_mod->stop_cbfn(&rx_mod->bna->enet);
+       rx_mod->stop_cbfn = NULL;
+}
+
+static void
+bna_rx_start(struct bna_rx *rx)
+{
+       rx->rx_flags |= BNA_RX_F_ENET_STARTED;
+       if (rx->rx_flags & BNA_RX_F_ENABLED)
+               bfa_fsm_send_event(rx, RX_E_START);
+}
+
+static void
+bna_rx_stop(struct bna_rx *rx)
+{
+       rx->rx_flags &= ~BNA_RX_F_ENET_STARTED;
+       if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped)
+               bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx);
+       else {
+               rx->stop_cbfn = bna_rx_mod_cb_rx_stopped;
+               rx->stop_cbarg = &rx->bna->rx_mod;
+               bfa_fsm_send_event(rx, RX_E_STOP);
+       }
+}
+
+static void
+bna_rx_fail(struct bna_rx *rx)
+{
+       /* Indicate Enet is not enabled, and failed */
+       rx->rx_flags &= ~BNA_RX_F_ENET_STARTED;
+       bfa_fsm_send_event(rx, RX_E_FAIL);
+}
+
+void
+bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+       struct bna_rx *rx;
+       struct list_head *qe;
+
+       rx_mod->flags |= BNA_RX_MOD_F_ENET_STARTED;
+       if (type == BNA_RX_T_LOOPBACK)
+               rx_mod->flags |= BNA_RX_MOD_F_ENET_LOOPBACK;
+
+       list_for_each(qe, &rx_mod->rx_active_q) {
+               rx = (struct bna_rx *)qe;
+               if (rx->type == type)
+                       bna_rx_start(rx);
+       }
+}
+
+void
+bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+       struct bna_rx *rx;
+       struct list_head *qe;
+
+       rx_mod->flags &= ~BNA_RX_MOD_F_ENET_STARTED;
+       rx_mod->flags &= ~BNA_RX_MOD_F_ENET_LOOPBACK;
+
+       rx_mod->stop_cbfn = bna_enet_cb_rx_stopped;
+
+       bfa_wc_init(&rx_mod->rx_stop_wc, bna_rx_mod_cb_rx_stopped_all, rx_mod);
+
+       list_for_each(qe, &rx_mod->rx_active_q) {
+               rx = (struct bna_rx *)qe;
+               if (rx->type == type) {
+                       bfa_wc_up(&rx_mod->rx_stop_wc);
+                       bna_rx_stop(rx);
+               }
+       }
+
+       bfa_wc_wait(&rx_mod->rx_stop_wc);
+}
+
+void
+bna_rx_mod_fail(struct bna_rx_mod *rx_mod)
+{
+       struct bna_rx *rx;
+       struct list_head *qe;
+
+       rx_mod->flags &= ~BNA_RX_MOD_F_ENET_STARTED;
+       rx_mod->flags &= ~BNA_RX_MOD_F_ENET_LOOPBACK;
+
+       list_for_each(qe, &rx_mod->rx_active_q) {
+               rx = (struct bna_rx *)qe;
+               bna_rx_fail(rx);
+       }
+}
+
+void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
+                       struct bna_res_info *res_info)
+{
+       int     index;
+       struct bna_rx *rx_ptr;
+       struct bna_rxp *rxp_ptr;
+       struct bna_rxq *rxq_ptr;
+
+       rx_mod->bna = bna;
+       rx_mod->flags = 0;
+
+       rx_mod->rx = (struct bna_rx *)
+               res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva;
+       rx_mod->rxp = (struct bna_rxp *)
+               res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva;
+       rx_mod->rxq = (struct bna_rxq *)
+               res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva;
+
+       /* Initialize the queues */
+       INIT_LIST_HEAD(&rx_mod->rx_free_q);
+       rx_mod->rx_free_count = 0;
+       INIT_LIST_HEAD(&rx_mod->rxq_free_q);
+       rx_mod->rxq_free_count = 0;
+       INIT_LIST_HEAD(&rx_mod->rxp_free_q);
+       rx_mod->rxp_free_count = 0;
+       INIT_LIST_HEAD(&rx_mod->rx_active_q);
+
+       /* Build RX queues */
+       for (index = 0; index < bna->ioceth.attr.num_rxp; index++) {
+               rx_ptr = &rx_mod->rx[index];
+
+               bfa_q_qe_init(&rx_ptr->qe);
+               INIT_LIST_HEAD(&rx_ptr->rxp_q);
+               rx_ptr->bna = NULL;
+               rx_ptr->rid = index;
+               rx_ptr->stop_cbfn = NULL;
+               rx_ptr->stop_cbarg = NULL;
+
+               list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q);
+               rx_mod->rx_free_count++;
+       }
+
+       /* build RX-path queue */
+       for (index = 0; index < bna->ioceth.attr.num_rxp; index++) {
+               rxp_ptr = &rx_mod->rxp[index];
+               bfa_q_qe_init(&rxp_ptr->qe);
+               list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q);
+               rx_mod->rxp_free_count++;
+       }
+
+       /* build RXQ queue */
+       for (index = 0; index < (bna->ioceth.attr.num_rxp * 2); index++) {
+               rxq_ptr = &rx_mod->rxq[index];
+               bfa_q_qe_init(&rxq_ptr->qe);
+               list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q);
+               rx_mod->rxq_free_count++;
+       }
+}
+
+void
+bna_rx_mod_uninit(struct bna_rx_mod *rx_mod)
+{
+       struct list_head                *qe;
+       int i;
+
+       i = 0;
+       list_for_each(qe, &rx_mod->rx_free_q)
+               i++;
+
+       i = 0;
+       list_for_each(qe, &rx_mod->rxp_free_q)
+               i++;
+
+       i = 0;
+       list_for_each(qe, &rx_mod->rxq_free_q)
+               i++;
+
+       rx_mod->bna = NULL;
+}
+
+void
+bna_bfi_rx_enet_start_rsp(struct bna_rx *rx, struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_rx_cfg_rsp *cfg_rsp = &rx->bfi_enet_cmd.cfg_rsp;
+       struct bna_rxp *rxp = NULL;
+       struct bna_rxq *q0 = NULL, *q1 = NULL;
+       struct list_head *rxp_qe;
+       int i;
+
+       bfa_msgq_rsp_copy(&rx->bna->msgq, (u8 *)cfg_rsp,
+               sizeof(struct bfi_enet_rx_cfg_rsp));
+
+       rx->hw_id = cfg_rsp->hw_id;
+
+       for (i = 0, rxp_qe = bfa_q_first(&rx->rxp_q);
+               i < rx->num_paths;
+               i++, rxp_qe = bfa_q_next(rxp_qe)) {
+               rxp = (struct bna_rxp *)rxp_qe;
+               GET_RXQS(rxp, q0, q1);
+
+               /* Setup doorbells */
+               rxp->cq.ccb->i_dbell->doorbell_addr =
+                       rx->bna->pcidev.pci_bar_kva
+                       + ntohl(cfg_rsp->q_handles[i].i_dbell);
+               rxp->hw_id = cfg_rsp->q_handles[i].hw_cqid;
+               q0->rcb->q_dbell =
+                       rx->bna->pcidev.pci_bar_kva
+                       + ntohl(cfg_rsp->q_handles[i].ql_dbell);
+               q0->hw_id = cfg_rsp->q_handles[i].hw_lqid;
+               if (q1) {
+                       q1->rcb->q_dbell =
+                       rx->bna->pcidev.pci_bar_kva
+                       + ntohl(cfg_rsp->q_handles[i].qs_dbell);
+                       q1->hw_id = cfg_rsp->q_handles[i].hw_sqid;
+               }
+
+               /* Initialize producer/consumer indexes */
+               (*rxp->cq.ccb->hw_producer_index) = 0;
+               rxp->cq.ccb->producer_index = 0;
+               q0->rcb->producer_index = q0->rcb->consumer_index = 0;
+               if (q1)
+                       q1->rcb->producer_index = q1->rcb->consumer_index = 0;
+       }
+
+       bfa_fsm_send_event(rx, RX_E_STARTED);
+}
+
+void
+bna_bfi_rx_enet_stop_rsp(struct bna_rx *rx, struct bfi_msgq_mhdr *msghdr)
+{
+       bfa_fsm_send_event(rx, RX_E_STOPPED);
+}
+
+void
+bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
+{
+       u32 cq_size, hq_size, dq_size;
+       u32 cpage_count, hpage_count, dpage_count;
+       struct bna_mem_info *mem_info;
+       u32 cq_depth;
+       u32 hq_depth;
+       u32 dq_depth;
+
+       dq_depth = q_cfg->q_depth;
+       hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth);
+       cq_depth = dq_depth + hq_depth;
+
+       BNA_TO_POWER_OF_2_HIGH(cq_depth);
+       cq_size = cq_depth * BFI_CQ_WI_SIZE;
+       cq_size = ALIGN(cq_size, PAGE_SIZE);
+       cpage_count = SIZE_TO_PAGES(cq_size);
+
+       BNA_TO_POWER_OF_2_HIGH(dq_depth);
+       dq_size = dq_depth * BFI_RXQ_WI_SIZE;
+       dq_size = ALIGN(dq_size, PAGE_SIZE);
+       dpage_count = SIZE_TO_PAGES(dq_size);
+
+       if (BNA_RXP_SINGLE != q_cfg->rxp_type) {
+               BNA_TO_POWER_OF_2_HIGH(hq_depth);
+               hq_size = hq_depth * BFI_RXQ_WI_SIZE;
+               hq_size = ALIGN(hq_size, PAGE_SIZE);
+               hpage_count = SIZE_TO_PAGES(hq_size);
+       } else
+               hpage_count = 0;
+
+       res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = sizeof(struct bna_ccb);
+       mem_info->num = q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = sizeof(struct bna_rcb);
+       mem_info->num = BNA_GET_RXQS(q_cfg);
+
+       res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = cpage_count * sizeof(struct bna_dma_addr);
+       mem_info->num = q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = cpage_count * sizeof(void *);
+       mem_info->num = q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = PAGE_SIZE;
+       mem_info->num = cpage_count * q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = dpage_count * sizeof(struct bna_dma_addr);
+       mem_info->num = q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = dpage_count * sizeof(void *);
+       mem_info->num = q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = PAGE_SIZE;
+       mem_info->num = dpage_count * q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = hpage_count * sizeof(struct bna_dma_addr);
+       mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
+
+       res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = hpage_count * sizeof(void *);
+       mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
+
+       res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = (hpage_count ? PAGE_SIZE : 0);
+       mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0);
+
+       res_info[BNA_RX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = BFI_IBIDX_SIZE;
+       mem_info->num = q_cfg->num_paths;
+
+       res_info[BNA_RX_RES_MEM_T_RIT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_RX_RES_MEM_T_RIT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = BFI_ENET_RSS_RIT_MAX;
+       mem_info->num = 1;
+
+       res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR;
+       res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX;
+       res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths;
+}
+
+struct bna_rx *
+bna_rx_create(struct bna *bna, struct bnad *bnad,
+               struct bna_rx_config *rx_cfg,
+               struct bna_rx_event_cbfn *rx_cbfn,
+               struct bna_res_info *res_info,
+               void *priv)
+{
+       struct bna_rx_mod *rx_mod = &bna->rx_mod;
+       struct bna_rx *rx;
+       struct bna_rxp *rxp;
+       struct bna_rxq *q0;
+       struct bna_rxq *q1;
+       struct bna_intr_info *intr_info;
+       u32 page_count;
+       struct bna_mem_descr *ccb_mem;
+       struct bna_mem_descr *rcb_mem;
+       struct bna_mem_descr *unmapq_mem;
+       struct bna_mem_descr *cqpt_mem;
+       struct bna_mem_descr *cswqpt_mem;
+       struct bna_mem_descr *cpage_mem;
+       struct bna_mem_descr *hqpt_mem;
+       struct bna_mem_descr *dqpt_mem;
+       struct bna_mem_descr *hsqpt_mem;
+       struct bna_mem_descr *dsqpt_mem;
+       struct bna_mem_descr *hpage_mem;
+       struct bna_mem_descr *dpage_mem;
+       int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0;
+       int dpage_count, hpage_count, rcb_idx;
+
+       if (!bna_rx_res_check(rx_mod, rx_cfg))
+               return NULL;
+
+       intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
+       ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0];
+       rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0];
+       unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0];
+       cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0];
+       cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0];
+       cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0];
+       hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0];
+       dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0];
+       hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0];
+       dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0];
+       hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
+       dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];
+
+       page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num /
+                       rx_cfg->num_paths;
+
+       dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num /
+                       rx_cfg->num_paths;
+
+       hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num /
+                       rx_cfg->num_paths;
+
+       rx = bna_rx_get(rx_mod, rx_cfg->rx_type);
+       rx->bna = bna;
+       rx->rx_flags = 0;
+       INIT_LIST_HEAD(&rx->rxp_q);
+       rx->stop_cbfn = NULL;
+       rx->stop_cbarg = NULL;
+       rx->priv = priv;
+
+       rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn;
+       rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
+       rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
+       rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
+       /* Following callbacks are mandatory */
+       rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
+       rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;
+
+       if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_ENET_STARTED) {
+               switch (rx->type) {
+               case BNA_RX_T_REGULAR:
+                       if (!(rx->bna->rx_mod.flags &
+                               BNA_RX_MOD_F_ENET_LOOPBACK))
+                               rx->rx_flags |= BNA_RX_F_ENET_STARTED;
+                       break;
+               case BNA_RX_T_LOOPBACK:
+                       if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_ENET_LOOPBACK)
+                               rx->rx_flags |= BNA_RX_F_ENET_STARTED;
+                       break;
+               }
+       }
+
+       rx->num_paths = rx_cfg->num_paths;
+       for (i = 0, rcb_idx = 0; i < rx->num_paths; i++) {
+               rxp = bna_rxp_get(rx_mod);
+               list_add_tail(&rxp->qe, &rx->rxp_q);
+               rxp->type = rx_cfg->rxp_type;
+               rxp->rx = rx;
+               rxp->cq.rx = rx;
+
+               q0 = bna_rxq_get(rx_mod);
+               if (BNA_RXP_SINGLE == rx_cfg->rxp_type)
+                       q1 = NULL;
+               else
+                       q1 = bna_rxq_get(rx_mod);
+
+               if (1 == intr_info->num)
+                       rxp->vector = intr_info->idl[0].vector;
+               else
+                       rxp->vector = intr_info->idl[i].vector;
+
+               /* Setup IB */
+
+               rxp->cq.ib.ib_seg_host_addr.lsb =
+               res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
+               rxp->cq.ib.ib_seg_host_addr.msb =
+               res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
+               rxp->cq.ib.ib_seg_host_addr_kva =
+               res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
+               rxp->cq.ib.intr_type = intr_info->intr_type;
+               if (intr_info->intr_type == BNA_INTR_T_MSIX)
+                       rxp->cq.ib.intr_vector = rxp->vector;
+               else
+                       rxp->cq.ib.intr_vector = (1 << rxp->vector);
+               rxp->cq.ib.coalescing_timeo = rx_cfg->coalescing_timeo;
+               rxp->cq.ib.interpkt_count = BFI_RX_INTERPKT_COUNT;
+               rxp->cq.ib.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
+
+               bna_rxp_add_rxqs(rxp, q0, q1);
+
+               /* Setup large Q */
+
+               q0->rx = rx;
+               q0->rxp = rxp;
+
+               q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
+               q0->rcb->unmap_q = (void *)unmapq_mem[rcb_idx].kva;
+               rcb_idx++;
+               q0->rcb->q_depth = rx_cfg->q_depth;
+               q0->rcb->rxq = q0;
+               q0->rcb->bnad = bna->bnad;
+               q0->rcb->id = 0;
+               q0->rx_packets = q0->rx_bytes = 0;
+               q0->rx_packets_with_error = q0->rxbuf_alloc_failed = 0;
+
+               bna_rxq_qpt_setup(q0, rxp, dpage_count, PAGE_SIZE,
+                       &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]);
+               q0->rcb->page_idx = dpage_idx;
+               q0->rcb->page_count = dpage_count;
+               dpage_idx += dpage_count;
+
+               if (rx->rcb_setup_cbfn)
+                       rx->rcb_setup_cbfn(bnad, q0->rcb);
+
+               /* Setup small Q */
+
+               if (q1) {
+                       q1->rx = rx;
+                       q1->rxp = rxp;
+
+                       q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
+                       q1->rcb->unmap_q = (void *)unmapq_mem[rcb_idx].kva;
+                       rcb_idx++;
+                       q1->rcb->q_depth = rx_cfg->q_depth;
+                       q1->rcb->rxq = q1;
+                       q1->rcb->bnad = bna->bnad;
+                       q1->rcb->id = 1;
+                       q1->buffer_size = (rx_cfg->rxp_type == BNA_RXP_HDS) ?
+                                       rx_cfg->hds_config.forced_offset
+                                       : rx_cfg->small_buff_size;
+                       q1->rx_packets = q1->rx_bytes = 0;
+                       q1->rx_packets_with_error = q1->rxbuf_alloc_failed = 0;
+
+                       bna_rxq_qpt_setup(q1, rxp, hpage_count, PAGE_SIZE,
+                               &hqpt_mem[i], &hsqpt_mem[i],
+                               &hpage_mem[hpage_idx]);
+                       q1->rcb->page_idx = hpage_idx;
+                       q1->rcb->page_count = hpage_count;
+                       hpage_idx += hpage_count;
+
+                       if (rx->rcb_setup_cbfn)
+                               rx->rcb_setup_cbfn(bnad, q1->rcb);
+               }
+
+               /* Setup CQ */
+
+               rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva;
+               rxp->cq.ccb->q_depth =  rx_cfg->q_depth +
+                                       ((rx_cfg->rxp_type == BNA_RXP_SINGLE) ?
+                                       0 : rx_cfg->q_depth);
+               rxp->cq.ccb->cq = &rxp->cq;
+               rxp->cq.ccb->rcb[0] = q0->rcb;
+               q0->rcb->ccb = rxp->cq.ccb;
+               if (q1) {
+                       rxp->cq.ccb->rcb[1] = q1->rcb;
+                       q1->rcb->ccb = rxp->cq.ccb;
+               }
+               rxp->cq.ccb->hw_producer_index =
+                       (u32 *)rxp->cq.ib.ib_seg_host_addr_kva;
+               rxp->cq.ccb->i_dbell = &rxp->cq.ib.door_bell;
+               rxp->cq.ccb->intr_type = rxp->cq.ib.intr_type;
+               rxp->cq.ccb->intr_vector = rxp->cq.ib.intr_vector;
+               rxp->cq.ccb->rx_coalescing_timeo =
+                       rxp->cq.ib.coalescing_timeo;
+               rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0;
+               rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0;
+               rxp->cq.ccb->bnad = bna->bnad;
+               rxp->cq.ccb->id = i;
+
+               bna_rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
+                       &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]);
+               rxp->cq.ccb->page_idx = cpage_idx;
+               rxp->cq.ccb->page_count = page_count;
+               cpage_idx += page_count;
+
+               if (rx->ccb_setup_cbfn)
+                       rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);
+       }
+
+       rx->hds_cfg = rx_cfg->hds_config;
+
+       bna_rxf_init(&rx->rxf, rx, rx_cfg, res_info);
+
+       bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+
+       rx_mod->rid_mask |= (1 << rx->rid);
+
+       return rx;
+}
+
+void
+bna_rx_destroy(struct bna_rx *rx)
+{
+       struct bna_rx_mod *rx_mod = &rx->bna->rx_mod;
+       struct bna_rxq *q0 = NULL;
+       struct bna_rxq *q1 = NULL;
+       struct bna_rxp *rxp;
+       struct list_head *qe;
+
+       bna_rxf_uninit(&rx->rxf);
+
+       while (!list_empty(&rx->rxp_q)) {
+               bfa_q_deq(&rx->rxp_q, &rxp);
+               GET_RXQS(rxp, q0, q1);
+               if (rx->rcb_destroy_cbfn)
+                       rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb);
+               q0->rcb = NULL;
+               q0->rxp = NULL;
+               q0->rx = NULL;
+               bna_rxq_put(rx_mod, q0);
+
+               if (q1) {
+                       if (rx->rcb_destroy_cbfn)
+                               rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb);
+                       q1->rcb = NULL;
+                       q1->rxp = NULL;
+                       q1->rx = NULL;
+                       bna_rxq_put(rx_mod, q1);
+               }
+               rxp->rxq.slr.large = NULL;
+               rxp->rxq.slr.small = NULL;
+
+               if (rx->ccb_destroy_cbfn)
+                       rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb);
+               rxp->cq.ccb = NULL;
+               rxp->rx = NULL;
+               bna_rxp_put(rx_mod, rxp);
+       }
+
+       list_for_each(qe, &rx_mod->rx_active_q) {
+               if (qe == &rx->qe) {
+                       list_del(&rx->qe);
+                       bfa_q_qe_init(&rx->qe);
+                       break;
+               }
+       }
+
+       rx_mod->rid_mask &= ~(1 << rx->rid);
+
+       rx->bna = NULL;
+       rx->priv = NULL;
+       bna_rx_put(rx_mod, rx);
+}
+
+void
+bna_rx_enable(struct bna_rx *rx)
+{
+       if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped)
+               return;
+
+       rx->rx_flags |= BNA_RX_F_ENABLED;
+       if (rx->rx_flags & BNA_RX_F_ENET_STARTED)
+               bfa_fsm_send_event(rx, RX_E_START);
+}
+
+void
+bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
+               void (*cbfn)(void *, struct bna_rx *))
+{
+       if (type == BNA_SOFT_CLEANUP) {
+               /* h/w should not be accessed. Treat we're stopped */
+               (*cbfn)(rx->bna->bnad, rx);
+       } else {
+               rx->stop_cbfn = cbfn;
+               rx->stop_cbarg = rx->bna->bnad;
+
+               rx->rx_flags &= ~BNA_RX_F_ENABLED;
+
+               bfa_fsm_send_event(rx, RX_E_STOP);
+       }
+}
+
+void
+bna_rx_cleanup_complete(struct bna_rx *rx)
+{
+       bfa_fsm_send_event(rx, RX_E_CLEANUP_DONE);
+}
+
+enum bna_cb_status
+bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
+               enum bna_rxmode bitmask,
+               void (*cbfn)(struct bnad *, struct bna_rx *))
+{
+       struct bna_rxf *rxf = &rx->rxf;
+       int need_hw_config = 0;
+
+       /* Error checks */
+
+       if (is_promisc_enable(new_mode, bitmask)) {
+               /* If promisc mode is already enabled elsewhere in the system */
+               if ((rx->bna->promisc_rid != BFI_INVALID_RID) &&
+                       (rx->bna->promisc_rid != rxf->rx->rid))
+                       goto err_return;
+
+               /* If default mode is already enabled in the system */
+               if (rx->bna->default_mode_rid != BFI_INVALID_RID)
+                       goto err_return;
+
+               /* Trying to enable promiscuous and default mode together */
+               if (is_default_enable(new_mode, bitmask))
+                       goto err_return;
+       }
+
+       if (is_default_enable(new_mode, bitmask)) {
+               /* If default mode is already enabled elsewhere in the system */
+               if ((rx->bna->default_mode_rid != BFI_INVALID_RID) &&
+                       (rx->bna->default_mode_rid != rxf->rx->rid)) {
+                               goto err_return;
+               }
+
+               /* If promiscuous mode is already enabled in the system */
+               if (rx->bna->promisc_rid != BFI_INVALID_RID)
+                       goto err_return;
+       }
+
+       /* Process the commands */
+
+       if (is_promisc_enable(new_mode, bitmask)) {
+               if (bna_rxf_promisc_enable(rxf))
+                       need_hw_config = 1;
+       } else if (is_promisc_disable(new_mode, bitmask)) {
+               if (bna_rxf_promisc_disable(rxf))
+                       need_hw_config = 1;
+       }
+
+       if (is_allmulti_enable(new_mode, bitmask)) {
+               if (bna_rxf_allmulti_enable(rxf))
+                       need_hw_config = 1;
+       } else if (is_allmulti_disable(new_mode, bitmask)) {
+               if (bna_rxf_allmulti_disable(rxf))
+                       need_hw_config = 1;
+       }
+
+       /* Trigger h/w if needed */
+
+       if (need_hw_config) {
+               rxf->cam_fltr_cbfn = cbfn;
+               rxf->cam_fltr_cbarg = rx->bna->bnad;
+               bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+       } else if (cbfn)
+               (*cbfn)(rx->bna->bnad, rx);
+
+       return BNA_CB_SUCCESS;
+
+err_return:
+       return BNA_CB_FAIL;
+}
+
+void
+bna_rx_vlanfilter_enable(struct bna_rx *rx)
+{
+       struct bna_rxf *rxf = &rx->rxf;
+
+       if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) {
+               rxf->vlan_filter_status = BNA_STATUS_T_ENABLED;
+               rxf->vlan_pending_bitmask = (u8)BFI_VLAN_BMASK_ALL;
+               bfa_fsm_send_event(rxf, RXF_E_CONFIG);
+       }
+}
+
+void
+bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo)
+{
+       struct bna_rxp *rxp;
+       struct list_head *qe;
+
+       list_for_each(qe, &rx->rxp_q) {
+               rxp = (struct bna_rxp *)qe;
+               rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo;
+               bna_ib_coalescing_timeo_set(&rxp->cq.ib, coalescing_timeo);
+       }
+}
+
+void
+bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX])
+{
+       int i, j;
+
+       for (i = 0; i < BNA_LOAD_T_MAX; i++)
+               for (j = 0; j < BNA_BIAS_T_MAX; j++)
+                       bna->rx_mod.dim_vector[i][j] = vector[i][j];
+}
+
+void
+bna_rx_dim_update(struct bna_ccb *ccb)
+{
+       struct bna *bna = ccb->cq->rx->bna;
+       u32 load, bias;
+       u32 pkt_rt, small_rt, large_rt;
+       u8 coalescing_timeo;
+
+       if ((ccb->pkt_rate.small_pkt_cnt == 0) &&
+               (ccb->pkt_rate.large_pkt_cnt == 0))
+               return;
+
+       /* Arrive at preconfigured coalescing timeo value based on pkt rate */
+
+       small_rt = ccb->pkt_rate.small_pkt_cnt;
+       large_rt = ccb->pkt_rate.large_pkt_cnt;
+
+       pkt_rt = small_rt + large_rt;
+
+       if (pkt_rt < BNA_PKT_RATE_10K)
+               load = BNA_LOAD_T_LOW_4;
+       else if (pkt_rt < BNA_PKT_RATE_20K)
+               load = BNA_LOAD_T_LOW_3;
+       else if (pkt_rt < BNA_PKT_RATE_30K)
+               load = BNA_LOAD_T_LOW_2;
+       else if (pkt_rt < BNA_PKT_RATE_40K)
+               load = BNA_LOAD_T_LOW_1;
+       else if (pkt_rt < BNA_PKT_RATE_50K)
+               load = BNA_LOAD_T_HIGH_1;
+       else if (pkt_rt < BNA_PKT_RATE_60K)
+               load = BNA_LOAD_T_HIGH_2;
+       else if (pkt_rt < BNA_PKT_RATE_80K)
+               load = BNA_LOAD_T_HIGH_3;
+       else
+               load = BNA_LOAD_T_HIGH_4;
+
+       if (small_rt > (large_rt << 1))
+               bias = 0;
+       else
+               bias = 1;
+
+       ccb->pkt_rate.small_pkt_cnt = 0;
+       ccb->pkt_rate.large_pkt_cnt = 0;
+
+       coalescing_timeo = bna->rx_mod.dim_vector[load][bias];
+       ccb->rx_coalescing_timeo = coalescing_timeo;
+
+       /* Set it to IB */
+       bna_ib_coalescing_timeo_set(&ccb->cq->ib, coalescing_timeo);
+}
+
+const u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = {
+       {12, 12},
+       {6, 10},
+       {5, 10},
+       {4, 8},
+       {3, 6},
+       {3, 6},
+       {2, 4},
+       {1, 2},
+};
+
+/**
+ * TX
+ */
+#define call_tx_stop_cbfn(tx)                                          \
+do {                                                                   \
+       if ((tx)->stop_cbfn) {                                          \
+               void (*cbfn)(void *, struct bna_tx *);          \
+               void *cbarg;                                            \
+               cbfn = (tx)->stop_cbfn;                                 \
+               cbarg = (tx)->stop_cbarg;                               \
+               (tx)->stop_cbfn = NULL;                                 \
+               (tx)->stop_cbarg = NULL;                                \
+               cbfn(cbarg, (tx));                                      \
+       }                                                               \
+} while (0)
+
+#define call_tx_prio_change_cbfn(tx)                                   \
+do {                                                                   \
+       if ((tx)->prio_change_cbfn) {                                   \
+               void (*cbfn)(struct bnad *, struct bna_tx *);   \
+               cbfn = (tx)->prio_change_cbfn;                          \
+               (tx)->prio_change_cbfn = NULL;                          \
+               cbfn((tx)->bna->bnad, (tx));                            \
+       }                                                               \
+} while (0)
+
+static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx);
+static void bna_bfi_tx_enet_start(struct bna_tx *tx);
+static void bna_tx_enet_stop(struct bna_tx *tx);
+
+enum bna_tx_event {
+       TX_E_START                      = 1,
+       TX_E_STOP                       = 2,
+       TX_E_FAIL                       = 3,
+       TX_E_STARTED                    = 4,
+       TX_E_STOPPED                    = 5,
+       TX_E_PRIO_CHANGE                = 6,
+       TX_E_CLEANUP_DONE               = 7,
+       TX_E_BW_UPDATE                  = 8,
+};
+
+bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx, enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, start_wait, struct bna_tx, enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, started, struct bna_tx, enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, stop_wait, struct bna_tx, enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, cleanup_wait, struct bna_tx,
+                       enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx,
+                       enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, prio_cleanup_wait, struct bna_tx,
+                       enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, failed, struct bna_tx, enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, quiesce_wait, struct bna_tx,
+                       enum bna_tx_event);
+
+static void
+bna_tx_sm_stopped_entry(struct bna_tx *tx)
+{
+       call_tx_stop_cbfn(tx);
+}
+
+static void
+bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_START:
+               bfa_fsm_set_state(tx, bna_tx_sm_start_wait);
+               break;
+
+       case TX_E_STOP:
+               call_tx_stop_cbfn(tx);
+               break;
+
+       case TX_E_FAIL:
+               /* No-op */
+               break;
+
+       case TX_E_PRIO_CHANGE:
+               call_tx_prio_change_cbfn(tx);
+               break;
+
+       case TX_E_BW_UPDATE:
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_start_wait_entry(struct bna_tx *tx)
+{
+       bna_bfi_tx_enet_start(tx);
+}
+
+static void
+bna_tx_sm_start_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_STOP:
+               tx->flags &= ~(BNA_TX_F_PRIO_CHANGED | BNA_TX_F_BW_UPDATED);
+               bfa_fsm_set_state(tx, bna_tx_sm_stop_wait);
+               break;
+
+       case TX_E_FAIL:
+               tx->flags &= ~(BNA_TX_F_PRIO_CHANGED | BNA_TX_F_BW_UPDATED);
+               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+               break;
+
+       case TX_E_STARTED:
+               if (tx->flags & (BNA_TX_F_PRIO_CHANGED | BNA_TX_F_BW_UPDATED)) {
+                       tx->flags &= ~(BNA_TX_F_PRIO_CHANGED |
+                               BNA_TX_F_BW_UPDATED);
+                       bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
+               } else
+                       bfa_fsm_set_state(tx, bna_tx_sm_started);
+               break;
+
+       case TX_E_PRIO_CHANGE:
+               tx->flags |=  BNA_TX_F_PRIO_CHANGED;
+               break;
+
+       case TX_E_BW_UPDATE:
+               tx->flags |= BNA_TX_F_BW_UPDATED;
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_started_entry(struct bna_tx *tx)
+{
+       struct bna_txq *txq;
+       struct list_head                 *qe;
+       int is_regular = (tx->type == BNA_TX_T_REGULAR);
+
+       list_for_each(qe, &tx->txq_q) {
+               txq = (struct bna_txq *)qe;
+               txq->tcb->priority = txq->priority;
+               /* Start IB */
+               bna_ib_start(tx->bna, &txq->ib, is_regular);
+       }
+       tx->tx_resume_cbfn(tx->bna->bnad, tx);
+}
+
+static void
+bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_STOP:
+               bfa_fsm_set_state(tx, bna_tx_sm_stop_wait);
+               tx->tx_stall_cbfn(tx->bna->bnad, tx);
+               bna_tx_enet_stop(tx);
+               break;
+
+       case TX_E_FAIL:
+               bfa_fsm_set_state(tx, bna_tx_sm_failed);
+               tx->tx_stall_cbfn(tx->bna->bnad, tx);
+               tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
+               break;
+
+       case TX_E_PRIO_CHANGE:
+       case TX_E_BW_UPDATE:
+               bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_stop_wait_entry(struct bna_tx *tx)
+{
+}
+
+static void
+bna_tx_sm_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_FAIL:
+       case TX_E_STOPPED:
+               bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
+               tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
+               break;
+
+       case TX_E_STARTED:
+               /**
+                * We are here due to start_wait -> stop_wait transition on
+                * TX_E_STOP event
+                */
+               bna_tx_enet_stop(tx);
+               break;
+
+       case TX_E_PRIO_CHANGE:
+       case TX_E_BW_UPDATE:
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_cleanup_wait_entry(struct bna_tx *tx)
+{
+}
+
+static void
+bna_tx_sm_cleanup_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_FAIL:
+       case TX_E_PRIO_CHANGE:
+       case TX_E_BW_UPDATE:
+               /* No-op */
+               break;
+
+       case TX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx)
+{
+       tx->tx_stall_cbfn(tx->bna->bnad, tx);
+       bna_tx_enet_stop(tx);
+}
+
+static void
+bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_STOP:
+               bfa_fsm_set_state(tx, bna_tx_sm_stop_wait);
+               break;
+
+       case TX_E_FAIL:
+               bfa_fsm_set_state(tx, bna_tx_sm_failed);
+               call_tx_prio_change_cbfn(tx);
+               tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
+               break;
+
+       case TX_E_STOPPED:
+               bfa_fsm_set_state(tx, bna_tx_sm_prio_cleanup_wait);
+               break;
+
+       case TX_E_PRIO_CHANGE:
+       case TX_E_BW_UPDATE:
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_prio_cleanup_wait_entry(struct bna_tx *tx)
+{
+       call_tx_prio_change_cbfn(tx);
+       tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
+}
+
+static void
+bna_tx_sm_prio_cleanup_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_STOP:
+               bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
+               break;
+
+       case TX_E_FAIL:
+               bfa_fsm_set_state(tx, bna_tx_sm_failed);
+               break;
+
+       case TX_E_PRIO_CHANGE:
+       case TX_E_BW_UPDATE:
+               /* No-op */
+               break;
+
+       case TX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(tx, bna_tx_sm_start_wait);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_failed_entry(struct bna_tx *tx)
+{
+}
+
+static void
+bna_tx_sm_failed(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_START:
+               bfa_fsm_set_state(tx, bna_tx_sm_quiesce_wait);
+               break;
+
+       case TX_E_STOP:
+               bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
+               break;
+
+       case TX_E_FAIL:
+               /* No-op */
+               break;
+
+       case TX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_tx_sm_quiesce_wait_entry(struct bna_tx *tx)
+{
+}
+
+static void
+bna_tx_sm_quiesce_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+       switch (event) {
+       case TX_E_STOP:
+               bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
+               break;
+
+       case TX_E_FAIL:
+               bfa_fsm_set_state(tx, bna_tx_sm_failed);
+               break;
+
+       case TX_E_CLEANUP_DONE:
+               bfa_fsm_set_state(tx, bna_tx_sm_start_wait);
+               break;
+
+       case TX_E_BW_UPDATE:
+               /* No-op */
+               break;
+
+       default:
+               bfa_sm_fault(event);
+       }
+}
+
+static void
+bna_bfi_tx_enet_start(struct bna_tx *tx)
+{
+       struct bfi_enet_tx_cfg_req *cfg_req = &tx->bfi_enet_cmd.cfg_req;
+       struct bna_txq *txq = NULL;
+       struct list_head *qe;
+       int i;
+
+       bfi_msgq_mhdr_set(cfg_req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_TX_CFG_SET_REQ, 0, tx->rid);
+       cfg_req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_tx_cfg_req)));
+
+       cfg_req->num_queues = tx->num_txq;
+       for (i = 0, qe = bfa_q_first(&tx->txq_q);
+               i < tx->num_txq;
+               i++, qe = bfa_q_next(qe)) {
+               txq = (struct bna_txq *)qe;
+
+               bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].q.q, &txq->qpt);
+               cfg_req->q_cfg[i].q.priority = txq->priority;
+
+               cfg_req->q_cfg[i].ib.index_addr.a32.addr_lo =
+                       txq->ib.ib_seg_host_addr.lsb;
+               cfg_req->q_cfg[i].ib.index_addr.a32.addr_hi =
+                       txq->ib.ib_seg_host_addr.msb;
+               cfg_req->q_cfg[i].ib.intr.msix_index =
+                       htons((u16)txq->ib.intr_vector);
+       }
+
+       cfg_req->ib_cfg.int_pkt_dma = BNA_STATUS_T_ENABLED;
+       cfg_req->ib_cfg.int_enabled = BNA_STATUS_T_ENABLED;
+       cfg_req->ib_cfg.int_pkt_enabled = BNA_STATUS_T_DISABLED;
+       cfg_req->ib_cfg.continuous_coalescing = BNA_STATUS_T_ENABLED;
+       cfg_req->ib_cfg.msix = (txq->ib.intr_type == BNA_INTR_T_MSIX)
+                               ? BNA_STATUS_T_ENABLED : BNA_STATUS_T_DISABLED;
+       cfg_req->ib_cfg.coalescing_timeout =
+                       htonl((u32)txq->ib.coalescing_timeo);
+       cfg_req->ib_cfg.inter_pkt_timeout =
+                       htonl((u32)txq->ib.interpkt_timeo);
+       cfg_req->ib_cfg.inter_pkt_count = (u8)txq->ib.interpkt_count;
+
+       cfg_req->tx_cfg.vlan_mode = BFI_ENET_TX_VLAN_WI;
+       cfg_req->tx_cfg.vlan_id = htons((u16)tx->txf_vlan_id);
+       cfg_req->tx_cfg.admit_tagged_frame = BNA_STATUS_T_DISABLED;
+       cfg_req->tx_cfg.apply_vlan_filter = BNA_STATUS_T_DISABLED;
+
+       bfa_msgq_cmd_set(&tx->msgq_cmd, NULL, NULL,
+               sizeof(struct bfi_enet_tx_cfg_req), &cfg_req->mh);
+       bfa_msgq_cmd_post(&tx->bna->msgq, &tx->msgq_cmd);
+}
+
+static void
+bna_bfi_tx_enet_stop(struct bna_tx *tx)
+{
+       struct bfi_enet_req *req = &tx->bfi_enet_cmd.req;
+
+       bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
+               BFI_ENET_H2I_TX_CFG_CLR_REQ, 0, tx->rid);
+       req->mh.num_entries = htons(
+               bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_req)));
+       bfa_msgq_cmd_set(&tx->msgq_cmd, NULL, NULL, sizeof(struct bfi_enet_req),
+               &req->mh);
+       bfa_msgq_cmd_post(&tx->bna->msgq, &tx->msgq_cmd);
+}
+
+static void
+bna_tx_enet_stop(struct bna_tx *tx)
+{
+       struct bna_txq *txq;
+       struct list_head                 *qe;
+
+       /* Stop IB */
+       list_for_each(qe, &tx->txq_q) {
+               txq = (struct bna_txq *)qe;
+               bna_ib_stop(tx->bna, &txq->ib);
+       }
+
+       bna_bfi_tx_enet_stop(tx);
+}
+
+static void
+bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
+               struct bna_mem_descr *qpt_mem,
+               struct bna_mem_descr *swqpt_mem,
+               struct bna_mem_descr *page_mem)
+{
+       int i;
+
+       txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+       txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+       txq->qpt.kv_qpt_ptr = qpt_mem->kva;
+       txq->qpt.page_count = page_count;
+       txq->qpt.page_size = page_size;
+
+       txq->tcb->sw_qpt = (void **) swqpt_mem->kva;
+
+       for (i = 0; i < page_count; i++) {
+               txq->tcb->sw_qpt[i] = page_mem[i].kva;
+
+               ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
+                       page_mem[i].dma.lsb;
+               ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
+                       page_mem[i].dma.msb;
+       }
+}
+
+static struct bna_tx *
+bna_tx_get(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+       struct list_head        *qe = NULL;
+       struct bna_tx *tx = NULL;
+
+       if (list_empty(&tx_mod->tx_free_q))
+               return NULL;
+       if (type == BNA_TX_T_REGULAR) {
+               bfa_q_deq(&tx_mod->tx_free_q, &qe);
+       } else {
+               bfa_q_deq_tail(&tx_mod->tx_free_q, &qe);
+       }
+       tx = (struct bna_tx *)qe;
+       bfa_q_qe_init(&tx->qe);
+       tx->type = type;
+
+       return tx;
+}
+
+static void
+bna_tx_free(struct bna_tx *tx)
+{
+       struct bna_tx_mod *tx_mod = &tx->bna->tx_mod;
+       struct bna_txq *txq;
+       struct list_head *prev_qe;
+       struct list_head *qe;
+
+       while (!list_empty(&tx->txq_q)) {
+               bfa_q_deq(&tx->txq_q, &txq);
+               bfa_q_qe_init(&txq->qe);
+               txq->tcb = NULL;
+               txq->tx = NULL;
+               list_add_tail(&txq->qe, &tx_mod->txq_free_q);
+       }
+
+       list_for_each(qe, &tx_mod->tx_active_q) {
+               if (qe == &tx->qe) {
+                       list_del(&tx->qe);
+                       bfa_q_qe_init(&tx->qe);
+                       break;
+               }
+       }
+
+       tx->bna = NULL;
+       tx->priv = NULL;
+
+       prev_qe = NULL;
+       list_for_each(qe, &tx_mod->tx_free_q) {
+               if (((struct bna_tx *)qe)->rid < tx->rid)
+                       prev_qe = qe;
+               else {
+                       break;
+               }
+       }
+
+       if (prev_qe == NULL) {
+               /* This is the first entry */
+               bfa_q_enq_head(&tx_mod->tx_free_q, &tx->qe);
+       } else if (bfa_q_next(prev_qe) == &tx_mod->tx_free_q) {
+               /* This is the last entry */
+               list_add_tail(&tx->qe, &tx_mod->tx_free_q);
+       } else {
+               /* Somewhere in the middle */
+               bfa_q_next(&tx->qe) = bfa_q_next(prev_qe);
+               bfa_q_prev(&tx->qe) = prev_qe;
+               bfa_q_next(prev_qe) = &tx->qe;
+               bfa_q_prev(bfa_q_next(&tx->qe)) = &tx->qe;
+       }
+}
+
+static void
+bna_tx_start(struct bna_tx *tx)
+{
+       tx->flags |= BNA_TX_F_ENET_STARTED;
+       if (tx->flags & BNA_TX_F_ENABLED)
+               bfa_fsm_send_event(tx, TX_E_START);
+}
+
+static void
+bna_tx_stop(struct bna_tx *tx)
+{
+       tx->stop_cbfn = bna_tx_mod_cb_tx_stopped;
+       tx->stop_cbarg = &tx->bna->tx_mod;
+
+       tx->flags &= ~BNA_TX_F_ENET_STARTED;
+       bfa_fsm_send_event(tx, TX_E_STOP);
+}
+
+static void
+bna_tx_fail(struct bna_tx *tx)
+{
+       tx->flags &= ~BNA_TX_F_ENET_STARTED;
+       bfa_fsm_send_event(tx, TX_E_FAIL);
+}
+
+void
+bna_bfi_tx_enet_start_rsp(struct bna_tx *tx, struct bfi_msgq_mhdr *msghdr)
+{
+       struct bfi_enet_tx_cfg_rsp *cfg_rsp = &tx->bfi_enet_cmd.cfg_rsp;
+       struct bna_txq *txq = NULL;
+       struct list_head *qe;
+       int i;
+
+       bfa_msgq_rsp_copy(&tx->bna->msgq, (u8 *)cfg_rsp,
+               sizeof(struct bfi_enet_tx_cfg_rsp));
+
+       tx->hw_id = cfg_rsp->hw_id;
+
+       for (i = 0, qe = bfa_q_first(&tx->txq_q);
+               i < tx->num_txq; i++, qe = bfa_q_next(qe)) {
+               txq = (struct bna_txq *)qe;
+
+               /* Setup doorbells */
+               txq->tcb->i_dbell->doorbell_addr =
+                       tx->bna->pcidev.pci_bar_kva
+                       + ntohl(cfg_rsp->q_handles[i].i_dbell);
+               txq->tcb->q_dbell =
+                       tx->bna->pcidev.pci_bar_kva
+                       + ntohl(cfg_rsp->q_handles[i].q_dbell);
+               txq->hw_id = cfg_rsp->q_handles[i].hw_qid;
+
+               /* Initialize producer/consumer indexes */
+               (*txq->tcb->hw_consumer_index) = 0;
+               txq->tcb->producer_index = txq->tcb->consumer_index = 0;
+       }
+
+       bfa_fsm_send_event(tx, TX_E_STARTED);
+}
+
+void
+bna_bfi_tx_enet_stop_rsp(struct bna_tx *tx, struct bfi_msgq_mhdr *msghdr)
+{
+       bfa_fsm_send_event(tx, TX_E_STOPPED);
+}
+
+void
+bna_bfi_bw_update_aen(struct bna_tx_mod *tx_mod)
+{
+       struct bna_tx *tx;
+       struct list_head                *qe;
+
+       list_for_each(qe, &tx_mod->tx_active_q) {
+               tx = (struct bna_tx *)qe;
+               bfa_fsm_send_event(tx, TX_E_BW_UPDATE);
+       }
+}
+
+void
+bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
+{
+       u32 q_size;
+       u32 page_count;
+       struct bna_mem_info *mem_info;
+
+       res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = sizeof(struct bna_tcb);
+       mem_info->num = num_txq;
+
+       q_size = txq_depth * BFI_TXQ_WI_SIZE;
+       q_size = ALIGN(q_size, PAGE_SIZE);
+       page_count = q_size >> PAGE_SHIFT;
+
+       res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = page_count * sizeof(struct bna_dma_addr);
+       mem_info->num = num_txq;
+
+       res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_KVA;
+       mem_info->len = page_count * sizeof(void *);
+       mem_info->num = num_txq;
+
+       res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = PAGE_SIZE;
+       mem_info->num = num_txq * page_count;
+
+       res_info[BNA_TX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
+       mem_info = &res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info;
+       mem_info->mem_type = BNA_MEM_T_DMA;
+       mem_info->len = BFI_IBIDX_SIZE;
+       mem_info->num = num_txq;
+
+       res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR;
+       res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type =
+                       BNA_INTR_T_MSIX;
+       res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq;
+}
+
+struct bna_tx *
+bna_tx_create(struct bna *bna, struct bnad *bnad,
+               struct bna_tx_config *tx_cfg,
+               struct bna_tx_event_cbfn *tx_cbfn,
+               struct bna_res_info *res_info, void *priv)
+{
+       struct bna_intr_info *intr_info;
+       struct bna_tx_mod *tx_mod = &bna->tx_mod;
+       struct bna_tx *tx;
+       struct bna_txq *txq;
+       struct list_head *qe;
+       int page_count;
+       int page_size;
+       int page_idx;
+       int i;
+
+       intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
+       page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) /
+                       tx_cfg->num_txq;
+       page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len;
+
+       /**
+        * Get resources
+        */
+
+       if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq))
+               return NULL;
+
+       /* Tx */
+
+       tx = bna_tx_get(tx_mod, tx_cfg->tx_type);
+       if (!tx)
+               return NULL;
+       tx->bna = bna;
+       tx->priv = priv;
+
+       /* TxQs */
+
+       INIT_LIST_HEAD(&tx->txq_q);
+       for (i = 0; i < tx_cfg->num_txq; i++) {
+               if (list_empty(&tx_mod->txq_free_q))
+                       goto err_return;
+
+               bfa_q_deq(&tx_mod->txq_free_q, &txq);
+               bfa_q_qe_init(&txq->qe);
+               list_add_tail(&txq->qe, &tx->txq_q);
+               txq->tx = tx;
+       }
+
+       /*
+        * Initialize
+        */
+
+       /* Tx */
+
+       tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn;
+       tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn;
+       /* Following callbacks are mandatory */
+       tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn;
+       tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn;
+       tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn;
+
+       list_add_tail(&tx->qe, &tx_mod->tx_active_q);
+
+       tx->num_txq = tx_cfg->num_txq;
+
+       tx->flags = 0;
+       if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_ENET_STARTED) {
+               switch (tx->type) {
+               case BNA_TX_T_REGULAR:
+                       if (!(tx->bna->tx_mod.flags &
+                               BNA_TX_MOD_F_ENET_LOOPBACK))
+                               tx->flags |= BNA_TX_F_ENET_STARTED;
+                       break;
+               case BNA_TX_T_LOOPBACK:
+                       if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_ENET_LOOPBACK)
+                               tx->flags |= BNA_TX_F_ENET_STARTED;
+                       break;
+               }
+       }
+
+       /* TxQ */
+
+       i = 0;
+       page_idx = 0;
+       list_for_each(qe, &tx->txq_q) {
+               txq = (struct bna_txq *)qe;
+               txq->tcb = (struct bna_tcb *)
+               res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva;
+               txq->tx_packets = 0;
+               txq->tx_bytes = 0;
+
+               /* IB */
+               txq->ib.ib_seg_host_addr.lsb =
+               res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
+               txq->ib.ib_seg_host_addr.msb =
+               res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
+               txq->ib.ib_seg_host_addr_kva =
+               res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
+               txq->ib.intr_type = intr_info->intr_type;
+               txq->ib.intr_vector = (intr_info->num == 1) ?
+                                       intr_info->idl[0].vector :
+                                       intr_info->idl[i].vector;
+               if (intr_info->intr_type == BNA_INTR_T_INTX)
+                       txq->ib.intr_vector = (1 <<  txq->ib.intr_vector);
+               txq->ib.coalescing_timeo = tx_cfg->coalescing_timeo;
+               txq->ib.interpkt_timeo = 0; /* Not used */
+               txq->ib.interpkt_count = BFI_TX_INTERPKT_COUNT;
+
+               /* TCB */
+
+               txq->tcb->q_depth = tx_cfg->txq_depth;
+               txq->tcb->unmap_q = (void *)
+               res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva;
+               txq->tcb->hw_consumer_index =
+                       (u32 *)txq->ib.ib_seg_host_addr_kva;
+               txq->tcb->i_dbell = &txq->ib.door_bell;
+               txq->tcb->intr_type = txq->ib.intr_type;
+               txq->tcb->intr_vector = txq->ib.intr_vector;
+               txq->tcb->txq = txq;
+               txq->tcb->bnad = bnad;
+               txq->tcb->id = i;
+
+               /* QPT, SWQPT, Pages */
+               bna_txq_qpt_setup(txq, page_count, page_size,
+                       &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
+                       &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
+                       &res_info[BNA_TX_RES_MEM_T_PAGE].
+                                 res_u.mem_info.mdl[page_idx]);
+               txq->tcb->page_idx = page_idx;
+               txq->tcb->page_count = page_count;
+               page_idx += page_count;
+
+               /* Callback to bnad for setting up TCB */
+               if (tx->tcb_setup_cbfn)
+                       (tx->tcb_setup_cbfn)(bna->bnad, txq->tcb);
+
+               if (tx_cfg->num_txq == BFI_TX_MAX_PRIO)
+                       txq->priority = txq->tcb->id;
+               else
+                       txq->priority = tx_mod->default_prio;
+
+               i++;
+       }
+
+       tx->txf_vlan_id = 0;
+
+       bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+
+       tx_mod->rid_mask |= (1 << tx->rid);
+
+       return tx;
+
+err_return:
+       bna_tx_free(tx);
+       return NULL;
+}
+
+void
+bna_tx_destroy(struct bna_tx *tx)
+{
+       struct bna_txq *txq;
+       struct list_head *qe;
+
+       list_for_each(qe, &tx->txq_q) {
+               txq = (struct bna_txq *)qe;
+               if (tx->tcb_destroy_cbfn)
+                       (tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb);
+       }
+
+       tx->bna->tx_mod.rid_mask &= ~(1 << tx->rid);
+       bna_tx_free(tx);
+}
+
+void
+bna_tx_enable(struct bna_tx *tx)
+{
+       if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped)
+               return;
+
+       tx->flags |= BNA_TX_F_ENABLED;
+
+       if (tx->flags & BNA_TX_F_ENET_STARTED)
+               bfa_fsm_send_event(tx, TX_E_START);
+}
+
+void
+bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
+               void (*cbfn)(void *, struct bna_tx *))
+{
+       if (type == BNA_SOFT_CLEANUP) {
+               (*cbfn)(tx->bna->bnad, tx);
+               return;
+       }
+
+       tx->stop_cbfn = cbfn;
+       tx->stop_cbarg = tx->bna->bnad;
+
+       tx->flags &= ~BNA_TX_F_ENABLED;
+
+       bfa_fsm_send_event(tx, TX_E_STOP);
+}
+
+void
+bna_tx_cleanup_complete(struct bna_tx *tx)
+{
+       bfa_fsm_send_event(tx, TX_E_CLEANUP_DONE);
+}
+
+static void
+bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx)
+{
+       struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
+
+       bfa_wc_down(&tx_mod->tx_stop_wc);
+}
+
+static void
+bna_tx_mod_cb_tx_stopped_all(void *arg)
+{
+       struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
+
+       if (tx_mod->stop_cbfn)
+               tx_mod->stop_cbfn(&tx_mod->bna->enet);
+       tx_mod->stop_cbfn = NULL;
+}
+
+void
+bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
+               struct bna_res_info *res_info)
+{
+       int i;
+
+       tx_mod->bna = bna;
+       tx_mod->flags = 0;
+
+       tx_mod->tx = (struct bna_tx *)
+               res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva;
+       tx_mod->txq = (struct bna_txq *)
+               res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva;
+
+       INIT_LIST_HEAD(&tx_mod->tx_free_q);
+       INIT_LIST_HEAD(&tx_mod->tx_active_q);
+
+       INIT_LIST_HEAD(&tx_mod->txq_free_q);
+
+       for (i = 0; i < bna->ioceth.attr.num_txq; i++) {
+               tx_mod->tx[i].rid = i;
+               bfa_q_qe_init(&tx_mod->tx[i].qe);
+               list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q);
+               bfa_q_qe_init(&tx_mod->txq[i].qe);
+               list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q);
+       }
+
+       tx_mod->prio_map = BFI_TX_PRIO_MAP_ALL;
+       tx_mod->default_prio = 0;
+       tx_mod->iscsi_over_cee = BNA_STATUS_T_DISABLED;
+       tx_mod->iscsi_prio = -1;
+}
+
+void
+bna_tx_mod_uninit(struct bna_tx_mod *tx_mod)
+{
+       struct list_head                *qe;
+       int i;
+
+       i = 0;
+       list_for_each(qe, &tx_mod->tx_free_q)
+               i++;
+
+       i = 0;
+       list_for_each(qe, &tx_mod->txq_free_q)
+               i++;
+
+       tx_mod->bna = NULL;
+}
+
+void
+bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+       struct bna_tx *tx;
+       struct list_head                *qe;
+
+       tx_mod->flags |= BNA_TX_MOD_F_ENET_STARTED;
+       if (type == BNA_TX_T_LOOPBACK)
+               tx_mod->flags |= BNA_TX_MOD_F_ENET_LOOPBACK;
+
+       list_for_each(qe, &tx_mod->tx_active_q) {
+               tx = (struct bna_tx *)qe;
+               if (tx->type == type)
+                       bna_tx_start(tx);
+       }
+}
+
+void
+bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+       struct bna_tx *tx;
+       struct list_head                *qe;
+
+       tx_mod->flags &= ~BNA_TX_MOD_F_ENET_STARTED;
+       tx_mod->flags &= ~BNA_TX_MOD_F_ENET_LOOPBACK;
+
+       tx_mod->stop_cbfn = bna_enet_cb_tx_stopped;
+
+       bfa_wc_init(&tx_mod->tx_stop_wc, bna_tx_mod_cb_tx_stopped_all, tx_mod);
+
+       list_for_each(qe, &tx_mod->tx_active_q) {
+               tx = (struct bna_tx *)qe;
+               if (tx->type == type) {
+                       bfa_wc_up(&tx_mod->tx_stop_wc);
+                       bna_tx_stop(tx);
+               }
+       }
+
+       bfa_wc_wait(&tx_mod->tx_stop_wc);
+}
+
+void
+bna_tx_mod_fail(struct bna_tx_mod *tx_mod)
+{
+       struct bna_tx *tx;
+       struct list_head                *qe;
+
+       tx_mod->flags &= ~BNA_TX_MOD_F_ENET_STARTED;
+       tx_mod->flags &= ~BNA_TX_MOD_F_ENET_LOOPBACK;
+
+       list_for_each(qe, &tx_mod->tx_active_q) {
+               tx = (struct bna_tx *)qe;
+               bna_tx_fail(tx);
+       }
+}
+
+void
+bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo)
+{
+       struct bna_txq *txq;
+       struct list_head *qe;
+
+       list_for_each(qe, &tx->txq_q) {
+               txq = (struct bna_txq *)qe;
+               bna_ib_coalescing_timeo_set(&txq->ib, coalescing_timeo);
+       }
+}
similarity index 58%
rename from drivers/net/bna/bna_types.h
rename to drivers/net/ethernet/brocade/bna/bna_types.h
index 2f89cb235248b234e34853c0efb6de588e11c730..8a6da0c3cd89febc63f6cfbe33832e109e19dea2 100644 (file)
 #define __BNA_TYPES_H__
 
 #include "cna.h"
-#include "bna_hw.h"
+#include "bna_hw_defs.h"
 #include "bfa_cee.h"
+#include "bfi_enet.h"
+#include "bfa_msgq.h"
 
 /**
  *
  *
  */
 
+struct bna_mcam_handle;
 struct bna_txq;
 struct bna_tx;
 struct bna_rxq;
 struct bna_cq;
 struct bna_rx;
 struct bna_rxf;
-struct bna_port;
+struct bna_enet;
 struct bna;
 struct bnad;
 
@@ -86,31 +89,29 @@ enum bna_res_req_type {
        BNA_RES_MEM_T_ATTR              = 1,
        BNA_RES_MEM_T_FWTRC             = 2,
        BNA_RES_MEM_T_STATS             = 3,
-       BNA_RES_MEM_T_SWSTATS           = 4,
-       BNA_RES_MEM_T_IBIDX             = 5,
-       BNA_RES_MEM_T_IB_ARRAY          = 6,
-       BNA_RES_MEM_T_INTR_ARRAY        = 7,
-       BNA_RES_MEM_T_IDXSEG_ARRAY      = 8,
-       BNA_RES_MEM_T_TX_ARRAY          = 9,
-       BNA_RES_MEM_T_TXQ_ARRAY         = 10,
-       BNA_RES_MEM_T_RX_ARRAY          = 11,
-       BNA_RES_MEM_T_RXP_ARRAY         = 12,
-       BNA_RES_MEM_T_RXQ_ARRAY         = 13,
-       BNA_RES_MEM_T_UCMAC_ARRAY       = 14,
-       BNA_RES_MEM_T_MCMAC_ARRAY       = 15,
-       BNA_RES_MEM_T_RIT_ENTRY         = 16,
-       BNA_RES_MEM_T_RIT_SEGMENT       = 17,
-       BNA_RES_INTR_T_MBOX             = 18,
        BNA_RES_T_MAX
 };
 
+enum bna_mod_res_req_type {
+       BNA_MOD_RES_MEM_T_TX_ARRAY      = 0,
+       BNA_MOD_RES_MEM_T_TXQ_ARRAY     = 1,
+       BNA_MOD_RES_MEM_T_RX_ARRAY      = 2,
+       BNA_MOD_RES_MEM_T_RXP_ARRAY     = 3,
+       BNA_MOD_RES_MEM_T_RXQ_ARRAY     = 4,
+       BNA_MOD_RES_MEM_T_UCMAC_ARRAY   = 5,
+       BNA_MOD_RES_MEM_T_MCMAC_ARRAY   = 6,
+       BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY = 7,
+       BNA_MOD_RES_T_MAX
+};
+
 enum bna_tx_res_req_type {
        BNA_TX_RES_MEM_T_TCB    = 0,
        BNA_TX_RES_MEM_T_UNMAPQ = 1,
        BNA_TX_RES_MEM_T_QPT    = 2,
        BNA_TX_RES_MEM_T_SWQPT  = 3,
        BNA_TX_RES_MEM_T_PAGE   = 4,
-       BNA_TX_RES_INTR_T_TXCMPL = 5,
+       BNA_TX_RES_MEM_T_IBIDX  = 5,
+       BNA_TX_RES_INTR_T_TXCMPL = 6,
        BNA_TX_RES_T_MAX,
 };
 
@@ -127,13 +128,10 @@ enum bna_rx_mem_type {
        BNA_RX_RES_MEM_T_DSWQPT         = 9,    /* RX s/w QPT */
        BNA_RX_RES_MEM_T_DPAGE          = 10,   /* RX s/w QPT */
        BNA_RX_RES_MEM_T_HPAGE          = 11,   /* RX s/w QPT */
-       BNA_RX_RES_T_INTR               = 12,   /* Rx interrupts */
-       BNA_RX_RES_T_MAX                = 13
-};
-
-enum bna_mbox_state {
-       BNA_MBOX_FREE           = 0,
-       BNA_MBOX_POSTED         = 1
+       BNA_RX_RES_MEM_T_IBIDX          = 12,
+       BNA_RX_RES_MEM_T_RIT            = 13,
+       BNA_RX_RES_T_INTR               = 14,   /* Rx interrupts */
+       BNA_RX_RES_T_MAX                = 15
 };
 
 enum bna_tx_type {
@@ -142,14 +140,15 @@ enum bna_tx_type {
 };
 
 enum bna_tx_flags {
-       BNA_TX_F_PORT_STARTED   = 1,
+       BNA_TX_F_ENET_STARTED   = 1,
        BNA_TX_F_ENABLED        = 2,
-       BNA_TX_F_PRIO_LOCK      = 4,
+       BNA_TX_F_PRIO_CHANGED   = 4,
+       BNA_TX_F_BW_UPDATED     = 8,
 };
 
 enum bna_tx_mod_flags {
-       BNA_TX_MOD_F_PORT_STARTED       = 1,
-       BNA_TX_MOD_F_PORT_LOOPBACK      = 2,
+       BNA_TX_MOD_F_ENET_STARTED       = 1,
+       BNA_TX_MOD_F_ENET_LOOPBACK      = 2,
 };
 
 enum bna_rx_type {
@@ -165,80 +164,49 @@ enum bna_rxp_type {
 
 enum bna_rxmode {
        BNA_RXMODE_PROMISC      = 1,
-       BNA_RXMODE_ALLMULTI     = 2
+       BNA_RXMODE_DEFAULT      = 2,
+       BNA_RXMODE_ALLMULTI     = 4
 };
 
 enum bna_rx_event {
        RX_E_START                      = 1,
        RX_E_STOP                       = 2,
        RX_E_FAIL                       = 3,
-       RX_E_RXF_STARTED                = 4,
-       RX_E_RXF_STOPPED                = 5,
-       RX_E_RXQ_STOPPED                = 6,
-};
-
-enum bna_rx_state {
-       BNA_RX_STOPPED                  = 1,
-       BNA_RX_RXF_START_WAIT           = 2,
-       BNA_RX_STARTED                  = 3,
-       BNA_RX_RXF_STOP_WAIT            = 4,
-       BNA_RX_RXQ_STOP_WAIT            = 5,
+       RX_E_STARTED                    = 4,
+       RX_E_STOPPED                    = 5,
+       RX_E_RXF_STARTED                = 6,
+       RX_E_RXF_STOPPED                = 7,
+       RX_E_CLEANUP_DONE               = 8,
 };
 
 enum bna_rx_flags {
-       BNA_RX_F_ENABLE         = 0x01,         /* bnad enabled rxf */
-       BNA_RX_F_PORT_ENABLED   = 0x02,         /* Port object is enabled */
-       BNA_RX_F_PORT_FAILED    = 0x04,         /* Port in failed state */
+       BNA_RX_F_ENET_STARTED   = 1,
+       BNA_RX_F_ENABLED        = 2,
 };
 
 enum bna_rx_mod_flags {
-       BNA_RX_MOD_F_PORT_STARTED       = 1,
-       BNA_RX_MOD_F_PORT_LOOPBACK      = 2,
-};
-
-enum bna_rxf_oper_state {
-       BNA_RXF_OPER_STATE_RUNNING      = 0x01, /* rxf operational */
-       BNA_RXF_OPER_STATE_PAUSED       = 0x02, /* rxf in PAUSED state */
+       BNA_RX_MOD_F_ENET_STARTED       = 1,
+       BNA_RX_MOD_F_ENET_LOOPBACK      = 2,
 };
 
 enum bna_rxf_flags {
-       BNA_RXF_FL_STOP_PENDING         = 0x01,
-       BNA_RXF_FL_FAILED               = 0x02,
-       BNA_RXF_FL_RSS_CONFIG_PENDING   = 0x04,
-       BNA_RXF_FL_OPERSTATE_CHANGED    = 0x08,
-       BNA_RXF_FL_RXF_ENABLED          = 0x10,
-       BNA_RXF_FL_VLAN_CONFIG_PENDING  = 0x20,
+       BNA_RXF_F_PAUSED                = 1,
 };
 
 enum bna_rxf_event {
        RXF_E_START                     = 1,
        RXF_E_STOP                      = 2,
        RXF_E_FAIL                      = 3,
-       RXF_E_CAM_FLTR_MOD              = 4,
-       RXF_E_STARTED                   = 5,
-       RXF_E_STOPPED                   = 6,
-       RXF_E_CAM_FLTR_RESP             = 7,
-       RXF_E_PAUSE                     = 8,
-       RXF_E_RESUME                    = 9,
-       RXF_E_STAT_CLEARED              = 10,
-};
-
-enum bna_rxf_state {
-       BNA_RXF_STOPPED                 = 1,
-       BNA_RXF_START_WAIT              = 2,
-       BNA_RXF_CAM_FLTR_MOD_WAIT       = 3,
-       BNA_RXF_STARTED                 = 4,
-       BNA_RXF_CAM_FLTR_CLR_WAIT       = 5,
-       BNA_RXF_STOP_WAIT               = 6,
-       BNA_RXF_PAUSE_WAIT              = 7,
-       BNA_RXF_RESUME_WAIT             = 8,
-       BNA_RXF_STAT_CLR_WAIT           = 9,
+       RXF_E_CONFIG                    = 4,
+       RXF_E_PAUSE                     = 5,
+       RXF_E_RESUME                    = 6,
+       RXF_E_FW_RESP                   = 7,
 };
 
-enum bna_port_type {
-       BNA_PORT_T_REGULAR              = 0,
-       BNA_PORT_T_LOOPBACK_INTERNAL    = 1,
-       BNA_PORT_T_LOOPBACK_EXTERNAL    = 2,
+enum bna_enet_type {
+       BNA_ENET_T_REGULAR              = 0,
+       BNA_ENET_T_LOOPBACK_INTERNAL    = 1,
+       BNA_ENET_T_LOOPBACK_EXTERNAL    = 2,
 };
 
 enum bna_link_status {
@@ -247,17 +215,27 @@ enum bna_link_status {
        BNA_CEE_UP              = 2
 };
 
-enum bna_llport_flags {
-       BNA_LLPORT_F_ADMIN_UP           = 1,
-       BNA_LLPORT_F_PORT_ENABLED       = 2,
-       BNA_LLPORT_F_RX_STARTED         = 4
+enum bna_ethport_flags {
+       BNA_ETHPORT_F_ADMIN_UP          = 1,
+       BNA_ETHPORT_F_PORT_ENABLED      = 2,
+       BNA_ETHPORT_F_RX_STARTED        = 4,
 };
 
-enum bna_port_flags {
-       BNA_PORT_F_DEVICE_READY = 1,
-       BNA_PORT_F_ENABLED      = 2,
-       BNA_PORT_F_PAUSE_CHANGED = 4,
-       BNA_PORT_F_MTU_CHANGED  = 8
+enum bna_enet_flags {
+       BNA_ENET_F_IOCETH_READY         = 1,
+       BNA_ENET_F_ENABLED              = 2,
+       BNA_ENET_F_PAUSE_CHANGED        = 4,
+       BNA_ENET_F_MTU_CHANGED          = 8
+};
+
+enum bna_rss_flags {
+       BNA_RSS_F_RIT_PENDING           = 1,
+       BNA_RSS_F_CFG_PENDING           = 2,
+       BNA_RSS_F_STATUS_PENDING        = 4,
+};
+
+enum bna_mod_flags {
+       BNA_MOD_F_INIT_DONE             = 1,
 };
 
 enum bna_pkt_rates {
@@ -289,10 +267,17 @@ enum bna_dim_bias_types {
        BNA_BIAS_T_MAX                  = 2
 };
 
+#define BNA_MAX_NAME_SIZE      64
+struct bna_ident {
+       int                     id;
+       char                    name[BNA_MAX_NAME_SIZE];
+};
+
 struct bna_mac {
        /* This should be the first one */
        struct list_head                        qe;
        u8                      addr[ETH_ALEN];
+       struct bna_mcam_handle *handle;
 };
 
 struct bna_mem_descr {
@@ -338,23 +323,29 @@ struct bna_qpt {
        u32             page_size;
 };
 
+struct bna_attr {
+       int                     num_txq;
+       int                     num_rxp;
+       int                     num_ucmac;
+       int                     num_mcmac;
+       int                     max_rit_size;
+};
+
 /**
  *
- * Device
+ * IOCEth
  *
  */
 
-struct bna_device {
+struct bna_ioceth {
        bfa_fsm_t               fsm;
        struct bfa_ioc ioc;
 
-       enum bna_intr_type intr_type;
-       int                     vector;
+       struct bna_attr attr;
+       struct bfa_msgq_cmd_entry msgq_cmd;
+       struct bfi_enet_attr_req attr_req;
 
-       void (*ready_cbfn)(struct bnad *bnad, enum bna_cb_status status);
-       struct bnad *ready_cbarg;
-
-       void (*stop_cbfn)(struct bnad *bnad, enum bna_cb_status status);
+       void (*stop_cbfn)(struct bnad *bnad);
        struct bnad *stop_cbarg;
 
        struct bna *bna;
@@ -362,32 +353,7 @@ struct bna_device {
 
 /**
  *
- * Mail box
- *
- */
-
-struct bna_mbox_qe {
-       /* This should be the first one */
-       struct list_head                        qe;
-
-       struct bfa_mbox_cmd cmd;
-       u32             cmd_len;
-       /* Callback for port, tx, rx, rxf */
-       void (*cbfn)(void *arg, int status);
-       void                    *cbarg;
-};
-
-struct bna_mbox_mod {
-       enum bna_mbox_state state;
-       struct list_head                        posted_q;
-       u32             msg_pending;
-       u32             msg_ctr;
-       struct bna *bna;
-};
-
-/**
- *
- * Port
+ * Enet
  *
  */
 
@@ -397,50 +363,58 @@ struct bna_pause_config {
        enum bna_status rx_pause;
 };
 
-struct bna_llport {
+struct bna_enet {
        bfa_fsm_t               fsm;
-       enum bna_llport_flags flags;
+       enum bna_enet_flags flags;
 
-       enum bna_port_type type;
+       enum bna_enet_type type;
 
-       enum bna_link_status link_status;
+       struct bna_pause_config pause_config;
+       int                     mtu;
 
-       int                     rx_started_count;
+       /* Callback for bna_enet_disable(), enet_stop() */
+       void (*stop_cbfn)(void *);
+       void                    *stop_cbarg;
+
+       /* Callback for bna_enet_pause_config() */
+       void (*pause_cbfn)(struct bnad *);
+
+       /* Callback for bna_enet_mtu_set() */
+       void (*mtu_cbfn)(struct bnad *);
 
-       void (*stop_cbfn)(struct bna_port *, enum bna_cb_status);
+       struct bfa_wc           chld_stop_wc;
 
-       struct bna_mbox_qe mbox_qe;
+       struct bfa_msgq_cmd_entry msgq_cmd;
+       struct bfi_enet_set_pause_req pause_req;
 
        struct bna *bna;
 };
 
-struct bna_port {
-       bfa_fsm_t               fsm;
-       enum bna_port_flags flags;
-
-       enum bna_port_type type;
+/**
+ *
+ * Ethport
+ *
+ */
 
-       struct bna_llport llport;
+struct bna_ethport {
+       bfa_fsm_t               fsm;
+       enum bna_ethport_flags flags;
 
-       struct bna_pause_config pause_config;
-       u8                      priority;
-       int                     mtu;
+       enum bna_link_status link_status;
 
-       /* Callback for bna_port_disable(), port_stop() */
-       void (*stop_cbfn)(void *, enum bna_cb_status);
-       void                    *stop_cbarg;
+       int                     rx_started_count;
 
-       /* Callback for bna_port_pause_config() */
-       void (*pause_cbfn)(struct bnad *, enum bna_cb_status);
+       void (*stop_cbfn)(struct bna_enet *);
 
-       /* Callback for bna_port_mtu_set() */
-       void (*mtu_cbfn)(struct bnad *, enum bna_cb_status);
+       void (*adminup_cbfn)(struct bnad *, enum bna_cb_status);
 
        void (*link_cbfn)(struct bnad *, enum bna_link_status);
 
-       struct bfa_wc           chld_stop_wc;
-
-       struct bna_mbox_qe mbox_qe;
+       struct bfa_msgq_cmd_entry msgq_cmd;
+       union {
+               struct bfi_enet_enable_req admin_req;
+               struct bfi_enet_diag_lb_req lpbk_req;
+       } bfi_enet_cmd;
 
        struct bna *bna;
 };
@@ -451,82 +425,26 @@ struct bna_port {
  *
  */
 
-/* IB index segment structure */
-struct bna_ibidx_seg {
-       /* This should be the first one */
-       struct list_head                        qe;
-
-       u8                      ib_seg_size;
-       u8                      ib_idx_tbl_offset;
-};
-
-/* Interrupt structure */
-struct bna_intr {
-       /* This should be the first one */
-       struct list_head                        qe;
-       int                     ref_count;
-
-       enum bna_intr_type intr_type;
-       int                     vector;
-
-       struct bna_ib *ib;
-};
-
 /* Doorbell structure */
 struct bna_ib_dbell {
        void *__iomem doorbell_addr;
        u32             doorbell_ack;
 };
 
-/* Interrupt timer configuration */
-struct bna_ib_config {
-       u8              coalescing_timeo;    /* Unit is 5usec. */
-
-       int                     interpkt_count;
-       int                     interpkt_timeo;
-
-       enum ib_flags ctrl_flags;
-};
-
 /* IB structure */
 struct bna_ib {
-       /* This should be the first one */
-       struct list_head                        qe;
-
-       int                     ib_id;
-
-       int                     ref_count;
-       int                     start_count;
-
        struct bna_dma_addr ib_seg_host_addr;
        void            *ib_seg_host_addr_kva;
-       u32             idx_mask; /* Size >= BNA_IBIDX_MAX_SEGSIZE */
-
-       struct bna_ibidx_seg *idx_seg;
 
        struct bna_ib_dbell door_bell;
 
-       struct bna_intr *intr;
-
-       struct bna_ib_config ib_config;
-
-       struct bna *bna;
-};
-
-/* IB module - keeps track of IBs and interrupts */
-struct bna_ib_mod {
-       struct bna_ib *ib;              /* BFI_MAX_IB entries */
-       struct bna_intr *intr;          /* BFI_MAX_IB entries */
-       struct bna_ibidx_seg *idx_seg;  /* BNA_IBIDX_TOTAL_SEGS */
-
-       struct list_head                        ib_free_q;
-
-       struct list_head                ibidx_seg_pool[BFI_IBIDX_TOTAL_POOLS];
+       enum bna_intr_type      intr_type;
+       int                     intr_vector;
 
-       struct list_head                        intr_free_q;
-       struct list_head                        intr_active_q;
+       u8                      coalescing_timeo;    /* Unit is 5usec. */
 
-       struct bna *bna;
+       int                     interpkt_count;
+       int                     interpkt_timeo;
 };
 
 /**
@@ -552,6 +470,7 @@ struct bna_tcb {
        /* Control path */
        struct bna_txq *txq;
        struct bnad *bnad;
+       void                    *priv; /* BNAD's cookie */
        enum bna_intr_type intr_type;
        int                     intr_vector;
        u8                      priority; /* Current priority */
@@ -565,68 +484,66 @@ struct bna_txq {
        /* This should be the first one */
        struct list_head                        qe;
 
-       int                     txq_id;
-
        u8                      priority;
 
        struct bna_qpt qpt;
        struct bna_tcb *tcb;
-       struct bna_ib *ib;
-       int                     ib_seg_offset;
+       struct bna_ib ib;
 
        struct bna_tx *tx;
 
+       int                     hw_id;
+
        u64             tx_packets;
        u64             tx_bytes;
 };
 
-/* TxF structure (hardware Tx Function) */
-struct bna_txf {
-       int                     txf_id;
-       enum txf_flags ctrl_flags;
-       u16             vlan;
-};
-
 /* Tx object */
 struct bna_tx {
        /* This should be the first one */
        struct list_head                        qe;
+       int                     rid;
+       int                     hw_id;
 
        bfa_fsm_t               fsm;
        enum bna_tx_flags flags;
 
        enum bna_tx_type type;
+       int                     num_txq;
 
        struct list_head                        txq_q;
-       struct bna_txf txf;
+       u16                     txf_vlan_id;
 
        /* Tx event handlers */
        void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *);
        void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *);
-       void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *);
-       void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *);
-       void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *);
+       void (*tx_stall_cbfn)(struct bnad *, struct bna_tx *);
+       void (*tx_resume_cbfn)(struct bnad *, struct bna_tx *);
+       void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tx *);
 
        /* callback for bna_tx_disable(), bna_tx_stop() */
-       void (*stop_cbfn)(void *arg, struct bna_tx *tx,
-                               enum bna_cb_status status);
+       void (*stop_cbfn)(void *arg, struct bna_tx *tx);
        void                    *stop_cbarg;
 
        /* callback for bna_tx_prio_set() */
-       void (*prio_change_cbfn)(struct bnad *bnad, struct bna_tx *tx,
-                               enum bna_cb_status status);
-
-       struct bfa_wc           txq_stop_wc;
+       void (*prio_change_cbfn)(struct bnad *bnad, struct bna_tx *tx);
 
-       struct bna_mbox_qe mbox_qe;
+       struct bfa_msgq_cmd_entry msgq_cmd;
+       union {
+               struct bfi_enet_tx_cfg_req      cfg_req;
+               struct bfi_enet_req             req;
+               struct bfi_enet_tx_cfg_rsp      cfg_rsp;
+       } bfi_enet_cmd;
 
        struct bna *bna;
        void                    *priv;  /* bnad's cookie */
 };
 
+/* Tx object configuration used during creation */
 struct bna_tx_config {
        int                     num_txq;
        int                     txq_depth;
+       int                     coalescing_timeo;
        enum bna_tx_type tx_type;
 };
 
@@ -635,9 +552,9 @@ struct bna_tx_event_cbfn {
        void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *);
        void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *);
        /* Mandatory */
-       void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *);
-       void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *);
-       void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *);
+       void (*tx_stall_cbfn)(struct bnad *, struct bna_tx *);
+       void (*tx_resume_cbfn)(struct bnad *, struct bna_tx *);
+       void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tx *);
 };
 
 /* Tx module - keeps track of free, active tx objects */
@@ -651,55 +568,23 @@ struct bna_tx_mod {
        struct list_head                        txq_free_q;
 
        /* callback for bna_tx_mod_stop() */
-       void (*stop_cbfn)(struct bna_port *port,
-                               enum bna_cb_status status);
+       void (*stop_cbfn)(struct bna_enet *enet);
 
        struct bfa_wc           tx_stop_wc;
 
        enum bna_tx_mod_flags flags;
 
-       int                     priority;
-       int                     cee_link;
+       u8                      prio_map;
+       int                     default_prio;
+       int                     iscsi_over_cee;
+       int                     iscsi_prio;
+       int                     prio_reconfigured;
 
-       u32             txf_bmap[2];
+       u32                     rid_mask;
 
        struct bna *bna;
 };
 
-/**
- *
- * Receive Indirection Table
- *
- */
-
-/* One row of RIT table */
-struct bna_rit_entry {
-       u8 large_rxq_id;        /* used for either large or data buffers */
-       u8 small_rxq_id;        /* used for either small or header buffers */
-};
-
-/* RIT segment */
-struct bna_rit_segment {
-       struct list_head                        qe;
-
-       u32             rit_offset;
-       u32             rit_size;
-       /**
-        * max_rit_size: Varies per RIT segment depending on how RIT is
-        * partitioned
-        */
-       u32             max_rit_size;
-
-       struct bna_rit_entry *rit;
-};
-
-struct bna_rit_mod {
-       struct bna_rit_entry *rit;
-       struct bna_rit_segment *rit_segment;
-
-       struct list_head                rit_seg_pool[BFI_RIT_SEG_TOTAL_POOLS];
-};
-
 /**
  *
  * Rx object
@@ -719,8 +604,9 @@ struct bna_rcb {
        int                     page_count;
        /* Control path */
        struct bna_rxq *rxq;
-       struct bna_cq *cq;
+       struct bna_ccb *ccb;
        struct bnad *bnad;
+       void                    *priv; /* BNAD's cookie */
        unsigned long           flags;
        int                     id;
 };
@@ -728,7 +614,6 @@ struct bna_rcb {
 /* RxQ structure - QPT, configuration */
 struct bna_rxq {
        struct list_head                        qe;
-       int                     rxq_id;
 
        int                     buffer_size;
        int                     q_depth;
@@ -739,6 +624,8 @@ struct bna_rxq {
        struct bna_rxp *rxp;
        struct bna_rx *rx;
 
+       int                     hw_id;
+
        u64             rx_packets;
        u64             rx_bytes;
        u64             rx_packets_with_error;
@@ -784,6 +671,7 @@ struct bna_ccb {
        /* Control path */
        struct bna_cq *cq;
        struct bnad *bnad;
+       void                    *priv; /* BNAD's cookie */
        enum bna_intr_type intr_type;
        int                     intr_vector;
        u8                      rx_coalescing_timeo; /* For NAPI */
@@ -793,46 +681,43 @@ struct bna_ccb {
 
 /* CQ QPT, configuration  */
 struct bna_cq {
-       int                     cq_id;
-
        struct bna_qpt qpt;
        struct bna_ccb *ccb;
 
-       struct bna_ib *ib;
-       u8                      ib_seg_offset;
+       struct bna_ib ib;
 
        struct bna_rx *rx;
 };
 
 struct bna_rss_config {
-       enum rss_hash_type hash_type;
+       enum bfi_enet_rss_type  hash_type;
        u8                      hash_mask;
-       u32             toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN];
+       u32             toeplitz_hash_key[BFI_ENET_RSS_KEY_LEN];
 };
 
 struct bna_hds_config {
-       enum hds_header_type hdr_type;
-       int                     header_size;
+       enum bfi_enet_hds_type  hdr_type;
+       int                     forced_offset;
 };
 
-/* This structure is used during RX creation */
+/* Rx object configuration used during creation */
 struct bna_rx_config {
        enum bna_rx_type rx_type;
        int                     num_paths;
        enum bna_rxp_type rxp_type;
        int                     paused;
        int                     q_depth;
+       int                     coalescing_timeo;
        /*
         * Small/Large (or Header/Data) buffer size to be configured
         * for SLR and HDS queue type. Large buffer size comes from
-        * port->mtu.
+        * enet->mtu.
         */
        int                     small_buff_size;
 
        enum bna_status rss_status;
        struct bna_rss_config rss_config;
 
-       enum bna_status hds_status;
        struct bna_hds_config hds_config;
 
        enum bna_status vlan_strip_status;
@@ -851,51 +736,35 @@ struct bna_rxp {
 
        /* MSI-x vector number for configuring RSS */
        int                     vector;
-
-       struct bna_mbox_qe mbox_qe;
-};
-
-/* HDS configuration structure */
-struct bna_rxf_hds {
-       enum hds_header_type hdr_type;
-       int                     header_size;
-};
-
-/* RSS configuration structure */
-struct bna_rxf_rss {
-       enum rss_hash_type hash_type;
-       u8                      hash_mask;
-       u32             toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN];
+       int                     hw_id;
 };
 
 /* RxF structure (hardware Rx Function) */
 struct bna_rxf {
        bfa_fsm_t               fsm;
-       int                     rxf_id;
-       enum rxf_flags ctrl_flags;
-       u16             default_vlan_tag;
-       enum bna_rxf_oper_state rxf_oper_state;
-       enum bna_status hds_status;
-       struct bna_rxf_hds hds_cfg;
-       enum bna_status rss_status;
-       struct bna_rxf_rss rss_cfg;
-       struct bna_rit_segment *rit_segment;
-       struct bna_rx *rx;
-       u32             forced_offset;
-       struct bna_mbox_qe mbox_qe;
-       int                     mcast_rxq_id;
+       enum bna_rxf_flags flags;
+
+       struct bfa_msgq_cmd_entry msgq_cmd;
+       union {
+               struct bfi_enet_enable_req req;
+               struct bfi_enet_rss_cfg_req rss_req;
+               struct bfi_enet_rit_req rit_req;
+               struct bfi_enet_rx_vlan_req vlan_req;
+               struct bfi_enet_mcast_add_req mcast_add_req;
+               struct bfi_enet_mcast_del_req mcast_del_req;
+               struct bfi_enet_ucast_req ucast_req;
+       } bfi_enet_cmd;
 
        /* callback for bna_rxf_start() */
-       void (*start_cbfn) (struct bna_rx *rx, enum bna_cb_status status);
+       void (*start_cbfn) (struct bna_rx *rx);
        struct bna_rx *start_cbarg;
 
        /* callback for bna_rxf_stop() */
-       void (*stop_cbfn) (struct bna_rx *rx, enum bna_cb_status status);
+       void (*stop_cbfn) (struct bna_rx *rx);
        struct bna_rx *stop_cbarg;
 
-       /* callback for bna_rxf_receive_enable() / bna_rxf_receive_disable() */
-       void (*oper_state_cbfn) (struct bnad *bnad, struct bna_rx *rx,
-                       enum bna_cb_status status);
+       /* callback for bna_rx_receive_pause() / bna_rx_receive_resume() */
+       void (*oper_state_cbfn) (struct bnad *bnad, struct bna_rx *rx);
        struct bnad *oper_state_cbarg;
 
        /**
@@ -905,25 +774,25 @@ struct bna_rxf {
         *      bna_rxf_{ucast/mcast}_del(),
         *      bna_rxf_mode_set()
         */
-       void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx,
-                               enum bna_cb_status status);
+       void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx);
        struct bnad *cam_fltr_cbarg;
 
-       enum bna_rxf_flags rxf_flags;
-
        /* List of unicast addresses yet to be applied to h/w */
        struct list_head                        ucast_pending_add_q;
        struct list_head                        ucast_pending_del_q;
+       struct bna_mac *ucast_pending_mac;
        int                     ucast_pending_set;
        /* ucast addresses applied to the h/w */
        struct list_head                        ucast_active_q;
-       struct bna_mac *ucast_active_mac;
+       struct bna_mac ucast_active_mac;
+       int                     ucast_active_set;
 
        /* List of multicast addresses yet to be applied to h/w */
        struct list_head                        mcast_pending_add_q;
        struct list_head                        mcast_pending_del_q;
        /* multicast addresses applied to the h/w */
        struct list_head                        mcast_active_q;
+       struct list_head                        mcast_handle_q;
 
        /* Rx modes yet to be applied to h/w */
        enum bna_rxmode rxmode_pending;
@@ -931,41 +800,58 @@ struct bna_rxf {
        /* Rx modes applied to h/w */
        enum bna_rxmode rxmode_active;
 
+       u8                      vlan_pending_bitmask;
        enum bna_status vlan_filter_status;
-       u32             vlan_filter_table[(BFI_MAX_VLAN + 1) / 32];
+       u32     vlan_filter_table[(BFI_ENET_VLAN_ID_MAX) / 32];
+       bool                    vlan_strip_pending;
+       enum bna_status         vlan_strip_status;
+
+       enum bna_rss_flags      rss_pending;
+       enum bna_status         rss_status;
+       struct bna_rss_config   rss_cfg;
+       u8                      *rit;
+       int                     rit_size;
+
+       struct bna_rx           *rx;
 };
 
 /* Rx object */
 struct bna_rx {
        /* This should be the first one */
        struct list_head                        qe;
+       int                     rid;
+       int                     hw_id;
 
        bfa_fsm_t               fsm;
 
        enum bna_rx_type type;
 
-       /* list-head for RX path objects */
+       int                     num_paths;
        struct list_head                        rxp_q;
 
+       struct bna_hds_config   hds_cfg;
+
        struct bna_rxf rxf;
 
        enum bna_rx_flags rx_flags;
 
-       struct bna_mbox_qe mbox_qe;
-
-       struct bfa_wc           rxq_stop_wc;
+       struct bfa_msgq_cmd_entry msgq_cmd;
+       union {
+               struct bfi_enet_rx_cfg_req      cfg_req;
+               struct bfi_enet_req             req;
+               struct bfi_enet_rx_cfg_rsp      cfg_rsp;
+       } bfi_enet_cmd;
 
        /* Rx event handlers */
        void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *);
        void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
        void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
        void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
-       void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *);
-       void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *);
+       void (*rx_cleanup_cbfn)(struct bnad *, struct bna_rx *);
+       void (*rx_post_cbfn)(struct bnad *, struct bna_rx *);
 
        /* callback for bna_rx_disable(), bna_rx_stop() */
-       void (*stop_cbfn)(void *arg, struct bna_rx *rx,
-                               enum bna_cb_status status);
+       void (*stop_cbfn)(void *arg, struct bna_rx *rx);
        void                    *stop_cbarg;
 
        struct bna *bna;
@@ -979,8 +865,8 @@ struct bna_rx_event_cbfn {
        void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
        void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
        /* Mandatory */
-       void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *);
-       void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *);
+       void (*rx_cleanup_cbfn)(struct bnad *, struct bna_rx *);
+       void (*rx_post_cbfn)(struct bnad *, struct bna_rx *);
 };
 
 /* Rx module - keeps track of free, active rx objects */
@@ -1003,12 +889,11 @@ struct bna_rx_mod {
        enum bna_rx_mod_flags flags;
 
        /* callback for bna_rx_mod_stop() */
-       void (*stop_cbfn)(struct bna_port *port,
-                               enum bna_cb_status status);
+       void (*stop_cbfn)(struct bna_enet *enet);
 
        struct bfa_wc           rx_stop_wc;
        u32             dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX];
-       u32             rxf_bmap[2];
+       u32             rid_mask;
 };
 
 /**
@@ -1024,9 +909,18 @@ struct bna_ucam_mod {
        struct bna *bna;
 };
 
+struct bna_mcam_handle {
+       /* This should be the first one */
+       struct list_head                        qe;
+       int                     handle;
+       int                     refcnt;
+};
+
 struct bna_mcam_mod {
        struct bna_mac *mcmac;          /* BFI_MAX_MCMAC entries */
+       struct bna_mcam_handle *mchandle;       /* BFI_MAX_MCMAC entries */
        struct list_head                        free_q;
+       struct list_head                        free_handle_q;
 
        struct bna *bna;
 };
@@ -1037,50 +931,20 @@ struct bna_mcam_mod {
  *
  */
 
-struct bna_tx_stats {
-       int                     tx_state;
-       int                     tx_flags;
-       int                     num_txqs;
-       u32             txq_bmap[2];
-       int                     txf_id;
-};
-
-struct bna_rx_stats {
-       int                     rx_state;
-       int                     rx_flags;
-       int                     num_rxps;
-       int                     num_rxqs;
-       u32             rxq_bmap[2];
-       u32             cq_bmap[2];
-       int                     rxf_id;
-       int                     rxf_state;
-       int                     rxf_oper_state;
-       int                     num_active_ucast;
-       int                     num_active_mcast;
-       int                     rxmode_active;
-       int                     vlan_filter_status;
-       u32             vlan_filter_table[(BFI_MAX_VLAN + 1) / 32];
-       int                     rss_status;
-       int                     hds_status;
-};
-
-struct bna_sw_stats {
-       int                     device_state;
-       int                     port_state;
-       int                     port_flags;
-       int                     llport_state;
-       int                     priority;
-       int                     num_active_tx;
-       int                     num_active_rx;
-       struct bna_tx_stats tx_stats[BFI_MAX_TXQ];
-       struct bna_rx_stats rx_stats[BFI_MAX_RXQ];
+struct bna_stats {
+       struct bna_dma_addr     hw_stats_dma;
+       struct bfi_enet_stats   *hw_stats_kva;
+       struct bfi_enet_stats   hw_stats;
 };
 
-struct bna_stats {
-       u32             txf_bmap[2];
-       u32             rxf_bmap[2];
-       struct bfi_ll_stats     *hw_stats;
-       struct bna_sw_stats *sw_stats;
+struct bna_stats_mod {
+       bool            ioc_ready;
+       bool            stats_get_busy;
+       bool            stats_clr_busy;
+       struct bfa_msgq_cmd_entry stats_get_cmd;
+       struct bfa_msgq_cmd_entry stats_clr_cmd;
+       struct bfi_enet_stats_req stats_get;
+       struct bfi_enet_stats_req stats_clr;
 };
 
 /**
@@ -1090,38 +954,32 @@ struct bna_stats {
  */
 
 struct bna {
+       struct bna_ident ident;
        struct bfa_pcidev pcidev;
 
-       int                     port_num;
-
-       struct bna_chip_regs regs;
+       struct bna_reg regs;
+       struct bna_bit_defn bits;
 
-       struct bna_dma_addr hw_stats_dma;
        struct bna_stats stats;
 
-       struct bna_device device;
+       struct bna_ioceth ioceth;
        struct bfa_cee cee;
+       struct bfa_msgq msgq;
 
-       struct bna_mbox_mod mbox_mod;
-
-       struct bna_port port;
+       struct bna_ethport ethport;
+       struct bna_enet enet;
+       struct bna_stats_mod stats_mod;
 
        struct bna_tx_mod tx_mod;
-
        struct bna_rx_mod rx_mod;
-
-       struct bna_ib_mod ib_mod;
-
        struct bna_ucam_mod ucam_mod;
        struct bna_mcam_mod mcam_mod;
 
-       struct bna_rit_mod rit_mod;
+       enum bna_mod_flags mod_flags;
 
-       int                     rxf_promisc_id;
-
-       struct bna_mbox_qe mbox_qe;
+       int                     default_mode_rid;
+       int                     promisc_rid;
 
        struct bnad *bnad;
 };
-
 #endif /* __BNA_TYPES_H__ */
similarity index 85%
rename from drivers/net/bna/bnad.c
rename to drivers/net/ethernet/brocade/bna/bnad.c
index 8e35b2596f93a9b0953ab52fac65827cae3a0322..bdfda0779a8489c8bcc2489cd9892e16e87b0422 100644 (file)
@@ -441,11 +441,15 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
        struct bnad_skb_unmap *unmap_array;
        struct sk_buff *skb;
        u32 flags, unmap_cons;
-       u32 qid0 = ccb->rcb[0]->rxq->rxq_id;
        struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
+       struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
+
+       set_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
 
-       if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))
+       if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)) {
+               clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
                return 0;
+       }
 
        prefetch(bnad->netdev);
        BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
@@ -455,10 +459,10 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
                packets++;
                BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length));
 
-               if (qid0 == cmpl->rxq_id)
-                       rcb = ccb->rcb[0];
-               else
+               if (bna_is_small_rxq(cmpl->rxq_id))
                        rcb = ccb->rcb[1];
+               else
+                       rcb = ccb->rcb[0];
 
                unmap_q = rcb->unmap_q;
                unmap_array = unmap_q->unmap_array;
@@ -518,12 +522,9 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
                if (flags & BNA_CQ_EF_VLAN)
                        __vlan_hwaccel_put_tag(skb, ntohs(cmpl->vlan_tag));
 
-               if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
-                       struct bnad_rx_ctrl *rx_ctrl;
-
-                       rx_ctrl = (struct bnad_rx_ctrl *) ccb->ctrl;
+               if (skb->ip_summed == CHECKSUM_UNNECESSARY)
                        napi_gro_receive(&rx_ctrl->napi, skb);
-               else {
+               else {
                        netif_receive_skb(skb);
                }
 
@@ -545,6 +546,8 @@ next:
                        bna_ib_ack(ccb->i_dbell, 0);
        }
 
+       clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
+
        return packets;
 }
 
@@ -611,7 +614,7 @@ bnad_msix_mbox_handler(int irq, void *data)
 
        bna_intr_status_get(&bnad->bna, intr_status);
 
-       if (BNA_IS_MBOX_ERR_INTR(intr_status))
+       if (BNA_IS_MBOX_ERR_INTR(&bnad->bna, intr_status))
                bna_mbox_handler(&bnad->bna, intr_status);
 
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -628,6 +631,7 @@ bnad_isr(int irq, void *data)
        struct bnad *bnad = (struct bnad *)data;
        struct bnad_rx_info *rx_info;
        struct bnad_rx_ctrl *rx_ctrl;
+       struct bna_tcb *tcb = NULL;
 
        if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)))
                return IRQ_NONE;
@@ -639,7 +643,7 @@ bnad_isr(int irq, void *data)
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
 
-       if (BNA_IS_MBOX_ERR_INTR(intr_status))
+       if (BNA_IS_MBOX_ERR_INTR(&bnad->bna, intr_status))
                bna_mbox_handler(&bnad->bna, intr_status);
 
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -650,8 +654,11 @@ bnad_isr(int irq, void *data)
        /* Process data interrupts */
        /* Tx processing */
        for (i = 0; i < bnad->num_tx; i++) {
-               for (j = 0; j < bnad->num_txq_per_tx; j++)
-                       bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+               for (j = 0; j < bnad->num_txq_per_tx; j++) {
+                       tcb = bnad->tx_info[i].tcb[j];
+                       if (tcb && test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
+                               bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+               }
        }
        /* Rx processing */
        for (i = 0; i < bnad->num_rx; i++) {
@@ -706,43 +713,49 @@ bnad_set_netdev_perm_addr(struct bnad *bnad)
 
 /* Callbacks */
 void
-bnad_cb_device_enable_mbox_intr(struct bnad *bnad)
+bnad_cb_mbox_intr_enable(struct bnad *bnad)
 {
        bnad_enable_mbox_irq(bnad);
 }
 
 void
-bnad_cb_device_disable_mbox_intr(struct bnad *bnad)
+bnad_cb_mbox_intr_disable(struct bnad *bnad)
 {
        bnad_disable_mbox_irq(bnad);
 }
 
 void
-bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status)
+bnad_cb_ioceth_ready(struct bnad *bnad)
+{
+       bnad->bnad_completions.ioc_comp_status = BNA_CB_SUCCESS;
+       complete(&bnad->bnad_completions.ioc_comp);
+}
+
+void
+bnad_cb_ioceth_failed(struct bnad *bnad)
 {
+       bnad->bnad_completions.ioc_comp_status = BNA_CB_FAIL;
        complete(&bnad->bnad_completions.ioc_comp);
-       bnad->bnad_completions.ioc_comp_status = status;
 }
 
 void
-bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status)
+bnad_cb_ioceth_disabled(struct bnad *bnad)
 {
+       bnad->bnad_completions.ioc_comp_status = BNA_CB_SUCCESS;
        complete(&bnad->bnad_completions.ioc_comp);
-       bnad->bnad_completions.ioc_comp_status = status;
 }
 
 static void
-bnad_cb_port_disabled(void *arg, enum bna_cb_status status)
+bnad_cb_enet_disabled(void *arg)
 {
        struct bnad *bnad = (struct bnad *)arg;
 
-       complete(&bnad->bnad_completions.port_comp);
-
        netif_carrier_off(bnad->netdev);
+       complete(&bnad->bnad_completions.enet_comp);
 }
 
 void
-bnad_cb_port_link_status(struct bnad *bnad,
+bnad_cb_ethport_link_status(struct bnad *bnad,
                        enum bna_link_status link_status)
 {
        bool link_up = 0;
@@ -750,34 +763,60 @@ bnad_cb_port_link_status(struct bnad *bnad,
        link_up = (link_status == BNA_LINK_UP) || (link_status == BNA_CEE_UP);
 
        if (link_status == BNA_CEE_UP) {
+               if (!test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags))
+                       BNAD_UPDATE_CTR(bnad, cee_toggle);
                set_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags);
-               BNAD_UPDATE_CTR(bnad, cee_up);
-       } else
+       } else {
+               if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags))
+                       BNAD_UPDATE_CTR(bnad, cee_toggle);
                clear_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags);
+       }
 
        if (link_up) {
                if (!netif_carrier_ok(bnad->netdev)) {
-                       struct bna_tcb *tcb = bnad->tx_info[0].tcb[0];
-                       if (!tcb)
-                               return;
-                       pr_warn("bna: %s link up\n",
+                       uint tx_id, tcb_id;
+                       printk(KERN_WARNING "bna: %s link up\n",
                                bnad->netdev->name);
                        netif_carrier_on(bnad->netdev);
                        BNAD_UPDATE_CTR(bnad, link_toggle);
-                       if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) {
-                               /* Force an immediate Transmit Schedule */
-                               pr_info("bna: %s TX_STARTED\n",
-                                       bnad->netdev->name);
-                               netif_wake_queue(bnad->netdev);
-                               BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
-                       } else {
-                               netif_stop_queue(bnad->netdev);
-                               BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+                       for (tx_id = 0; tx_id < bnad->num_tx; tx_id++) {
+                               for (tcb_id = 0; tcb_id < bnad->num_txq_per_tx;
+                                     tcb_id++) {
+                                       struct bna_tcb *tcb =
+                                       bnad->tx_info[tx_id].tcb[tcb_id];
+                                       u32 txq_id;
+                                       if (!tcb)
+                                               continue;
+
+                                       txq_id = tcb->id;
+
+                                       if (test_bit(BNAD_TXQ_TX_STARTED,
+                                                    &tcb->flags)) {
+                                               /*
+                                                * Force an immediate
+                                                * Transmit Schedule */
+                                               printk(KERN_INFO "bna: %s %d "
+                                                     "TXQ_STARTED\n",
+                                                      bnad->netdev->name,
+                                                      txq_id);
+                                               netif_wake_subqueue(
+                                                               bnad->netdev,
+                                                               txq_id);
+                                               BNAD_UPDATE_CTR(bnad,
+                                                       netif_queue_wakeup);
+                                       } else {
+                                               netif_stop_subqueue(
+                                                               bnad->netdev,
+                                                               txq_id);
+                                               BNAD_UPDATE_CTR(bnad,
+                                                       netif_queue_stop);
+                                       }
+                               }
                        }
                }
        } else {
                if (netif_carrier_ok(bnad->netdev)) {
-                       pr_warn("bna: %s link down\n",
+                       printk(KERN_WARNING "bna: %s link down\n",
                                bnad->netdev->name);
                        netif_carrier_off(bnad->netdev);
                        BNAD_UPDATE_CTR(bnad, link_toggle);
@@ -786,8 +825,7 @@ bnad_cb_port_link_status(struct bnad *bnad,
 }
 
 static void
-bnad_cb_tx_disabled(void *arg, struct bna_tx *tx,
-                       enum bna_cb_status status)
+bnad_cb_tx_disabled(void *arg, struct bna_tx *tx)
 {
        struct bnad *bnad = (struct bnad *)arg;
 
@@ -864,108 +902,166 @@ bnad_cb_ccb_destroy(struct bnad *bnad, struct bna_ccb *ccb)
 }
 
 static void
-bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb)
+bnad_cb_tx_stall(struct bnad *bnad, struct bna_tx *tx)
 {
        struct bnad_tx_info *tx_info =
-                       (struct bnad_tx_info *)tcb->txq->tx->priv;
-
-       if (tx_info != &bnad->tx_info[0])
-               return;
+                       (struct bnad_tx_info *)tx->priv;
+       struct bna_tcb *tcb;
+       u32 txq_id;
+       int i;
 
-       clear_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
-       netif_stop_queue(bnad->netdev);
-       pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name);
+       for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) {
+               tcb = tx_info->tcb[i];
+               if (!tcb)
+                       continue;
+               txq_id = tcb->id;
+               clear_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
+               netif_stop_subqueue(bnad->netdev, txq_id);
+               printk(KERN_INFO "bna: %s %d TXQ_STOPPED\n",
+                       bnad->netdev->name, txq_id);
+       }
 }
 
 static void
-bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb)
+bnad_cb_tx_resume(struct bnad *bnad, struct bna_tx *tx)
 {
-       struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+       struct bnad_tx_info *tx_info = (struct bnad_tx_info *)tx->priv;
+       struct bna_tcb *tcb;
+       struct bnad_unmap_q *unmap_q;
+       u32 txq_id;
+       int i;
 
-       if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
-               return;
+       for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) {
+               tcb = tx_info->tcb[i];
+               if (!tcb)
+                       continue;
+               txq_id = tcb->id;
 
-       clear_bit(BNAD_RF_TX_SHUTDOWN_DELAYED, &bnad->run_flags);
+               unmap_q = tcb->unmap_q;
 
-       while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
-               cpu_relax();
+               if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
+                       continue;
 
-       bnad_free_all_txbufs(bnad, tcb);
+               while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+                       cpu_relax();
 
-       unmap_q->producer_index = 0;
-       unmap_q->consumer_index = 0;
+               bnad_free_all_txbufs(bnad, tcb);
 
-       smp_mb__before_clear_bit();
-       clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+               unmap_q->producer_index = 0;
+               unmap_q->consumer_index = 0;
+
+               smp_mb__before_clear_bit();
+               clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+
+               set_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
+
+               if (netif_carrier_ok(bnad->netdev)) {
+                       printk(KERN_INFO "bna: %s %d TXQ_STARTED\n",
+                               bnad->netdev->name, txq_id);
+                       netif_wake_subqueue(bnad->netdev, txq_id);
+                       BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+               }
+       }
 
        /*
-        * Workaround for first device enable failure & we
+        * Workaround for first ioceth enable failure & we
         * get a 0 MAC address. We try to get the MAC address
         * again here.
         */
        if (is_zero_ether_addr(&bnad->perm_addr.mac[0])) {
-               bna_port_mac_get(&bnad->bna.port, &bnad->perm_addr);
+               bna_enet_perm_mac_get(&bnad->bna.enet, &bnad->perm_addr);
                bnad_set_netdev_perm_addr(bnad);
        }
-
-       set_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
-
-       if (netif_carrier_ok(bnad->netdev)) {
-               pr_info("bna: %s TX_STARTED\n", bnad->netdev->name);
-               netif_wake_queue(bnad->netdev);
-               BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
-       }
 }
 
 static void
-bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
+bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
 {
-       /* Delay only once for the whole Tx Path Shutdown */
-       if (!test_and_set_bit(BNAD_RF_TX_SHUTDOWN_DELAYED, &bnad->run_flags))
-               mdelay(BNAD_TXRX_SYNC_MDELAY);
+       struct bnad_tx_info *tx_info = (struct bnad_tx_info *)tx->priv;
+       struct bna_tcb *tcb;
+       int i;
+
+       for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) {
+               tcb = tx_info->tcb[i];
+               if (!tcb)
+                       continue;
+       }
+
+       mdelay(BNAD_TXRX_SYNC_MDELAY);
+       bna_tx_cleanup_complete(tx);
 }
 
 static void
-bnad_cb_rx_cleanup(struct bnad *bnad,
-                       struct bna_ccb *ccb)
+bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
 {
-       clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags);
+       struct bnad_rx_info *rx_info = (struct bnad_rx_info *)rx->priv;
+       struct bna_ccb *ccb;
+       struct bnad_rx_ctrl *rx_ctrl;
+       int i;
+
+       mdelay(BNAD_TXRX_SYNC_MDELAY);
+
+       for (i = 0; i < BNAD_MAX_RXPS_PER_RX; i++) {
+               rx_ctrl = &rx_info->rx_ctrl[i];
+               ccb = rx_ctrl->ccb;
+               if (!ccb)
+                       continue;
+
+               clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags);
+
+               if (ccb->rcb[1])
+                       clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
 
-       if (ccb->rcb[1])
-               clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
+               while (test_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags))
+                       cpu_relax();
+       }
 
-       if (!test_and_set_bit(BNAD_RF_RX_SHUTDOWN_DELAYED, &bnad->run_flags))
-               mdelay(BNAD_TXRX_SYNC_MDELAY);
+       bna_rx_cleanup_complete(rx);
 }
 
 static void
-bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
 {
-       struct bnad_unmap_q *unmap_q = rcb->unmap_q;
-
-       clear_bit(BNAD_RF_RX_SHUTDOWN_DELAYED, &bnad->run_flags);
-
-       if (rcb == rcb->cq->ccb->rcb[0])
-               bnad_cq_cmpl_init(bnad, rcb->cq->ccb);
+       struct bnad_rx_info *rx_info = (struct bnad_rx_info *)rx->priv;
+       struct bna_ccb *ccb;
+       struct bna_rcb *rcb;
+       struct bnad_rx_ctrl *rx_ctrl;
+       struct bnad_unmap_q *unmap_q;
+       int i;
+       int j;
 
-       bnad_free_all_rxbufs(bnad, rcb);
+       for (i = 0; i < BNAD_MAX_RXPS_PER_RX; i++) {
+               rx_ctrl = &rx_info->rx_ctrl[i];
+               ccb = rx_ctrl->ccb;
+               if (!ccb)
+                       continue;
 
-       set_bit(BNAD_RXQ_STARTED, &rcb->flags);
+               bnad_cq_cmpl_init(bnad, ccb);
 
-       /* Now allocate & post buffers for this RCB */
-       /* !!Allocation in callback context */
-       if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
-               if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
-                        >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
-                       bnad_alloc_n_post_rxbufs(bnad, rcb);
-               smp_mb__before_clear_bit();
-               clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
+               for (j = 0; j < BNAD_MAX_RXQ_PER_RXP; j++) {
+                       rcb = ccb->rcb[j];
+                       if (!rcb)
+                               continue;
+                       bnad_free_all_rxbufs(bnad, rcb);
+
+                       set_bit(BNAD_RXQ_STARTED, &rcb->flags);
+                       unmap_q = rcb->unmap_q;
+
+                       /* Now allocate & post buffers for this RCB */
+                       /* !!Allocation in callback context */
+                       if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
+                               if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
+                                       >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
+                                       bnad_alloc_n_post_rxbufs(bnad, rcb);
+                                       smp_mb__before_clear_bit();
+                               clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
+                       }
+               }
        }
 }
 
 static void
-bnad_cb_rx_disabled(void *arg, struct bna_rx *rx,
-                       enum bna_cb_status status)
+bnad_cb_rx_disabled(void *arg, struct bna_rx *rx)
 {
        struct bnad *bnad = (struct bnad *)arg;
 
@@ -973,10 +1069,9 @@ bnad_cb_rx_disabled(void *arg, struct bna_rx *rx,
 }
 
 static void
-bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx,
-                               enum bna_cb_status status)
+bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx)
 {
-       bnad->bnad_completions.mcast_comp_status = status;
+       bnad->bnad_completions.mcast_comp_status = BNA_CB_SUCCESS;
        complete(&bnad->bnad_completions.mcast_comp);
 }
 
@@ -995,6 +1090,13 @@ bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
                  jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ));
 }
 
+static void
+bnad_cb_enet_mtu_set(struct bnad *bnad)
+{
+       bnad->bnad_completions.mtu_comp_status = BNA_CB_SUCCESS;
+       complete(&bnad->bnad_completions.mtu_comp);
+}
+
 /* Resource allocation, free functions */
 
 static void
@@ -1073,23 +1175,17 @@ err_return:
 
 /* Free IRQ for Mailbox */
 static void
-bnad_mbox_irq_free(struct bnad *bnad,
-                  struct bna_intr_info *intr_info)
+bnad_mbox_irq_free(struct bnad *bnad)
 {
        int irq;
        unsigned long flags;
 
-       if (intr_info->idl == NULL)
-               return;
-
        spin_lock_irqsave(&bnad->bna_lock, flags);
        bnad_disable_mbox_irq(bnad);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
        irq = BNAD_GET_MBOX_IRQ(bnad);
        free_irq(irq, bnad);
-
-       kfree(intr_info->idl);
 }
 
 /*
@@ -1098,32 +1194,22 @@ bnad_mbox_irq_free(struct bnad *bnad,
  * from bna
  */
 static int
-bnad_mbox_irq_alloc(struct bnad *bnad,
-                   struct bna_intr_info *intr_info)
+bnad_mbox_irq_alloc(struct bnad *bnad)
 {
        int             err = 0;
        unsigned long   irq_flags, flags;
        u32     irq;
        irq_handler_t   irq_handler;
 
-       /* Mbox should use only 1 vector */
-
-       intr_info->idl = kzalloc(sizeof(*(intr_info->idl)), GFP_KERNEL);
-       if (!intr_info->idl)
-               return -ENOMEM;
-
        spin_lock_irqsave(&bnad->bna_lock, flags);
        if (bnad->cfg_flags & BNAD_CF_MSIX) {
                irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
                irq = bnad->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector;
                irq_flags = 0;
-               intr_info->intr_type = BNA_INTR_T_MSIX;
-               intr_info->idl[0].vector = BNAD_MAILBOX_MSIX_INDEX;
        } else {
                irq_handler = (irq_handler_t)bnad_isr;
                irq = bnad->pcidev->irq;
                irq_flags = IRQF_SHARED;
-               intr_info->intr_type = BNA_INTR_T_INTX;
        }
 
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -1140,11 +1226,6 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
        err = request_irq(irq, irq_handler, irq_flags,
                          bnad->mbox_irq_name, bnad);
 
-       if (err) {
-               kfree(intr_info->idl);
-               intr_info->idl = NULL;
-       }
-
        return err;
 }
 
@@ -1158,7 +1239,7 @@ bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info)
 /* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */
 static int
 bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
-                   uint txrx_id, struct bna_intr_info *intr_info)
+                   u32 txrx_id, struct bna_intr_info *intr_info)
 {
        int i, vector_start = 0;
        u32 cfg_flags;
@@ -1241,7 +1322,7 @@ bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info,
  */
 static int
 bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info,
-                       uint tx_id, int num_txqs)
+                       u32 tx_id, int num_txqs)
 {
        int i;
        int err;
@@ -1294,7 +1375,7 @@ bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info,
  */
 static int
 bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info,
-                       uint rx_id, int num_rxps)
+                       u32 rx_id, int num_rxps)
 {
        int i;
        int err;
@@ -1338,7 +1419,7 @@ bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
 /* Allocates memory and interrupt resources for Tx object */
 static int
 bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
-                 uint tx_id)
+                 u32 tx_id)
 {
        int i, err = 0;
 
@@ -1407,7 +1488,7 @@ bnad_ioc_timeout(unsigned long data)
        unsigned long flags;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bfa_nw_ioc_timeout((void *) &bnad->bna.device.ioc);
+       bfa_nw_ioc_timeout((void *) &bnad->bna.ioceth.ioc);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 }
 
@@ -1418,7 +1499,7 @@ bnad_ioc_hb_check(unsigned long data)
        unsigned long flags;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bfa_nw_ioc_hb_check((void *) &bnad->bna.device.ioc);
+       bfa_nw_ioc_hb_check((void *) &bnad->bna.ioceth.ioc);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 }
 
@@ -1429,7 +1510,7 @@ bnad_iocpf_timeout(unsigned long data)
        unsigned long flags;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bfa_nw_iocpf_timeout((void *) &bnad->bna.device.ioc);
+       bfa_nw_iocpf_timeout((void *) &bnad->bna.ioceth.ioc);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 }
 
@@ -1440,7 +1521,7 @@ bnad_iocpf_sem_timeout(unsigned long data)
        unsigned long flags;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bfa_nw_iocpf_sem_timeout((void *) &bnad->bna.device.ioc);
+       bfa_nw_iocpf_sem_timeout((void *) &bnad->bna.ioceth.ioc);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 }
 
@@ -1499,7 +1580,7 @@ bnad_stats_timeout(unsigned long data)
                return;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_stats_get(&bnad->bna);
+       bna_hw_stats_get(&bnad->bna);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 }
 
@@ -1632,7 +1713,7 @@ bnad_napi_disable(struct bnad *bnad, u32 rx_id)
 
 /* Should be held with conf_lock held */
 void
-bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
+bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
 {
        struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
        struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
@@ -1656,6 +1737,7 @@ bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
        tx_info->tx = NULL;
+       tx_info->tx_id = 0;
 
        if (0 == tx_id)
                tasklet_kill(&bnad->tx_free_tasklet);
@@ -1665,7 +1747,7 @@ bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
 
 /* Should be held with conf_lock held */
 int
-bnad_setup_tx(struct bnad *bnad, uint tx_id)
+bnad_setup_tx(struct bnad *bnad, u32 tx_id)
 {
        int err;
        struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
@@ -1677,10 +1759,13 @@ bnad_setup_tx(struct bnad *bnad, uint tx_id)
        struct bna_tx *tx;
        unsigned long flags;
 
+       tx_info->tx_id = tx_id;
+
        /* Initialize the Tx object configuration */
        tx_config->num_txq = bnad->num_txq_per_tx;
        tx_config->txq_depth = bnad->txq_depth;
        tx_config->tx_type = BNA_TX_T_REGULAR;
+       tx_config->coalescing_timeo = bnad->tx_coalescing_timeo;
 
        /* Initialize the tx event handlers */
        tx_cbfn.tcb_setup_cbfn = bnad_cb_tcb_setup;
@@ -1741,14 +1826,15 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
 {
        rx_config->rx_type = BNA_RX_T_REGULAR;
        rx_config->num_paths = bnad->num_rxp_per_rx;
+       rx_config->coalescing_timeo = bnad->rx_coalescing_timeo;
 
        if (bnad->num_rxp_per_rx > 1) {
                rx_config->rss_status = BNA_STATUS_T_ENABLED;
                rx_config->rss_config.hash_type =
-                               (BFI_RSS_T_V4_TCP |
-                                BFI_RSS_T_V6_TCP |
-                                BFI_RSS_T_V4_IP  |
-                                BFI_RSS_T_V6_IP);
+                               (BFI_ENET_RSS_IPV6 |
+                                BFI_ENET_RSS_IPV6_TCP |
+                                BFI_ENET_RSS_IPV4 |
+                                BFI_ENET_RSS_IPV4_TCP);
                rx_config->rss_config.hash_mask =
                                bnad->num_rxp_per_rx - 1;
                get_random_bytes(rx_config->rss_config.toeplitz_hash_key,
@@ -1768,7 +1854,7 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
 
 /* Called with mutex_lock(&bnad->conf_mutex) held */
 void
-bnad_cleanup_rx(struct bnad *bnad, uint rx_id)
+bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
 {
        struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
        struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
@@ -1811,7 +1897,7 @@ bnad_cleanup_rx(struct bnad *bnad, uint rx_id)
 
 /* Called with mutex_lock(&bnad->conf_mutex) held */
 int
-bnad_setup_rx(struct bnad *bnad, uint rx_id)
+bnad_setup_rx(struct bnad *bnad, u32 rx_id)
 {
        int err;
        struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
@@ -1823,6 +1909,8 @@ bnad_setup_rx(struct bnad *bnad, uint rx_id)
        struct bna_rx *rx;
        unsigned long flags;
 
+       rx_info->rx_id = rx_id;
+
        /* Initialize the Rx object configuration */
        bnad_init_rx_config(bnad, rx_config);
 
@@ -1978,7 +2066,7 @@ bnad_restore_vlans(struct bnad *bnad, u32 rx_id)
        u16 vid;
        unsigned long flags;
 
-       BUG_ON(!(VLAN_N_VID == (BFI_MAX_VLAN + 1)));
+       BUG_ON(!(VLAN_N_VID == BFI_ENET_VLAN_ID_MAX));
 
        for_each_set_bit(vid, bnad->active_vlans, VLAN_N_VID) {
                spin_lock_irqsave(&bnad->bna_lock, flags);
@@ -2031,11 +2119,11 @@ bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
 void
 bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
 {
-       struct bfi_ll_stats_mac *mac_stats;
-       u64 bmap;
+       struct bfi_enet_stats_mac *mac_stats;
+       u32 bmap;
        int i;
 
-       mac_stats = &bnad->stats.bna_stats->hw_stats->mac_stats;
+       mac_stats = &bnad->stats.bna_stats->hw_stats.mac_stats;
        stats->rx_errors =
                mac_stats->rx_fcs_error + mac_stats->rx_alignment_error +
                mac_stats->rx_frame_length_error + mac_stats->rx_code_error +
@@ -2054,13 +2142,12 @@ bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
        stats->rx_crc_errors = mac_stats->rx_fcs_error;
        stats->rx_frame_errors = mac_stats->rx_alignment_error;
        /* recv'r fifo overrun */
-       bmap = (u64)bnad->stats.bna_stats->rxf_bmap[0] |
-               ((u64)bnad->stats.bna_stats->rxf_bmap[1] << 32);
-       for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+       bmap = bna_rx_rid_mask(&bnad->bna);
+       for (i = 0; bmap; i++) {
                if (bmap & 1) {
                        stats->rx_fifo_errors +=
                                bnad->stats.bna_stats->
-                                       hw_stats->rxf_stats[i].frame_drops;
+                                       hw_stats.rxf_stats[i].frame_drops;
                        break;
                }
                bmap >>= 1;
@@ -2158,7 +2245,7 @@ bnad_q_num_init(struct bnad *bnad)
  * Called with bnad->bna_lock held b'cos of cfg_flags access
  */
 static void
-bnad_q_num_adjust(struct bnad *bnad, int msix_vectors)
+bnad_q_num_adjust(struct bnad *bnad, int msix_vectors, int temp)
 {
        bnad->num_txq_per_tx = 1;
        if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx)  +
@@ -2171,76 +2258,72 @@ bnad_q_num_adjust(struct bnad *bnad, int msix_vectors)
                bnad->num_rxp_per_rx = 1;
 }
 
-/* Enable / disable device */
-static void
-bnad_device_disable(struct bnad *bnad)
+/* Enable / disable ioceth */
+static int
+bnad_ioceth_disable(struct bnad *bnad)
 {
        unsigned long flags;
-
-       init_completion(&bnad->bnad_completions.ioc_comp);
+       int err = 0;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_device_disable(&bnad->bna.device, BNA_HARD_CLEANUP);
+       init_completion(&bnad->bnad_completions.ioc_comp);
+       bna_ioceth_disable(&bnad->bna.ioceth, BNA_HARD_CLEANUP);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
-       wait_for_completion(&bnad->bnad_completions.ioc_comp);
+       wait_for_completion_timeout(&bnad->bnad_completions.ioc_comp,
+               msecs_to_jiffies(BNAD_IOCETH_TIMEOUT));
+
+       err = bnad->bnad_completions.ioc_comp_status;
+       return err;
 }
 
 static int
-bnad_device_enable(struct bnad *bnad)
+bnad_ioceth_enable(struct bnad *bnad)
 {
        int err = 0;
        unsigned long flags;
 
-       init_completion(&bnad->bnad_completions.ioc_comp);
-
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_device_enable(&bnad->bna.device);
+       init_completion(&bnad->bnad_completions.ioc_comp);
+       bnad->bnad_completions.ioc_comp_status = BNA_CB_WAITING;
+       bna_ioceth_enable(&bnad->bna.ioceth);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
-       wait_for_completion(&bnad->bnad_completions.ioc_comp);
+       wait_for_completion_timeout(&bnad->bnad_completions.ioc_comp,
+               msecs_to_jiffies(BNAD_IOCETH_TIMEOUT));
 
-       if (bnad->bnad_completions.ioc_comp_status)
-               err = bnad->bnad_completions.ioc_comp_status;
+       err = bnad->bnad_completions.ioc_comp_status;
 
        return err;
 }
 
 /* Free BNA resources */
 static void
-bnad_res_free(struct bnad *bnad)
+bnad_res_free(struct bnad *bnad, struct bna_res_info *res_info,
+               u32 res_val_max)
 {
        int i;
-       struct bna_res_info *res_info = &bnad->res_info[0];
 
-       for (i = 0; i < BNA_RES_T_MAX; i++) {
-               if (res_info[i].res_type == BNA_RES_T_MEM)
-                       bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
-               else
-                       bnad_mbox_irq_free(bnad, &res_info[i].res_u.intr_info);
-       }
+       for (i = 0; i < res_val_max; i++)
+               bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
 }
 
 /* Allocates memory and interrupt resources for BNA */
 static int
-bnad_res_alloc(struct bnad *bnad)
+bnad_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
+               u32 res_val_max)
 {
        int i, err;
-       struct bna_res_info *res_info = &bnad->res_info[0];
 
-       for (i = 0; i < BNA_RES_T_MAX; i++) {
-               if (res_info[i].res_type == BNA_RES_T_MEM)
-                       err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
-               else
-                       err = bnad_mbox_irq_alloc(bnad,
-                                                 &res_info[i].res_u.intr_info);
+       for (i = 0; i < res_val_max; i++) {
+               err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
                if (err)
                        goto err_return;
        }
        return 0;
 
 err_return:
-       bnad_res_free(bnad);
+       bnad_res_free(bnad, res_info, res_val_max);
        return err;
 }
 
@@ -2276,7 +2359,7 @@ bnad_enable_msix(struct bnad *bnad)
 
                spin_lock_irqsave(&bnad->bna_lock, flags);
                /* ret = #of vectors that we got */
-               bnad_q_num_adjust(bnad, ret);
+               bnad_q_num_adjust(bnad, ret, 0);
                spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
                bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx)
@@ -2284,6 +2367,9 @@ bnad_enable_msix(struct bnad *bnad)
                        * bnad->num_rxp_per_rx) +
                         BNAD_MAILBOX_MSIX_VECTORS;
 
+               if (bnad->msix_num > ret)
+                       goto intx_mode;
+
                /* Try once more with adjusted numbers */
                /* If this fails, fall back to INTx */
                ret = pci_enable_msix(bnad->pcidev, bnad->msix_table,
@@ -2293,6 +2379,9 @@ bnad_enable_msix(struct bnad *bnad)
 
        } else if (ret < 0)
                goto intx_mode;
+
+       pci_intx(bnad->pcidev, 0);
+
        return;
 
 intx_mode:
@@ -2351,12 +2440,12 @@ bnad_open(struct net_device *netdev)
        pause_config.tx_pause = 0;
        pause_config.rx_pause = 0;
 
-       mtu = ETH_HLEN + bnad->netdev->mtu + ETH_FCS_LEN;
+       mtu = ETH_HLEN + VLAN_HLEN + bnad->netdev->mtu + ETH_FCS_LEN;
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_port_mtu_set(&bnad->bna.port, mtu, NULL);
-       bna_port_pause_config(&bnad->bna.port, &pause_config, NULL);
-       bna_port_enable(&bnad->bna.port);
+       bna_enet_mtu_set(&bnad->bna.enet, mtu, NULL);
+       bna_enet_pause_config(&bnad->bna.enet, &pause_config, NULL);
+       bna_enet_enable(&bnad->bna.enet);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
        /* Enable broadcast */
@@ -2396,14 +2485,14 @@ bnad_stop(struct net_device *netdev)
        /* Stop the stats timer */
        bnad_stats_timer_stop(bnad);
 
-       init_completion(&bnad->bnad_completions.port_comp);
+       init_completion(&bnad->bnad_completions.enet_comp);
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_port_disable(&bnad->bna.port, BNA_HARD_CLEANUP,
-                       bnad_cb_port_disabled);
+       bna_enet_disable(&bnad->bna.enet, BNA_HARD_CLEANUP,
+                       bnad_cb_enet_disabled);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
-       wait_for_completion(&bnad->bnad_completions.port_comp);
+       wait_for_completion(&bnad->bnad_completions.enet_comp);
 
        bnad_cleanup_tx(bnad, 0);
        bnad_cleanup_rx(bnad, 0);
@@ -2425,19 +2514,18 @@ static netdev_tx_t
 bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
        struct bnad *bnad = netdev_priv(netdev);
+       u32 txq_id = 0;
+       struct bna_tcb *tcb = bnad->tx_info[0].tcb[txq_id];
 
        u16             txq_prod, vlan_tag = 0;
        u32             unmap_prod, wis, wis_used, wi_range;
        u32             vectors, vect_id, i, acked;
-       u32             tx_id;
        int                     err;
 
-       struct bnad_tx_info *tx_info;
-       struct bna_tcb *tcb;
-       struct bnad_unmap_q *unmap_q;
+       struct bnad_unmap_q *unmap_q = tcb->unmap_q;
        dma_addr_t              dma_addr;
        struct bna_txq_entry *txqent;
-       bna_txq_wi_ctrl_flag_t  flags;
+       u16     flags;
 
        if (unlikely
            (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) {
@@ -2445,15 +2533,9 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
                return NETDEV_TX_OK;
        }
 
-       tx_id = 0;
-
-       tx_info = &bnad->tx_info[tx_id];
-       tcb = tx_info->tcb[tx_id];
-       unmap_q = tcb->unmap_q;
-
        /*
         * Takes care of the Tx that is scheduled between clearing the flag
-        * and the netif_stop_queue() call.
+        * and the netif_stop_all_queue() call.
         */
        if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) {
                dev_kfree_skb(skb);
@@ -2467,9 +2549,8 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
        }
        wis = BNA_TXQ_WI_NEEDED(vectors);       /* 4 vectors per work item */
        acked = 0;
-       if (unlikely
-           (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
-            vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
+       if (unlikely(wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
+                       vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
                if ((u16) (*tcb->hw_consumer_index) !=
                    tcb->consumer_index &&
                    !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
@@ -2602,7 +2683,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
-               u32             size = frag->size;
+               u16             size = frag->size;
 
                if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) {
                        vect_id = 0;
@@ -2760,11 +2841,25 @@ bnad_set_mac_address(struct net_device *netdev, void *mac_addr)
 }
 
 static int
-bnad_change_mtu(struct net_device *netdev, int new_mtu)
+bnad_mtu_set(struct bnad *bnad, int mtu)
 {
-       int mtu, err = 0;
        unsigned long flags;
 
+       init_completion(&bnad->bnad_completions.mtu_comp);
+
+       spin_lock_irqsave(&bnad->bna_lock, flags);
+       bna_enet_mtu_set(&bnad->bna.enet, mtu, bnad_cb_enet_mtu_set);
+       spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+       wait_for_completion(&bnad->bnad_completions.mtu_comp);
+
+       return bnad->bnad_completions.mtu_comp_status;
+}
+
+static int
+bnad_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       int err, mtu = netdev->mtu;
        struct bnad *bnad = netdev_priv(netdev);
 
        if (new_mtu + ETH_HLEN < ETH_ZLEN || new_mtu > BNAD_JUMBO_MTU)
@@ -2774,11 +2869,10 @@ bnad_change_mtu(struct net_device *netdev, int new_mtu)
 
        netdev->mtu = new_mtu;
 
-       mtu = ETH_HLEN + new_mtu + ETH_FCS_LEN;
-
-       spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_port_mtu_set(&bnad->bna.port, mtu, NULL);
-       spin_unlock_irqrestore(&bnad->bna_lock, flags);
+       mtu = ETH_HLEN + VLAN_HLEN + new_mtu + ETH_FCS_LEN;
+       err = bnad_mtu_set(bnad, mtu);
+       if (err)
+               err = -EBUSY;
 
        mutex_unlock(&bnad->conf_mutex);
        return err;
@@ -2863,7 +2957,6 @@ static const struct net_device_ops bnad_netdev_ops = {
        .ndo_start_xmit         = bnad_start_xmit,
        .ndo_get_stats64                = bnad_get_stats64,
        .ndo_set_rx_mode        = bnad_set_rx_mode,
-       .ndo_set_multicast_list = bnad_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = bnad_set_mac_address,
        .ndo_change_mtu         = bnad_change_mtu,
@@ -2968,7 +3061,7 @@ bnad_uninit(struct bnad *bnad)
 
 /*
  * Initialize locks
-       a) Per device mutes used for serializing configuration
+       a) Per ioceth mutes used for serializing configuration
           changes from OS interface
        b) spin lock used to protect bna state machine
  */
@@ -3058,12 +3151,15 @@ bnad_pci_probe(struct pci_dev *pdev,
         */
        netdev = alloc_etherdev(sizeof(struct bnad));
        if (!netdev) {
-               dev_err(&pdev->dev, "alloc_etherdev failed\n");
+               dev_err(&pdev->dev, "netdev allocation failed\n");
                err = -ENOMEM;
                return err;
        }
        bnad = netdev_priv(netdev);
 
+       bnad_lock_init(bnad);
+
+       mutex_lock(&bnad->conf_mutex);
        /*
         * PCI initialization
         *      Output : using_dac = 1 for 64 bit DMA
@@ -3073,7 +3169,6 @@ bnad_pci_probe(struct pci_dev *pdev,
        if (err)
                goto free_netdev;
 
-       bnad_lock_init(bnad);
        /*
         * Initialize bnad structure
         * Setup relation between pci_dev & netdev
@@ -3082,21 +3177,22 @@ bnad_pci_probe(struct pci_dev *pdev,
        err = bnad_init(bnad, pdev, netdev);
        if (err)
                goto pci_uninit;
+
        /* Initialize netdev structure, set up ethtool ops */
        bnad_netdev_init(bnad, using_dac);
 
        /* Set link to down state */
        netif_carrier_off(netdev);
 
-       bnad_enable_msix(bnad);
-
        /* Get resource requirement form bna */
+       spin_lock_irqsave(&bnad->bna_lock, flags);
        bna_res_req(&bnad->res_info[0]);
+       spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
        /* Allocate resources from bna */
-       err = bnad_res_alloc(bnad);
+       err = bnad_res_alloc(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
        if (err)
-               goto free_netdev;
+               goto drv_uninit;
 
        bna = &bnad->bna;
 
@@ -3106,69 +3202,102 @@ bnad_pci_probe(struct pci_dev *pdev,
        pcidev_info.device_id = bnad->pcidev->device;
        pcidev_info.pci_bar_kva = bnad->bar0;
 
-       mutex_lock(&bnad->conf_mutex);
-
        spin_lock_irqsave(&bnad->bna_lock, flags);
        bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
        bnad->stats.bna_stats = &bna->stats;
 
+       bnad_enable_msix(bnad);
+       err = bnad_mbox_irq_alloc(bnad);
+       if (err)
+               goto res_free;
+
+
        /* Set up timers */
-       setup_timer(&bnad->bna.device.ioc.ioc_timer, bnad_ioc_timeout,
+       setup_timer(&bnad->bna.ioceth.ioc.ioc_timer, bnad_ioc_timeout,
                                ((unsigned long)bnad));
-       setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check,
+       setup_timer(&bnad->bna.ioceth.ioc.hb_timer, bnad_ioc_hb_check,
                                ((unsigned long)bnad));
-       setup_timer(&bnad->bna.device.ioc.iocpf_timer, bnad_iocpf_timeout,
+       setup_timer(&bnad->bna.ioceth.ioc.iocpf_timer, bnad_iocpf_timeout,
                                ((unsigned long)bnad));
-       setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_iocpf_sem_timeout,
+       setup_timer(&bnad->bna.ioceth.ioc.sem_timer, bnad_iocpf_sem_timeout,
                                ((unsigned long)bnad));
 
        /* Now start the timer before calling IOC */
-       mod_timer(&bnad->bna.device.ioc.iocpf_timer,
+       mod_timer(&bnad->bna.ioceth.ioc.iocpf_timer,
                  jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ));
 
        /*
         * Start the chip
-        * Don't care even if err != 0, bna state machine will
-        * deal with it
+        * If the call back comes with error, we bail out.
+        * This is a catastrophic error.
         */
-       err = bnad_device_enable(bnad);
+       err = bnad_ioceth_enable(bnad);
+       if (err) {
+               pr_err("BNA: Initialization failed err=%d\n",
+                      err);
+               goto probe_success;
+       }
+
+       spin_lock_irqsave(&bnad->bna_lock, flags);
+       if (bna_num_txq_set(bna, BNAD_NUM_TXQ + 1) ||
+               bna_num_rxp_set(bna, BNAD_NUM_RXP + 1)) {
+               bnad_q_num_adjust(bnad, bna_attr(bna)->num_txq - 1,
+                       bna_attr(bna)->num_rxp - 1);
+               if (bna_num_txq_set(bna, BNAD_NUM_TXQ + 1) ||
+                       bna_num_rxp_set(bna, BNAD_NUM_RXP + 1))
+                       err = -EIO;
+       }
+       bna_mod_res_req(&bnad->bna, &bnad->mod_res_info[0]);
+       spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+       err = bnad_res_alloc(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+       if (err)
+               goto disable_ioceth;
+
+       spin_lock_irqsave(&bnad->bna_lock, flags);
+       bna_mod_init(&bnad->bna, &bnad->mod_res_info[0]);
+       spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
        /* Get the burnt-in mac */
        spin_lock_irqsave(&bnad->bna_lock, flags);
-       bna_port_mac_get(&bna->port, &bnad->perm_addr);
+       bna_enet_perm_mac_get(&bna->enet, &bnad->perm_addr);
        bnad_set_netdev_perm_addr(bnad);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
-       mutex_unlock(&bnad->conf_mutex);
-
        /* Finally, reguister with net_device layer */
        err = register_netdev(netdev);
        if (err) {
                pr_err("BNA : Registering with netdev failed\n");
-               goto disable_device;
+               goto probe_uninit;
        }
+       set_bit(BNAD_RF_NETDEV_REGISTERED, &bnad->run_flags);
 
+probe_success:
+       mutex_unlock(&bnad->conf_mutex);
        return 0;
 
-disable_device:
-       mutex_lock(&bnad->conf_mutex);
-       bnad_device_disable(bnad);
-       del_timer_sync(&bnad->bna.device.ioc.ioc_timer);
-       del_timer_sync(&bnad->bna.device.ioc.sem_timer);
-       del_timer_sync(&bnad->bna.device.ioc.hb_timer);
+probe_uninit:
+       bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+disable_ioceth:
+       bnad_ioceth_disable(bnad);
+       del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+       del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
+       del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
        spin_lock_irqsave(&bnad->bna_lock, flags);
        bna_uninit(bna);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
-       mutex_unlock(&bnad->conf_mutex);
-
-       bnad_res_free(bnad);
+       bnad_mbox_irq_free(bnad);
        bnad_disable_msix(bnad);
+res_free:
+       bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
+drv_uninit:
+       bnad_uninit(bnad);
 pci_uninit:
        bnad_pci_uninit(pdev);
+       mutex_unlock(&bnad->conf_mutex);
        bnad_lock_uninit(bnad);
-       bnad_uninit(bnad);
 free_netdev:
        free_netdev(netdev);
        return err;
@@ -3189,21 +3318,24 @@ bnad_pci_remove(struct pci_dev *pdev)
        bnad = netdev_priv(netdev);
        bna = &bnad->bna;
 
-       unregister_netdev(netdev);
+       if (test_and_clear_bit(BNAD_RF_NETDEV_REGISTERED, &bnad->run_flags))
+               unregister_netdev(netdev);
 
        mutex_lock(&bnad->conf_mutex);
-       bnad_device_disable(bnad);
-       del_timer_sync(&bnad->bna.device.ioc.ioc_timer);
-       del_timer_sync(&bnad->bna.device.ioc.sem_timer);
-       del_timer_sync(&bnad->bna.device.ioc.hb_timer);
+       bnad_ioceth_disable(bnad);
+       del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+       del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
+       del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
        spin_lock_irqsave(&bnad->bna_lock, flags);
        bna_uninit(bna);
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
-       mutex_unlock(&bnad->conf_mutex);
 
-       bnad_res_free(bnad);
+       bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
+       bnad_res_free(bnad, &bnad->res_info[0], BNA_RES_T_MAX);
+       bnad_mbox_irq_free(bnad);
        bnad_disable_msix(bnad);
        bnad_pci_uninit(pdev);
+       mutex_unlock(&bnad->conf_mutex);
        bnad_lock_uninit(bnad);
        bnad_uninit(bnad);
        free_netdev(netdev);
similarity index 89%
rename from drivers/net/bna/bnad.h
rename to drivers/net/ethernet/brocade/bna/bnad.h
index 458eb30371b5c2bde4a602809635e0f07d5229ad..5b5451edf4979771fcd94d9b2f42641f114e73f8 100644 (file)
@@ -44,6 +44,7 @@
 
 #define BNAD_MAX_RXS           1
 #define BNAD_MAX_RXPS_PER_RX   16
+#define BNAD_MAX_RXQ_PER_RXP   2
 
 /*
  * Control structure pointed to ccb->ctrl, which
@@ -66,7 +67,7 @@ struct bnad_rx_ctrl {
 #define BNAD_NAME                      "bna"
 #define BNAD_NAME_LEN                  64
 
-#define BNAD_VERSION                   "2.3.2.3"
+#define BNAD_VERSION                   "3.0.2.0"
 
 #define BNAD_MAILBOX_MSIX_INDEX                0
 #define BNAD_MAILBOX_MSIX_VECTORS      1
@@ -76,6 +77,8 @@ struct bnad_rx_ctrl {
 #define BNAD_STATS_TIMER_FREQ          1000    /* in msecs */
 #define BNAD_DIM_TIMER_FREQ            1000    /* in msecs */
 
+#define BNAD_IOCETH_TIMEOUT         10000
+
 #define BNAD_MAX_Q_DEPTH               0x10000
 #define BNAD_MIN_Q_DEPTH               0x200
 
@@ -93,6 +96,10 @@ struct bnad_rx_ctrl {
 #define BNAD_RXQ_REFILL                        0
 #define BNAD_RXQ_STARTED               1
 
+/* Resource limits */
+#define BNAD_NUM_TXQ                   (bnad->num_tx * bnad->num_txq_per_tx)
+#define BNAD_NUM_RXP                   (bnad->num_rx * bnad->num_rxp_per_rx)
+
 /*
  * DATA STRUCTURES
  */
@@ -115,7 +122,8 @@ struct bnad_completion {
        struct completion       tx_comp;
        struct completion       rx_comp;
        struct completion       stats_comp;
-       struct completion       port_comp;
+       struct completion       enet_comp;
+       struct completion       mtu_comp;
 
        u8                      ioc_comp_status;
        u8                      ucast_comp_status;
@@ -124,6 +132,7 @@ struct bnad_completion {
        u8                      rx_comp_status;
        u8                      stats_comp_status;
        u8                      port_comp_status;
+       u8                      mtu_comp_status;
 };
 
 /* Tx Rx Control Stats */
@@ -145,6 +154,7 @@ struct bnad_drv_stats {
        u64             netif_rx_dropped;
 
        u64             link_toggle;
+       u64             cee_toggle;
        u64             cee_up;
 
        u64             rxp_info_alloc_failed;
@@ -174,12 +184,14 @@ struct bnad_rx_res_info {
 struct bnad_tx_info {
        struct bna_tx *tx; /* 1:1 between tx_info & tx */
        struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX];
+       u32 tx_id;
 } ____cacheline_aligned;
 
 struct bnad_rx_info {
        struct bna_rx *rx; /* 1:1 between rx_info & rx */
 
        struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXPS_PER_RX];
+       u32 rx_id;
 } ____cacheline_aligned;
 
 /* Unmap queues for Tx / Rx cleanup */
@@ -205,13 +217,18 @@ struct bnad_unmap_q {
 /* Defines for run_flags bit-mask */
 /* Set, tested & cleared using xxx_bit() functions */
 /* Values indicated bit positions */
-#define        BNAD_RF_CEE_RUNNING             1
+#define BNAD_RF_CEE_RUNNING            0
+#define BNAD_RF_MTU_SET                1
 #define BNAD_RF_MBOX_IRQ_DISABLED      2
-#define BNAD_RF_RX_STARTED             3
+#define BNAD_RF_NETDEV_REGISTERED      3
 #define BNAD_RF_DIM_TIMER_RUNNING      4
 #define BNAD_RF_STATS_TIMER_RUNNING    5
-#define BNAD_RF_TX_SHUTDOWN_DELAYED    6
-#define BNAD_RF_RX_SHUTDOWN_DELAYED    7
+#define BNAD_RF_TX_PRIO_SET            6
+
+
+/* Define for Fast Path flags */
+/* Defined as bit positions */
+#define BNAD_FP_IN_RX_PATH           0
 
 struct bnad {
        struct net_device       *netdev;
@@ -265,6 +282,7 @@ struct bnad {
 
        /* Control path resources, memory & irq */
        struct bna_res_info res_info[BNA_RES_T_MAX];
+       struct bna_res_info mod_res_info[BNA_MOD_RES_T_MAX];
        struct bnad_tx_res_info tx_res_info[BNAD_MAX_TXS];
        struct bnad_rx_res_info rx_res_info[BNAD_MAX_RXS];
 
@@ -302,10 +320,10 @@ extern void bnad_set_ethtool_ops(struct net_device *netdev);
 extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad);
 extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad);
 
-extern int bnad_setup_rx(struct bnad *bnad, uint rx_id);
-extern int bnad_setup_tx(struct bnad *bnad, uint tx_id);
-extern void bnad_cleanup_tx(struct bnad *bnad, uint tx_id);
-extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id);
+extern int bnad_setup_rx(struct bnad *bnad, u32 rx_id);
+extern int bnad_setup_tx(struct bnad *bnad, u32 tx_id);
+extern void bnad_cleanup_tx(struct bnad *bnad, u32 tx_id);
+extern void bnad_cleanup_rx(struct bnad *bnad, u32 rx_id);
 
 /* Timer start/stop protos */
 extern void bnad_dim_timer_start(struct bnad *bnad);
similarity index 67%
rename from drivers/net/bna/bnad_ethtool.c
rename to drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index fea07f19a5dbc83ff1fc02f4e4cf1e96278e3e23..1c19dcea83c2486b65f4ef66f630125fa4e0096b 100644 (file)
 
 #define BNAD_NUM_TXF_COUNTERS 12
 #define BNAD_NUM_RXF_COUNTERS 10
-#define BNAD_NUM_CQ_COUNTERS 3
+#define BNAD_NUM_CQ_COUNTERS (3 + 5)
 #define BNAD_NUM_RXQ_COUNTERS 6
 #define BNAD_NUM_TXQ_COUNTERS 5
 
 #define BNAD_ETHTOOL_STATS_NUM                                         \
        (sizeof(struct rtnl_link_stats64) / sizeof(u64) +       \
        sizeof(struct bnad_drv_stats) / sizeof(u64) +           \
-       offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64))
+       offsetof(struct bfi_enet_stats, rxf_stats[0]) / sizeof(u64))
 
 static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
        "rx_packets",
@@ -277,7 +277,7 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
        ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL);
        if (ioc_attr) {
                spin_lock_irqsave(&bnad->bna_lock, flags);
-               bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr);
+               bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, ioc_attr);
                spin_unlock_irqrestore(&bnad->bna_lock, flags);
 
                strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver,
@@ -288,323 +288,6 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
        strncpy(drvinfo->bus_info, pci_name(bnad->pcidev), ETHTOOL_BUSINFO_LEN);
 }
 
-static int
-get_regs(struct bnad *bnad, u32 * regs)
-{
-       int num = 0, i;
-       u32 reg_addr;
-       unsigned long flags;
-
-#define BNAD_GET_REG(addr)                                     \
-do {                                                           \
-       if (regs)                                               \
-               regs[num++] = readl(bnad->bar0 + (addr));       \
-       else                                                    \
-               num++;                                          \
-} while (0)
-
-       spin_lock_irqsave(&bnad->bna_lock, flags);
-
-       /* DMA Block Internal Registers */
-       BNAD_GET_REG(DMA_CTRL_REG0);
-       BNAD_GET_REG(DMA_CTRL_REG1);
-       BNAD_GET_REG(DMA_ERR_INT_STATUS);
-       BNAD_GET_REG(DMA_ERR_INT_ENABLE);
-       BNAD_GET_REG(DMA_ERR_INT_STATUS_SET);
-
-       /* APP Block Register Address Offset from BAR0 */
-       BNAD_GET_REG(HOSTFN0_INT_STATUS);
-       BNAD_GET_REG(HOSTFN0_INT_MASK);
-       BNAD_GET_REG(HOST_PAGE_NUM_FN0);
-       BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN0);
-       BNAD_GET_REG(FN0_PCIE_ERR_REG);
-       BNAD_GET_REG(FN0_ERR_TYPE_STATUS_REG);
-       BNAD_GET_REG(FN0_ERR_TYPE_MSK_STATUS_REG);
-
-       BNAD_GET_REG(HOSTFN1_INT_STATUS);
-       BNAD_GET_REG(HOSTFN1_INT_MASK);
-       BNAD_GET_REG(HOST_PAGE_NUM_FN1);
-       BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN1);
-       BNAD_GET_REG(FN1_PCIE_ERR_REG);
-       BNAD_GET_REG(FN1_ERR_TYPE_STATUS_REG);
-       BNAD_GET_REG(FN1_ERR_TYPE_MSK_STATUS_REG);
-
-       BNAD_GET_REG(PCIE_MISC_REG);
-
-       BNAD_GET_REG(HOST_SEM0_INFO_REG);
-       BNAD_GET_REG(HOST_SEM1_INFO_REG);
-       BNAD_GET_REG(HOST_SEM2_INFO_REG);
-       BNAD_GET_REG(HOST_SEM3_INFO_REG);
-
-       BNAD_GET_REG(TEMPSENSE_CNTL_REG);
-       BNAD_GET_REG(TEMPSENSE_STAT_REG);
-
-       BNAD_GET_REG(APP_LOCAL_ERR_STAT);
-       BNAD_GET_REG(APP_LOCAL_ERR_MSK);
-
-       BNAD_GET_REG(PCIE_LNK_ERR_STAT);
-       BNAD_GET_REG(PCIE_LNK_ERR_MSK);
-
-       BNAD_GET_REG(FCOE_FIP_ETH_TYPE);
-       BNAD_GET_REG(RESV_ETH_TYPE);
-
-       BNAD_GET_REG(HOSTFN2_INT_STATUS);
-       BNAD_GET_REG(HOSTFN2_INT_MASK);
-       BNAD_GET_REG(HOST_PAGE_NUM_FN2);
-       BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN2);
-       BNAD_GET_REG(FN2_PCIE_ERR_REG);
-       BNAD_GET_REG(FN2_ERR_TYPE_STATUS_REG);
-       BNAD_GET_REG(FN2_ERR_TYPE_MSK_STATUS_REG);
-
-       BNAD_GET_REG(HOSTFN3_INT_STATUS);
-       BNAD_GET_REG(HOSTFN3_INT_MASK);
-       BNAD_GET_REG(HOST_PAGE_NUM_FN3);
-       BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN3);
-       BNAD_GET_REG(FN3_PCIE_ERR_REG);
-       BNAD_GET_REG(FN3_ERR_TYPE_STATUS_REG);
-       BNAD_GET_REG(FN3_ERR_TYPE_MSK_STATUS_REG);
-
-       /* Host Command Status Registers */
-       reg_addr = HOST_CMDSTS0_CLR_REG;
-       for (i = 0; i < 16; i++) {
-               BNAD_GET_REG(reg_addr);
-               BNAD_GET_REG(reg_addr + 4);
-               BNAD_GET_REG(reg_addr + 8);
-               reg_addr += 0x10;
-       }
-
-       /* Function ID register */
-       BNAD_GET_REG(FNC_ID_REG);
-
-       /* Function personality register */
-       BNAD_GET_REG(FNC_PERS_REG);
-
-       /* Operation mode register */
-       BNAD_GET_REG(OP_MODE);
-
-       /* LPU0 Registers */
-       BNAD_GET_REG(LPU0_MBOX_CTL_REG);
-       BNAD_GET_REG(LPU0_MBOX_CMD_REG);
-       BNAD_GET_REG(LPU0_MBOX_LINK_0REG);
-       BNAD_GET_REG(LPU1_MBOX_LINK_0REG);
-       BNAD_GET_REG(LPU0_MBOX_STATUS_0REG);
-       BNAD_GET_REG(LPU1_MBOX_STATUS_0REG);
-       BNAD_GET_REG(LPU0_ERR_STATUS_REG);
-       BNAD_GET_REG(LPU0_ERR_SET_REG);
-
-       /* LPU1 Registers */
-       BNAD_GET_REG(LPU1_MBOX_CTL_REG);
-       BNAD_GET_REG(LPU1_MBOX_CMD_REG);
-       BNAD_GET_REG(LPU0_MBOX_LINK_1REG);
-       BNAD_GET_REG(LPU1_MBOX_LINK_1REG);
-       BNAD_GET_REG(LPU0_MBOX_STATUS_1REG);
-       BNAD_GET_REG(LPU1_MBOX_STATUS_1REG);
-       BNAD_GET_REG(LPU1_ERR_STATUS_REG);
-       BNAD_GET_REG(LPU1_ERR_SET_REG);
-
-       /* PSS Registers */
-       BNAD_GET_REG(PSS_CTL_REG);
-       BNAD_GET_REG(PSS_ERR_STATUS_REG);
-       BNAD_GET_REG(ERR_STATUS_SET);
-       BNAD_GET_REG(PSS_RAM_ERR_STATUS_REG);
-
-       /* Catapult CPQ Registers */
-       BNAD_GET_REG(HOSTFN0_LPU0_MBOX0_CMD_STAT);
-       BNAD_GET_REG(HOSTFN0_LPU1_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN0_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN0_MBOX0_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN0_LPU0_MBOX1_CMD_STAT);
-       BNAD_GET_REG(HOSTFN0_LPU1_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN0_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN0_MBOX1_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN1_LPU0_MBOX0_CMD_STAT);
-       BNAD_GET_REG(HOSTFN1_LPU1_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN1_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN1_MBOX0_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN1_LPU0_MBOX1_CMD_STAT);
-       BNAD_GET_REG(HOSTFN1_LPU1_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN1_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN1_MBOX1_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN2_LPU0_MBOX0_CMD_STAT);
-       BNAD_GET_REG(HOSTFN2_LPU1_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN2_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN2_MBOX0_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN2_LPU0_MBOX1_CMD_STAT);
-       BNAD_GET_REG(HOSTFN2_LPU1_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN2_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN2_MBOX1_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN3_LPU0_MBOX0_CMD_STAT);
-       BNAD_GET_REG(HOSTFN3_LPU1_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN3_MBOX0_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN3_MBOX0_CMD_STAT);
-
-       BNAD_GET_REG(HOSTFN3_LPU0_MBOX1_CMD_STAT);
-       BNAD_GET_REG(HOSTFN3_LPU1_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU0_HOSTFN3_MBOX1_CMD_STAT);
-       BNAD_GET_REG(LPU1_HOSTFN3_MBOX1_CMD_STAT);
-
-       /* Host Function Force Parity Error Registers */
-       BNAD_GET_REG(HOSTFN0_LPU_FORCE_PERR);
-       BNAD_GET_REG(HOSTFN1_LPU_FORCE_PERR);
-       BNAD_GET_REG(HOSTFN2_LPU_FORCE_PERR);
-       BNAD_GET_REG(HOSTFN3_LPU_FORCE_PERR);
-
-       /* LL Port[0|1] Halt Mask Registers */
-       BNAD_GET_REG(LL_HALT_MSK_P0);
-       BNAD_GET_REG(LL_HALT_MSK_P1);
-
-       /* LL Port[0|1] Error Mask Registers */
-       BNAD_GET_REG(LL_ERR_MSK_P0);
-       BNAD_GET_REG(LL_ERR_MSK_P1);
-
-       /* EMC FLI Registers */
-       BNAD_GET_REG(FLI_CMD_REG);
-       BNAD_GET_REG(FLI_ADDR_REG);
-       BNAD_GET_REG(FLI_CTL_REG);
-       BNAD_GET_REG(FLI_WRDATA_REG);
-       BNAD_GET_REG(FLI_RDDATA_REG);
-       BNAD_GET_REG(FLI_DEV_STATUS_REG);
-       BNAD_GET_REG(FLI_SIG_WD_REG);
-
-       BNAD_GET_REG(FLI_DEV_VENDOR_REG);
-       BNAD_GET_REG(FLI_ERR_STATUS_REG);
-
-       /* RxAdm 0 Registers */
-       BNAD_GET_REG(RAD0_CTL_REG);
-       BNAD_GET_REG(RAD0_PE_PARM_REG);
-       BNAD_GET_REG(RAD0_BCN_REG);
-       BNAD_GET_REG(RAD0_DEFAULT_REG);
-       BNAD_GET_REG(RAD0_PROMISC_REG);
-       BNAD_GET_REG(RAD0_BCNQ_REG);
-       BNAD_GET_REG(RAD0_DEFAULTQ_REG);
-
-       BNAD_GET_REG(RAD0_ERR_STS);
-       BNAD_GET_REG(RAD0_SET_ERR_STS);
-       BNAD_GET_REG(RAD0_ERR_INT_EN);
-       BNAD_GET_REG(RAD0_FIRST_ERR);
-       BNAD_GET_REG(RAD0_FORCE_ERR);
-
-       BNAD_GET_REG(RAD0_MAC_MAN_1H);
-       BNAD_GET_REG(RAD0_MAC_MAN_1L);
-       BNAD_GET_REG(RAD0_MAC_MAN_2H);
-       BNAD_GET_REG(RAD0_MAC_MAN_2L);
-       BNAD_GET_REG(RAD0_MAC_MAN_3H);
-       BNAD_GET_REG(RAD0_MAC_MAN_3L);
-       BNAD_GET_REG(RAD0_MAC_MAN_4H);
-       BNAD_GET_REG(RAD0_MAC_MAN_4L);
-
-       BNAD_GET_REG(RAD0_LAST4_IP);
-
-       /* RxAdm 1 Registers */
-       BNAD_GET_REG(RAD1_CTL_REG);
-       BNAD_GET_REG(RAD1_PE_PARM_REG);
-       BNAD_GET_REG(RAD1_BCN_REG);
-       BNAD_GET_REG(RAD1_DEFAULT_REG);
-       BNAD_GET_REG(RAD1_PROMISC_REG);
-       BNAD_GET_REG(RAD1_BCNQ_REG);
-       BNAD_GET_REG(RAD1_DEFAULTQ_REG);
-
-       BNAD_GET_REG(RAD1_ERR_STS);
-       BNAD_GET_REG(RAD1_SET_ERR_STS);
-       BNAD_GET_REG(RAD1_ERR_INT_EN);
-
-       /* TxA0 Registers */
-       BNAD_GET_REG(TXA0_CTRL_REG);
-       /* TxA0 TSO Sequence # Registers (RO) */
-       for (i = 0; i < 8; i++) {
-               BNAD_GET_REG(TXA0_TSO_TCP_SEQ_REG(i));
-               BNAD_GET_REG(TXA0_TSO_IP_INFO_REG(i));
-       }
-
-       /* TxA1 Registers */
-       BNAD_GET_REG(TXA1_CTRL_REG);
-       /* TxA1 TSO Sequence # Registers (RO) */
-       for (i = 0; i < 8; i++) {
-               BNAD_GET_REG(TXA1_TSO_TCP_SEQ_REG(i));
-               BNAD_GET_REG(TXA1_TSO_IP_INFO_REG(i));
-       }
-
-       /* RxA Registers */
-       BNAD_GET_REG(RXA0_CTL_REG);
-       BNAD_GET_REG(RXA1_CTL_REG);
-
-       /* PLB0 Registers */
-       BNAD_GET_REG(PLB0_ECM_TIMER_REG);
-       BNAD_GET_REG(PLB0_RL_CTL);
-       for (i = 0; i < 8; i++)
-               BNAD_GET_REG(PLB0_RL_MAX_BC(i));
-       BNAD_GET_REG(PLB0_RL_TU_PRIO);
-       for (i = 0; i < 8; i++)
-               BNAD_GET_REG(PLB0_RL_BYTE_CNT(i));
-       BNAD_GET_REG(PLB0_RL_MIN_REG);
-       BNAD_GET_REG(PLB0_RL_MAX_REG);
-       BNAD_GET_REG(PLB0_EMS_ADD_REG);
-
-       /* PLB1 Registers */
-       BNAD_GET_REG(PLB1_ECM_TIMER_REG);
-       BNAD_GET_REG(PLB1_RL_CTL);
-       for (i = 0; i < 8; i++)
-               BNAD_GET_REG(PLB1_RL_MAX_BC(i));
-       BNAD_GET_REG(PLB1_RL_TU_PRIO);
-       for (i = 0; i < 8; i++)
-               BNAD_GET_REG(PLB1_RL_BYTE_CNT(i));
-       BNAD_GET_REG(PLB1_RL_MIN_REG);
-       BNAD_GET_REG(PLB1_RL_MAX_REG);
-       BNAD_GET_REG(PLB1_EMS_ADD_REG);
-
-       /* HQM Control Register */
-       BNAD_GET_REG(HQM0_CTL_REG);
-       BNAD_GET_REG(HQM0_RXQ_STOP_SEM);
-       BNAD_GET_REG(HQM0_TXQ_STOP_SEM);
-       BNAD_GET_REG(HQM1_CTL_REG);
-       BNAD_GET_REG(HQM1_RXQ_STOP_SEM);
-       BNAD_GET_REG(HQM1_TXQ_STOP_SEM);
-
-       /* LUT Registers */
-       BNAD_GET_REG(LUT0_ERR_STS);
-       BNAD_GET_REG(LUT0_SET_ERR_STS);
-       BNAD_GET_REG(LUT1_ERR_STS);
-       BNAD_GET_REG(LUT1_SET_ERR_STS);
-
-       /* TRC Registers */
-       BNAD_GET_REG(TRC_CTL_REG);
-       BNAD_GET_REG(TRC_MODS_REG);
-       BNAD_GET_REG(TRC_TRGC_REG);
-       BNAD_GET_REG(TRC_CNT1_REG);
-       BNAD_GET_REG(TRC_CNT2_REG);
-       BNAD_GET_REG(TRC_NXTS_REG);
-       BNAD_GET_REG(TRC_DIRR_REG);
-       for (i = 0; i < 10; i++)
-               BNAD_GET_REG(TRC_TRGM_REG(i));
-       for (i = 0; i < 10; i++)
-               BNAD_GET_REG(TRC_NXTM_REG(i));
-       for (i = 0; i < 10; i++)
-               BNAD_GET_REG(TRC_STRM_REG(i));
-
-       spin_unlock_irqrestore(&bnad->bna_lock, flags);
-#undef BNAD_GET_REG
-       return num;
-}
-static int
-bnad_get_regs_len(struct net_device *netdev)
-{
-       int ret = get_regs(netdev_priv(netdev), NULL) * sizeof(u32);
-       return ret;
-}
-
-static void
-bnad_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
-{
-       memset(buf, 0, bnad_get_regs_len(netdev));
-       get_regs(netdev_priv(netdev), buf);
-}
-
 static void
 bnad_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo)
 {
@@ -779,8 +462,8 @@ bnad_get_pauseparam(struct net_device *netdev,
        struct bnad *bnad = netdev_priv(netdev);
 
        pauseparam->autoneg = 0;
-       pauseparam->rx_pause = bnad->bna.port.pause_config.rx_pause;
-       pauseparam->tx_pause = bnad->bna.port.pause_config.tx_pause;
+       pauseparam->rx_pause = bnad->bna.enet.pause_config.rx_pause;
+       pauseparam->tx_pause = bnad->bna.enet.pause_config.tx_pause;
 }
 
 static int
@@ -795,12 +478,12 @@ bnad_set_pauseparam(struct net_device *netdev,
                return -EINVAL;
 
        mutex_lock(&bnad->conf_mutex);
-       if (pauseparam->rx_pause != bnad->bna.port.pause_config.rx_pause ||
-           pauseparam->tx_pause != bnad->bna.port.pause_config.tx_pause) {
+       if (pauseparam->rx_pause != bnad->bna.enet.pause_config.rx_pause ||
+           pauseparam->tx_pause != bnad->bna.enet.pause_config.tx_pause) {
                pause_config.rx_pause = pauseparam->rx_pause;
                pause_config.tx_pause = pauseparam->tx_pause;
                spin_lock_irqsave(&bnad->bna_lock, flags);
-               bna_port_pause_config(&bnad->bna.port, &pause_config, NULL);
+               bna_enet_pause_config(&bnad->bna.enet, &pause_config, NULL);
                spin_unlock_irqrestore(&bnad->bna_lock, flags);
        }
        mutex_unlock(&bnad->conf_mutex);
@@ -812,7 +495,7 @@ bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
 {
        struct bnad *bnad = netdev_priv(netdev);
        int i, j, q_num;
-       u64 bmap;
+       u32 bmap;
 
        mutex_lock(&bnad->conf_mutex);
 
@@ -825,9 +508,8 @@ bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
                               ETH_GSTRING_LEN);
                        string += ETH_GSTRING_LEN;
                }
-               bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
-                       ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
-               for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+               bmap = bna_tx_rid_mask(&bnad->bna);
+               for (i = 0; bmap; i++) {
                        if (bmap & 1) {
                                sprintf(string, "txf%d_ucast_octets", i);
                                string += ETH_GSTRING_LEN;
@@ -857,9 +539,8 @@ bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
                        bmap >>= 1;
                }
 
-               bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
-                       ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
-               for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+               bmap = bna_rx_rid_mask(&bnad->bna);
+               for (i = 0; bmap; i++) {
                        if (bmap & 1) {
                                sprintf(string, "rxf%d_ucast_octets", i);
                                string += ETH_GSTRING_LEN;
@@ -980,18 +661,16 @@ bnad_get_stats_count_locked(struct net_device *netdev)
 {
        struct bnad *bnad = netdev_priv(netdev);
        int i, j, count, rxf_active_num = 0, txf_active_num = 0;
-       u64 bmap;
+       u32 bmap;
 
-       bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
-                       ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
-       for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+       bmap = bna_tx_rid_mask(&bnad->bna);
+       for (i = 0; bmap; i++) {
                if (bmap & 1)
                        txf_active_num++;
                bmap >>= 1;
        }
-       bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
-                       ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
-       for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+       bmap = bna_rx_rid_mask(&bnad->bna);
+       for (i = 0; bmap; i++) {
                if (bmap & 1)
                        rxf_active_num++;
                bmap >>= 1;
@@ -1104,7 +783,7 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
        unsigned long flags;
        struct rtnl_link_stats64 *net_stats64;
        u64 *stats64;
-       u64 bmap;
+       u32 bmap;
 
        mutex_lock(&bnad->conf_mutex);
        if (bnad_get_stats_count_locked(netdev) != stats->n_stats) {
@@ -1135,20 +814,20 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
                buf[bi++] = stats64[i];
 
        /* Fill hardware stats excluding the rxf/txf into ethtool bufs */
-       stats64 = (u64 *) bnad->stats.bna_stats->hw_stats;
+       stats64 = (u64 *) &bnad->stats.bna_stats->hw_stats;
        for (i = 0;
-            i < offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64);
+            i < offsetof(struct bfi_enet_stats, rxf_stats[0]) /
+               sizeof(u64);
             i++)
                buf[bi++] = stats64[i];
 
        /* Fill txf stats into ethtool buffers */
-       bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
-                       ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
-       for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+       bmap = bna_tx_rid_mask(&bnad->bna);
+       for (i = 0; bmap; i++) {
                if (bmap & 1) {
                        stats64 = (u64 *)&bnad->stats.bna_stats->
-                                               hw_stats->txf_stats[i];
-                       for (j = 0; j < sizeof(struct bfi_ll_stats_txf) /
+                                               hw_stats.txf_stats[i];
+                       for (j = 0; j < sizeof(struct bfi_enet_stats_txf) /
                                        sizeof(u64); j++)
                                buf[bi++] = stats64[j];
                }
@@ -1156,13 +835,12 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
        }
 
        /*  Fill rxf stats into ethtool buffers */
-       bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
-                       ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
-       for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+       bmap = bna_rx_rid_mask(&bnad->bna);
+       for (i = 0; bmap; i++) {
                if (bmap & 1) {
                        stats64 = (u64 *)&bnad->stats.bna_stats->
-                                               hw_stats->rxf_stats[i];
-                       for (j = 0; j < sizeof(struct bfi_ll_stats_rxf) /
+                                               hw_stats.rxf_stats[i];
+                       for (j = 0; j < sizeof(struct bfi_enet_stats_rxf) /
                                        sizeof(u64); j++)
                                buf[bi++] = stats64[j];
                }
@@ -1192,8 +870,6 @@ static struct ethtool_ops bnad_ethtool_ops = {
        .get_settings = bnad_get_settings,
        .set_settings = bnad_set_settings,
        .get_drvinfo = bnad_get_drvinfo,
-       .get_regs_len = bnad_get_regs_len,
-       .get_regs = bnad_get_regs,
        .get_wol = bnad_get_wol,
        .get_link = ethtool_op_get_link,
        .get_coalesce = bnad_get_coalesce,
similarity index 68%
rename from drivers/net/bna/cna.h
rename to drivers/net/ethernet/brocade/bna/cna.h
index a679e038747b7dc9a60450c59202ebcd593e72c6..50fce15feaccc17338be418033b41f463a70d626 100644 (file)
@@ -40,7 +40,7 @@
 
 extern char bfa_version[];
 
-#define        CNA_FW_FILE_CT  "ctfw_cna.bin"
+#define        CNA_FW_FILE_CT  "ctfw.bin"
 #define FC_SYMNAME_MAX 256     /*!< max name server symbolic name size */
 
 #pragma pack(1)
@@ -77,4 +77,33 @@ typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t;
        }                                                               \
 }
 
+/*
+ * bfa_q_deq_tail - dequeue an element from tail of the queue
+ */
+#define bfa_q_deq_tail(_q, _qe) {                                      \
+       if (!list_empty(_q)) {                                          \
+               *((struct list_head **) (_qe)) = bfa_q_prev(_q);        \
+               bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) =  \
+                                               (struct list_head *) (_q); \
+               bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe);\
+               bfa_q_qe_init(*((struct list_head **) _qe));            \
+       } else {                                                        \
+               *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
+       }                                                               \
+}
+
+/*
+ * bfa_add_tail_head - enqueue an element at the head of queue
+ */
+#define bfa_q_enq_head(_q, _qe) {                                      \
+       if (!(bfa_q_next(_qe) == NULL) && (bfa_q_prev(_qe) == NULL))    \
+               pr_err("Assertion failure: %s:%d: %d",                  \
+                       __FILE__, __LINE__,                             \
+               (bfa_q_next(_qe) == NULL) && (bfa_q_prev(_qe) == NULL));\
+       bfa_q_next(_qe) = bfa_q_next(_q);                               \
+       bfa_q_prev(_qe) = (struct list_head *) (_q);                    \
+       bfa_q_prev(bfa_q_next(_q)) = (struct list_head *) (_qe);        \
+       bfa_q_next(_q) = (struct list_head *) (_qe);                    \
+}
+
 #endif /* __CNA_H__ */
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
new file mode 100644 (file)
index 0000000..c00e706
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Atmel device configuration
+#
+
+config HAVE_NET_MACB
+       bool
+
+config NET_ATMEL
+       bool "Atmel devices"
+       depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y.
+         Make sure you know the name of your card. Read the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         If unsure, say Y.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the remaining Atmel network card questions. If you say Y, you will be
+         asked for your specific card in the following questions.
+
+if NET_ATMEL
+
+config ARM_AT91_ETHER
+       tristate "AT91RM9200 Ethernet support"
+       depends on ARM && ARCH_AT91RM9200
+       select MII
+       ---help---
+         If you wish to compile a kernel for the AT91RM9200 and enable
+         ethernet support, then you should always answer Y to this.
+
+config MACB
+       tristate "Atmel MACB support"
+       depends on HAVE_NET_MACB
+       select PHYLIB
+       ---help---
+         The Atmel MACB ethernet interface is found on many AT32 and AT91
+         parts. Say Y to include support for the MACB chip.
+
+         To compile this driver as a module, choose M here: the module
+         will be called macb.
+
+endif # NET_ATMEL
diff --git a/drivers/net/ethernet/cadence/Makefile b/drivers/net/ethernet/cadence/Makefile
new file mode 100644 (file)
index 0000000..9068b83
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Atmel network device drivers.
+#
+
+obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o
+obj-$(CONFIG_MACB) += macb.o
similarity index 99%
rename from drivers/net/arm/at91_ether.c
rename to drivers/net/ethernet/cadence/at91_ether.c
index 29dc43523cec2822b9b50902fe005d84d2aa4312..56624d3034871c4988ddd3e4963206133eaab517 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/mach-types.h>
 
 #include <mach/at91rm9200_emac.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <mach/board.h>
 
 #include "at91_ether.h"
@@ -968,7 +968,7 @@ static const struct net_device_ops at91ether_netdev_ops = {
        .ndo_stop               = at91ether_close,
        .ndo_start_xmit         = at91ether_start_xmit,
        .ndo_get_stats          = at91ether_stats,
-       .ndo_set_multicast_list = at91ether_set_multicast_list,
+       .ndo_set_rx_mode        = at91ether_set_multicast_list,
        .ndo_set_mac_address    = set_mac_address,
        .ndo_do_ioctl           = at91ether_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/macb.c
rename to drivers/net/ethernet/cadence/macb.c
index dc4e305a1087c69a0e09b4cbe50b189ff15b8cc1..a437b46e5490f8770707a5e4373c1bb4c9302fca 100644 (file)
@@ -1106,7 +1106,7 @@ static const struct net_device_ops macb_netdev_ops = {
        .ndo_open               = macb_open,
        .ndo_stop               = macb_close,
        .ndo_start_xmit         = macb_start_xmit,
-       .ndo_set_multicast_list = macb_set_rx_mode,
+       .ndo_set_rx_mode        = macb_set_rx_mode,
        .ndo_get_stats          = macb_get_stats,
        .ndo_do_ioctl           = macb_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig
new file mode 100644 (file)
index 0000000..7b54574
--- /dev/null
@@ -0,0 +1,106 @@
+#
+# Chelsio device configuration
+#
+
+config NET_VENDOR_CHELSIO
+       bool "Chelsio devices"
+       depends on PCI || INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Chelsio devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_CHELSIO
+
+config CHELSIO_T1
+       tristate "Chelsio 10Gb Ethernet support"
+       depends on PCI
+       select CRC32
+       select MDIO
+       ---help---
+         This driver supports Chelsio gigabit and 10-gigabit
+         Ethernet cards. More information about adapter features and
+         performance tuning is in <file:Documentation/networking/cxgb.txt>.
+
+         For general information about Chelsio and our products, visit
+         our website at <http://www.chelsio.com>.
+
+         For customer support, please visit our customer support page at
+         <http://www.chelsio.com/support.html>.
+
+         Please send feedback to <linux-bugs@chelsio.com>.
+
+         To compile this driver as a module, choose M here: the module
+         will be called cxgb.
+
+config CHELSIO_T1_1G
+       bool "Chelsio gigabit Ethernet support"
+       depends on CHELSIO_T1
+       ---help---
+         Enables support for Chelsio's gigabit Ethernet PCI cards.  If you
+         are using only 10G cards say 'N' here.
+
+config CHELSIO_T3
+       tristate "Chelsio Communications T3 10Gb Ethernet support"
+       depends on PCI && INET
+       select FW_LOADER
+       select MDIO
+       ---help---
+         This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
+         adapters.
+
+         For general information about Chelsio and our products, visit
+         our website at <http://www.chelsio.com>.
+
+         For customer support, please visit our customer support page at
+         <http://www.chelsio.com/support.html>.
+
+         Please send feedback to <linux-bugs@chelsio.com>.
+
+         To compile this driver as a module, choose M here: the module
+         will be called cxgb3.
+
+config CHELSIO_T4
+       tristate "Chelsio Communications T4 Ethernet support"
+       depends on PCI
+       select FW_LOADER
+       select MDIO
+       ---help---
+         This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
+         adapters.
+
+         For general information about Chelsio and our products, visit
+         our website at <http://www.chelsio.com>.
+
+         For customer support, please visit our customer support page at
+         <http://www.chelsio.com/support.html>.
+
+         Please send feedback to <linux-bugs@chelsio.com>.
+
+         To compile this driver as a module choose M here; the module
+         will be called cxgb4.
+
+config CHELSIO_T4VF
+       tristate "Chelsio Communications T4 Virtual Function Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
+         adapters with PCI-E SR-IOV Virtual Functions.
+
+         For general information about Chelsio and our products, visit
+         our website at <http://www.chelsio.com>.
+
+         For customer support, please visit our customer support page at
+         <http://www.chelsio.com/support.html>.
+
+         Please send feedback to <linux-bugs@chelsio.com>.
+
+         To compile this driver as a module choose M here; the module
+         will be called cxgb4vf.
+
+endif # NET_VENDOR_CHELSIO
diff --git a/drivers/net/ethernet/chelsio/Makefile b/drivers/net/ethernet/chelsio/Makefile
new file mode 100644 (file)
index 0000000..390510b
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the Chelsio network device drivers.
+#
+
+obj-$(CONFIG_CHELSIO_T1) += cxgb/
+obj-$(CONFIG_CHELSIO_T3) += cxgb3/
+obj-$(CONFIG_CHELSIO_T4) += cxgb4/
+obj-$(CONFIG_CHELSIO_T4VF) += cxgb4vf/
similarity index 99%
rename from drivers/net/chelsio/cxgb2.c
rename to drivers/net/ethernet/chelsio/cxgb/cxgb2.c
index 3edbbc4c5112487b7bca2a99bb1e890918a03a63..9993f4f1543325e508957869513919bb4815866a 100644 (file)
@@ -964,7 +964,7 @@ static const struct net_device_ops cxgb_netdev_ops = {
        .ndo_start_xmit         = t1_start_xmit,
        .ndo_get_stats          = t1_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = t1_set_rxmode,
+       .ndo_set_rx_mode        = t1_set_rxmode,
        .ndo_do_ioctl           = t1_ioctl,
        .ndo_change_mtu         = t1_change_mtu,
        .ndo_set_mac_address    = t1_set_mac_addr,
similarity index 99%
rename from drivers/net/cxgb3/cxgb3_main.c
rename to drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 93b41a7ac175cc49f76c147b3f0a1d953e50b9bd..29e0e4243231687246427239a7e9be65da65694c 100644 (file)
@@ -3153,7 +3153,7 @@ static const struct net_device_ops cxgb_netdev_ops = {
        .ndo_start_xmit         = t3_eth_xmit,
        .ndo_get_stats          = cxgb_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = cxgb_set_rxmode,
+       .ndo_set_rx_mode        = cxgb_set_rxmode,
        .ndo_do_ioctl           = cxgb_ioctl,
        .ndo_change_mtu         = cxgb_change_mtu,
        .ndo_set_mac_address    = cxgb_set_mac_addr,
similarity index 99%
rename from drivers/net/cxgb4/cxgb4_main.c
rename to drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index c9957b7f17b57f0d746bbf2987684b49c7ce3ba3..90b4921cac9b432ac0b414692f698ca192f17aa0 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/err.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/init.h>
 #include <linux/log2.h>
@@ -3639,6 +3640,8 @@ static int __devinit init_one(struct pci_dev *pdev,
                netdev->features |= netdev->hw_features | highdma;
                netdev->vlan_features = netdev->features & VLAN_FEAT;
 
+               netdev->priv_flags |= IFF_UNICAST_FLT;
+
                netdev->netdev_ops = &cxgb4_netdev_ops;
                SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
        }
similarity index 99%
rename from drivers/net/cxgb4vf/cxgb4vf_main.c
rename to drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index ec799139dfe26a638b89883fb12a94fa29898cce..da9072bfca8b859a508943d1abdc9fd12201865c 100644 (file)
@@ -2625,6 +2625,8 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
                if (pci_using_dac)
                        netdev->features |= NETIF_F_HIGHDMA;
 
+               netdev->priv_flags |= IFF_UNICAST_FLT;
+
                netdev->netdev_ops = &cxgb4vf_netdev_ops;
                SET_ETHTOOL_OPS(netdev, &cxgb4vf_ethtool_ops);
 
diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig
new file mode 100644 (file)
index 0000000..53ebe78
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Cirrus network device configuration
+#
+
+config NET_VENDOR_CIRRUS
+       bool "Cirrus devices"
+       depends on ARM && ARCH_EP93XX
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Cirrus cards. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_CIRRUS
+
+config EP93XX_ETH
+       tristate "EP93xx Ethernet support"
+       depends on ARM && ARCH_EP93XX
+       select MII
+       help
+         This is a driver for the ethernet hardware included in EP93xx CPUs.
+         Say Y if you are building a kernel for EP93xx based devices.
+
+endif # NET_VENDOR_CIRRUS
diff --git a/drivers/net/ethernet/cirrus/Makefile b/drivers/net/ethernet/cirrus/Makefile
new file mode 100644 (file)
index 0000000..9905ea2
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Cirrus network device drivers.
+#
+
+obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o
diff --git a/drivers/net/ethernet/cisco/Kconfig b/drivers/net/ethernet/cisco/Kconfig
new file mode 100644 (file)
index 0000000..bbd5348
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Cisco device configuration
+#
+
+config NET_VENDOR_CISCO
+       bool "Cisco devices"
+       depends on PCI && INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Cisco cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_CISCO
+
+source "drivers/net/ethernet/cisco/enic/Kconfig"
+
+endif # NET_VENDOR_CISCO
diff --git a/drivers/net/ethernet/cisco/Makefile b/drivers/net/ethernet/cisco/Makefile
new file mode 100644 (file)
index 0000000..6c7437b
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Cisco device drivers.
+#
+
+obj-$(CONFIG_ENIC) += enic/
diff --git a/drivers/net/ethernet/cisco/enic/Kconfig b/drivers/net/ethernet/cisco/enic/Kconfig
new file mode 100644 (file)
index 0000000..9cc706a
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Cisco device configuration
+#
+
+config ENIC
+       tristate "Cisco VIC Ethernet NIC Support"
+       depends on PCI && INET
+       ---help---
+         This enables the support for the Cisco VIC Ethernet card.
similarity index 99%
rename from drivers/net/enic/enic_main.c
rename to drivers/net/ethernet/cisco/enic/enic_main.c
index 67a27cd304dda1198f11a297334bd2512abe4ede..c751c25d301ef85f3b848fc9aacbbb60eabe254e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/ethtool.h>
@@ -2103,7 +2104,6 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
        .ndo_get_stats64        = enic_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_rx_mode        = enic_set_rx_mode,
-       .ndo_set_multicast_list = enic_set_rx_mode,
        .ndo_set_mac_address    = enic_set_mac_address_dynamic,
        .ndo_change_mtu         = enic_change_mtu,
        .ndo_vlan_rx_add_vid    = enic_vlan_rx_add_vid,
@@ -2125,7 +2125,6 @@ static const struct net_device_ops enic_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = enic_set_mac_address,
        .ndo_set_rx_mode        = enic_set_rx_mode,
-       .ndo_set_multicast_list = enic_set_rx_mode,
        .ndo_change_mtu         = enic_change_mtu,
        .ndo_vlan_rx_add_vid    = enic_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = enic_vlan_rx_kill_vid,
@@ -2442,6 +2441,8 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        if (using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        err = register_netdev(netdev);
        if (err) {
                dev_err(dev, "Cannot register net device, aborting\n");
diff --git a/drivers/net/ethernet/davicom/Kconfig b/drivers/net/ethernet/davicom/Kconfig
new file mode 100644 (file)
index 0000000..73c5d20
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Davicom device configuration
+#
+
+config DM9000
+       tristate "DM9000 support"
+       depends on ARM || BLACKFIN || MIPS
+       select CRC32
+       select MII
+       ---help---
+         Support for DM9000 chipset.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called dm9000.
+
+config DM9000_FORCE_SIMPLE_PHY_POLL
+       bool "Force simple NSR based PHY polling"
+       depends on DM9000
+       ---help---
+         This configuration forces the DM9000 to use the NSR's LinkStatus
+         bit to determine if the link is up or down instead of the more
+         costly MII PHY reads. Note, this will not work if the chip is
+         operating with an external PHY.
diff --git a/drivers/net/ethernet/davicom/Makefile b/drivers/net/ethernet/davicom/Makefile
new file mode 100644 (file)
index 0000000..74b31f0
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Davicom device drivers.
+#
+
+obj-$(CONFIG_DM9000) += dm9000.o
similarity index 99%
rename from drivers/net/dm9000.c
rename to drivers/net/ethernet/davicom/dm9000.c
index 8ef31dc4704d89d8c68d24fd6a1e085824c7d019..438f4580bf66207539761761e37c42e0ef303b78 100644 (file)
@@ -56,6 +56,13 @@ static int watchdog = 5000;
 module_param(watchdog, int, 0400);
 MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
 
+/*
+ * Debug messages level
+ */
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "dm9000 debug level (0-4)");
+
 /* DM9000 register address locking.
  *
  * The DM9000 uses an address register to control where data written
@@ -103,7 +110,6 @@ typedef struct board_info {
        unsigned int    flags;
        unsigned int    in_suspend :1;
        unsigned int    wake_supported :1;
-       int             debug_level;
 
        enum dm9000_type type;
 
@@ -138,8 +144,7 @@ typedef struct board_info {
 /* debug code */
 
 #define dm9000_dbg(db, lev, msg...) do {               \
-       if ((lev) < CONFIG_DM9000_DEBUGLEVEL &&         \
-           (lev) < db->debug_level) {                  \
+       if ((lev) < debug) {                            \
                dev_dbg(db->dev, msg);                  \
        }                                               \
 } while (0)
@@ -1339,7 +1344,7 @@ static const struct net_device_ops dm9000_netdev_ops = {
        .ndo_stop               = dm9000_stop,
        .ndo_start_xmit         = dm9000_start_xmit,
        .ndo_tx_timeout         = dm9000_timeout,
-       .ndo_set_multicast_list = dm9000_hash_table,
+       .ndo_set_rx_mode        = dm9000_hash_table,
        .ndo_do_ioctl           = dm9000_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_features       = dm9000_set_features,
diff --git a/drivers/net/ethernet/dec/Kconfig b/drivers/net/ethernet/dec/Kconfig
new file mode 100644 (file)
index 0000000..40e8df9
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# Digital Equipment Inc network device configuration
+#
+
+config NET_VENDOR_DEC
+       bool "Digital Equipment devices"
+       depends on PCI || EISA || CARDBUS
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about DEC cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_DEC
+
+config EWRK3
+       tristate "EtherWORKS 3 (DE203, DE204, DE205) support"
+       depends on ISA
+       select CRC32
+       ---help---
+         This driver supports the DE203, DE204 and DE205 network (Ethernet)
+         cards. If this is for you, say Y and read
+         <file:Documentation/networking/ewrk3.txt> in the kernel source as
+         well as the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ewrk3.
+
+source "drivers/net/ethernet/dec/tulip/Kconfig"
+
+endif # NET_VENDOR_DEC
diff --git a/drivers/net/ethernet/dec/Makefile b/drivers/net/ethernet/dec/Makefile
new file mode 100644 (file)
index 0000000..1b01ed8
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Digital Equipment Inc. network device drivers.
+#
+
+obj-$(CONFIG_EWRK3) += ewrk3.o
+obj-$(CONFIG_NET_TULIP) += tulip/
similarity index 99%
rename from drivers/net/ewrk3.c
rename to drivers/net/ethernet/dec/ewrk3.c
index 05a5f71451a76ba16fe62d5eb833153d60356e53..f9df5e4d0341eccf98f76557689f4e469355479c 100644 (file)
@@ -393,7 +393,7 @@ static const struct net_device_ops ewrk3_netdev_ops = {
        .ndo_open               = ewrk3_open,
        .ndo_start_xmit         = ewrk3_queue_pkt,
        .ndo_stop               = ewrk3_close,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_do_ioctl           = ewrk3_ioctl,
        .ndo_tx_timeout         = ewrk3_timeout,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 96%
rename from drivers/net/tulip/Kconfig
rename to drivers/net/ethernet/dec/tulip/Kconfig
index 1f8d4a8d8ea43ab09838026b3eb54f7ab881fdbc..f6af772b12c904913660b392e069705c31732aa6 100644 (file)
@@ -2,10 +2,10 @@
 # Tulip family network device configuration
 #
 
-menuconfig NET_TULIP
-       bool "\"Tulip\" family network device support"
-       depends on PCI || EISA || CARDBUS
-       help
+config NET_TULIP
+       bool "DEC - Tulip devices"
+       depends on (PCI || EISA || CARDBUS)
+       ---help---
          This selects the "Tulip" family of EISA/PCI network cards.
 
 if NET_TULIP
@@ -32,7 +32,7 @@ config DE2104X_DSL
        depends on DE2104X
        range 0 31
        default 0
-       help
+       ---help---
          Setting this value allows to align ring buffer descriptors into their
          own cache lines. Value of 4 corresponds to the typical 32 byte line
          (the descriptor is 16 bytes). This is necessary on systems that lack
@@ -59,7 +59,7 @@ config TULIP
 config TULIP_MWI
        bool "New bus configuration (EXPERIMENTAL)"
        depends on TULIP && EXPERIMENTAL
-       help
+       ---help---
          This configures your Tulip card specifically for the card and
          system cache line size type you are using.
 
@@ -70,7 +70,7 @@ config TULIP_MWI
 config TULIP_MMIO
        bool "Use PCI shared mem for NIC registers"
        depends on TULIP
-       help
+       ---help---
          Use PCI shared memory for the NIC registers, rather than going through
          the Tulip's PIO (programmed I/O ports).  Faster, but could produce
          obscure bugs if your mainboard has memory controller timing issues.
@@ -79,7 +79,7 @@ config TULIP_MMIO
 config TULIP_NAPI
        bool "Use RX polling (NAPI)"
        depends on TULIP
-       help
+       ---help---
          NAPI is a new driver API designed to reduce CPU and interrupt load
          when the driver is receiving lots of packets from the card. It is
          still somewhat experimental and thus not yet enabled by default.
@@ -107,7 +107,7 @@ config TULIP_DM910X
 
 config DE4X5
        tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
-       depends on PCI || EISA
+       depends on (PCI || EISA)
        select CRC32
        ---help---
          This is support for the DIGITAL series of PCI/EISA Ethernet cards.
@@ -126,7 +126,7 @@ config WINBOND_840
        depends on PCI
        select CRC32
        select MII
-       help
+       ---help---
          This driver is for the Winbond W89c840 chip.  It also works with 
          the TX9882 chip on the Compex RL100-ATX board.
          More specific information and updates are available from
similarity index 99%
rename from drivers/net/tulip/de2104x.c
rename to drivers/net/ethernet/dec/tulip/de2104x.c
index ce90efc6ba3c4bdb44f633a2609425cb534d7427..1427739d9a514c9881e3b5b8187df303bc6d66c2 100644 (file)
@@ -1956,7 +1956,7 @@ bad_srom:
 static const struct net_device_ops de_netdev_ops = {
        .ndo_open               = de_open,
        .ndo_stop               = de_close,
-       .ndo_set_multicast_list = de_set_rx_mode,
+       .ndo_set_rx_mode        = de_set_rx_mode,
        .ndo_start_xmit         = de_start_xmit,
        .ndo_get_stats          = de_get_stats,
        .ndo_tx_timeout         = de_tx_timeout,
similarity index 99%
rename from drivers/net/tulip/de4x5.c
rename to drivers/net/ethernet/dec/tulip/de4x5.c
index 959b41021a65a5258c58f629c39263d3b080e472..871bcaa7068d0f5a5eb476eb8facc5fd5cf9cd22 100644 (file)
@@ -1084,7 +1084,7 @@ static const struct net_device_ops de4x5_netdev_ops = {
     .ndo_stop          = de4x5_close,
     .ndo_start_xmit    = de4x5_queue_pkt,
     .ndo_get_stats     = de4x5_get_stats,
-    .ndo_set_multicast_list = set_multicast_list,
+    .ndo_set_rx_mode   = set_multicast_list,
     .ndo_do_ioctl      = de4x5_ioctl,
     .ndo_change_mtu    = eth_change_mtu,
     .ndo_set_mac_address= eth_mac_addr,
similarity index 99%
rename from drivers/net/tulip/dmfe.c
rename to drivers/net/ethernet/dec/tulip/dmfe.c
index 9a21ca3873fce6d0dbc455b6cda5025db9be6d59..17b11ee1745a3795fb2da04a928ebbdfb19357c5 100644 (file)
@@ -356,7 +356,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_open               = dmfe_open,
        .ndo_stop               = dmfe_stop,
        .ndo_start_xmit         = dmfe_start_xmit,
-       .ndo_set_multicast_list = dmfe_set_filter_mode,
+       .ndo_set_rx_mode        = dmfe_set_filter_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/tulip/tulip_core.c
rename to drivers/net/ethernet/dec/tulip/tulip_core.c
index 1246998a677ca5749cc0c68bf1f0dd549c451e42..011f67c7ca47a189aa5238c0697a8d03e49fc4be 100644 (file)
@@ -1291,7 +1291,7 @@ static const struct net_device_ops tulip_netdev_ops = {
        .ndo_stop               = tulip_close,
        .ndo_get_stats          = tulip_get_stats,
        .ndo_do_ioctl           = private_ioctl,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/tulip/uli526x.c
rename to drivers/net/ethernet/dec/tulip/uli526x.c
index 9e63f406f72db2a9b2aac4958df6a1e1853c33ef..7a44a7a6adc8a0c172a4aa11dfd623ab74ccdc15 100644 (file)
@@ -259,7 +259,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_open               = uli526x_open,
        .ndo_stop               = uli526x_stop,
        .ndo_start_xmit         = uli526x_start_xmit,
-       .ndo_set_multicast_list = uli526x_set_filter_mode,
+       .ndo_set_rx_mode        = uli526x_set_filter_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/tulip/winbond-840.c
rename to drivers/net/ethernet/dec/tulip/winbond-840.c
index 862eadf071916553b9a99d6b376b3238db45afff..4d01219ba22ffaf11890d0686e49217db8b63749 100644 (file)
@@ -350,7 +350,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_stop               = netdev_close,
        .ndo_start_xmit         = start_tx,
        .ndo_get_stats          = get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_tx_timeout         = tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
diff --git a/drivers/net/ethernet/dlink/Kconfig b/drivers/net/ethernet/dlink/Kconfig
new file mode 100644 (file)
index 0000000..9fdb66b
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# D-Link device configuration
+#
+
+config NET_VENDOR_DLINK
+       bool "D-Link devices"
+       depends on PCI || PARPORT
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about D-Link devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_DLINK
+
+config DE600
+       tristate "D-Link DE600 pocket adapter support"
+       depends on PARPORT
+       ---help---
+         This is a network (Ethernet) device which attaches to your parallel
+         port. Read <file:Documentation/networking/DLINK.txt> as well as the
+         Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>, if you want to use
+         this. It is possible to have several devices share a single parallel
+         port and it is safe to compile the corresponding drivers into the
+         kernel.
+
+         To compile this driver as a module, choose M here: the module
+         will be called de600.
+
+config DE620
+       tristate "D-Link DE620 pocket adapter support"
+       depends on PARPORT
+       ---help---
+         This is a network (Ethernet) device which attaches to your parallel
+         port. Read <file:Documentation/networking/DLINK.txt> as well as the
+         Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>, if you want to use
+         this. It is possible to have several devices share a single parallel
+         port and it is safe to compile the corresponding drivers into the
+         kernel.
+
+         To compile this driver as a module, choose M here: the module
+         will be called de620.
+
+config DL2K
+       tristate "DL2000/TC902x-based Gigabit Ethernet support"
+       depends on PCI
+       select CRC32
+       ---help---
+         This driver supports DL2000/TC902x-based Gigabit ethernet cards,
+         which includes
+         D-Link DGE-550T Gigabit Ethernet Adapter.
+         D-Link DL2000-based Gigabit Ethernet Adapter.
+         Sundance/Tamarack TC902x Gigabit Ethernet Adapter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called dl2k.
+
+config SUNDANCE
+       tristate "Sundance Alta support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver is for the Sundance "Alta" chip.
+         More specific information and updates are available from
+         <http://www.scyld.com/network/sundance.html>.
+
+config SUNDANCE_MMIO
+       bool "Use MMIO instead of PIO"
+       depends on SUNDANCE
+       ---help---
+         Enable memory-mapped I/O for interaction with Sundance NIC registers.
+         Do NOT enable this by default, PIO (enabled when MMIO is disabled)
+         is known to solve bugs on certain chips.
+
+         If unsure, say N.
+
+endif # NET_VENDOR_DLINK
diff --git a/drivers/net/ethernet/dlink/Makefile b/drivers/net/ethernet/dlink/Makefile
new file mode 100644 (file)
index 0000000..c705eaa
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the D-Link network device drivers.
+#
+
+obj-$(CONFIG_DE600) += de600.o
+obj-$(CONFIG_DE620) += de620.o
+obj-$(CONFIG_DL2K) += dl2k.o
+obj-$(CONFIG_SUNDANCE) += sundance.o
similarity index 99%
rename from drivers/net/de620.c
rename to drivers/net/ethernet/dlink/de620.c
index 1c51a757611904dfbc5aa03c6c56113a5321496c..3b934ab784d39f4270ffc45025673921f84cb65e 100644 (file)
@@ -767,7 +767,7 @@ static const struct net_device_ops de620_netdev_ops = {
        .ndo_stop               = de620_close,
        .ndo_start_xmit         = de620_start_xmit,
        .ndo_tx_timeout         = de620_timeout,
-       .ndo_set_multicast_list = de620_set_multicast_list,
+       .ndo_set_rx_mode        = de620_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/dl2k.c
rename to drivers/net/ethernet/dlink/dl2k.c
index ed73e4a93508aa9a7ee4382f6e9ce290cee1062a..3fa91408532f92ffd54155d6d4ad43464fe09649 100644 (file)
@@ -92,7 +92,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_get_stats          = get_stats,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
-       .ndo_set_multicast_list = set_multicast,
+       .ndo_set_rx_mode        = set_multicast,
        .ndo_do_ioctl           = rio_ioctl,
        .ndo_tx_timeout         = rio_tx_timeout,
        .ndo_change_mtu         = change_mtu,
similarity index 99%
rename from drivers/net/sundance.c
rename to drivers/net/ethernet/dlink/sundance.c
index 4793df843c247794a285b2bd574653a9e46d6098..dcd7f7a71ad4aaddbd426b8098b83d2b0aa8d14e 100644 (file)
@@ -464,7 +464,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_stop               = netdev_close,
        .ndo_start_xmit         = start_tx,
        .ndo_get_stats          = get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_tx_timeout         = tx_timeout,
        .ndo_change_mtu         = change_mtu,
diff --git a/drivers/net/ethernet/emulex/Kconfig b/drivers/net/ethernet/emulex/Kconfig
new file mode 100644 (file)
index 0000000..018ac94
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Emulex driver configuration
+#
+
+config NET_VENDOR_EMULEX
+       bool "Emulex devices"
+       depends on PCI && INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Emulex cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_EMULEX
+
+source "drivers/net/ethernet/emulex/benet/Kconfig"
+
+endif # NET_VENDOR_EMULEX
diff --git a/drivers/net/ethernet/emulex/Makefile b/drivers/net/ethernet/emulex/Makefile
new file mode 100644 (file)
index 0000000..ea8ec57
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Emulex device drivers.
+#
+
+obj-$(CONFIG_BE2NET) += benet/
diff --git a/drivers/net/ethernet/emulex/benet/Kconfig b/drivers/net/ethernet/emulex/benet/Kconfig
new file mode 100644 (file)
index 0000000..804db04
--- /dev/null
@@ -0,0 +1,6 @@
+config BE2NET
+       tristate "ServerEngines' 10Gbps NIC - BladeEngine"
+       depends on PCI && INET
+       ---help---
+         This driver implements the NIC functionality for ServerEngines'
+         10Gbps network adapter - BladeEngine.
similarity index 85%
rename from drivers/net/benet/be.h
rename to drivers/net/ethernet/emulex/benet/be.h
index c85768cd1b1880871763e8c2786936ea52a57ccf..12b5b5168dca36a3b5153c635564bbb6aa32a615 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/u64_stats_sync.h>
 
 #include "be_hw.h"
 
@@ -167,15 +168,15 @@ struct be_mcc_obj {
 };
 
 struct be_tx_stats {
-       u32 be_tx_reqs;         /* number of TX requests initiated */
-       u32 be_tx_stops;        /* number of times TX Q was stopped */
-       u32 be_tx_wrbs;         /* number of tx WRBs used */
-       u32 be_tx_compl;        /* number of tx completion entries processed */
-       ulong be_tx_jiffies;
-       u64 be_tx_bytes;
-       u64 be_tx_bytes_prev;
-       u64 be_tx_pkts;
-       u32 be_tx_rate;
+       u64 tx_bytes;
+       u64 tx_pkts;
+       u64 tx_reqs;
+       u64 tx_wrbs;
+       u64 tx_compl;
+       ulong tx_jiffies;
+       u32 tx_stops;
+       struct u64_stats_sync sync;
+       struct u64_stats_sync sync_compl;
 };
 
 struct be_tx_obj {
@@ -195,22 +196,20 @@ struct be_rx_page_info {
 };
 
 struct be_rx_stats {
-       u32 rx_post_fail;/* number of ethrx buffer alloc failures */
-       u32 rx_polls;   /* number of times NAPI called poll function */
-       u32 rx_events;  /* number of ucast rx completion events  */
-       u32 rx_compl;   /* number of rx completion entries processed */
-       ulong rx_dropped; /* number of skb allocation errors */
-       ulong rx_jiffies;
        u64 rx_bytes;
-       u64 rx_bytes_prev;
        u64 rx_pkts;
-       u32 rx_rate;
+       u64 rx_pkts_prev;
+       ulong rx_jiffies;
+       u32 rx_drops_no_skbs;   /* skb allocation errors */
+       u32 rx_drops_no_frags;  /* HW has no fetched frags */
+       u32 rx_post_fail;       /* page post alloc failures */
+       u32 rx_polls;           /* NAPI calls */
+       u32 rx_events;
+       u32 rx_compl;
        u32 rx_mcast_pkts;
-       u32 rxcp_err;   /* Num rx completion entries w/ err set. */
-       ulong rx_fps_jiffies;   /* jiffies at last FPS calc */
-       u32 rx_frags;
-       u32 prev_rx_frags;
-       u32 rx_fps;             /* Rx frags per second */
+       u32 rx_compl_err;       /* completions with err set */
+       u32 rx_pps;             /* pkts per second */
+       struct u64_stats_sync sync;
 };
 
 struct be_rx_compl_info {
@@ -218,7 +217,7 @@ struct be_rx_compl_info {
        u16 vlan_tag;
        u16 pkt_size;
        u16 rxq_idx;
-       u16 mac_id;
+       u16 port;
        u8 vlanf;
        u8 num_rcvd;
        u8 err;
@@ -247,43 +246,40 @@ struct be_rx_obj {
 
 struct be_drv_stats {
        u8 be_on_die_temperature;
-       u64 be_tx_events;
-       u64 eth_red_drops;
-       u64 rx_drops_no_pbuf;
-       u64 rx_drops_no_txpb;
-       u64 rx_drops_no_erx_descr;
-       u64 rx_drops_no_tpre_descr;
-       u64 rx_drops_too_many_frags;
-       u64 rx_drops_invalid_ring;
-       u64 forwarded_packets;
-       u64 rx_drops_mtu;
-       u64 rx_crc_errors;
-       u64 rx_alignment_symbol_errors;
-       u64 rx_pause_frames;
-       u64 rx_priority_pause_frames;
-       u64 rx_control_frames;
-       u64 rx_in_range_errors;
-       u64 rx_out_range_errors;
-       u64 rx_frame_too_long;
-       u64 rx_address_match_errors;
-       u64 rx_dropped_too_small;
-       u64 rx_dropped_too_short;
-       u64 rx_dropped_header_too_small;
-       u64 rx_dropped_tcp_length;
-       u64 rx_dropped_runt;
-       u64 rx_ip_checksum_errs;
-       u64 rx_tcp_checksum_errs;
-       u64 rx_udp_checksum_errs;
-       u64 rx_switched_unicast_packets;
-       u64 rx_switched_multicast_packets;
-       u64 rx_switched_broadcast_packets;
-       u64 tx_pauseframes;
-       u64 tx_priority_pauseframes;
-       u64 tx_controlframes;
-       u64 rxpp_fifo_overflow_drop;
-       u64 rx_input_fifo_overflow_drop;
-       u64 pmem_fifo_overflow_drop;
-       u64 jabber_events;
+       u32 tx_events;
+       u32 eth_red_drops;
+       u32 rx_drops_no_pbuf;
+       u32 rx_drops_no_txpb;
+       u32 rx_drops_no_erx_descr;
+       u32 rx_drops_no_tpre_descr;
+       u32 rx_drops_too_many_frags;
+       u32 rx_drops_invalid_ring;
+       u32 forwarded_packets;
+       u32 rx_drops_mtu;
+       u32 rx_crc_errors;
+       u32 rx_alignment_symbol_errors;
+       u32 rx_pause_frames;
+       u32 rx_priority_pause_frames;
+       u32 rx_control_frames;
+       u32 rx_in_range_errors;
+       u32 rx_out_range_errors;
+       u32 rx_frame_too_long;
+       u32 rx_address_match_errors;
+       u32 rx_dropped_too_small;
+       u32 rx_dropped_too_short;
+       u32 rx_dropped_header_too_small;
+       u32 rx_dropped_tcp_length;
+       u32 rx_dropped_runt;
+       u32 rx_ip_checksum_errs;
+       u32 rx_tcp_checksum_errs;
+       u32 rx_udp_checksum_errs;
+       u32 tx_pauseframes;
+       u32 tx_priority_pauseframes;
+       u32 tx_controlframes;
+       u32 rxpp_fifo_overflow_drop;
+       u32 rx_input_fifo_overflow_drop;
+       u32 pmem_fifo_overflow_drop;
+       u32 jabber_events;
 };
 
 struct be_vf_cfg {
@@ -338,7 +334,7 @@ struct be_adapter {
        u8 vlan_tag[VLAN_N_VID];
        u8 vlan_prio_bmap;      /* Available Priority BitMap */
        u16 recommended_prio;   /* Recommended Priority */
-       struct be_dma_mem mc_cmd_mem;
+       struct be_dma_mem rx_filter; /* Cmd DMA mem for rx-filter */
 
        struct be_dma_mem stats_cmd;
        /* Work queue used to perform periodic tasks like getting statistics */
@@ -385,6 +381,8 @@ struct be_adapter {
 #define BE_GEN2 2
 #define BE_GEN3 3
 
+#define ON                             1
+#define OFF                            0
 #define lancer_chip(adapter)   ((adapter->pdev->device == OC_DEVICE_ID3) || \
                                 (adapter->pdev->device == OC_DEVICE_ID4))
 
@@ -525,8 +523,7 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter)
 
 extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
                u16 num_popped);
-extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
-extern void netdev_stats_update(struct be_adapter *adapter);
+extern void be_link_status_update(struct be_adapter *adapter, u32 link_status);
 extern void be_parse_stats(struct be_adapter *adapter);
 extern int be_load_fw(struct be_adapter *adapter, u8 *func);
 #endif                         /* BE_H */
similarity index 94%
rename from drivers/net/benet/be_cmds.c
rename to drivers/net/ethernet/emulex/benet/be_cmds.c
index 054fa67bc4e34ee3edaf2126492df416639c0d9d..bec039d27714260754bfd002de7930a55013e927 100644 (file)
@@ -82,28 +82,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
                if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
                         (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
                        (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
-                       if (adapter->generation == BE_GEN3) {
-                               if (lancer_chip(adapter)) {
-                                       struct lancer_cmd_resp_pport_stats
-                                               *resp = adapter->stats_cmd.va;
-                                       be_dws_le_to_cpu(&resp->pport_stats,
-                                               sizeof(resp->pport_stats));
-                               } else {
-                                       struct be_cmd_resp_get_stats_v1 *resp =
-                                                       adapter->stats_cmd.va;
-
-                               be_dws_le_to_cpu(&resp->hw_stats,
-                                                       sizeof(resp->hw_stats));
-                               }
-                       } else {
-                               struct be_cmd_resp_get_stats_v0 *resp =
-                                                       adapter->stats_cmd.va;
-
-                               be_dws_le_to_cpu(&resp->hw_stats,
-                                                       sizeof(resp->hw_stats));
-                       }
                        be_parse_stats(adapter);
-                       netdev_stats_update(adapter);
                        adapter->stats_cmd_sent = false;
                }
        } else {
@@ -131,8 +110,7 @@ done:
 static void be_async_link_state_process(struct be_adapter *adapter,
                struct be_async_event_link_state *evt)
 {
-       be_link_status_update(adapter,
-               evt->port_link_status == ASYNC_EVENT_LINK_UP);
+       be_link_status_update(adapter, evt->port_link_status);
 }
 
 /* Grp5 CoS Priority evt */
@@ -162,7 +140,7 @@ static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
                struct be_async_event_grp5_pvid_state *evt)
 {
        if (evt->enabled)
-               adapter->pvid = le16_to_cpu(evt->tag);
+               adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK;
        else
                adapter->pvid = 0;
 }
@@ -1282,8 +1260,8 @@ err:
 }
 
 /* Uses synchronous mcc */
-int be_cmd_link_status_query(struct be_adapter *adapter,
-                       bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom)
+int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
+                       u16 *link_speed, u32 dom)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_link_status *req;
@@ -1298,8 +1276,6 @@ int be_cmd_link_status_query(struct be_adapter *adapter,
        }
        req = embedded_payload(wrb);
 
-       *link_up = false;
-
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
                        OPCODE_COMMON_NTWK_LINK_STATUS_QUERY);
 
@@ -1310,7 +1286,6 @@ int be_cmd_link_status_query(struct be_adapter *adapter,
        if (!status) {
                struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
                if (resp->mac_speed != PHY_LINK_SPEED_ZERO) {
-                       *link_up = true;
                        *link_speed = le16_to_cpu(resp->link_speed);
                        *mac_speed = resp->mac_speed;
                }
@@ -1573,27 +1548,14 @@ err:
        return status;
 }
 
-/* Uses MCC for this command as it may be called in BH context
- * Uses synchronous mcc
- */
-int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
+int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
 {
        struct be_mcc_wrb *wrb;
-       struct be_cmd_req_rx_filter *req;
-       struct be_dma_mem promiscous_cmd;
+       struct be_dma_mem *mem = &adapter->rx_filter;
+       struct be_cmd_req_rx_filter *req = mem->va;
        struct be_sge *sge;
        int status;
 
-       memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem));
-       promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter);
-       promiscous_cmd.va = pci_alloc_consistent(adapter->pdev,
-                               promiscous_cmd.size, &promiscous_cmd.dma);
-       if (!promiscous_cmd.va) {
-               dev_err(&adapter->pdev->dev,
-                               "Memory allocation failure\n");
-               return -ENOMEM;
-       }
-
        spin_lock_bh(&adapter->mcc_lock);
 
        wrb = wrb_from_mccq(adapter);
@@ -1601,80 +1563,37 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
                status = -EBUSY;
                goto err;
        }
-
-       req = promiscous_cmd.va;
        sge = nonembedded_sgl(wrb);
-
-       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
-                                       OPCODE_COMMON_NTWK_RX_FILTER);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                       OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
-
-       req->if_id = cpu_to_le32(adapter->if_handle);
-       req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
-       if (en)
-               req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
-
-       sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma));
-       sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF);
-       sge->len = cpu_to_le32(promiscous_cmd.size);
-
-       status = be_mcc_notify_wait(adapter);
-
-err:
-       spin_unlock_bh(&adapter->mcc_lock);
-       pci_free_consistent(adapter->pdev, promiscous_cmd.size,
-                       promiscous_cmd.va, promiscous_cmd.dma);
-       return status;
-}
-
-/*
- * Uses MCC for this command as it may be called in BH context
- * (mc == NULL) => multicast promiscuous
- */
-int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-               struct net_device *netdev, struct be_dma_mem *mem)
-{
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_req_mcast_mac_config *req = mem->va;
-       struct be_sge *sge;
-       int status;
-
-       spin_lock_bh(&adapter->mcc_lock);
-
-       wrb = wrb_from_mccq(adapter);
-       if (!wrb) {
-               status = -EBUSY;
-               goto err;
-       }
-       sge = nonembedded_sgl(wrb);
-       memset(req, 0, sizeof(*req));
-
-       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
-                       OPCODE_COMMON_NTWK_MULTICAST_SET);
        sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
        sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
        sge->len = cpu_to_le32(mem->size);
+       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+                               OPCODE_COMMON_NTWK_RX_FILTER);
 
+       memset(req, 0, sizeof(*req));
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-               OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
+                               OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
 
-       req->interface_id = if_id;
-       if (netdev) {
-               int i;
+       req->if_id = cpu_to_le32(adapter->if_handle);
+       if (flags & IFF_PROMISC) {
+               req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
+                                       BE_IF_FLAGS_VLAN_PROMISCUOUS);
+               if (value == ON)
+                       req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
+                                       BE_IF_FLAGS_VLAN_PROMISCUOUS);
+       } else if (flags & IFF_ALLMULTI) {
+               req->if_flags_mask = req->if_flags =
+                       cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
+       } else {
                struct netdev_hw_addr *ha;
+               int i = 0;
 
-               req->num_mac = cpu_to_le16(netdev_mc_count(netdev));
-
-               i = 0;
-               netdev_for_each_mc_addr(ha, netdev)
-                       memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
-       } else {
-               req->promiscuous = 1;
+               req->mcast_num = cpu_to_le16(netdev_mc_count(adapter->netdev));
+               netdev_for_each_mc_addr(ha, adapter->netdev)
+                       memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
        }
 
        status = be_mcc_notify_wait(adapter);
-
 err:
        spin_unlock_bh(&adapter->mcc_lock);
        return status;
@@ -2268,11 +2187,13 @@ err:
        return status;
 }
 
-int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd)
+int be_cmd_get_phy_info(struct be_adapter *adapter,
+                               struct be_phy_info *phy_info)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_get_phy_info *req;
        struct be_sge *sge;
+       struct be_dma_mem cmd;
        int status;
 
        spin_lock_bh(&adapter->mcc_lock);
@@ -2282,8 +2203,16 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd)
                status = -EBUSY;
                goto err;
        }
+       cmd.size = sizeof(struct be_cmd_req_get_phy_info);
+       cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
+                                       &cmd.dma);
+       if (!cmd.va) {
+               dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
+               status = -ENOMEM;
+               goto err;
+       }
 
-       req = cmd->va;
+       req = cmd.va;
        sge = nonembedded_sgl(wrb);
 
        be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
@@ -2293,11 +2222,20 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd)
                        OPCODE_COMMON_GET_PHY_DETAILS,
                        sizeof(*req));
 
-       sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma));
-       sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF);
-       sge->len = cpu_to_le32(cmd->size);
+       sge->pa_hi = cpu_to_le32(upper_32_bits(cmd.dma));
+       sge->pa_lo = cpu_to_le32(cmd.dma & 0xFFFFFFFF);
+       sge->len = cpu_to_le32(cmd.size);
 
        status = be_mcc_notify_wait(adapter);
+       if (!status) {
+               struct be_phy_info *resp_phy_info =
+                               cmd.va + sizeof(struct be_cmd_req_hdr);
+               phy_info->phy_type = le16_to_cpu(resp_phy_info->phy_type);
+               phy_info->interface_type =
+                       le16_to_cpu(resp_phy_info->interface_type);
+       }
+       pci_free_consistent(adapter->pdev, cmd.size,
+                               cmd.va, cmd.dma);
 err:
        spin_unlock_bh(&adapter->mcc_lock);
        return status;
similarity index 95%
rename from drivers/net/benet/be_cmds.h
rename to drivers/net/ethernet/emulex/benet/be_cmds.h
index 8e4d48824fe9c65193ac524b293b55d7f15ad38a..b61eac7ece3569b96a415d49ab93f3ad640e8d71 100644 (file)
@@ -89,9 +89,10 @@ struct be_async_event_trailer {
 };
 
 enum {
-       ASYNC_EVENT_LINK_DOWN   = 0x0,
-       ASYNC_EVENT_LINK_UP     = 0x1
+       LINK_DOWN       = 0x0,
+       LINK_UP         = 0x1
 };
+#define LINK_STATUS_MASK                       0x1
 
 /* When the event code of an async trailer is link-state, the mcc_compl
  * must be interpreted as follows
@@ -693,8 +694,7 @@ struct be_cmd_resp_get_stats_v0 {
        struct be_hw_stats_v0 hw_stats;
 };
 
-#define make_64bit_val(hi_32, lo_32)   (((u64)hi_32<<32) | lo_32)
-struct lancer_cmd_pport_stats {
+struct lancer_pport_stats {
        u32 tx_packets_lo;
        u32 tx_packets_hi;
        u32 tx_unicast_packets_lo;
@@ -871,16 +871,16 @@ struct lancer_cmd_req_pport_stats {
        struct be_cmd_req_hdr hdr;
        union {
                struct pport_stats_params params;
-               u8 rsvd[sizeof(struct lancer_cmd_pport_stats)];
+               u8 rsvd[sizeof(struct lancer_pport_stats)];
        } cmd_params;
 };
 
 struct lancer_cmd_resp_pport_stats {
        struct be_cmd_resp_hdr hdr;
-       struct lancer_cmd_pport_stats pport_stats;
+       struct lancer_pport_stats pport_stats;
 };
 
-static inline  struct lancer_cmd_pport_stats*
+static inline struct lancer_pport_stats*
        pport_stats_from_cmd(struct be_adapter *adapter)
 {
        struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va;
@@ -910,21 +910,12 @@ struct be_cmd_req_vlan_config {
        u16 normal_vlan[64];
 } __packed;
 
-/******************** Multicast MAC Config *******************/
+/******************* RX FILTER ******************************/
 #define BE_MAX_MC              64 /* set mcast promisc if > 64 */
 struct macaddr {
        u8 byte[ETH_ALEN];
 };
 
-struct be_cmd_req_mcast_mac_config {
-       struct be_cmd_req_hdr hdr;
-       u16 num_mac;
-       u8 promiscuous;
-       u8 interface_id;
-       struct macaddr mac[BE_MAX_MC];
-} __packed;
-
-/******************* RX FILTER ******************************/
 struct be_cmd_req_rx_filter {
        struct be_cmd_req_hdr hdr;
        u32 global_flags_mask;
@@ -932,11 +923,10 @@ struct be_cmd_req_rx_filter {
        u32 if_flags_mask;
        u32 if_flags;
        u32 if_id;
-       u32 multicast_num;
-       struct macaddr mac[BE_MAX_MC];
+       u32 mcast_num;
+       struct macaddr mcast_mac[BE_MAX_MC];
 };
 
-
 /******************** Link Status Query *******************/
 struct be_cmd_req_link_status {
        struct be_cmd_req_hdr hdr;
@@ -1254,14 +1244,19 @@ struct be_cmd_req_get_phy_info {
        struct be_cmd_req_hdr hdr;
        u8 rsvd0[24];
 };
-struct be_cmd_resp_get_phy_info {
-       struct be_cmd_req_hdr hdr;
+
+struct be_phy_info {
        u16 phy_type;
        u16 interface_type;
        u32 misc_params;
        u32 future_use[4];
 };
 
+struct be_cmd_resp_get_phy_info {
+       struct be_cmd_req_hdr hdr;
+       struct be_phy_info phy_info;
+};
+
 /*********************** Set QOS ***********************/
 
 #define BE_QOS_BITS_NIC                                1
@@ -1383,8 +1378,7 @@ struct be_cmd_resp_get_stats_v1 {
        struct be_hw_stats_v1 hw_stats;
 };
 
-static inline void *
-hw_stats_from_cmd(struct be_adapter *adapter)
+static inline void *hw_stats_from_cmd(struct be_adapter *adapter)
 {
        if (adapter->generation == BE_GEN3) {
                struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va;
@@ -1397,34 +1391,6 @@ hw_stats_from_cmd(struct be_adapter *adapter)
        }
 }
 
-static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter)
-{
-       if (adapter->generation == BE_GEN3) {
-               struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
-               struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
-
-               return &rxf_stats->port[adapter->port_num];
-       } else {
-               struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
-               struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
-
-               return &rxf_stats->port[adapter->port_num];
-       }
-}
-
-static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter)
-{
-       if (adapter->generation == BE_GEN3) {
-               struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
-
-               return &hw_stats->rxf;
-       } else {
-               struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
-
-               return &hw_stats->rxf;
-       }
-}
-
 static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
 {
        if (adapter->generation == BE_GEN3) {
@@ -1438,19 +1404,6 @@ static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
        }
 }
 
-static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter)
-{
-       if (adapter->generation == BE_GEN3) {
-               struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
-
-               return &hw_stats->pmem;
-       } else {
-               struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
-
-               return &hw_stats->pmem;
-       }
-}
-
 extern int be_pci_fnum_get(struct be_adapter *adapter);
 extern int be_cmd_POST(struct be_adapter *adapter);
 extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -1485,7 +1438,7 @@ extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
                        struct be_queue_info *q);
 extern int be_cmd_link_status_query(struct be_adapter *adapter,
-                       bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom);
+                       u8 *mac_speed, u16 *link_speed, u32 dom);
 extern int be_cmd_reset(struct be_adapter *adapter);
 extern int be_cmd_get_stats(struct be_adapter *adapter,
                        struct be_dma_mem *nonemb_cmd);
@@ -1497,9 +1450,7 @@ extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
 extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
                        u16 *vtag_array, u32 num, bool untagged,
                        bool promiscuous);
-extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en);
-extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
-                       struct net_device *netdev, struct be_dma_mem *mem);
+extern int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status);
 extern int be_cmd_set_flow_control(struct be_adapter *adapter,
                        u32 tx_fc, u32 rx_fc);
 extern int be_cmd_get_flow_control(struct be_adapter *adapter,
@@ -1540,7 +1491,7 @@ extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
 extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
                                u8 loopback_type, u8 enable);
 extern int be_cmd_get_phy_info(struct be_adapter *adapter,
-               struct be_dma_mem *cmd);
+                               struct be_phy_info *phy_info);
 extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
 extern void be_detect_dump_ue(struct be_adapter *adapter);
 extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
similarity index 85%
rename from drivers/net/benet/be_ethtool.c
rename to drivers/net/ethernet/emulex/benet/be_ethtool.c
index 7fd8130d86ea7b51b076fda3f293df467bd26548..f144a6f998624503be1fb21b8045f64cd701775e 100644 (file)
@@ -26,33 +26,18 @@ struct be_ethtool_stat {
        int offset;
 };
 
-enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
-                       DRVSTAT};
+enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
 #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
                                        offsetof(_struct, field)
-#define NETSTAT_INFO(field)    #field, NETSTAT,\
-                                       FIELDINFO(struct net_device_stats,\
-                                               field)
 #define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\
                                        FIELDINFO(struct be_tx_stats, field)
 #define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\
                                        FIELDINFO(struct be_rx_stats, field)
-#define ERXSTAT_INFO(field)    #field, ERXSTAT,\
-                                       FIELDINFO(struct be_erx_stats_v1, field)
 #define        DRVSTAT_INFO(field)     #field, DRVSTAT,\
-                                       FIELDINFO(struct be_drv_stats, \
-                                               field)
+                                       FIELDINFO(struct be_drv_stats, field)
 
 static const struct be_ethtool_stat et_stats[] = {
-       {NETSTAT_INFO(rx_packets)},
-       {NETSTAT_INFO(tx_packets)},
-       {NETSTAT_INFO(rx_bytes)},
-       {NETSTAT_INFO(tx_bytes)},
-       {NETSTAT_INFO(rx_errors)},
-       {NETSTAT_INFO(tx_errors)},
-       {NETSTAT_INFO(rx_dropped)},
-       {NETSTAT_INFO(tx_dropped)},
-       {DRVSTAT_INFO(be_tx_events)},
+       {DRVSTAT_INFO(tx_events)},
        {DRVSTAT_INFO(rx_crc_errors)},
        {DRVSTAT_INFO(rx_alignment_symbol_errors)},
        {DRVSTAT_INFO(rx_pause_frames)},
@@ -71,9 +56,6 @@ static const struct be_ethtool_stat et_stats[] = {
        {DRVSTAT_INFO(rx_ip_checksum_errs)},
        {DRVSTAT_INFO(rx_tcp_checksum_errs)},
        {DRVSTAT_INFO(rx_udp_checksum_errs)},
-       {DRVSTAT_INFO(rx_switched_unicast_packets)},
-       {DRVSTAT_INFO(rx_switched_multicast_packets)},
-       {DRVSTAT_INFO(rx_switched_broadcast_packets)},
        {DRVSTAT_INFO(tx_pauseframes)},
        {DRVSTAT_INFO(tx_controlframes)},
        {DRVSTAT_INFO(rx_priority_pause_frames)},
@@ -92,28 +74,33 @@ static const struct be_ethtool_stat et_stats[] = {
 };
 #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
 
-/* Stats related to multi RX queues */
+/* Stats related to multi RX queues: get_stats routine assumes bytes, pkts
+ * are first and second members respectively.
+ */
 static const struct be_ethtool_stat et_rx_stats[] = {
-       {DRVSTAT_RX_INFO(rx_bytes)},
-       {DRVSTAT_RX_INFO(rx_pkts)},
-       {DRVSTAT_RX_INFO(rx_rate)},
+       {DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */
+       {DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */
        {DRVSTAT_RX_INFO(rx_polls)},
        {DRVSTAT_RX_INFO(rx_events)},
        {DRVSTAT_RX_INFO(rx_compl)},
        {DRVSTAT_RX_INFO(rx_mcast_pkts)},
        {DRVSTAT_RX_INFO(rx_post_fail)},
-       {DRVSTAT_RX_INFO(rx_dropped)},
-       {ERXSTAT_INFO(rx_drops_no_fragments)}
+       {DRVSTAT_RX_INFO(rx_drops_no_skbs)},
+       {DRVSTAT_RX_INFO(rx_drops_no_frags)}
 };
 #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
 
-/* Stats related to multi TX queues */
+/* Stats related to multi TX queues: get_stats routine assumes compl is the
+ * first member
+ */
 static const struct be_ethtool_stat et_tx_stats[] = {
-       {DRVSTAT_TX_INFO(be_tx_rate)},
-       {DRVSTAT_TX_INFO(be_tx_reqs)},
-       {DRVSTAT_TX_INFO(be_tx_wrbs)},
-       {DRVSTAT_TX_INFO(be_tx_stops)},
-       {DRVSTAT_TX_INFO(be_tx_compl)}
+       {DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
+       {DRVSTAT_TX_INFO(tx_bytes)},
+       {DRVSTAT_TX_INFO(tx_pkts)},
+       {DRVSTAT_TX_INFO(tx_reqs)},
+       {DRVSTAT_TX_INFO(tx_wrbs)},
+       {DRVSTAT_TX_INFO(tx_compl)},
+       {DRVSTAT_TX_INFO(tx_stops)}
 };
 #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
 
@@ -260,50 +247,49 @@ be_get_ethtool_stats(struct net_device *netdev,
        struct be_adapter *adapter = netdev_priv(netdev);
        struct be_rx_obj *rxo;
        struct be_tx_obj *txo;
-       void *p = NULL;
-       int i, j, base;
+       void *p;
+       unsigned int i, j, base = 0, start;
 
        for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
-               switch (et_stats[i].type) {
-               case NETSTAT:
-                       p = &netdev->stats;
-                       break;
-               case DRVSTAT:
-                       p = &adapter->drv_stats;
-                       break;
-               }
-
-               p = (u8 *)p + et_stats[i].offset;
-               data[i] = (et_stats[i].size == sizeof(u64)) ?
-                               *(u64 *)p: *(u32 *)p;
+               p = (u8 *)&adapter->drv_stats + et_stats[i].offset;
+               data[i] = *(u32 *)p;
        }
+       base += ETHTOOL_STATS_NUM;
 
-       base = ETHTOOL_STATS_NUM;
        for_all_rx_queues(adapter, rxo, j) {
-               for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) {
-                       switch (et_rx_stats[i].type) {
-                       case DRVSTAT_RX:
-                               p = (u8 *)&rxo->stats + et_rx_stats[i].offset;
-                               break;
-                       case ERXSTAT:
-                               p = (u32 *)be_erx_stats_from_cmd(adapter) +
-                                                               rxo->q.id;
-                               break;
-                       }
-                       data[base + j * ETHTOOL_RXSTATS_NUM + i] =
-                               (et_rx_stats[i].size == sizeof(u64)) ?
-                                       *(u64 *)p: *(u32 *)p;
+               struct be_rx_stats *stats = rx_stats(rxo);
+
+               do {
+                       start = u64_stats_fetch_begin_bh(&stats->sync);
+                       data[base] = stats->rx_bytes;
+                       data[base + 1] = stats->rx_pkts;
+               } while (u64_stats_fetch_retry_bh(&stats->sync, start));
+
+               for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) {
+                       p = (u8 *)stats + et_rx_stats[i].offset;
+                       data[base + i] = *(u32 *)p;
                }
+               base += ETHTOOL_RXSTATS_NUM;
        }
 
-       base = ETHTOOL_STATS_NUM + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM;
        for_all_tx_queues(adapter, txo, j) {
-               for (i = 0; i < ETHTOOL_TXSTATS_NUM; i++) {
-                       p = (u8 *)&txo->stats + et_tx_stats[i].offset;
-                       data[base + j * ETHTOOL_TXSTATS_NUM + i] =
-                               (et_tx_stats[i].size == sizeof(u64)) ?
-                                       *(u64 *)p: *(u32 *)p;
-               }
+               struct be_tx_stats *stats = tx_stats(txo);
+
+               do {
+                       start = u64_stats_fetch_begin_bh(&stats->sync_compl);
+                       data[base] = stats->tx_compl;
+               } while (u64_stats_fetch_retry_bh(&stats->sync_compl, start));
+
+               do {
+                       start = u64_stats_fetch_begin_bh(&stats->sync);
+                       for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) {
+                               p = (u8 *)stats + et_tx_stats[i].offset;
+                               data[base + i] =
+                                       (et_tx_stats[i].size == sizeof(u64)) ?
+                                               *(u64 *)p : *(u32 *)p;
+                       }
+               } while (u64_stats_fetch_retry_bh(&stats->sync, start));
+               base += ETHTOOL_TXSTATS_NUM;
        }
 }
 
@@ -363,19 +349,15 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
 static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
-       struct be_dma_mem phy_cmd;
-       struct be_cmd_resp_get_phy_info *resp;
+       struct be_phy_info phy_info;
        u8 mac_speed = 0;
        u16 link_speed = 0;
-       bool link_up = false;
        int status;
-       u16 intf_type;
 
        if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
-               status = be_cmd_link_status_query(adapter, &link_up,
-                                               &mac_speed, &link_speed, 0);
+               status = be_cmd_link_status_query(adapter, &mac_speed,
+                                               &link_speed, 0);
 
-               be_link_status_update(adapter, link_up);
                /* link_speed is in units of 10 Mbps */
                if (link_speed) {
                        ethtool_cmd_speed_set(ecmd, link_speed*10);
@@ -399,20 +381,9 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                        }
                }
 
-               phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info);
-               phy_cmd.va = dma_alloc_coherent(&adapter->pdev->dev,
-                                               phy_cmd.size, &phy_cmd.dma,
-                                               GFP_KERNEL);
-               if (!phy_cmd.va) {
-                       dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
-                       return -ENOMEM;
-               }
-               status = be_cmd_get_phy_info(adapter, &phy_cmd);
+               status = be_cmd_get_phy_info(adapter, &phy_info);
                if (!status) {
-                       resp = phy_cmd.va;
-                       intf_type = le16_to_cpu(resp->interface_type);
-
-                       switch (intf_type) {
+                       switch (phy_info.interface_type) {
                        case PHY_TYPE_XFP_10GB:
                        case PHY_TYPE_SFP_1GB:
                        case PHY_TYPE_SFP_PLUS_10GB:
@@ -423,7 +394,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                                break;
                        }
 
-                       switch (intf_type) {
+                       switch (phy_info.interface_type) {
                        case PHY_TYPE_KR_10GB:
                        case PHY_TYPE_KX4_10GB:
                                ecmd->autoneg = AUTONEG_ENABLE;
@@ -441,8 +412,6 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                adapter->port_type = ecmd->port;
                adapter->transceiver = ecmd->transceiver;
                adapter->autoneg = ecmd->autoneg;
-               dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va,
-                                 phy_cmd.dma);
        } else {
                ethtool_cmd_speed_set(ecmd, adapter->link_speed);
                ecmd->port = adapter->port_type;
@@ -631,7 +600,6 @@ static void
 be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
-       bool link_up;
        u8 mac_speed = 0;
        u16 qos_link_speed = 0;
 
@@ -657,7 +625,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
                test->flags |= ETH_TEST_FL_FAILED;
        }
 
-       if (be_cmd_link_status_query(adapter, &link_up, &mac_speed,
+       if (be_cmd_link_status_query(adapter, &mac_speed,
                                &qos_link_speed, 0) != 0) {
                test->flags |= ETH_TEST_FL_FAILED;
                data[4] = -1;
similarity index 94%
rename from drivers/net/benet/be_hw.h
rename to drivers/net/ethernet/emulex/benet/be_hw.h
index 53d658afea2af48a958c0357f6ad51e0a5c7dbde..fbc8a915519e57aa36bb2f01f781475a5530ada1 100644 (file)
 #define IMG_TYPE_FCOE_FW_ACTIVE                10
 #define IMG_TYPE_FCOE_FW_BACKUP        11
 #define IMG_TYPE_NCSI_FW               13
+#define IMG_TYPE_PHY_FW                        99
+#define TN_8022                                13
 
+#define ILLEGAL_IOCTL_REQ              2
+#define FLASHROM_OPER_PHY_FLASH                9
+#define FLASHROM_OPER_PHY_SAVE         10
 #define FLASHROM_OPER_FLASH            1
 #define FLASHROM_OPER_SAVE             2
 #define FLASHROM_OPER_REPORT           4
 
-#define FLASH_IMAGE_MAX_SIZE_g2            (1310720) /* Max firmware image sz */
-#define FLASH_BIOS_IMAGE_MAX_SIZE_g2       (262144)  /* Max OPTION ROM img sz */
-#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2          (262144)  /* Max Redboot image sz */
-#define FLASH_IMAGE_MAX_SIZE_g3            (2097152) /* Max fw image size */
-#define FLASH_BIOS_IMAGE_MAX_SIZE_g3       (524288)  /* Max OPTION ROM img sz */
-#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3          (1048576)  /* Max Redboot image sz */
-#define FLASH_NCSI_IMAGE_MAX_SIZE_g3       (262144)  /* Max NSCI image sz */
+#define FLASH_IMAGE_MAX_SIZE_g2                (1310720) /* Max firmware image size */
+#define FLASH_BIOS_IMAGE_MAX_SIZE_g2   (262144)  /* Max OPTION ROM image sz */
+#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2        (262144)  /* Max Redboot image sz    */
+#define FLASH_IMAGE_MAX_SIZE_g3                (2097152) /* Max firmware image size */
+#define FLASH_BIOS_IMAGE_MAX_SIZE_g3   (524288)  /* Max OPTION ROM image sz */
+#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3        (1048576)  /* Max Redboot image sz    */
+#define FLASH_NCSI_IMAGE_MAX_SIZE_g3   (262144)
+#define FLASH_PHY_FW_IMAGE_MAX_SIZE_g3 262144
 
 #define FLASH_NCSI_MAGIC               (0x16032009)
 #define FLASH_NCSI_DISABLED            (0)
 #define FLASH_PXE_BIOS_START_g3            (13107200)
 #define FLASH_FCoE_BIOS_START_g3           (13631488)
 #define FLASH_REDBOOT_START_g3             (262144)
+#define FLASH_PHY_FW_START_g3             1310720
 
 /************* Rx Packet Type Encoding **************/
 #define BE_UNICAST_PACKET              0
similarity index 91%
rename from drivers/net/benet/be_main.c
rename to drivers/net/ethernet/emulex/benet/be_main.c
index c411bb1845fdd3601ec3787e96cd9bbe29447314..ef62594a19cdd5cf837c60ca4aa533af6c324667 100644 (file)
@@ -245,14 +245,14 @@ netdev_addr:
 
 static void populate_be2_stats(struct be_adapter *adapter)
 {
-
-       struct be_drv_stats *drvs = &adapter->drv_stats;
-       struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+       struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+       struct be_pmem_stats *pmem_sts = &hw_stats->pmem;
+       struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
        struct be_port_rxf_stats_v0 *port_stats =
-               be_port_rxf_stats_from_cmd(adapter);
-       struct be_rxf_stats_v0 *rxf_stats =
-               be_rxf_stats_from_cmd(adapter);
+                                       &rxf_stats->port[adapter->port_num];
+       struct be_drv_stats *drvs = &adapter->drv_stats;
 
+       be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats));
        drvs->rx_pause_frames = port_stats->rx_pause_frames;
        drvs->rx_crc_errors = port_stats->rx_crc_errors;
        drvs->rx_control_frames = port_stats->rx_control_frames;
@@ -267,12 +267,10 @@ static void populate_be2_stats(struct be_adapter *adapter)
        drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
        drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
        drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
-       drvs->rx_input_fifo_overflow_drop =
-               port_stats->rx_input_fifo_overflow;
+       drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow;
        drvs->rx_dropped_header_too_small =
                port_stats->rx_dropped_header_too_small;
-       drvs->rx_address_match_errors =
-               port_stats->rx_address_match_errors;
+       drvs->rx_address_match_errors = port_stats->rx_address_match_errors;
        drvs->rx_alignment_symbol_errors =
                port_stats->rx_alignment_symbol_errors;
 
@@ -280,36 +278,30 @@ static void populate_be2_stats(struct be_adapter *adapter)
        drvs->tx_controlframes = port_stats->tx_controlframes;
 
        if (adapter->port_num)
-               drvs->jabber_events =
-                       rxf_stats->port1_jabber_events;
+               drvs->jabber_events = rxf_stats->port1_jabber_events;
        else
-               drvs->jabber_events =
-                       rxf_stats->port0_jabber_events;
+               drvs->jabber_events = rxf_stats->port0_jabber_events;
        drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
        drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
        drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
        drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
        drvs->forwarded_packets = rxf_stats->forwarded_packets;
        drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
-       drvs->rx_drops_no_tpre_descr =
-               rxf_stats->rx_drops_no_tpre_descr;
-       drvs->rx_drops_too_many_frags =
-               rxf_stats->rx_drops_too_many_frags;
+       drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
+       drvs->rx_drops_too_many_frags = rxf_stats->rx_drops_too_many_frags;
        adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
 }
 
 static void populate_be3_stats(struct be_adapter *adapter)
 {
-       struct be_drv_stats *drvs = &adapter->drv_stats;
-       struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
-
-       struct be_rxf_stats_v1 *rxf_stats =
-               be_rxf_stats_from_cmd(adapter);
+       struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+       struct be_pmem_stats *pmem_sts = &hw_stats->pmem;
+       struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
        struct be_port_rxf_stats_v1 *port_stats =
-               be_port_rxf_stats_from_cmd(adapter);
+                                       &rxf_stats->port[adapter->port_num];
+       struct be_drv_stats *drvs = &adapter->drv_stats;
 
-       drvs->rx_priority_pause_frames = 0;
-       drvs->pmem_fifo_overflow_drop = 0;
+       be_dws_le_to_cpu(hw_stats, sizeof(*hw_stats));
        drvs->rx_pause_frames = port_stats->rx_pause_frames;
        drvs->rx_crc_errors = port_stats->rx_crc_errors;
        drvs->rx_control_frames = port_stats->rx_control_frames;
@@ -327,12 +319,10 @@ static void populate_be3_stats(struct be_adapter *adapter)
                port_stats->rx_dropped_header_too_small;
        drvs->rx_input_fifo_overflow_drop =
                port_stats->rx_input_fifo_overflow_drop;
-       drvs->rx_address_match_errors =
-               port_stats->rx_address_match_errors;
+       drvs->rx_address_match_errors = port_stats->rx_address_match_errors;
        drvs->rx_alignment_symbol_errors =
                port_stats->rx_alignment_symbol_errors;
-       drvs->rxpp_fifo_overflow_drop =
-               port_stats->rxpp_fifo_overflow_drop;
+       drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop;
        drvs->tx_pauseframes = port_stats->tx_pauseframes;
        drvs->tx_controlframes = port_stats->tx_controlframes;
        drvs->jabber_events = port_stats->jabber_events;
@@ -342,10 +332,8 @@ static void populate_be3_stats(struct be_adapter *adapter)
        drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
        drvs->forwarded_packets = rxf_stats->forwarded_packets;
        drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
-       drvs->rx_drops_no_tpre_descr =
-               rxf_stats->rx_drops_no_tpre_descr;
-       drvs->rx_drops_too_many_frags =
-               rxf_stats->rx_drops_too_many_frags;
+       drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
+       drvs->rx_drops_too_many_frags = rxf_stats->rx_drops_too_many_frags;
        adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
 }
 
@@ -353,22 +341,15 @@ static void populate_lancer_stats(struct be_adapter *adapter)
 {
 
        struct be_drv_stats *drvs = &adapter->drv_stats;
-       struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd
-                                               (adapter);
-       drvs->rx_priority_pause_frames = 0;
-       drvs->pmem_fifo_overflow_drop = 0;
-       drvs->rx_pause_frames =
-               make_64bit_val(pport_stats->rx_pause_frames_hi,
-                                pport_stats->rx_pause_frames_lo);
-       drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi,
-                                               pport_stats->rx_crc_errors_lo);
-       drvs->rx_control_frames =
-                       make_64bit_val(pport_stats->rx_control_frames_hi,
-                       pport_stats->rx_control_frames_lo);
+       struct lancer_pport_stats *pport_stats =
+                                       pport_stats_from_cmd(adapter);
+
+       be_dws_le_to_cpu(pport_stats, sizeof(*pport_stats));
+       drvs->rx_pause_frames = pport_stats->rx_pause_frames_lo;
+       drvs->rx_crc_errors = pport_stats->rx_crc_errors_lo;
+       drvs->rx_control_frames = pport_stats->rx_control_frames_lo;
        drvs->rx_in_range_errors = pport_stats->rx_in_range_errors;
-       drvs->rx_frame_too_long =
-               make_64bit_val(pport_stats->rx_internal_mac_errors_hi,
-                                       pport_stats->rx_frames_too_long_lo);
+       drvs->rx_frame_too_long = pport_stats->rx_frames_too_long_lo;
        drvs->rx_dropped_runt = pport_stats->rx_dropped_runt;
        drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors;
        drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors;
@@ -382,32 +363,24 @@ static void populate_lancer_stats(struct be_adapter *adapter)
                                pport_stats->rx_dropped_header_too_small;
        drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
        drvs->rx_address_match_errors = pport_stats->rx_address_match_errors;
-       drvs->rx_alignment_symbol_errors =
-               make_64bit_val(pport_stats->rx_symbol_errors_hi,
-                               pport_stats->rx_symbol_errors_lo);
+       drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo;
        drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
-       drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi,
-                                       pport_stats->tx_pause_frames_lo);
-       drvs->tx_controlframes =
-               make_64bit_val(pport_stats->tx_control_frames_hi,
-                               pport_stats->tx_control_frames_lo);
+       drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo;
+       drvs->tx_controlframes = pport_stats->tx_control_frames_lo;
        drvs->jabber_events = pport_stats->rx_jabbers;
-       drvs->rx_drops_no_pbuf = 0;
-       drvs->rx_drops_no_txpb = 0;
-       drvs->rx_drops_no_erx_descr = 0;
        drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue;
-       drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi,
-                                               pport_stats->num_forwards_lo);
-       drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi,
-                                               pport_stats->rx_drops_mtu_lo);
-       drvs->rx_drops_no_tpre_descr = 0;
+       drvs->forwarded_packets = pport_stats->num_forwards_lo;
+       drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo;
        drvs->rx_drops_too_many_frags =
-               make_64bit_val(pport_stats->rx_drops_too_many_frags_hi,
-                               pport_stats->rx_drops_too_many_frags_lo);
+                               pport_stats->rx_drops_too_many_frags_lo;
 }
 
 void be_parse_stats(struct be_adapter *adapter)
 {
+       struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter);
+       struct be_rx_obj *rxo;
+       int i;
+
        if (adapter->generation == BE_GEN3) {
                if (lancer_chip(adapter))
                        populate_lancer_stats(adapter);
@@ -416,50 +389,51 @@ void be_parse_stats(struct be_adapter *adapter)
        } else {
                populate_be2_stats(adapter);
        }
+
+       /* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
+       for_all_rx_queues(adapter, rxo, i)
+               rx_stats(rxo)->rx_drops_no_frags =
+                       erx->rx_drops_no_fragments[rxo->q.id];
 }
 
-void netdev_stats_update(struct be_adapter *adapter)
+static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
+                                       struct rtnl_link_stats64 *stats)
 {
+       struct be_adapter *adapter = netdev_priv(netdev);
        struct be_drv_stats *drvs = &adapter->drv_stats;
-       struct net_device_stats *dev_stats = &adapter->netdev->stats;
        struct be_rx_obj *rxo;
        struct be_tx_obj *txo;
-       unsigned long pkts = 0, bytes = 0, mcast = 0, drops = 0;
+       u64 pkts, bytes;
+       unsigned int start;
        int i;
 
        for_all_rx_queues(adapter, rxo, i) {
-               pkts += rx_stats(rxo)->rx_pkts;
-               bytes += rx_stats(rxo)->rx_bytes;
-               mcast += rx_stats(rxo)->rx_mcast_pkts;
-               drops += rx_stats(rxo)->rx_dropped;
-               /*  no space in linux buffers: best possible approximation */
-               if (adapter->generation == BE_GEN3) {
-                       if (!(lancer_chip(adapter))) {
-                               struct be_erx_stats_v1 *erx =
-                                       be_erx_stats_from_cmd(adapter);
-                               drops += erx->rx_drops_no_fragments[rxo->q.id];
-                       }
-               } else {
-                       struct be_erx_stats_v0 *erx =
-                                       be_erx_stats_from_cmd(adapter);
-                       drops += erx->rx_drops_no_fragments[rxo->q.id];
-               }
+               const struct be_rx_stats *rx_stats = rx_stats(rxo);
+               do {
+                       start = u64_stats_fetch_begin_bh(&rx_stats->sync);
+                       pkts = rx_stats(rxo)->rx_pkts;
+                       bytes = rx_stats(rxo)->rx_bytes;
+               } while (u64_stats_fetch_retry_bh(&rx_stats->sync, start));
+               stats->rx_packets += pkts;
+               stats->rx_bytes += bytes;
+               stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
+               stats->rx_dropped += rx_stats(rxo)->rx_drops_no_skbs +
+                                       rx_stats(rxo)->rx_drops_no_frags;
        }
-       dev_stats->rx_packets = pkts;
-       dev_stats->rx_bytes = bytes;
-       dev_stats->multicast = mcast;
-       dev_stats->rx_dropped = drops;
 
-       pkts = bytes = 0;
        for_all_tx_queues(adapter, txo, i) {
-               pkts += tx_stats(txo)->be_tx_pkts;
-               bytes += tx_stats(txo)->be_tx_bytes;
+               const struct be_tx_stats *tx_stats = tx_stats(txo);
+               do {
+                       start = u64_stats_fetch_begin_bh(&tx_stats->sync);
+                       pkts = tx_stats(txo)->tx_pkts;
+                       bytes = tx_stats(txo)->tx_bytes;
+               } while (u64_stats_fetch_retry_bh(&tx_stats->sync, start));
+               stats->tx_packets += pkts;
+               stats->tx_bytes += bytes;
        }
-       dev_stats->tx_packets = pkts;
-       dev_stats->tx_bytes = bytes;
 
        /* bad pkts received */
-       dev_stats->rx_errors = drvs->rx_crc_errors +
+       stats->rx_errors = drvs->rx_crc_errors +
                drvs->rx_alignment_symbol_errors +
                drvs->rx_in_range_errors +
                drvs->rx_out_range_errors +
@@ -468,115 +442,38 @@ void netdev_stats_update(struct be_adapter *adapter)
                drvs->rx_dropped_too_short +
                drvs->rx_dropped_header_too_small +
                drvs->rx_dropped_tcp_length +
-               drvs->rx_dropped_runt +
-               drvs->rx_tcp_checksum_errs +
-               drvs->rx_ip_checksum_errs +
-               drvs->rx_udp_checksum_errs;
+               drvs->rx_dropped_runt;
 
        /* detailed rx errors */
-       dev_stats->rx_length_errors = drvs->rx_in_range_errors +
+       stats->rx_length_errors = drvs->rx_in_range_errors +
                drvs->rx_out_range_errors +
                drvs->rx_frame_too_long;
 
-       dev_stats->rx_crc_errors = drvs->rx_crc_errors;
+       stats->rx_crc_errors = drvs->rx_crc_errors;
 
        /* frame alignment errors */
-       dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
+       stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
 
        /* receiver fifo overrun */
        /* drops_no_pbuf is no per i/f, it's per BE card */
-       dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
+       stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
                                drvs->rx_input_fifo_overflow_drop +
                                drvs->rx_drops_no_pbuf;
+       return stats;
 }
 
-void be_link_status_update(struct be_adapter *adapter, bool link_up)
+void be_link_status_update(struct be_adapter *adapter, u32 link_status)
 {
        struct net_device *netdev = adapter->netdev;
 
-       /* If link came up or went down */
-       if (adapter->link_up != link_up) {
-               adapter->link_speed = -1;
-               if (link_up) {
-                       netif_carrier_on(netdev);
-                       printk(KERN_INFO "%s: Link up\n", netdev->name);
-               } else {
-                       netif_carrier_off(netdev);
-                       printk(KERN_INFO "%s: Link down\n", netdev->name);
-               }
-               adapter->link_up = link_up;
-       }
-}
-
-/* Update the EQ delay n BE based on the RX frags consumed / sec */
-static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
-{
-       struct be_eq_obj *rx_eq = &rxo->rx_eq;
-       struct be_rx_stats *stats = &rxo->stats;
-       ulong now = jiffies;
-       u32 eqd;
-
-       if (!rx_eq->enable_aic)
-               return;
-
-       /* Wrapped around */
-       if (time_before(now, stats->rx_fps_jiffies)) {
-               stats->rx_fps_jiffies = now;
-               return;
-       }
-
-       /* Update once a second */
-       if ((now - stats->rx_fps_jiffies) < HZ)
-               return;
-
-       stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) /
-                       ((now - stats->rx_fps_jiffies) / HZ);
-
-       stats->rx_fps_jiffies = now;
-       stats->prev_rx_frags = stats->rx_frags;
-       eqd = stats->rx_fps / 110000;
-       eqd = eqd << 3;
-       if (eqd > rx_eq->max_eqd)
-               eqd = rx_eq->max_eqd;
-       if (eqd < rx_eq->min_eqd)
-               eqd = rx_eq->min_eqd;
-       if (eqd < 10)
-               eqd = 0;
-       if (eqd != rx_eq->cur_eqd)
-               be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd);
-
-       rx_eq->cur_eqd = eqd;
-}
-
-static u32 be_calc_rate(u64 bytes, unsigned long ticks)
-{
-       u64 rate = bytes;
-
-       do_div(rate, ticks / HZ);
-       rate <<= 3;                     /* bytes/sec -> bits/sec */
-       do_div(rate, 1000000ul);        /* MB/Sec */
-
-       return rate;
-}
-
-static void be_tx_rate_update(struct be_tx_obj *txo)
-{
-       struct be_tx_stats *stats = tx_stats(txo);
-       ulong now = jiffies;
-
-       /* Wrapped around? */
-       if (time_before(now, stats->be_tx_jiffies)) {
-               stats->be_tx_jiffies = now;
-               return;
-       }
-
-       /* Update tx rate once in two seconds */
-       if ((now - stats->be_tx_jiffies) > 2 * HZ) {
-               stats->be_tx_rate = be_calc_rate(stats->be_tx_bytes
-                                                 - stats->be_tx_bytes_prev,
-                                                now - stats->be_tx_jiffies);
-               stats->be_tx_jiffies = now;
-               stats->be_tx_bytes_prev = stats->be_tx_bytes;
+       /* when link status changes, link speed must be re-queried from card */
+       adapter->link_speed = -1;
+       if ((link_status & LINK_STATUS_MASK) == LINK_UP) {
+               netif_carrier_on(netdev);
+               dev_info(&adapter->pdev->dev, "%s: Link up\n", netdev->name);
+       } else {
+               netif_carrier_off(netdev);
+               dev_info(&adapter->pdev->dev, "%s: Link down\n", netdev->name);
        }
 }
 
@@ -585,12 +482,14 @@ static void be_tx_stats_update(struct be_tx_obj *txo,
 {
        struct be_tx_stats *stats = tx_stats(txo);
 
-       stats->be_tx_reqs++;
-       stats->be_tx_wrbs += wrb_cnt;
-       stats->be_tx_bytes += copied;
-       stats->be_tx_pkts += (gso_segs ? gso_segs : 1);
+       u64_stats_update_begin(&stats->sync);
+       stats->tx_reqs++;
+       stats->tx_wrbs += wrb_cnt;
+       stats->tx_bytes += copied;
+       stats->tx_pkts += (gso_segs ? gso_segs : 1);
        if (stopped)
-               stats->be_tx_stops++;
+               stats->tx_stops++;
+       u64_stats_update_end(&stats->sync);
 }
 
 /* Determine number of WRB entries needed to xmit data in an skb */
@@ -829,6 +728,10 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
                status = be_cmd_vlan_config(adapter, if_handle, vtag, 1, 1, 0);
        }
 
+       /* No need to further configure vids if in promiscuous mode */
+       if (adapter->promiscuous)
+               return 0;
+
        if (adapter->vlans_added <= adapter->max_vlans)  {
                /* Construct VLAN Table to give to HW */
                for (i = 0; i < VLAN_N_VID; i++) {
@@ -879,7 +782,7 @@ static void be_set_multicast_list(struct net_device *netdev)
        struct be_adapter *adapter = netdev_priv(netdev);
 
        if (netdev->flags & IFF_PROMISC) {
-               be_cmd_promiscuous_config(adapter, true);
+               be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
                adapter->promiscuous = true;
                goto done;
        }
@@ -887,19 +790,20 @@ static void be_set_multicast_list(struct net_device *netdev)
        /* BE was previously in promiscuous mode; disable it */
        if (adapter->promiscuous) {
                adapter->promiscuous = false;
-               be_cmd_promiscuous_config(adapter, false);
+               be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
+
+               if (adapter->vlans_added)
+                       be_vid_config(adapter, false, 0);
        }
 
        /* Enable multicast promisc if num configured exceeds what we support */
        if (netdev->flags & IFF_ALLMULTI ||
-           netdev_mc_count(netdev) > BE_MAX_MC) {
-               be_cmd_multicast_set(adapter, adapter->if_handle, NULL,
-                               &adapter->mc_cmd_mem);
+                       netdev_mc_count(netdev) > BE_MAX_MC) {
+               be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
                goto done;
        }
 
-       be_cmd_multicast_set(adapter, adapter->if_handle, netdev,
-               &adapter->mc_cmd_mem);
+       be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
 done:
        return;
 }
@@ -1005,10 +909,17 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
        return status;
 }
 
-static void be_rx_rate_update(struct be_rx_obj *rxo)
+static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
 {
-       struct be_rx_stats *stats = &rxo->stats;
+       struct be_eq_obj *rx_eq = &rxo->rx_eq;
+       struct be_rx_stats *stats = rx_stats(rxo);
        ulong now = jiffies;
+       ulong delta = now - stats->rx_jiffies;
+       u64 pkts;
+       unsigned int start, eqd;
+
+       if (!rx_eq->enable_aic)
+               return;
 
        /* Wrapped around */
        if (time_before(now, stats->rx_jiffies)) {
@@ -1016,29 +927,46 @@ static void be_rx_rate_update(struct be_rx_obj *rxo)
                return;
        }
 
-       /* Update the rate once in two seconds */
-       if ((now - stats->rx_jiffies) < 2 * HZ)
+       /* Update once a second */
+       if (delta < HZ)
                return;
 
-       stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev,
-                               now - stats->rx_jiffies);
+       do {
+               start = u64_stats_fetch_begin_bh(&stats->sync);
+               pkts = stats->rx_pkts;
+       } while (u64_stats_fetch_retry_bh(&stats->sync, start));
+
+       stats->rx_pps = (unsigned long)(pkts - stats->rx_pkts_prev) / (delta / HZ);
+       stats->rx_pkts_prev = pkts;
        stats->rx_jiffies = now;
-       stats->rx_bytes_prev = stats->rx_bytes;
+       eqd = stats->rx_pps / 110000;
+       eqd = eqd << 3;
+       if (eqd > rx_eq->max_eqd)
+               eqd = rx_eq->max_eqd;
+       if (eqd < rx_eq->min_eqd)
+               eqd = rx_eq->min_eqd;
+       if (eqd < 10)
+               eqd = 0;
+       if (eqd != rx_eq->cur_eqd) {
+               be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd);
+               rx_eq->cur_eqd = eqd;
+       }
 }
 
 static void be_rx_stats_update(struct be_rx_obj *rxo,
                struct be_rx_compl_info *rxcp)
 {
-       struct be_rx_stats *stats = &rxo->stats;
+       struct be_rx_stats *stats = rx_stats(rxo);
 
+       u64_stats_update_begin(&stats->sync);
        stats->rx_compl++;
-       stats->rx_frags += rxcp->num_rcvd;
        stats->rx_bytes += rxcp->pkt_size;
        stats->rx_pkts++;
        if (rxcp->pkt_type == BE_MULTICAST_PACKET)
                stats->rx_mcast_pkts++;
        if (rxcp->err)
-               stats->rxcp_err++;
+               stats->rx_compl_err++;
+       u64_stats_update_end(&stats->sync);
 }
 
 static inline bool csum_passed(struct be_rx_compl_info *rxcp)
@@ -1174,7 +1102,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 
        skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN);
        if (unlikely(!skb)) {
-               rxo->stats.rx_dropped++;
+               rx_stats(rxo)->rx_drops_no_skbs++;
                be_rx_compl_discard(adapter, rxo, rxcp);
                return;
        }
@@ -1285,6 +1213,7 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter,
                rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
                                               compl);
        }
+       rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
 }
 
 static void be_parse_rx_compl_v0(struct be_adapter *adapter,
@@ -1317,6 +1246,7 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter,
                rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
                                               compl);
        }
+       rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
 }
 
 static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -1347,8 +1277,7 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
                if (!lancer_chip(adapter))
                        rxcp->vlan_tag = swab16(rxcp->vlan_tag);
 
-               if (((adapter->pvid & VLAN_VID_MASK) ==
-                    (rxcp->vlan_tag & VLAN_VID_MASK)) &&
+               if (adapter->pvid == (rxcp->vlan_tag & VLAN_VID_MASK) &&
                    !adapter->vlan_tag[rxcp->vlan_tag])
                        rxcp->vlanf = 0;
        }
@@ -1389,7 +1318,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
                if (!pagep) {
                        pagep = be_alloc_pages(adapter->big_page_size, gfp);
                        if (unlikely(!pagep)) {
-                               rxo->stats.rx_post_fail++;
+                               rx_stats(rxo)->rx_post_fail++;
                                break;
                        }
                        page_dmaaddr = dma_map_page(&adapter->pdev->dev, pagep,
@@ -1899,22 +1828,36 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
        struct be_rx_compl_info *rxcp;
        u32 work_done;
 
-       rxo->stats.rx_polls++;
+       rx_stats(rxo)->rx_polls++;
        for (work_done = 0; work_done < budget; work_done++) {
                rxcp = be_rx_compl_get(rxo);
                if (!rxcp)
                        break;
 
-               /* Ignore flush completions */
-               if (rxcp->num_rcvd && rxcp->pkt_size) {
-                       if (do_gro(rxcp))
-                               be_rx_compl_process_gro(adapter, rxo, rxcp);
-                       else
-                               be_rx_compl_process(adapter, rxo, rxcp);
-               } else if (rxcp->pkt_size == 0) {
+               /* Is it a flush compl that has no data */
+               if (unlikely(rxcp->num_rcvd == 0))
+                       goto loop_continue;
+
+               /* Discard compl with partial DMA Lancer B0 */
+               if (unlikely(!rxcp->pkt_size)) {
                        be_rx_compl_discard(adapter, rxo, rxcp);
+                       goto loop_continue;
                }
 
+               /* On BE drop pkts that arrive due to imperfect filtering in
+                * promiscuous mode on some skews
+                */
+               if (unlikely(rxcp->port != adapter->port_num &&
+                               !lancer_chip(adapter))) {
+                       be_rx_compl_discard(adapter, rxo, rxcp);
+                       goto loop_continue;
+               }
+
+               if (do_gro(rxcp))
+                       be_rx_compl_process_gro(adapter, rxo, rxcp);
+               else
+                       be_rx_compl_process(adapter, rxo, rxcp);
+loop_continue:
                be_rx_stats_update(rxo, rxcp);
        }
 
@@ -1968,8 +1911,9 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
                                netif_wake_subqueue(adapter->netdev, i);
                        }
 
-                       adapter->drv_stats.be_tx_events++;
-                       txo->stats.be_tx_compl += tx_compl;
+                       u64_stats_update_begin(&tx_stats(txo)->sync_compl);
+                       tx_stats(txo)->tx_compl += tx_compl;
+                       u64_stats_update_end(&tx_stats(txo)->sync_compl);
                }
        }
 
@@ -1983,6 +1927,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
        napi_complete(napi);
 
        be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+       adapter->drv_stats.tx_events++;
        return 1;
 }
 
@@ -2031,7 +1976,6 @@ static void be_worker(struct work_struct *work)
        struct be_adapter *adapter =
                container_of(work, struct be_adapter, work.work);
        struct be_rx_obj *rxo;
-       struct be_tx_obj *txo;
        int i;
 
        if (!adapter->ue_detected && !lancer_chip(adapter))
@@ -2060,11 +2004,7 @@ static void be_worker(struct work_struct *work)
                        be_cmd_get_stats(adapter, &adapter->stats_cmd);
        }
 
-       for_all_tx_queues(adapter, txo, i)
-               be_tx_rate_update(txo);
-
        for_all_rx_queues(adapter, rxo, i) {
-               be_rx_rate_update(rxo);
                be_rx_eqd_update(adapter, rxo);
 
                if (rxo->rx_post_starved) {
@@ -2294,9 +2234,6 @@ static int be_close(struct net_device *netdev)
 
        be_async_mcc_disable(adapter);
 
-       netif_carrier_off(netdev);
-       adapter->link_up = false;
-
        if (!lancer_chip(adapter))
                be_intr_set(adapter, false);
 
@@ -2374,10 +2311,7 @@ static int be_open(struct net_device *netdev)
        struct be_adapter *adapter = netdev_priv(netdev);
        struct be_eq_obj *tx_eq = &adapter->tx_eq;
        struct be_rx_obj *rxo;
-       bool link_up;
        int status, i;
-       u8 mac_speed;
-       u16 link_speed;
 
        status = be_rx_queues_setup(adapter);
        if (status)
@@ -2400,12 +2334,6 @@ static int be_open(struct net_device *netdev)
        /* Now that interrupts are on we can process async mcc */
        be_async_mcc_enable(adapter);
 
-       status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
-                       &link_speed, 0);
-       if (status)
-               goto err;
-       be_link_status_update(adapter, link_up);
-
        if (be_physfn(adapter)) {
                status = be_vid_config(adapter, false, 0);
                if (status)
@@ -2656,6 +2584,21 @@ static bool be_flash_redboot(struct be_adapter *adapter,
                return true;
 }
 
+static bool phy_flashing_required(struct be_adapter *adapter)
+{
+       int status = 0;
+       struct be_phy_info phy_info;
+
+       status = be_cmd_get_phy_info(adapter, &phy_info);
+       if (status)
+               return false;
+       if ((phy_info.phy_type == TN_8022) &&
+               (phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
+               return true;
+       }
+       return false;
+}
+
 static int be_flash_data(struct be_adapter *adapter,
                        const struct firmware *fw,
                        struct be_dma_mem *flash_cmd, int num_of_images)
@@ -2669,7 +2612,7 @@ static int be_flash_data(struct be_adapter *adapter,
        const struct flash_comp *pflashcomp;
        int num_comp;
 
-       static const struct flash_comp gen3_flash_types[9] = {
+       static const struct flash_comp gen3_flash_types[10] = {
                { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
                        FLASH_IMAGE_MAX_SIZE_g3},
                { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
@@ -2687,7 +2630,9 @@ static int be_flash_data(struct be_adapter *adapter,
                { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
                        FLASH_IMAGE_MAX_SIZE_g3},
                { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
-                       FLASH_NCSI_IMAGE_MAX_SIZE_g3}
+                       FLASH_NCSI_IMAGE_MAX_SIZE_g3},
+               { FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
+                       FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
        };
        static const struct flash_comp gen2_flash_types[8] = {
                { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
@@ -2721,6 +2666,10 @@ static int be_flash_data(struct be_adapter *adapter,
                if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
                                memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
                        continue;
+               if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
+                       if (!phy_flashing_required(adapter))
+                               continue;
+               }
                if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
                        (!be_flash_redboot(adapter, fw->data,
                        pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
@@ -2729,25 +2678,35 @@ static int be_flash_data(struct be_adapter *adapter,
                p = fw->data;
                p += filehdr_size + pflashcomp[i].offset
                        + (num_of_images * sizeof(struct image_hdr));
-       if (p + pflashcomp[i].size > fw->data + fw->size)
-               return -1;
-       total_bytes = pflashcomp[i].size;
+               if (p + pflashcomp[i].size > fw->data + fw->size)
+                       return -1;
+               total_bytes = pflashcomp[i].size;
                while (total_bytes) {
                        if (total_bytes > 32*1024)
                                num_bytes = 32*1024;
                        else
                                num_bytes = total_bytes;
                        total_bytes -= num_bytes;
-
-                       if (!total_bytes)
-                               flash_op = FLASHROM_OPER_FLASH;
-                       else
-                               flash_op = FLASHROM_OPER_SAVE;
+                       if (!total_bytes) {
+                               if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
+                                       flash_op = FLASHROM_OPER_PHY_FLASH;
+                               else
+                                       flash_op = FLASHROM_OPER_FLASH;
+                       } else {
+                               if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
+                                       flash_op = FLASHROM_OPER_PHY_SAVE;
+                               else
+                                       flash_op = FLASHROM_OPER_SAVE;
+                       }
                        memcpy(req->params.data_buf, p, num_bytes);
                        p += num_bytes;
                        status = be_cmd_write_flashrom(adapter, flash_cmd,
                                pflashcomp[i].optype, flash_op, num_bytes);
                        if (status) {
+                               if ((status == ILLEGAL_IOCTL_REQ) &&
+                                       (pflashcomp[i].optype ==
+                                               IMG_TYPE_PHY_FW))
+                                       break;
                                dev_err(&adapter->pdev->dev,
                                        "cmd to write to flash rom failed.\n");
                                return -1;
@@ -2938,6 +2897,7 @@ static struct net_device_ops be_netdev_ops = {
        .ndo_set_rx_mode        = be_set_multicast_list,
        .ndo_set_mac_address    = be_mac_addr_set,
        .ndo_change_mtu         = be_change_mtu,
+       .ndo_get_stats64        = be_get_stats64,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_vlan_rx_add_vid    = be_vlan_add_vid,
        .ndo_vlan_rx_kill_vid   = be_vlan_rem_vid,
@@ -3060,7 +3020,7 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
                dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
                                  mem->dma);
 
-       mem = &adapter->mc_cmd_mem;
+       mem = &adapter->rx_filter;
        if (mem->va)
                dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
                                  mem->dma);
@@ -3070,7 +3030,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
 {
        struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
        struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
-       struct be_dma_mem *mc_cmd_mem = &adapter->mc_cmd_mem;
+       struct be_dma_mem *rx_filter = &adapter->rx_filter;
        int status;
 
        status = be_map_pci_bars(adapter);
@@ -3086,21 +3046,19 @@ static int be_ctrl_init(struct be_adapter *adapter)
                status = -ENOMEM;
                goto unmap_pci_bars;
        }
-
        mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
        mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
        mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
        memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
 
-       mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config);
-       mc_cmd_mem->va = dma_alloc_coherent(&adapter->pdev->dev,
-                                           mc_cmd_mem->size, &mc_cmd_mem->dma,
-                                           GFP_KERNEL);
-       if (mc_cmd_mem->va == NULL) {
+       rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
+       rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
+                                       &rx_filter->dma, GFP_KERNEL);
+       if (rx_filter->va == NULL) {
                status = -ENOMEM;
                goto free_mbox;
        }
-       memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
+       memset(rx_filter->va, 0, rx_filter->size);
 
        mutex_init(&adapter->mbox_lock);
        spin_lock_init(&adapter->mcc_lock);
@@ -3421,11 +3379,9 @@ static int __devinit be_probe(struct pci_dev *pdev,
        status = register_netdev(netdev);
        if (status != 0)
                goto unsetup;
-       netif_carrier_off(netdev);
 
        if (be_physfn(adapter) && adapter->sriov_enabled) {
                u8 mac_speed;
-               bool link_up;
                u16 vf, lnk_speed;
 
                if (!lancer_chip(adapter)) {
@@ -3435,8 +3391,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
                }
 
                for (vf = 0; vf < num_vfs; vf++) {
-                       status = be_cmd_link_status_query(adapter, &link_up,
-                                       &mac_speed, &lnk_speed, vf + 1);
+                       status = be_cmd_link_status_query(adapter, &mac_speed,
+                                               &lnk_speed, vf + 1);
                        if (!status)
                                adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10;
                        else
similarity index 99%
rename from drivers/net/ethoc.c
rename to drivers/net/ethernet/ethoc.c
index 8abbe1d828267dfa73025b4e1bf01c2bdde977d6..bdb348a5ccf60bd6bb93b2d745546445b5f2d413 100644 (file)
@@ -888,7 +888,7 @@ static const struct net_device_ops ethoc_netdev_ops = {
        .ndo_do_ioctl = ethoc_ioctl,
        .ndo_set_config = ethoc_config,
        .ndo_set_mac_address = ethoc_set_mac_address,
-       .ndo_set_multicast_list = ethoc_set_multicast_list,
+       .ndo_set_rx_mode = ethoc_set_multicast_list,
        .ndo_change_mtu = ethoc_change_mtu,
        .ndo_tx_timeout = ethoc_tx_timeout,
        .ndo_start_xmit = ethoc_start_xmit,
diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig
new file mode 100644 (file)
index 0000000..b0d76f0
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# Faraday device configuration
+#
+
+config NET_VENDOR_FARADAY
+       bool "Faraday devices"
+       depends on ARM
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Faraday cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_FARADAY
+
+config FTMAC100
+       tristate "Faraday FTMAC100 10/100 Ethernet support"
+       depends on ARM
+       select MII
+       ---help---
+         This driver supports the FTMAC100 10/100 Ethernet controller
+         from Faraday. It is used on Faraday A320, Andes AG101 and some
+         other ARM/NDS32 SoC's.
+
+config FTGMAC100
+       tristate "Faraday FTGMAC100 Gigabit Ethernet support"
+       depends on ARM
+       select PHYLIB
+       ---help---
+         This driver supports the FTGMAC100 Gigabit Ethernet controller
+         from Faraday. It is used on Faraday A369, Andes AG102 and some
+         other ARM/NDS32 SoC's.
+
+endif # NET_VENDOR_FARADAY
diff --git a/drivers/net/ethernet/faraday/Makefile b/drivers/net/ethernet/faraday/Makefile
new file mode 100644 (file)
index 0000000..408b539
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Faraday device drivers.
+#
+
+obj-$(CONFIG_FTGMAC100) += ftgmac100.o
+obj-$(CONFIG_FTMAC100) += ftmac100.o
similarity index 99%
rename from drivers/net/fealnx.c
rename to drivers/net/ethernet/fealnx.c
index fa8677c323848ee4f9f0a0d6fee670dc05c64dc3..61d2bddec1fa9e6c38fc5521a3962647e159f4e0 100644 (file)
@@ -469,7 +469,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_stop               = netdev_close,
        .ndo_start_xmit         = start_tx,
        .ndo_get_stats          = get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_do_ioctl           = mii_ioctl,
        .ndo_tx_timeout         = fealnx_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
new file mode 100644 (file)
index 0000000..2fd2c61
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# Freescale device configuration
+#
+
+config NET_VENDOR_FREESCALE
+       bool "Freescale devices"
+       depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
+                  M523x || M527x || M5272 || M528x || M520x || M532x || \
+                  IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC || \
+                  (PPC_MPC52xx && PPC_BESTCOMM)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about IBM devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_FREESCALE
+
+config FEC
+       bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
+       depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
+                   IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC)
+       default IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC if ARM
+       select PHYLIB
+       ---help---
+         Say Y here if you want to use the built-in 10/100 Fast ethernet
+         controller on some Motorola ColdFire and Freescale i.MX processors.
+
+config FEC_MPC52xx
+       tristate "FEC MPC52xx driver"
+       depends on PPC_MPC52xx && PPC_BESTCOMM
+       select CRC32
+       select PHYLIB
+       select PPC_BESTCOMM_FEC
+       ---help---
+         This option enables support for the MPC5200's on-chip
+         Fast Ethernet Controller
+         If compiled as module, it will be called fec_mpc52xx.
+
+config FEC_MPC52xx_MDIO
+       bool "FEC MPC52xx MDIO bus driver"
+       depends on FEC_MPC52xx
+       default y
+       ---help---
+         The MPC5200's FEC can connect to the Ethernet either with
+         an external MII PHY chip or 10 Mbps 7-wire interface
+         (Motorola? industry standard).
+         If your board uses an external PHY connected to FEC, enable this.
+         If not sure, enable.
+         If compiled as module, it will be called fec_mpc52xx_phy.
+
+source "drivers/net/ethernet/freescale/fs_enet/Kconfig"
+
+config FSL_PQ_MDIO
+       tristate "Freescale PQ MDIO"
+       depends on FSL_SOC
+       select PHYLIB
+       ---help---
+         This driver supports the MDIO bus used by the gianfar and UCC drivers.
+
+config UCC_GETH
+       tristate "Freescale QE Gigabit Ethernet"
+       depends on QUICC_ENGINE
+       select FSL_PQ_MDIO
+       select PHYLIB
+       ---help---
+         This driver supports the Gigabit Ethernet mode of the QUICC Engine,
+         which is available on some Freescale SOCs.
+
+config UGETH_TX_ON_DEMAND
+       bool "Transmit on Demand support"
+       depends on UCC_GETH
+
+config GIANFAR
+       tristate "Gianfar Ethernet"
+       depends on FSL_SOC
+       select FSL_PQ_MDIO
+       select PHYLIB
+       select CRC32
+       ---help---
+         This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
+         and MPC86xx family of chips, and the FEC on the 8540.
+
+endif # NET_VENDOR_FREESCALE
diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile
new file mode 100644 (file)
index 0000000..1752488
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# Makefile for the Freescale network device drivers.
+#
+
+obj-$(CONFIG_FEC) += fec.o
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
+ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
+       obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
+endif
+obj-$(CONFIG_FS_ENET) += fs_enet/
+obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
+obj-$(CONFIG_GIANFAR) += gianfar_driver.o
+obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
+gianfar_driver-objs := gianfar.o \
+               gianfar_ethtool.o \
+               gianfar_sysfs.o
+obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
+ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
similarity index 99%
rename from drivers/net/fec.c
rename to drivers/net/ethernet/freescale/fec.c
index e8266ccf818a033b0539e8e3cb0b3c82c4056c7c..158b82ea6df526090d4543f534ecdb6df2e27fea 100644 (file)
@@ -1325,7 +1325,7 @@ static const struct net_device_ops fec_netdev_ops = {
        .ndo_open               = fec_enet_open,
        .ndo_stop               = fec_enet_close,
        .ndo_start_xmit         = fec_enet_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = fec_timeout,
similarity index 99%
rename from drivers/net/fec_mpc52xx.c
rename to drivers/net/ethernet/freescale/fec_mpc52xx.c
index cb4416e591f1f180c9b94b8a7fe4e25ff7758a78..30745b56fe5d6d5d11193eb966699bf6aed55fc7 100644 (file)
@@ -828,7 +828,7 @@ static const struct net_device_ops mpc52xx_fec_netdev_ops = {
        .ndo_open = mpc52xx_fec_open,
        .ndo_stop = mpc52xx_fec_close,
        .ndo_start_xmit = mpc52xx_fec_start_xmit,
-       .ndo_set_multicast_list = mpc52xx_fec_set_multicast_list,
+       .ndo_set_rx_mode = mpc52xx_fec_set_multicast_list,
        .ndo_set_mac_address = mpc52xx_fec_set_mac_address,
        .ndo_validate_addr = eth_validate_addr,
        .ndo_do_ioctl = mpc52xx_fec_ioctl,
similarity index 91%
rename from drivers/net/fs_enet/Kconfig
rename to drivers/net/ethernet/freescale/fs_enet/Kconfig
index fc073b5a38c7c61543a9348d7fabb6d7327d3d2c..be92229f2c2a52f447c96a086e4683cc0c341e68 100644 (file)
@@ -1,6 +1,6 @@
 config FS_ENET
        tristate "Freescale Ethernet Driver"
-       depends on CPM1 || CPM2 || PPC_MPC512x
+       depends on NET_VENDOR_FREESCALE && (CPM1 || CPM2 || PPC_MPC512x)
        select MII
        select PHYLIB
 
similarity index 99%
rename from drivers/net/fs_enet/fs_enet-main.c
rename to drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 329ef231a09649209dc3baa856ae145f94366864..5bf5471f06ffd77bf82e9d5c91a90ebb75a38216 100644 (file)
@@ -988,7 +988,7 @@ static const struct net_device_ops fs_enet_netdev_ops = {
        .ndo_get_stats          = fs_enet_get_stats,
        .ndo_start_xmit         = fs_enet_start_xmit,
        .ndo_tx_timeout         = fs_timeout,
-       .ndo_set_multicast_list = fs_set_multicast_list,
+       .ndo_set_rx_mode        = fs_set_multicast_list,
        .ndo_do_ioctl           = fs_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/gianfar.c
rename to drivers/net/ethernet/freescale/gianfar.c
index 2659daad783ddb857f5e9597bbb2a2ea95c05f04..81d409d08c9746910d73e5c22be7d8c22a35ddd8 100644 (file)
@@ -458,7 +458,7 @@ static const struct net_device_ops gfar_netdev_ops = {
        .ndo_stop = gfar_close,
        .ndo_change_mtu = gfar_change_mtu,
        .ndo_set_features = gfar_set_features,
-       .ndo_set_multicast_list = gfar_set_multi,
+       .ndo_set_rx_mode = gfar_set_multi,
        .ndo_tx_timeout = gfar_timeout,
        .ndo_do_ioctl = gfar_ioctl,
        .ndo_get_stats = gfar_get_stats,
@@ -2710,8 +2710,13 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
        /* Tell the skb what kind of packet this is */
        skb->protocol = eth_type_trans(skb, dev);
 
-       /* Set vlan tag */
-       if (fcb->flags & RXFCB_VLN)
+       /*
+        * There's need to check for NETIF_F_HW_VLAN_RX here.
+        * Even if vlan rx accel is disabled, on some chips
+        * RXFCB_VLN is pseudo randomly set.
+        */
+       if (dev->features & NETIF_F_HW_VLAN_RX &&
+           fcb->flags & RXFCB_VLN)
                __vlan_hwaccel_put_tag(skb, fcb->vlctl);
 
        /* Send the packet up the stack */
similarity index 99%
rename from drivers/net/gianfar_ethtool.c
rename to drivers/net/ethernet/freescale/gianfar_ethtool.c
index 6e350692d1184147b0989e19d8be3b8436938d29..25a8c2adb001892acc1c2531de8ed8b62b30d8e0 100644 (file)
@@ -686,10 +686,21 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
 {
        unsigned int last_rule_idx = priv->cur_filer_idx;
        unsigned int cmp_rqfpr;
-       unsigned int local_rqfpr[MAX_FILER_IDX + 1];
-       unsigned int local_rqfcr[MAX_FILER_IDX + 1];
+       unsigned int *local_rqfpr;
+       unsigned int *local_rqfcr;
        int i = 0x0, k = 0x0;
        int j = MAX_FILER_IDX, l = 0x0;
+       int ret = 1;
+
+       local_rqfpr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1),
+               GFP_KERNEL);
+       local_rqfcr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1),
+               GFP_KERNEL);
+       if (!local_rqfpr || !local_rqfcr) {
+               pr_err("Out of memory\n");
+               ret = 0;
+               goto err;
+       }
 
        switch (class) {
        case TCP_V4_FLOW:
@@ -706,7 +717,8 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
                break;
        default:
                pr_err("Right now this class is not supported\n");
-               return 0;
+               ret = 0;
+               goto err;
        }
 
        for (i = 0; i < MAX_FILER_IDX + 1; i++) {
@@ -721,7 +733,8 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
 
        if (i == MAX_FILER_IDX + 1) {
                pr_err("No parse rule found, can't create hash rules\n");
-               return 0;
+               ret = 0;
+               goto err;
        }
 
        /* If a match was found, then it begins the starting of a cluster rule
@@ -765,7 +778,10 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u
                priv->cur_filer_idx = priv->cur_filer_idx - 1;
        }
 
-       return 1;
+err:
+       kfree(local_rqfcr);
+       kfree(local_rqfpr);
+       return ret;
 }
 
 static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
similarity index 99%
rename from drivers/net/ucc_geth.c
rename to drivers/net/ethernet/freescale/ucc_geth.c
index d3465ab50e5633aa02901b1dc3e88badbf5c3aa4..46d690a92c0bda42990b9bd5b4b43bb18ee0af74 100644 (file)
@@ -1761,10 +1761,12 @@ static int init_phy(struct net_device *dev)
        if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
                uec_configure_serdes(dev);
 
-       phydev->supported &= (ADVERTISED_10baseT_Half |
-                                ADVERTISED_10baseT_Full |
-                                ADVERTISED_100baseT_Half |
-                                ADVERTISED_100baseT_Full);
+       phydev->supported &= (SUPPORTED_MII |
+                             SUPPORTED_Autoneg |
+                             ADVERTISED_10baseT_Half |
+                             ADVERTISED_10baseT_Full |
+                             ADVERTISED_100baseT_Half |
+                             ADVERTISED_100baseT_Full);
 
        if (priv->max_speed == SPEED_1000)
                phydev->supported |= ADVERTISED_1000baseT_Full;
@@ -3729,7 +3731,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ucc_geth_set_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
-       .ndo_set_multicast_list = ucc_geth_set_multi,
+       .ndo_set_rx_mode        = ucc_geth_set_multi,
        .ndo_tx_timeout         = ucc_geth_timeout,
        .ndo_do_ioctl           = ucc_geth_ioctl,
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/ethernet/fujitsu/Kconfig b/drivers/net/ethernet/fujitsu/Kconfig
new file mode 100644 (file)
index 0000000..2cd968e
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Fujitsu Network device configuration
+#
+
+config NET_VENDOR_FUJITSU
+       bool "Fujitsu devices"
+       depends on ISA || PCMCIA || ((ISA || MCA_LEGACY) && EXPERIMENTAL)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         the questions about Fujitsu cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_FUJITSU
+
+config AT1700
+       tristate "AT1700/1720 support (EXPERIMENTAL)"
+       depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
+       select CRC32
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called at1700.
+
+config PCMCIA_FMVJ18X
+       tristate "Fujitsu FMV-J18x PCMCIA support"
+       depends on PCMCIA
+       select CRC32
+       ---help---
+         Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible
+         PCMCIA (PC-card) Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called fmvj18x_cs.  If unsure, say N.
+
+config ETH16I
+       tristate "ICL EtherTeam 16i/32 support"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called eth16i.
+
+endif # NET_VENDOR_FUJITSU
diff --git a/drivers/net/ethernet/fujitsu/Makefile b/drivers/net/ethernet/fujitsu/Makefile
new file mode 100644 (file)
index 0000000..2730ae6
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the Fujitsu network device drivers.
+#
+
+obj-$(CONFIG_AT1700) += at1700.o
+obj-$(CONFIG_ETH16I) += eth16i.o
+obj-$(CONFIG_PCMCIA_FMVJ18X) += fmvj18x_cs.o
similarity index 99%
rename from drivers/net/at1700.c
rename to drivers/net/ethernet/fujitsu/at1700.c
index 65a78f965dd25c5f30442e9a010ecac849c761ce..7c6c908bdf02c4374604d76697df2b4168f5c7d4 100644 (file)
@@ -253,7 +253,7 @@ static const struct net_device_ops at1700_netdev_ops = {
        .ndo_open               = net_open,
        .ndo_stop               = net_close,
        .ndo_start_xmit         = net_send_packet,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_tx_timeout         = net_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/eth16i.c
rename to drivers/net/ethernet/fujitsu/eth16i.c
index 12d28e9d0cb7b77df1a03a26ebd1ab68b03dd9d2..b0e2313af3d1d9674c20290c944afd8c373e3f08 100644 (file)
@@ -478,7 +478,7 @@ static const struct net_device_ops eth16i_netdev_ops = {
        .ndo_open               = eth16i_open,
        .ndo_stop               = eth16i_close,
        .ndo_start_xmit         = eth16i_tx,
-       .ndo_set_multicast_list = eth16i_multicast,
+       .ndo_set_rx_mode        = eth16i_multicast,
        .ndo_tx_timeout         = eth16i_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/pcmcia/fmvj18x_cs.c
rename to drivers/net/ethernet/fujitsu/fmvj18x_cs.c
index 723815e7a9973e77116d6a089871449dddb93f2c..15416752c13e0646ccfc3eac1435671dc9f4ac25 100644 (file)
@@ -226,7 +226,7 @@ static const struct net_device_ops fjn_netdev_ops = {
        .ndo_start_xmit         = fjn_start_xmit,
        .ndo_tx_timeout         = fjn_tx_timeout,
        .ndo_set_config         = fjn_config,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/hp/Kconfig b/drivers/net/ethernet/hp/Kconfig
new file mode 100644 (file)
index 0000000..07b42e9
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# HP network device configuration
+#
+
+config NET_VENDOR_HP
+       bool "HP devices"
+       depends on ISA || EISA || PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about HP cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_HP
+
+config HP100
+       tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
+       depends on (ISA || EISA || PCI)
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called hp100.
+
+endif # NET_VENDOR_HP
diff --git a/drivers/net/ethernet/hp/Makefile b/drivers/net/ethernet/hp/Makefile
new file mode 100644 (file)
index 0000000..20b6918
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the HP network device drivers.
+#
+
+obj-$(CONFIG_HP100) += hp100.o
similarity index 99%
rename from drivers/net/hp100.c
rename to drivers/net/ethernet/hp/hp100.c
index b6519c1ba7e1442443eb3f32d5fcdb14af28ea7e..6a5ee0776b2897e400ccdda6828f8c954c28d4d6 100644 (file)
@@ -430,7 +430,7 @@ static const struct net_device_ops hp100_bm_netdev_ops = {
        .ndo_stop               = hp100_close,
        .ndo_start_xmit         = hp100_start_xmit_bm,
        .ndo_get_stats          = hp100_get_stats,
-       .ndo_set_multicast_list = hp100_set_multicast_list,
+       .ndo_set_rx_mode        = hp100_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
@@ -441,7 +441,7 @@ static const struct net_device_ops hp100_netdev_ops = {
        .ndo_stop               = hp100_close,
        .ndo_start_xmit         = hp100_start_xmit,
        .ndo_get_stats          = hp100_get_stats,
-       .ndo_set_multicast_list = hp100_set_multicast_list,
+       .ndo_set_rx_mode        = hp100_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/3c505.c
rename to drivers/net/ethernet/i825xx/3c505.c
index 88d766ee0e1bc35c89a53effa08d9c41b80fa198..40e1a175fcebcc5668cb9e137336dfd1cdc21f42 100644 (file)
@@ -1363,7 +1363,7 @@ static const struct net_device_ops elp_netdev_ops = {
        .ndo_get_stats          = elp_get_stats,
        .ndo_start_xmit         = elp_start_xmit,
        .ndo_tx_timeout         = elp_timeout,
-       .ndo_set_multicast_list = elp_set_mc_list,
+       .ndo_set_rx_mode        = elp_set_mc_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/3c523.c
rename to drivers/net/ethernet/i825xx/3c523.c
index bc0d1a1c2e2862ace01203842fe9175a9d3b91f7..d70d3df4c9855e735b100d6d372b10d6ac1b0595 100644 (file)
@@ -409,7 +409,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_start_xmit         = elmc_send_packet,
        .ndo_tx_timeout         = elmc_timeout,
 #ifdef ELMC_MULTICAST
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
 #endif
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/3c527.c
rename to drivers/net/ethernet/i825xx/3c527.c
index d9d056d207f318644c176f3d524fd6029994e7b7..474b5e71a53a7da43df83fdfda311675b9d3f91c 100644 (file)
@@ -292,7 +292,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_stop               = mc32_close,
        .ndo_start_xmit         = mc32_send_packet,
        .ndo_get_stats          = mc32_get_stats,
-       .ndo_set_multicast_list = mc32_set_multicast_list,
+       .ndo_set_rx_mode        = mc32_set_multicast_list,
        .ndo_tx_timeout         = mc32_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/82596.c
rename to drivers/net/ethernet/i825xx/82596.c
index be1f1970c8422610d7ef37ebc85692a4372a9fbe..f2408a4d5d9c914c9cd1e96cf19cbb5abe701926 100644 (file)
@@ -1145,7 +1145,7 @@ static const struct net_device_ops i596_netdev_ops = {
        .ndo_open               = i596_open,
        .ndo_stop               = i596_close,
        .ndo_start_xmit         = i596_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = i596_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig
new file mode 100644 (file)
index 0000000..5c30a5b
--- /dev/null
@@ -0,0 +1,182 @@
+#
+# Intel 82596/82593/82596 network device configuration
+#
+
+config NET_VENDOR_I825XX
+       bool "Intel (82586/82593/82596) devices"
+       depends on NET_VENDOR_INTEL && (ISA || ISA_DMA_API || ARM || \
+                  ARCH_ACORN || MCA || MCA_LEGACY || SNI_RM || SUN3 || \
+                  GSC || BVME6000 || MVME16x || EXPERIMENTAL)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question does not directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about these devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_I825XX
+
+config ELPLUS
+       tristate "3c505 \"EtherLink Plus\" support"
+       depends on ISA && ISA_DMA_API
+       ---help---
+         Information about this network (Ethernet) card can be found in
+         <file:Documentation/networking/3c505.txt>.  If you have a card of
+         this type, say Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c505.
+
+config EL16
+       tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
+       depends on ISA && EXPERIMENTAL
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c507.
+
+config ELMC
+       tristate "3c523 \"EtherLink/MC\" support"
+       depends on MCA_LEGACY
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c523.
+
+config ELMC_II
+       tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
+       depends on MCA && MCA_LEGACY
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called 3c527.
+
+config ARM_ETHER1
+       tristate "Acorn Ether1 support"
+       depends on ARM && ARCH_ACORN
+       ---help---
+         If you have an Acorn system with one of these (AKA25) network cards,
+         you should say Y to this option if you wish to use it with Linux.
+
+config APRICOT
+       tristate "Apricot Xen-II on board Ethernet"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) controller of this type, say Y and
+         read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called apricot.
+
+config BVME6000_NET
+       tristate "BVME6000 Ethernet support"
+       depends on BVME6000MVME16x
+       ---help---
+         This is the driver for the Ethernet interface on BVME4000 and
+         BVME6000 VME boards.  Say Y here to include the driver for this chip
+         in your kernel.
+         To compile this driver as a module, choose M here.
+
+config EEXPRESS
+       tristate "EtherExpress 16 support"
+       depends on ISA
+       ---help---
+         If you have an EtherExpress16 network (Ethernet) card, say Y and
+         read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.  Note that the Intel
+         EtherExpress16 card used to be regarded as a very poor choice
+         because the driver was very unreliable. We now have a new driver
+         that should do better.
+
+         To compile this driver as a module, choose M here. The module
+         will be called eexpress.
+
+config EEXPRESS_PRO
+       tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y. This
+         driver supports Intel i82595{FX,TX} based boards. Note however
+         that the EtherExpress PRO/100 Ethernet card has its own separate
+         driver.  Please read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called eepro.
+
+config LASI_82596
+       tristate "Lasi ethernet"
+       depends on GSC
+       ---help---
+         Say Y here to support the builtin Intel 82596 ethernet controller
+         found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
+
+config LP486E
+       tristate "LP486E on board Ethernet"
+       depends on ISA
+       ---help---
+         Say Y here to support the 82596-based on-board Ethernet controller
+         for the Panther motherboard, which is one of the two shipped in the
+         Intel Professional Workstation.
+
+config MVME16x_NET
+       tristate "MVME16x Ethernet support"
+       depends on MVME16x
+       ---help---
+         This is the driver for the Ethernet interface on the Motorola
+         MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the
+         driver for this chip in your kernel.
+         To compile this driver as a module, choose M here.
+
+config NI52
+       tristate "NI5210 support"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ni52.
+
+config SNI_82596
+       tristate "SNI RM ethernet"
+       depends on SNI_RM
+       ---help---
+         Say Y here to support the on-board Intel 82596 ethernet controller
+         built into SNI RM machines.
+
+config SUN3_82586
+       bool "Sun3 on-board Intel 82586 support"
+       depends on SUN3
+       ---help---
+         This driver enables support for the on-board Intel 82586 based
+         Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards.  Note
+         that this driver does not support 82586-based adapters on additional
+         VME boards.
+
+config ZNET
+       tristate "Zenith Z-Note support (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && ISA_DMA_API
+       ---help---
+         The Zenith Z-Note notebook computer has a built-in network
+         (Ethernet) card, and this is the Linux driver for it. Note that the
+         IBM Thinkpad 300 is compatible with the Z-Note and is also supported
+         by this driver. Read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+endif # NET_VENDOR_I825XX
diff --git a/drivers/net/ethernet/i825xx/Makefile b/drivers/net/ethernet/i825xx/Makefile
new file mode 100644 (file)
index 0000000..f68a369
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Makefile for the Intel 82586/82593/82596 chipset device drivers.
+#
+
+obj-$(CONFIG_ARM_ETHER1) += ether1.o
+obj-$(CONFIG_EEXPRESS) += eexpress.o
+obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
+obj-$(CONFIG_ELPLUS) += 3c505.o
+obj-$(CONFIG_EL16) += 3c507.o
+obj-$(CONFIG_ELMC) += 3c523.o
+obj-$(CONFIG_ELMC_II) += 3c527.o
+obj-$(CONFIG_LP486E) += lp486e.o
+obj-$(CONFIG_NI52) += ni52.o
+obj-$(CONFIG_SUN3_82586) += sun3_82586.o
+obj-$(CONFIG_ZNET) += znet.o
+obj-$(CONFIG_APRICOT) += 82596.o
+obj-$(CONFIG_LASI_82596) += lasi_82596.o
+obj-$(CONFIG_SNI_82596) += sni_82596.o
+obj-$(CONFIG_MVME16x_NET) += 82596.o
+obj-$(CONFIG_BVME6000_NET) += 82596.o
similarity index 99%
rename from drivers/net/eepro.c
rename to drivers/net/ethernet/i825xx/eepro.c
index dfeb006035df60dd16add78680076e22caf566c4..067c46069a113aed9e8c9ac7220e3e6516599b97 100644 (file)
@@ -743,7 +743,7 @@ static const struct net_device_ops eepro_netdev_ops = {
        .ndo_open               = eepro_open,
        .ndo_stop               = eepro_close,
        .ndo_start_xmit         = eepro_send_packet,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = eepro_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/eexpress.c
rename to drivers/net/ethernet/i825xx/eexpress.c
index a19228563efd9e9b3e15ab029acf65947f1021c4..3a9580f3d4dd247f61054069a943b2384f399438 100644 (file)
@@ -1047,7 +1047,7 @@ static const struct net_device_ops eexp_netdev_ops = {
        .ndo_open               = eexp_open,
        .ndo_stop               = eexp_close,
        .ndo_start_xmit         = eexp_xmit,
-       .ndo_set_multicast_list = eexp_set_multicast,
+       .ndo_set_rx_mode        = eexp_set_multicast,
        .ndo_tx_timeout         = eexp_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/arm/ether1.c
rename to drivers/net/ethernet/i825xx/ether1.c
index b00781c02d5d40b8b2e1aece3bba6070f24872ea..42e90a97c7a5e6f965cdcc7e6615699a14f7f4e5 100644 (file)
@@ -985,7 +985,7 @@ static const struct net_device_ops ether1_netdev_ops = {
        .ndo_open               = ether1_open,
        .ndo_stop               = ether1_close,
        .ndo_start_xmit         = ether1_sendpacket,
-       .ndo_set_multicast_list = ether1_setmulticastlist,
+       .ndo_set_rx_mode        = ether1_setmulticastlist,
        .ndo_tx_timeout         = ether1_timeout,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/lib82596.c
rename to drivers/net/ethernet/i825xx/lib82596.c
index 9e042894479b6c5e74d9ef28c4540c2370bad0a9..3efbd8dbb63dd27b268167b9ad9538a455ef86c8 100644 (file)
@@ -1038,7 +1038,7 @@ static const struct net_device_ops i596_netdev_ops = {
        .ndo_open               = i596_open,
        .ndo_stop               = i596_close,
        .ndo_start_xmit         = i596_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = i596_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/lp486e.c
rename to drivers/net/ethernet/i825xx/lp486e.c
index 385a95311cd2c82a8a1e0298b9152da366195760..414044b3cb113e384ab2ed902305a9ec4e267ef7 100644 (file)
@@ -954,7 +954,7 @@ static const struct net_device_ops i596_netdev_ops = {
        .ndo_open               = i596_open,
        .ndo_stop               = i596_close,
        .ndo_start_xmit         = i596_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = i596_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/ni52.c
rename to drivers/net/ethernet/i825xx/ni52.c
index d973fc6c6b88a68095bcd12632d981f1ad946e3f..c0893715ef478c1d088e68971c3642d2921d4695 100644 (file)
@@ -445,7 +445,7 @@ static const struct net_device_ops ni52_netdev_ops = {
        .ndo_get_stats          = ni52_get_stats,
        .ndo_tx_timeout         = ni52_timeout,
        .ndo_start_xmit         = ni52_send_packet,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/sun3_82586.c
rename to drivers/net/ethernet/i825xx/sun3_82586.c
index b6ae53bada7500a92a18a7ebe3ec5b07ebed2c1c..6ef5e11d1c84a1f018e5b24344c7c4279b6bde16 100644 (file)
@@ -333,7 +333,7 @@ static const struct net_device_ops sun3_82586_netdev_ops = {
        .ndo_open               = sun3_82586_open,
        .ndo_stop               = sun3_82586_close,
        .ndo_start_xmit         = sun3_82586_send_packet,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_tx_timeout         = sun3_82586_timeout,
        .ndo_get_stats          = sun3_82586_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/znet.c
rename to drivers/net/ethernet/i825xx/znet.c
index 8b8881718f5e1b28699b25b847a921e29592dbc6..962b4c421f3fce4bcbf605b7aa1a18a9a94cf53c 100644 (file)
@@ -356,7 +356,7 @@ static const struct net_device_ops znet_netdev_ops = {
        .ndo_open               = znet_open,
        .ndo_stop               = znet_close,
        .ndo_start_xmit         = znet_send_packet,
-       .ndo_set_multicast_list = znet_set_multicast_list,
+       .ndo_set_rx_mode        = znet_set_multicast_list,
        .ndo_tx_timeout         = znet_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/ibm/Kconfig b/drivers/net/ethernet/ibm/Kconfig
new file mode 100644 (file)
index 0000000..4c7ef98
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# IBM device configuration.
+#
+
+config NET_VENDOR_IBM
+       bool "IBM devices"
+       depends on MCA || PPC_PSERIES || PPC_PSERIES || PPC_DCR || \
+                  (IBMEBUS && INET && SPARSEMEM)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about IBM devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_IBM
+
+config IBMVETH
+       tristate "IBM LAN Virtual Ethernet support"
+       depends on PPC_PSERIES
+       ---help---
+         This driver supports virtual ethernet adapters on newer IBM iSeries
+         and pSeries systems.
+
+         To compile this driver as a module, choose M here. The module will
+         be called ibmveth.
+
+config ISERIES_VETH
+       tristate "iSeries Virtual Ethernet driver support"
+       depends on PPC_ISERIES
+
+source "drivers/net/ethernet/ibm/emac/Kconfig"
+
+config EHEA
+       tristate "eHEA Ethernet support"
+       depends on IBMEBUS && INET && SPARSEMEM
+       select INET_LRO
+       ---help---
+         This driver supports the IBM pSeries eHEA ethernet adapter.
+
+         To compile the driver as a module, choose M here. The module
+         will be called ehea.
+
+endif # NET_VENDOR_IBM
diff --git a/drivers/net/ethernet/ibm/Makefile b/drivers/net/ethernet/ibm/Makefile
new file mode 100644 (file)
index 0000000..5a7d4e9
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for th IBM network device drivers.
+#
+
+obj-$(CONFIG_IBMVETH) += ibmveth.o
+obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
+obj-$(CONFIG_IBM_EMAC) += emac/
+obj-$(CONFIG_EHEA) += ehea/
similarity index 99%
rename from drivers/net/ehea/ehea_main.c
rename to drivers/net/ethernet/ibm/ehea/ehea_main.c
index be2cb4ab8b4f4b09cbd36b8c4f5fc3444466e05f..583bcd32e5436b7deaa2b063b514db13998350f4 100644 (file)
@@ -3161,7 +3161,7 @@ static const struct net_device_ops ehea_netdev_ops = {
        .ndo_get_stats          = ehea_get_stats,
        .ndo_set_mac_address    = ehea_set_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = ehea_set_multicast_list,
+       .ndo_set_rx_mode        = ehea_set_multicast_list,
        .ndo_change_mtu         = ehea_change_mtu,
        .ndo_vlan_rx_add_vid    = ehea_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ehea_vlan_rx_kill_vid,
similarity index 63%
rename from drivers/net/ibm_newemac/Kconfig
rename to drivers/net/ethernet/ibm/emac/Kconfig
index 78a1628c9892f71514cd781eed6a62b56fa0de48..3f44a30e0615080973f26e256f8a20bc31501cbc 100644 (file)
@@ -1,4 +1,4 @@
-config IBM_NEW_EMAC
+config IBM_EMAC
        tristate "IBM EMAC Ethernet support"
        depends on PPC_DCR
        select CRC32
@@ -7,29 +7,29 @@ config IBM_NEW_EMAC
          typically found on 4xx embedded PowerPC chips, but also on the
          Axon southbridge for Cell.
 
-config IBM_NEW_EMAC_RXB
+config IBM_EMAC_RXB
        int "Number of receive buffers"
-       depends on IBM_NEW_EMAC
+       depends on IBM_EMAC
        default "128"
 
-config IBM_NEW_EMAC_TXB
+config IBM_EMAC_TXB
        int "Number of transmit buffers"
-       depends on IBM_NEW_EMAC
+       depends on IBM_EMAC
        default "64"
 
-config IBM_NEW_EMAC_POLL_WEIGHT
+config IBM_EMAC_POLL_WEIGHT
        int "MAL NAPI polling weight"
-       depends on IBM_NEW_EMAC
+       depends on IBM_EMAC
        default "32"
 
-config IBM_NEW_EMAC_RX_COPY_THRESHOLD
+config IBM_EMAC_RX_COPY_THRESHOLD
        int "RX skb copy threshold (bytes)"
-       depends on IBM_NEW_EMAC
+       depends on IBM_EMAC
        default "256"
 
-config IBM_NEW_EMAC_RX_SKB_HEADROOM
+config IBM_EMAC_RX_SKB_HEADROOM
        int "Additional RX skb headroom (bytes)"
-       depends on IBM_NEW_EMAC
+       depends on IBM_EMAC
        default "0"
        help
          Additional receive skb headroom. Note, that driver
@@ -39,38 +39,38 @@ config IBM_NEW_EMAC_RX_SKB_HEADROOM
 
          If unsure, set to 0.
 
-config IBM_NEW_EMAC_DEBUG
+config IBM_EMAC_DEBUG
        bool "Debugging"
-       depends on IBM_NEW_EMAC
+       depends on IBM_EMAC
        default n
 
 # The options below has to be select'ed by the respective
 # processor types or platforms
 
-config IBM_NEW_EMAC_ZMII
+config IBM_EMAC_ZMII
        bool
        default n
 
-config IBM_NEW_EMAC_RGMII
+config IBM_EMAC_RGMII
        bool
        default n
 
-config IBM_NEW_EMAC_TAH
+config IBM_EMAC_TAH
        bool
        default n
 
-config IBM_NEW_EMAC_EMAC4
+config IBM_EMAC_EMAC4
        bool
        default n
 
-config IBM_NEW_EMAC_NO_FLOW_CTRL
+config IBM_EMAC_NO_FLOW_CTRL
        bool
        default n
 
-config IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
+config IBM_EMAC_MAL_CLR_ICINTSTAT
        bool
        default n
 
-config IBM_NEW_EMAC_MAL_COMMON_ERR
+config IBM_EMAC_MAL_COMMON_ERR
        bool
        default n
diff --git a/drivers/net/ethernet/ibm/emac/Makefile b/drivers/net/ethernet/ibm/emac/Makefile
new file mode 100644 (file)
index 0000000..eba2183
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the PowerPC 4xx on-chip ethernet driver
+#
+
+obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
+
+ibm_emac-y := mal.o core.o phy.o
+ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += zmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += rgmii.o
+ibm_emac-$(CONFIG_IBM_EMAC_TAH) += tah.o
+ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += debug.o
similarity index 99%
rename from drivers/net/ibm_newemac/core.c
rename to drivers/net/ethernet/ibm/emac/core.c
index 70cb7d8a3b53c6eeb10595455434a34836c9b44e..a573df1fafb66d67363befb04ec4d8abb2c8cfc4 100644 (file)
@@ -90,7 +90,7 @@ MODULE_LICENSE("GPL");
 /* If packet size is less than this number, we allocate small skb and copy packet
  * contents into it instead of just sending original big skb up
  */
-#define EMAC_RX_COPY_THRESH            CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD
+#define EMAC_RX_COPY_THRESH            CONFIG_IBM_EMAC_RX_COPY_THRESHOLD
 
 /* Since multiple EMACs share MDIO lines in various ways, we need
  * to avoid re-using the same PHY ID in cases where the arch didn't
@@ -1618,7 +1618,7 @@ static void emac_parse_rx_error(struct emac_instance *dev, u16 ctrl)
 static inline void emac_rx_csum(struct emac_instance *dev,
                                struct sk_buff *skb, u16 ctrl)
 {
-#ifdef CONFIG_IBM_NEW_EMAC_TAH
+#ifdef CONFIG_IBM_EMAC_TAH
        if (!ctrl && dev->tah_dev) {
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                ++dev->stats.rx_packets_csum;
@@ -2577,7 +2577,7 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                    of_device_is_compatible(np, "ibm,emac-440gr"))
                        dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
                if (of_device_is_compatible(np, "ibm,emac-405ez")) {
-#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL
+#ifdef CONFIG_IBM_EMAC_NO_FLOW_CTRL
                        dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x;
 #else
                        printk(KERN_ERR "%s: Flow control not disabled!\n",
@@ -2601,7 +2601,7 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 
        /* Enable TAH/ZMII/RGMII features as found */
        if (dev->tah_ph != 0) {
-#ifdef CONFIG_IBM_NEW_EMAC_TAH
+#ifdef CONFIG_IBM_EMAC_TAH
                dev->features |= EMAC_FTR_HAS_TAH;
 #else
                printk(KERN_ERR "%s: TAH support not enabled !\n",
@@ -2611,7 +2611,7 @@ static int __devinit emac_init_config(struct emac_instance *dev)
        }
 
        if (dev->zmii_ph != 0) {
-#ifdef CONFIG_IBM_NEW_EMAC_ZMII
+#ifdef CONFIG_IBM_EMAC_ZMII
                dev->features |= EMAC_FTR_HAS_ZMII;
 #else
                printk(KERN_ERR "%s: ZMII support not enabled !\n",
@@ -2621,7 +2621,7 @@ static int __devinit emac_init_config(struct emac_instance *dev)
        }
 
        if (dev->rgmii_ph != 0) {
-#ifdef CONFIG_IBM_NEW_EMAC_RGMII
+#ifdef CONFIG_IBM_EMAC_RGMII
                dev->features |= EMAC_FTR_HAS_RGMII;
 #else
                printk(KERN_ERR "%s: RGMII support not enabled !\n",
@@ -2661,7 +2661,7 @@ static const struct net_device_ops emac_netdev_ops = {
        .ndo_open               = emac_open,
        .ndo_stop               = emac_close,
        .ndo_get_stats          = emac_stats,
-       .ndo_set_multicast_list = emac_set_multicast_list,
+       .ndo_set_rx_mode        = emac_set_multicast_list,
        .ndo_do_ioctl           = emac_ioctl,
        .ndo_tx_timeout         = emac_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
@@ -2674,7 +2674,7 @@ static const struct net_device_ops emac_gige_netdev_ops = {
        .ndo_open               = emac_open,
        .ndo_stop               = emac_close,
        .ndo_get_stats          = emac_stats,
-       .ndo_set_multicast_list = emac_set_multicast_list,
+       .ndo_set_rx_mode        = emac_set_multicast_list,
        .ndo_do_ioctl           = emac_ioctl,
        .ndo_tx_timeout         = emac_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 97%
rename from drivers/net/ibm_newemac/core.h
rename to drivers/net/ethernet/ibm/emac/core.h
index 4fec0844d59dffd34496428a900deb5d0641c3d4..fa3ec57935fafa74537c0bc5b61fc3ee9d0f363f 100644 (file)
@@ -47,8 +47,8 @@
 #include "tah.h"
 #include "debug.h"
 
-#define NUM_TX_BUFF                    CONFIG_IBM_NEW_EMAC_TXB
-#define NUM_RX_BUFF                    CONFIG_IBM_NEW_EMAC_RXB
+#define NUM_TX_BUFF                    CONFIG_IBM_EMAC_TXB
+#define NUM_RX_BUFF                    CONFIG_IBM_EMAC_RXB
 
 /* Simple sanity check */
 #if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256
@@ -72,7 +72,7 @@ static inline int emac_rx_size(int mtu)
 #define EMAC_DMA_ALIGN(x)              ALIGN((x), dma_get_cache_alignment())
 
 #define EMAC_RX_SKB_HEADROOM           \
-       EMAC_DMA_ALIGN(CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM)
+       EMAC_DMA_ALIGN(CONFIG_IBM_EMAC_RX_SKB_HEADROOM)
 
 /* Size of RX skb for the given MTU */
 static inline int emac_rx_skb_size(int mtu)
@@ -335,21 +335,21 @@ enum {
        EMAC_FTRS_ALWAYS        = 0,
 
        EMAC_FTRS_POSSIBLE      =
-#ifdef CONFIG_IBM_NEW_EMAC_EMAC4
+#ifdef CONFIG_IBM_EMAC_EMAC4
            EMAC_FTR_EMAC4      | EMAC_FTR_EMAC4SYNC    |
            EMAC_FTR_HAS_NEW_STACR      |
            EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
 #endif
-#ifdef CONFIG_IBM_NEW_EMAC_TAH
+#ifdef CONFIG_IBM_EMAC_TAH
            EMAC_FTR_HAS_TAH    |
 #endif
-#ifdef CONFIG_IBM_NEW_EMAC_ZMII
+#ifdef CONFIG_IBM_EMAC_ZMII
            EMAC_FTR_HAS_ZMII   |
 #endif
-#ifdef CONFIG_IBM_NEW_EMAC_RGMII
+#ifdef CONFIG_IBM_EMAC_RGMII
            EMAC_FTR_HAS_RGMII  |
 #endif
-#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL
+#ifdef CONFIG_IBM_EMAC_NO_FLOW_CTRL
            EMAC_FTR_NO_FLOW_CONTROL_40x |
 #endif
        EMAC_FTR_460EX_PHY_CLK_FIX |
similarity index 98%
rename from drivers/net/ibm_newemac/debug.h
rename to drivers/net/ethernet/ibm/emac/debug.h
index e596c77ccdf7ea54e1fb64054bc89f1b3ac07a6b..90477fe69d0ce83df515e5c8be9e4db374907afa 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "core.h"
 
-#if defined(CONFIG_IBM_NEW_EMAC_DEBUG)
+#if defined(CONFIG_IBM_EMAC_DEBUG)
 
 struct emac_instance;
 struct mal_instance;
similarity index 99%
rename from drivers/net/ibm_newemac/mal.c
rename to drivers/net/ethernet/ibm/emac/mal.c
index d268f404b7b0388a97ca45944c12edf613e125cf..f3c50b97ec61b589b4f45d472881a0a62cba469d 100644 (file)
@@ -577,8 +577,8 @@ static int __devinit mal_probe(struct platform_device *ofdev)
        }
 
        if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-405ez")) {
-#if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \
-               defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR)
+#if defined(CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT) && \
+               defined(CONFIG_IBM_EMAC_MAL_COMMON_ERR)
                mal->features |= (MAL_FTR_CLEAR_ICINTSTAT |
                                MAL_FTR_COMMON_ERR_INT);
 #else
@@ -616,7 +616,7 @@ static int __devinit mal_probe(struct platform_device *ofdev)
        init_dummy_netdev(&mal->dummy_dev);
 
        netif_napi_add(&mal->dummy_dev, &mal->napi, mal_poll,
-                      CONFIG_IBM_NEW_EMAC_POLL_WEIGHT);
+                      CONFIG_IBM_EMAC_POLL_WEIGHT);
 
        /* Load power-on reset defaults */
        mal_reset(mal);
similarity index 99%
rename from drivers/net/ibm_newemac/mal.h
rename to drivers/net/ethernet/ibm/emac/mal.h
index 66084214bf455ff56f0f4fae0c1110f84d99c502..d06f985bda321aac1277a30297e1b2f9527d02e3 100644 (file)
@@ -245,10 +245,10 @@ enum {
        MAL_FTRS_ALWAYS = 0,
 
        MAL_FTRS_POSSIBLE =
-#ifdef CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
+#ifdef CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT
                MAL_FTR_CLEAR_ICINTSTAT |
 #endif
-#ifdef CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR
+#ifdef CONFIG_IBM_EMAC_MAL_COMMON_ERR
                MAL_FTR_COMMON_ERR_INT |
 #endif
                0,
similarity index 96%
rename from drivers/net/ibm_newemac/rgmii.h
rename to drivers/net/ethernet/ibm/emac/rgmii.h
index d69799049865c9ab8c3861208ca201c5bbe14494..9296b6c5f92054033235c06f1f965c4ddcce648e 100644 (file)
@@ -54,7 +54,7 @@ struct rgmii_instance {
        struct platform_device          *ofdev;
 };
 
-#ifdef CONFIG_IBM_NEW_EMAC_RGMII
+#ifdef CONFIG_IBM_EMAC_RGMII
 
 extern int rgmii_init(void);
 extern void rgmii_exit(void);
@@ -77,6 +77,6 @@ extern void *rgmii_dump_regs(struct platform_device *ofdev, void *buf);
 # define rgmii_set_speed(x,y,z)        do { } while(0)
 # define rgmii_get_regs_len(x) 0
 # define rgmii_dump_regs(x,buf)        (buf)
-#endif                         /* !CONFIG_IBM_NEW_EMAC_RGMII */
+#endif                         /* !CONFIG_IBM_EMAC_RGMII */
 
 #endif /* __IBM_NEWEMAC_RGMII_H */
similarity index 97%
rename from drivers/net/ibm_newemac/tah.h
rename to drivers/net/ethernet/ibm/emac/tah.h
index 61dbeca006d14707f0f66f7e37f4975f6b4eeabf..3437ab4964c713e76bc5d17d6099237d5af7d0bf 100644 (file)
@@ -70,7 +70,7 @@ struct tah_instance {
 #define TAH_MR_DTFP            0x00100000
 #define TAH_MR_DIG             0x00080000
 
-#ifdef CONFIG_IBM_NEW_EMAC_TAH
+#ifdef CONFIG_IBM_EMAC_TAH
 
 extern int tah_init(void);
 extern void tah_exit(void);
@@ -90,6 +90,6 @@ extern void *tah_dump_regs(struct platform_device *ofdev, void *buf);
 # define tah_get_regs_len(x)   0
 # define tah_dump_regs(x,buf)  (buf)
 
-#endif                         /* !CONFIG_IBM_NEW_EMAC_TAH */
+#endif                         /* !CONFIG_IBM_EMAC_TAH */
 
 #endif /* __IBM_NEWEMAC_TAH_H */
similarity index 96%
rename from drivers/net/ibm_newemac/zmii.h
rename to drivers/net/ethernet/ibm/emac/zmii.h
index 1333fa2b278182d20eaa2b119959b8a4d935c2de..ceaed823a83c081edbef4a24838bbf34ec797043 100644 (file)
@@ -51,7 +51,7 @@ struct zmii_instance {
        struct platform_device          *ofdev;
 };
 
-#ifdef CONFIG_IBM_NEW_EMAC_ZMII
+#ifdef CONFIG_IBM_EMAC_ZMII
 
 extern int zmii_init(void);
 extern void zmii_exit(void);
@@ -73,6 +73,6 @@ extern void *zmii_dump_regs(struct platform_device *ofdev, void *buf);
 # define zmii_set_speed(x,y,z) do { } while(0)
 # define zmii_get_regs_len(x)  0
 # define zmii_dump_regs(x,buf) (buf)
-#endif                         /* !CONFIG_IBM_NEW_EMAC_ZMII */
+#endif                         /* !CONFIG_IBM_EMAC_ZMII */
 
 #endif /* __IBM_NEWEMAC_ZMII_H */
similarity index 99%
rename from drivers/net/ibmveth.c
rename to drivers/net/ethernet/ibm/ibmveth.c
index ba99af05bf62744148a4d33d008c04ddece97a98..bba1ffcd92d1f212d5c98495c866efbfbc302f3e 100644 (file)
@@ -1299,7 +1299,7 @@ static const struct net_device_ops ibmveth_netdev_ops = {
        .ndo_open               = ibmveth_open,
        .ndo_stop               = ibmveth_close,
        .ndo_start_xmit         = ibmveth_start_xmit,
-       .ndo_set_multicast_list = ibmveth_set_multicast_list,
+       .ndo_set_rx_mode        = ibmveth_set_multicast_list,
        .ndo_do_ioctl           = ibmveth_ioctl,
        .ndo_change_mtu         = ibmveth_change_mtu,
        .ndo_fix_features       = ibmveth_fix_features,
similarity index 99%
rename from drivers/net/iseries_veth.c
rename to drivers/net/ethernet/ibm/iseries_veth.c
index 53dd39e9130ef7372b01d0c1b0b31b236708a9ff..4326681df382ac461c24e21eb6a6ea0ee64d4426 100644 (file)
@@ -1009,7 +1009,7 @@ static const struct net_device_ops veth_netdev_ops = {
        .ndo_stop               = veth_close,
        .ndo_start_xmit         = veth_start_xmit,
        .ndo_change_mtu         = veth_change_mtu,
-       .ndo_set_multicast_list = veth_set_multicast_list,
+       .ndo_set_rx_mode        = veth_set_multicast_list,
        .ndo_set_mac_address    = NULL,
        .ndo_validate_addr      = eth_validate_addr,
 };
diff --git a/drivers/net/ethernet/icplus/Kconfig b/drivers/net/ethernet/icplus/Kconfig
new file mode 100644 (file)
index 0000000..e888222
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# IC Plus device configuration
+#
+
+config IP1000
+       tristate "IP1000 Gigabit Ethernet support"
+       depends on PCI && EXPERIMENTAL
+       select MII
+       ---help---
+         This driver supports IP1000 gigabit Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called ipg.  This is recommended.
diff --git a/drivers/net/ethernet/icplus/Makefile b/drivers/net/ethernet/icplus/Makefile
new file mode 100644 (file)
index 0000000..5bc87c1
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the IC Plus device drivers
+#
+
+obj-$(CONFIG_IP1000) += ipg.o
similarity index 92%
rename from drivers/net/ipg.c
rename to drivers/net/ethernet/icplus/ipg.c
index d4aa40adf1e95430e408896b36083780764d1d2d..8fd80a00b898333af18d76aa0c44bc4f22b3b8f5 100644 (file)
@@ -20,6 +20,9 @@
  *   http://www.icplus.com.tw
  *   jesse@icplus.com.tw
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
@@ -67,7 +70,7 @@ MODULE_LICENSE("GPL");
  * Variable record -- index by leading revision/length
  * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
  */
-static unsigned short DefaultPhyParam[] = {
+static const unsigned short DefaultPhyParam[] = {
        /* 11/12/03 IP1000A v1-3 rev=0x40 */
        /*--------------------------------------------------------------------------
        (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
@@ -85,7 +88,7 @@ static unsigned short DefaultPhyParam[] = {
        0x0000
 };
 
-static const char *ipg_brand_name[] = {
+static const char * const ipg_brand_name[] = {
        "IC PLUS IP1000 1000/100/10 based NIC",
        "Sundance Technology ST2021 based NIC",
        "Tamarack Microelectronics TC9020/9021 based NIC",
@@ -118,23 +121,23 @@ static void ipg_dump_rfdlist(struct net_device *dev)
 
        IPG_DEBUG_MSG("_dump_rfdlist\n");
 
-       printk(KERN_INFO "rx_current = %2.2x\n", sp->rx_current);
-       printk(KERN_INFO "rx_dirty   = %2.2x\n", sp->rx_dirty);
-       printk(KERN_INFO "RFDList start address = %16.16lx\n",
-              (unsigned long) sp->rxd_map);
-       printk(KERN_INFO "RFDListPtr register   = %8.8x%8.8x\n",
-              ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0));
+       netdev_info(dev, "rx_current = %02x\n", sp->rx_current);
+       netdev_info(dev, "rx_dirty   = %02x\n", sp->rx_dirty);
+       netdev_info(dev, "RFDList start address = %016lx\n",
+                   (unsigned long)sp->rxd_map);
+       netdev_info(dev, "RFDListPtr register   = %08x%08x\n",
+                   ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0));
 
        for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
                offset = (u32) &sp->rxd[i].next_desc - (u32) sp->rxd;
-               printk(KERN_INFO "%2.2x %4.4x RFDNextPtr = %16.16lx\n", i,
-                      offset, (unsigned long) sp->rxd[i].next_desc);
+               netdev_info(dev, "%02x %04x RFDNextPtr = %016lx\n",
+                           i, offset, (unsigned long)sp->rxd[i].next_desc);
                offset = (u32) &sp->rxd[i].rfs - (u32) sp->rxd;
-               printk(KERN_INFO "%2.2x %4.4x RFS        = %16.16lx\n", i,
-                      offset, (unsigned long) sp->rxd[i].rfs);
+               netdev_info(dev, "%02x %04x RFS        = %016lx\n",
+                           i, offset, (unsigned long)sp->rxd[i].rfs);
                offset = (u32) &sp->rxd[i].frag_info - (u32) sp->rxd;
-               printk(KERN_INFO "%2.2x %4.4x frag_info   = %16.16lx\n", i,
-                      offset, (unsigned long) sp->rxd[i].frag_info);
+               netdev_info(dev, "%02x %04x frag_info   = %016lx\n",
+                           i, offset, (unsigned long)sp->rxd[i].frag_info);
        }
 }
 
@@ -147,24 +150,24 @@ static void ipg_dump_tfdlist(struct net_device *dev)
 
        IPG_DEBUG_MSG("_dump_tfdlist\n");
 
-       printk(KERN_INFO "tx_current         = %2.2x\n", sp->tx_current);
-       printk(KERN_INFO "tx_dirty = %2.2x\n", sp->tx_dirty);
-       printk(KERN_INFO "TFDList start address = %16.16lx\n",
-              (unsigned long) sp->txd_map);
-       printk(KERN_INFO "TFDListPtr register   = %8.8x%8.8x\n",
-              ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0));
+       netdev_info(dev, "tx_current         = %02x\n", sp->tx_current);
+       netdev_info(dev, "tx_dirty = %02x\n", sp->tx_dirty);
+       netdev_info(dev, "TFDList start address = %016lx\n",
+                   (unsigned long) sp->txd_map);
+       netdev_info(dev, "TFDListPtr register   = %08x%08x\n",
+                   ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0));
 
        for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
                offset = (u32) &sp->txd[i].next_desc - (u32) sp->txd;
-               printk(KERN_INFO "%2.2x %4.4x TFDNextPtr = %16.16lx\n", i,
-                      offset, (unsigned long) sp->txd[i].next_desc);
+               netdev_info(dev, "%02x %04x TFDNextPtr = %016lx\n",
+                           i, offset, (unsigned long)sp->txd[i].next_desc);
 
                offset = (u32) &sp->txd[i].tfc - (u32) sp->txd;
-               printk(KERN_INFO "%2.2x %4.4x TFC        = %16.16lx\n", i,
-                      offset, (unsigned long) sp->txd[i].tfc);
+               netdev_info(dev, "%02x %04x TFC        = %016lx\n",
+                           i, offset, (unsigned long) sp->txd[i].tfc);
                offset = (u32) &sp->txd[i].frag_info - (u32) sp->txd;
-               printk(KERN_INFO "%2.2x %4.4x frag_info   = %16.16lx\n", i,
-                      offset, (unsigned long) sp->txd[i].frag_info);
+               netdev_info(dev, "%02x %04x frag_info   = %016lx\n",
+                           i, offset, (unsigned long) sp->txd[i].frag_info);
        }
 }
 #endif
@@ -480,6 +483,10 @@ static int ipg_config_autoneg(struct net_device *dev)
        u32 mac_ctrl_val;
        u32 asicctrl;
        u8 phyctrl;
+       const char *speed;
+       const char *duplex;
+       const char *tx_desc;
+       const char *rx_desc;
 
        IPG_DEBUG_MSG("_config_autoneg\n");
 
@@ -499,27 +506,27 @@ static int ipg_config_autoneg(struct net_device *dev)
         */
        sp->tenmbpsmode = 0;
 
-       printk(KERN_INFO "%s: Link speed = ", dev->name);
-
        /* Determine actual speed of operation. */
        switch (phyctrl & IPG_PC_LINK_SPEED) {
        case IPG_PC_LINK_SPEED_10MBPS:
-               printk("10Mbps.\n");
-               printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n",
-                      dev->name);
+               speed = "10Mbps";
                sp->tenmbpsmode = 1;
                break;
        case IPG_PC_LINK_SPEED_100MBPS:
-               printk("100Mbps.\n");
+               speed = "100Mbps";
                break;
        case IPG_PC_LINK_SPEED_1000MBPS:
-               printk("1000Mbps.\n");
+               speed = "1000Mbps";
                break;
        default:
-               printk("undefined!\n");
+               speed = "undefined!";
                return 0;
        }
 
+       netdev_info(dev, "Link speed = %s\n", speed);
+       if (sp->tenmbpsmode == 1)
+               netdev_info(dev, "10Mbps operational mode enabled\n");
+
        if (phyctrl & IPG_PC_DUPLEX_STATUS) {
                fullduplex = 1;
                txflowcontrol = 1;
@@ -528,38 +535,41 @@ static int ipg_config_autoneg(struct net_device *dev)
 
        /* Configure full duplex, and flow control. */
        if (fullduplex == 1) {
+
                /* Configure IPG for full duplex operation. */
-               printk(KERN_INFO "%s: setting full duplex, ", dev->name);
+
+               duplex = "full";
 
                mac_ctrl_val |= IPG_MC_DUPLEX_SELECT_FD;
 
                if (txflowcontrol == 1) {
-                       printk("TX flow control");
+                       tx_desc  = "";
                        mac_ctrl_val |= IPG_MC_TX_FLOW_CONTROL_ENABLE;
                } else {
-                       printk("no TX flow control");
+                       tx_desc = "no ";
                        mac_ctrl_val &= ~IPG_MC_TX_FLOW_CONTROL_ENABLE;
                }
 
                if (rxflowcontrol == 1) {
-                       printk(", RX flow control.");
+                       rx_desc = "";
                        mac_ctrl_val |= IPG_MC_RX_FLOW_CONTROL_ENABLE;
                } else {
-                       printk(", no RX flow control.");
+                       rx_desc = "no ";
                        mac_ctrl_val &= ~IPG_MC_RX_FLOW_CONTROL_ENABLE;
                }
-
-               printk("\n");
        } else {
-               /* Configure IPG for half duplex operation. */
-               printk(KERN_INFO "%s: setting half duplex, "
-                      "no TX flow control, no RX flow control.\n", dev->name);
-
-               mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD &
-                       ~IPG_MC_TX_FLOW_CONTROL_ENABLE &
-                       ~IPG_MC_RX_FLOW_CONTROL_ENABLE;
+               duplex = "half";
+               tx_desc = "no ";
+               rx_desc = "no ";
+               mac_ctrl_val &= (~IPG_MC_DUPLEX_SELECT_FD &
+                                ~IPG_MC_TX_FLOW_CONTROL_ENABLE &
+                                ~IPG_MC_RX_FLOW_CONTROL_ENABLE);
        }
+
+       netdev_info(dev, "setting %s duplex, %sTX, %sRX flow control\n",
+                   duplex, tx_desc, rx_desc);
        ipg_w32(mac_ctrl_val, MAC_CTRL);
+
        return 0;
 }
 
@@ -784,14 +794,13 @@ static int init_rfdlist(struct net_device *dev)
                         * A receive buffer was not ready, break the
                         * RFD list here.
                         */
-                       IPG_DEBUG_MSG("Cannot allocate Rx buffer.\n");
+                       IPG_DEBUG_MSG("Cannot allocate Rx buffer\n");
 
                        /* Just in case we cannot allocate a single RFD.
                         * Should not occur.
                         */
                        if (i == 0) {
-                               printk(KERN_ERR "%s: No memory available"
-                                       " for RFD list.\n", dev->name);
+                               netdev_err(dev, "No memory available for RFD list\n");
                                return -ENOMEM;
                        }
                }
@@ -838,7 +847,7 @@ static void init_tfdlist(struct net_device *dev)
        sp->tx_dirty = 0;
 
        /* Write the location of the TFDList to the IPG. */
-       IPG_DDEBUG_MSG("Starting TFDListPtr = %8.8x\n",
+       IPG_DDEBUG_MSG("Starting TFDListPtr = %08x\n",
                       (u32) sp->txd_map);
        ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0);
        ipg_w32(0x00000000, TFD_LIST_PTR_1);
@@ -864,7 +873,7 @@ static void ipg_nic_txfree(struct net_device *dev)
                struct sk_buff *skb = sp->tx_buff[dirty];
                struct ipg_tx *txfd = sp->txd + dirty;
 
-               IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc);
+               IPG_DEBUG_MSG("TFC = %016lx\n", (unsigned long) txfd->tfc);
 
                /* Look at each TFD's TFC field beginning
                 * at the last freed TFD up to the current TFD.
@@ -906,10 +915,8 @@ static void ipg_tx_timeout(struct net_device *dev)
        spin_lock_irq(&sp->lock);
 
        /* Re-configure after DMA reset. */
-       if (ipg_io_config(dev) < 0) {
-               printk(KERN_INFO "%s: Error during re-configuration.\n",
-                      dev->name);
-       }
+       if (ipg_io_config(dev) < 0)
+               netdev_info(dev, "Error during re-configuration\n");
 
        init_tfdlist(dev);
 
@@ -938,7 +945,7 @@ static void ipg_nic_txcleanup(struct net_device *dev)
                 */
                u32 txstatusdword = ipg_r32(TX_STATUS);
 
-               IPG_DEBUG_MSG("TxStatus = %8.8x\n", txstatusdword);
+               IPG_DEBUG_MSG("TxStatus = %08x\n", txstatusdword);
 
                /* Check for Transmit errors. Error bits only valid if
                 * TX_COMPLETE bit in the TXSTATUS register is a 1.
@@ -953,20 +960,20 @@ static void ipg_nic_txcleanup(struct net_device *dev)
 
                /* Transmit error, increment stat counters. */
                if (txstatusdword & IPG_TS_TX_ERROR) {
-                       IPG_DEBUG_MSG("Transmit error.\n");
+                       IPG_DEBUG_MSG("Transmit error\n");
                        sp->stats.tx_errors++;
                }
 
                /* Late collision, re-enable transmitter. */
                if (txstatusdword & IPG_TS_LATE_COLLISION) {
-                       IPG_DEBUG_MSG("Late collision on transmit.\n");
+                       IPG_DEBUG_MSG("Late collision on transmit\n");
                        ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
                                IPG_MC_RSVD_MASK, MAC_CTRL);
                }
 
                /* Maximum collisions, re-enable transmitter. */
                if (txstatusdword & IPG_TS_TX_MAX_COLL) {
-                       IPG_DEBUG_MSG("Maximum collisions on transmit.\n");
+                       IPG_DEBUG_MSG("Maximum collisions on transmit\n");
                        ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
                                IPG_MC_RSVD_MASK, MAC_CTRL);
                }
@@ -975,16 +982,14 @@ static void ipg_nic_txcleanup(struct net_device *dev)
                 * transmitter.
                 */
                if (txstatusdword & IPG_TS_TX_UNDERRUN) {
-                       IPG_DEBUG_MSG("Transmitter underrun.\n");
+                       IPG_DEBUG_MSG("Transmitter underrun\n");
                        sp->stats.tx_fifo_errors++;
                        ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA |
                                  IPG_AC_NETWORK | IPG_AC_FIFO);
 
                        /* Re-configure after DMA reset. */
                        if (ipg_io_config(dev) < 0) {
-                               printk(KERN_INFO
-                                      "%s: Error during re-configuration.\n",
-                                      dev->name);
+                               netdev_info(dev, "Error during re-configuration\n");
                        }
                        init_tfdlist(dev);
 
@@ -1063,7 +1068,7 @@ static int ipg_nic_rxrestore(struct net_device *dev)
                 * Linux system).
                 */
                if (ipg_get_rxbuff(dev, entry) < 0) {
-                       IPG_DEBUG_MSG("Cannot allocate new Rx buffer.\n");
+                       IPG_DEBUG_MSG("Cannot allocate new Rx buffer\n");
 
                        break;
                }
@@ -1134,7 +1139,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev)
             (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME |
              IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |
              IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))) {
-               IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",
+               IPG_DEBUG_MSG("Rx error, RFS = %016lx\n",
                              (unsigned long) rxfd->rfs);
 
                /* Increment general receive error statistic. */
@@ -1142,13 +1147,13 @@ static int ipg_nic_rx_check_error(struct net_device *dev)
 
                /* Increment detailed receive error statistics. */
                if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) {
-                       IPG_DEBUG_MSG("RX FIFO overrun occurred.\n");
+                       IPG_DEBUG_MSG("RX FIFO overrun occurred\n");
 
                        sp->stats.rx_fifo_errors++;
                }
 
                if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) {
-                       IPG_DEBUG_MSG("RX runt occurred.\n");
+                       IPG_DEBUG_MSG("RX runt occurred\n");
                        sp->stats.rx_length_errors++;
                }
 
@@ -1157,7 +1162,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev)
                 */
 
                if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) {
-                       IPG_DEBUG_MSG("RX alignment error occurred.\n");
+                       IPG_DEBUG_MSG("RX alignment error occurred\n");
                        sp->stats.rx_frame_errors++;
                }
 
@@ -1404,7 +1409,7 @@ static int ipg_nic_rx(struct net_device *dev)
                 */
                if (framelen > sp->rxfrag_size) {
                        IPG_DEBUG_MSG
-                           ("RFS FrameLen > allocated fragment size.\n");
+                           ("RFS FrameLen > allocated fragment size\n");
 
                        framelen = sp->rxfrag_size;
                }
@@ -1414,7 +1419,7 @@ static int ipg_nic_rx(struct net_device *dev)
                        IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |
                        IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR)))) {
 
-                       IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",
+                       IPG_DEBUG_MSG("Rx error, RFS = %016lx\n",
                                      (unsigned long int) rxfd->rfs);
 
                        /* Increment general receive error statistic. */
@@ -1422,12 +1427,12 @@ static int ipg_nic_rx(struct net_device *dev)
 
                        /* Increment detailed receive error statistics. */
                        if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) {
-                               IPG_DEBUG_MSG("RX FIFO overrun occurred.\n");
+                               IPG_DEBUG_MSG("RX FIFO overrun occurred\n");
                                sp->stats.rx_fifo_errors++;
                        }
 
                        if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) {
-                               IPG_DEBUG_MSG("RX runt occurred.\n");
+                               IPG_DEBUG_MSG("RX runt occurred\n");
                                sp->stats.rx_length_errors++;
                        }
 
@@ -1437,7 +1442,7 @@ static int ipg_nic_rx(struct net_device *dev)
                         */
 
                        if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) {
-                               IPG_DEBUG_MSG("RX alignment error occurred.\n");
+                               IPG_DEBUG_MSG("RX alignment error occurred\n");
                                sp->stats.rx_frame_errors++;
                        }
 
@@ -1508,7 +1513,7 @@ static int ipg_nic_rx(struct net_device *dev)
 
                rxfd = sp->rxd + entry;
 
-               IPG_DEBUG_MSG("Frame requires multiple RFDs.\n");
+               IPG_DEBUG_MSG("Frame requires multiple RFDs\n");
 
                /* An unexpected event, additional code needed to handle
                 * properly. So for the time being, just disregard the
@@ -1557,8 +1562,7 @@ static void ipg_reset_after_host_error(struct work_struct *work)
        init_tfdlist(dev);
 
        if (ipg_io_config(dev) < 0) {
-               printk(KERN_INFO "%s: Cannot recover from PCI error.\n",
-                      dev->name);
+               netdev_info(dev, "Cannot recover from PCI error\n");
                schedule_delayed_work(&sp->task, HZ);
        }
 }
@@ -1586,7 +1590,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
         */
        status = ipg_r16(INT_STATUS_ACK);
 
-       IPG_DEBUG_MSG("IntStatusAck = %4.4x\n", status);
+       IPG_DEBUG_MSG("IntStatusAck = %04x\n", status);
 
        /* Shared IRQ of remove event. */
        if (!(status & IPG_IS_RSVD_MASK))
@@ -1599,7 +1603,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
 
        /* If RFDListEnd interrupt, restore all used RFDs. */
        if (status & IPG_IS_RFD_LIST_END) {
-               IPG_DEBUG_MSG("RFDListEnd Interrupt.\n");
+               IPG_DEBUG_MSG("RFDListEnd Interrupt\n");
 
                /* The RFD list end indicates an RFD was encountered
                 * with a 0 NextPtr, or with an RFDDone bit set to 1
@@ -1661,21 +1665,20 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
        /* If LinkEvent interrupt, resolve autonegotiation. */
        if (status & IPG_IS_LINK_EVENT) {
                if (ipg_config_autoneg(dev) < 0)
-                       printk(KERN_INFO "%s: Auto-negotiation error.\n",
-                              dev->name);
+                       netdev_info(dev, "Auto-negotiation error\n");
        }
 
        /* If MACCtrlFrame interrupt, do nothing. */
        if (status & IPG_IS_MAC_CTRL_FRAME)
-               IPG_DEBUG_MSG("MACCtrlFrame interrupt.\n");
+               IPG_DEBUG_MSG("MACCtrlFrame interrupt\n");
 
        /* If RxComplete interrupt, do nothing. */
        if (status & IPG_IS_RX_COMPLETE)
-               IPG_DEBUG_MSG("RxComplete interrupt.\n");
+               IPG_DEBUG_MSG("RxComplete interrupt\n");
 
        /* If RxEarly interrupt, do nothing. */
        if (status & IPG_IS_RX_EARLY)
-               IPG_DEBUG_MSG("RxEarly interrupt.\n");
+               IPG_DEBUG_MSG("RxEarly interrupt\n");
 
 out_enable:
        /* Re-enable IPG interrupts. */
@@ -1749,8 +1752,7 @@ static int ipg_nic_open(struct net_device *dev)
        rc = request_irq(pdev->irq, ipg_interrupt_handler, IRQF_SHARED,
                         dev->name, dev);
        if (rc < 0) {
-               printk(KERN_INFO "%s: Error when requesting interrupt.\n",
-                      dev->name);
+               netdev_info(dev, "Error when requesting interrupt\n");
                goto out;
        }
 
@@ -1770,8 +1772,7 @@ static int ipg_nic_open(struct net_device *dev)
 
        rc = init_rfdlist(dev);
        if (rc < 0) {
-               printk(KERN_INFO "%s: Error during configuration.\n",
-                      dev->name);
+               netdev_info(dev, "Error during configuration\n");
                goto err_free_tx_2;
        }
 
@@ -1779,14 +1780,13 @@ static int ipg_nic_open(struct net_device *dev)
 
        rc = ipg_io_config(dev);
        if (rc < 0) {
-               printk(KERN_INFO "%s: Error during configuration.\n",
-                      dev->name);
+               netdev_info(dev, "Error during configuration\n");
                goto err_release_tfdlist_3;
        }
 
        /* Resolve autonegotiation. */
        if (ipg_config_autoneg(dev) < 0)
-               printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name);
+               netdev_info(dev, "Auto-negotiation error\n");
 
        /* initialize JUMBO Frame control variable */
        sp->jumbo.found_start = 0;
@@ -1961,7 +1961,7 @@ static void ipg_set_phy_default_param(unsigned char rev,
 {
        unsigned short length;
        unsigned char revision;
-       unsigned short *phy_param;
+       const unsigned short *phy_param;
        unsigned short address, value;
 
        phy_param = &DefaultPhyParam[0];
@@ -2201,7 +2201,7 @@ static const struct net_device_ops ipg_netdev_ops = {
        .ndo_stop               = ipg_nic_stop,
        .ndo_start_xmit         = ipg_nic_hard_start_xmit,
        .ndo_get_stats          = ipg_nic_get_stats,
-       .ndo_set_multicast_list = ipg_nic_set_multicast_list,
+       .ndo_set_rx_mode        = ipg_nic_set_multicast_list,
        .ndo_do_ioctl           = ipg_ioctl,
        .ndo_tx_timeout         = ipg_tx_timeout,
        .ndo_change_mtu         = ipg_nic_change_mtu,
@@ -2222,7 +2222,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
        if (rc < 0)
                goto out;
 
-       printk(KERN_INFO "%s: %s\n", pci_name(pdev), ipg_brand_name[i]);
+       pr_info("%s: %s\n", pci_name(pdev), ipg_brand_name[i]);
 
        pci_set_master(pdev);
 
@@ -2230,8 +2230,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
        if (rc < 0) {
                rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc < 0) {
-                       printk(KERN_ERR "%s: DMA config failed.\n",
-                              pci_name(pdev));
+                       pr_err("%s: DMA config failed\n", pci_name(pdev));
                        goto err_disable_0;
                }
        }
@@ -2241,7 +2240,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
         */
        dev = alloc_etherdev(sizeof(struct ipg_nic_private));
        if (!dev) {
-               printk(KERN_ERR "%s: alloc_etherdev failed\n", pci_name(pdev));
+               pr_err("%s: alloc_etherdev failed\n", pci_name(pdev));
                rc = -ENOMEM;
                goto err_disable_0;
        }
@@ -2267,7 +2266,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
 
        ioaddr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
        if (!ioaddr) {
-               printk(KERN_ERR "%s cannot map MMIO\n", pci_name(pdev));
+               pr_err("%s: cannot map MMIO\n", pci_name(pdev));
                rc = -EIO;
                goto err_release_regions_2;
        }
@@ -2289,7 +2288,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
        if (rc < 0)
                goto err_unmap_3;
 
-       printk(KERN_INFO "Ethernet device registered as: %s\n", dev->name);
+       netdev_info(dev, "Ethernet device registered\n");
 out:
        return rc;
 
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
new file mode 100644 (file)
index 0000000..5fe185b
--- /dev/null
@@ -0,0 +1,220 @@
+#
+# Intel network device configuration
+#
+
+config NET_VENDOR_INTEL
+       bool "Intel devices"
+       depends on PCI || PCI_MSI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Intel cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_INTEL
+
+config E100
+       tristate "Intel(R) PRO/100+ support"
+       depends on PCI
+       select MII
+       ---help---
+         This driver supports Intel(R) PRO/100 family of adapters.
+         To verify that your adapter is supported, find the board ID number
+         on the adapter. Look for a label that has a barcode and a number
+         in the format 123456-001 (six digits hyphen three digits).
+
+         Use the above information and the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         to identify the adapter.
+
+         For the latest Intel PRO/100 network driver for Linux, see:
+
+         <http://www.intel.com/p/en_US/support/highlights/network/pro100plus>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e100.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called e100.
+
+config E1000
+       tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) PRO/1000 gigabit ethernet family of
+         adapters.  For more information on how to identify your adapter, go
+         to the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e1000.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called e1000.
+
+config E1000E
+       tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
+       depends on PCI && (!SPARC32 || BROKEN)
+       select CRC32
+       ---help---
+         This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
+         ethernet family of adapters. For PCI or PCI-X e1000 adapters,
+         use the regular e1000 driver For more information on how to
+         identify your adapter, go to the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         To compile this driver as a module, choose M here. The module
+         will be called e1000e.
+
+config IGB
+       tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) 82575/82576 gigabit ethernet family of
+         adapters.  For more information on how to identify your adapter, go
+         to the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e1000.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called igb.
+
+config IGB_DCA
+       bool "Direct Cache Access (DCA) Support"
+       default y
+       depends on IGB && DCA && !(IGB=y && DCA=m)
+       ---help---
+         Say Y here if you want to use Direct Cache Access (DCA) in the
+         driver.  DCA is a method for warming the CPU cache before data
+         is used, with the intent of lessening the impact of cache misses.
+
+config IGBVF
+       tristate "Intel(R) 82576 Virtual Function Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) 82576 virtual functions.  For more
+         information on how to identify your adapter, go to the Adapter &
+         Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e1000.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called igbvf.
+
+config IXGB
+       tristate "Intel(R) PRO/10GbE support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) PRO/10GbE family of adapters for
+         PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver
+         instead. For more information on how to identify your adapter, go
+         to the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/ixgb.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ixgb.
+
+config IXGBE
+       tristate "Intel(R) 10GbE PCI Express adapters support"
+       depends on PCI && INET
+       select MDIO
+       ---help---
+         This driver supports Intel(R) 10GbE PCI Express family of
+         adapters.  For more information on how to identify your adapter, go
+         to the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         To compile this driver as a module, choose M here. The module
+         will be called ixgbe.
+
+config IXGBE_DCA
+       bool "Direct Cache Access (DCA) Support"
+       default y
+       depends on IXGBE && DCA && !(IXGBE=y && DCA=m)
+       ---help---
+         Say Y here if you want to use Direct Cache Access (DCA) in the
+         driver.  DCA is a method for warming the CPU cache before data
+         is used, with the intent of lessening the impact of cache misses.
+
+config IXGBE_DCB
+       bool "Data Center Bridging (DCB) Support"
+       default n
+       depends on IXGBE && DCB
+       ---help---
+         Say Y here if you want to use Data Center Bridging (DCB) in the
+         driver.
+
+         If unsure, say N.
+
+config IXGBEVF
+       tristate "Intel(R) 82599 Virtual Function Ethernet support"
+       depends on PCI_MSI
+       ---help---
+         This driver supports Intel(R) 82599 virtual functions.  For more
+         information on how to identify your adapter, go to the Adapter &
+         Driver ID Guide at:
+
+         <http://support.intel.com/support/network/sb/CS-008441.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/ixgbevf.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ixgbevf.  MSI-X interrupt support is required
+         for this driver to work correctly.
+
+endif # NET_VENDOR_INTEL
diff --git a/drivers/net/ethernet/intel/Makefile b/drivers/net/ethernet/intel/Makefile
new file mode 100644 (file)
index 0000000..c8210e6
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for the Intel network device drivers.
+#
+
+obj-$(CONFIG_E100) += e100.o
+obj-$(CONFIG_E1000) += e1000/
+obj-$(CONFIG_E1000E) += e1000e/
+obj-$(CONFIG_IGB) += igb/
+obj-$(CONFIG_IGBVF) += igbvf/
+obj-$(CONFIG_IXGBE) += ixgbe/
+obj-$(CONFIG_IXGBEVF) += ixgbevf/
+obj-$(CONFIG_IXGB) += ixgb/
similarity index 99%
rename from drivers/net/e100.c
rename to drivers/net/ethernet/intel/e100.c
index c1352c60c29945a8e2d1d0063bf1dd09eeb1cdd1..fe87d3eea5edf8e64302e20692845f30275fb718 100644 (file)
@@ -2738,7 +2738,7 @@ static const struct net_device_ops e100_netdev_ops = {
        .ndo_stop               = e100_close,
        .ndo_start_xmit         = e100_xmit_frame,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = e100_set_multicast_list,
+       .ndo_set_rx_mode        = e100_set_multicast_list,
        .ndo_set_mac_address    = e100_set_mac_address,
        .ndo_change_mtu         = e100_change_mtu,
        .ndo_do_ioctl           = e100_do_ioctl,
similarity index 99%
rename from drivers/net/e1000/e1000_main.c
rename to drivers/net/ethernet/intel/e1000/e1000_main.c
index f97afda941d727a2b6e2afb8370ac46847c08b4d..7c280e5832b2023a543ef7bba5b4855e7067bdf5 100644 (file)
@@ -1080,6 +1080,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        netdev->vlan_features |= NETIF_F_HW_CSUM;
        netdev->vlan_features |= NETIF_F_SG;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
 
        /* initialize eeprom parameters */
similarity index 96%
rename from drivers/net/e1000e/Makefile
rename to drivers/net/ethernet/intel/e1000e/Makefile
index 28519acacd2d28f4eea74fd0fe4239c9d6ff1aa7..948c05db5d68cdc6318e814c5711948125eb4687 100644 (file)
@@ -32,6 +32,6 @@
 
 obj-$(CONFIG_E1000E) += e1000e.o
 
-e1000e-objs := 82571.o ich8lan.o es2lan.o \
+e1000e-objs := 82571.o ich8lan.o 80003es2lan.o \
               lib.o phy.o param.o ethtool.o netdev.o
 
similarity index 99%
rename from drivers/net/e1000e/e1000.h
rename to drivers/net/ethernet/intel/e1000e/e1000.h
index 35916f485028d4617f0e7c86860a1d1b82edf585..fa72052a00317fbd46967f37c904934605ec613c 100644 (file)
@@ -155,6 +155,9 @@ struct e1000_info;
 #define HV_M_STATUS_SPEED_1000            0x0200
 #define HV_M_STATUS_LINK_UP               0x0040
 
+#define E1000_ICH_FWSM_PCIM2PCI                0x01000000 /* ME PCIm-to-PCI active */
+#define E1000_ICH_FWSM_PCIM2PCI_COUNT  2000
+
 /* Time to wait before putting the device into D3 if there's no link (in ms). */
 #define LINK_TIMEOUT           100
 
@@ -454,11 +457,13 @@ struct e1000_info {
 #define FLAG2_DISABLE_AIM                 (1 << 8)
 #define FLAG2_CHECK_PHY_HANG              (1 << 9)
 #define FLAG2_NO_DISABLE_RX               (1 << 10)
+#define FLAG2_PCIM2PCI_ARBITER_WA         (1 << 11)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
+#define E1000_RX_DESC_EXT(R, i)            \
+       (&(((union e1000_rx_desc_extended *)((R).desc))[i]))
 #define E1000_GET_DESC(R, i, type)     (&(((struct type *)((R).desc))[i]))
-#define E1000_RX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_rx_desc)
 #define E1000_TX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_tx_desc)
 #define E1000_CONTEXT_DESC(R, i)       E1000_GET_DESC(R, i, e1000_context_desc)
 
similarity index 99%
rename from drivers/net/e1000e/ethtool.c
rename to drivers/net/ethernet/intel/e1000e/ethtool.c
index 6a0526a59a8a38ce00e8c0aaeb9795db02d11d97..e0cbd6a0bde8b21dc90271d6226b38a53dd0bed4 100644 (file)
@@ -1195,7 +1195,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
                goto err_nomem;
        }
 
-       rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc);
+       rx_ring->size = rx_ring->count * sizeof(union e1000_rx_desc_extended);
        rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
                                           &rx_ring->dma, GFP_KERNEL);
        if (!rx_ring->desc) {
@@ -1221,7 +1221,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
        ew32(RCTL, rctl);
 
        for (i = 0; i < rx_ring->count; i++) {
-               struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
+               union e1000_rx_desc_extended *rx_desc;
                struct sk_buff *skb;
 
                skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL);
@@ -1239,8 +1239,9 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
                        ret_val = 8;
                        goto err_nomem;
                }
-               rx_desc->buffer_addr =
-                       cpu_to_le64(rx_ring->buffer_info[i].dma);
+               rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
+               rx_desc->read.buffer_addr =
+                   cpu_to_le64(rx_ring->buffer_info[i].dma);
                memset(skb->data, 0x00, skb->len);
        }
 
similarity index 98%
rename from drivers/net/e1000e/ich8lan.c
rename to drivers/net/ethernet/intel/e1000e/ich8lan.c
index 4e36978b8fd8f11c2042d611165a28b119111ad1..54add27c8f760ae871858f837d6d956ee2387f03 100644 (file)
 #define HV_PM_CTRL             PHY_REG(770, 17)
 
 /* PHY Low Power Idle Control */
-#define I82579_LPI_CTRL                        PHY_REG(772, 20)
-#define I82579_LPI_CTRL_ENABLE_MASK    0x6000
+#define I82579_LPI_CTRL                                PHY_REG(772, 20)
+#define I82579_LPI_CTRL_ENABLE_MASK            0x6000
+#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT   0x80
 
 /* EMI Registers */
 #define I82579_EMI_ADDR         0x10
 #define HV_KMRN_MODE_CTRL      PHY_REG(769, 16)
 #define HV_KMRN_MDIO_SLOW      0x0400
 
+/* KMRN FIFO Control and Status */
+#define HV_KMRN_FIFO_CTRLSTA                  PHY_REG(770, 16)
+#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK    0x7000
+#define HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT   12
+
 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
 /* Offset 04h HSFSTS */
 union ich8_hws_flash_status {
@@ -657,6 +663,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
        struct e1000_mac_info *mac = &hw->mac;
        s32 ret_val;
        bool link;
+       u16 phy_reg;
 
        /*
         * We only want to go out to the PHY registers to see if Auto-Neg
@@ -689,16 +696,35 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 
        mac->get_link_status = false;
 
-       if (hw->phy.type == e1000_phy_82578) {
-               ret_val = e1000_link_stall_workaround_hv(hw);
-               if (ret_val)
-                       goto out;
-       }
-
-       if (hw->mac.type == e1000_pch2lan) {
+       switch (hw->mac.type) {
+       case e1000_pch2lan:
                ret_val = e1000_k1_workaround_lv(hw);
                if (ret_val)
                        goto out;
+               /* fall-thru */
+       case e1000_pchlan:
+               if (hw->phy.type == e1000_phy_82578) {
+                       ret_val = e1000_link_stall_workaround_hv(hw);
+                       if (ret_val)
+                               goto out;
+               }
+
+               /*
+                * Workaround for PCHx parts in half-duplex:
+                * Set the number of preambles removed from the packet
+                * when it is passed from the PHY to the MAC to prevent
+                * the MAC from misinterpreting the packet type.
+                */
+               e1e_rphy(hw, HV_KMRN_FIFO_CTRLSTA, &phy_reg);
+               phy_reg &= ~HV_KMRN_FIFO_CTRLSTA_PREAMBLE_MASK;
+
+               if ((er32(STATUS) & E1000_STATUS_FD) != E1000_STATUS_FD)
+                       phy_reg |= (1 << HV_KMRN_FIFO_CTRLSTA_PREAMBLE_SHIFT);
+
+               e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, phy_reg);
+               break;
+       default:
+               break;
        }
 
        /*
@@ -788,6 +814,11 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
            (adapter->hw.phy.type == e1000_phy_igp_3))
                adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
 
+       /* Enable workaround for 82579 w/ ME enabled */
+       if ((adapter->hw.mac.type == e1000_pch2lan) &&
+           (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+               adapter->flags2 |= FLAG2_PCIM2PCI_ARBITER_WA;
+
        /* Disable EEE by default until IEEE802.3az spec is finalized */
        if (adapter->flags2 & FLAG2_HAS_EEE)
                adapter->hw.dev_spec.ich8lan.eee_disable = true;
@@ -1355,7 +1386,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
                        return ret_val;
 
                /* Preamble tuning for SSC */
-               ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204);
+               ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204);
                if (ret_val)
                        return ret_val;
        }
@@ -1645,6 +1676,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
        s32 ret_val = 0;
        u16 status_reg = 0;
        u32 mac_reg;
+       u16 phy_reg;
 
        if (hw->mac.type != e1000_pch2lan)
                goto out;
@@ -1659,12 +1691,19 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
                mac_reg = er32(FEXTNVM4);
                mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
 
-               if (status_reg & HV_M_STATUS_SPEED_1000)
+               ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
+               if (ret_val)
+                       goto out;
+
+               if (status_reg & HV_M_STATUS_SPEED_1000) {
                        mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
-               else
+                       phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
+               } else {
                        mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
-
+                       phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT;
+               }
                ew32(FEXTNVM4, mac_reg);
+               ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
        }
 
 out:
similarity index 96%
rename from drivers/net/e1000e/netdev.c
rename to drivers/net/ethernet/intel/e1000e/netdev.c
index 362f70382cdd411483ad95ec26af24b0a08e198e..48edd1656d798b06eac5b710a0493e72e7f5edc5 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/if_vlan.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/aer.h>
 #include <linux/prefetch.h>
@@ -56,7 +56,7 @@
 
 #define DRV_EXTRAVERSION "-k"
 
-#define DRV_VERSION "1.4.4" DRV_EXTRAVERSION
+#define DRV_VERSION "1.5.1" DRV_EXTRAVERSION
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -192,7 +192,7 @@ static void e1000e_dump(struct e1000_adapter *adapter)
        struct e1000_buffer *buffer_info;
        struct e1000_ring *rx_ring = adapter->rx_ring;
        union e1000_rx_desc_packet_split *rx_desc_ps;
-       struct e1000_rx_desc *rx_desc;
+       union e1000_rx_desc_extended *rx_desc;
        struct my_u1 {
                u64 a;
                u64 b;
@@ -399,41 +399,70 @@ rx_ring_summary:
                break;
        default:
        case 0:
-               /* Legacy Receive Descriptor Format
+               /* Extended Receive Descriptor (Read) Format
                 *
-                * +-----------------------------------------------------+
-                * |                Buffer Address [63:0]                |
-                * +-----------------------------------------------------+
-                * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
-                * +-----------------------------------------------------+
-                * 63       48 47    40 39      32 31         16 15      0
+                *   +-----------------------------------------------------+
+                * 0 |                Buffer Address [63:0]                |
+                *   +-----------------------------------------------------+
+                * 8 |                      Reserved                       |
+                *   +-----------------------------------------------------+
                 */
-               printk(KERN_INFO "Rl[desc]     [address 63:0  ] "
-                      "[vl er S cks ln] [bi->dma       ] [bi->skb] "
-                      "<-- Legacy format\n");
-               for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
-                       rx_desc = E1000_RX_DESC(*rx_ring, i);
+               printk(KERN_INFO "R  [desc]      [buf addr 63:0 ] "
+                      "[reserved 63:0 ] [bi->dma       ] "
+                      "[bi->skb] <-- Ext (Read) format\n");
+               /* Extended Receive Descriptor (Write-Back) Format
+                *
+                *   63       48 47    32 31    24 23            4 3        0
+                *   +------------------------------------------------------+
+                *   |     RSS Hash      |        |               |         |
+                * 0 +-------------------+  Rsvd  |   Reserved    | MRQ RSS |
+                *   | Packet   | IP     |        |               |  Type   |
+                *   | Checksum | Ident  |        |               |         |
+                *   +------------------------------------------------------+
+                * 8 | VLAN Tag | Length | Extended Error | Extended Status |
+                *   +------------------------------------------------------+
+                *   63       48 47    32 31            20 19               0
+                */
+               printk(KERN_INFO "RWB[desc]      [cs ipid    mrq] "
+                      "[vt   ln xe  xs] "
+                      "[bi->skb] <-- Ext (Write-Back) format\n");
+
+               for (i = 0; i < rx_ring->count; i++) {
                        buffer_info = &rx_ring->buffer_info[i];
-                       u0 = (struct my_u0 *)rx_desc;
-                       printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX "
-                              "%016llX %p", i,
-                              (unsigned long long)le64_to_cpu(u0->a),
-                              (unsigned long long)le64_to_cpu(u0->b),
-                              (unsigned long long)buffer_info->dma,
-                              buffer_info->skb);
+                       rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
+                       u1 = (struct my_u1 *)rx_desc;
+                       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+                       if (staterr & E1000_RXD_STAT_DD) {
+                               /* Descriptor Done */
+                               printk(KERN_INFO "RWB[0x%03X]     %016llX "
+                                      "%016llX ---------------- %p", i,
+                                      (unsigned long long)le64_to_cpu(u1->a),
+                                      (unsigned long long)le64_to_cpu(u1->b),
+                                      buffer_info->skb);
+                       } else {
+                               printk(KERN_INFO "R  [0x%03X]     %016llX "
+                                      "%016llX %016llX %p", i,
+                                      (unsigned long long)le64_to_cpu(u1->a),
+                                      (unsigned long long)le64_to_cpu(u1->b),
+                                      (unsigned long long)buffer_info->dma,
+                                      buffer_info->skb);
+
+                               if (netif_msg_pktdata(adapter))
+                                       print_hex_dump(KERN_INFO, "",
+                                                      DUMP_PREFIX_ADDRESS, 16,
+                                                      1,
+                                                      phys_to_virt
+                                                      (buffer_info->dma),
+                                                      adapter->rx_buffer_len,
+                                                      true);
+                       }
+
                        if (i == rx_ring->next_to_use)
                                printk(KERN_CONT " NTU\n");
                        else if (i == rx_ring->next_to_clean)
                                printk(KERN_CONT " NTC\n");
                        else
                                printk(KERN_CONT "\n");
-
-                       if (netif_msg_pktdata(adapter))
-                               print_hex_dump(KERN_INFO, "",
-                                              DUMP_PREFIX_ADDRESS,
-                                              16, 1,
-                                              phys_to_virt(buffer_info->dma),
-                                              adapter->rx_buffer_len, true);
                }
        }
 
@@ -519,7 +548,64 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
 }
 
 /**
- * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
+ * e1000e_update_tail_wa - helper function for e1000e_update_[rt]dt_wa()
+ * @hw: pointer to the HW structure
+ * @tail: address of tail descriptor register
+ * @i: value to write to tail descriptor register
+ *
+ * When updating the tail register, the ME could be accessing Host CSR
+ * registers at the same time.  Normally, this is handled in h/w by an
+ * arbiter but on some parts there is a bug that acknowledges Host accesses
+ * later than it should which could result in the descriptor register to
+ * have an incorrect value.  Workaround this by checking the FWSM register
+ * which has bit 24 set while ME is accessing Host CSR registers, wait
+ * if it is set and try again a number of times.
+ **/
+static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail,
+                                       unsigned int i)
+{
+       unsigned int j = 0;
+
+       while ((j++ < E1000_ICH_FWSM_PCIM2PCI_COUNT) &&
+              (er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI))
+               udelay(50);
+
+       writel(i, tail);
+
+       if ((j == E1000_ICH_FWSM_PCIM2PCI_COUNT) && (i != readl(tail)))
+               return E1000_ERR_SWFW_SYNC;
+
+       return 0;
+}
+
+static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i)
+{
+       u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail);
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (e1000e_update_tail_wa(hw, tail, i)) {
+               u32 rctl = er32(RCTL);
+               ew32(RCTL, rctl & ~E1000_RCTL_EN);
+               e_err("ME firmware caused invalid RDT - resetting\n");
+               schedule_work(&adapter->reset_task);
+       }
+}
+
+static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i)
+{
+       u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail);
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (e1000e_update_tail_wa(hw, tail, i)) {
+               u32 tctl = er32(TCTL);
+               ew32(TCTL, tctl & ~E1000_TCTL_EN);
+               e_err("ME firmware caused invalid TDT - resetting\n");
+               schedule_work(&adapter->reset_task);
+       }
+}
+
+/**
+ * e1000_alloc_rx_buffers - Replace used receive buffers
  * @adapter: address of board private structure
  **/
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
@@ -528,7 +614,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_ring *rx_ring = adapter->rx_ring;
-       struct e1000_rx_desc *rx_desc;
+       union e1000_rx_desc_extended *rx_desc;
        struct e1000_buffer *buffer_info;
        struct sk_buff *skb;
        unsigned int i;
@@ -562,8 +648,8 @@ map_skb:
                        break;
                }
 
-               rx_desc = E1000_RX_DESC(*rx_ring, i);
-               rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+               rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
+               rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
 
                if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
                        /*
@@ -573,7 +659,10 @@ map_skb:
                         * such as IA-64).
                         */
                        wmb();
-                       writel(i, adapter->hw.hw_addr + rx_ring->tail);
+                       if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
+                               e1000e_update_rdt_wa(adapter, i);
+                       else
+                               writel(i, adapter->hw.hw_addr + rx_ring->tail);
                }
                i++;
                if (i == rx_ring->count)
@@ -673,7 +762,11 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                         * such as IA-64).
                         */
                        wmb();
-                       writel(i << 1, adapter->hw.hw_addr + rx_ring->tail);
+                       if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
+                               e1000e_update_rdt_wa(adapter, i << 1);
+                       else
+                               writel(i << 1,
+                                      adapter->hw.hw_addr + rx_ring->tail);
                }
 
                i++;
@@ -697,7 +790,7 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
 {
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
-       struct e1000_rx_desc *rx_desc;
+       union e1000_rx_desc_extended *rx_desc;
        struct e1000_ring *rx_ring = adapter->rx_ring;
        struct e1000_buffer *buffer_info;
        struct sk_buff *skb;
@@ -738,8 +831,8 @@ check_page:
                                                        PAGE_SIZE,
                                                        DMA_FROM_DEVICE);
 
-               rx_desc = E1000_RX_DESC(*rx_ring, i);
-               rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+               rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
+               rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
 
                if (unlikely(++i == rx_ring->count))
                        i = 0;
@@ -756,7 +849,10 @@ check_page:
                 * applicable for weak-ordered memory model archs,
                 * such as IA-64). */
                wmb();
-               writel(i, adapter->hw.hw_addr + rx_ring->tail);
+               if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
+                       e1000e_update_rdt_wa(adapter, i);
+               else
+                       writel(i, adapter->hw.hw_addr + rx_ring->tail);
        }
 }
 
@@ -774,28 +870,27 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_hw *hw = &adapter->hw;
        struct e1000_ring *rx_ring = adapter->rx_ring;
-       struct e1000_rx_desc *rx_desc, *next_rxd;
+       union e1000_rx_desc_extended *rx_desc, *next_rxd;
        struct e1000_buffer *buffer_info, *next_buffer;
-       u32 length;
+       u32 length, staterr;
        unsigned int i;
        int cleaned_count = 0;
        bool cleaned = 0;
        unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 
        i = rx_ring->next_to_clean;
-       rx_desc = E1000_RX_DESC(*rx_ring, i);
+       rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
+       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
        buffer_info = &rx_ring->buffer_info[i];
 
-       while (rx_desc->status & E1000_RXD_STAT_DD) {
+       while (staterr & E1000_RXD_STAT_DD) {
                struct sk_buff *skb;
-               u8 status;
 
                if (*work_done >= work_to_do)
                        break;
                (*work_done)++;
                rmb();  /* read descriptor and rx_buffer_info after status DD */
 
-               status = rx_desc->status;
                skb = buffer_info->skb;
                buffer_info->skb = NULL;
 
@@ -804,7 +899,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                i++;
                if (i == rx_ring->count)
                        i = 0;
-               next_rxd = E1000_RX_DESC(*rx_ring, i);
+               next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
                prefetch(next_rxd);
 
                next_buffer = &rx_ring->buffer_info[i];
@@ -817,7 +912,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                                 DMA_FROM_DEVICE);
                buffer_info->dma = 0;
 
-               length = le16_to_cpu(rx_desc->length);
+               length = le16_to_cpu(rx_desc->wb.upper.length);
 
                /*
                 * !EOP means multiple descriptors were used to store a single
@@ -826,7 +921,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                 * next frame that _does_ have the EOP bit set, as it is by
                 * definition only a frame fragment
                 */
-               if (unlikely(!(status & E1000_RXD_STAT_EOP)))
+               if (unlikely(!(staterr & E1000_RXD_STAT_EOP)))
                        adapter->flags2 |= FLAG2_IS_DISCARDING;
 
                if (adapter->flags2 & FLAG2_IS_DISCARDING) {
@@ -834,12 +929,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                        e_dbg("Receive packet consumed multiple buffers\n");
                        /* recycle */
                        buffer_info->skb = skb;
-                       if (status & E1000_RXD_STAT_EOP)
+                       if (staterr & E1000_RXD_STAT_EOP)
                                adapter->flags2 &= ~FLAG2_IS_DISCARDING;
                        goto next_desc;
                }
 
-               if (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
+               if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
                        /* recycle */
                        buffer_info->skb = skb;
                        goto next_desc;
@@ -877,15 +972,15 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                skb_put(skb, length);
 
                /* Receive Checksum Offload */
-               e1000_rx_checksum(adapter,
-                                 (u32)(status) |
-                                 ((u32)(rx_desc->errors) << 24),
-                                 le16_to_cpu(rx_desc->csum), skb);
+               e1000_rx_checksum(adapter, staterr,
+                                 le16_to_cpu(rx_desc->wb.lower.hi_dword.
+                                             csum_ip.csum), skb);
 
-               e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special);
+               e1000_receive_skb(adapter, netdev, skb, staterr,
+                                 rx_desc->wb.upper.vlan);
 
 next_desc:
-               rx_desc->status = 0;
+               rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
 
                /* return some buffers to hardware, one at a time is too slow */
                if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
@@ -897,6 +992,8 @@ next_desc:
                /* use prefetched values */
                rx_desc = next_rxd;
                buffer_info = next_buffer;
+
+               staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
        }
        rx_ring->next_to_clean = i;
 
@@ -1280,35 +1377,34 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_ring *rx_ring = adapter->rx_ring;
-       struct e1000_rx_desc *rx_desc, *next_rxd;
+       union e1000_rx_desc_extended *rx_desc, *next_rxd;
        struct e1000_buffer *buffer_info, *next_buffer;
-       u32 length;
+       u32 length, staterr;
        unsigned int i;
        int cleaned_count = 0;
        bool cleaned = false;
        unsigned int total_rx_bytes=0, total_rx_packets=0;
 
        i = rx_ring->next_to_clean;
-       rx_desc = E1000_RX_DESC(*rx_ring, i);
+       rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
+       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
        buffer_info = &rx_ring->buffer_info[i];
 
-       while (rx_desc->status & E1000_RXD_STAT_DD) {
+       while (staterr & E1000_RXD_STAT_DD) {
                struct sk_buff *skb;
-               u8 status;
 
                if (*work_done >= work_to_do)
                        break;
                (*work_done)++;
                rmb();  /* read descriptor and rx_buffer_info after status DD */
 
-               status = rx_desc->status;
                skb = buffer_info->skb;
                buffer_info->skb = NULL;
 
                ++i;
                if (i == rx_ring->count)
                        i = 0;
-               next_rxd = E1000_RX_DESC(*rx_ring, i);
+               next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
                prefetch(next_rxd);
 
                next_buffer = &rx_ring->buffer_info[i];
@@ -1319,23 +1415,22 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
                               DMA_FROM_DEVICE);
                buffer_info->dma = 0;
 
-               length = le16_to_cpu(rx_desc->length);
+               length = le16_to_cpu(rx_desc->wb.upper.length);
 
                /* errors is only valid for DD + EOP descriptors */
-               if (unlikely((status & E1000_RXD_STAT_EOP) &&
-                   (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
-                               /* recycle both page and skb */
-                               buffer_info->skb = skb;
-                               /* an error means any chain goes out the window
-                                * too */
-                               if (rx_ring->rx_skb_top)
-                                       dev_kfree_skb_irq(rx_ring->rx_skb_top);
-                               rx_ring->rx_skb_top = NULL;
-                               goto next_desc;
+               if (unlikely((staterr & E1000_RXD_STAT_EOP) &&
+                            (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK))) {
+                       /* recycle both page and skb */
+                       buffer_info->skb = skb;
+                       /* an error means any chain goes out the window too */
+                       if (rx_ring->rx_skb_top)
+                               dev_kfree_skb_irq(rx_ring->rx_skb_top);
+                       rx_ring->rx_skb_top = NULL;
+                       goto next_desc;
                }
 
 #define rxtop (rx_ring->rx_skb_top)
-               if (!(status & E1000_RXD_STAT_EOP)) {
+               if (!(staterr & E1000_RXD_STAT_EOP)) {
                        /* this descriptor is only the beginning (or middle) */
                        if (!rxtop) {
                                /* this is the beginning of a chain */
@@ -1390,10 +1485,9 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
                }
 
                /* Receive Checksum Offload XXX recompute due to CRC strip? */
-               e1000_rx_checksum(adapter,
-                                 (u32)(status) |
-                                 ((u32)(rx_desc->errors) << 24),
-                                 le16_to_cpu(rx_desc->csum), skb);
+               e1000_rx_checksum(adapter, staterr,
+                                 le16_to_cpu(rx_desc->wb.lower.hi_dword.
+                                             csum_ip.csum), skb);
 
                /* probably a little skewed due to removing CRC */
                total_rx_bytes += skb->len;
@@ -1406,11 +1500,11 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
                        goto next_desc;
                }
 
-               e1000_receive_skb(adapter, netdev, skb, status,
-                                 rx_desc->special);
+               e1000_receive_skb(adapter, netdev, skb, staterr,
+                                 rx_desc->wb.upper.vlan);
 
 next_desc:
-               rx_desc->status = 0;
+               rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
 
                /* return some buffers to hardware, one at a time is too slow */
                if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
@@ -1422,6 +1516,8 @@ next_desc:
                /* use prefetched values */
                rx_desc = next_rxd;
                buffer_info = next_buffer;
+
+               staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
        }
        rx_ring->next_to_clean = i;
 
@@ -2820,6 +2916,10 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                break;
        }
 
+       /* Enable Extended Status in all Receive Descriptors */
+       rfctl = er32(RFCTL);
+       rfctl |= E1000_RFCTL_EXTEN;
+
        /*
         * 82571 and greater support packet-split where the protocol
         * header is placed in skb->data and the packet data is
@@ -2845,9 +2945,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
        if (adapter->rx_ps_pages) {
                u32 psrctl = 0;
 
-               /* Configure extra packet-split registers */
-               rfctl = er32(RFCTL);
-               rfctl |= E1000_RFCTL_EXTEN;
                /*
                 * disable packet split support for IPv6 extension headers,
                 * because some malformed IPv6 headers can hang the Rx
@@ -2855,8 +2952,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
                          E1000_RFCTL_NEW_IPV6_EXT_DIS);
 
-               ew32(RFCTL, rfctl);
-
                /* Enable Packet split descriptors */
                rctl |= E1000_RCTL_DTYP_PS;
 
@@ -2879,6 +2974,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                ew32(PSRCTL, psrctl);
        }
 
+       ew32(RFCTL, rfctl);
        ew32(RCTL, rctl);
        /* just started the receive unit, no need to restart */
        adapter->flags &= ~FLAG_RX_RESTART_NOW;
@@ -2904,11 +3000,11 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
                adapter->clean_rx = e1000_clean_rx_irq_ps;
                adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
        } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
-               rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
+               rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
                adapter->clean_rx = e1000_clean_jumbo_rx_irq;
                adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
        } else {
-               rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
+               rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
                adapter->clean_rx = e1000_clean_rx_irq;
                adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
        }
@@ -4689,7 +4785,12 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
        wmb();
 
        tx_ring->next_to_use = i;
-       writel(i, adapter->hw.hw_addr + tx_ring->tail);
+
+       if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
+               e1000e_update_tdt_wa(adapter, i);
+       else
+               writel(i, adapter->hw.hw_addr + tx_ring->tail);
+
        /*
         * we need this if more than one processor can write to our tail
         * at a time, it synchronizes IO on IA64/Altix systems
@@ -5764,7 +5865,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
        .ndo_stop               = e1000_close,
        .ndo_start_xmit         = e1000_xmit_frame,
        .ndo_get_stats64        = e1000e_get_stats64,
-       .ndo_set_multicast_list = e1000_set_multi,
+       .ndo_set_rx_mode        = e1000_set_multi,
        .ndo_set_mac_address    = e1000_set_mac,
        .ndo_change_mtu         = e1000_change_mtu,
        .ndo_do_ioctl           = e1000_ioctl,
similarity index 99%
rename from drivers/net/igb/igb_main.c
rename to drivers/net/ethernet/intel/igb/igb_main.c
index 40d4c405fd7e0218703c091619a632b8525cd2c6..801608497409139a3ab5b8a50e6f2a980d209912 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/net_tstamp.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
@@ -1789,7 +1790,6 @@ static const struct net_device_ops igb_netdev_ops = {
        .ndo_start_xmit         = igb_xmit_frame_adv,
        .ndo_get_stats64        = igb_get_stats64,
        .ndo_set_rx_mode        = igb_set_rx_mode,
-       .ndo_set_multicast_list = igb_set_rx_mode,
        .ndo_set_mac_address    = igb_set_mac,
        .ndo_change_mtu         = igb_change_mtu,
        .ndo_do_ioctl           = igb_ioctl,
@@ -1973,6 +1973,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                netdev->features |= NETIF_F_SCTP_CSUM;
        }
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        adapter->en_mng_pt = igb_enable_mng_pass_thru(hw);
 
        /* before reading the NVM, reset the controller to put the device in a
similarity index 99%
rename from drivers/net/igbvf/netdev.c
rename to drivers/net/ethernet/intel/igbvf/netdev.c
index 40ed066e3ef48177cca4725405c53b78cd6af786..a6bdb3c744f0d1fb1c60e865c0956b786fac34fe 100644 (file)
@@ -2538,7 +2538,7 @@ static const struct net_device_ops igbvf_netdev_ops = {
        .ndo_stop                       = igbvf_close,
        .ndo_start_xmit                 = igbvf_xmit_frame,
        .ndo_get_stats                  = igbvf_get_stats,
-       .ndo_set_multicast_list         = igbvf_set_multi,
+       .ndo_set_rx_mode                = igbvf_set_multi,
        .ndo_set_mac_address            = igbvf_set_mac,
        .ndo_change_mtu                 = igbvf_change_mtu,
        .ndo_do_ioctl                   = igbvf_ioctl,
similarity index 99%
rename from drivers/net/ixgb/ixgb_main.c
rename to drivers/net/ethernet/intel/ixgb/ixgb_main.c
index 6a130eb51cfaef41c556f81b5f19bfc26a3f926b..b8ef2c0fc5d0d7e86ef65e99aa5fcdb7b83118de 100644 (file)
@@ -330,7 +330,7 @@ static const struct net_device_ops ixgb_netdev_ops = {
        .ndo_stop               = ixgb_close,
        .ndo_start_xmit         = ixgb_xmit_frame,
        .ndo_get_stats          = ixgb_get_stats,
-       .ndo_set_multicast_list = ixgb_set_multi,
+       .ndo_set_rx_mode        = ixgb_set_multi,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ixgb_set_mac,
        .ndo_change_mtu         = ixgb_change_mtu,
similarity index 97%
rename from drivers/net/ixgbe/ixgbe.h
rename to drivers/net/ethernet/intel/ixgbe/ixgbe.h
index e04a8e49e6dcc37c3143276b2b955dad90e77c24..378ce46a7f92fc0d7f815ff3f3530da07f036e4d 100644 (file)
 #define IXGBE_RX_BUFFER_WRITE  16      /* Must be power of 2 */
 
 #define IXGBE_TX_FLAGS_CSUM            (u32)(1)
-#define IXGBE_TX_FLAGS_VLAN            (u32)(1 << 1)
-#define IXGBE_TX_FLAGS_TSO             (u32)(1 << 2)
-#define IXGBE_TX_FLAGS_IPV4            (u32)(1 << 3)
-#define IXGBE_TX_FLAGS_FCOE            (u32)(1 << 4)
-#define IXGBE_TX_FLAGS_FSO             (u32)(1 << 5)
+#define IXGBE_TX_FLAGS_HW_VLAN         (u32)(1 << 1)
+#define IXGBE_TX_FLAGS_SW_VLAN         (u32)(1 << 2)
+#define IXGBE_TX_FLAGS_TSO             (u32)(1 << 3)
+#define IXGBE_TX_FLAGS_IPV4            (u32)(1 << 4)
+#define IXGBE_TX_FLAGS_FCOE            (u32)(1 << 5)
+#define IXGBE_TX_FLAGS_FSO             (u32)(1 << 6)
+#define IXGBE_TX_FLAGS_MAPPED_AS_PAGE  (u32)(1 << 7)
 #define IXGBE_TX_FLAGS_VLAN_MASK       0xffff0000
-#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK   0x0000e000
+#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK  0xe0000000
+#define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT  29
 #define IXGBE_TX_FLAGS_VLAN_SHIFT      16
 
 #define IXGBE_MAX_RSC_INT_RATE          162760
@@ -141,14 +144,14 @@ struct vf_macvlans {
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
 struct ixgbe_tx_buffer {
-       struct sk_buff *skb;
-       dma_addr_t dma;
+       union ixgbe_adv_tx_desc *next_to_watch;
        unsigned long time_stamp;
-       u16 length;
-       u16 next_to_watch;
-       unsigned int bytecount;
+       dma_addr_t dma;
+       u32 length;
+       u32 tx_flags;
+       struct sk_buff *skb;
+       u32 bytecount;
        u16 gso_segs;
-       u8 mapped_as_page;
 };
 
 struct ixgbe_rx_buffer {
similarity index 99%
rename from drivers/net/ixgbe/ixgbe_dcb_nl.c
rename to drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index 0ace6ce1d0b44271dc9e7ae67cf04db79947f35f..da6d53e7af99796c4687db22ff2a939cd22e45e0 100644 (file)
@@ -414,7 +414,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
                u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7};
                int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 
-#ifdef CONFIG_FCOE
+#ifdef IXGBE_FCOE
                if (adapter->netdev->features & NETIF_F_FCOE_MTU)
                        max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
 #endif
similarity index 99%
rename from drivers/net/ixgbe/ixgbe_fcoe.c
rename to drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index 824edae7786542ab7cc5f951d8eeb69c5f185106..e9b992fe5e46fb3e9c5793c9200187926f7fc028 100644 (file)
@@ -241,10 +241,12 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
         */
        if (lastsize == bufflen) {
                if (j >= IXGBE_BUFFCNT_MAX) {
-                       e_err(drv, "xid=%x:%d,%d,%d:addr=%llx "
-                               "not enough user buffers. We need an extra "
-                               "buffer because lastsize is bufflen.\n",
-                               xid, i, j, dmacount, (u64)addr);
+                       printk_once("Will NOT use DDP since there are not "
+                                   "enough user buffers. We need an  extra "
+                                   "buffer because lastsize is bufflen. "
+                                   "xid=%x:%d,%d,%d:addr=%llx\n",
+                                   xid, i, j, dmacount, (u64)addr);
+
                        goto out_noddp_free;
                }
 
similarity index 96%
rename from drivers/net/ixgbe/ixgbe_main.c
rename to drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index e86297b32733e8a0af34a329a3f839ce2c57205b..e8aad76fa53010ea55ad103b28deab7998cd8692 100644 (file)
@@ -42,6 +42,7 @@
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 #include <scsi/fc/fc_fcoe.h>
@@ -384,7 +385,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
                tx_ring = adapter->tx_ring[n];
                tx_buffer_info =
                        &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
-               pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
+               pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n",
                           n, tx_ring->next_to_use, tx_ring->next_to_clean,
                           (u64)tx_buffer_info->dma,
                           tx_buffer_info->length,
@@ -423,7 +424,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
                        tx_buffer_info = &tx_ring->tx_buffer_info[i];
                        u0 = (struct my_u0 *)tx_desc;
                        pr_info("T [0x%03X]    %016llX %016llX %016llX"
-                               " %04X  %3X %016llX %p", i,
+                               " %04X  %p %016llX %p", i,
                                le64_to_cpu(u0->a),
                                le64_to_cpu(u0->b),
                                (u64)tx_buffer_info->dma,
@@ -642,27 +643,31 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
        }
 }
 
-void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
-                                     struct ixgbe_tx_buffer *tx_buffer_info)
+static inline void ixgbe_unmap_tx_resource(struct ixgbe_ring *ring,
+                                          struct ixgbe_tx_buffer *tx_buffer)
 {
-       if (tx_buffer_info->dma) {
-               if (tx_buffer_info->mapped_as_page)
-                       dma_unmap_page(tx_ring->dev,
-                                      tx_buffer_info->dma,
-                                      tx_buffer_info->length,
-                                      DMA_TO_DEVICE);
+       if (tx_buffer->dma) {
+               if (tx_buffer->tx_flags & IXGBE_TX_FLAGS_MAPPED_AS_PAGE)
+                       dma_unmap_page(ring->dev,
+                                      tx_buffer->dma,
+                                      tx_buffer->length,
+                                      DMA_TO_DEVICE);
                else
-                       dma_unmap_single(tx_ring->dev,
-                                        tx_buffer_info->dma,
-                                        tx_buffer_info->length,
-                                        DMA_TO_DEVICE);
-               tx_buffer_info->dma = 0;
+                       dma_unmap_single(ring->dev,
+                                        tx_buffer->dma,
+                                        tx_buffer->length,
+                                        DMA_TO_DEVICE);
        }
-       if (tx_buffer_info->skb) {
+       tx_buffer->dma = 0;
+}
+
+void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
+                                     struct ixgbe_tx_buffer *tx_buffer_info)
+{
+       ixgbe_unmap_tx_resource(tx_ring, tx_buffer_info);
+       if (tx_buffer_info->skb)
                dev_kfree_skb_any(tx_buffer_info->skb);
-               tx_buffer_info->skb = NULL;
-       }
-       tx_buffer_info->time_stamp = 0;
+       tx_buffer_info->skb = NULL;
        /* tx_buffer_info must be completely set up in the transmit path */
 }
 
@@ -796,56 +801,72 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
                               struct ixgbe_ring *tx_ring)
 {
        struct ixgbe_adapter *adapter = q_vector->adapter;
-       union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
-       struct ixgbe_tx_buffer *tx_buffer_info;
+       struct ixgbe_tx_buffer *tx_buffer;
+       union ixgbe_adv_tx_desc *tx_desc;
        unsigned int total_bytes = 0, total_packets = 0;
-       u16 i, eop, count = 0;
+       u16 i = tx_ring->next_to_clean;
+       u16 count;
 
-       i = tx_ring->next_to_clean;
-       eop = tx_ring->tx_buffer_info[i].next_to_watch;
-       eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
+       tx_buffer = &tx_ring->tx_buffer_info[i];
+       tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
 
-       while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
-              (count < q_vector->tx.work_limit)) {
-               bool cleaned = false;
-               rmb(); /* read buffer_info after eop_desc */
-               for ( ; !cleaned; count++) {
-                       tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
-                       tx_buffer_info = &tx_ring->tx_buffer_info[i];
+       for (count = 0; count < q_vector->tx.work_limit; count++) {
+               union ixgbe_adv_tx_desc *eop_desc = tx_buffer->next_to_watch;
+
+               /* if next_to_watch is not set then there is no work pending */
+               if (!eop_desc)
+                       break;
+
+               /* if DD is not set pending work has not been completed */
+               if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
+                       break;
 
+               /* count the packet as being completed */
+               tx_ring->tx_stats.completed++;
+
+               /* clear next_to_watch to prevent false hangs */
+               tx_buffer->next_to_watch = NULL;
+
+               /* prevent any other reads prior to eop_desc being verified */
+               rmb();
+
+               do {
+                       ixgbe_unmap_tx_resource(tx_ring, tx_buffer);
                        tx_desc->wb.status = 0;
-                       cleaned = (i == eop);
+                       if (likely(tx_desc == eop_desc)) {
+                               eop_desc = NULL;
+                               dev_kfree_skb_any(tx_buffer->skb);
+                               tx_buffer->skb = NULL;
+
+                               total_bytes += tx_buffer->bytecount;
+                               total_packets += tx_buffer->gso_segs;
+                       }
 
+                       tx_buffer++;
+                       tx_desc++;
                        i++;
-                       if (i == tx_ring->count)
+                       if (unlikely(i == tx_ring->count)) {
                                i = 0;
 
-                       if (cleaned && tx_buffer_info->skb) {
-                               total_bytes += tx_buffer_info->bytecount;
-                               total_packets += tx_buffer_info->gso_segs;
+                               tx_buffer = tx_ring->tx_buffer_info;
+                               tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0);
                        }
 
-                       ixgbe_unmap_and_free_tx_resource(tx_ring,
-                                                        tx_buffer_info);
-               }
-
-               tx_ring->tx_stats.completed++;
-               eop = tx_ring->tx_buffer_info[i].next_to_watch;
-               eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
+               } while (eop_desc);
        }
 
        tx_ring->next_to_clean = i;
+       u64_stats_update_begin(&tx_ring->syncp);
        tx_ring->stats.bytes += total_bytes;
        tx_ring->stats.packets += total_packets;
-       u64_stats_update_begin(&tx_ring->syncp);
+       u64_stats_update_end(&tx_ring->syncp);
        q_vector->tx.total_bytes += total_bytes;
        q_vector->tx.total_packets += total_packets;
-       u64_stats_update_end(&tx_ring->syncp);
 
        if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
                /* schedule immediate reset if we believe we hung */
                struct ixgbe_hw *hw = &adapter->hw;
-               tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
+               tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
                e_err(drv, "Detected Tx Unit Hang\n"
                        "  Tx Queue             <%d>\n"
                        "  TDH, TDT             <%x>, <%x>\n"
@@ -857,8 +878,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
                        tx_ring->queue_index,
                        IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)),
                        IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)),
-                       tx_ring->next_to_use, eop,
-                       tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
+                       tx_ring->next_to_use, i,
+                       tx_ring->tx_buffer_info[i].time_stamp, jiffies);
 
                netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
 
@@ -1459,8 +1480,10 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                if (ixgbe_rx_is_fcoe(adapter, rx_desc)) {
                        ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb,
                                                   staterr);
-                       if (!ddp_bytes)
+                       if (!ddp_bytes) {
+                               dev_kfree_skb_any(skb);
                                goto next_desc;
+                       }
                }
 #endif /* IXGBE_FCOE */
                ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
@@ -3594,7 +3617,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
 
        /* reconfigure the hardware */
        if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) {
-#ifdef CONFIG_FCOE
+#ifdef IXGBE_FCOE
                if (adapter->netdev->features & NETIF_F_FCOE_MTU)
                        max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
 #endif
@@ -6348,7 +6371,7 @@ static bool ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
        u32 type_tucmd = 0;
 
        if (skb->ip_summed != CHECKSUM_PARTIAL) {
-           if (!(tx_flags & IXGBE_TX_FLAGS_VLAN))
+           if (!(tx_flags & IXGBE_TX_FLAGS_HW_VLAN))
                        return false;
        } else {
                u8 l4_hdr = 0;
@@ -6405,185 +6428,179 @@ static bool ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
        return (skb->ip_summed == CHECKSUM_PARTIAL);
 }
 
-static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
-                       struct ixgbe_ring *tx_ring,
-                       struct sk_buff *skb, u32 tx_flags,
-                       unsigned int first, const u8 hdr_len)
+static __le32 ixgbe_tx_cmd_type(u32 tx_flags)
 {
-       struct device *dev = tx_ring->dev;
-       struct ixgbe_tx_buffer *tx_buffer_info;
-       unsigned int len;
-       unsigned int total = skb->len;
-       unsigned int offset = 0, size, count = 0;
-       unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
-       unsigned int f;
-       unsigned int bytecount = skb->len;
-       u16 gso_segs = 1;
-       u16 i;
+       /* set type for advanced descriptor with frame checksum insertion */
+       __le32 cmd_type = cpu_to_le32(IXGBE_ADVTXD_DTYP_DATA |
+                                     IXGBE_ADVTXD_DCMD_IFCS |
+                                     IXGBE_ADVTXD_DCMD_DEXT);
 
-       i = tx_ring->next_to_use;
+       /* set HW vlan bit if vlan is present */
+       if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN)
+               cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE);
 
-       if (tx_flags & IXGBE_TX_FLAGS_FCOE)
-               /* excluding fcoe_crc_eof for FCoE */
-               total -= sizeof(struct fcoe_crc_eof);
+       /* set segmentation enable bits for TSO/FSO */
+#ifdef IXGBE_FCOE
+       if ((tx_flags & IXGBE_TX_FLAGS_TSO) || (tx_flags & IXGBE_TX_FLAGS_FSO))
+#else
+       if (tx_flags & IXGBE_TX_FLAGS_TSO)
+#endif
+               cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_TSE);
 
-       len = min(skb_headlen(skb), total);
-       while (len) {
-               tx_buffer_info = &tx_ring->tx_buffer_info[i];
-               size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
-
-               tx_buffer_info->length = size;
-               tx_buffer_info->mapped_as_page = false;
-               tx_buffer_info->dma = dma_map_single(dev,
-                                                    skb->data + offset,
-                                                    size, DMA_TO_DEVICE);
-               if (dma_mapping_error(dev, tx_buffer_info->dma))
-                       goto dma_error;
-               tx_buffer_info->time_stamp = jiffies;
-               tx_buffer_info->next_to_watch = i;
+       return cmd_type;
+}
 
-               len -= size;
-               total -= size;
-               offset += size;
-               count++;
+static __le32 ixgbe_tx_olinfo_status(u32 tx_flags, unsigned int paylen)
+{
+       __le32 olinfo_status =
+               cpu_to_le32(paylen << IXGBE_ADVTXD_PAYLEN_SHIFT);
 
-               if (len) {
-                       i++;
-                       if (i == tx_ring->count)
-                               i = 0;
-               }
+       if (tx_flags & IXGBE_TX_FLAGS_TSO) {
+               olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_TXSM |
+                                           (1 << IXGBE_ADVTXD_IDX_SHIFT));
+               /* enble IPv4 checksum for TSO */
+               if (tx_flags & IXGBE_TX_FLAGS_IPV4)
+                       olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_IXSM);
        }
 
-       for (f = 0; f < nr_frags; f++) {
-               struct skb_frag_struct *frag;
+       /* enable L4 checksum for TSO and TX checksum offload */
+       if (tx_flags & IXGBE_TX_FLAGS_CSUM)
+               olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_POPTS_TXSM);
 
-               frag = &skb_shinfo(skb)->frags[f];
-               len = min((unsigned int)frag->size, total);
-               offset = frag->page_offset;
+#ifdef IXGBE_FCOE
+       /* use index 1 context for FCOE/FSO */
+       if (tx_flags & IXGBE_TX_FLAGS_FCOE)
+               olinfo_status |= cpu_to_le32(IXGBE_ADVTXD_CC |
+                                           (1 << IXGBE_ADVTXD_IDX_SHIFT));
 
-               while (len) {
-                       i++;
-                       if (i == tx_ring->count)
-                               i = 0;
+#endif
+       return olinfo_status;
+}
 
-                       tx_buffer_info = &tx_ring->tx_buffer_info[i];
-                       size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
-
-                       tx_buffer_info->length = size;
-                       tx_buffer_info->dma = dma_map_page(dev,
-                                                          frag->page,
-                                                          offset, size,
-                                                          DMA_TO_DEVICE);
-                       tx_buffer_info->mapped_as_page = true;
-                       if (dma_mapping_error(dev, tx_buffer_info->dma))
-                               goto dma_error;
-                       tx_buffer_info->time_stamp = jiffies;
-                       tx_buffer_info->next_to_watch = i;
-
-                       len -= size;
-                       total -= size;
-                       offset += size;
-                       count++;
+#define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \
+                      IXGBE_TXD_CMD_RS)
+
+static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
+                        struct sk_buff *skb,
+                        struct ixgbe_tx_buffer *first,
+                        u32 tx_flags,
+                        const u8 hdr_len)
+{
+       struct device *dev = tx_ring->dev;
+       struct ixgbe_tx_buffer *tx_buffer_info;
+       union ixgbe_adv_tx_desc *tx_desc;
+       dma_addr_t dma;
+       __le32 cmd_type, olinfo_status;
+       struct skb_frag_struct *frag;
+       unsigned int f = 0;
+       unsigned int data_len = skb->data_len;
+       unsigned int size = skb_headlen(skb);
+       u32 offset = 0;
+       u32 paylen = skb->len - hdr_len;
+       u16 i = tx_ring->next_to_use;
+       u16 gso_segs;
+
+#ifdef IXGBE_FCOE
+       if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
+               if (data_len >= sizeof(struct fcoe_crc_eof)) {
+                       data_len -= sizeof(struct fcoe_crc_eof);
+               } else {
+                       size -= sizeof(struct fcoe_crc_eof) - data_len;
+                       data_len = 0;
                }
-               if (total == 0)
-                       break;
        }
 
-       if (tx_flags & IXGBE_TX_FLAGS_TSO)
-               gso_segs = skb_shinfo(skb)->gso_segs;
-#ifdef IXGBE_FCOE
-       /* adjust for FCoE Sequence Offload */
-       else if (tx_flags & IXGBE_TX_FLAGS_FSO)
-               gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
-                                       skb_shinfo(skb)->gso_size);
-#endif /* IXGBE_FCOE */
-       bytecount += (gso_segs - 1) * hdr_len;
+#endif
+       dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE);
+       if (dma_mapping_error(dev, dma))
+               goto dma_error;
 
-       /* multiply data chunks by size of headers */
-       tx_ring->tx_buffer_info[i].bytecount = bytecount;
-       tx_ring->tx_buffer_info[i].gso_segs = gso_segs;
-       tx_ring->tx_buffer_info[i].skb = skb;
-       tx_ring->tx_buffer_info[first].next_to_watch = i;
+       cmd_type = ixgbe_tx_cmd_type(tx_flags);
+       olinfo_status = ixgbe_tx_olinfo_status(tx_flags, paylen);
 
-       return count;
+       tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
 
-dma_error:
-       e_dev_err("TX DMA map failed\n");
+       for (;;) {
+               while (size > IXGBE_MAX_DATA_PER_TXD) {
+                       tx_desc->read.buffer_addr = cpu_to_le64(dma + offset);
+                       tx_desc->read.cmd_type_len =
+                               cmd_type | cpu_to_le32(IXGBE_MAX_DATA_PER_TXD);
+                       tx_desc->read.olinfo_status = olinfo_status;
 
-       /* clear timestamp and dma mappings for failed tx_buffer_info map */
-       tx_buffer_info->dma = 0;
-       tx_buffer_info->time_stamp = 0;
-       tx_buffer_info->next_to_watch = 0;
-       if (count)
-               count--;
+                       offset += IXGBE_MAX_DATA_PER_TXD;
+                       size -= IXGBE_MAX_DATA_PER_TXD;
 
-       /* clear timestamp and dma mappings for remaining portion of packet */
-       while (count--) {
-               if (i == 0)
-                       i += tx_ring->count;
-               i--;
-               tx_buffer_info = &tx_ring->tx_buffer_info[i];
-               ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
-       }
+                       tx_desc++;
+                       i++;
+                       if (i == tx_ring->count) {
+                               tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0);
+                               i = 0;
+                       }
+               }
 
-       return 0;
-}
+               tx_buffer_info = &tx_ring->tx_buffer_info[i];
+               tx_buffer_info->length = offset + size;
+               tx_buffer_info->tx_flags = tx_flags;
+               tx_buffer_info->dma = dma;
 
-static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring,
-                          int tx_flags, int count, u32 paylen, u8 hdr_len)
-{
-       union ixgbe_adv_tx_desc *tx_desc = NULL;
-       struct ixgbe_tx_buffer *tx_buffer_info;
-       u32 olinfo_status = 0, cmd_type_len = 0;
-       unsigned int i;
-       u32 txd_cmd = IXGBE_TXD_CMD_EOP | IXGBE_TXD_CMD_RS | IXGBE_TXD_CMD_IFCS;
+               tx_desc->read.buffer_addr = cpu_to_le64(dma + offset);
+               tx_desc->read.cmd_type_len = cmd_type | cpu_to_le32(size);
+               tx_desc->read.olinfo_status = olinfo_status;
 
-       cmd_type_len |= IXGBE_ADVTXD_DTYP_DATA;
+               if (!data_len)
+                       break;
 
-       cmd_type_len |= IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT;
+               frag = &skb_shinfo(skb)->frags[f];
+#ifdef IXGBE_FCOE
+               size = min_t(unsigned int, data_len, frag->size);
+#else
+               size = frag->size;
+#endif
+               data_len -= size;
+               f++;
 
-       if (tx_flags & IXGBE_TX_FLAGS_VLAN)
-               cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE;
+               offset = 0;
+               tx_flags |= IXGBE_TX_FLAGS_MAPPED_AS_PAGE;
 
-       if (tx_flags & IXGBE_TX_FLAGS_TSO) {
-               cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
+               dma = dma_map_page(dev, frag->page, frag->page_offset,
+                                  size, DMA_TO_DEVICE);
+               if (dma_mapping_error(dev, dma))
+                       goto dma_error;
 
-               olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
-                                IXGBE_ADVTXD_POPTS_SHIFT;
+               tx_desc++;
+               i++;
+               if (i == tx_ring->count) {
+                       tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0);
+                       i = 0;
+               }
+       }
 
-               /* use index 1 context for tso */
-               olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
-               if (tx_flags & IXGBE_TX_FLAGS_IPV4)
-                       olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
-                                        IXGBE_ADVTXD_POPTS_SHIFT;
+       tx_desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD);
 
-       } else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
-               olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
-                                IXGBE_ADVTXD_POPTS_SHIFT;
+       i++;
+       if (i == tx_ring->count)
+               i = 0;
 
-       if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
-               olinfo_status |= IXGBE_ADVTXD_CC;
-               olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
-               if (tx_flags & IXGBE_TX_FLAGS_FSO)
-                       cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
-       }
+       tx_ring->next_to_use = i;
 
-       olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
+       if (tx_flags & IXGBE_TX_FLAGS_TSO)
+               gso_segs = skb_shinfo(skb)->gso_segs;
+#ifdef IXGBE_FCOE
+       /* adjust for FCoE Sequence Offload */
+       else if (tx_flags & IXGBE_TX_FLAGS_FSO)
+               gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
+                                       skb_shinfo(skb)->gso_size);
+#endif /* IXGBE_FCOE */
+       else
+               gso_segs = 1;
 
-       i = tx_ring->next_to_use;
-       while (count--) {
-               tx_buffer_info = &tx_ring->tx_buffer_info[i];
-               tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
-               tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
-               tx_desc->read.cmd_type_len =
-                       cpu_to_le32(cmd_type_len | tx_buffer_info->length);
-               tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
-               i++;
-               if (i == tx_ring->count)
-                       i = 0;
-       }
+       /* multiply data chunks by size of headers */
+       tx_buffer_info->bytecount = paylen + (gso_segs * hdr_len);
+       tx_buffer_info->gso_segs = gso_segs;
+       tx_buffer_info->skb = skb;
 
-       tx_desc->read.cmd_type_len |= cpu_to_le32(txd_cmd);
+       /* set the timestamp */
+       first->time_stamp = jiffies;
 
        /*
         * Force memory writes to complete before letting h/w
@@ -6593,8 +6610,30 @@ static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring,
         */
        wmb();
 
-       tx_ring->next_to_use = i;
+       /* set next_to_watch value indicating a packet is present */
+       first->next_to_watch = tx_desc;
+
+       /* notify HW of packet */
        writel(i, tx_ring->tail);
+
+       return;
+dma_error:
+       dev_err(dev, "TX DMA map failed\n");
+
+       /* clear dma mappings for failed tx_buffer_info map */
+       for (;;) {
+               tx_buffer_info = &tx_ring->tx_buffer_info[i];
+               ixgbe_unmap_tx_resource(tx_ring, tx_buffer_info);
+               if (tx_buffer_info == first)
+                       break;
+               if (i == 0)
+                       i = tx_ring->count;
+               i--;
+       }
+
+       dev_kfree_skb_any(skb);
+
+       tx_ring->next_to_use = i;
 }
 
 static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb,
@@ -6633,8 +6672,8 @@ static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb,
 
        th = tcp_hdr(skb);
 
-       /* skip this packet since the socket is closing */
-       if (th->fin)
+       /* skip this packet since it is invalid or the socket is closing */
+       if (!th || th->fin)
                return;
 
        /* sample on all syn packets or once every atr sample count */
@@ -6659,7 +6698,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, struct sk_buff *skb,
         * since src port and flex bytes occupy the same word XOR them together
         * and write the value to source port portion of compressed dword
         */
-       if (vlan_id)
+       if (tx_flags & (IXGBE_TX_FLAGS_SW_VLAN | IXGBE_TX_FLAGS_HW_VLAN))
                common.port.src ^= th->dest ^ __constant_htons(ETH_P_8021Q);
        else
                common.port.src ^= th->dest ^ protocol;
@@ -6741,14 +6780,14 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                          struct ixgbe_adapter *adapter,
                          struct ixgbe_ring *tx_ring)
 {
+       struct ixgbe_tx_buffer *first;
        int tso;
-       u32  tx_flags = 0;
+       u32 tx_flags = 0;
 #if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
        unsigned short f;
 #endif
-       u16 first;
        u16 count = TXD_USE_COUNT(skb_headlen(skb));
-       __be16 protocol;
+       __be16 protocol = skb->protocol;
        u8 hdr_len = 0;
 
        /*
@@ -6769,68 +6808,82 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                return NETDEV_TX_BUSY;
        }
 
-       protocol = vlan_get_protocol(skb);
-
+       /* if we have a HW VLAN tag being added default to the HW one */
        if (vlan_tx_tag_present(skb)) {
-               tx_flags |= vlan_tx_tag_get(skb);
-               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                       tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
-                       tx_flags |= tx_ring->dcb_tc << 13;
+               tx_flags |= vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT;
+               tx_flags |= IXGBE_TX_FLAGS_HW_VLAN;
+       /* else if it is a SW VLAN check the next protocol and store the tag */
+       } else if (protocol == __constant_htons(ETH_P_8021Q)) {
+               struct vlan_hdr *vhdr, _vhdr;
+               vhdr = skb_header_pointer(skb, ETH_HLEN, sizeof(_vhdr), &_vhdr);
+               if (!vhdr)
+                       goto out_drop;
+
+               protocol = vhdr->h_vlan_encapsulated_proto;
+               tx_flags |= ntohs(vhdr->h_vlan_TCI) << IXGBE_TX_FLAGS_VLAN_SHIFT;
+               tx_flags |= IXGBE_TX_FLAGS_SW_VLAN;
+       }
+
+       if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
+           skb->priority != TC_PRIO_CONTROL) {
+               tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
+               tx_flags |= tx_ring->dcb_tc <<
+                           IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT;
+               if (tx_flags & IXGBE_TX_FLAGS_SW_VLAN) {
+                       struct vlan_ethhdr *vhdr;
+                       if (skb_header_cloned(skb) &&
+                           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+                               goto out_drop;
+                       vhdr = (struct vlan_ethhdr *)skb->data;
+                       vhdr->h_vlan_TCI = htons(tx_flags >>
+                                                IXGBE_TX_FLAGS_VLAN_SHIFT);
+               } else {
+                       tx_flags |= IXGBE_TX_FLAGS_HW_VLAN;
                }
-               tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
-               tx_flags |= IXGBE_TX_FLAGS_VLAN;
-       } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED &&
-                  skb->priority != TC_PRIO_CONTROL) {
-               tx_flags |= tx_ring->dcb_tc << 13;
-               tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
-               tx_flags |= IXGBE_TX_FLAGS_VLAN;
        }
 
-#ifdef IXGBE_FCOE
-       /* for FCoE with DCB, we force the priority to what
-        * was specified by the switch */
-       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED &&
-           (protocol == htons(ETH_P_FCOE)))
-               tx_flags |= IXGBE_TX_FLAGS_FCOE;
-
-#endif
        /* record the location of the first descriptor for this packet */
-       first = tx_ring->next_to_use;
+       first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
 
-       if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
 #ifdef IXGBE_FCOE
-               /* setup tx offload for FCoE */
+       /* setup tx offload for FCoE */
+       if ((protocol == __constant_htons(ETH_P_FCOE)) &&
+           (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) {
                tso = ixgbe_fso(tx_ring, skb, tx_flags, &hdr_len);
                if (tso < 0)
                        goto out_drop;
                else if (tso)
-                       tx_flags |= IXGBE_TX_FLAGS_FSO;
-#endif /* IXGBE_FCOE */
-       } else {
-               if (protocol == htons(ETH_P_IP))
-                       tx_flags |= IXGBE_TX_FLAGS_IPV4;
-               tso = ixgbe_tso(tx_ring, skb, tx_flags, protocol, &hdr_len);
-               if (tso < 0)
-                       goto out_drop;
-               else if (tso)
-                       tx_flags |= IXGBE_TX_FLAGS_TSO;
-               else if (ixgbe_tx_csum(tx_ring, skb, tx_flags, protocol))
-                       tx_flags |= IXGBE_TX_FLAGS_CSUM;
+                       tx_flags |= IXGBE_TX_FLAGS_FSO |
+                                   IXGBE_TX_FLAGS_FCOE;
+               else
+                       tx_flags |= IXGBE_TX_FLAGS_FCOE;
+
+               goto xmit_fcoe;
        }
 
-       count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first, hdr_len);
-       if (count) {
-               /* add the ATR filter if ATR is on */
-               if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
-                       ixgbe_atr(tx_ring, skb, tx_flags, protocol);
-               ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len);
-               ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
+#endif /* IXGBE_FCOE */
+       /* setup IPv4/IPv6 offloads */
+       if (protocol == __constant_htons(ETH_P_IP))
+               tx_flags |= IXGBE_TX_FLAGS_IPV4;
 
-       } else {
-               tx_ring->tx_buffer_info[first].time_stamp = 0;
-               tx_ring->next_to_use = first;
+       tso = ixgbe_tso(tx_ring, skb, tx_flags, protocol, &hdr_len);
+       if (tso < 0)
                goto out_drop;
-       }
+       else if (tso)
+               tx_flags |= IXGBE_TX_FLAGS_TSO;
+       else if (ixgbe_tx_csum(tx_ring, skb, tx_flags, protocol))
+               tx_flags |= IXGBE_TX_FLAGS_CSUM;
+
+       /* add the ATR filter if ATR is on */
+       if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
+               ixgbe_atr(tx_ring, skb, tx_flags, protocol);
+
+#ifdef IXGBE_FCOE
+xmit_fcoe:
+#endif /* IXGBE_FCOE */
+       ixgbe_tx_map(tx_ring, skb, first, tx_flags, hdr_len);
+
+       ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
 
        return NETDEV_TX_OK;
 
@@ -7204,7 +7257,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_start_xmit         = ixgbe_xmit_frame,
        .ndo_select_queue       = ixgbe_select_queue,
        .ndo_set_rx_mode        = ixgbe_set_rx_mode,
-       .ndo_set_multicast_list = ixgbe_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ixgbe_set_mac,
        .ndo_change_mtu         = ixgbe_change_mtu,
@@ -7527,6 +7579,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        netdev->vlan_features |= NETIF_F_IPV6_CSUM;
        netdev->vlan_features |= NETIF_F_SG;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
                adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED |
                                    IXGBE_FLAG_DCB_ENABLED);
similarity index 99%
rename from drivers/net/ixgbevf/ixgbevf_main.c
rename to drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 3b880a27f8d118eb6b08fcd5e23678bdf2c27653..b1e1c2daf5f9a7d935dc3ad7b8b0f9efe3f9af9f 100644 (file)
@@ -44,6 +44,7 @@
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 
@@ -3220,7 +3221,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_stop               = ixgbevf_close,
        .ndo_start_xmit         = ixgbevf_xmit_frame,
        .ndo_set_rx_mode        = ixgbevf_set_rx_mode,
-       .ndo_set_multicast_list = ixgbevf_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ixgbevf_set_mac,
        .ndo_change_mtu         = ixgbevf_change_mtu,
@@ -3358,6 +3358,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        /* The HW MAC address was set and/or determined in sw_init */
        memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
        memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
similarity index 99%
rename from drivers/net/jme.c
rename to drivers/net/ethernet/jme.c
index 3ac262f55633387d46947ca2d2c2259e1736867b..a869ee47dde689af20fdf9d68cfe2450ced31934 100644 (file)
@@ -2839,7 +2839,7 @@ static const struct net_device_ops jme_netdev_ops = {
        .ndo_do_ioctl           = jme_ioctl,
        .ndo_start_xmit         = jme_start_xmit,
        .ndo_set_mac_address    = jme_set_macaddr,
-       .ndo_set_multicast_list = jme_set_multi,
+       .ndo_set_rx_mode        = jme_set_multi,
        .ndo_change_mtu         = jme_change_mtu,
        .ndo_tx_timeout         = jme_tx_timeout,
        .ndo_fix_features       = jme_fix_features,
similarity index 100%
rename from drivers/net/jme.h
rename to drivers/net/ethernet/jme.h
similarity index 99%
rename from drivers/net/korina.c
rename to drivers/net/ethernet/korina.c
index 763844c587fd13ac9303347e0408855598a1bbe6..d8430f487b84f8012ec8390e522ae19eeba9949e 100644 (file)
@@ -58,7 +58,6 @@
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
@@ -1089,7 +1088,7 @@ static const struct net_device_ops korina_netdev_ops = {
        .ndo_open               = korina_open,
        .ndo_stop               = korina_close,
        .ndo_start_xmit         = korina_send_packet,
-       .ndo_set_multicast_list = korina_multicast_list,
+       .ndo_set_rx_mode        = korina_multicast_list,
        .ndo_tx_timeout         = korina_tx_timeout,
        .ndo_do_ioctl           = korina_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/lantiq_etop.c
rename to drivers/net/ethernet/lantiq_etop.c
index 45f252b7da307fdca5217d5618ecec4dc8701c4a..6bb2b9506cadfde73ddef809bc0fcf78dd202b0a 100644 (file)
@@ -687,7 +687,7 @@ static const struct net_device_ops ltq_eth_netdev_ops = {
        .ndo_do_ioctl = ltq_etop_ioctl,
        .ndo_set_mac_address = ltq_etop_set_mac_address,
        .ndo_validate_addr = eth_validate_addr,
-       .ndo_set_multicast_list = ltq_etop_set_multicast_list,
+       .ndo_set_rx_mode = ltq_etop_set_multicast_list,
        .ndo_select_queue = ltq_etop_select_queue,
        .ndo_init = ltq_etop_init,
        .ndo_tx_timeout = ltq_etop_tx_timeout,
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
new file mode 100644 (file)
index 0000000..e525408
--- /dev/null
@@ -0,0 +1,110 @@
+#
+# Marvell device configuration
+#
+
+config NET_VENDOR_MARVELL
+       bool "Marvell devices"
+       depends on PCI || CPU_PXA168 || MV64X60 || PPC32 || PLAT_ORION || INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Marvell devices. If you say Y, you will be
+         asked for your specific card in the following questions.
+
+if NET_VENDOR_MARVELL
+
+config MV643XX_ETH
+       tristate "Marvell Discovery (643XX) and Orion ethernet support"
+       depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
+       select INET_LRO
+       select PHYLIB
+       ---help---
+         This driver supports the gigabit ethernet MACs in the
+         Marvell Discovery PPC/MIPS chipset family (MV643XX) and
+         in the Marvell Orion ARM SoC family.
+
+         Some boards that use the Discovery chipset are the Momenco
+         Ocelot C and Jaguar ATX and Pegasos II.
+
+config PXA168_ETH
+       tristate "Marvell pxa168 ethernet support"
+       depends on CPU_PXA168
+       select PHYLIB
+       ---help---
+         This driver supports the pxa168 Ethernet ports.
+
+         To compile this driver as a module, choose M here. The module
+         will be called pxa168_eth.
+
+config SKGE
+       tristate "Marvell Yukon Gigabit Ethernet support"
+       depends on PCI
+       select CRC32
+       ---help---
+         This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
+         and related Gigabit Ethernet adapters. It is a new smaller driver
+         with better performance and more complete ethtool support.
+
+         It does not support the link failover and network management
+         features that "portable" vendor supplied sk98lin driver does.
+
+         This driver supports adapters based on the original Yukon chipset:
+         Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
+         Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872.
+
+         It does not support the newer Yukon2 chipset: a separate driver,
+         sky2, is provided for these adapters.
+
+         To compile this driver as a module, choose M here: the module
+         will be called skge.  This is recommended.
+
+config SKGE_DEBUG
+       bool "Debugging interface"
+       depends on SKGE && DEBUG_FS
+       ---help---
+         This option adds the ability to dump driver state for debugging.
+         The file /sys/kernel/debug/skge/ethX displays the state of the internal
+         transmit and receive rings.
+
+         If unsure, say N.
+
+config SKGE_GENESIS
+       bool "Support for older SysKonnect Genesis boards"
+       depends on SKGE
+       ---help---
+        This enables support for the older and uncommon SysKonnect Genesis
+        chips, which support MII via an external transceiver, instead of
+        an internal one. Disabling this option will save some memory
+        by making code smaller. If unsure say Y.
+
+config SKY2
+       tristate "Marvell Yukon 2 support"
+       depends on PCI
+       select CRC32
+       ---help---
+         This driver supports Gigabit Ethernet adapters based on the
+         Marvell Yukon 2 chipset:
+         Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
+         88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
+
+         There is companion driver for the older Marvell Yukon and
+         SysKonnect Genesis based adapters: skge.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sky2.  This is recommended.
+
+config SKY2_DEBUG
+       bool "Debugging interface"
+       depends on SKY2 && DEBUG_FS
+       ---help---
+         This option adds the ability to dump driver state for debugging.
+         The file /sys/kernel/debug/sky2/ethX displays the state of the internal
+         transmit and receive rings.
+
+         If unsure, say N.
+
+endif # NET_VENDOR_MARVELL
diff --git a/drivers/net/ethernet/marvell/Makefile b/drivers/net/ethernet/marvell/Makefile
new file mode 100644 (file)
index 0000000..57e3234
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the Marvell device drivers.
+#
+
+obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
+obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
+obj-$(CONFIG_SKGE) += skge.o
+obj-$(CONFIG_SKY2) += sky2.o
similarity index 99%
rename from drivers/net/mv643xx_eth.c
rename to drivers/net/ethernet/marvell/mv643xx_eth.c
index 259699983ca51c272a3ee42bfd4d922c85238440..1e2c9f072bfd3af99f9cb5c710f752cd4d4ba9f7 100644 (file)
@@ -2923,6 +2923,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
        dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
 
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        if (mp->shared->win_protect)
similarity index 99%
rename from drivers/net/skge.c
rename to drivers/net/ethernet/marvell/skge.c
index 98ec614c56901a53b43d17aeef91a7350a767c8c..34622b0380946ad9c710c643b595db499a7ab436 100644 (file)
@@ -3762,7 +3762,7 @@ static const struct net_device_ops skge_netdev_ops = {
        .ndo_tx_timeout         = skge_tx_timeout,
        .ndo_change_mtu         = skge_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = skge_set_multicast,
+       .ndo_set_rx_mode        = skge_set_multicast,
        .ndo_set_mac_address    = skge_set_mac_address,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = skge_netpoll,
similarity index 99%
rename from drivers/net/sky2.c
rename to drivers/net/ethernet/marvell/sky2.c
index 57339da76326eb504b4365a2716247c77af182ca..3ff0a1292933817d4523e586d5aa14b0f4e569ac 100644 (file)
@@ -4612,7 +4612,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
        .ndo_do_ioctl           = sky2_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = sky2_set_mac_address,
-       .ndo_set_multicast_list = sky2_set_multicast,
+       .ndo_set_rx_mode        = sky2_set_multicast,
        .ndo_change_mtu         = sky2_change_mtu,
        .ndo_fix_features       = sky2_fix_features,
        .ndo_set_features       = sky2_set_features,
@@ -4629,7 +4629,7 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
        .ndo_do_ioctl           = sky2_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = sky2_set_mac_address,
-       .ndo_set_multicast_list = sky2_set_multicast,
+       .ndo_set_rx_mode        = sky2_set_multicast,
        .ndo_change_mtu         = sky2_change_mtu,
        .ndo_fix_features       = sky2_fix_features,
        .ndo_set_features       = sky2_set_features,
diff --git a/drivers/net/ethernet/mellanox/Kconfig b/drivers/net/ethernet/mellanox/Kconfig
new file mode 100644 (file)
index 0000000..e069491
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Mellanox driver configuration
+#
+
+config NET_VENDOR_MELLANOX
+       bool "Mellanox devices"
+       depends on PCI && INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Mellanox cards. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_MELLANOX
+
+source "drivers/net/ethernet/mellanox/mlx4/Kconfig"
+
+endif # NET_VENDOR_MELLANOX
diff --git a/drivers/net/ethernet/mellanox/Makefile b/drivers/net/ethernet/mellanox/Makefile
new file mode 100644 (file)
index 0000000..37afb96
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Mellanox device drivers.
+#
+
+obj-$(CONFIG_MLX4_CORE) += mlx4/
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig
new file mode 100644 (file)
index 0000000..1bb9353
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# Mellanox driver configuration
+#
+
+config MLX4_EN
+       tristate "Mellanox Technologies 10Gbit Ethernet support"
+       depends on PCI && INET
+       select MLX4_CORE
+       select INET_LRO
+       ---help---
+         This driver supports Mellanox Technologies ConnectX Ethernet
+         devices.
+
+config MLX4_CORE
+       tristate
+       depends on PCI
+       default n
+
+config MLX4_DEBUG
+       bool "Verbose debugging output" if (MLX4_CORE && EXPERT)
+       depends on MLX4_CORE
+       default y
+       ---help---
+         This option causes debugging code to be compiled into the
+         mlx4_core driver.  The output can be turned on via the
+         debug_level module parameter (which can also be set after
+         the driver is loaded through sysfs).
similarity index 99%
rename from drivers/net/mlx4/en_netdev.c
rename to drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 4b0f32e568f8636c96b47b4e5014032ddf4d329b..27789be1e6acdbf2a9bf65f938ed127d50dad5f2 100644 (file)
@@ -1016,7 +1016,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
        .ndo_start_xmit         = mlx4_en_xmit,
        .ndo_select_queue       = mlx4_en_select_queue,
        .ndo_get_stats          = mlx4_en_get_stats,
-       .ndo_set_multicast_list = mlx4_en_set_multicast,
+       .ndo_set_rx_mode        = mlx4_en_set_multicast,
        .ndo_set_mac_address    = mlx4_en_set_mac,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = mlx4_en_change_mtu,
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
new file mode 100644 (file)
index 0000000..4227de6
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Micrel device configuration
+#
+
+config NET_VENDOR_MICREL
+       bool "Micrel devices"
+       depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM || \
+                  (ARM && ARCH_KS8695)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Micrel devices. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_MICREL
+
+config ARM_KS8695_ETHER
+       tristate "KS8695 Ethernet support"
+       depends on ARM && ARCH_KS8695
+       select MII
+       ---help---
+         If you wish to compile a kernel for the KS8695 and want to
+         use the internal ethernet then you should answer Y to this.
+
+config KS8842
+       tristate "Micrel KSZ8841/42 with generic bus interface"
+       depends on HAS_IOMEM && DMA_ENGINE
+       ---help---
+         This platform driver is for KSZ8841(1-port) / KS8842(2-port)
+         ethernet switch chip (managed, VLAN, QoS) from Micrel or
+         Timberdale(FPGA).
+
+config KS8851
+       tristate "Micrel KS8851 SPI"
+       depends on SPI
+       select MII
+       select CRC32
+       ---help---
+         SPI driver for Micrel KS8851 SPI attached network chip.
+
+config KS8851_MLL
+       tristate "Micrel KS8851 MLL"
+       depends on HAS_IOMEM
+       select MII
+       ---help---
+         This platform driver is for Micrel KS8851 Address/data bus
+         multiplexed network chip.
+
+config KSZ884X_PCI
+       tristate "Micrel KSZ8841/2 PCI"
+       depends on PCI
+       select MII
+       select CRC32
+       ---help---
+         This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ksz884x.
+
+endif # NET_VENDOR_MICREL
diff --git a/drivers/net/ethernet/micrel/Makefile b/drivers/net/ethernet/micrel/Makefile
new file mode 100644 (file)
index 0000000..c83e4bc
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for the Micrel network device drivers.
+#
+
+obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o
+obj-$(CONFIG_KS8842) += ks8842.o
+obj-$(CONFIG_KS8851) += ks8851.o
+obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
+obj-$(CONFIG_KSZ884X_PCI) += ksz884x.o
similarity index 99%
rename from drivers/net/arm/ks8695net.c
rename to drivers/net/ethernet/micrel/ks8695net.c
index c827a6097d024fda867cfff7365ea4da2ff31bc2..70788401d699811f115e73ec106ce57b4771aa83 100644 (file)
@@ -1333,7 +1333,7 @@ static const struct net_device_ops ks8695_netdev_ops = {
        .ndo_tx_timeout         = ks8695_timeout,
        .ndo_set_mac_address    = ks8695_set_mac,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = ks8695_set_multicast,
+       .ndo_set_rx_mode        = ks8695_set_multicast,
 };
 
 /**
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
new file mode 100644 (file)
index 0000000..53b0b04
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Microchip network device configuration
+#
+
+config NET_VENDOR_MICROCHIP
+       bool "Microchip devices"
+       depends on SPI && EXPERIMENTAL
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Microchip cards. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_MICROCHIP
+
+config ENC28J60
+       tristate "ENC28J60 support"
+       depends on SPI && EXPERIMENTAL
+       select CRC32
+       ---help---
+         Support for the Microchip EN28J60 ethernet chip.
+
+         To compile this driver as a module, choose M here. The module will be
+         called enc28j60.
+
+config ENC28J60_WRITEVERIFY
+       bool "Enable write verify"
+       depends on ENC28J60
+       ---help---
+         Enable the verify after the buffer write useful for debugging purpose.
+         If unsure, say N.
+
+endif # NET_VENDOR_MICROCHIP
diff --git a/drivers/net/ethernet/microchip/Makefile b/drivers/net/ethernet/microchip/Makefile
new file mode 100644 (file)
index 0000000..573d429
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Microchip network device drivers.
+#
+
+obj-$(CONFIG_ENC28J60) += enc28j60.o
similarity index 99%
rename from drivers/net/enc28j60.c
rename to drivers/net/ethernet/microchip/enc28j60.c
index 2837ce209cd7df517119eba565dee34c64492b58..50055e0282edf03b597a3b3c652e49f25cbecb05 100644 (file)
@@ -1534,7 +1534,7 @@ static const struct net_device_ops enc28j60_netdev_ops = {
        .ndo_open               = enc28j60_net_open,
        .ndo_stop               = enc28j60_net_close,
        .ndo_start_xmit         = enc28j60_send_packet,
-       .ndo_set_multicast_list = enc28j60_set_multicast_list,
+       .ndo_set_rx_mode        = enc28j60_set_multicast_list,
        .ndo_set_mac_address    = enc28j60_set_mac_address,
        .ndo_tx_timeout         = enc28j60_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/mipsnet.c
rename to drivers/net/ethernet/mipsnet.c
index 004e64ab1f9557deba4febb6eb1f33859d16b579..d05b0c9e1e9c4a96c8c214f31848eeecb9d929a5 100644 (file)
@@ -242,7 +242,7 @@ static const struct net_device_ops mipsnet_netdev_ops = {
        .ndo_open               = mipsnet_open,
        .ndo_stop               = mipsnet_close,
        .ndo_start_xmit         = mipsnet_xmit,
-       .ndo_set_multicast_list = mipsnet_set_mclist,
+       .ndo_set_rx_mode        = mipsnet_set_mclist,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/myricom/Kconfig b/drivers/net/ethernet/myricom/Kconfig
new file mode 100644 (file)
index 0000000..1816ae1
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# Myricom device configuration
+#
+
+config NET_VENDOR_MYRI
+       bool "Myricom devices"
+       depends on PCI && INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say
+         Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Myricom cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_MYRI
+
+config MYRI10GE
+       tristate "Myricom Myri-10G Ethernet support"
+       depends on PCI && INET
+       select FW_LOADER
+       select CRC32
+       select INET_LRO
+       ---help---
+         This driver supports Myricom Myri-10G Dual Protocol interface in
+         Ethernet mode. If the eeprom on your board is not recent enough,
+         you will need a newer firmware image.
+         You may get this image or more information, at:
+
+         <http://www.myri.com/scs/download-Myri10GE.html>
+
+         To compile this driver as a module, choose M here. The module
+         will be called myri10ge.
+
+config MYRI10GE_DCA
+       bool "Direct Cache Access (DCA) Support"
+       default y
+       depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m)
+       ---help---
+         Say Y here if you want to use Direct Cache Access (DCA) in the
+         driver.  DCA is a method for warming the CPU cache before data
+         is used, with the intent of lessening the impact of cache misses.
+
+endif # NET_VENDOR_MYRI
diff --git a/drivers/net/ethernet/myricom/Makefile b/drivers/net/ethernet/myricom/Makefile
new file mode 100644 (file)
index 0000000..296c0a1
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Myricom network device drivers.
+#
+
+obj-$(CONFIG_MYRI10GE) += myri10ge/
similarity index 99%
rename from drivers/net/myri10ge/myri10ge.c
rename to drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 1d2247554a35a0b5a6aff465207a2dc9a8243c21..81c17002374b0f201135a0d73c06ef49ad16350a 100644 (file)
@@ -3892,7 +3892,7 @@ static const struct net_device_ops myri10ge_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = myri10ge_change_mtu,
        .ndo_fix_features       = myri10ge_fix_features,
-       .ndo_set_multicast_list = myri10ge_set_multicast_list,
+       .ndo_set_rx_mode        = myri10ge_set_multicast_list,
        .ndo_set_mac_address    = myri10ge_set_mac_address,
 };
 
diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig
new file mode 100644 (file)
index 0000000..1e5c1e1
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# National Semi-conductor device configuration
+#
+
+config NET_VENDOR_NATSEMI
+       bool "National Semi-conductor devices"
+       depends on MCA || MAC || MACH_JAZZ || PCI || XTENSA_PLATFORM_XT2000
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about National Semi-conductor devices. If you say Y,
+         you will be asked for your specific card in the following questions.
+
+if NET_VENDOR_NATSEMI
+
+config IBMLANA
+       tristate "IBM LAN Adapter/A support"
+       depends on MCA
+       ---help---
+         This is a Micro Channel Ethernet adapter.  You need to set
+         CONFIG_MCA to use this driver.  It is both available as an in-kernel
+         driver and as a module.
+
+         To compile this driver as a module, choose M here. The only
+         currently supported card is the IBM LAN Adapter/A for Ethernet.  It
+         will both support 16K and 32K memory windows, however a 32K window
+         gives a better security against packet losses.  Usage of multiple
+         boards with this driver should be possible, but has not been tested
+         up to now due to lack of hardware.
+
+config MACSONIC
+       tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
+       depends on MAC
+       ---help---
+         Support for NatSemi SONIC based Ethernet devices.  This includes
+         the onboard Ethernet in many Quadras as well as some LC-PDS,
+         a few Nubus and all known Comm Slot Ethernet cards.  If you have
+         one of these say Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. This module will
+         be called macsonic.
+
+config MIPS_JAZZ_SONIC
+       tristate "MIPS JAZZ onboard SONIC Ethernet support"
+       depends on MACH_JAZZ
+       ---help---
+         This is the driver for the onboard card of MIPS Magnum 4000,
+         Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
+
+config NATSEMI
+       tristate "National Semiconductor DP8381x series PCI Ethernet support"
+       depends on PCI
+       select CRC32
+       ---help---
+         This driver is for the National Semiconductor DP83810 series,
+         which is used in cards from PureData, NetGear, Linksys
+         and others, including the 83815 chip.
+         More specific information and updates are available from
+         <http://www.scyld.com/network/natsemi.html>.
+
+config NS83820
+       tristate "National Semiconductor DP83820 support"
+       depends on PCI
+       ---help---
+         This is a driver for the National Semiconductor DP83820 series
+         of gigabit ethernet MACs.  Cards using this chipset include
+         the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
+         SOHO-GA2000T, SOHO-GA2500T.  The driver supports the use of
+         zero copy.
+
+config XTENSA_XT2000_SONIC
+       tristate "Xtensa XT2000 onboard SONIC Ethernet support"
+       depends on XTENSA_PLATFORM_XT2000
+       ---help---
+         This is the driver for the onboard card of the Xtensa XT2000 board.
+
+endif # NET_VENDOR_NATSEMI
diff --git a/drivers/net/ethernet/natsemi/Makefile b/drivers/net/ethernet/natsemi/Makefile
new file mode 100644 (file)
index 0000000..9aa5dea
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the National Semi-conductor Sonic devices.
+#
+
+obj-$(CONFIG_IBMLANA) += ibmlana.o
+obj-$(CONFIG_MACSONIC) += macsonic.o
+obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
+obj-$(CONFIG_NATSEMI) += natsemi.o
+obj-$(CONFIG_NS83820) += ns83820.o
+obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
similarity index 99%
rename from drivers/net/ibmlana.c
rename to drivers/net/ethernet/natsemi/ibmlana.c
index a7d6cad3295368a85f5720965746930141f51ac6..999407f7ebdf02227a79db0412433c5ba694d860 100644 (file)
@@ -910,7 +910,7 @@ static const struct net_device_ops ibmlana_netdev_ops = {
        .ndo_open               = ibmlana_open,
        .ndo_stop               = ibmlana_close,
        .ndo_start_xmit         = ibmlana_tx,
-       .ndo_set_multicast_list = ibmlana_set_multicast_list,
+       .ndo_set_rx_mode        = ibmlana_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/jazzsonic.c
rename to drivers/net/ethernet/natsemi/jazzsonic.c
index 949c1f9336445685998a891905924973c3eb7ef1..fc7c6a932ad95b8e19e0f977f0144842ef439bd9 100644 (file)
@@ -111,7 +111,7 @@ static const struct net_device_ops sonic_netdev_ops = {
        .ndo_stop               = jazzsonic_close,
        .ndo_start_xmit         = sonic_send_packet,
        .ndo_get_stats          = sonic_get_stats,
-       .ndo_set_multicast_list = sonic_multicast_list,
+       .ndo_set_rx_mode        = sonic_multicast_list,
        .ndo_tx_timeout         = sonic_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/macsonic.c
rename to drivers/net/ethernet/natsemi/macsonic.c
index c93679ee6994a7ff5851e507974565a5a3495f1b..5c36948e54d74862d149e857ac34f6f22dbae0c7 100644 (file)
@@ -190,7 +190,7 @@ static const struct net_device_ops macsonic_netdev_ops = {
        .ndo_open               = macsonic_open,
        .ndo_stop               = macsonic_close,
        .ndo_start_xmit         = sonic_send_packet,
-       .ndo_set_multicast_list = sonic_multicast_list,
+       .ndo_set_rx_mode        = sonic_multicast_list,
        .ndo_tx_timeout         = sonic_tx_timeout,
        .ndo_get_stats          = sonic_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/natsemi.c
rename to drivers/net/ethernet/natsemi/natsemi.c
index 2962cc695ce383202dfce41437380507a595d026..6ca047aab7938f3e0b79a3ceccbd5355491bf503 100644 (file)
@@ -783,7 +783,7 @@ static const struct net_device_ops natsemi_netdev_ops = {
        .ndo_stop               = netdev_close,
        .ndo_start_xmit         = start_tx,
        .ndo_get_stats          = get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = natsemi_change_mtu,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_tx_timeout         = ns_tx_timeout,
similarity index 99%
rename from drivers/net/ns83820.c
rename to drivers/net/ethernet/natsemi/ns83820.c
index e736aec588fcb1cbdc3e365b88e158592322b8f2..1a1e20e97a23af42aea539c582432fa1b839a1e8 100644 (file)
@@ -1937,7 +1937,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_start_xmit         = ns83820_hard_start_xmit,
        .ndo_get_stats          = ns83820_get_stats,
        .ndo_change_mtu         = ns83820_change_mtu,
-       .ndo_set_multicast_list = ns83820_set_multicast,
+       .ndo_set_rx_mode        = ns83820_set_multicast,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_tx_timeout         = ns83820_tx_timeout,
similarity index 99%
rename from drivers/net/xtsonic.c
rename to drivers/net/ethernet/natsemi/xtsonic.c
index 9f12026d98e7f9a94a8ac5f42e662de9ce5010f9..ccf61b9da8d1f59bd0be03a8e2d394683bdfa174 100644 (file)
@@ -122,7 +122,7 @@ static const struct net_device_ops xtsonic_netdev_ops = {
        .ndo_stop               = xtsonic_close,
        .ndo_start_xmit         = sonic_send_packet,
        .ndo_get_stats          = sonic_get_stats,
-       .ndo_set_multicast_list = sonic_multicast_list,
+       .ndo_set_rx_mode        = sonic_multicast_list,
        .ndo_tx_timeout         = sonic_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
diff --git a/drivers/net/ethernet/neterion/Kconfig b/drivers/net/ethernet/neterion/Kconfig
new file mode 100644 (file)
index 0000000..3d98e62
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Exar device configuration
+#
+
+config NET_VENDOR_EXAR
+       bool "Exar devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say
+         Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Exar cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_EXAR
+
+config S2IO
+       tristate "Exar Xframe 10Gb Ethernet Adapter"
+       depends on PCI
+       ---help---
+         This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters.
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/s2io.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called s2io.
+
+config VXGE
+       tristate "Exar X3100 Series 10GbE PCIe Server Adapter"
+       depends on PCI && INET
+       ---help---
+         This driver supports Exar Corp's X3100 Series 10 GbE PCIe
+         I/O Virtualized Server Adapter.
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/vxge.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called vxge.
+
+config VXGE_DEBUG_TRACE_ALL
+       bool "Enabling All Debug trace statements in driver"
+       default n
+       depends on VXGE
+       ---help---
+         Say Y here if you want to enabling all the debug trace statements in
+         the vxge driver. By default only few debug trace statements are
+         enabled.
+
+endif # NET_VENDOR_EXAR
diff --git a/drivers/net/ethernet/neterion/Makefile b/drivers/net/ethernet/neterion/Makefile
new file mode 100644 (file)
index 0000000..70c8058
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Exar network device drivers.
+#
+
+obj-$(CONFIG_S2IO) += s2io.o
+obj-$(CONFIG_VXGE) += vxge/
similarity index 99%
rename from drivers/net/s2io.c
rename to drivers/net/ethernet/neterion/s2io.c
index 277d48b0800a28781f392e7a6fde83030e37e809..840cbb25bddec20f3ec5a2eec8bc9eaf4d7f9388 100644 (file)
@@ -7682,7 +7682,7 @@ static const struct net_device_ops s2io_netdev_ops = {
        .ndo_get_stats          = s2io_get_stats,
        .ndo_start_xmit         = s2io_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = s2io_set_multicast,
+       .ndo_set_rx_mode        = s2io_set_multicast,
        .ndo_do_ioctl           = s2io_ioctl,
        .ndo_set_mac_address    = s2io_set_mac_addr,
        .ndo_change_mtu         = s2io_change_mtu,
similarity index 99%
rename from drivers/net/vxge/vxge-main.c
rename to drivers/net/ethernet/neterion/vxge/vxge-main.c
index 178348a258d2d32363f2c3e33bbdb60a0e8d55b9..1a53a24fe3d45a2ad832515d46311414f1a30c22 100644 (file)
@@ -3354,7 +3354,7 @@ static const struct net_device_ops vxge_netdev_ops = {
        .ndo_get_stats64        = vxge_get_stats64,
        .ndo_start_xmit         = vxge_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = vxge_set_multicast,
+       .ndo_set_rx_mode        = vxge_set_multicast,
        .ndo_do_ioctl           = vxge_ioctl,
        .ndo_set_mac_address    = vxge_set_mac_addr,
        .ndo_change_mtu         = vxge_change_mtu,
similarity index 99%
rename from drivers/net/netx-eth.c
rename to drivers/net/ethernet/netx-eth.c
index 2dfee892d200b163e72f4c5839d6a877e15b4db4..8d288af16fc9958bcd5fd0973f5e8173c24da529 100644 (file)
@@ -306,7 +306,7 @@ static const struct net_device_ops netx_eth_netdev_ops = {
        .ndo_stop               = netx_eth_close,
        .ndo_start_xmit         = netx_eth_hard_start_xmit,
        .ndo_tx_timeout         = netx_eth_timeout,
-       .ndo_set_multicast_list = netx_eth_set_multicast_list,
+       .ndo_set_rx_mode        = netx_eth_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/nuvoton/Kconfig b/drivers/net/ethernet/nuvoton/Kconfig
new file mode 100644 (file)
index 0000000..3b91c3b
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Nuvoton network device configuration
+#
+
+config NET_VENDOR_NUVOTON
+       bool "Nuvoton devices"
+       depends on ARM && ARCH_W90X900
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Nuvoton cards. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_NUVOTON
+
+config W90P910_ETH
+       tristate "Nuvoton w90p910 Ethernet support"
+       depends on ARM && ARCH_W90X900
+       select PHYLIB
+       select MII
+       ---help---
+         Say Y here if you want to use built-in Ethernet ports
+         on w90p910 processor.
+
+endif # NET_VENDOR_NUVOTON
diff --git a/drivers/net/ethernet/nuvoton/Makefile b/drivers/net/ethernet/nuvoton/Makefile
new file mode 100644 (file)
index 0000000..171aa04
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Nuvoton network device drivers.
+#
+
+obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o
similarity index 99%
rename from drivers/net/arm/w90p910_ether.c
rename to drivers/net/ethernet/nuvoton/w90p910_ether.c
index bfea499a351309f2292998208e9b302ff3a58c07..f1bfb8f8fcf01759ec711b80a413780e0eea030c 100644 (file)
@@ -919,7 +919,7 @@ static const struct net_device_ops w90p910_ether_netdev_ops = {
        .ndo_stop               = w90p910_ether_close,
        .ndo_start_xmit         = w90p910_ether_start_xmit,
        .ndo_get_stats          = w90p910_ether_stats,
-       .ndo_set_multicast_list = w90p910_ether_set_multicast_list,
+       .ndo_set_rx_mode        = w90p910_ether_set_multicast_list,
        .ndo_set_mac_address    = w90p910_set_mac_address,
        .ndo_do_ioctl           = w90p910_ether_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/nvidia/Kconfig b/drivers/net/ethernet/nvidia/Kconfig
new file mode 100644 (file)
index 0000000..0a18e73
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# NVIDIA network device configuration
+#
+
+config NET_VENDOR_NVIDIA
+       bool "NVIDIA devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about NVIDIA cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_NVIDIA
+
+config FORCEDETH
+       tristate "nForce Ethernet support"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) controller of this type, say Y and
+         read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called forcedeth.
+
+endif # NET_VENDOR_NVIDIA
diff --git a/drivers/net/ethernet/nvidia/Makefile b/drivers/net/ethernet/nvidia/Makefile
new file mode 100644 (file)
index 0000000..e079ae5
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the NVIDIA network device drivers.
+#
+
+obj-$(CONFIG_FORCEDETH) += forcedeth.o
similarity index 99%
rename from drivers/net/forcedeth.c
rename to drivers/net/ethernet/nvidia/forcedeth.c
index e55df308a3af219a54beaadc7dfdcd42c9508de8..98bb64bc24d93c2bd0ea75168c3fd931799c84ae 100644 (file)
@@ -5208,7 +5208,7 @@ static const struct net_device_ops nv_netdev_ops = {
        .ndo_set_features       = nv_set_features,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = nv_set_mac_address,
-       .ndo_set_multicast_list = nv_set_multicast,
+       .ndo_set_rx_mode        = nv_set_multicast,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = nv_poll_controller,
 #endif
@@ -5225,7 +5225,7 @@ static const struct net_device_ops nv_netdev_ops_optimized = {
        .ndo_set_features       = nv_set_features,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = nv_set_mac_address,
-       .ndo_set_multicast_list = nv_set_multicast,
+       .ndo_set_rx_mode        = nv_set_multicast,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = nv_poll_controller,
 #endif
@@ -5615,7 +5615,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                goto out_error;
        }
 
-       nv_vlan_mode(dev, dev->features);
+       if (id->driver_data & DEV_HAS_VLAN)
+               nv_vlan_mode(dev, dev->features);
 
        netif_carrier_off(dev);
 
similarity index 85%
rename from drivers/net/octeon/Kconfig
rename to drivers/net/ethernet/octeon/Kconfig
index 1e56bbf3f5c02cfc5b0d77c296b862172029ca9c..3de52ffd28722dd493d5a30a319bfaed9f372b93 100644 (file)
@@ -1,10 +1,14 @@
+#
+# Cavium network device configuration
+#
+
 config OCTEON_MGMT_ETHERNET
        tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)"
        depends on  CPU_CAVIUM_OCTEON
        select PHYLIB
        select MDIO_OCTEON
        default y
-       help
+       ---help---
          This option enables the ethernet driver for the management
          port on Cavium Networks' Octeon CN57XX, CN56XX, CN55XX,
          CN54XX, CN52XX, and CN6XXX chips.
diff --git a/drivers/net/ethernet/octeon/Makefile b/drivers/net/ethernet/octeon/Makefile
new file mode 100644 (file)
index 0000000..efa41c1
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Cavium network device drivers.
+#
+
+obj-$(CONFIG_OCTEON_MGMT_ETHERNET)     += octeon_mgmt.o
similarity index 99%
rename from drivers/net/octeon/octeon_mgmt.c
rename to drivers/net/ethernet/octeon/octeon_mgmt.c
index 429e08c84e9bb2e3a8860124abb2d5fb6b7f760f..bc1d946b7971b6c1ede4fc7616aa5609d153b26c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
 #include <linux/phy.h>
@@ -1059,7 +1060,6 @@ static const struct net_device_ops octeon_mgmt_ops = {
        .ndo_stop =                     octeon_mgmt_stop,
        .ndo_start_xmit =               octeon_mgmt_xmit,
        .ndo_set_rx_mode =              octeon_mgmt_set_rx_filtering,
-       .ndo_set_multicast_list =       octeon_mgmt_set_rx_filtering,
        .ndo_set_mac_address =          octeon_mgmt_set_mac_address,
        .ndo_do_ioctl =                 octeon_mgmt_ioctl,
        .ndo_change_mtu =               octeon_mgmt_change_mtu,
@@ -1102,6 +1102,8 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
        tasklet_init(&p->tx_clean_tasklet,
                     octeon_mgmt_clean_tx_tasklet, (unsigned long)p);
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        netdev->netdev_ops = &octeon_mgmt_ops;
        netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
 
diff --git a/drivers/net/ethernet/oki-semi/Kconfig b/drivers/net/ethernet/oki-semi/Kconfig
new file mode 100644 (file)
index 0000000..97f5e72
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# OKI Semiconductor device configuration
+#
+
+config NET_VENDOR_OKI
+       bool "OKI Semiconductor devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about OKI Semiconductor cards. If you say Y, you will
+         be asked for your specific card in the following questions.
+
+if NET_VENDOR_OKI
+
+source "drivers/net/ethernet/oki-semi/pch_gbe/Kconfig"
+
+endif # NET_VENDOR_OKI
diff --git a/drivers/net/ethernet/oki-semi/Makefile b/drivers/net/ethernet/oki-semi/Makefile
new file mode 100644 (file)
index 0000000..b6780c8
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the OKI Semiconductor device drivers.
+#
+
+obj-$(CONFIG_PCH_GBE) += pch_gbe/
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
new file mode 100644 (file)
index 0000000..c85709d
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# OKI Semiconductor device configuration
+#
+
+config PCH_GBE
+       tristate "OKI SEMICONDUCTOR ML7223 IOH GbE (Intel EG20T PCH)"
+       depends on PCI
+       select MII
+       ---help---
+         This is a gigabit ethernet driver for EG20T PCH.
+         EG20T PCH is the platform controller hub that is used in Intel's
+         general embedded platform.  EG20T PCH has Gigabit Ethernet interface.
+         Using this interface, it is able to access system devices connected
+         to Gigabit Ethernet.  This driver enables Gigabit Ethernet function.
+
+         This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+         Output Hub), ML7223.
+         ML7223 IOH is for MP(Media Phone) use.
+         ML7223 is companion chip for Intel Atom E6xx series.
+         ML7223 is completely compatible for Intel EG20T PCH.
similarity index 99%
rename from drivers/net/pch_gbe/pch_gbe_main.c
rename to drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index eac3c5ca9731b8d9f15819a801654a8e76fd4917..72276fe78f8fec4b935c5159791e46d0b367be90 100644 (file)
@@ -2158,7 +2158,7 @@ static const struct net_device_ops pch_gbe_netdev_ops = {
        .ndo_change_mtu = pch_gbe_change_mtu,
        .ndo_set_features = pch_gbe_set_features,
        .ndo_do_ioctl = pch_gbe_ioctl,
-       .ndo_set_multicast_list = &pch_gbe_set_multi,
+       .ndo_set_rx_mode = pch_gbe_set_multi,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = pch_gbe_netpoll,
 #endif
diff --git a/drivers/net/ethernet/packetengines/Kconfig b/drivers/net/ethernet/packetengines/Kconfig
new file mode 100644 (file)
index 0000000..4add1db
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# Packet engine device configuration
+#
+
+config NET_PACKET_ENGINE
+       bool "Packet Engine devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about packet engine devices. If you say Y, you will
+         be asked for your specific card in the following questions.
+
+if NET_PACKET_ENGINE
+
+config HAMACHI
+       tristate "Packet Engines Hamachi GNIC-II support"
+       depends on PCI
+       select MII
+       ---help---
+         If you have a Gigabit Ethernet card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module will be
+         called hamachi.
+
+config YELLOWFIN
+       tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       ---help---
+         Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet
+         adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is
+         used by the Beowulf Linux cluster project.  See
+         <http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html> for more
+         information about this driver in particular and Beowulf in general.
+
+         To compile this driver as a module, choose M here: the module
+         will be called yellowfin.  This is recommended.
+
+endif # NET_PACKET_ENGINE
diff --git a/drivers/net/ethernet/packetengines/Makefile b/drivers/net/ethernet/packetengines/Makefile
new file mode 100644 (file)
index 0000000..995ccd0
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Packet Engine network device drivers.
+#
+
+obj-$(CONFIG_HAMACHI) += hamachi.o
+obj-$(CONFIG_YELLOWFIN) += yellowfin.o
similarity index 99%
rename from drivers/net/hamachi.c
rename to drivers/net/ethernet/packetengines/hamachi.c
index c274b3d77eb5994b48e5863ac9703852656786a7..3458df3780b8fa381ace2a80a1c2ff1c9f7de140 100644 (file)
@@ -567,7 +567,7 @@ static const struct net_device_ops hamachi_netdev_ops = {
        .ndo_stop               = hamachi_close,
        .ndo_start_xmit         = hamachi_start_xmit,
        .ndo_get_stats          = hamachi_get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/yellowfin.c
rename to drivers/net/ethernet/packetengines/yellowfin.c
index 3e5ac60b89ac00559df4eaca6fd076146ccf1f7c..db44e9af03c317ca1cd5e713fd8ccf781d09683f 100644 (file)
@@ -359,7 +359,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_open               = yellowfin_open,
        .ndo_stop               = yellowfin_close,
        .ndo_start_xmit         = yellowfin_start_xmit,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/pasemi/Kconfig b/drivers/net/ethernet/pasemi/Kconfig
new file mode 100644 (file)
index 0000000..ccb79b8
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# PA Semi network device configuration
+#
+
+config NET_VENDOR_PASEMI
+       bool "PA Semi devices"
+       depends on PPC_PASEMI && PCI && INET
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about PA Semi cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_PASEMI
+
+config PASEMI_MAC
+       tristate "PA Semi 1/10Gbit MAC"
+       depends on PPC_PASEMI && PCI && INET
+       select PHYLIB
+       select INET_LRO
+       ---help---
+         This driver supports the on-chip 1/10Gbit Ethernet controller on
+         PA Semi's PWRficient line of chips.
+
+endif # NET_VENDOR_PASEMI
diff --git a/drivers/net/ethernet/pasemi/Makefile b/drivers/net/ethernet/pasemi/Makefile
new file mode 100644 (file)
index 0000000..05db543
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the A Semi network device drivers.
+#
+
+obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o
similarity index 99%
rename from drivers/net/pasemi_mac.c
rename to drivers/net/ethernet/pasemi/pasemi_mac.c
index 9ec112ca62e4f71fa6368cbe3390dd5922fd05ae..fad620da7c11c6f726e4300edc2efd016c877467 100644 (file)
@@ -1719,7 +1719,7 @@ static const struct net_device_ops pasemi_netdev_ops = {
        .ndo_open               = pasemi_mac_open,
        .ndo_stop               = pasemi_mac_close,
        .ndo_start_xmit         = pasemi_mac_start_tx,
-       .ndo_set_multicast_list = pasemi_mac_set_rx_mode,
+       .ndo_set_rx_mode        = pasemi_mac_set_rx_mode,
        .ndo_set_mac_address    = pasemi_mac_set_mac_addr,
        .ndo_change_mtu         = pasemi_mac_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
new file mode 100644 (file)
index 0000000..a7c4424
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# QLogic network device configuration
+#
+
+config NET_VENDOR_QLOGIC
+       bool "QLogic devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about QLogic cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_QLOGIC
+
+config QLA3XXX
+       tristate "QLogic QLA3XXX Network Driver Support"
+       depends on PCI
+       ---help---
+         This driver supports QLogic ISP3XXX gigabit Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called qla3xxx.
+
+config QLCNIC
+       tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
+       depends on PCI
+       select FW_LOADER
+       ---help---
+         This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
+         devices.
+
+config QLGE
+       tristate "QLogic QLGE 10Gb Ethernet Driver Support"
+       depends on PCI
+       ---help---
+         This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
+
+         To compile this driver as a module, choose M here: the module
+         will be called qlge.
+
+config NETXEN_NIC
+       tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
+       depends on PCI
+       select FW_LOADER
+       ---help---
+         This enables the support for NetXen's Gigabit Ethernet card.
+
+endif # NET_VENDOR_QLOGIC
diff --git a/drivers/net/ethernet/qlogic/Makefile b/drivers/net/ethernet/qlogic/Makefile
new file mode 100644 (file)
index 0000000..b2a283d
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the QLogic network device drivers.
+#
+
+obj-$(CONFIG_QLA3XXX) += qla3xxx.o
+obj-$(CONFIG_QLCNIC) += qlcnic/
+obj-$(CONFIG_QLGE) += qlge/
+obj-$(CONFIG_NETXEN_NIC) += netxen/
similarity index 99%
rename from drivers/net/netxen/netxen_nic.h
rename to drivers/net/ethernet/qlogic/netxen/netxen_nic.h
index f744d291218a2928e8277e030ac81e71125ae9f4..196b660e1d91836236b4f102680b15bd488cd6c7 100644 (file)
@@ -940,6 +940,11 @@ typedef struct nx_mac_list_s {
        uint8_t mac_addr[ETH_ALEN+2];
 } nx_mac_list_t;
 
+struct nx_vlan_ip_list {
+       struct list_head list;
+       u32 ip_addr;
+};
+
 /*
  * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
  * adjusted based on configured MTU.
@@ -1165,6 +1170,7 @@ struct netxen_adapter {
        struct net_device *netdev;
        struct pci_dev *pdev;
        struct list_head mac_list;
+       struct list_head vlan_ip_list;
 
        spinlock_t tx_clean_lock;
 
similarity index 99%
rename from drivers/net/netxen/netxen_nic_init.c
rename to drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
index e8993a76a08041b10b1bf54560ee69b2bb36409a..d6c6357de6aa3d674096edfd61346653b0b180ce 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/netdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/if_vlan.h>
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
 
@@ -1619,6 +1620,7 @@ netxen_process_lro(struct netxen_adapter *adapter,
        int index;
        u16 lro_length, length, data_offset;
        u32 seq_number;
+       u8 vhdr_len;
 
        if (unlikely(ring > adapter->max_rds_rings))
                return NULL;
@@ -1652,8 +1654,10 @@ netxen_process_lro(struct netxen_adapter *adapter,
        skb_pull(skb, l2_hdr_offset);
        skb->protocol = eth_type_trans(skb, netdev);
 
-       iph = (struct iphdr *)skb->data;
-       th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+       if (skb->protocol == htons(ETH_P_8021Q))
+               vhdr_len = VLAN_HLEN;
+       iph = (struct iphdr *)(skb->data + vhdr_len);
+       th = (struct tcphdr *)((skb->data + vhdr_len) + (iph->ihl << 2));
 
        length = (iph->ihl << 2) + (th->doff << 2) + lro_length;
        iph->tot_len = htons(length);
similarity index 96%
rename from drivers/net/netxen/netxen_nic_main.c
rename to drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index f574edff7fcb8ed9790a5281d1cff27b1b76d2d4..de18e4753b64880c2fb6e56441f8ae94ecb54275 100644 (file)
@@ -91,7 +91,8 @@ static irqreturn_t netxen_intr(int irq, void *data);
 static irqreturn_t netxen_msi_intr(int irq, void *data);
 static irqreturn_t netxen_msix_intr(int irq, void *data);
 
-static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+static void netxen_free_vlan_ip_list(struct netxen_adapter *);
+static void netxen_restore_indev_addr(struct net_device *dev, unsigned long);
 static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev,
                                                      struct rtnl_link_stats64 *stats);
 static int netxen_nic_set_mac(struct net_device *netdev, void *p);
@@ -523,7 +524,7 @@ static const struct net_device_ops netxen_netdev_ops = {
        .ndo_start_xmit    = netxen_nic_xmit_frame,
        .ndo_get_stats64   = netxen_nic_get_stats,
        .ndo_validate_addr = eth_validate_addr,
-       .ndo_set_multicast_list = netxen_set_multicast_list,
+       .ndo_set_rx_mode   = netxen_set_multicast_list,
        .ndo_set_mac_address    = netxen_nic_set_mac,
        .ndo_change_mtu    = netxen_nic_change_mtu,
        .ndo_tx_timeout    = netxen_tx_timeout,
@@ -1359,6 +1360,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        spin_lock_init(&adapter->tx_clean_lock);
        INIT_LIST_HEAD(&adapter->mac_list);
+       INIT_LIST_HEAD(&adapter->vlan_ip_list);
 
        err = netxen_setup_pci_map(adapter);
        if (err)
@@ -1481,6 +1483,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        cancel_work_sync(&adapter->tx_timeout_task);
 
+       netxen_free_vlan_ip_list(adapter);
        netxen_nic_detach(adapter);
 
        nx_decr_dev_ref_cnt(adapter);
@@ -1563,7 +1566,7 @@ static int netxen_nic_attach_func(struct pci_dev *pdev)
                if (err)
                        goto err_out_detach;
 
-               netxen_config_indev_addr(netdev, NETDEV_UP);
+               netxen_restore_indev_addr(netdev, NETDEV_UP);
        }
 
        netif_device_attach(netdev);
@@ -2374,7 +2377,7 @@ netxen_attach_work(struct work_struct *work)
                        goto done;
                }
 
-               netxen_config_indev_addr(netdev, NETDEV_UP);
+               netxen_restore_indev_addr(netdev, NETDEV_UP);
        }
 
        netif_device_attach(netdev);
@@ -2848,10 +2851,70 @@ netxen_destip_supported(struct netxen_adapter *adapter)
 }
 
 static void
-netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+netxen_free_vlan_ip_list(struct netxen_adapter *adapter)
+{
+       struct nx_vlan_ip_list  *cur;
+       struct list_head *head = &adapter->vlan_ip_list;
+
+       while (!list_empty(head)) {
+               cur = list_entry(head->next, struct nx_vlan_ip_list, list);
+               netxen_config_ipaddr(adapter, cur->ip_addr, NX_IP_DOWN);
+               list_del(&cur->list);
+               kfree(cur);
+       }
+
+}
+static void
+netxen_list_config_vlan_ip(struct netxen_adapter *adapter,
+               struct in_ifaddr *ifa, unsigned long event)
+{
+       struct net_device *dev;
+       struct nx_vlan_ip_list *cur, *tmp_cur;
+       struct list_head *head;
+
+       dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
+
+       if (dev == NULL)
+               return;
+
+       if (!is_vlan_dev(dev))
+               return;
+
+       switch (event) {
+       case NX_IP_UP:
+               list_for_each(head, &adapter->vlan_ip_list) {
+                       cur = list_entry(head, struct nx_vlan_ip_list, list);
+
+                       if (cur->ip_addr == ifa->ifa_address)
+                               return;
+               }
+
+               cur = kzalloc(sizeof(struct nx_vlan_ip_list), GFP_ATOMIC);
+               if (cur == NULL) {
+                       printk(KERN_ERR "%s: failed to add vlan ip to list\n",
+                                       adapter->netdev->name);
+                       return;
+               }
+
+               cur->ip_addr = ifa->ifa_address;
+               list_add_tail(&cur->list, &adapter->vlan_ip_list);
+               break;
+       case NX_IP_DOWN:
+               list_for_each_entry_safe(cur, tmp_cur,
+                                       &adapter->vlan_ip_list, list) {
+                       if (cur->ip_addr == ifa->ifa_address) {
+                               list_del(&cur->list);
+                               kfree(cur);
+                               break;
+                       }
+               }
+       }
+}
+static void
+netxen_config_indev_addr(struct netxen_adapter *adapter,
+               struct net_device *dev, unsigned long event)
 {
        struct in_device *indev;
-       struct netxen_adapter *adapter = netdev_priv(dev);
 
        if (!netxen_destip_supported(adapter))
                return;
@@ -2865,10 +2928,12 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
                case NETDEV_UP:
                        netxen_config_ipaddr(adapter,
                                        ifa->ifa_address, NX_IP_UP);
+                       netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP);
                        break;
                case NETDEV_DOWN:
                        netxen_config_ipaddr(adapter,
                                        ifa->ifa_address, NX_IP_DOWN);
+                       netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN);
                        break;
                default:
                        break;
@@ -2878,11 +2943,28 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
        in_dev_put(indev);
 }
 
+static void
+netxen_restore_indev_addr(struct net_device *netdev, unsigned long event)
+
+{
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+       struct nx_vlan_ip_list *pos, *tmp_pos;
+       unsigned long ip_event;
+
+       ip_event = (event == NETDEV_UP) ? NX_IP_UP : NX_IP_DOWN;
+       netxen_config_indev_addr(adapter, netdev, event);
+
+       list_for_each_entry_safe(pos, tmp_pos, &adapter->vlan_ip_list, list) {
+               netxen_config_ipaddr(adapter, pos->ip_addr, ip_event);
+       }
+}
+
 static int netxen_netdev_event(struct notifier_block *this,
                                 unsigned long event, void *ptr)
 {
        struct netxen_adapter *adapter;
        struct net_device *dev = (struct net_device *)ptr;
+       struct net_device *orig_dev = dev;
 
 recheck:
        if (dev == NULL)
@@ -2904,7 +2986,7 @@ recheck:
        if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
                goto done;
 
-       netxen_config_indev_addr(dev, event);
+       netxen_config_indev_addr(adapter, orig_dev, event);
 done:
        return NOTIFY_DONE;
 }
@@ -2921,7 +3003,7 @@ netxen_inetaddr_event(struct notifier_block *this,
        dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
 
 recheck:
-       if (dev == NULL || !netif_running(dev))
+       if (dev == NULL)
                goto done;
 
        if (dev->priv_flags & IFF_802_1Q_VLAN) {
@@ -2943,9 +3025,11 @@ recheck:
        switch (event) {
        case NETDEV_UP:
                netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP);
+               netxen_list_config_vlan_ip(adapter, ifa, NX_IP_UP);
                break;
        case NETDEV_DOWN:
                netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN);
+               netxen_list_config_vlan_ip(adapter, ifa, NX_IP_DOWN);
                break;
        default:
                break;
@@ -2964,7 +3048,10 @@ static struct notifier_block netxen_inetaddr_cb = {
 };
 #else
 static void
-netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+netxen_restore_indev_addr(struct net_device *dev, unsigned long event)
+{ }
+static void
+netxen_free_vlan_ip_list(struct netxen_adapter *adapter)
 { }
 #endif
 
similarity index 99%
rename from drivers/net/qla3xxx.c
rename to drivers/net/ethernet/qlogic/qla3xxx.c
index 2f6914025efc8bbfed44320014aea866e7d774cf..8cab61c08c8da9a4084342b7bc2a2a64aead318f 100644 (file)
@@ -1650,7 +1650,7 @@ static int ql_mii_setup(struct ql3_adapter *qdev)
                                 SUPPORTED_1000baseT_Half |     \
                                 SUPPORTED_1000baseT_Full |     \
                                 SUPPORTED_Autoneg |            \
-                                SUPPORTED_TP);                 \
+                                SUPPORTED_TP)                  \
 
 static u32 ql_supported_modes(struct ql3_adapter *qdev)
 {
@@ -3762,7 +3762,6 @@ static const struct net_device_ops ql3xxx_netdev_ops = {
        .ndo_open               = ql3xxx_open,
        .ndo_start_xmit         = ql3xxx_send,
        .ndo_stop               = ql3xxx_close,
-       .ndo_set_multicast_list = NULL, /* not allowed on NIC side */
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ql3xxx_set_mac_address,
similarity index 99%
rename from drivers/net/qlcnic/qlcnic.h
rename to drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index baf646d98fa07a7e8fdce96ee15ebc9a3a00f0a5..53c6e5dcf26c11ba1aa5f16d737f27ec6708b2a0 100644 (file)
@@ -36,8 +36,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 21
-#define QLCNIC_LINUX_VERSIONID  "5.0.21"
+#define _QLCNIC_LINUX_SUBVERSION 22
+#define QLCNIC_LINUX_VERSIONID  "5.0.22"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
                 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -911,6 +911,7 @@ struct qlcnic_ipaddr {
 #define QLCNIC_PROMISC_DISABLED                0x800
 #define QLCNIC_NEED_FLR                        0x1000
 #define QLCNIC_FW_RESET_OWNER          0x2000
+#define QLCNIC_FW_HANG                 0x4000
 #define QLCNIC_IS_MSI_FAMILY(adapter) \
        ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
 
@@ -1344,6 +1345,7 @@ enum op_codes {
 #define QLCNIC_FORCE_FW_DUMP_KEY       0xdeadfeed
 #define QLCNIC_ENABLE_FW_DUMP          0xaddfeed
 #define QLCNIC_DISABLE_FW_DUMP         0xbadfeed
+#define QLCNIC_FORCE_FW_RESET          0xdeaddead
 
 struct qlcnic_dump_operations {
        enum op_codes opcode;
similarity index 98%
rename from drivers/net/qlcnic/qlcnic_ethtool.c
rename to drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 72a723d5c988949f8b6b92462a6207a1529c4974..7c64f2ffc219fa9e1f4bf7290adca8dc23770435 100644 (file)
@@ -1105,7 +1105,10 @@ qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
-       dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
+       if (fw_dump->clr)
+               dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
+       else
+               dump->len = 0;
        dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
        dump->version = adapter->fw_version;
        return 0;
@@ -1152,7 +1155,8 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
-       if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
+       switch (val->flag) {
+       case QLCNIC_FORCE_FW_DUMP_KEY:
                if (!fw_dump->enable) {
                        netdev_info(netdev, "FW dump not enabled\n");
                        return ret;
@@ -1164,17 +1168,25 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
                }
                netdev_info(netdev, "Forcing a FW dump\n");
                qlcnic_dev_request_reset(adapter);
-       } else if (val->flag == QLCNIC_DISABLE_FW_DUMP) {
+               break;
+       case QLCNIC_DISABLE_FW_DUMP:
                if (fw_dump->enable) {
                        netdev_info(netdev, "Disabling FW dump\n");
                        fw_dump->enable = 0;
                }
-       } else if (val->flag == QLCNIC_ENABLE_FW_DUMP) {
+               break;
+       case QLCNIC_ENABLE_FW_DUMP:
                if (!fw_dump->enable && fw_dump->tmpl_hdr) {
                        netdev_info(netdev, "Enabling FW dump\n");
                        fw_dump->enable = 1;
                }
-       } else {
+               break;
+       case QLCNIC_FORCE_FW_RESET:
+               netdev_info(netdev, "Forcing a FW reset\n");
+               qlcnic_dev_request_reset(adapter);
+               adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
+               break;
+       default:
                if (val->flag > QLCNIC_DUMP_MASK_MAX ||
                        val->flag < QLCNIC_DUMP_MASK_MIN) {
                                netdev_info(netdev,
similarity index 99%
rename from drivers/net/qlcnic/qlcnic_hw.c
rename to drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 4055c218ef2adba4ae03f29b5e4a18ffd3f77709..74e9d7b94965bafb8ac4199b77915438159c58c9 100644 (file)
@@ -1773,8 +1773,8 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
                goto error;
        } else {
                fw_dump->clr = 1;
-               snprintf(mesg, sizeof(mesg), "FW dump for device: %d\n",
-                       adapter->pdev->devfn);
+               snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
+                       adapter->netdev->name);
                dev_info(&adapter->pdev->dev, "Dump data, %d bytes captured\n",
                        fw_dump->size);
                /* Send a udev event to notify availability of FW dump */
similarity index 99%
rename from drivers/net/qlcnic/qlcnic_init.c
rename to drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index ee8a3982395ebce8503fc04ced5ae27ac7aecb41..3b6741e4754dea9b239942f227f16d152c28ba56 100644 (file)
@@ -1056,7 +1056,8 @@ qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter)
 int
 qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
 {
-       if (qlcnic_check_fw_hearbeat(adapter)) {
+       if ((adapter->flags & QLCNIC_FW_HANG) ||
+                       qlcnic_check_fw_hearbeat(adapter)) {
                qlcnic_rom_lock_recovery(adapter);
                return 1;
        }
similarity index 98%
rename from drivers/net/qlcnic/qlcnic_main.c
rename to drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 5ca1b562443c402b7f0e82e405d61e9f319a86a1..b447cc50693a92b4b2dc5ce0e2c21d129cb9a990 100644 (file)
@@ -325,7 +325,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
        .ndo_start_xmit    = qlcnic_xmit_frame,
        .ndo_get_stats     = qlcnic_get_stats,
        .ndo_validate_addr = eth_validate_addr,
-       .ndo_set_multicast_list = qlcnic_set_multi,
+       .ndo_set_rx_mode   = qlcnic_set_multi,
        .ndo_set_mac_address    = qlcnic_set_mac,
        .ndo_change_mtu    = qlcnic_change_mtu,
        .ndo_fix_features  = qlcnic_fix_features,
@@ -643,8 +643,11 @@ static void get_brd_name(struct qlcnic_adapter *adapter, char *name)
 static void
 qlcnic_check_options(struct qlcnic_adapter *adapter)
 {
-       u32 fw_major, fw_minor, fw_build;
+       u32 fw_major, fw_minor, fw_build, prev_fw_version;
        struct pci_dev *pdev = adapter->pdev;
+       struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+
+       prev_fw_version = adapter->fw_version;
 
        fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
        fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
@@ -652,6 +655,17 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
 
        adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
 
+       if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) {
+               if (fw_dump->tmpl_hdr == NULL ||
+                               adapter->fw_version > prev_fw_version) {
+                       if (fw_dump->tmpl_hdr)
+                               vfree(fw_dump->tmpl_hdr);
+                       if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
+                               dev_info(&pdev->dev,
+                                       "Supports FW dump capability\n");
+               }
+       }
+
        dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
                        fw_major, fw_minor, fw_build);
        if (adapter->ahw->port_type == QLCNIC_XGBE) {
@@ -1610,12 +1624,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_decr_ref;
        }
 
-       /* Get FW dump template and store it */
-       if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
-               if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
-                       dev_info(&pdev->dev,
-                               "Supports FW dump capability\n");
-
        if (qlcnic_read_mac_addr(adapter))
                dev_warn(&pdev->dev, "failed to read mac addr\n");
 
@@ -2682,6 +2690,7 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
        qlcnic_api_unlock(adapter);
 err:
        adapter->fw_fail_cnt = 0;
+       adapter->flags &= ~QLCNIC_FW_HANG;
        clear_bit(__QLCNIC_START_FW, &adapter->state);
        clear_bit(__QLCNIC_RESETTING, &adapter->state);
 }
@@ -2859,6 +2868,7 @@ skip_ack_check:
                    (adapter->flags & QLCNIC_FW_RESET_OWNER)) {
                        QLCDB(adapter, DRV, "Take FW dump\n");
                        qlcnic_dump_fw(adapter);
+                       adapter->flags |= QLCNIC_FW_HANG;
                }
                rtnl_unlock();
 
@@ -3046,6 +3056,7 @@ attach:
 done:
        netif_device_attach(netdev);
        adapter->fw_fail_cnt = 0;
+       adapter->flags &= ~QLCNIC_FW_HANG;
        clear_bit(__QLCNIC_RESETTING, &adapter->state);
 
        if (!qlcnic_clr_drv_state(adapter))
@@ -3090,13 +3101,26 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
        if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
                return 0;
 
+       adapter->flags |= QLCNIC_FW_HANG;
+
        qlcnic_dev_request_reset(adapter);
 
        if (auto_fw_reset)
                clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
 
        dev_info(&netdev->dev, "firmware hang detected\n");
-
+       dev_info(&adapter->pdev->dev, "Dumping hw/fw registers\n"
+                       "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
+                       "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
+                       "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
+                       "PEG_NET_4_PC: 0x%x\n",
+                       QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1),
+                       QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS2),
+                       QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c),
+                       QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c),
+                       QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c),
+                       QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c),
+                       QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c));
 detach:
        adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state :
                QLCNIC_DEV_NEED_RESET;
similarity index 99%
rename from drivers/net/qlge/qlge_main.c
rename to drivers/net/ethernet/qlogic/qlge/qlge_main.c
index f07e96ec8843001c3f04afbe0ff6e91acade08c2..39360c485867dd23434ab0fe4efd352edf9cdcc2 100644 (file)
@@ -4676,7 +4676,7 @@ static const struct net_device_ops qlge_netdev_ops = {
        .ndo_start_xmit         = qlge_send,
        .ndo_change_mtu         = qlge_change_mtu,
        .ndo_get_stats          = qlge_get_stats,
-       .ndo_set_multicast_list = qlge_set_multicast_list,
+       .ndo_set_rx_mode        = qlge_set_multicast_list,
        .ndo_set_mac_address    = qlge_set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = qlge_tx_timeout,
diff --git a/drivers/net/ethernet/racal/Kconfig b/drivers/net/ethernet/racal/Kconfig
new file mode 100644 (file)
index 0000000..45d4930
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Racal-Interlan device configuration
+#
+
+config NET_VENDOR_RACAL
+       bool "Racal-Interlan (Micom) NI devices"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, such
+         as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about NI cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_RACAL
+
+config NI5010
+       tristate "NI5010 support (EXPERIMENTAL)"
+       depends on ISA && EXPERIMENTAL && BROKEN_ON_SMP
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>. Note that this is still
+         experimental code.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ni5010.
+
+endif # NET_VENDOR_RACAL
diff --git a/drivers/net/ethernet/racal/Makefile b/drivers/net/ethernet/racal/Makefile
new file mode 100644 (file)
index 0000000..1e210ca
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Racal-Interlan network device drivers.
+#
+
+obj-$(CONFIG_NI5010) += ni5010.o
similarity index 99%
rename from drivers/net/ni5010.c
rename to drivers/net/ethernet/racal/ni5010.c
index 4d3f2e2b28bd2f6a6f9f3c1bcba4e7e1467c5d14..072810da9a373dfb6b61db9b48f2dd988475f1a5 100644 (file)
@@ -192,7 +192,7 @@ static const struct net_device_ops ni5010_netdev_ops = {
        .ndo_open               = ni5010_open,
        .ndo_stop               = ni5010_close,
        .ndo_start_xmit         = ni5010_send_packet,
-       .ndo_set_multicast_list = ni5010_set_multicast_list,
+       .ndo_set_rx_mode        = ni5010_set_multicast_list,
        .ndo_tx_timeout         = ni5010_timeout,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/rdc/Kconfig b/drivers/net/ethernet/rdc/Kconfig
new file mode 100644 (file)
index 0000000..b15ebac
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# RDC network device configuration
+#
+
+config NET_VENDOR_RDC
+       bool "RDC devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about RDC cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_RDC
+
+config R6040
+       tristate "RDC R6040 Fast Ethernet Adapter support"
+       depends on PCI
+       select CRC32
+       select MII
+       select PHYLIB
+       ---help---
+         This is a driver for the R6040 Fast Ethernet MACs found in the
+         the RDC R-321x System-on-chips.
+
+         To compile this driver as a module, choose M here: the module
+         will be called r6040. This is recommended.
+
+endif # NET_VENDOR_RDC
diff --git a/drivers/net/ethernet/rdc/Makefile b/drivers/net/ethernet/rdc/Makefile
new file mode 100644 (file)
index 0000000..8d51fd2
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the RDC network device drivers.
+#
+
+obj-$(CONFIG_R6040) += r6040.o
similarity index 99%
rename from drivers/net/r6040.c
rename to drivers/net/ethernet/rdc/r6040.c
index b64fcee483aa903df5f48e69e4a1267dfc9ef987..2bbadc044784ecaf49bcb2ad4cc59a722bda99ed 100644 (file)
@@ -982,7 +982,7 @@ static const struct net_device_ops r6040_netdev_ops = {
        .ndo_stop               = r6040_close,
        .ndo_start_xmit         = r6040_start_xmit,
        .ndo_get_stats          = r6040_get_stats,
-       .ndo_set_multicast_list = r6040_multicast_list,
+       .ndo_set_rx_mode        = r6040_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/8139cp.c
rename to drivers/net/ethernet/realtek/8139cp.c
index cc4c210a91f8dc030a4e8c6f9d063aaf96501978..5d2d1b8678f6ddefa6539372cf153e35931f96a8 100644 (file)
@@ -1785,7 +1785,7 @@ static const struct net_device_ops cp_netdev_ops = {
        .ndo_stop               = cp_close,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = cp_set_mac_address,
-       .ndo_set_multicast_list = cp_set_rx_mode,
+       .ndo_set_rx_mode        = cp_set_rx_mode,
        .ndo_get_stats          = cp_get_stats,
        .ndo_do_ioctl           = cp_ioctl,
        .ndo_start_xmit         = cp_start_xmit,
similarity index 99%
rename from drivers/net/8139too.c
rename to drivers/net/ethernet/realtek/8139too.c
index c2672c692d6f2942c676b4f3138e3e2bf192ce6a..4d6b254fc6c16de399ac168490089c1cd691625f 100644 (file)
@@ -916,7 +916,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = rtl8139_set_mac_address,
        .ndo_start_xmit         = rtl8139_start_xmit,
-       .ndo_set_multicast_list = rtl8139_set_rx_mode,
+       .ndo_set_rx_mode        = rtl8139_set_rx_mode,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_tx_timeout         = rtl8139_tx_timeout,
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig
new file mode 100644 (file)
index 0000000..a5f67a0
--- /dev/null
@@ -0,0 +1,126 @@
+#
+# Realtek device configuration
+#
+
+config NET_VENDOR_REALTEK
+       bool "Realtek devices"
+       depends on PCI || (PARPORT && X86)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Realtek devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_REALTEK
+
+config ATP
+       tristate "AT-LAN-TEC/RealTek pocket adapter support"
+       depends on PARPORT && X86
+       select CRC32
+       ---help---
+         This is a network (Ethernet) device which attaches to your parallel
+         port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>, if you
+         want to use this.  If you intend to use this driver, you should have
+         said N to the "Parallel printer support", because the two drivers
+         don't like each other.
+
+         To compile this driver as a module, choose M here: the module
+         will be called atp.
+
+config 8139CP
+       tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       select MII
+       ---help---
+         This is a driver for the Fast Ethernet PCI network cards based on
+         the RTL8139C+ chips. If you have one of those, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8139cp.  This is recommended.
+
+config 8139TOO
+       tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This is a driver for the Fast Ethernet PCI network cards based on
+         the RTL 8129/8130/8139 chips. If you have one of those, say Y and
+         read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here: the module
+         will be called 8139too.  This is recommended.
+
+config 8139TOO_PIO
+       bool "Use PIO instead of MMIO"
+       default y
+       depends on 8139TOO
+       ---help---
+         This instructs the driver to use programmed I/O ports (PIO) instead
+         of PCI shared memory (MMIO).  This can possibly solve some problems
+         in case your mainboard has memory consistency issues.  If unsure,
+         say N.
+
+config 8139TOO_TUNE_TWISTER
+       bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
+       depends on 8139TOO
+       ---help---
+         This implements a function which might come in handy in case you
+         are using low quality on long cabling. It is required for RealTek
+         RTL-8139 revision K boards, and totally unused otherwise.  It tries
+         to match the transceiver to the cable characteristics. This is
+         experimental since hardly documented by the manufacturer.
+         If unsure, say Y.
+
+config 8139TOO_8129
+       bool "Support for older RTL-8129/8130 boards"
+       depends on 8139TOO
+       ---help---
+         This enables support for the older and uncommon RTL-8129 and
+         RTL-8130 chips, which support MII via an external transceiver,
+         instead of an internal one.  Disabling this option will save some
+         memory by making the code size smaller.  If unsure, say Y.
+
+config 8139_OLD_RX_RESET
+       bool "Use older RX-reset method"
+       depends on 8139TOO
+       ---help---
+         The 8139too driver was recently updated to contain a more rapid
+         reset sequence, in the face of severe receive errors.  This "new"
+         RX-reset method should be adequate for all boards.  But if you
+         experience problems, you can enable this option to restore the
+         old RX-reset behavior.  If unsure, say N.
+
+config R8169
+       tristate "Realtek 8169 gigabit ethernet support"
+       depends on PCI
+       select FW_LOADER
+       select CRC32
+       select MII
+       ---help---
+         Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
+
+         To compile this driver as a module, choose M here: the module
+         will be called r8169.  This is recommended.
+
+config SC92031
+       tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       ---help---
+         This is a driver for the Fast Ethernet PCI network cards based on
+         the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you
+         have one of these, say Y here.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sc92031.  This is recommended.
+
+endif # NET_VENDOR_REALTEK
diff --git a/drivers/net/ethernet/realtek/Makefile b/drivers/net/ethernet/realtek/Makefile
new file mode 100644 (file)
index 0000000..e48cfb6
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for the Realtek network device drivers.
+#
+
+obj-$(CONFIG_8139CP) += 8139cp.o
+obj-$(CONFIG_8139TOO) += 8139too.o
+obj-$(CONFIG_ATP) += atp.o
+obj-$(CONFIG_R8169) += r8169.o
+obj-$(CONFIG_SC92031) += sc92031.o
similarity index 99%
rename from drivers/net/atp.c
rename to drivers/net/ethernet/realtek/atp.c
index f3459798b0e993bdc559898c214dc51919c59693..e3f57fdbf0eaee7cadf90265b51a1102f3142658 100644 (file)
@@ -245,7 +245,7 @@ static const struct net_device_ops atp_netdev_ops = {
        .ndo_open               = net_open,
        .ndo_stop               = net_close,
        .ndo_start_xmit         = atp_send_packet,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_tx_timeout         = tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/r8169.c
rename to drivers/net/ethernet/realtek/r8169.c
index 02339b3352e7d4340db9106c86b59b61404bf6ea..1cf8c3c1328df82f0e6657b3a013b0efc06d8b19 100644 (file)
@@ -3277,7 +3277,7 @@ static const struct net_device_ops rtl8169_netdev_ops = {
        .ndo_set_features       = rtl8169_set_features,
        .ndo_set_mac_address    = rtl_set_mac_address,
        .ndo_do_ioctl           = rtl8169_ioctl,
-       .ndo_set_multicast_list = rtl_set_rx_mode,
+       .ndo_set_rx_mode        = rtl_set_rx_mode,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = rtl8169_netpoll,
 #endif
similarity index 99%
rename from drivers/net/sc92031.c
rename to drivers/net/ethernet/realtek/sc92031.c
index 9da47337b7c3ab86d182e2378f58d105f46f2b7c..128f8ebb81ece9b55af239521d6d8c4185dfe936 100644 (file)
@@ -1390,7 +1390,7 @@ static const struct net_device_ops sc92031_netdev_ops = {
        .ndo_start_xmit         = sc92031_start_xmit,
        .ndo_open               = sc92031_open,
        .ndo_stop               = sc92031_stop,
-       .ndo_set_multicast_list = sc92031_set_multicast_list,
+       .ndo_set_rx_mode        = sc92031_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
new file mode 100644 (file)
index 0000000..f57ae23
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# Renesas device configuration
+#
+
+config SH_ETH
+       tristate "Renesas SuperH Ethernet support"
+       depends on SUPERH && \
+               (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
+                CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
+                CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
+       select CRC32
+       select MII
+       select MDIO_BITBANG
+       select PHYLIB
+       ---help---
+         Renesas SuperH Ethernet device driver.
+         This driver supporting CPUs are:
+               - SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
diff --git a/drivers/net/ethernet/renesas/Makefile b/drivers/net/ethernet/renesas/Makefile
new file mode 100644 (file)
index 0000000..1c278a8
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Renesas device drivers.
+#
+
+obj-$(CONFIG_SH_ETH) += sh_eth.o
similarity index 99%
rename from drivers/net/sh_eth.c
rename to drivers/net/ethernet/renesas/sh_eth.c
index ad35c210b839b950726960144ac1da72a43833cc..bf2404ae3b874238876d3cf9fa173c9666a090c8 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -1758,7 +1759,7 @@ static const struct net_device_ops sh_eth_netdev_ops = {
        .ndo_start_xmit         = sh_eth_start_xmit,
        .ndo_get_stats          = sh_eth_get_stats,
 #if defined(SH_ETH_HAS_TSU)
-       .ndo_set_multicast_list = sh_eth_set_multicast_list,
+       .ndo_set_rx_mode        = sh_eth_set_multicast_list,
 #endif
        .ndo_tx_timeout         = sh_eth_tx_timeout,
        .ndo_do_ioctl           = sh_eth_do_ioctl,
diff --git a/drivers/net/ethernet/seeq/Kconfig b/drivers/net/ethernet/seeq/Kconfig
new file mode 100644 (file)
index 0000000..0266791
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# SEEQ device configuration
+#
+
+config NET_VENDOR_SEEQ
+       bool "SEEQ devices"
+       depends on (ARM && ARCH_ACORN) || SGI_HAS_SEEQ || EXPERIMENTAL
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about SEEQ devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_SEEQ
+
+config ARM_ETHER3
+       tristate "Acorn/ANT Ether3 support"
+       depends on ARM && ARCH_ACORN
+       ---help---
+         If you have an Acorn system with one of these network cards, you
+         should say Y to this option if you wish to use it with Linux.
+
+config SEEQ8005
+       tristate "SEEQ8005 support (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       ---help---
+         This is a driver for the SEEQ 8005 network (Ethernet) card.  If this
+         is for you, read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called seeq8005.
+
+config SGISEEQ
+       tristate "SGI Seeq ethernet controller support"
+       depends on SGI_HAS_SEEQ
+       ---help---
+         Say Y here if you have an Seeq based Ethernet network card. This is
+         used in many Silicon Graphics machines.
+
+endif # NET_VENDOR_SEEQ
diff --git a/drivers/net/ethernet/seeq/Makefile b/drivers/net/ethernet/seeq/Makefile
new file mode 100644 (file)
index 0000000..3e258a5
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the SEEQ network device drivers
+#
+
+obj-$(CONFIG_ARM_ETHER3) += ether3.o
+obj-$(CONFIG_SEEQ8005) += seeq8005.o
+obj-$(CONFIG_SGISEEQ) += sgiseeq.o
similarity index 99%
rename from drivers/net/arm/ether3.c
rename to drivers/net/ethernet/seeq/ether3.c
index 44a8746f4014b81f8f767a81c45c8826f8ac03cc..893c880dadf0f021f05b84d6f9f24b2f36b6b13b 100644 (file)
@@ -761,7 +761,7 @@ static const struct net_device_ops ether3_netdev_ops = {
        .ndo_open               = ether3_open,
        .ndo_stop               = ether3_close,
        .ndo_start_xmit         = ether3_sendpacket,
-       .ndo_set_multicast_list = ether3_setmulticastlist,
+       .ndo_set_rx_mode        = ether3_setmulticastlist,
        .ndo_tx_timeout         = ether3_timeout,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/seeq8005.c
rename to drivers/net/ethernet/seeq/seeq8005.c
index d2fce98f557fbf2195c704e1d7b56a1339c916aa..60561451789b0ff491ccbfe6a14fd2e5d5295a9a 100644 (file)
@@ -148,7 +148,7 @@ static const struct net_device_ops seeq8005_netdev_ops = {
        .ndo_stop               = seeq8005_close,
        .ndo_start_xmit         = seeq8005_send_packet,
        .ndo_tx_timeout         = seeq8005_timeout,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/sgiseeq.c
rename to drivers/net/ethernet/seeq/sgiseeq.c
index 52fb7ed9f3654bc272dbf6a824e26d3f860841ff..c3673f151a41f2001a0f46fddb22473c05be3cc0 100644 (file)
@@ -715,7 +715,7 @@ static const struct net_device_ops sgiseeq_netdev_ops = {
        .ndo_stop               = sgiseeq_close,
        .ndo_start_xmit         = sgiseeq_start_xmit,
        .ndo_tx_timeout         = timeout,
-       .ndo_set_multicast_list = sgiseeq_set_multicast,
+       .ndo_set_rx_mode        = sgiseeq_set_multicast,
        .ndo_set_mac_address    = sgiseeq_set_mac_address,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 96%
rename from drivers/net/sfc/Kconfig
rename to drivers/net/ethernet/sfc/Kconfig
index a3d5bb9e39dc5cfb48fb0d696c06c3a1f4b5d7c1..5d18841f0f3d5393cb72d132f6a54c08f0a33254 100644 (file)
@@ -5,7 +5,7 @@ config SFC
        select CRC32
        select I2C
        select I2C_ALGOBIT
-       help
+       ---help---
          This driver supports 10-gigabit Ethernet cards based on
          the Solarflare SFC4000 and SFC9000-family controllers.
 
@@ -15,7 +15,7 @@ config SFC_MTD
        bool "Solarflare SFC4000/SFC9000-family MTD support"
        depends on SFC && MTD && !(SFC=y && MTD=m)
        default y
-       help
+       ---help---
          This exposes the on-board flash memory as MTD devices (e.g.
          /dev/mtd1).  This makes it possible to upload new firmware
          to the NIC.
similarity index 99%
rename from drivers/net/sfc/efx.c
rename to drivers/net/ethernet/sfc/efx.c
index faca764aa21bef971677c3fc3dc027e3b5dd0fa6..b6b0e71f7fc8e61a256d2c66130b1738b8231f9d 100644 (file)
@@ -1903,7 +1903,7 @@ static const struct net_device_ops efx_netdev_ops = {
        .ndo_do_ioctl           = efx_ioctl,
        .ndo_change_mtu         = efx_change_mtu,
        .ndo_set_mac_address    = efx_set_mac_address,
-       .ndo_set_multicast_list = efx_set_multicast_list,
+       .ndo_set_rx_mode        = efx_set_multicast_list,
        .ndo_set_features       = efx_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = efx_netpoll,
diff --git a/drivers/net/ethernet/sgi/Kconfig b/drivers/net/ethernet/sgi/Kconfig
new file mode 100644 (file)
index 0000000..3098594
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# SGI device configuration
+#
+
+config NET_VENDOR_SGI
+       bool "SGI devices"
+       depends on (PCI && SGI_IP27) || SGI_IP32
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about SGI devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_SGI
+
+config SGI_IOC3_ETH
+       bool "SGI IOC3 Ethernet"
+       depends on PCI && SGI_IP27
+       select CRC32
+       select MII
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+config SGI_O2MACE_ETH
+       tristate "SGI O2 MACE Fast Ethernet support"
+       depends on SGI_IP32=y
+
+endif # NET_VENDOR_SGI
diff --git a/drivers/net/ethernet/sgi/Makefile b/drivers/net/ethernet/sgi/Makefile
new file mode 100644 (file)
index 0000000..e5bedd2
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the SGI device drivers.
+#
+
+obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
+obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
similarity index 99%
rename from drivers/net/ioc3-eth.c
rename to drivers/net/ethernet/sgi/ioc3-eth.c
index a234e4504522122ccd39f7f0318cf87b339685d1..ac149d99f78ff0a5ba79de441cda7dd2e1e86484 100644 (file)
@@ -1220,7 +1220,7 @@ static const struct net_device_ops ioc3_netdev_ops = {
        .ndo_start_xmit         = ioc3_start_xmit,
        .ndo_tx_timeout         = ioc3_timeout,
        .ndo_get_stats          = ioc3_get_stats,
-       .ndo_set_multicast_list = ioc3_set_multicast_list,
+       .ndo_set_rx_mode        = ioc3_set_multicast_list,
        .ndo_do_ioctl           = ioc3_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ioc3_set_mac_address,
diff --git a/drivers/net/ethernet/sis/Kconfig b/drivers/net/ethernet/sis/Kconfig
new file mode 100644 (file)
index 0000000..01d43e8
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# Silicon Integrated Systems (SiS) device configuration
+#
+
+config NET_VENDOR_SIS
+       bool "Silicon Integrated Systems (SiS) devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about SiS devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_SIS
+
+config SIS900
+       tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This is a driver for the Fast Ethernet PCI network cards based on
+         the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
+         SiS 630 and SiS 540 chipsets.
+
+         This driver also supports AMD 79C901 HomePNA so that you can use
+         your phone line as a network cable.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sis900.  This is recommended.
+
+config SIS190
+       tristate "SiS190/SiS191 gigabit ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
+         a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
+         appear in lan on motherboard designs which are based on SiS 965
+         and SiS 966 south bridge.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sis190.  This is recommended.
+
+endif # NET_VENDOR_SIS
diff --git a/drivers/net/ethernet/sis/Makefile b/drivers/net/ethernet/sis/Makefile
new file mode 100644 (file)
index 0000000..58d3ac1
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for Silicon Integrated Systems (SiS) network device drivers.
+#
+
+obj-$(CONFIG_SIS190) += sis190.o
+obj-$(CONFIG_SIS900) += sis900.o
similarity index 99%
rename from drivers/net/sis190.c
rename to drivers/net/ethernet/sis/sis190.c
index 3c0f1312b3914f29dba7660068a923141eb09663..1b4658c99391a4edbc09670f0145ec6d8bcbe31f 100644 (file)
@@ -1841,7 +1841,7 @@ static const struct net_device_ops sis190_netdev_ops = {
        .ndo_do_ioctl           = sis190_ioctl,
        .ndo_start_xmit         = sis190_start_xmit,
        .ndo_tx_timeout         = sis190_tx_timeout,
-       .ndo_set_multicast_list = sis190_set_rx_mode,
+       .ndo_set_rx_mode        = sis190_set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = sis190_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/sis900.c
rename to drivers/net/ethernet/sis/sis900.c
index 658a1928fe79a04caaa97b31db87c65f542b5c81..a184abc5ef11802afcefc86300d3fda2be7b763f 100644 (file)
@@ -403,7 +403,7 @@ static const struct net_device_ops sis900_netdev_ops = {
        .ndo_stop               = sis900_close,
        .ndo_start_xmit         = sis900_start_xmit,
        .ndo_set_config         = sis900_set_config,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig
new file mode 100644 (file)
index 0000000..702efe6
--- /dev/null
@@ -0,0 +1,131 @@
+#
+# Western Digital/SMC network device configuration
+#
+
+config NET_VENDOR_SMSC
+       bool "SMC (SMSC)/Western Digital devices"
+       depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \
+               BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about SMC/Western Digital cards. If you say Y, you will
+         be asked for your specific card in the following questions.
+
+if NET_VENDOR_SMSC
+
+config SMC9194
+       tristate "SMC 9194 support"
+       depends on (ISA || MAC && BROKEN)
+       select CRC32
+       ---help---
+         This is support for the SMC9xxx based Ethernet cards. Choose this
+         option if you have a DELL laptop with the docking station, or
+         another SMC9192/9194 based chipset.  Say Y if you want it compiled
+         into the kernel, and read the file
+         <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called smc9194.
+
+config SMC91X
+       tristate "SMC 91C9x/91C1xxx support"
+       select CRC32
+       select MII
+       depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \
+                   MN10300 || COLDFIRE)
+       ---help---
+         This is a driver for SMC's 91x series of Ethernet chipsets,
+         including the SMC91C94 and the SMC91C111. Say Y if you want it
+         compiled into the kernel, and read the file
+         <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO,
+         available from  <http://www.tldp.org/docs.html#howto>.
+
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want).
+         The module will be called smc91x.  If you want to compile it as a
+         module, say M here and read <file:Documentation/kbuild/modules.txt>.
+
+config PCMCIA_SMC91C92
+       tristate "SMC 91Cxx PCMCIA support"
+       depends on PCMCIA
+       select CRC32
+       select MII
+       ---help---
+         Say Y here if you intend to attach an SMC 91Cxx compatible PCMCIA
+         (PC-card) Ethernet or Fast Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called smc91c92_cs.  If unsure, say N.
+
+config EPIC100
+       tristate "SMC EtherPower II"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
+         which is based on the SMC83c17x (EPIC/100).
+         More specific information and updates are available from
+         <http://www.scyld.com/network/epic100.html>.
+
+config SMC911X
+       tristate "SMSC LAN911[5678] support"
+       select CRC32
+       select MII
+       depends on (ARM || SUPERH || MN10300)
+       ---help---
+         This is a driver for SMSC's LAN911x series of Ethernet chipsets
+         including the new LAN9115, LAN9116, LAN9117, and LAN9118.
+         Say Y if you want it compiled into the kernel,
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         This driver is also available as a module. The module will be
+         called smc911x.  If you want to compile it as a module, say M
+         here and read <file:Documentation/kbuild/modules.txt>
+
+config SMSC911X
+       tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
+       depends on (ARM || SUPERH || BLACKFIN || MIPS || MN10300)
+       select CRC32
+       select MII
+       select PHYLIB
+       ---help---
+         Say Y here if you want support for SMSC LAN911x and LAN921x families
+         of ethernet controllers.
+
+         To compile this driver as a module, choose M here and read
+         <file:Documentation/networking/net-modules.txt>. The module
+         will be called smsc911x.
+
+config SMSC911X_ARCH_HOOKS
+       def_bool n
+       depends on SMSC911X
+       ---help---
+         If the arch enables this, it allows the arch to implement various
+         hooks for more comprehensive interrupt control and also to override
+         the source of the MAC address.
+
+config SMSC9420
+       tristate "SMSC LAN9420 PCI ethernet adapter support"
+       depends on PCI
+       select CRC32
+       select PHYLIB
+       select SMSC_PHY
+       ---help---
+         This is a driver for SMSC's LAN9420 PCI ethernet adapter.
+         Say Y if you want it compiled into the kernel,
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         This driver is also available as a module. The module will be
+         called smsc9420.  If you want to compile it as a module, say M
+         here and read <file:Documentation/kbuild/modules.txt>
+
+endif # NET_VENDOR_SMSC
diff --git a/drivers/net/ethernet/smsc/Makefile b/drivers/net/ethernet/smsc/Makefile
new file mode 100644 (file)
index 0000000..f3438de
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the SMSC network device drivers.
+#
+
+obj-$(CONFIG_SMC9194) += smc9194.o
+obj-$(CONFIG_SMC91X) += smc91x.o
+obj-$(CONFIG_PCMCIA_SMC91C92) += smc91c92_cs.o
+obj-$(CONFIG_EPIC100) += epic100.o
+obj-$(CONFIG_SMSC9420) += smsc9420.o
+obj-$(CONFIG_SMC911X) += smc911x.o
+obj-$(CONFIG_SMSC911X) += smsc911x.o
similarity index 99%
rename from drivers/net/epic100.c
rename to drivers/net/ethernet/smsc/epic100.c
index 814c187d5f956deccca33b27cb4c0509264e13fb..0a5dfb814157f66343af36f4724718aa3503d4c0 100644 (file)
@@ -314,7 +314,7 @@ static const struct net_device_ops epic_netdev_ops = {
        .ndo_start_xmit         = epic_start_xmit,
        .ndo_tx_timeout         = epic_tx_timeout,
        .ndo_get_stats          = epic_get_stats,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_do_ioctl           = netdev_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/smc911x.c
rename to drivers/net/ethernet/smsc/smc911x.c
index a91fe1723020f3cda01d6c755ce13d0741faffb2..8f61fe9db1d0b6f10d86067c56ceac2788f94d87 100644 (file)
@@ -1768,7 +1768,7 @@ static const struct net_device_ops smc911x_netdev_ops = {
        .ndo_stop               = smc911x_close,
        .ndo_start_xmit         = smc911x_hard_start_xmit,
        .ndo_tx_timeout         = smc911x_timeout,
-       .ndo_set_multicast_list = smc911x_set_multicast_list,
+       .ndo_set_rx_mode        = smc911x_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/smc9194.c
rename to drivers/net/ethernet/smsc/smc9194.c
index 5b65ac4b3cefc0a40a500a0e10fe66e06a974470..4e45094efb18966c9d879bdd3d3989cc31bb6b77 100644 (file)
@@ -827,7 +827,7 @@ static const struct net_device_ops smc_netdev_ops = {
        .ndo_stop               = smc_close,
        .ndo_start_xmit         = smc_wait_to_send_packet,
        .ndo_tx_timeout         = smc_timeout,
-       .ndo_set_multicast_list = smc_set_multicast_list,
+       .ndo_set_rx_mode        = smc_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/pcmcia/smc91c92_cs.c
rename to drivers/net/ethernet/smsc/smc91c92_cs.c
index cffbc0373fa9bd1a3aae0e69bd26b7f7c2f070c2..cbfa981871314a4e5605117b88b275df9eb215ff 100644 (file)
@@ -294,7 +294,7 @@ static const struct net_device_ops smc_netdev_ops = {
        .ndo_start_xmit         = smc_start_xmit,
        .ndo_tx_timeout         = smc_tx_timeout,
        .ndo_set_config         = s9k_config,
-       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_set_rx_mode        = set_rx_mode,
        .ndo_do_ioctl           = smc_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/smc91x.c
rename to drivers/net/ethernet/smsc/smc91x.c
index 2b1d254d59af8ec7405e142d99d92fd21848c0ef..f47f81e25322942d18abd0c929cb17ca2730a7db 100644 (file)
@@ -1768,7 +1768,7 @@ static const struct net_device_ops smc_netdev_ops = {
        .ndo_stop               = smc_close,
        .ndo_start_xmit         = smc_hard_start_xmit,
        .ndo_tx_timeout         = smc_timeout,
-       .ndo_set_multicast_list = smc_set_multicast_list,
+       .ndo_set_rx_mode        = smc_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 97%
rename from drivers/net/smsc911x.c
rename to drivers/net/ethernet/smsc/smsc911x.c
index b9016a30cdc55fe6e9d47742ab0d6ba56af9bcf9..788c4fdab9c22bdd707426d42511d2038df7da2e 100644 (file)
 #include <linux/phy.h>
 #include <linux/smsc911x.h>
 #include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_net.h>
 #include "smsc911x.h"
 
 #define SMSC_CHIPNAME          "smsc911x"
@@ -1902,7 +1906,7 @@ static const struct net_device_ops smsc911x_netdev_ops = {
        .ndo_stop               = smsc911x_stop,
        .ndo_start_xmit         = smsc911x_hard_start_xmit,
        .ndo_get_stats          = smsc911x_get_stats,
-       .ndo_set_multicast_list = smsc911x_set_multicast_list,
+       .ndo_set_rx_mode        = smsc911x_set_multicast_list,
        .ndo_do_ioctl           = smsc911x_do_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
@@ -2095,8 +2099,58 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
        .tx_writefifo = smsc911x_tx_writefifo_shift,
 };
 
+#ifdef CONFIG_OF
+static int __devinit smsc911x_probe_config_dt(
+                               struct smsc911x_platform_config *config,
+                               struct device_node *np)
+{
+       const char *mac;
+       u32 width = 0;
+
+       if (!np)
+               return -ENODEV;
+
+       config->phy_interface = of_get_phy_mode(np);
+
+       mac = of_get_mac_address(np);
+       if (mac)
+               memcpy(config->mac, mac, ETH_ALEN);
+
+       of_property_read_u32(np, "reg-shift", &config->shift);
+
+       of_property_read_u32(np, "reg-io-width", &width);
+       if (width == 4)
+               config->flags |= SMSC911X_USE_32BIT;
+
+       if (of_get_property(np, "smsc,irq-active-high", NULL))
+               config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
+
+       if (of_get_property(np, "smsc,irq-push-pull", NULL))
+               config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
+
+       if (of_get_property(np, "smsc,force-internal-phy", NULL))
+               config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
+
+       if (of_get_property(np, "smsc,force-external-phy", NULL))
+               config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
+
+       if (of_get_property(np, "smsc,save-mac-address", NULL))
+               config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
+
+       return 0;
+}
+#else
+static inline int smsc911x_probe_config_dt(
+                               struct smsc911x_platform_config *config,
+                               struct device_node *np)
+{
+       return -ENODEV;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
 {
+       struct device_node *np = pdev->dev.of_node;
        struct net_device *dev;
        struct smsc911x_data *pdata;
        struct smsc911x_platform_config *config = pdev->dev.platform_data;
@@ -2107,13 +2161,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
 
        pr_info("Driver version %s\n", SMSC_DRV_VERSION);
 
-       /* platform data specifies irq & dynamic bus configuration */
-       if (!pdev->dev.platform_data) {
-               pr_warn("platform_data not provided\n");
-               retval = -ENODEV;
-               goto out_0;
-       }
-
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                           "smsc911x-memory");
        if (!res)
@@ -2152,9 +2199,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
        irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
        pdata->ioaddr = ioremap_nocache(res->start, res_size);
 
-       /* copy config parameters across to pdata */
-       memcpy(&pdata->config, config, sizeof(pdata->config));
-
        pdata->dev = dev;
        pdata->msg_enable = ((1 << debug) - 1);
 
@@ -2164,10 +2208,22 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
                goto out_free_netdev_2;
        }
 
+       retval = smsc911x_probe_config_dt(&pdata->config, np);
+       if (retval && config) {
+               /* copy config parameters across to pdata */
+               memcpy(&pdata->config, config, sizeof(pdata->config));
+               retval = 0;
+       }
+
+       if (retval) {
+               SMSC_WARN(pdata, probe, "Error smsc911x config not found");
+               goto out_unmap_io_3;
+       }
+
        /* assume standard, non-shifted, access to HW registers */
        pdata->ops = &standard_smsc911x_ops;
        /* apply the right access if shifting is needed */
-       if (config->shift)
+       if (pdata->config.shift)
                pdata->ops = &shifted_smsc911x_ops;
 
        retval = smsc911x_init(dev);
@@ -2314,6 +2370,12 @@ static const struct dev_pm_ops smsc911x_pm_ops = {
 #define SMSC911X_PM_OPS NULL
 #endif
 
+static const struct of_device_id smsc911x_dt_ids[] = {
+       { .compatible = "smsc,lan9115", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
+
 static struct platform_driver smsc911x_driver = {
        .probe = smsc911x_drv_probe,
        .remove = __devexit_p(smsc911x_drv_remove),
@@ -2321,6 +2383,7 @@ static struct platform_driver smsc911x_driver = {
                .name   = SMSC_CHIPNAME,
                .owner  = THIS_MODULE,
                .pm     = SMSC911X_PM_OPS,
+               .of_match_table = smsc911x_dt_ids,
        },
 };
 
similarity index 99%
rename from drivers/net/smsc9420.c
rename to drivers/net/ethernet/smsc/smsc9420.c
index 459726f5475417f6effcb8fad59284f1f6a09d28..4f15680849ffcc51a95c31425167011d1b0e277f 100644 (file)
@@ -1566,7 +1566,7 @@ static const struct net_device_ops smsc9420_netdev_ops = {
        .ndo_stop               = smsc9420_stop,
        .ndo_start_xmit         = smsc9420_hard_start_xmit,
        .ndo_get_stats          = smsc9420_get_stats,
-       .ndo_set_multicast_list = smsc9420_set_multicast_list,
+       .ndo_set_rx_mode        = smsc9420_set_multicast_list,
        .ndo_do_ioctl           = smsc9420_do_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/stmicro/Kconfig b/drivers/net/ethernet/stmicro/Kconfig
new file mode 100644 (file)
index 0000000..e40df64
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# STMicroelectronics device configuration
+#
+
+config NET_VENDOR_STMICRO
+       bool "STMicroelectronics devices"
+       depends on HAS_IOMEM
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about STMicroelectronics cards. If you say Y, you will
+         be asked for your specific card in the following questions.
+
+if NET_VENDOR_STMICRO
+
+source "drivers/net/ethernet/stmicro/stmmac/Kconfig"
+
+endif # NET_VENDOR_STMICRO
diff --git a/drivers/net/ethernet/stmicro/Makefile b/drivers/net/ethernet/stmicro/Makefile
new file mode 100644 (file)
index 0000000..9b3bfdd
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the STMicroelectronics device drivers.
+#
+
+obj-$(CONFIG_STMMAC_ETH) += stmmac/
similarity index 93%
rename from drivers/net/stmmac/Kconfig
rename to drivers/net/ethernet/stmicro/stmmac/Kconfig
index 7df7df4e79c5cef7b3f6e006a2150d21f882c101..cda61e37c357b817ccf17399b0475caf03ad6a98 100644 (file)
@@ -1,10 +1,10 @@
 config STMMAC_ETH
        tristate "STMicroelectronics 10/100/1000 Ethernet driver"
+       depends on HAS_IOMEM
        select MII
        select PHYLIB
        select CRC32
-       depends on NETDEVICES && HAS_IOMEM
-       help
+       ---help---
          This is the driver for the Ethernet IPs are built around a
          Synopsys IP Core and only tested on the STMicroelectronics
          platforms.
@@ -14,7 +14,7 @@ if STMMAC_ETH
 config STMMAC_DA
        bool "STMMAC DMA arbitration scheme"
        default n
-       help
+       ---help---
          Selecting this option, rx has priority over Tx (only for Giga
          Ethernet device).
          By default, the DMA arbitration scheme is based on Round-robin
@@ -24,7 +24,7 @@ config STMMAC_DUAL_MAC
        bool "STMMAC: dual mac support (EXPERIMENTAL)"
        default n
         depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
-       help
+       ---help---
          Some ST SoCs (for example the stx7141 and stx7200c2) have two
          Ethernet Controllers. This option turns on the second Ethernet
          device on this kind of platforms.
@@ -33,7 +33,7 @@ config STMMAC_TIMER
        bool "STMMAC Timer optimisation"
        default n
        depends on RTC_HCTOSYS_DEVICE
-       help
+       ---help---
          Use an external timer for mitigating the number of network
          interrupts. Currently, for SH architectures, it is possible
          to use the TMU channel 2 and the SH-RTC device.
@@ -45,12 +45,12 @@ choice
 config STMMAC_TMU_TIMER
         bool "TMU channel 2"
         depends on CPU_SH4
-       help
+       ---help---
 
 config STMMAC_RTC_TIMER
         bool "Real time clock"
         depends on RTC_CLASS
-       help
+       ---help---
 
 endchoice
 
similarity index 99%
rename from drivers/net/stmmac/stmmac_main.c
rename to drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c6e567e04effdb1ba3a5c77c228956e757dbef22..68fb5b0593a09056dc581ae8913c5d7ac74f5c32 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/crc32.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
@@ -1284,7 +1285,7 @@ static int stmmac_config(struct net_device *dev, struct ifmap *map)
 }
 
 /**
- *  stmmac_multicast_list - entry point for multicast addressing
+ *  stmmac_set_rx_mode - entry point for multicast addressing
  *  @dev : pointer to the device structure
  *  Description:
  *  This function is a driver entry point which gets called by the kernel
@@ -1292,7 +1293,7 @@ static int stmmac_config(struct net_device *dev, struct ifmap *map)
  *  Return value:
  *  void.
  */
-static void stmmac_multicast_list(struct net_device *dev)
+static void stmmac_set_rx_mode(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
 
@@ -1421,7 +1422,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
        .ndo_stop = stmmac_release,
        .ndo_change_mtu = stmmac_change_mtu,
        .ndo_fix_features = stmmac_fix_features,
-       .ndo_set_multicast_list = stmmac_multicast_list,
+       .ndo_set_rx_mode = stmmac_set_rx_mode,
        .ndo_tx_timeout = stmmac_tx_timeout,
        .ndo_do_ioctl = stmmac_ioctl,
        .ndo_set_config = stmmac_config,
@@ -1498,10 +1499,12 @@ static int stmmac_mac_device_setup(struct net_device *dev)
 
        struct mac_device_info *device;
 
-       if (priv->plat->has_gmac)
+       if (priv->plat->has_gmac) {
+               dev->priv_flags |= IFF_UNICAST_FLT;
                device = dwmac1000_setup(priv->ioaddr);
-       else
+       } else {
                device = dwmac100_setup(priv->ioaddr);
+       }
 
        if (!device)
                return -ENOMEM;
diff --git a/drivers/net/ethernet/sun/Kconfig b/drivers/net/ethernet/sun/Kconfig
new file mode 100644 (file)
index 0000000..5132fa6
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# Sun network device configuration
+#
+
+config NET_VENDOR_SUN
+       bool "Sun devices"
+       depends on SUN3 || SBUS || PCI || SUN_LDOMS
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say
+         Y and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Sun network interfaces. If you say Y, you will be
+         asked for your specific card in the following questions.
+
+if NET_VENDOR_SUN
+
+config HAPPYMEAL
+       tristate "Sun Happy Meal 10/100baseT support"
+       depends on (SBUS || PCI)
+       select CRC32
+       ---help---
+         This driver supports the "hme" interface present on most Ultra
+         systems and as an option on older Sbus systems. This driver supports
+         both PCI and Sbus devices. This driver also supports the "qfe" quad
+         100baseT device available in both PCI and Sbus configurations.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sunhme.
+
+config SUNBMAC
+       tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
+       depends on SBUS && EXPERIMENTAL
+       select CRC32
+       ---help---
+         This driver supports the "be" interface available as an Sbus option.
+         This is Sun's older 100baseT Ethernet device.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sunbmac.
+
+config SUNQE
+       tristate "Sun QuadEthernet support"
+       depends on SBUS
+       select CRC32
+       ---help---
+         This driver supports the "qe" 10baseT Ethernet device, available as
+         an Sbus option. Note that this is not the same as Quad FastEthernet
+         "qfe" which is supported by the Happy Meal driver instead.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sunqe.
+
+config SUNGEM
+       tristate "Sun GEM support"
+       depends on PCI
+       select CRC32
+       select SUNGEM_PHY
+       ---help---
+         Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
+         <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
+
+config CASSINI
+       tristate "Sun Cassini support"
+       depends on PCI
+       select CRC32
+       ---help---
+         Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
+         <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
+
+config SUNVNET
+       tristate "Sun Virtual Network support"
+       depends on SUN_LDOMS
+       ---help---
+         Support for virtual network devices under Sun Logical Domains.
+
+config NIU
+       tristate "Sun Neptune 10Gbit Ethernet support"
+       depends on PCI
+       select CRC32
+       ---help---
+         This enables support for cards based upon Sun's
+         Neptune chipset.
+
+endif # NET_VENDOR_SUN
diff --git a/drivers/net/ethernet/sun/Makefile b/drivers/net/ethernet/sun/Makefile
new file mode 100644 (file)
index 0000000..1e620ff
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for the Sun network device drivers.
+#
+
+obj-$(CONFIG_HAPPYMEAL) += sunhme.o
+obj-$(CONFIG_SUNQE) += sunqe.o
+obj-$(CONFIG_SUNBMAC) += sunbmac.o
+obj-$(CONFIG_SUNGEM) += sungem.o
+obj-$(CONFIG_CASSINI) += cassini.o
+obj-$(CONFIG_SUNVNET) += sunvnet.o
+obj-$(CONFIG_NIU) += niu.o
similarity index 99%
rename from drivers/net/cassini.c
rename to drivers/net/ethernet/sun/cassini.c
index 646c86bcc545e08835cc07b07ca913b1ba64dbcc..1776a37b7aed755652311545111e831bcebd828d 100644 (file)
@@ -4910,7 +4910,7 @@ static const struct net_device_ops cas_netdev_ops = {
        .ndo_stop               = cas_close,
        .ndo_start_xmit         = cas_start_xmit,
        .ndo_get_stats          = cas_get_stats,
-       .ndo_set_multicast_list = cas_set_multicast,
+       .ndo_set_rx_mode        = cas_set_multicast,
        .ndo_do_ioctl           = cas_ioctl,
        .ndo_tx_timeout         = cas_tx_timeout,
        .ndo_change_mtu         = cas_change_mtu,
similarity index 99%
rename from drivers/net/niu.c
rename to drivers/net/ethernet/sun/niu.c
index ed47585a6862b2d49af9e51a3f1ac3cab70ce3f6..3c9ef1c196a920170a1075c66eb20ec1ba063245 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/bitops.h>
 #include <linux/mii.h>
+#include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
@@ -9716,7 +9717,7 @@ static const struct net_device_ops niu_netdev_ops = {
        .ndo_stop               = niu_close,
        .ndo_start_xmit         = niu_start_xmit,
        .ndo_get_stats64        = niu_get_stats,
-       .ndo_set_multicast_list = niu_set_rx_mode,
+       .ndo_set_rx_mode        = niu_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = niu_set_mac_addr,
        .ndo_do_ioctl           = niu_ioctl,
@@ -9852,6 +9853,8 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
 
        niu_set_basic_features(dev);
 
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        np->regs = pci_ioremap_bar(pdev, 0);
        if (!np->regs) {
                dev_err(&pdev->dev, "Cannot map device registers, aborting\n");
similarity index 99%
rename from drivers/net/sunbmac.c
rename to drivers/net/ethernet/sun/sunbmac.c
index 297a4242106b300b48fcbbccbe142dde7f353df9..c94f5ef348d45fc437b8a428e973aa3c0b2c2986 100644 (file)
@@ -1070,7 +1070,7 @@ static const struct net_device_ops bigmac_ops = {
        .ndo_stop               = bigmac_close,
        .ndo_start_xmit         = bigmac_start_xmit,
        .ndo_get_stats          = bigmac_get_stats,
-       .ndo_set_multicast_list = bigmac_set_multicast,
+       .ndo_set_rx_mode        = bigmac_set_multicast,
        .ndo_tx_timeout         = bigmac_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/sungem.c
rename to drivers/net/ethernet/sun/sungem.c
index ade35dde5b51593638327ab5a640f995fb0c08a3..11fd299f5b990746c88362e3910405713cf7b71f 100644 (file)
@@ -59,7 +59,7 @@
 #include <asm/pmac_feature.h>
 #endif
 
-#include "sungem_phy.h"
+#include <linux/sungem_phy.h>
 #include "sungem.h"
 
 /* Stripping FCS is causing problems, disabled for now */
@@ -1721,7 +1721,7 @@ static void gem_init_phy(struct gem *gp)
        if (gp->phy_type == phy_mii_mdio0 ||
            gp->phy_type == phy_mii_mdio1) {
                /* Reset and detect MII PHY */
-               mii_phy_probe(&gp->phy_mii, gp->mii_phy_addr);
+               sungem_phy_probe(&gp->phy_mii, gp->mii_phy_addr);
 
                /* Init PHY */
                if (gp->phy_mii.def && gp->phy_mii.def->ops->init)
@@ -2820,7 +2820,7 @@ static const struct net_device_ops gem_netdev_ops = {
        .ndo_stop               = gem_close,
        .ndo_start_xmit         = gem_start_xmit,
        .ndo_get_stats          = gem_get_stats,
-       .ndo_set_multicast_list = gem_set_multicast,
+       .ndo_set_rx_mode        = gem_set_multicast,
        .ndo_do_ioctl           = gem_ioctl,
        .ndo_tx_timeout         = gem_tx_timeout,
        .ndo_change_mtu         = gem_change_mtu,
similarity index 99%
rename from drivers/net/sunhme.c
rename to drivers/net/ethernet/sun/sunhme.c
index 856e05b9fba3876fcea95289bf4eb13dea39c0ca..42f866ef81e1785213a288bda738438b94fa9607 100644 (file)
@@ -2619,7 +2619,7 @@ static const struct net_device_ops hme_netdev_ops = {
        .ndo_start_xmit         = happy_meal_start_xmit,
        .ndo_tx_timeout         = happy_meal_tx_timeout,
        .ndo_get_stats          = happy_meal_get_stats,
-       .ndo_set_multicast_list = happy_meal_set_multicast,
+       .ndo_set_rx_mode        = happy_meal_set_multicast,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
similarity index 99%
rename from drivers/net/sunqe.c
rename to drivers/net/ethernet/sun/sunqe.c
index 209c7f8df003e52d880043e64f27540258881eca..b28f74367ebee8333c2fe6abea3bf8823b788ec0 100644 (file)
@@ -824,7 +824,7 @@ static const struct net_device_ops qec_ops = {
        .ndo_open               = qe_open,
        .ndo_stop               = qe_close,
        .ndo_start_xmit         = qe_start_xmit,
-       .ndo_set_multicast_list = qe_set_multicast,
+       .ndo_set_rx_mode        = qe_set_multicast,
        .ndo_tx_timeout         = qe_tx_timeout,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
similarity index 99%
rename from drivers/net/sunvnet.c
rename to drivers/net/ethernet/sun/sunvnet.c
index bf3c762de6204ac7c2536e210e1b89a16e5a28d0..8c6c059f34899d98d50bc6e1d1b2afc65c7aedb1 100644 (file)
@@ -1012,7 +1012,7 @@ static DEFINE_MUTEX(vnet_list_mutex);
 static const struct net_device_ops vnet_ops = {
        .ndo_open               = vnet_open,
        .ndo_stop               = vnet_close,
-       .ndo_set_multicast_list = vnet_set_rx_mode,
+       .ndo_set_rx_mode        = vnet_set_rx_mode,
        .ndo_set_mac_address    = vnet_set_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = vnet_tx_timeout,
diff --git a/drivers/net/ethernet/tehuti/Kconfig b/drivers/net/ethernet/tehuti/Kconfig
new file mode 100644 (file)
index 0000000..914ad40
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Tehuti network device configuration
+#
+
+config NET_VENDOR_TEHUTI
+       bool "Tehuti devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Tehuti cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_TEHUTI
+
+config TEHUTI
+       tristate "Tehuti Networks 10G Ethernet"
+       depends on PCI
+       ---help---
+         Tehuti Networks 10G Ethernet NIC
+
+endif # NET_VENDOR_TEHUTI
diff --git a/drivers/net/ethernet/tehuti/Makefile b/drivers/net/ethernet/tehuti/Makefile
new file mode 100644 (file)
index 0000000..f995421
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Tehuti network device drivers.
+#
+
+obj-$(CONFIG_TEHUTI) += tehuti.o
similarity index 99%
rename from drivers/net/tehuti.c
rename to drivers/net/ethernet/tehuti/tehuti.c
index 749bbf18dc6a72e104b321df6d4c3242c7e52b8c..bc65aa8de4d0873a915df9ba8078a975c7a3494b 100644 (file)
@@ -1860,7 +1860,7 @@ static const struct net_device_ops bdx_netdev_ops = {
        .ndo_start_xmit         = bdx_tx_transmit,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = bdx_ioctl,
-       .ndo_set_multicast_list = bdx_setmulti,
+       .ndo_set_rx_mode        = bdx_setmulti,
        .ndo_change_mtu         = bdx_change_mtu,
        .ndo_set_mac_address    = bdx_set_mac,
        .ndo_vlan_rx_add_vid    = bdx_vlan_rx_add_vid,
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
new file mode 100644 (file)
index 0000000..1284319
--- /dev/null
@@ -0,0 +1,76 @@
+#
+# TI device configuration
+#
+
+config NET_VENDOR_TI
+       bool "Texas Instruments (TI) devices"
+       depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3))
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about TI devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_TI
+
+config TI_DAVINCI_EMAC
+       tristate "TI DaVinci EMAC Support"
+       depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+       select TI_DAVINCI_MDIO
+       select TI_DAVINCI_CPDMA
+       select PHYLIB
+       ---help---
+         This driver supports TI's DaVinci Ethernet .
+
+         To compile this driver as a module, choose M here: the module
+         will be called davinci_emac_driver.  This is recommended.
+
+config TI_DAVINCI_MDIO
+       tristate "TI DaVinci MDIO Support"
+       depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+       select PHYLIB
+       ---help---
+         This driver supports TI's DaVinci MDIO module.
+
+         To compile this driver as a module, choose M here: the module
+         will be called davinci_mdio.  This is recommended.
+
+config TI_DAVINCI_CPDMA
+       tristate "TI DaVinci CPDMA Support"
+       depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+       ---help---
+         This driver supports TI's DaVinci CPDMA dma engine.
+
+         To compile this driver as a module, choose M here: the module
+         will be called davinci_cpdma.  This is recommended.
+
+config TLAN
+       tristate "TI ThunderLAN support"
+       depends on (PCI || EISA)
+       ---help---
+         If you have a PCI Ethernet network card based on the ThunderLAN chip
+         which is supported by this driver, say Y and read the
+         Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Devices currently supported by this driver are Compaq Netelligent,
+         Compaq NetFlex and Olicom cards.  Please read the file
+         <file:Documentation/networking/tlan.txt> for more details.
+
+         To compile this driver as a module, choose M here. The module
+         will be called tlan.
+
+         Please email feedback to <torben.mathiasen@compaq.com>.
+
+config CPMAC
+       tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && AR7
+       select PHYLIB
+       ---help---
+         TI AR7 CPMAC Ethernet support
+
+endif # NET_VENDOR_TI
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
new file mode 100644 (file)
index 0000000..aedb3af
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for the TI network device drivers.
+#
+
+obj-$(CONFIG_TLAN) += tlan.o
+obj-$(CONFIG_CPMAC) += cpmac.o
+obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
+obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
+obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
similarity index 99%
rename from drivers/net/cpmac.c
rename to drivers/net/ethernet/ti/cpmac.c
index e0638cb4b07c0f60babceca58436d687ef263938..aaac0c7ad111192605075348264d1ddc38ceb2e6 100644 (file)
@@ -1100,7 +1100,7 @@ static const struct net_device_ops cpmac_netdev_ops = {
        .ndo_stop               = cpmac_stop,
        .ndo_start_xmit         = cpmac_start_xmit,
        .ndo_tx_timeout         = cpmac_tx_timeout,
-       .ndo_set_multicast_list = cpmac_set_multicast_list,
+       .ndo_set_rx_mode        = cpmac_set_multicast_list,
        .ndo_do_ioctl           = cpmac_ioctl,
        .ndo_set_config         = cpmac_config,
        .ndo_change_mtu         = eth_change_mtu,
similarity index 99%
rename from drivers/net/davinci_emac.c
rename to drivers/net/ethernet/ti/davinci_emac.c
index 3f451e4d8361699b617a5745d4de0c2f8f9ce183..815c7970261bc2ee09e8b8107afe6463aeffe69c 100644 (file)
@@ -1741,7 +1741,7 @@ static const struct net_device_ops emac_netdev_ops = {
        .ndo_open               = emac_dev_open,
        .ndo_stop               = emac_dev_stop,
        .ndo_start_xmit         = emac_dev_xmit,
-       .ndo_set_multicast_list = emac_dev_mcast_set,
+       .ndo_set_rx_mode        = emac_dev_mcast_set,
        .ndo_set_mac_address    = emac_dev_setmac_addr,
        .ndo_do_ioctl           = emac_devioctl,
        .ndo_tx_timeout         = emac_dev_tx_timeout,
similarity index 99%
rename from drivers/net/tlan.c
rename to drivers/net/ethernet/ti/tlan.c
index 145871b3130b1a0bb2a023824945d93821b0c49e..9c0dd6b8d6c9a9e6dfae193c36d469d8573853d4 100644 (file)
@@ -774,7 +774,7 @@ static const struct net_device_ops tlan_netdev_ops = {
        .ndo_start_xmit         = tlan_start_tx,
        .ndo_tx_timeout         = tlan_tx_timeout,
        .ndo_get_stats          = tlan_get_stats,
-       .ndo_set_multicast_list = tlan_set_multicast_list,
+       .ndo_set_rx_mode        = tlan_set_multicast_list,
        .ndo_do_ioctl           = tlan_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
diff --git a/drivers/net/ethernet/tile/Kconfig b/drivers/net/ethernet/tile/Kconfig
new file mode 100644 (file)
index 0000000..2d9218f
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Tilera network device configuration
+#
+
+config TILE_NET
+       tristate "Tilera GBE/XGBE network driver support"
+       depends on TILE
+       default y
+       select CRC32
+       ---help---
+         This is a standard Linux network device driver for the
+         on-chip Tilera Gigabit Ethernet and XAUI interfaces.
+
+         To compile this driver as a module, choose M here: the module
+         will be called tile_net.
diff --git a/drivers/net/ethernet/toshiba/Kconfig b/drivers/net/ethernet/toshiba/Kconfig
new file mode 100644 (file)
index 0000000..6ef2ce2
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Toshiba network device configuration
+#
+
+config NET_VENDOR_TOSHIBA
+       bool "Toshiba devices"
+       depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) || PPC_PS3
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Toshiba cards. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_TOSHIBA
+
+config GELIC_NET
+       tristate "PS3 Gigabit Ethernet driver"
+       depends on PPC_PS3
+       select PS3_SYS_MANAGER
+       ---help---
+         This driver supports the network device on the PS3 game
+         console.  This driver has built-in support for Ethernet.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ps3_gelic.
+
+config GELIC_WIRELESS
+       bool "PS3 Wireless support"
+       depends on GELIC_NET && WLAN
+       select WIRELESS_EXT
+       ---help---
+         This option adds the support for the wireless feature of PS3.
+         If you have the wireless-less model of PS3 or have no plan to
+         use wireless feature, disabling this option saves memory.  As
+         the driver automatically distinguishes the models, you can
+         safely enable this option even if you have a wireless-less model.
+
+config SPIDER_NET
+       tristate "Spider Gigabit Ethernet driver"
+       depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
+       select FW_LOADER
+       select SUNGEM_PHY
+       ---help---
+         This driver supports the Gigabit Ethernet chips present on the
+         Cell Processor-Based Blades from IBM.
+
+config TC35815
+       tristate "TOSHIBA TC35815 Ethernet support"
+       depends on PCI && MIPS
+       select PHYLIB
+
+endif # NET_VENDOR_TOSHIBA
diff --git a/drivers/net/ethernet/toshiba/Makefile b/drivers/net/ethernet/toshiba/Makefile
new file mode 100644 (file)
index 0000000..a506900
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the Toshiba network device drivers.
+#
+
+obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
+gelic_wireless-$(CONFIG_GELIC_WIRELESS) += ps3_gelic_wireless.o
+ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
+spidernet-y += spider_net.o spider_net_ethtool.o
+obj-$(CONFIG_SPIDER_NET) += spidernet.o
+obj-$(CONFIG_TC35815) += tc35815.o
similarity index 99%
rename from drivers/net/ps3_gelic_net.c
rename to drivers/net/ethernet/toshiba/ps3_gelic_net.c
index d82a82d9870cc9a78f6b7e13b32eeda64558175e..ddb33cfd3543d6a16c8e469454ba5666d05945ae 100644 (file)
@@ -1452,7 +1452,7 @@ static const struct net_device_ops gelic_netdevice_ops = {
        .ndo_open = gelic_net_open,
        .ndo_stop = gelic_net_stop,
        .ndo_start_xmit = gelic_net_xmit,
-       .ndo_set_multicast_list = gelic_net_set_multi,
+       .ndo_set_rx_mode = gelic_net_set_multi,
        .ndo_change_mtu = gelic_net_change_mtu,
        .ndo_tx_timeout = gelic_net_tx_timeout,
        .ndo_set_mac_address = eth_mac_addr,
similarity index 99%
rename from drivers/net/ps3_gelic_wireless.c
rename to drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
index 2e62938c0f824a39afc61b6634129f0367a03e03..fd4ed7f8cfa102afe368a497add1f7ef1365079d 100644 (file)
@@ -2568,7 +2568,7 @@ static const struct net_device_ops gelic_wl_netdevice_ops = {
        .ndo_open = gelic_wl_open,
        .ndo_stop = gelic_wl_stop,
        .ndo_start_xmit = gelic_net_xmit,
-       .ndo_set_multicast_list = gelic_net_set_multi,
+       .ndo_set_rx_mode = gelic_net_set_multi,
        .ndo_change_mtu = gelic_net_change_mtu,
        .ndo_tx_timeout = gelic_net_tx_timeout,
        .ndo_set_mac_address = eth_mac_addr,
similarity index 99%
rename from drivers/net/spider_net.c
rename to drivers/net/ethernet/toshiba/spider_net.c
index 1ff3491c82402aee8e468e660d53c523c1f403cf..6199f6b387b6b5dc9ee9891f66b28e9078099c5e 100644 (file)
@@ -196,7 +196,7 @@ spider_net_setup_aneg(struct spider_net_card *card)
        if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_THALF))
                advertise |= SUPPORTED_1000baseT_Half;
 
-       mii_phy_probe(phy, phy->mii_id);
+       sungem_phy_probe(phy, phy->mii_id);
        phy->def->ops->setup_aneg(phy, advertise);
 
 }
@@ -2120,7 +2120,7 @@ spider_net_setup_phy(struct spider_net_card *card)
                unsigned short id;
                id = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
                if (id != 0x0000 && id != 0xffff) {
-                       if (!mii_phy_probe(phy, phy->mii_id)) {
+                       if (!sungem_phy_probe(phy, phy->mii_id)) {
                                pr_info("Found %s.\n", phy->def->name);
                                break;
                        }
@@ -2259,7 +2259,7 @@ static const struct net_device_ops spider_net_ops = {
        .ndo_open               = spider_net_open,
        .ndo_stop               = spider_net_stop,
        .ndo_start_xmit         = spider_net_xmit,
-       .ndo_set_multicast_list = spider_net_set_multi,
+       .ndo_set_rx_mode        = spider_net_set_multi,
        .ndo_set_mac_address    = spider_net_set_mac,
        .ndo_change_mtu         = spider_net_change_mtu,
        .ndo_do_ioctl           = spider_net_do_ioctl,
similarity index 99%
rename from drivers/net/spider_net.h
rename to drivers/net/ethernet/toshiba/spider_net.h
index 020f64a8fcf79a97bfa26828be3303f7a6cbfbdf..4ba2135474d1a118a7a86b579aae38b11eb2c56a 100644 (file)
@@ -27,7 +27,7 @@
 
 #define VERSION "2.0 B"
 
-#include "sungem_phy.h"
+#include <linux/sungem_phy.h>
 
 extern int spider_net_stop(struct net_device *netdev);
 extern int spider_net_open(struct net_device *netdev);
similarity index 99%
rename from drivers/net/tc35815.c
rename to drivers/net/ethernet/toshiba/tc35815.c
index 4a55a162dfe6409ea11dbe858ea86721bd40aa9c..71b785cd756368aa2a2c4972e7a9cc9ae9506408 100644 (file)
@@ -774,7 +774,7 @@ static const struct net_device_ops tc35815_netdev_ops = {
        .ndo_stop               = tc35815_close,
        .ndo_start_xmit         = tc35815_send_packet,
        .ndo_get_stats          = tc35815_get_stats,
-       .ndo_set_multicast_list = tc35815_set_multicast_list,
+       .ndo_set_rx_mode        = tc35815_set_multicast_list,
        .ndo_tx_timeout         = tc35815_tx_timeout,
        .ndo_do_ioctl           = tc35815_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/tundra/Kconfig b/drivers/net/ethernet/tundra/Kconfig
new file mode 100644 (file)
index 0000000..03925d1
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Tundra network device configuration
+#
+
+config NET_VENDOR_TUNDRA
+       bool "Tundra devices"
+       depends on TSI108_BRIDGE
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Tundra cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_TUNDRA
+
+config TSI108_ETH
+       tristate "Tundra TSI108 gigabit Ethernet support"
+       depends on TSI108_BRIDGE
+       ---help---
+         This driver supports Tundra TSI108 gigabit Ethernet ports.
+         To compile this driver as a module, choose M here: the module
+         will be called tsi108_eth.
+
+endif # NET_VENDOR_TUNDRA
diff --git a/drivers/net/ethernet/tundra/Makefile b/drivers/net/ethernet/tundra/Makefile
new file mode 100644 (file)
index 0000000..439f693
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Tundra network device drivers.
+#
+
+obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
similarity index 99%
rename from drivers/net/tsi108_eth.c
rename to drivers/net/ethernet/tundra/tsi108_eth.c
index 64cb9ac19ed92d020dc3021665fe64090d58e4eb..480a4ba53172590ac244823b37a0b15bb6295efd 100644 (file)
@@ -1554,7 +1554,7 @@ static const struct net_device_ops tsi108_netdev_ops = {
        .ndo_open               = tsi108_open,
        .ndo_stop               = tsi108_close,
        .ndo_start_xmit         = tsi108_send_packet,
-       .ndo_set_multicast_list = tsi108_set_rx_mode,
+       .ndo_set_rx_mode        = tsi108_set_rx_mode,
        .ndo_get_stats          = tsi108_get_stats,
        .ndo_do_ioctl           = tsi108_do_ioctl,
        .ndo_set_mac_address    = tsi108_set_mac,
diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig
new file mode 100644 (file)
index 0000000..7199194
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# VIA device configuration
+#
+
+config NET_VENDOR_VIA
+       bool "VIA devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about VIA devices. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_VIA
+
+config VIA_RHINE
+       tristate "VIA Rhine support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
+         Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
+         Ethernet functions can also be found integrated on South Bridges
+         (e.g. VT8235).
+
+         To compile this driver as a module, choose M here. The module
+         will be called via-rhine.
+
+config VIA_RHINE_MMIO
+       bool "Use MMIO instead of PIO"
+       depends on VIA_RHINE
+       ---help---
+         This instructs the driver to use PCI shared memory (MMIO) instead of
+         programmed I/O ports (PIO). Enabling this gives an improvement in
+         processing time in parts of the driver.
+
+         If unsure, say Y.
+
+config VIA_VELOCITY
+       tristate "VIA Velocity support"
+       depends on PCI
+       select CRC32
+       select CRC_CCITT
+       select MII
+       ---help---
+         If you have a VIA "Velocity" based network card say Y here.
+
+         To compile this driver as a module, choose M here. The module
+         will be called via-velocity.
+
+endif # NET_VENDOR_VIA
diff --git a/drivers/net/ethernet/via/Makefile b/drivers/net/ethernet/via/Makefile
new file mode 100644 (file)
index 0000000..46c5d4a
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the VIA device drivers.
+#
+
+obj-$(CONFIG_VIA_RHINE) += via-rhine.o
+obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
similarity index 99%
rename from drivers/net/via-rhine.c
rename to drivers/net/ethernet/via/via-rhine.c
index 7f23ab913fd9044fea6c2377bacbf5fd4f632ccc..f34dd99fe57917c546414c47607180bee2e59467 100644 (file)
@@ -697,7 +697,7 @@ static const struct net_device_ops rhine_netdev_ops = {
        .ndo_stop                = rhine_close,
        .ndo_start_xmit          = rhine_start_tx,
        .ndo_get_stats           = rhine_get_stats,
-       .ndo_set_multicast_list  = rhine_set_rx_mode,
+       .ndo_set_rx_mode         = rhine_set_rx_mode,
        .ndo_change_mtu          = eth_change_mtu,
        .ndo_validate_addr       = eth_validate_addr,
        .ndo_set_mac_address     = eth_mac_addr,
similarity index 97%
rename from drivers/net/via-velocity.c
rename to drivers/net/ethernet/via/via-velocity.c
index deb1eca13c9f4f8321facaced82e6740da5f5cb5..086463b141b66194b1c51ad288cebf27dd03617e 100644 (file)
@@ -42,7 +42,6 @@
  *
  */
 
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/bitops.h>
@@ -112,7 +111,6 @@ static void mac_get_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
        BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
 }
 
-
 /**
  *     mac_set_cam_mask        -       Set a CAM mask
  *     @regs: register block for this velocity
@@ -515,10 +513,6 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
        mac_set_cam_mask(regs, vptr->mCAMmask);
 
        /* Enable VCAMs */
-
-       if (test_bit(0, vptr->active_vlans))
-               WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
-
        for_each_set_bit(vid, vptr->active_vlans, VLAN_N_VID) {
                mac_set_vlan_cam(regs, i, (u8 *) &vid);
                vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
@@ -700,7 +694,6 @@ static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
        return 0;
 }
 
-
 /**
  *     mii_check_media_mode    -       check media state
  *     @regs: velocity registers
@@ -866,8 +859,6 @@ static u32 check_connection_type(struct mac_regs __iomem *regs)
        return status;
 }
 
-
-
 /**
  *     velocity_set_media_mode         -       set media mode
  *     @mii_status: old MII link state
@@ -1262,6 +1253,7 @@ static void setup_queue_timers(struct velocity_info *vptr)
                writeb(rxqueue_timer, &vptr->mac_regs->RQETMR);
        }
 }
+
 /**
  * setup_adaptive_interrupts  -  Setup interrupt suppression
  *
@@ -1601,8 +1593,6 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
        vptr->rx.info = NULL;
 }
 
-
-
 /**
  *     velocity_init_rd_ring   -       set up receive ring
  *     @vptr: velocity to configure
@@ -1676,7 +1666,6 @@ static void velocity_free_dma_rings(struct velocity_info *vptr)
        pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
 }
 
-
 static int velocity_init_rings(struct velocity_info *vptr, int mtu)
 {
        int ret;
@@ -1739,7 +1728,6 @@ static void velocity_free_tx_buf(struct velocity_info *vptr,
        tdinfo->skb = NULL;
 }
 
-
 /*
  *     FIXME: could we merge this with velocity_free_tx_buf ?
  */
@@ -1787,7 +1775,6 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
        }
 }
 
-
 static void velocity_free_rings(struct velocity_info *vptr)
 {
        velocity_free_td_ring(vptr);
@@ -2025,7 +2012,6 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
        }
 }
 
-
 /**
  *     velocity_receive_frame  -       received packet processor
  *     @vptr: velocity we are handling
@@ -2092,11 +2078,11 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
        netif_rx(skb);
 
        stats->rx_bytes += pkt_len;
+       stats->rx_packets++;
 
        return 0;
 }
 
-
 /**
  *     velocity_rx_srv         -       service RX interrupt
  *     @vptr: velocity
@@ -2404,7 +2390,6 @@ static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd
        return 0;
 }
 
-
 /**
  *     velocity_ioctl          -       ioctl entry point
  *     @dev: network device
@@ -2619,15 +2604,14 @@ out:
        return NETDEV_TX_OK;
 }
 
-
 static const struct net_device_ops velocity_netdev_ops = {
        .ndo_open               = velocity_open,
        .ndo_stop               = velocity_close,
        .ndo_start_xmit         = velocity_xmit,
        .ndo_get_stats          = velocity_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
-       .ndo_set_multicast_list = velocity_set_multi,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_set_rx_mode        = velocity_set_multi,
        .ndo_change_mtu         = velocity_change_mtu,
        .ndo_do_ioctl           = velocity_ioctl,
        .ndo_vlan_rx_add_vid    = velocity_vlan_rx_add_vid,
@@ -2717,7 +2701,6 @@ static u32 velocity_get_link(struct net_device *dev)
        return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0) ? 1 : 0;
 }
 
-
 /**
  *     velocity_found1         -       set up discovered velocity card
  *     @pdev: PCI device
@@ -2864,7 +2847,6 @@ err_free_dev:
        goto out;
 }
 
-
 #ifdef CONFIG_PM
 /**
  *     wol_calc_crc            -       WOL CRC
@@ -3035,7 +3017,7 @@ static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
 
        spin_lock_irqsave(&vptr->lock, flags);
        pci_save_state(pdev);
-#ifdef ETHTOOL_GWOL
+
        if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
                velocity_get_ip(vptr);
                velocity_save_context(vptr, &vptr->context);
@@ -3049,9 +3031,7 @@ static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
                pci_disable_device(pdev);
                pci_set_power_state(pdev, pci_choose_state(pdev, state));
        }
-#else
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-#endif
+
        spin_unlock_irqrestore(&vptr->lock, flags);
        return 0;
 }
@@ -3132,13 +3112,13 @@ static int velocity_resume(struct pci_dev *pdev)
  *     uses this to handle all our card discover and plugging
  */
 static struct pci_driver velocity_driver = {
-      .name    = VELOCITY_NAME,
-      .id_table        = velocity_id_table,
-      .probe   = velocity_found1,
-      .remove  = __devexit_p(velocity_remove1),
+       .name           = VELOCITY_NAME,
+       .id_table       = velocity_id_table,
+       .probe          = velocity_found1,
+       .remove         = __devexit_p(velocity_remove1),
 #ifdef CONFIG_PM
-      .suspend = velocity_suspend,
-      .resume  = velocity_resume,
+       .suspend        = velocity_suspend,
+       .resume         = velocity_resume,
 #endif
 };
 
@@ -3448,26 +3428,99 @@ static int velocity_set_coalesce(struct net_device *dev,
        return 0;
 }
 
+static const char velocity_gstrings[][ETH_GSTRING_LEN] = {
+       "rx_all",
+       "rx_ok",
+       "tx_ok",
+       "rx_error",
+       "rx_runt_ok",
+       "rx_runt_err",
+       "rx_64",
+       "tx_64",
+       "rx_65_to_127",
+       "tx_65_to_127",
+       "rx_128_to_255",
+       "tx_128_to_255",
+       "rx_256_to_511",
+       "tx_256_to_511",
+       "rx_512_to_1023",
+       "tx_512_to_1023",
+       "rx_1024_to_1518",
+       "tx_1024_to_1518",
+       "tx_ether_collisions",
+       "rx_crc_errors",
+       "rx_jumbo",
+       "tx_jumbo",
+       "rx_mac_control_frames",
+       "tx_mac_control_frames",
+       "rx_frame_alignement_errors",
+       "rx_long_ok",
+       "rx_long_err",
+       "tx_sqe_errors",
+       "rx_no_buf",
+       "rx_symbol_errors",
+       "in_range_length_errors",
+       "late_collisions"
+};
+
+static void velocity_get_strings(struct net_device *dev, u32 sset, u8 *data)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               memcpy(data, *velocity_gstrings, sizeof(velocity_gstrings));
+               break;
+       }
+}
+
+static int velocity_get_sset_count(struct net_device *dev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return ARRAY_SIZE(velocity_gstrings);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void velocity_get_ethtool_stats(struct net_device *dev,
+                                      struct ethtool_stats *stats, u64 *data)
+{
+       if (netif_running(dev)) {
+               struct velocity_info *vptr = netdev_priv(dev);
+               u32 *p = vptr->mib_counter;
+               int i;
+
+               spin_lock_irq(&vptr->lock);
+               velocity_update_hw_mibs(vptr);
+               spin_unlock_irq(&vptr->lock);
+
+               for (i = 0; i < ARRAY_SIZE(velocity_gstrings); i++)
+                       *data++ = *p++;
+       }
+}
+
 static const struct ethtool_ops velocity_ethtool_ops = {
-       .get_settings   =       velocity_get_settings,
-       .set_settings   =       velocity_set_settings,
-       .get_drvinfo    =       velocity_get_drvinfo,
-       .get_wol        =       velocity_ethtool_get_wol,
-       .set_wol        =       velocity_ethtool_set_wol,
-       .get_msglevel   =       velocity_get_msglevel,
-       .set_msglevel   =       velocity_set_msglevel,
-       .get_link       =       velocity_get_link,
-       .get_coalesce   =       velocity_get_coalesce,
-       .set_coalesce   =       velocity_set_coalesce,
-       .begin          =       velocity_ethtool_up,
-       .complete       =       velocity_ethtool_down
+       .get_settings           = velocity_get_settings,
+       .set_settings           = velocity_set_settings,
+       .get_drvinfo            = velocity_get_drvinfo,
+       .get_wol                = velocity_ethtool_get_wol,
+       .set_wol                = velocity_ethtool_set_wol,
+       .get_msglevel           = velocity_get_msglevel,
+       .set_msglevel           = velocity_set_msglevel,
+       .get_link               = velocity_get_link,
+       .get_strings            = velocity_get_strings,
+       .get_sset_count         = velocity_get_sset_count,
+       .get_ethtool_stats      = velocity_get_ethtool_stats,
+       .get_coalesce           = velocity_get_coalesce,
+       .set_coalesce           = velocity_set_coalesce,
+       .begin                  = velocity_ethtool_up,
+       .complete               = velocity_ethtool_down
 };
 
-#ifdef CONFIG_PM
-#ifdef CONFIG_INET
+#if defined(CONFIG_PM) && defined(CONFIG_INET)
 static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
 {
-       struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
+       struct in_ifaddr *ifa = ptr;
        struct net_device *dev = ifa->ifa_dev->dev;
 
        if (dev_net(dev) == &init_net &&
@@ -3476,12 +3529,9 @@ static int velocity_netdev_event(struct notifier_block *nb, unsigned long notifi
 
        return NOTIFY_DONE;
 }
-#endif /* CONFIG_INET */
-#endif /* CONFIG_PM */
 
-#if defined(CONFIG_PM) && defined(CONFIG_INET)
 static struct notifier_block velocity_inetaddr_notifier = {
-      .notifier_call   = velocity_netdev_event,
+       .notifier_call  = velocity_netdev_event,
 };
 
 static void velocity_register_notifier(void)
diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
new file mode 100644 (file)
index 0000000..4e3aad4
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# Xilink device configuration
+#
+
+config NET_VENDOR_XILINX
+       bool "Xilinx devices"
+       depends on PPC || PPC32 || MICROBLAZE
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Xilinx devices. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_XILINX
+
+config XILINX_EMACLITE
+       tristate "Xilinx 10/100 Ethernet Lite support"
+       depends on (PPC32 || MICROBLAZE)
+       select PHYLIB
+       ---help---
+         This driver supports the 10/100 Ethernet Lite from Xilinx.
+
+config XILINX_LL_TEMAC
+       tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
+       depends on (PPC || MICROBLAZE)
+       select PHYLIB
+       ---help---
+         This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
+         core used in Xilinx Spartan and Virtex FPGAs
+
+endif # NET_VENDOR_XILINX
diff --git a/drivers/net/ethernet/xilinx/Makefile b/drivers/net/ethernet/xilinx/Makefile
new file mode 100644 (file)
index 0000000..5feac73
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the Xilink network device drivers.
+#
+
+ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
+obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
+obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
similarity index 99%
rename from drivers/net/ll_temac_main.c
rename to drivers/net/ethernet/xilinx/ll_temac_main.c
index 728fe414147a25688d8b96327448a9c5e1a90233..570776edc01bab37dc268760a5568334ca797d46 100644 (file)
@@ -922,7 +922,6 @@ static const struct net_device_ops temac_netdev_ops = {
        .ndo_start_xmit = temac_start_xmit,
        .ndo_set_mac_address = netdev_set_mac_address,
        .ndo_validate_addr = eth_validate_addr,
-       //.ndo_set_multicast_list = temac_set_multicast_list,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = temac_poll_controller,
 #endif
diff --git a/drivers/net/ethernet/xircom/Kconfig b/drivers/net/ethernet/xircom/Kconfig
new file mode 100644 (file)
index 0000000..3d64e58
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# Xircom network device configuration
+#
+
+config NET_VENDOR_XIRCOM
+       bool "Xircom devices"
+       depends on PCMCIA
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Xircom cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_XIRCOM
+
+config PCMCIA_XIRC2PS
+       tristate "Xircom 16-bit PCMCIA support"
+       depends on PCMCIA
+       ---help---
+         Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card)
+         Ethernet or Fast Ethernet card to your computer.
+
+         To compile this driver as a module, choose M here: the module will be
+         called xirc2ps_cs.  If unsure, say N.
+
+endif # NET_VENDOR_XIRCOM
diff --git a/drivers/net/ethernet/xircom/Makefile b/drivers/net/ethernet/xircom/Makefile
new file mode 100644 (file)
index 0000000..3b7aebd
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Xircom network device drivers.
+#
+
+obj-$(CONFIG_PCMCIA_XIRC2PS) += xirc2ps_cs.o
similarity index 99%
rename from drivers/net/pcmcia/xirc2ps_cs.c
rename to drivers/net/ethernet/xircom/xirc2ps_cs.c
index e33b190d716fc7f7cf0c56a8ca0783110e999c47..bbe8b7dbf3f381aadba59d6900c9aca7002adc6d 100644 (file)
@@ -467,7 +467,7 @@ static const struct net_device_ops netdev_ops = {
        .ndo_tx_timeout         = xirc_tx_timeout,
        .ndo_set_config         = do_config,
        .ndo_do_ioctl           = do_ioctl,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
new file mode 100644 (file)
index 0000000..6bbcc54
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Intel XScale IXP device configuration
+#
+
+config NET_VENDOR_XSCALE
+       bool "Intel XScale IXP devices"
+       depends on NET_VENDOR_INTEL && ((ARM && ARCH_IXP4XX && \
+                  IXP4XX_NPE && IXP4XX_QMGR) || ARCH_ENP2611)
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question does not directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about XSacle IXP devices. If you say Y, you will be
+         asked for your specific card in the following questions.
+
+if NET_VENDOR_XSCALE
+
+config IXP4XX_ETH
+       tristate "Intel IXP4xx Ethernet support"
+       depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
+       select PHYLIB
+       ---help---
+         Say Y here if you want to use built-in Ethernet ports
+         on IXP4xx processor.
+
+source "drivers/net/ethernet/xscale/ixp2000/Kconfig"
+
+endif # NET_VENDOR_XSCALE
diff --git a/drivers/net/ethernet/xscale/Makefile b/drivers/net/ethernet/xscale/Makefile
new file mode 100644 (file)
index 0000000..b195b9d
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the Intel XScale IXP device drivers.
+#
+
+obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
+obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o
similarity index 94%
rename from drivers/net/ixp2000/Kconfig
rename to drivers/net/ethernet/xscale/ixp2000/Kconfig
index 2fec2415651f16e7ea75fd527a03a0b6c4bb19c7..58dbc5b876bc6b9228d33e3c0c3f5bd8ee304af7 100644 (file)
@@ -1,6 +1,6 @@
 config ENP2611_MSF_NET
        tristate "Radisys ENP2611 MSF network interface support"
        depends on ARCH_ENP2611
-       help
+       ---help---
          This is a driver for the MSF network interface unit in
          the IXP2400 on the Radisys ENP2611 platform.
similarity index 99%
rename from drivers/net/arm/ixp4xx_eth.c
rename to drivers/net/ethernet/xscale/ixp4xx_eth.c
index de51e8453c133700a6c1e06087c7f00625cf1d07..ec96d910e9a3e6528172329f730465d2bda4caac 100644 (file)
@@ -1339,7 +1339,7 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
        .ndo_open = eth_open,
        .ndo_stop = eth_close,
        .ndo_start_xmit = eth_xmit,
-       .ndo_set_multicast_list = eth_set_mcast_list,
+       .ndo_set_rx_mode = eth_set_mcast_list,
        .ndo_do_ioctl = eth_ioctl,
        .ndo_change_mtu = eth_change_mtu,
        .ndo_set_mac_address = eth_mac_addr,
diff --git a/drivers/net/ibm_newemac/Makefile b/drivers/net/ibm_newemac/Makefile
deleted file mode 100644 (file)
index 0b5c995..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the PowerPC 4xx on-chip ethernet driver
-#
-
-obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac.o
-
-ibm_newemac-y := mal.o core.o phy.o
-ibm_newemac-$(CONFIG_IBM_NEW_EMAC_ZMII) += zmii.o
-ibm_newemac-$(CONFIG_IBM_NEW_EMAC_RGMII) += rgmii.o
-ibm_newemac-$(CONFIG_IBM_NEW_EMAC_TAH) += tah.o
-ibm_newemac-$(CONFIG_IBM_NEW_EMAC_DEBUG) += debug.o
index 41c96b3d8152acba4d61ed5b43b7086deae07f7a..e880c79d7bd811a68a3c2fa3a8ae3369f77e4bd9 100644 (file)
@@ -750,7 +750,7 @@ static int stir_transmit_thread(void *arg)
 
                        write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
 
-                       refrigerator();
+                       try_to_freeze();
 
                        if (change_speed(stir, stir->speed))
                                break;
diff --git a/drivers/net/mac-puv3.c b/drivers/net/mac-puv3.c
new file mode 100644 (file)
index 0000000..f55d6c2
--- /dev/null
@@ -0,0 +1,1807 @@
+/*
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *     Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *     Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/bug.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/cache.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/hardware.h>
+
+MODULE_DESCRIPTION("PKUNITY-3 SoC Ethernet driver");
+MODULE_LICENSE("GPL v2");
+
+/*
+ * umal_string: PKUnity-v3-UMAL
+ * umal_mdio_string: umal-mdio
+ */
+static const char umal_string[] = "PKUnity-v3-UMAL";
+static const char umal_mdio_string[] = "umal-mdio";
+
+/*
+ * enum umal-fc -  Simple types
+ */
+enum umal_fc {
+       umal_fc_none,
+       umal_fc_disabled,
+       umal_fc_frame,
+       umal_fc_collision,
+       umal_fc_carrier,
+};
+
+/*
+ * enum umal-state -  Simple types
+ */
+enum umal_state {
+       umal_state_uninit,
+       umal_state_off,
+       umal_state_on,
+       umal_state_broken,
+};
+
+/*
+ *  Macros
+ */
+#define UMALDMA_NEXTBUF(d, f) ((((d)->f+1) == (d)->umaldma_dscrtable_end) ? \
+                         (d)->umaldma_dscrtable : (d)->f+1)
+
+#define DMA_RX                 0
+#define DMA_TX                 1
+
+#define UMAL_MAX_TXDESCR       256
+#define UMAL_MAX_RXDESCR       256
+
+#define ENET_PACKET_SIZE       1518
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT             (2*HZ)
+
+/*
+ * struct umaldmadscr - DMA Descriptor structure
+ */
+struct umaldmadscr {
+       dma_addr_t   packet_start_addr;
+       int          packet_size;
+       dma_addr_t   next_descriptor;
+       struct umaldmadscr *next_descriptor_Virt;
+};
+
+/**
+ * struct umadlma - DMA Controller structure
+ * @umaldma_eth: back pointer to associated MAC
+ * @umaldma_txdir: direction(1 = transmit)
+ * @umaldma_maxdescr: total number of descriptors in ring
+ * @umaldma_dscrtable: base of the descriptor table
+ * @umaldma_dscrtable_unaligned: base of the descriptor table unaligned
+ * @umaldma_dscrtable_phys: phys addr
+ * @umaldma_dscrtable_phys_unaligned: another phys addr
+ * @umaldma_dscrtable_end: the end of the descriptor table
+ * @umaldma_ctxtable: context table, one per descr
+ * @umaldma_addptr: next dscr for sw to add
+ * @umaldma_remptr: next dscr for sw to remove
+ *
+ * DMA Controller.
+ * umaldma_eth, umaldma_txdir, umaldma_maxdescr is used to identify
+ * the channel and the registers associated with it.
+ * And the following other members is used for maintenance of the ring.
+ */
+struct umaldma {
+       /*
+        * This stuff is used to identify the channel and the registers
+        * associated with it.
+        */
+       /* back pointer to associated MAC */
+       struct umal_softc       *umaldma_eth;
+       /* direction (1=transmit) */
+       int                     umaldma_txdir;
+       /* total # of descriptors in ring */
+       int                     umaldma_maxdescr;
+       /*
+        * This stuff is for maintenance of the ring
+        */
+       /* base of descriptor table */
+       struct umaldmadscr      *umaldma_dscrtable;
+       void                    *umaldma_dscrtable_unaligned;
+       /* and also the phys addr */
+       dma_addr_t              umaldma_dscrtable_phys;
+       /* and also the phys addr */
+       dma_addr_t              umaldma_dscrtable_phys_unaligned;
+       /* end of descriptor table */
+       struct umaldmadscr      *umaldma_dscrtable_end;
+       /* context table, one per descr */
+       struct sk_buff          **umaldma_ctxtable;
+       /* next dscr for sw to add */
+       struct umaldmadscr      *umaldma_addptr;
+       /* next dscr for sw to remove */
+       struct umaldmadscr      *umaldma_remptr;
+};
+
+/*
+ * struct my_struct -  Ethernet softc structure
+ */
+struct umal_softc {
+       /* Linux-specific things */
+       struct net_device       *umal_dev;      /* pointer to linux device */
+       int                     umal_idx;
+       struct phy_device       *phy_dev;       /* the associated PHY device */
+       struct mii_bus          *mii_bus;       /* the MII bus */
+       int                     phy_irq[PHY_MAX_ADDR];
+       spinlock_t              umal_lock;      /* spin lock */
+       int                     umal_devflags;  /* current device flags */
+
+       /* Controller-specific things */
+       enum umal_state         umal_state;     /* current state */
+       unsigned char           umal_hwaddr[ETH_ALEN];
+
+       int                     umal_speed;     /* current speed */
+       int                     umal_duplex;    /* current duplex */
+       enum umal_fc            umal_fc;        /* cur. flow control setting */
+       int                     umal_pause;     /* current pause setting */
+       int                     umal_link;      /* current link state */
+
+       struct umaldma          umal_rxdma;     /* rx dma channel */
+       struct umaldma          umal_txdma;     /* tx dma channel */
+};
+
+/*
+ * MII Bus functions  - for PAL (phy abstraction layer)
+ */
+
+/**
+ * umal_mii_reset() - Reset MII bus.
+ * @bus: MDIO bus handle.
+ *
+ * MII Bus functions for PAL (phy abstraction layer)
+ * Reset MII bus.
+ * Return value, 0 if ok.
+ */
+static int umal_mii_reset(struct mii_bus *bus)
+{
+       /* reset the MII management */
+       writel(UMAL_MIICFG_RESET, UMAL_MIICFG);
+       /* enable the MII management */
+       writel(0, UMAL_MIICFG);
+       /* source clock division = 28 */
+       writel(readl(UMAL_MIICFG) | 0x7, UMAL_MIICFG);
+
+       return 0;
+}
+
+/**
+ * umal_mii_read() - Read a PHY register.
+ * @bus: MDIO bus handle
+ * @phyaddr: PHY's address
+ * @regidx: index of register to read
+ *
+ * MII Bus functions for PAL (phy abstraction layer)
+ * Read a PHY register.
+ * Return valume, value read, or 0xffff if an error occurred.
+ */
+static int umal_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
+{
+       int tmp = 0;
+
+       writel((phyaddr<<8) | regidx, UMAL_MIIADDR);
+       writel(UMAL_MIICMD_READ, UMAL_MIICMD);
+
+       tmp = readl(UMAL_MIIIDCT);
+       while (tmp & UMAL_MIIIDCT_BUSY)
+               tmp = readl(UMAL_MIIIDCT);
+
+       if (tmp & UMAL_MIIIDCT_NOTVALID)
+               return 0xffff;
+
+       writel(0, UMAL_MIICMD);
+
+       tmp = readl(UMAL_MIISTATUS);
+       return tmp;
+}
+
+/**
+ * umal_mii_write() - Write a value to a PHY register.
+ * @bus: MDIO bus handle
+ * @phyaddr: PHY to use
+ * @regidx: register within the PHY
+ * @val: data to write to register
+ *
+ * MII Bus functions for PAL (phy abstraction layer)
+ * Write a value to a PHY register
+ * Return value, 0 if ok
+ */
+static int umal_mii_write(struct mii_bus *bus, int phyaddr, int regidx, u16 val)
+{
+       int tmp = 0;
+
+       writel((phyaddr<<8) | regidx, UMAL_MIIADDR);
+       writel(val, UMAL_MIICTRL);
+
+       tmp = readl(UMAL_MIIIDCT);
+       while (tmp & UMAL_MIIIDCT_BUSY)
+               tmp = readl(UMAL_MIIIDCT);
+
+       return 0;
+}
+
+/**
+ * umal_clr_intr() - Clear all interrupt of umal
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Clear all interrupt of umal
+ * Return value, nothing
+ */
+static void umal_clr_intr(struct net_device *dev)
+{
+       unsigned int int_status;
+
+       if (!netif_device_present(dev))
+               return;
+       int_status = readl(UMAL_DMAInterrupt);
+       if (int_status & INT_RX_PKT)
+               writel(CLR_RX_PKT, UMAL_DMARxStatus);
+
+       if (int_status & INT_RX_BUS_ERR)
+               writel(CLR_RX_BUS_ERR, UMAL_DMARxStatus);
+
+       if (int_status & INT_RX_OVERFLOW)
+               writel(CLR_RX_OVERFLOW, UMAL_DMARxStatus);
+
+       if (int_status & INT_TX_PKT)
+               writel(CLR_TX_PKT, UMAL_DMATxStatus);
+
+       if (int_status & INT_TX_BUS_ERR)
+               writel(CLR_TX_BUS_ERR, UMAL_DMATxStatus);
+
+       if (int_status & INT_TX_UNDERRUN)
+               writel(CLR_TX_UNDERRUN, UMAL_DMATxStatus);
+}
+
+/**
+ * umal_promiscuous_mode() - Turn on or off promiscuous mode
+ * @sc: softc
+ * @onoff: 1 to turn on, 0 to turn off
+ *
+ * UMAL functions
+ * Turn on or off promiscuous mode
+ * Return value, nothing
+ */
+static void umal_promiscuous_mode(struct umal_softc *sc, int onoff)
+{
+       if (onoff) {
+               writel(readl(UMAL_FIFOCFG4) & ~0x40000, UMAL_FIFOCFG4);
+               writel(readl(UMAL_FIFOCFG5) | 0x40000, UMAL_FIFOCFG5);
+       } else {
+               writel(readl(UMAL_FIFOCFG4) | 0x40000, UMAL_FIFOCFG4);
+               writel(readl(UMAL_FIFOCFG5) & ~0x40000, UMAL_FIFOCFG5);
+       }
+}
+
+/**
+ * umal_setmulti() - Reprogram the multicasr table into the hardware.
+ * @sc: softc
+ *
+ * UMAL functions
+ * Reprogram the multicast table into the hardware, given
+ * the list of multicasts associated with the interface
+ * structure.
+ * Return value, nothing
+ */
+static void umal_setmulti(struct umal_softc *sc)
+{
+}
+
+/**
+ * umal_set_speed() - Configure LAN speed for the specified MAC.
+ * @s: sbmac structure
+ * @speed: speed to set MAC to (see enum sbmac_speed)
+ *
+ * UMAL functions
+ * Configure LAN speed for the specified MAC.
+ * Warning: must be called when MAC is off!
+ * Return value,
+ *     1 if successful
+ *     0 indicates invalid parameters
+ */
+static int umal_set_speed(struct umal_softc *s, int speed)
+{
+       unsigned int cfg;
+
+       /* Save new current values */
+       s->umal_speed = speed;
+
+       if (s->umal_state == umal_state_on)
+               return 0;       /* save for next restart */
+
+       /* Read current register values */
+       cfg = readl(UMAL_CFG2);
+
+       /* Mask out the stuff we want to change */
+       cfg &= ~(UMAL_CFG2_MODEMASK);
+
+       /* Now add in the new bits */
+       switch (speed) {
+       case SPEED_10:
+       case SPEED_100:
+               cfg |= UMAL_CFG2_NIBBLEMODE;
+               break;
+
+       default:
+               return 0;
+       }
+
+       /* Send the bits back to the hardware */
+       writel(cfg, UMAL_CFG2);
+
+       return 1;
+}
+
+/**
+ * umal_set_duplex() - Set Ethernet duplex and flow control options for this MAC
+ * @s: umal structure
+ * @duplex: duplex setting (see enum sbmac_duplex)
+ * @fc: flow control setting (see enum sbmac_fc)
+ *
+ * UMAL functions
+ * Set Ethernet duplex and flow control options for this MAC
+ * Warning: must be called when MAC is off!
+ * Return value,
+ *      1 if ok
+ *      0 if an invalid parameter combination was specified
+ */
+static int umal_set_duplex(struct umal_softc *s, int duplex,
+               enum umal_fc fc)
+{
+       unsigned int cfg1, cfg2;
+       int err = 0;
+
+       /* Save new current values */
+       s->umal_duplex = duplex;
+       s->umal_fc = fc;
+
+       if (s->umal_state == umal_state_on)
+               return 0;       /* save for next restart */
+
+       /* Read current register values */
+       cfg1 = readl(UMAL_CFG1);
+       cfg2 = readl(UMAL_CFG2);
+
+       /* Mask off the stuff we're about to change */
+       cfg1 &= ~(UMAL_CFG1_TXFLOWCTL | UMAL_CFG1_RXFLOWCTL);
+       cfg2 &= ~(UMAL_CFG2_FULLDUPLEX);
+
+       err = 0;
+       switch (duplex) {
+       case DUPLEX_HALF:
+               break;
+
+       case DUPLEX_FULL:
+               cfg2 |= UMAL_CFG2_FULLDUPLEX;
+               break;
+
+       default:
+               err = 1;
+       }
+       if (!err)
+               writel(cfg2, UMAL_CFG2);
+
+       err = 0;
+       switch (fc) {
+       case umal_fc_disabled:
+               break;
+
+       case umal_fc_collision:
+               break;
+
+       case umal_fc_carrier:
+               break;
+
+       case umal_fc_frame:
+               cfg1 |= UMAL_CFG1_TXFLOWCTL | UMAL_CFG1_RXFLOWCTL;
+               break;
+
+       default:
+               err = 1;
+       }
+
+       if (!err)
+               writel(cfg1, UMAL_CFG1);
+
+       /* Send the bits back to the hardware */
+       return 1;
+}
+
+/**
+ * umaldma_channel_start() - Open a DMA channel.
+ * @d: DMA channel to init (context must be previously init'd)
+ * @rxtx: DMA_RX or DMA_TX depending on what type of channel
+ *
+ * UMAL DMA functions
+ * Open a DMA channel
+ * Return value, nothing
+ */
+static void umaldma_channel_start(struct umaldma *d, int rxtx)
+{
+       /*
+        * Turn on the DMA channel
+        */
+       if (rxtx == DMA_TX) {
+               writel(d->umaldma_dscrtable_phys, UMAL_DMATxDescriptor);
+               writel(UMAL_DMA_Enable, UMAL_DMATxCtrl);
+       } else {
+               writel(d->umaldma_dscrtable_phys, UMAL_DMARxDescriptor);
+               writel(UMAL_DMA_Enable, UMAL_DMARxCtrl);
+       }
+}
+
+/**
+ * umaldma_channel_stop() - Close DMA channel.
+ * @d: DMA channel to init (context must be previously init'd
+ *
+ * UMAL DMA functions
+ * Close DMA channel.
+ * Return value, nothing
+ */
+static void umaldma_channel_stop(struct umaldma *d)
+{
+       /*
+        * Turn off the DMA channel
+        */
+       if (d->umaldma_txdir == DMA_TX) {
+               writel(0, UMAL_DMATxCtrl);
+               writel(0, UMAL_DMATxDescriptor);
+       } else {
+               writel(0, UMAL_DMARxCtrl);
+               writel(0, UMAL_DMARxDescriptor);
+       }
+
+       /*
+        * Zero ring pointers
+        */
+       d->umaldma_addptr = d->umaldma_dscrtable;
+       d->umaldma_remptr = d->umaldma_dscrtable;
+}
+
+/**
+ * umaldma_add_rcvbuffer() - Add a buffer to the specified DMA channel.
+ * @sc: softc structure
+ * @d: DMA channel descriptor
+ * @sb: sk_buff to add, or NULL if we shoule allocate one
+ *
+ * UMAL DMA functions
+ * Add a buffer to the specified DMA channel.
+ * For receive channels, this queues a buffer for inbound packets.
+ * Return calue,
+ *     0 if buffer coule could not be added(ring is full)
+ *     1 if buffer added successfully
+ */
+static int umaldma_add_rcvbuffer(struct umal_softc *sc, struct umaldma *d,
+               struct sk_buff *sb)
+{
+       struct net_device *dev = sc->umal_dev;
+       struct umaldmadscr *dsc;
+       struct umaldmadscr *nextdsc;
+       struct sk_buff *sb_new = NULL;
+
+       /* get pointer to our current place in the ring */
+       dsc = d->umaldma_addptr;
+       nextdsc = UMALDMA_NEXTBUF(d, umaldma_addptr);
+
+       /*
+        * figure out if the ring is full - if the next descriptor
+        * is the same as the one that we're going to remove from
+        * the ring, the ring is full
+        */
+       if (nextdsc == d->umaldma_remptr)
+               return -ENOSPC;
+
+       /*
+        * Allocate a sk_buff if we don't already have one.
+        * If we do have an sk_buff, reset it so that it's empty.
+        *
+        * Note: sk_buffs don't seem to be guaranteed to have any sort
+        * of alignment when they are allocated.  Therefore, allocate enough
+        * extra space to make sure that:
+        *
+        *    1. the data does not start in the middle of a cache line.
+        *    2. The data does not end in the middle of a cache line
+        *    3. The buffer can be aligned such that the IP addresses are
+        *       naturally aligned.
+        *
+        *  Remember, the SOCs MAC writes whole cache lines at a time,
+        *  without reading the old contents first.  So, if the sk_buff's
+        *  data portion starts in the middle of a cache line, the SOC
+        *  DMA will trash the beginning (and ending) portions.
+        */
+       if (sb == NULL) {
+               sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE +
+                       SMP_CACHE_BYTES * 2 + NET_IP_ALIGN);
+               if (sb_new == NULL) {
+                       pr_info("%s: sk_buff allocation failed\n",
+                               d->umaldma_eth->umal_dev->name);
+                       return -ENOMEM;
+               }
+               skb_reserve(sb_new, SMP_CACHE_BYTES + NET_IP_ALIGN);
+       } else {
+               sb_new = sb;
+               /*
+                * nothing special to reinit buffer, it's already aligned
+                * and sb->data already points to a good place.
+                */
+       }
+
+       /* fill in the descriptor */
+       dsc->packet_start_addr = virt_to_phys(sb_new->data);
+       dsc->packet_size      = UMAL_DESC_PACKETSIZE_EMPTY;
+
+       /* fill in the context */
+       d->umaldma_ctxtable[dsc-d->umaldma_dscrtable] = sb_new;
+
+       /* point at next packet */
+       d->umaldma_addptr = nextdsc;
+
+       return 0;
+}
+
+/**
+ * umaldma_fillring() - Fill the specified DMA channel with sk_buffs
+ * @sc: softc structure
+ * @d: DMA channel
+ *
+ * UMAL DMA functions
+ * Fill the specified DMA channel (must be receive channel) with sk_buffs
+ * Return value, nothing
+ */
+static void umaldma_fillring(struct umal_softc *sc, struct umaldma *d)
+{
+       int idx;
+       for (idx = 0; idx < UMAL_MAX_RXDESCR - 1; idx++) {
+               if (umaldma_add_rcvbuffer(sc, d, NULL) != 0)
+                       break;
+       }
+}
+
+/**
+ * umal_channel_start() - Start packet processing on this MAC.
+ * @s: umal context structure
+ *
+ * UMAL Channel functions
+ * Start packet processing on this MAC.
+ * Return value, nothing
+ */
+static void umal_channel_start(struct umal_softc *s)
+{
+       /*
+        * Don't do this if running
+        */
+       if (s->umal_state == umal_state_on)
+               return;
+
+       /* don't accept any packets, disable all interrupts */
+       umaldma_channel_stop(&(s->umal_rxdma));
+       umaldma_channel_stop(&(s->umal_txdma));
+
+       writel(0, UMAL_DMAIntrMask);
+       umal_clr_intr(s->umal_dev);
+
+       /*
+        * Program the hardware address.  It goes into the hardware-address
+        * register as well as the first filter register.
+        */
+       writel(s->umal_hwaddr[0]<<24 | s->umal_hwaddr[1]<<16 |
+                       s->umal_hwaddr[2]<<8 | s->umal_hwaddr[3], UMAL_STADDR1);
+       writel(s->umal_hwaddr[4]<<24 |  s->umal_hwaddr[5]<<16, UMAL_STADDR2);
+
+       /* Configure the speed, duplex, and flow control */
+       umal_set_speed(s, s->umal_speed);
+       umal_set_duplex(s, s->umal_duplex, s->umal_fc);
+
+       /* Program multicast addresses */
+       umal_setmulti(s);
+
+       /* If channel was in promiscuous mode before, turn that on */
+       if (s->umal_devflags & IFF_PROMISC)
+               umal_promiscuous_mode(s, 1);
+
+       /* Fill the receive ring */
+       umaldma_fillring(s, &(s->umal_rxdma));
+
+       umaldma_channel_start(&(s->umal_rxdma), DMA_RX);
+       umaldma_channel_start(&(s->umal_txdma), DMA_TX);
+
+       s->umal_state = umal_state_on;
+
+       /* Initialize DMA channels (rings should be ok now) */
+       writel(INT_RX_BUS_ERR | INT_RX_OVERFLOW |
+                       INT_RX_PKT        | INT_TX_BUS_ERR |
+                       INT_TX_UNDERRUN   | INT_TX_PKT |
+                       UMAL_DMAIntrMask_ENABLEHALFWORD, UMAL_DMAIntrMask);
+
+       /* we're running now.  */
+       writel(readl(UMAL_CFG1) | UMAL_CFG1_RXENABLE | UMAL_CFG1_TXENABLE,
+                       UMAL_CFG1);
+}
+
+/**
+ * umaldma_emptyring() - Free all allocated sk_buffs on specified DMA channel.
+ * @d: DMA channel
+ *
+ * UMAL DMA functions
+ * Free all allocated sk_buffs on the specified DMA channel
+ * Return value, nothing
+ */
+static void umaldma_emptyring(struct umaldma *d)
+{
+       int idx;
+       struct sk_buff *sb;
+
+       for (idx = 0; idx < d->umaldma_maxdescr; idx++) {
+               sb = d->umaldma_ctxtable[idx];
+               if (sb) {
+                       dev_kfree_skb(sb);
+                       d->umaldma_ctxtable[idx] = NULL;
+               }
+       }
+}
+
+/**
+ * umal_channel_stop() - Stop packet processing on this MAC.
+ * @s: umal context structure
+ *
+ * UMAL Channel functions
+ * Stop packet processing on this MAC.
+ * Return value, nothing
+ */
+static void umal_channel_stop(struct umal_softc *s)
+{
+       /* don't do this if already stopped */
+       if (s->umal_state == umal_state_off)
+               return;
+
+       /* don't accept any packets, disable all interrupts */
+       writel(0, UMAL_DMAIntrMask);
+       umal_clr_intr(s->umal_dev);
+
+       /* turn off receiver and transmitter */
+       writel(UMAL_CFG1_RESET, UMAL_CFG1);     /* reset MAC */
+       writel(0, UMAL_CFG1);
+
+       /* We're stopped now. */
+       s->umal_state = umal_state_off;
+
+       /* Stop DMA channels (rings should be ok now) */
+       umaldma_channel_stop(&(s->umal_rxdma));
+       umaldma_channel_stop(&(s->umal_txdma));
+
+       /* Empty the receive and transmit rings */
+       umaldma_emptyring(&(s->umal_rxdma));
+       umaldma_emptyring(&(s->umal_txdma));
+}
+
+/**
+ * umal_miipoll() - Phy statemachine call back routine for link change
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Phy statemachine call back routine for link change
+ * Return value, nothing
+ */
+static void umal_miipoll(struct net_device *dev)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+       struct phy_device *phy_dev = sc->phy_dev;
+       unsigned long flags;
+       enum umal_fc fc;
+       int link_chg, speed_chg, duplex_chg, pause_chg, fc_chg;
+
+       link_chg = (sc->umal_link != phy_dev->link);
+       speed_chg = (sc->umal_speed != phy_dev->speed);
+       duplex_chg = (sc->umal_duplex != phy_dev->duplex);
+       pause_chg = (sc->umal_pause != phy_dev->pause);
+
+       if (!link_chg && !speed_chg && !duplex_chg && !pause_chg)
+               return;
+
+       if (!phy_dev->link) {
+               if (link_chg) {
+                       sc->umal_link = phy_dev->link;
+                       sc->umal_duplex = -1;
+                       sc->umal_fc = umal_fc_disabled;
+                       sc->umal_pause = -1;
+                       pr_info("%s: link unavailable\n", dev->name);
+               }
+               return;
+       }
+
+       if (phy_dev->duplex == DUPLEX_FULL) {
+               if (phy_dev->pause)
+                       fc = umal_fc_frame;
+               else
+                       fc = umal_fc_disabled;
+       } else
+               fc = umal_fc_collision;
+       fc_chg = (sc->umal_fc != fc);
+
+       pr_info("%s: link available: %dbase-%cD\n", dev->name, phy_dev->speed,
+               phy_dev->duplex == DUPLEX_FULL ? 'F' : 'H');
+
+       spin_lock_irqsave(&sc->umal_lock, flags);
+
+       sc->umal_speed = phy_dev->speed;
+       sc->umal_duplex = phy_dev->duplex;
+       sc->umal_fc = fc;
+       sc->umal_pause = phy_dev->pause;
+       sc->umal_link = phy_dev->link;
+
+       if ((speed_chg || duplex_chg || fc_chg) &&
+               sc->umal_state != umal_state_off) {
+               /* something changed, restart the channel */
+               umal_channel_stop(sc);
+               umal_channel_start(sc);
+       }
+
+       spin_unlock_irqrestore(&sc->umal_lock, flags);
+}
+
+/**
+ * umal_mii_probe() - Write a value to a PHY register.
+ * @dev: net_device structure
+ *
+ * MII Bus functions for PAL (phy abstraction layer)
+ * Write a value to a PHY register.
+ * Return value, 0 if ok.
+ */
+static int umal_mii_probe(struct net_device *dev)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+       struct phy_device *phy_dev;
+       int i;
+
+       for (i = 0; i < PHY_MAX_ADDR; i++) {
+               phy_dev = sc->mii_bus->phy_map[i];
+               if (phy_dev)
+                       break;
+       }
+       if (!phy_dev) {
+               printk(KERN_ERR "%s: no PHY found\n", dev->name);
+               return -ENXIO;
+       }
+
+       phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &umal_miipoll, 0,
+                             PHY_INTERFACE_MODE_MII);
+       if (IS_ERR(phy_dev)) {
+               printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
+               return PTR_ERR(phy_dev);
+       }
+
+       /* Remove any features not supported by the controller */
+       phy_dev->supported &= SUPPORTED_10baseT_Half |
+                             SUPPORTED_10baseT_Full |
+                             SUPPORTED_100baseT_Half |
+                             SUPPORTED_100baseT_Full |
+                             SUPPORTED_Autoneg |
+                             SUPPORTED_MII;
+       phy_dev->advertising = phy_dev->supported;
+
+       pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+               dev->name, phy_dev->drv->name,
+               dev_name(&phy_dev->dev), phy_dev->irq);
+
+       sc->phy_dev = phy_dev;
+
+       return 0;
+}
+
+/*
+ * UMAL DMA functions
+ */
+
+/**
+ * umaldma_initctx() - Initialize a DMA channel context.
+ * @d: struct umaldma (DMA channel context)
+ * @s: struct umal_softc (pointer to a MAC)
+ * @rxtx: Identifies DMA_TX or DMA_RX for channel direction
+ * @maxdescr: number of descriptors
+ *
+ * UMAL DMA functions
+ * Initialize a DMA channel context.  Since there are potentially
+ * eight DMA channels per MAC, it's nice to do this in a standard
+ * way.
+ * Return value, nothing
+ */
+static void umaldma_initctx(struct umaldma *d, struct umal_softc *s, int rxtx,
+               int maxdescr)
+{
+       struct umaldmadscr *dscr_item;
+       int idx;
+
+       /*
+        * Save away interesting stuff in the structure
+        */
+       d->umaldma_eth   = s;
+       d->umaldma_txdir = rxtx;
+       d->umaldma_maxdescr = maxdescr;
+
+       /*
+        * Allocate memory for the ring
+        */
+       d->umaldma_dscrtable_unaligned = dma_alloc_coherent(NULL,
+                                       sizeof(*d->umaldma_dscrtable),
+                                       &d->umaldma_dscrtable_phys_unaligned,
+                                       GFP_KERNEL | GFP_DMA);
+       dma_cache_sync(NULL, d->umaldma_dscrtable_unaligned,
+                       sizeof(*d->umaldma_dscrtable), DMA_BIDIRECTIONAL);
+
+       /*
+        * The descriptor table must be aligned to at least 16 bytes or the
+        * MAC will corrupt it.
+        */
+       d->umaldma_dscrtable = (struct umaldmadscr *)
+                       ALIGN((unsigned long)d->umaldma_dscrtable_unaligned,
+                       sizeof(*d->umaldma_dscrtable));
+       d->umaldma_dscrtable_end = d->umaldma_dscrtable + d->umaldma_maxdescr;
+       d->umaldma_dscrtable_phys = ALIGN((unsigned long)
+                               d->umaldma_dscrtable_phys_unaligned,
+                               sizeof(*d->umaldma_dscrtable));
+
+       for (idx = 0; idx < d->umaldma_maxdescr; idx++) {
+               dscr_item                      = d->umaldma_dscrtable + idx;
+               dscr_item->packet_start_addr     = 0;
+               dscr_item->packet_size          = UMAL_DESC_PACKETSIZE_EMPTY;
+               dscr_item->next_descriptor      = (dma_addr_t)(
+                               (struct umaldmadscr *)d->umaldma_dscrtable_phys
+                               + (idx+1));
+               dscr_item->next_descriptor_Virt
+                       = d->umaldma_dscrtable + (idx+1);
+       }
+       dscr_item                      = d->umaldma_dscrtable +
+                                       (d->umaldma_maxdescr - 1);
+       dscr_item->next_descriptor      = d->umaldma_dscrtable_phys;
+       dscr_item->next_descriptor_Virt = d->umaldma_dscrtable;
+
+       d->umaldma_addptr = d->umaldma_dscrtable;
+       d->umaldma_remptr = d->umaldma_dscrtable;
+
+       /*
+        * And context table
+        */
+       d->umaldma_ctxtable = kcalloc(d->umaldma_maxdescr,
+                                   sizeof(*d->umaldma_ctxtable), GFP_KERNEL);
+}
+
+/**
+ * umaldma_uninitctx() - Uninitialize a DMA channel context.
+ * @d: struct umaldma (DMA channel context)
+ *
+ * UMAL DMA functions
+ * Uninitialize a DMA channel context
+ * Return value, nothing
+ */
+static void umaldma_uninitctx(struct umaldma *d)
+{
+       if (d->umaldma_dscrtable_unaligned) {
+               dma_free_coherent(NULL, sizeof(*d->umaldma_dscrtable),
+                               d->umaldma_dscrtable_unaligned,
+                               d->umaldma_dscrtable_phys_unaligned);
+               d->umaldma_dscrtable_unaligned = d->umaldma_dscrtable = NULL;
+               d->umaldma_dscrtable_phys_unaligned = 0;
+               d->umaldma_dscrtable_phys = 0;
+       }
+
+       kfree(d->umaldma_ctxtable);
+       d->umaldma_ctxtable = NULL;
+}
+
+/**
+ * umaldma_add_txbuffer() - Add a transmit buffer to the specified DMA channel.
+ * @d: DMA channel descriptor
+ * @sb: sk_buff to add
+ *
+ * UMAL DMA functions
+ * Add a transmit buffer to the specified DMA channel, causing a
+ * transmit to start.
+ * Return value,
+ *     0 transmit queued successfully
+ *     otherwise error code
+ */
+static int umaldma_add_txbuffer(struct umaldma *d, struct sk_buff *sb)
+{
+       struct umaldmadscr *dsc;
+       struct umaldmadscr *nextdsc;
+
+       /* get pointer to our current place in the ring */
+       dsc = d->umaldma_addptr;
+       nextdsc = UMALDMA_NEXTBUF(d, umaldma_addptr);
+
+       /*
+        * figure out if the ring is full - if the next descriptor
+        * is the same as the one that we're going to remove from
+        * the ring, the ring is full
+        */
+       if (nextdsc == d->umaldma_remptr)
+               return -ENOSPC;
+
+       /*
+        * fill in the descriptor.  Note that the number of cache
+        * blocks in the descriptor is the number of blocks
+        * *spanned*, so we need to add in the offset (if any)
+        * while doing the calculation.
+        */
+       dsc->packet_start_addr = virt_to_phys(sb->data);
+       dsc->packet_size      = sb->len | UMAL_DESC_PACKETSIZE_NONEMPTY;
+
+       dma_map_single(NULL, sb->data, sb->len, DMA_BIDIRECTIONAL);
+       dma_cache_sync(NULL, sb->data, sb->len, DMA_BIDIRECTIONAL);
+
+       /* fill in the context */
+       d->umaldma_ctxtable[dsc-d->umaldma_dscrtable] = sb;
+
+       /* point at next packet */
+       d->umaldma_addptr = nextdsc;
+
+       return 0;
+}
+
+/**
+ * umaldma_rx_process() - Process "completed" receive buffers.
+ * @sc: softc structure
+ * @d: DMA channel context
+ * @work_to_do: no. of packets to process before enabling interrupt
+ *  again (for NAPI)
+ * @poll: 1. using polling (for NAPI)
+ *
+ * UMAL DMA functions
+ * Process "completed" receive buffers on the specified DMA channel.
+ * Return value, nothing
+ */
+static int umaldma_rx_process(struct umal_softc *sc, struct umaldma *d,
+               int work_to_do, int poll)
+{
+       struct net_device *dev = sc->umal_dev;
+       int curidx;
+       int hwidx;
+       struct umaldmadscr *dsc;
+       struct sk_buff *sb;
+       int len;
+       int work_done = 0;
+       int dropped = 0;
+       unsigned int int_status;
+
+       if (!netif_device_present(dev))
+               return 0;
+
+       int_status = readl(UMAL_DMAInterrupt);
+
+       if (int_status & INT_RX_BUS_ERR) {
+               writel(CLR_RX_BUS_ERR, UMAL_DMARxStatus);
+               writel(readl(UMAL_DMARxCtrl) | UMAL_DMA_Enable, UMAL_DMARxCtrl);
+       }
+
+       if (int_status & INT_RX_OVERFLOW) {
+               writel(CLR_RX_OVERFLOW, UMAL_DMARxStatus);
+               writel(readl(UMAL_DMARxCtrl) | UMAL_DMA_Enable, UMAL_DMARxCtrl);
+       }
+
+       if (!(int_status & INT_RX_PKT))
+               return 0;
+
+       while (work_to_do-- > 0) {
+               /*
+                * figure out where we are (as an index) and where
+                * the hardware is (also as an index)
+                *
+                * This could be done faster if (for example) the
+                * descriptor table was page-aligned and contiguous in
+                * both virtual and physical memory -- you could then
+                * just compare the low-order bits of the virtual
+                * address (sbdma_remptr) and the physical address
+                * (sbdma_curdscr CSR)
+                */
+               dsc = d->umaldma_remptr;
+               curidx = dsc - d->umaldma_dscrtable;
+
+               hwidx = (struct umaldmadscr *) readl(UMAL_DMARxDescriptor) -
+                       (struct umaldmadscr *)d->umaldma_dscrtable_phys;
+
+               writel(CLR_RX_PKT, UMAL_DMARxStatus);
+
+               /*
+                * If they're the same, that means we've processed all
+                * of the descriptors up to (but not including) the one
+                * that the hardware is working on right now.
+                */
+               if (curidx == hwidx)
+                       goto done;
+
+               /*
+                * Otherwise, get the packet's sk_buff ptr back
+                */
+               sb = d->umaldma_ctxtable[curidx];
+               len = dsc->packet_size & 0xfff;
+               d->umaldma_ctxtable[curidx] = NULL;
+
+               /* .. and advance to the next buffer.  */
+               d->umaldma_remptr = UMALDMA_NEXTBUF(d, umaldma_remptr);
+
+               /*
+                * Check packet status.  If good, process it.
+                * If not, silently drop it and put it back on the
+                * receive ring.
+                */
+               if (likely(!(dsc->packet_size & UMAL_DESC_PACKETSIZE_EMPTY))) {
+                       /*
+                        * Add a new buffer to replace the old one.
+                        * If we fail to allocate a buffer, we're going
+                        * to drop this packet and put it right back on
+                        * the receive ring.
+                        */
+                       if (unlikely(umaldma_add_rcvbuffer(sc, d, NULL)
+                                       == -ENOMEM)) {
+                               dev->stats.rx_dropped++;
+                               /* Re-add old buffer */
+                               umaldma_add_rcvbuffer(sc, d, sb);
+                               /* No point in continuing */
+                               printk(KERN_ERR "dropped packet (1)\n");
+                               d->umaldma_remptr = UMALDMA_NEXTBUF(d,
+                                               umaldma_remptr);
+                               goto done;
+                       } else {
+                               /* Set length into the packet */
+                               skb_put(sb, len + 4);
+
+                               /*
+                                * Buffer has been replaced on the
+                                * receive ring.  Pass the buffer to
+                                * the kernel
+                                */
+                               sb->protocol = eth_type_trans(sb,
+                                       d->umaldma_eth->umal_dev);
+                               /*
+                                * Check hw IPv4/TCP checksum
+                                * if supported
+                                */
+                               skb_checksum_none_assert(sb);
+
+                               if (poll)
+                                       dropped = netif_receive_skb(sb);
+                               else
+                                       dropped = netif_rx(sb);
+
+                               if (dropped == NET_RX_DROP) {
+                                       dev->stats.rx_dropped++;
+                                       d->umaldma_remptr = UMALDMA_NEXTBUF(d,
+                                                       umaldma_remptr);
+                                       goto done;
+                               } else {
+                                       dev->stats.rx_bytes += len;
+                                       dev->stats.rx_packets++;
+                               }
+                       }
+               } else {
+                       /*
+                        * Packet was mangled somehow.  Just drop it and
+                        * put it back on the receive ring.
+                        */
+                       dev->stats.rx_errors++;
+                       umaldma_add_rcvbuffer(sc, d, sb);
+               }
+               work_done++;
+       }
+done:
+       return work_done;
+}
+
+/**
+ * umaldma_tx_process() - Process "completed" transmit buffers.
+ * @sc: softc structure
+ * @d: DMA channel context
+ * @poll: - 1, using polling (for NAPI)
+ *
+ * UMAL DMA functions
+ * Process "completed" transmit buffers on the specified DMA channel.
+ * This is normally called within the interrupt service routine.
+ * Note that this isn't really ideal for priority channels, since
+ * it processes all of the packets on a given channel before
+ * returning.
+ * Return value, nothing
+ */
+static void umaldma_tx_process(struct umal_softc *sc, struct umaldma *d,
+               int poll)
+{
+       struct net_device *dev = sc->umal_dev;
+       int curidx;
+       int hwidx;
+       struct umaldmadscr *dsc;
+       struct sk_buff *sb;
+       unsigned long flags;
+       int packets_handled = 0;
+       unsigned int int_status;
+
+       if (!netif_device_present(dev))
+               return;
+
+       spin_lock_irqsave(&(sc->umal_lock), flags);
+
+       int_status = readl(UMAL_DMAInterrupt);
+
+       if (int_status & INT_TX_BUS_ERR)
+               writel(CLR_TX_BUS_ERR, UMAL_DMATxStatus);
+
+       if (int_status & INT_TX_UNDERRUN)
+               writel(CLR_TX_UNDERRUN, UMAL_DMATxStatus);
+
+       if (int_status & INT_TX_PKT) {
+               hwidx = (struct umaldmadscr *)readl(UMAL_DMATxDescriptor) -
+                       (struct umaldmadscr *)d->umaldma_dscrtable_phys;
+
+               if (d->umaldma_remptr == d->umaldma_addptr)
+                       goto end_unlock;
+
+               for (;;) {
+                       /*
+                        * figure out where we are (as an index) and where
+                        * the hardware is (also as an index)
+                        *
+                        * This could be done faster if (for example) the
+                        * descriptor table was page-aligned and contiguous in
+                        * both virtual and physical memory -- you could then
+                        * just compare the low-order bits of the virtual
+                        * address (sbdma_remptr) and the physical address
+                        * (sbdma_curdscr CSR)
+                        */
+                       curidx = d->umaldma_remptr - d->umaldma_dscrtable;
+
+                       /*
+                        * If they're the same, that means we've processed all
+                        * of the descriptors up to (but not including) the one
+                        * that the hardware is working on right now.
+                        */
+                       if (curidx == hwidx)
+                               break;
+
+                       /* Otherwise, get the packet's sk_buff ptr back */
+                       dsc = &(d->umaldma_dscrtable[curidx]);
+                       sb = d->umaldma_ctxtable[curidx];
+
+                       /* Stats */
+                       dev->stats.tx_bytes += sb->len;
+                       dev->stats.tx_packets++;
+
+                       /* for transmits, we just free buffers.  */
+                       dev_kfree_skb_irq(sb);
+                       d->umaldma_ctxtable[curidx] = NULL;
+                       writel(CLR_TX_PKT, UMAL_DMATxStatus);
+
+                       /* .. and advance to the next buffer.  */
+                       d->umaldma_remptr = UMALDMA_NEXTBUF(d, umaldma_remptr);
+                       packets_handled++;
+               }
+
+               /*
+                * Decide if we should wake up the protocol or not.
+                * Other drivers seem to do this when we reach a low
+                * watermark on the transmit queue.
+                */
+               if (packets_handled)
+                       netif_wake_queue(d->umaldma_eth->umal_dev);
+       }
+
+end_unlock:
+       spin_unlock_irqrestore(&(sc->umal_lock), flags);
+}
+
+/*
+ * UMAL Channel functions
+ */
+
+/**
+ * umal_initctx() - Initialize an Ethernet context structure
+ * @s: umal context structure
+ *
+ * UMAL Channel functions
+ * Initialize an Ethernet context structure - this is called
+ * once per MAC. Memory is allocated here, so don't
+ * call it again from inside the ioctl routines that bring the
+ * interface up/down
+ * Return value, 0
+ */
+static int umal_initctx(struct umal_softc *s)
+{
+       /*
+        * Initialize the DMA channels.
+        * Note: Only do this _once_, as it allocates memory from the kernel!
+        */
+       umaldma_initctx(&(s->umal_txdma), s, DMA_TX, UMAL_MAX_TXDESCR);
+       umaldma_initctx(&(s->umal_rxdma), s, DMA_RX, UMAL_MAX_RXDESCR);
+
+       /* initial state is OFF */
+       s->umal_state = umal_state_off;
+
+       return 0;
+}
+
+/**
+ * umal_uninitctx() - Initialize an Ethernet context structure.
+ * @s: umal context structure
+ *
+ * UMAL Channel functions
+ * Initialize an Ethernet context structure.
+ * Memory is allocated here, so don't call it again from inside the
+ * ioctl routines that bring the interface up/down
+ * Return value, Nothing
+ */
+static void umal_uninitctx(struct umal_softc *s)
+{
+       umaldma_uninitctx(&(s->umal_txdma));
+       umaldma_uninitctx(&(s->umal_rxdma));
+}
+
+/**
+ * umal_set_channel_state() - Set the channel's state ON or OFF
+ * @s: umal context structure
+ * @state: new state
+ *
+ * UMAL Channel functions
+ * Set the channel's state ON or OFF
+ * Return value, old state
+ */
+static enum umal_state umal_set_channel_state(struct umal_softc *s,
+               enum umal_state state)
+{
+       enum umal_state oldstate = s->umal_state;
+
+       /* If same as previous state, return */
+       if (state == oldstate)
+               return oldstate;
+
+       /* If new state is ON, turn channel on */
+       if (state == umal_state_on)
+               umal_channel_start(s);
+       else
+               umal_channel_stop(s);
+
+       /* Return previous state */
+       return oldstate;
+}
+
+/**
+ * umal_set_rx_mode() - Set promiscuous mode and multicast list
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Set promiscuous mode and multicast list
+ * Return value, nothing
+ */
+static void umal_set_rx_mode(struct net_device *dev)
+{
+       unsigned long flags;
+       struct umal_softc *sc = netdev_priv(dev);
+
+       spin_lock_irqsave(&sc->umal_lock, flags);
+       if ((dev->flags ^ sc->umal_devflags) & IFF_PROMISC) {
+               /* Promiscuous changed.  */
+               if (dev->flags & IFF_PROMISC)
+                       umal_promiscuous_mode(sc, 1);
+               else
+                       umal_promiscuous_mode(sc, 0);
+       }
+       spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+       /* Program the multicasts.  Do this every time.  */
+       umal_setmulti(sc);
+}
+
+/**
+ * umal_intr() - Interrupt handler for MAC interrupts
+ * @irq: irq number
+ * @dev_instance: net_device structure
+ *
+ * UMAL functions
+ * Interrupt handler for MAC interrupts
+ * Return value, irq handling result
+ */
+static irqreturn_t umal_intr(int irq, void *dev_instance)
+{
+       struct net_device *dev = (struct net_device *) dev_instance;
+       struct umal_softc *sc = netdev_priv(dev);
+       uint64_t isr;
+       int handled = 0;
+
+       /*
+        * Read the ISR (this clears the bits in the real
+        * register, except for counter addr)
+        */
+       isr = readl(UMAL_DMAInterrupt);
+       if (isr == 0)
+               return IRQ_RETVAL(0);
+
+       if (sc->umal_state != umal_state_on) {
+               umal_clr_intr(dev);
+               return IRQ_RETVAL(0);
+       }
+       handled = 1;
+
+       /* Transmits on channel 0 */
+       if (isr & INT_TX_MASK)
+               umaldma_tx_process(sc, &(sc->umal_txdma), 0);
+       if (isr & INT_RX_MASK)
+               umaldma_rx_process(sc, &(sc->umal_rxdma),
+                                UMAL_MAX_RXDESCR * 2, 0);
+
+       return IRQ_RETVAL(handled);
+}
+
+/**
+ * umal_open() - OPen umal device
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Open umal device
+ * Return value,
+ *     0 if ok
+ *     otherwise error
+ */
+static int umal_open(struct net_device *dev)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+       int err;
+
+       sc->umal_speed = 0;
+       sc->umal_duplex = -1;
+       sc->umal_fc = umal_fc_none;
+       sc->umal_pause = -1;
+       sc->umal_link = 0;
+
+       /* reset mac and interface */
+       writel(UMAL_CFG1_RESET, UMAL_CFG1);     /* reset MAC */
+       writel(0, UMAL_CFG1);                   /* clear the reset bit of MAC */
+       writel(UMAL_IFCTRL_RESET, UMAL_IFCTRL); /* reset the MAC Interface */
+       writel(0, UMAL_DMAIntrMask);
+
+       /* Attach to the PHY */
+       err = umal_mii_probe(dev);
+       if (err)
+               goto out_unregister;
+
+       /* Turn on the channel */
+       phy_start(sc->phy_dev);
+
+       /* config fifo */
+       writel(0x000000ff, UMAL_FIFOCFG0);      /* reset FIFO */
+       writel(0x0fff0fff, UMAL_FIFOCFG1);
+       writel(0x0aaa0555, UMAL_FIFOCFG2);
+       writel(0x02800fff, UMAL_FIFOCFG3);
+       writel(0x00000070, UMAL_FIFOCFG4);
+       writel(0x0007ff8f, UMAL_FIFOCFG5);
+       writel(0x0000ff00, UMAL_FIFOCFG0);
+
+       writel(0x7016, UMAL_CFG2);
+
+       /*
+        * map/route interrupt (clear status first, in case something
+        * weird is pending; we haven't initialized the mac registers
+        * yet)
+        */
+       umal_clr_intr(dev);
+
+       err = request_irq(dev->irq, umal_intr, IRQF_SHARED, dev->name, dev);
+       if (err) {
+               printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name,
+                      dev->irq);
+               goto out_err;
+       }
+
+       umal_set_channel_state(sc, umal_state_on);
+
+       netif_start_queue(dev);
+
+       umal_set_rx_mode(dev);
+
+       return 0;
+
+out_unregister:
+       free_irq(dev->irq, dev);
+out_err:
+       return err;
+}
+
+/**
+ * umal_close() - Close umal device
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Close umal device
+ * Return value, 0 if ok
+ */
+static int umal_close(struct net_device *dev)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+
+       phy_stop(sc->phy_dev);
+
+       umal_set_channel_state(sc, umal_state_off);
+
+       netif_stop_queue(dev);
+
+       phy_disconnect(sc->phy_dev);
+       sc->phy_dev = NULL;
+
+       free_irq(dev->irq, dev);
+
+       umaldma_emptyring(&(sc->umal_rxdma));
+       umaldma_emptyring(&(sc->umal_txdma));
+
+       return 0;
+}
+
+/**
+ * umal_mii_ioctl() - Umal device ioctrl routine
+ * @dev: net_device structure
+ * @rq: interface request structure
+ * @cmd: ioctrl command
+ *
+ * UMAL functions
+ * Umal device ioctrl routine
+ * Return value, ioctrl command result
+ */
+static int umal_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+
+       if (!netif_running(dev) || !sc->phy_dev)
+               return -EINVAL;
+
+       return phy_mii_ioctl(sc->phy_dev, rq, cmd);
+}
+
+/**
+ * umal_start_tx() - Start output on the specified interface.
+ * @skb: sk_buff structure
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Start output on the specified interface.  Basically, we
+ * queue as many buffers as we can until the ring fills up, or
+ * we run off the end of the queue, whichever comes first.
+ * Return value,
+ *     0 if ok
+ *     otherwise error
+ */
+static int umal_start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+       unsigned long flags;
+
+       /* lock eth irq */
+       spin_lock_irqsave(&sc->umal_lock, flags);
+
+       /*
+        * Put the buffer on the transmit ring.  If we
+        * don't have room, stop the queue.
+        */
+       if (umaldma_add_txbuffer(&(sc->umal_txdma), skb)) {
+               /* XXX: save skb that we could not send */
+               netif_stop_queue(dev);
+               spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+               return NETDEV_TX_BUSY;
+       }
+
+       writel(readl(UMAL_CFG1) | UMAL_CFG1_TXENABLE, UMAL_CFG1);
+       writel(readl(UMAL_DMATxCtrl) | UMAL_DMA_Enable, UMAL_DMATxCtrl);
+
+       spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+       return 0;
+}
+
+/**
+ * umal_tx_timeout() - Update statistic structure
+ * @dev: net_device structure
+ *
+ * UMAL functions
+ * Tx timeout, update statistic structure
+ * Return value, nothing
+ */
+static void umal_tx_timeout(struct net_device *dev)
+{
+       struct umal_softc *sc = netdev_priv(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sc->umal_lock, flags);
+
+       dev->trans_start = jiffies; /* prevent tx timeout */
+       dev->stats.tx_errors++;
+
+       spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+       printk(KERN_WARNING "%s: Transmit timed out\n", dev->name);
+}
+
+/**
+ * umal_change_mtu() - Change MTU value
+ * @dev: net_device structure
+ * @new_mtu: new mtu value
+ *
+ * UMAL functions
+ * Change MTU value
+ * Return value, 1 if ok
+ */
+static int umal_change_mtu(struct net_device *dev, int new_mtu)
+{
+       if (new_mtu > ENET_PACKET_SIZE)
+               return -EINVAL;
+
+       dev->mtu = new_mtu;
+
+       pr_info("changing the mtu to %d\n", new_mtu);
+
+       return 0;
+}
+
+/*
+ * UMAL functions
+ */
+static const struct net_device_ops umal_netdev_ops = {
+       .ndo_open               = umal_open,
+       .ndo_stop               = umal_close,
+       .ndo_start_xmit         = umal_start_tx,
+       .ndo_set_multicast_list = umal_set_rx_mode,
+       .ndo_tx_timeout         = umal_tx_timeout,
+       .ndo_do_ioctl           = umal_mii_ioctl,
+       .ndo_change_mtu         = umal_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
+/**
+ * umal_init() - init hardware and hook ourselves into linux.
+ * @pldev: net_device structure
+ * @base: unknown
+ *
+ * UMAL functions
+ * Attach routine - init hardware and hook ourselves into linux
+ * Return value, 0 if ok
+ */
+static int umal_init(struct platform_device *pldev, long long base)
+{
+       struct net_device *dev = dev_get_drvdata(&pldev->dev);
+       int idx = pldev->id;
+       struct umal_softc *sc = netdev_priv(dev);
+       unsigned char *eaddr;
+       int i;
+       int err;
+
+       sc->umal_dev = dev;
+       sc->umal_idx = idx;
+
+       eaddr = sc->umal_hwaddr;
+
+#ifdef CONFIG_CMDLINE_FORCE
+       eaddr[0] = 0x00;
+       eaddr[1] = 0x25;
+       eaddr[2] = 0x9b;
+       eaddr[3] = 0xff;
+       eaddr[4] = 0x00;
+       eaddr[5] = 0x00;
+#endif
+
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = eaddr[i];
+
+       /* Set up Linux device callins */
+       spin_lock_init(&(sc->umal_lock));
+
+       dev->netdev_ops = &umal_netdev_ops;
+       dev->watchdog_timeo = TX_TIMEOUT;
+       dev->irq = IRQ_UMAL;
+
+       sc->mii_bus = mdiobus_alloc();
+       if (sc->mii_bus == NULL) {
+               err = -ENOMEM;
+               goto uninit_ctx;
+       }
+
+       sc->mii_bus->name = umal_mdio_string;
+       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+       sc->mii_bus->priv = sc;
+       sc->mii_bus->read = umal_mii_read;
+       sc->mii_bus->write = umal_mii_write;
+       sc->mii_bus->reset = umal_mii_reset;
+       sc->mii_bus->irq = sc->phy_irq;
+       for (i = 0; i < PHY_MAX_ADDR; ++i)
+               sc->mii_bus->irq[i] = PHY_POLL;
+
+       sc->mii_bus->parent = &pldev->dev;
+
+       /* Probe PHY address */
+       err = mdiobus_register(sc->mii_bus);
+       if (err) {
+               printk(KERN_ERR "%s: unable to register MDIO bus\n",
+                      dev->name);
+               goto free_mdio;
+       }
+       dev_set_drvdata(&pldev->dev, sc->mii_bus);
+
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR "%s.%d: unable to register netdev\n",
+                      umal_string, idx);
+               goto unreg_mdio;
+       }
+
+       pr_info("%s.%d: registered as %s\n", umal_string, idx, dev->name);
+
+       /*
+        * Initialize context (get pointers to registers and stuff), then
+        * allocate the memory for the descriptor tables.
+        */
+       dev->dev.coherent_dma_mask = 0xFFFFFFFF;
+       umal_initctx(sc);
+
+       /*
+        * Display Ethernet address (this is called during the config
+        * process so we need to finish off the config message that
+        * was being displayed)
+        */
+       pr_info("%s: UMAL Ethernet at 0x%08Lx, address: %pM\n",
+              dev->name, base, eaddr);
+
+       return 0;
+unreg_mdio:
+       mdiobus_unregister(sc->mii_bus);
+       dev_set_drvdata(&pldev->dev, NULL);
+free_mdio:
+       mdiobus_free(sc->mii_bus);
+uninit_ctx:
+       umal_uninitctx(sc);
+       return err;
+}
+
+static int umal_probe(struct platform_device *pldev)
+{
+       struct net_device *dev;
+       struct umal_softc *sc;
+       struct resource *res;
+       int err;
+
+       res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+       BUG_ON(!res);
+
+       /* Okay.  Initialize this MAC.  */
+       dev = alloc_etherdev(sizeof(struct umal_softc));
+       if (!dev) {
+               printk(KERN_ERR "%s: unable to allocate etherdev\n",
+                      dev_name(&pldev->dev));
+               err = -ENOMEM;
+               goto out_out;
+       }
+
+       dev_set_drvdata(&pldev->dev, dev);
+       SET_NETDEV_DEV(dev, &pldev->dev);
+
+       sc = netdev_priv(dev);
+
+       err = umal_init(pldev, res->start);
+       if (err)
+               goto out_kfree;
+
+       return 0;
+
+out_kfree:
+       free_netdev(dev);
+
+out_out:
+       return err;
+}
+
+static int __exit umal_remove(struct platform_device *pldev)
+{
+       struct net_device *dev = dev_get_drvdata(&pldev->dev);
+       struct umal_softc *sc = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       umal_uninitctx(sc);
+       mdiobus_unregister(sc->mii_bus);
+       free_netdev(dev);
+
+       return 0;
+}
+
+#if CONFIG_PM
+static void umal_reset(struct net_device *ndev)
+{
+       writel(UMAL_CFG1_RESET, UMAL_CFG1);     /* reset MAC */
+       writel(0, UMAL_CFG1);                   /* clear the reset bit of MAC */
+       writel(UMAL_IFCTRL_RESET, UMAL_IFCTRL); /* reset the MAC Interface */
+       writel(1, UMAL_DMAIntrMask);
+
+       writel(0x000000ff, UMAL_FIFOCFG0);      /* reset FIFO */
+       writel(0x0fff0fff, UMAL_FIFOCFG1);
+       writel(0x0aaa0555, UMAL_FIFOCFG2);
+       writel(0x02800fff, UMAL_FIFOCFG3);
+       writel(0x00000070, UMAL_FIFOCFG4);
+       writel(0x0007ff8f, UMAL_FIFOCFG5);
+       writel(0x0000ff00, UMAL_FIFOCFG0);
+
+       writel(0x7016, UMAL_CFG2);
+}
+
+static void umal_shutdown(struct net_device *ndev)
+{
+       /* XXX: something should be cleared */
+       return;
+}
+
+static int umal_suspend(struct platform_device *pldev, pm_message_t state)
+{
+       struct net_device *ndev = platform_get_drvdata(pldev);
+
+       if (netif_running(ndev)) {
+               netif_device_detach(ndev);
+               umal_shutdown(ndev);
+       }
+       return 0;
+}
+
+static int umal_resume(struct platform_device *pldev)
+{
+       struct net_device *dev = platform_get_drvdata(pldev);
+
+       if (netif_running(dev)) {
+               umal_reset(dev);
+               netif_device_attach(dev);
+       }
+       return 0;
+}
+#else
+static int umal_suspend(struct platform_device *pldev, pm_message_t state) { }
+static int umal_resume(struct platform_device *pldev) { }
+#endif
+static struct platform_driver umal_driver = {
+       .probe = umal_probe,
+       .remove = __exit_p(umal_remove),
+       .driver = {
+               .name = umal_string,
+               .owner  = THIS_MODULE,
+       },
+       .suspend = umal_suspend,
+       .resume  = umal_resume,
+};
+
+static int __init umal_init_module(void)
+{
+       return platform_driver_register(&umal_driver);
+}
+
+static void __exit umal_cleanup_module(void)
+{
+       platform_driver_unregister(&umal_driver);
+}
+
+module_init(umal_init_module);
+module_exit(umal_cleanup_module);
index 05172c39a0ceaab229c4c89411c7fabc7201ce0c..836e13fcb3ecce21f498bbbd822f32362e345ce0 100644 (file)
@@ -561,7 +561,7 @@ static const struct net_device_ops macvlan_netdev_ops = {
        .ndo_change_mtu         = macvlan_change_mtu,
        .ndo_change_rx_flags    = macvlan_change_rx_flags,
        .ndo_set_mac_address    = macvlan_set_mac_address,
-       .ndo_set_multicast_list = macvlan_set_multicast_list,
+       .ndo_set_rx_mode        = macvlan_set_multicast_list,
        .ndo_get_stats64        = macvlan_dev_get_stats64,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_vlan_rx_add_vid    = macvlan_vlan_rx_add_vid,
diff --git a/drivers/net/octeon/Makefile b/drivers/net/octeon/Makefile
deleted file mode 100644 (file)
index 906edec..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_OCTEON_MGMT_ETHERNET)     += octeon_mgmt.o
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
deleted file mode 100644 (file)
index c0f2337..0000000
+++ /dev/null
@@ -1,1923 +0,0 @@
-/*
-
-       drivers/net/pci-skeleton.c
-
-       Maintained by Jeff Garzik <jgarzik@pobox.com>
-
-       Original code came from 8139too.c, which in turns was based
-       originally on Donald Becker's rtl8139.c driver, versions 1.11
-       and older.  This driver was originally based on rtl8139.c
-       version 1.07.  Header of rtl8139.c version 1.11:
-
-       -----<snip>-----
-
-               Written 1997-2000 by Donald Becker.
-               This software may be used and distributed according to the
-               terms of the GNU General Public License (GPL), incorporated
-               herein by reference.  Drivers based on or derived from this
-               code fall under the GPL and must retain the authorship,
-               copyright and license notice.  This file is not a complete
-               program and may only be used when the entire operating
-               system is licensed under the GPL.
-
-               This driver is for boards based on the RTL8129 and RTL8139
-               PCI ethernet chips.
-
-               The author may be reached as becker@scyld.com, or C/O Scyld
-               Computing Corporation 410 Severn Ave., Suite 210 Annapolis
-               MD 21403
-
-               Support and updates available at
-               http://www.scyld.com/network/rtl8139.html
-
-               Twister-tuning table provided by Kinston
-               <shangh@realtek.com.tw>.
-
-       -----<snip>-----
-
-       This software may be used and distributed according to the terms
-       of the GNU General Public License, incorporated herein by reference.
-
-
------------------------------------------------------------------------------
-
-                               Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the RealTek RTL8139 series, the RealTek
-Fast Ethernet controllers for PCI and CardBus.  This chip is used on many
-low-end boards, sometimes with its markings changed.
-
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board.  The system BIOS will assign the
-PCI INTA signal to a (preferably otherwise unused) system IRQ line.
-
-III. Driver operation
-
-IIIa. Rx Ring buffers
-
-The receive unit uses a single linear ring buffer rather than the more
-common (and more efficient) descriptor-based architecture.  Incoming frames
-are sequentially stored into the Rx region, and the host copies them into
-skbuffs.
-
-Comment: While it is theoretically possible to process many frames in place,
-any delay in Rx processing would cause us to drop frames.  More importantly,
-the Linux protocol stack is not designed to operate in this manner.
-
-IIIb. Tx operation
-
-The RTL8139 uses a fixed set of four Tx descriptors in register space.
-In a stunningly bad design choice, Tx frames must be 32 bit aligned.  Linux
-aligns the IP header on word boundaries, and 14 byte ethernet header means
-that almost all frames will need to be copied to an alignment buffer.
-
-IVb. References
-
-http://www.realtek.com.tw/
-http://www.scyld.com/expert/NWay.html
-
-IVc. Errata
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/crc32.h>
-#include <linux/io.h>
-
-#define NETDRV_VERSION         "1.0.1"
-#define MODNAME                        "netdrv"
-#define NETDRV_DRIVER_LOAD_MSG "MyVendor Fast Ethernet driver " NETDRV_VERSION " loaded"
-
-static char version[] __devinitdata =
-       KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n"
-       "  Support available from http://foo.com/bar/baz.html\n";
-
-/* define to 1 to enable PIO instead of MMIO */
-#undef USE_IO_OPS
-
-/* define to 1 to enable copious debugging info */
-#undef NETDRV_DEBUG
-
-/* define to 1 to disable lightweight runtime debugging checks */
-#undef NETDRV_NDEBUG
-
-
-#ifdef NETDRV_DEBUG
-/* note: prints function name for you */
-#define DPRINTK(fmt, args...)                                  \
-       printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-#define DPRINTK(fmt, args...)                          \
-do {                                                   \
-       if (0)                                          \
-               printk(KERN_DEBUG fmt, ##args);         \
-} while (0)
-#endif
-
-#ifdef NETDRV_NDEBUG
-#define assert(expr) do {} while (0)
-#else
-#define assert(expr)                                           \
-       if (!(expr)) {                                          \
-               printk("Assertion failed! %s,%s,%s,line=%d\n",  \
-                      #expr, __FILE__, __func__, __LINE__);    \
-       }
-#endif
-
-
-/* A few user-configurable values. */
-/* media options */
-static int media[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
-
-/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
-   The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
-static int multicast_filter_limit = 32;
-
-/* Size of the in-memory receive ring. */
-#define RX_BUF_LEN_IDX 2       /* 0==8K, 1==16K, 2==32K, 3==64K */
-#define RX_BUF_LEN     (8192 << RX_BUF_LEN_IDX)
-#define RX_BUF_PAD     16
-#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
-#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
-
-/* Number of Tx descriptor registers. */
-#define NUM_TX_DESC    4
-
-/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/
-#define MAX_ETH_FRAME_SIZE     1536
-
-/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
-#define TX_BUF_SIZE    MAX_ETH_FRAME_SIZE
-#define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC)
-
-/* PCI Tuning Parameters
-   Threshold is bytes transferred to chip before transmission starts. */
-#define TX_FIFO_THRESH 256     /* In bytes, rounded down to 32 byte units. */
-
-/* The following settings are log_2(bytes)-4:
-   0==16 bytes 1==32 2==64 3==128 4==256 5==512 6==1024 7==end of packet.
-*/
-#define RX_FIFO_THRESH 6       /* Rx buffer level before first PCI xfer.  */
-#define RX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
-#define TX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
-
-
-/* Operational parameters that usually are not changed. */
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT     (6 * HZ)
-
-enum {
-       HAS_CHIP_XCVR = 0x020000,
-       HAS_LNK_CHNG = 0x040000,
-};
-
-#define NETDRV_MIN_IO_SIZE 0x80
-#define RTL8139B_IO_SIZE 256
-
-#define NETDRV_CAPS    (HAS_CHIP_XCVR | HAS_LNK_CHNG)
-
-typedef enum {
-       RTL8139 = 0,
-       NETDRV_CB,
-       SMC1211TX,
-       /*MPX5030,*/
-       DELTA8139,
-       ADDTRON8139,
-} board_t;
-
-
-/* indexed by board_t, above */
-static struct {
-       const char *name;
-} board_info[] __devinitdata = {
-       { "RealTek RTL8139 Fast Ethernet" },
-       { "RealTek RTL8139B PCI/CardBus" },
-       { "SMC1211TX EZCard 10/100 (RealTek RTL8139)" },
-/*     { MPX5030, "Accton MPX5030 (RealTek RTL8139)" },*/
-       { "Delta Electronics 8139 10/100BaseTX" },
-       { "Addtron Technology 8139 10/100BaseTX" },
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(netdrv_pci_tbl) = {
-       {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-       {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NETDRV_CB },
-       {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },
-/*     {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/
-       {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 },
-       {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
-       {0,}
-};
-MODULE_DEVICE_TABLE(pci, netdrv_pci_tbl);
-
-
-/* The rest of these values should never change. */
-
-/* Symbolic offsets to registers. */
-enum NETDRV_registers {
-       MAC0 = 0,               /* Ethernet hardware address. */
-       MAR0 = 8,               /* Multicast filter. */
-       TxStatus0 = 0x10,       /* Transmit status (Four 32bit registers). */
-       TxAddr0 = 0x20,         /* Tx descriptors (also four 32bit). */
-       RxBuf = 0x30,
-       RxEarlyCnt = 0x34,
-       RxEarlyStatus = 0x36,
-       ChipCmd = 0x37,
-       RxBufPtr = 0x38,
-       RxBufAddr = 0x3A,
-       IntrMask = 0x3C,
-       IntrStatus = 0x3E,
-       TxConfig = 0x40,
-       ChipVersion = 0x43,
-       RxConfig = 0x44,
-       Timer = 0x48,           /* A general-purpose counter. */
-       RxMissed = 0x4C,        /* 24 bits valid, write clears. */
-       Cfg9346 = 0x50,
-       Config0 = 0x51,
-       Config1 = 0x52,
-       FlashReg = 0x54,
-       MediaStatus = 0x58,
-       Config3 = 0x59,
-       Config4 = 0x5A,         /* absent on RTL-8139A */
-       HltClk = 0x5B,
-       MultiIntr = 0x5C,
-       TxSummary = 0x60,
-       BasicModeCtrl = 0x62,
-       BasicModeStatus = 0x64,
-       NWayAdvert = 0x66,
-       NWayLPAR = 0x68,
-       NWayExpansion = 0x6A,
-       /* Undocumented registers, but required for proper operation. */
-       FIFOTMS = 0x70,         /* FIFO Control and test. */
-       CSCR = 0x74,            /* Chip Status and Configuration Register. */
-       PARA78 = 0x78,
-       PARA7c = 0x7c,          /* Magic transceiver parameter register. */
-       Config5 = 0xD8,         /* absent on RTL-8139A */
-};
-
-enum ClearBitMasks {
-       MultiIntrClear = 0xF000,
-       ChipCmdClear = 0xE2,
-       Config1Clear = (1 << 7) | (1 << 6) | (1 << 3) | (1 << 2) | (1 << 1),
-};
-
-enum ChipCmdBits {
-       CmdReset = 0x10,
-       CmdRxEnb = 0x08,
-       CmdTxEnb = 0x04,
-       RxBufEmpty = 0x01,
-};
-
-/* Interrupt register bits, using my own meaningful names. */
-enum IntrStatusBits {
-       PCIErr = 0x8000,
-       PCSTimeout = 0x4000,
-       RxFIFOOver = 0x40,
-       RxUnderrun = 0x20,
-       RxOverflow = 0x10,
-       TxErr = 0x08,
-       TxOK = 0x04,
-       RxErr = 0x02,
-       RxOK = 0x01,
-};
-enum TxStatusBits {
-       TxHostOwns = 0x2000,
-       TxUnderrun = 0x4000,
-       TxStatOK = 0x8000,
-       TxOutOfWindow = 0x20000000,
-       TxAborted = 0x40000000,
-       TxCarrierLost = 0x80000000,
-};
-enum RxStatusBits {
-       RxMulticast = 0x8000,
-       RxPhysical = 0x4000,
-       RxBroadcast = 0x2000,
-       RxBadSymbol = 0x0020,
-       RxRunt = 0x0010,
-       RxTooLong = 0x0008,
-       RxCRCErr = 0x0004,
-       RxBadAlign = 0x0002,
-       RxStatusOK = 0x0001,
-};
-
-/* Bits in RxConfig. */
-enum rx_mode_bits {
-       AcceptErr = 0x20,
-       AcceptRunt = 0x10,
-       AcceptBroadcast = 0x08,
-       AcceptMulticast = 0x04,
-       AcceptMyPhys = 0x02,
-       AcceptAllPhys = 0x01,
-};
-
-/* Bits in TxConfig. */
-enum tx_config_bits {
-       TxIFG1 = (1 << 25),     /* Interframe Gap Time */
-       TxIFG0 = (1 << 24),     /* Enabling these bits violates IEEE 802.3 */
-       TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
-       TxCRC = (1 << 16),      /* DISABLE appending CRC to end of Tx packets */
-       TxClearAbt = (1 << 0),  /* Clear abort (WO) */
-       TxDMAShift = 8,         /* DMA burst value(0-7) is shift this many bits */
-
-       TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
-};
-
-/* Bits in Config1 */
-enum Config1Bits {
-       Cfg1_PM_Enable = 0x01,
-       Cfg1_VPD_Enable = 0x02,
-       Cfg1_PIO = 0x04,
-       Cfg1_MMIO = 0x08,
-       Cfg1_LWAKE = 0x10,
-       Cfg1_Driver_Load = 0x20,
-       Cfg1_LED0 = 0x40,
-       Cfg1_LED1 = 0x80,
-};
-
-enum RxConfigBits {
-       /* Early Rx threshold, none or X/16 */
-       RxCfgEarlyRxNone = 0,
-       RxCfgEarlyRxShift = 24,
-
-       /* rx fifo threshold */
-       RxCfgFIFOShift = 13,
-       RxCfgFIFONone = (7 << RxCfgFIFOShift),
-
-       /* Max DMA burst */
-       RxCfgDMAShift = 8,
-       RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
-
-       /* rx ring buffer length */
-       RxCfgRcv8K = 0,
-       RxCfgRcv16K = (1 << 11),
-       RxCfgRcv32K = (1 << 12),
-       RxCfgRcv64K = (1 << 11) | (1 << 12),
-
-       /* Disable packet wrap at end of Rx buffer */
-       RxNoWrap = (1 << 7),
-};
-
-
-/* Twister tuning parameters from RealTek.
-   Completely undocumented, but required to tune bad links. */
-enum CSCRBits {
-       CSCR_LinkOKBit = 0x0400,
-       CSCR_LinkChangeBit = 0x0800,
-       CSCR_LinkStatusBits = 0x0f000,
-       CSCR_LinkDownOffCmd = 0x003c0,
-       CSCR_LinkDownCmd = 0x0f3c0,
-};
-
-
-enum Cfg9346Bits {
-       Cfg9346_Lock = 0x00,
-       Cfg9346_Unlock = 0xC0,
-};
-
-
-#define PARA78_default 0x78fa8388
-#define PARA7c_default 0xcb38de43      /* param[0][3] */
-#define PARA7c_xxx             0xcb38de43
-static const unsigned long param[4][4] = {
-       {0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43},
-       {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
-       {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
-       {0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
-};
-
-struct ring_info {
-       struct sk_buff *skb;
-       dma_addr_t mapping;
-};
-
-
-typedef enum {
-       CH_8139 = 0,
-       CH_8139_K,
-       CH_8139A,
-       CH_8139B,
-       CH_8130,
-       CH_8139C,
-} chip_t;
-
-
-/* directly indexed by chip_t, above */
-static const struct {
-       const char *name;
-       u8 version; /* from RTL8139C docs */
-       u32 RxConfigMask; /* should clear the bits supported by this chip */
-} rtl_chip_info[] = {
-       { "RTL-8139",
-         0x40,
-         0xf0fe0040, /* XXX copied from RTL8139A, verify */
-       },
-
-       { "RTL-8139 rev K",
-         0x60,
-         0xf0fe0040,
-       },
-
-       { "RTL-8139A",
-         0x70,
-         0xf0fe0040,
-       },
-
-       { "RTL-8139B",
-         0x78,
-         0xf0fc0040
-       },
-
-       { "RTL-8130",
-         0x7C,
-         0xf0fe0040, /* XXX copied from RTL8139A, verify */
-       },
-
-       { "RTL-8139C",
-         0x74,
-         0xf0fc0040, /* XXX copied from RTL8139B, verify */
-       },
-
-};
-
-
-struct netdrv_private {
-       board_t board;
-       void *mmio_addr;
-       int drv_flags;
-       struct pci_dev *pci_dev;
-       struct timer_list timer;        /* Media selection timer. */
-       unsigned char *rx_ring;
-       unsigned int cur_rx;    /* Index into the Rx buffer of next Rx pkt. */
-       unsigned int tx_flag;
-       atomic_t cur_tx;
-       atomic_t dirty_tx;
-       /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-       struct ring_info tx_info[NUM_TX_DESC];
-       unsigned char *tx_buf[NUM_TX_DESC];     /* Tx bounce buffers */
-       unsigned char *tx_bufs; /* Tx bounce buffer region. */
-       dma_addr_t rx_ring_dma;
-       dma_addr_t tx_bufs_dma;
-       char phys[4];           /* MII device addresses. */
-       char twistie, twist_row, twist_col;     /* Twister tune state. */
-       unsigned int full_duplex:1;     /* Full-duplex operation requested. */
-       unsigned int duplex_lock:1;
-       unsigned int default_port:4;    /* Last dev->if_port value. */
-       unsigned int media2:4;  /* Secondary monitored media port. */
-       unsigned int medialock:1;       /* Don't sense media type. */
-       unsigned int mediasense:1;      /* Media sensing in progress. */
-       spinlock_t lock;
-       chip_t chipset;
-};
-
-MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
-MODULE_DESCRIPTION("Skeleton for a PCI Fast Ethernet driver");
-MODULE_LICENSE("GPL");
-module_param(multicast_filter_limit, int, 0);
-module_param(max_interrupt_work, int, 0);
-module_param_array(media, int, NULL, 0);
-MODULE_PARM_DESC(multicast_filter_limit,
-                MODNAME " maximum number of filtered multicast addresses");
-MODULE_PARM_DESC(max_interrupt_work,
-                MODNAME " maximum events handled per interrupt");
-MODULE_PARM_DESC(media,
-                MODNAME " Bits 0-3: media type, bit 17: full duplex");
-
-static int read_eeprom(void *ioaddr, int location, int addr_len);
-static int netdrv_open(struct net_device *dev);
-static int mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location,
-                      int val);
-static void netdrv_timer(unsigned long data);
-static void netdrv_tx_timeout(struct net_device *dev);
-static void netdrv_init_ring(struct net_device *dev);
-static int netdrv_start_xmit(struct sk_buff *skb,
-                            struct net_device *dev);
-static irqreturn_t netdrv_interrupt(int irq, void *dev_instance);
-static int netdrv_close(struct net_device *dev);
-static int netdrv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void netdrv_set_rx_mode(struct net_device *dev);
-static void netdrv_hw_start(struct net_device *dev);
-
-
-#ifdef USE_IO_OPS
-
-#define NETDRV_R8(reg)         inb(((unsigned long)ioaddr) + (reg))
-#define NETDRV_R16(reg)                inw(((unsigned long)ioaddr) + (reg))
-#define NETDRV_R32(reg)                ((unsigned long)inl(((unsigned long)ioaddr) + (reg)))
-#define NETDRV_W8(reg, val8)   outb((val8), ((unsigned long)ioaddr) + (reg))
-#define NETDRV_W16(reg, val16) outw((val16), ((unsigned long)ioaddr) + (reg))
-#define NETDRV_W32(reg, val32) outl((val32), ((unsigned long)ioaddr) + (reg))
-#define NETDRV_W8_F            NETDRV_W8
-#define NETDRV_W16_F           NETDRV_W16
-#define NETDRV_W32_F           NETDRV_W32
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb(addr) inb((unsigned long)(addr))
-#define readw(addr) inw((unsigned long)(addr))
-#define readl(addr) inl((unsigned long)(addr))
-#define writeb(val, addr) outb((val), (unsigned long)(addr))
-#define writew(val, addr) outw((val), (unsigned long)(addr))
-#define writel(val, addr) outl((val), (unsigned long)(addr))
-
-#else
-
-/* write MMIO register, with flush */
-/* Flush avoids rtl8139 bug w/ posted MMIO writes */
-#define NETDRV_W8_F(reg, val8)                 \
-do {                                           \
-       writeb((val8), ioaddr + (reg));         \
-       readb(ioaddr + (reg));                  \
-} while (0)
-#define NETDRV_W16_F(reg, val16)               \
-do {                                           \
-       writew((val16), ioaddr + (reg));        \
-       readw(ioaddr + (reg));                  \
-} while (0)
-#define NETDRV_W32_F(reg, val32)               \
-do {                                           \
-       writel((val32), ioaddr + (reg));        \
-       readl(ioaddr + (reg));                  \
-} while (0)
-
-
-#ifdef MMIO_FLUSH_AUDIT_COMPLETE
-
-/* write MMIO register */
-#define NETDRV_W8(reg, val8)   writeb((val8), ioaddr + (reg))
-#define NETDRV_W16(reg, val16) writew((val16), ioaddr + (reg))
-#define NETDRV_W32(reg, val32) writel((val32), ioaddr + (reg))
-
-#else
-
-/* write MMIO register, then flush */
-#define NETDRV_W8              NETDRV_W8_F
-#define NETDRV_W16             NETDRV_W16_F
-#define NETDRV_W32             NETDRV_W32_F
-
-#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
-
-/* read MMIO register */
-#define NETDRV_R8(reg)         readb(ioaddr + (reg))
-#define NETDRV_R16(reg)                readw(ioaddr + (reg))
-#define NETDRV_R32(reg)                ((unsigned long) readl(ioaddr + (reg)))
-
-#endif /* USE_IO_OPS */
-
-
-static const u16 netdrv_intr_mask =
-       PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
-       TxErr | TxOK | RxErr | RxOK;
-
-static const unsigned int netdrv_rx_config =
-       RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
-       (RX_FIFO_THRESH << RxCfgFIFOShift) |
-       (RX_DMA_BURST << RxCfgDMAShift);
-
-
-static int __devinit netdrv_init_board(struct pci_dev *pdev,
-                                      struct net_device **dev_out,
-                                      void **ioaddr_out)
-{
-       void *ioaddr = NULL;
-       struct net_device *dev;
-       struct netdrv_private *tp;
-       int rc, i;
-       u32 pio_start, pio_end, pio_flags, pio_len;
-       unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
-       u32 tmp;
-
-       DPRINTK("ENTER\n");
-
-       assert(pdev != NULL);
-       assert(ioaddr_out != NULL);
-
-       *ioaddr_out = NULL;
-       *dev_out = NULL;
-
-       /* dev zeroed in alloc_etherdev */
-       dev = alloc_etherdev(sizeof(*tp));
-       if (dev == NULL) {
-               dev_err(&pdev->dev, "unable to alloc new ethernet\n");
-               DPRINTK("EXIT, returning -ENOMEM\n");
-               return -ENOMEM;
-       }
-       SET_NETDEV_DEV(dev, &pdev->dev);
-       tp = netdev_priv(dev);
-
-       /* enable device(incl. PCI PM wakeup), and bus-mastering */
-       rc = pci_enable_device(pdev);
-       if (rc)
-               goto err_out;
-
-       pio_start = pci_resource_start(pdev, 0);
-       pio_end = pci_resource_end(pdev, 0);
-       pio_flags = pci_resource_flags(pdev, 0);
-       pio_len = pci_resource_len(pdev, 0);
-
-       mmio_start = pci_resource_start(pdev, 1);
-       mmio_end = pci_resource_end(pdev, 1);
-       mmio_flags = pci_resource_flags(pdev, 1);
-       mmio_len = pci_resource_len(pdev, 1);
-
-       /* set this immediately, we need to know before
-        * we talk to the chip directly */
-       DPRINTK("PIO region size == %#02X\n", pio_len);
-       DPRINTK("MMIO region size == %#02lX\n", mmio_len);
-
-       /* make sure PCI base addr 0 is PIO */
-       if (!(pio_flags & IORESOURCE_IO)) {
-               dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-
-       /* make sure PCI base addr 1 is MMIO */
-       if (!(mmio_flags & IORESOURCE_MEM)) {
-               dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-
-       /* check for weird/broken PCI region reporting */
-       if ((pio_len < NETDRV_MIN_IO_SIZE) ||
-           (mmio_len < NETDRV_MIN_IO_SIZE)) {
-               dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-
-       rc = pci_request_regions(pdev, MODNAME);
-       if (rc)
-               goto err_out;
-
-       pci_set_master(pdev);
-
-#ifdef USE_IO_OPS
-       ioaddr = (void *)pio_start;
-#else
-       /* ioremap MMIO region */
-       ioaddr = ioremap(mmio_start, mmio_len);
-       if (ioaddr == NULL) {
-               dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
-               rc = -EIO;
-               goto err_out_free_res;
-       }
-#endif /* USE_IO_OPS */
-
-       /* Soft reset the chip. */
-       NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) | CmdReset);
-
-       /* Check that the chip has finished the reset. */
-       for (i = 1000; i > 0; i--)
-               if ((NETDRV_R8(ChipCmd) & CmdReset) == 0)
-                       break;
-               else
-                       udelay(10);
-
-       /* Bring the chip out of low-power mode. */
-       /* <insert device-specific code here> */
-
-#ifndef USE_IO_OPS
-       /* sanity checks -- ensure PIO and MMIO registers agree */
-       assert(inb(pio_start+Config0) == readb(ioaddr+Config0));
-       assert(inb(pio_start+Config1) == readb(ioaddr+Config1));
-       assert(inb(pio_start+TxConfig) == readb(ioaddr+TxConfig));
-       assert(inb(pio_start+RxConfig) == readb(ioaddr+RxConfig));
-#endif /* !USE_IO_OPS */
-
-       /* identify chip attached to board */
-       tmp = NETDRV_R8(ChipVersion);
-       for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--)
-               if (tmp == rtl_chip_info[i].version) {
-                       tp->chipset = i;
-                       goto match;
-               }
-
-       /* if unknown chip, assume array element #0, original RTL-8139 in this case */
-       dev_printk(KERN_DEBUG, &pdev->dev,
-                  "unknown chip version, assuming RTL-8139\n");
-       dev_printk(KERN_DEBUG, &pdev->dev, "TxConfig = %#lx\n",
-                  NETDRV_R32(TxConfig));
-       tp->chipset = 0;
-
-match:
-       DPRINTK("chipset id(%d) == index %d, '%s'\n",
-               tmp, tp->chipset, rtl_chip_info[tp->chipset].name);
-
-       rc = register_netdev(dev);
-       if (rc)
-               goto err_out_unmap;
-
-       DPRINTK("EXIT, returning 0\n");
-       *ioaddr_out = ioaddr;
-       *dev_out = dev;
-       return 0;
-
-err_out_unmap:
-#ifndef USE_IO_OPS
-       iounmap(ioaddr);
-err_out_free_res:
-#endif
-       pci_release_regions(pdev);
-err_out:
-       free_netdev(dev);
-       DPRINTK("EXIT, returning %d\n", rc);
-       return rc;
-}
-
-static const struct net_device_ops netdrv_netdev_ops = {
-       .ndo_open               = netdrv_open,
-       .ndo_stop               = netdrv_close,
-       .ndo_start_xmit         = netdrv_start_xmit,
-       .ndo_set_multicast_list = netdrv_set_rx_mode,
-       .ndo_do_ioctl           = netdrv_ioctl,
-       .ndo_tx_timeout         = netdrv_tx_timeout,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
-};
-
-static int __devinit netdrv_init_one(struct pci_dev *pdev,
-                                    const struct pci_device_id *ent)
-{
-       struct net_device *dev = NULL;
-       struct netdrv_private *tp;
-       int i, addr_len, option;
-       void *ioaddr = NULL;
-       static int board_idx = -1;
-
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
-       static int printed_version;
-       if (!printed_version++)
-               printk(version);
-#endif
-
-       DPRINTK("ENTER\n");
-
-       assert(pdev != NULL);
-       assert(ent != NULL);
-
-       board_idx++;
-
-       i = netdrv_init_board(pdev, &dev, &ioaddr);
-       if (i < 0) {
-               DPRINTK("EXIT, returning %d\n", i);
-               return i;
-       }
-
-       tp = netdev_priv(dev);
-
-       assert(ioaddr != NULL);
-       assert(dev != NULL);
-       assert(tp != NULL);
-
-       addr_len = read_eeprom(ioaddr, 0, 8) == 0x8129 ? 8 : 6;
-       for (i = 0; i < 3; i++)
-               ((u16 *)(dev->dev_addr))[i] =
-                       le16_to_cpu(read_eeprom(ioaddr, i + 7, addr_len));
-
-       dev->netdev_ops = &netdrv_netdev_ops;
-       dev->watchdog_timeo = TX_TIMEOUT;
-
-       dev->irq = pdev->irq;
-       dev->base_addr = (unsigned long) ioaddr;
-
-       /* netdev_priv()/tp zeroed and aligned in alloc_etherdev */
-       tp = netdev_priv(dev);
-
-       /* note: tp->chipset set in netdrv_init_board */
-       tp->drv_flags = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-               PCI_COMMAND_MASTER | NETDRV_CAPS;
-       tp->pci_dev = pdev;
-       tp->board = ent->driver_data;
-       tp->mmio_addr = ioaddr;
-       spin_lock_init(&tp->lock);
-
-       pci_set_drvdata(pdev, dev);
-
-       tp->phys[0] = 32;
-
-       netdev_info(dev, "%s at %#lx, %pM IRQ %d\n",
-                   board_info[ent->driver_data].name,
-                   dev->base_addr, dev->dev_addr, dev->irq);
-
-       netdev_printk(KERN_DEBUG, dev, "Identified 8139 chip type '%s'\n",
-                     rtl_chip_info[tp->chipset].name);
-
-       /* Put the chip into low-power mode. */
-       NETDRV_W8_F(Cfg9346, Cfg9346_Unlock);
-
-       /* The lower four bits are the media type. */
-       option = (board_idx > 7) ? 0 : media[board_idx];
-       if (option > 0) {
-               tp->full_duplex = (option & 0x200) ? 1 : 0;
-               tp->default_port = option & 15;
-               if (tp->default_port)
-                       tp->medialock = 1;
-       }
-
-       if (tp->full_duplex) {
-               netdev_info(dev, "Media type forced to Full Duplex\n");
-               mdio_write(dev, tp->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
-               tp->duplex_lock = 1;
-       }
-
-       DPRINTK("EXIT - returning 0\n");
-       return 0;
-}
-
-
-static void __devexit netdrv_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct netdrv_private *np;
-
-       DPRINTK("ENTER\n");
-
-       assert(dev != NULL);
-
-       np = netdev_priv(dev);
-       assert(np != NULL);
-
-       unregister_netdev(dev);
-
-#ifndef USE_IO_OPS
-       iounmap(np->mmio_addr);
-#endif /* !USE_IO_OPS */
-
-       pci_release_regions(pdev);
-
-       free_netdev(dev);
-
-       pci_set_drvdata(pdev, NULL);
-
-       pci_disable_device(pdev);
-
-       DPRINTK("EXIT\n");
-}
-
-
-/* Serial EEPROM section. */
-
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK   0x04    /* EEPROM shift clock. */
-#define EE_CS          0x08    /* EEPROM chip select. */
-#define EE_DATA_WRITE  0x02    /* EEPROM chip data in. */
-#define EE_WRITE_0     0x00
-#define EE_WRITE_1     0x02
-#define EE_DATA_READ   0x01    /* EEPROM chip data out. */
-#define EE_ENB         (0x80 | EE_CS)
-
-/* Delay between EEPROM clock transitions.
-   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
-*/
-
-#define eeprom_delay() readl(ee_addr)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD   (5)
-#define EE_READ_CMD    (6)
-#define EE_ERASE_CMD   (7)
-
-static int __devinit read_eeprom(void *ioaddr, int location, int addr_len)
-{
-       int i;
-       unsigned retval = 0;
-       void *ee_addr = ioaddr + Cfg9346;
-       int read_cmd = location | (EE_READ_CMD << addr_len);
-
-       DPRINTK("ENTER\n");
-
-       writeb(EE_ENB & ~EE_CS, ee_addr);
-       writeb(EE_ENB, ee_addr);
-       eeprom_delay();
-
-       /* Shift the read command bits out. */
-       for (i = 4 + addr_len; i >= 0; i--) {
-               int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-               writeb(EE_ENB | dataval, ee_addr);
-               eeprom_delay();
-               writeb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
-               eeprom_delay();
-       }
-       writeb(EE_ENB, ee_addr);
-       eeprom_delay();
-
-       for (i = 16; i > 0; i--) {
-               writeb(EE_ENB | EE_SHIFT_CLK, ee_addr);
-               eeprom_delay();
-               retval =
-                       (retval << 1) | ((readb(ee_addr) & EE_DATA_READ) ? 1 :
-                                       0);
-               writeb(EE_ENB, ee_addr);
-               eeprom_delay();
-       }
-
-       /* Terminate the EEPROM access. */
-       writeb(~EE_CS, ee_addr);
-       eeprom_delay();
-
-       DPRINTK("EXIT - returning %d\n", retval);
-       return retval;
-}
-
-/* MII serial management: mostly bogus for now. */
-/* Read and write the MII management registers using software-generated
-   serial MDIO protocol.
-   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues. */
-#define MDIO_DIR       0x80
-#define MDIO_DATA_OUT  0x04
-#define MDIO_DATA_IN   0x02
-#define MDIO_CLK       0x01
-#define MDIO_WRITE0    (MDIO_DIR)
-#define MDIO_WRITE1    (MDIO_DIR | MDIO_DATA_OUT)
-
-#define mdio_delay()   readb(mdio_addr)
-
-
-static char mii_2_8139_map[8] = {
-       BasicModeCtrl,
-       BasicModeStatus,
-       0,
-       0,
-       NWayAdvert,
-       NWayLPAR,
-       NWayExpansion,
-       0
-};
-
-
-/* Syncronize the MII management interface by shifting 32 one bits out. */
-static void mdio_sync(void *mdio_addr)
-{
-       int i;
-
-       DPRINTK("ENTER\n");
-
-       for (i = 32; i >= 0; i--) {
-               writeb(MDIO_WRITE1, mdio_addr);
-               mdio_delay();
-               writeb(MDIO_WRITE1 | MDIO_CLK, mdio_addr);
-               mdio_delay();
-       }
-
-       DPRINTK("EXIT\n");
-}
-
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *mdio_addr = tp->mmio_addr + Config4;
-       int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
-       int retval = 0;
-       int i;
-
-       DPRINTK("ENTER\n");
-
-       if (phy_id > 31) {      /* Really a 8139.  Use internal registers. */
-               DPRINTK("EXIT after directly using 8139 internal regs\n");
-               return location < 8 && mii_2_8139_map[location] ?
-                       readw(tp->mmio_addr + mii_2_8139_map[location]) : 0;
-       }
-       mdio_sync(mdio_addr);
-       /* Shift the read command bits out. */
-       for (i = 15; i >= 0; i--) {
-               int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
-
-               writeb(MDIO_DIR | dataval, mdio_addr);
-               mdio_delay();
-               writeb(MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
-               mdio_delay();
-       }
-
-       /* Read the two transition, 16 data, and wire-idle bits. */
-       for (i = 19; i > 0; i--) {
-               writeb(0, mdio_addr);
-               mdio_delay();
-               retval = ((retval << 1) | ((readb(mdio_addr) & MDIO_DATA_IN))
-                         ? 1 : 0);
-               writeb(MDIO_CLK, mdio_addr);
-               mdio_delay();
-       }
-
-       DPRINTK("EXIT, returning %d\n", (retval >> 1) & 0xffff);
-       return (retval >> 1) & 0xffff;
-}
-
-
-static void mdio_write(struct net_device *dev, int phy_id, int location,
-                      int value)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *mdio_addr = tp->mmio_addr + Config4;
-       int mii_cmd =
-               (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
-       int i;
-
-       DPRINTK("ENTER\n");
-
-       if (phy_id > 31) {      /* Really a 8139.  Use internal registers. */
-               if (location < 8 && mii_2_8139_map[location]) {
-                       writew(value,
-                              tp->mmio_addr + mii_2_8139_map[location]);
-                       readw(tp->mmio_addr + mii_2_8139_map[location]);
-               }
-               DPRINTK("EXIT after directly using 8139 internal regs\n");
-               return;
-       }
-       mdio_sync(mdio_addr);
-
-       /* Shift the command bits out. */
-       for (i = 31; i >= 0; i--) {
-               int dataval =
-                       (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-               writeb(dataval, mdio_addr);
-               mdio_delay();
-               writeb(dataval | MDIO_CLK, mdio_addr);
-               mdio_delay();
-       }
-
-       /* Clear out extra bits. */
-       for (i = 2; i > 0; i--) {
-               writeb(0, mdio_addr);
-               mdio_delay();
-               writeb(MDIO_CLK, mdio_addr);
-               mdio_delay();
-       }
-
-       DPRINTK("EXIT\n");
-}
-
-
-static int netdrv_open(struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       int retval;
-       void *ioaddr = tp->mmio_addr;
-
-       DPRINTK("ENTER\n");
-
-       retval = request_irq(dev->irq, netdrv_interrupt, IRQF_SHARED, dev->name, dev);
-       if (retval) {
-               DPRINTK("EXIT, returning %d\n", retval);
-               return retval;
-       }
-
-       tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
-                                          &tp->tx_bufs_dma);
-       tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
-                                          &tp->rx_ring_dma);
-       if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
-               free_irq(dev->irq, dev);
-
-               if (tp->tx_bufs)
-                       pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
-                                           tp->tx_bufs, tp->tx_bufs_dma);
-               if (tp->rx_ring)
-                       pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
-                                           tp->rx_ring, tp->rx_ring_dma);
-
-               DPRINTK("EXIT, returning -ENOMEM\n");
-               return -ENOMEM;
-
-       }
-
-       tp->full_duplex = tp->duplex_lock;
-       tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
-
-       netdrv_init_ring(dev);
-       netdrv_hw_start(dev);
-
-       netdev_dbg(dev, "ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
-                  (unsigned long long)pci_resource_start(tp->pci_dev, 1),
-                  dev->irq, NETDRV_R8(MediaStatus),
-                  tp->full_duplex ? "full" : "half");
-
-       /* Set the timer to switch to check for link beat and perhaps switch
-          to an alternate media type. */
-       init_timer(&tp->timer);
-       tp->timer.expires = jiffies + 3 * HZ;
-       tp->timer.data = (unsigned long) dev;
-       tp->timer.function = netdrv_timer;
-       add_timer(&tp->timer);
-
-       DPRINTK("EXIT, returning 0\n");
-       return 0;
-}
-
-
-/* Start the hardware at open or resume. */
-static void netdrv_hw_start(struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       u32 i;
-
-       DPRINTK("ENTER\n");
-
-       /* Soft reset the chip. */
-       NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) | CmdReset);
-       udelay(100);
-
-       /* Check that the chip has finished the reset. */
-       for (i = 1000; i > 0; i--)
-               if ((NETDRV_R8(ChipCmd) & CmdReset) == 0)
-                       break;
-
-       /* Restore our idea of the MAC address. */
-       NETDRV_W32_F(MAC0 + 0, cpu_to_le32(*(u32 *)(dev->dev_addr + 0)));
-       NETDRV_W32_F(MAC0 + 4, cpu_to_le32(*(u32 *)(dev->dev_addr + 4)));
-
-       /* Must enable Tx/Rx before setting transfer thresholds! */
-       NETDRV_W8_F(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) |
-                   CmdRxEnb | CmdTxEnb);
-
-       i = netdrv_rx_config |
-               (NETDRV_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-       NETDRV_W32_F(RxConfig, i);
-
-       /* Check this value: the documentation for IFG contradicts ifself. */
-       NETDRV_W32(TxConfig, (TX_DMA_BURST << TxDMAShift));
-
-       /* unlock Config[01234] and BMCR register writes */
-       NETDRV_W8_F(Cfg9346, Cfg9346_Unlock);
-       udelay(10);
-
-       tp->cur_rx = 0;
-
-       /* Lock Config[01234] and BMCR register writes */
-       NETDRV_W8_F(Cfg9346, Cfg9346_Lock);
-       udelay(10);
-
-       /* init Rx ring buffer DMA address */
-       NETDRV_W32_F(RxBuf, tp->rx_ring_dma);
-
-       /* init Tx buffer DMA addresses */
-       for (i = 0; i < NUM_TX_DESC; i++)
-               NETDRV_W32_F(TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
-
-       NETDRV_W32_F(RxMissed, 0);
-
-       netdrv_set_rx_mode(dev);
-
-       /* no early-rx interrupts */
-       NETDRV_W16(MultiIntr, NETDRV_R16(MultiIntr) & MultiIntrClear);
-
-       /* make sure RxTx has started */
-       NETDRV_W8_F(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear) |
-                   CmdRxEnb | CmdTxEnb);
-
-       /* Enable all known interrupts by setting the interrupt mask. */
-       NETDRV_W16_F(IntrMask, netdrv_intr_mask);
-
-       netif_start_queue(dev);
-
-       DPRINTK("EXIT\n");
-}
-
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void netdrv_init_ring(struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       int i;
-
-       DPRINTK("ENTER\n");
-
-       tp->cur_rx = 0;
-       atomic_set(&tp->cur_tx, 0);
-       atomic_set(&tp->dirty_tx, 0);
-
-       for (i = 0; i < NUM_TX_DESC; i++) {
-               tp->tx_info[i].skb = NULL;
-               tp->tx_info[i].mapping = 0;
-               tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];
-       }
-
-       DPRINTK("EXIT\n");
-}
-
-
-static void netdrv_timer(unsigned long data)
-{
-       struct net_device *dev = (struct net_device *) data;
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       int next_tick = 60 * HZ;
-       int mii_lpa;
-
-       mii_lpa = mdio_read(dev, tp->phys[0], MII_LPA);
-
-       if (!tp->duplex_lock && mii_lpa != 0xffff) {
-               int duplex = ((mii_lpa & LPA_100FULL) ||
-                            (mii_lpa & 0x01C0) == 0x0040);
-               if (tp->full_duplex != duplex) {
-                       tp->full_duplex = duplex;
-                       netdev_info(dev, "Setting %s-duplex based on MII #%d link partner ability of %04x\n",
-                                   tp->full_duplex ? "full" : "half",
-                                   tp->phys[0], mii_lpa);
-                       NETDRV_W8(Cfg9346, Cfg9346_Unlock);
-                       NETDRV_W8(Config1, tp->full_duplex ? 0x60 : 0x20);
-                       NETDRV_W8(Cfg9346, Cfg9346_Lock);
-               }
-       }
-
-       netdev_dbg(dev, "Media selection tick, Link partner %04x\n",
-                  NETDRV_R16(NWayLPAR));
-       netdev_dbg(dev, "Other registers are IntMask %04x IntStatus %04x RxStatus %04lx\n",
-                  NETDRV_R16(IntrMask),
-                  NETDRV_R16(IntrStatus),
-                  NETDRV_R32(RxEarlyStatus));
-       netdev_dbg(dev, "Chip config %02x %02x\n",
-                  NETDRV_R8(Config0), NETDRV_R8(Config1));
-
-       tp->timer.expires = jiffies + next_tick;
-       add_timer(&tp->timer);
-}
-
-
-static void netdrv_tx_clear(struct net_device *dev)
-{
-       int i;
-       struct netdrv_private *tp = netdev_priv(dev);
-
-       atomic_set(&tp->cur_tx, 0);
-       atomic_set(&tp->dirty_tx, 0);
-
-       /* Dump the unsent Tx packets. */
-       for (i = 0; i < NUM_TX_DESC; i++) {
-               struct ring_info *rp = &tp->tx_info[i];
-               if (rp->mapping != 0) {
-                       pci_unmap_single(tp->pci_dev, rp->mapping,
-                                        rp->skb->len, PCI_DMA_TODEVICE);
-                       rp->mapping = 0;
-               }
-               if (rp->skb) {
-                       dev_kfree_skb(rp->skb);
-                       rp->skb = NULL;
-                       dev->stats.tx_dropped++;
-               }
-       }
-}
-
-
-static void netdrv_tx_timeout(struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       int i;
-       u8 tmp8;
-       unsigned long flags;
-
-       netdev_dbg(dev, "Transmit timeout, status %02x %04x media %02x\n",
-                  NETDRV_R8(ChipCmd),
-                  NETDRV_R16(IntrStatus),
-                  NETDRV_R8(MediaStatus));
-
-       /* disable Tx ASAP, if not already */
-       tmp8 = NETDRV_R8(ChipCmd);
-       if (tmp8 & CmdTxEnb)
-               NETDRV_W8(ChipCmd, tmp8 & ~CmdTxEnb);
-
-       /* Disable interrupts by clearing the interrupt mask. */
-       NETDRV_W16(IntrMask, 0x0000);
-
-       /* Emit info to figure out what went wrong. */
-       netdev_dbg(dev, "Tx queue start entry %d dirty entry %d\n",
-                  atomic_read(&tp->cur_tx),
-                  atomic_read(&tp->dirty_tx));
-       for (i = 0; i < NUM_TX_DESC; i++)
-               netdev_dbg(dev, "Tx descriptor %d is %08lx%s\n",
-                          i, NETDRV_R32(TxStatus0 + (i * 4)),
-                          i == atomic_read(&tp->dirty_tx) % NUM_TX_DESC ?
-                          "(queue head)" : "");
-
-       /* Stop a shared interrupt from scavenging while we are. */
-       spin_lock_irqsave(&tp->lock, flags);
-
-       netdrv_tx_clear(dev);
-
-       spin_unlock_irqrestore(&tp->lock, flags);
-
-       /* ...and finally, reset everything */
-       netdrv_hw_start(dev);
-
-       netif_wake_queue(dev);
-}
-
-
-
-static int netdrv_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       int entry;
-
-       /* Calculate the next Tx descriptor entry. */
-       entry = atomic_read(&tp->cur_tx) % NUM_TX_DESC;
-
-       assert(tp->tx_info[entry].skb == NULL);
-       assert(tp->tx_info[entry].mapping == 0);
-
-       tp->tx_info[entry].skb = skb;
-       /* tp->tx_info[entry].mapping = 0; */
-       skb_copy_from_linear_data(skb, tp->tx_buf[entry], skb->len);
-
-       /* Note: the chip doesn't have auto-pad! */
-       NETDRV_W32(TxStatus0 + (entry * sizeof(u32)),
-                  tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
-
-       atomic_inc(&tp->cur_tx);
-       if ((atomic_read(&tp->cur_tx) - atomic_read(&tp->dirty_tx)) >= NUM_TX_DESC)
-               netif_stop_queue(dev);
-
-       netdev_dbg(dev, "Queued Tx packet at %p size %u to slot %d\n",
-                  skb->data, skb->len, entry);
-
-       return NETDEV_TX_OK;
-}
-
-
-static void netdrv_tx_interrupt(struct net_device *dev,
-                               struct netdrv_private *tp,
-                               void *ioaddr)
-{
-       int cur_tx, dirty_tx, tx_left;
-
-       assert(dev != NULL);
-       assert(tp != NULL);
-       assert(ioaddr != NULL);
-
-       dirty_tx = atomic_read(&tp->dirty_tx);
-
-       cur_tx = atomic_read(&tp->cur_tx);
-       tx_left = cur_tx - dirty_tx;
-       while (tx_left > 0) {
-               int entry = dirty_tx % NUM_TX_DESC;
-               int txstatus;
-
-               txstatus = NETDRV_R32(TxStatus0 + (entry * sizeof(u32)));
-
-               if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
-                       break;  /* It still hasn't been Txed */
-
-               /* Note: TxCarrierLost is always asserted at 100mbps. */
-               if (txstatus & (TxOutOfWindow | TxAborted)) {
-                       /* There was an major error, log it. */
-                       netdev_dbg(dev, "Transmit error, Tx status %#08x\n",
-                                  txstatus);
-                       dev->stats.tx_errors++;
-                       if (txstatus & TxAborted) {
-                               dev->stats.tx_aborted_errors++;
-                               NETDRV_W32(TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
-                       }
-                       if (txstatus & TxCarrierLost)
-                               dev->stats.tx_carrier_errors++;
-                       if (txstatus & TxOutOfWindow)
-                               dev->stats.tx_window_errors++;
-               } else {
-                       if (txstatus & TxUnderrun) {
-                               /* Add 64 to the Tx FIFO threshold. */
-                               if (tp->tx_flag < 0x00300000)
-                                       tp->tx_flag += 0x00020000;
-                               dev->stats.tx_fifo_errors++;
-                       }
-                       dev->stats.collisions += (txstatus >> 24) & 15;
-                       dev->stats.tx_bytes += txstatus & 0x7ff;
-                       dev->stats.tx_packets++;
-               }
-
-               /* Free the original skb. */
-               if (tp->tx_info[entry].mapping != 0) {
-                       pci_unmap_single(tp->pci_dev,
-                                        tp->tx_info[entry].mapping,
-                                        tp->tx_info[entry].skb->len,
-                                        PCI_DMA_TODEVICE);
-                       tp->tx_info[entry].mapping = 0;
-               }
-               dev_kfree_skb_irq(tp->tx_info[entry].skb);
-               tp->tx_info[entry].skb = NULL;
-               dirty_tx++;
-               if (dirty_tx < 0) { /* handle signed int overflow */
-                       atomic_sub(cur_tx, &tp->cur_tx); /* XXX racy? */
-                       dirty_tx = cur_tx - tx_left + 1;
-               }
-               if (netif_queue_stopped(dev))
-                       netif_wake_queue(dev);
-
-               cur_tx = atomic_read(&tp->cur_tx);
-               tx_left = cur_tx - dirty_tx;
-
-       }
-
-#ifndef NETDRV_NDEBUG
-       if (atomic_read(&tp->cur_tx) - dirty_tx > NUM_TX_DESC) {
-               netdev_err(dev, "Out-of-sync dirty pointer, %d vs. %d\n",
-                          dirty_tx, atomic_read(&tp->cur_tx));
-               dirty_tx += NUM_TX_DESC;
-       }
-#endif /* NETDRV_NDEBUG */
-
-       atomic_set(&tp->dirty_tx, dirty_tx);
-}
-
-
-/* TODO: clean this up!  Rx reset need not be this intensive */
-static void netdrv_rx_err(u32 rx_status, struct net_device *dev,
-                         struct netdrv_private *tp, void *ioaddr)
-{
-       u8 tmp8;
-       int tmp_work = 1000;
-
-       netdev_dbg(dev, "Ethernet frame had errors, status %08x\n", rx_status);
-       if (rx_status & RxTooLong)
-               netdev_dbg(dev, "Oversized Ethernet frame, status %04x!\n",
-                          rx_status);
-               /* A.C.: The chip hangs here. */
-       dev->stats.rx_errors++;
-       if (rx_status & (RxBadSymbol | RxBadAlign))
-               dev->stats.rx_frame_errors++;
-       if (rx_status & (RxRunt | RxTooLong))
-               dev->stats.rx_length_errors++;
-       if (rx_status & RxCRCErr)
-               dev->stats.rx_crc_errors++;
-       /* Reset the receiver, based on RealTek recommendation.(Bug?) */
-       tp->cur_rx = 0;
-
-       /* disable receive */
-       tmp8 = NETDRV_R8(ChipCmd) & ChipCmdClear;
-       NETDRV_W8_F(ChipCmd, tmp8 | CmdTxEnb);
-
-       /* A.C.: Reset the multicast list. */
-       netdrv_set_rx_mode(dev);
-
-       /* XXX potentially temporary hack to
-        * restart hung receiver */
-       while (--tmp_work > 0) {
-               tmp8 = NETDRV_R8(ChipCmd);
-               if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
-                       break;
-               NETDRV_W8_F(ChipCmd,
-                           (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
-       }
-
-       /* G.S.: Re-enable receiver */
-       /* XXX temporary hack to work around receiver hang */
-       netdrv_set_rx_mode(dev);
-
-       if (tmp_work <= 0)
-               netdev_warn(dev, "tx/rx enable wait too long\n");
-}
-
-
-/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
-   field alignments and semantics. */
-static void netdrv_rx_interrupt(struct net_device *dev,
-                               struct netdrv_private *tp, void *ioaddr)
-{
-       unsigned char *rx_ring;
-       u16 cur_rx;
-
-       assert(dev != NULL);
-       assert(tp != NULL);
-       assert(ioaddr != NULL);
-
-       rx_ring = tp->rx_ring;
-       cur_rx = tp->cur_rx;
-
-       netdev_dbg(dev, "In netdrv_rx(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
-                  cur_rx, NETDRV_R16(RxBufAddr),
-                  NETDRV_R16(RxBufPtr), NETDRV_R8(ChipCmd));
-
-       while ((NETDRV_R8(ChipCmd) & RxBufEmpty) == 0) {
-               int ring_offset = cur_rx % RX_BUF_LEN;
-               u32 rx_status;
-               unsigned int rx_size;
-               unsigned int pkt_size;
-               struct sk_buff *skb;
-
-               /* read size+status of next frame from DMA ring buffer */
-               rx_status = le32_to_cpu(*(u32 *)(rx_ring + ring_offset));
-               rx_size = rx_status >> 16;
-               pkt_size = rx_size - 4;
-
-               netdev_dbg(dev, "netdrv_rx() status %04x, size %04x, cur %04x\n",
-                          rx_status, rx_size, cur_rx);
-#if defined(NETDRV_DEBUG) && (NETDRV_DEBUG > 2)
-               print_hex_dump_bytes("Frame contents: ", HEX_DUMP_OFFSET,
-                                    &rx_ring[ring_offset], 70);
-#endif
-
-               /* If Rx err or invalid rx_size/rx_status received
-                *(which happens if we get lost in the ring),
-                * Rx process gets reset, so we abort any further
-                * Rx processing.
-                */
-               if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
-                   (!(rx_status & RxStatusOK))) {
-                       netdrv_rx_err(rx_status, dev, tp, ioaddr);
-                       return;
-               }
-
-               /* Malloc up new buffer, compatible with net-2e. */
-               /* Omit the four octet CRC from the length. */
-
-               /* TODO: consider allocating skb's outside of
-                * interrupt context, both to speed interrupt processing,
-                * and also to reduce the chances of having to
-                * drop packets here under memory pressure.
-                */
-
-               skb = dev_alloc_skb(pkt_size + 2);
-               if (skb) {
-                       skb_reserve(skb, 2);    /* 16 byte align the IP fields. */
-
-                       skb_copy_to_linear_data(skb, &rx_ring[ring_offset + 4], pkt_size);
-                       skb_put(skb, pkt_size);
-
-                       skb->protocol = eth_type_trans(skb, dev);
-                       netif_rx(skb);
-                       dev->stats.rx_bytes += pkt_size;
-                       dev->stats.rx_packets++;
-               } else {
-                       netdev_warn(dev, "Memory squeeze, dropping packet\n");
-                       dev->stats.rx_dropped++;
-               }
-
-               cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
-               NETDRV_W16_F(RxBufPtr, cur_rx - 16);
-       }
-
-       netdev_dbg(dev, "Done netdrv_rx(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
-                  cur_rx, NETDRV_R16(RxBufAddr),
-                  NETDRV_R16(RxBufPtr), NETDRV_R8(ChipCmd));
-
-       tp->cur_rx = cur_rx;
-}
-
-
-static void netdrv_weird_interrupt(struct net_device *dev,
-                                  struct netdrv_private *tp,
-                                  void *ioaddr,
-                                  int status, int link_changed)
-{
-       netdev_printk(KERN_DEBUG, dev, "Abnormal interrupt, status %08x\n",
-                     status);
-
-       assert(dev != NULL);
-       assert(tp != NULL);
-       assert(ioaddr != NULL);
-
-       /* Update the error count. */
-       dev->stats.rx_missed_errors += NETDRV_R32(RxMissed);
-       NETDRV_W32(RxMissed, 0);
-
-       if ((status & RxUnderrun) && link_changed &&
-           (tp->drv_flags & HAS_LNK_CHNG)) {
-               /* Really link-change on new chips. */
-               int lpar = NETDRV_R16(NWayLPAR);
-               int duplex = ((lpar & 0x0100) || (lpar & 0x01C0) == 0x0040 ||
-                            tp->duplex_lock);
-               if (tp->full_duplex != duplex) {
-                       tp->full_duplex = duplex;
-                       NETDRV_W8(Cfg9346, Cfg9346_Unlock);
-                       NETDRV_W8(Config1, tp->full_duplex ? 0x60 : 0x20);
-                       NETDRV_W8(Cfg9346, Cfg9346_Lock);
-               }
-               status &= ~RxUnderrun;
-       }
-
-       /* XXX along with netdrv_rx_err, are we double-counting errors? */
-       if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
-               dev->stats.rx_errors++;
-
-       if (status & (PCSTimeout))
-               dev->stats.rx_length_errors++;
-       if (status & (RxUnderrun | RxFIFOOver))
-               dev->stats.rx_fifo_errors++;
-       if (status & RxOverflow) {
-               dev->stats.rx_over_errors++;
-               tp->cur_rx = NETDRV_R16(RxBufAddr) % RX_BUF_LEN;
-               NETDRV_W16_F(RxBufPtr, tp->cur_rx - 16);
-       }
-       if (status & PCIErr) {
-               u16 pci_cmd_status;
-               pci_read_config_word(tp->pci_dev, PCI_STATUS, &pci_cmd_status);
-
-               netdev_err(dev, "PCI Bus error %04x\n", pci_cmd_status);
-       }
-}
-
-
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
-static irqreturn_t netdrv_interrupt(int irq, void *dev_instance)
-{
-       struct net_device *dev = (struct net_device *) dev_instance;
-       struct netdrv_private *tp = netdev_priv(dev);
-       int boguscnt = max_interrupt_work;
-       void *ioaddr = tp->mmio_addr;
-       int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
-       int handled = 0;
-
-       spin_lock(&tp->lock);
-
-       do {
-               status = NETDRV_R16(IntrStatus);
-
-               /* h/w no longer present(hotplug?) or major error, bail */
-               if (status == 0xFFFF)
-                       break;
-
-               handled = 1;
-               /* Acknowledge all of the current interrupt sources ASAP */
-               NETDRV_W16_F(IntrStatus, status);
-
-               netdev_dbg(dev, "interrupt  status=%#04x new intstat=%#04x\n",
-                          status, NETDRV_R16(IntrStatus));
-
-               if ((status &
-                    (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
-                     RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
-                       break;
-
-               /* Check uncommon events with one test. */
-               if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
-                            RxFIFOOver | TxErr | RxErr))
-                       netdrv_weird_interrupt(dev, tp, ioaddr,
-                                              status, link_changed);
-
-               if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))     /* Rx interrupt */
-                       netdrv_rx_interrupt(dev, tp, ioaddr);
-
-               if (status & (TxOK | TxErr))
-                       netdrv_tx_interrupt(dev, tp, ioaddr);
-
-               boguscnt--;
-       } while (boguscnt > 0);
-
-       if (boguscnt <= 0) {
-               netdev_warn(dev, "Too much work at interrupt, IntrStatus=%#04x\n",
-                           status);
-
-               /* Clear all interrupt sources. */
-               NETDRV_W16(IntrStatus, 0xffff);
-       }
-
-       spin_unlock(&tp->lock);
-
-       netdev_dbg(dev, "exiting interrupt, intr_status=%#04x\n",
-                  NETDRV_R16(IntrStatus));
-       return IRQ_RETVAL(handled);
-}
-
-
-static int netdrv_close(struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       unsigned long flags;
-
-       DPRINTK("ENTER\n");
-
-       netif_stop_queue(dev);
-
-       netdev_dbg(dev, "Shutting down ethercard, status was %#04x\n",
-                  NETDRV_R16(IntrStatus));
-
-       del_timer_sync(&tp->timer);
-
-       spin_lock_irqsave(&tp->lock, flags);
-
-       /* Stop the chip's Tx and Rx DMA processes. */
-       NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear));
-
-       /* Disable interrupts by clearing the interrupt mask. */
-       NETDRV_W16(IntrMask, 0x0000);
-
-       /* Update the error counts. */
-       dev->stats.rx_missed_errors += NETDRV_R32(RxMissed);
-       NETDRV_W32(RxMissed, 0);
-
-       spin_unlock_irqrestore(&tp->lock, flags);
-
-       free_irq(dev->irq, dev);
-
-       netdrv_tx_clear(dev);
-
-       pci_free_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
-                           tp->rx_ring, tp->rx_ring_dma);
-       pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
-                           tp->tx_bufs, tp->tx_bufs_dma);
-       tp->rx_ring = NULL;
-       tp->tx_bufs = NULL;
-
-       /* Green! Put the chip in low-power mode. */
-       NETDRV_W8(Cfg9346, Cfg9346_Unlock);
-       NETDRV_W8(Config1, 0x03);
-       NETDRV_W8(Cfg9346, Cfg9346_Lock);
-
-       DPRINTK("EXIT\n");
-       return 0;
-}
-
-
-static int netdrv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       struct mii_ioctl_data *data = if_mii(rq);
-       unsigned long flags;
-       int rc = 0;
-
-       DPRINTK("ENTER\n");
-
-       switch (cmd) {
-       case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
-               data->phy_id = tp->phys[0] & 0x3f;
-               /* Fall Through */
-
-       case SIOCGMIIREG:               /* Read MII PHY register. */
-               spin_lock_irqsave(&tp->lock, flags);
-               data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
-               spin_unlock_irqrestore(&tp->lock, flags);
-               break;
-
-       case SIOCSMIIREG:               /* Write MII PHY register. */
-               spin_lock_irqsave(&tp->lock, flags);
-               mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
-               spin_unlock_irqrestore(&tp->lock, flags);
-               break;
-
-       default:
-               rc = -EOPNOTSUPP;
-               break;
-       }
-
-       DPRINTK("EXIT, returning %d\n", rc);
-       return rc;
-}
-
-/* Set or clear the multicast filter for this adaptor.
-   This routine is not state sensitive and need not be SMP locked. */
-
-static void netdrv_set_rx_mode(struct net_device *dev)
-{
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       u32 mc_filter[2];       /* Multicast hash filter */
-       int rx_mode;
-       u32 tmp;
-
-       DPRINTK("ENTER\n");
-
-       netdev_dbg(dev, "%s(%04x) done -- Rx config %08lx\n",
-                  __func__, dev->flags, NETDRV_R32(RxConfig));
-
-       /* Note: do not reorder, GCC is clever about common statements. */
-       if (dev->flags & IFF_PROMISC) {
-               rx_mode =
-                       AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
-                       AcceptAllPhys;
-               mc_filter[1] = mc_filter[0] = 0xffffffff;
-       } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
-                  (dev->flags & IFF_ALLMULTI)) {
-               /* Too many to filter perfectly -- accept all multicasts. */
-               rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-               mc_filter[1] = mc_filter[0] = 0xffffffff;
-       } else {
-               struct netdev_hw_addr *ha;
-
-               rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-               mc_filter[1] = mc_filter[0] = 0;
-               netdev_for_each_mc_addr(ha, dev) {
-                       int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
-
-                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-               }
-       }
-
-       /* if called from irq handler, lock already acquired */
-       if (!in_irq())
-               spin_lock_irq(&tp->lock);
-
-       /* We can safely update without stopping the chip. */
-       tmp = netdrv_rx_config | rx_mode |
-               (NETDRV_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
-       NETDRV_W32_F(RxConfig, tmp);
-       NETDRV_W32_F(MAR0 + 0, mc_filter[0]);
-       NETDRV_W32_F(MAR0 + 4, mc_filter[1]);
-
-       if (!in_irq())
-               spin_unlock_irq(&tp->lock);
-
-       DPRINTK("EXIT\n");
-}
-
-
-#ifdef CONFIG_PM
-
-static int netdrv_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct netdrv_private *tp = netdev_priv(dev);
-       void *ioaddr = tp->mmio_addr;
-       unsigned long flags;
-
-       if (!netif_running(dev))
-               return 0;
-       netif_device_detach(dev);
-
-       spin_lock_irqsave(&tp->lock, flags);
-
-       /* Disable interrupts, stop Tx and Rx. */
-       NETDRV_W16(IntrMask, 0x0000);
-       NETDRV_W8(ChipCmd, (NETDRV_R8(ChipCmd) & ChipCmdClear));
-
-       /* Update the error counts. */
-       dev->stats.rx_missed_errors += NETDRV_R32(RxMissed);
-       NETDRV_W32(RxMissed, 0);
-
-       spin_unlock_irqrestore(&tp->lock, flags);
-
-       pci_save_state(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-
-static int netdrv_resume(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       /*struct netdrv_private *tp = netdev_priv(dev);*/
-
-       if (!netif_running(dev))
-               return 0;
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       netif_device_attach(dev);
-       netdrv_hw_start(dev);
-
-       return 0;
-}
-
-#endif /* CONFIG_PM */
-
-
-static struct pci_driver netdrv_pci_driver = {
-       .name           = MODNAME,
-       .id_table       = netdrv_pci_tbl,
-       .probe          = netdrv_init_one,
-       .remove         = __devexit_p(netdrv_remove_one),
-#ifdef CONFIG_PM
-       .suspend        = netdrv_suspend,
-       .resume         = netdrv_resume,
-#endif /* CONFIG_PM */
-};
-
-
-static int __init netdrv_init_module(void)
-{
-/* when a module, this is printed whether or not devices are found in probe */
-#ifdef MODULE
-       printk(version);
-#endif
-       return pci_register_driver(&netdrv_pci_driver);
-}
-
-
-static void __exit netdrv_cleanup_module(void)
-{
-       pci_unregister_driver(&netdrv_pci_driver);
-}
-
-
-module_init(netdrv_init_module);
-module_exit(netdrv_cleanup_module);
index 9b8f793b1cc81c08ac586ae99082ce72658fcb9a..12e7ae47c066f792704569a183180a03c2edb9f5 100644 (file)
@@ -21,84 +21,6 @@ menuconfig NET_PCMCIA
 
 if NET_PCMCIA && PCMCIA
 
-config PCMCIA_3C589
-       tristate "3Com 3c589 PCMCIA support"
-       help
-         Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
-         (PC-card) Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called 3c589_cs.  If unsure, say N.
-
-config PCMCIA_3C574
-       tristate "3Com 3c574 PCMCIA support"
-       help
-         Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
-         (PC-card) Fast Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called 3c574_cs.  If unsure, say N.
-
-config PCMCIA_FMVJ18X
-       tristate "Fujitsu FMV-J18x PCMCIA support"
-       select CRC32
-       help
-         Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible
-         PCMCIA (PC-card) Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called fmvj18x_cs.  If unsure, say N.
-
-config PCMCIA_PCNET
-       tristate "NE2000 compatible PCMCIA support"
-       select CRC32
-       help
-         Say Y here if you intend to attach an NE2000 compatible PCMCIA
-         (PC-card) Ethernet or Fast Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called pcnet_cs.  If unsure, say N.
-
-config PCMCIA_NMCLAN
-       tristate "New Media PCMCIA support"
-       help
-         Say Y here if you intend to attach a New Media Ethernet or LiveWire
-         PCMCIA (PC-card) Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called nmclan_cs.  If unsure, say N.
-
-config PCMCIA_SMC91C92
-       tristate "SMC 91Cxx PCMCIA support"
-       select CRC32
-       select MII
-       help
-         Say Y here if you intend to attach an SMC 91Cxx compatible PCMCIA
-         (PC-card) Ethernet or Fast Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called smc91c92_cs.  If unsure, say N.
-
-config PCMCIA_XIRC2PS
-       tristate "Xircom 16-bit PCMCIA support"
-       help
-         Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card)
-         Ethernet or Fast Ethernet card to your computer.
-
-         To compile this driver as a module, choose M here: the module will be
-         called xirc2ps_cs.  If unsure, say N.
-
-config PCMCIA_AXNET
-       tristate "Asix AX88190 PCMCIA support"
-       ---help---
-         Say Y here if you intend to attach an Asix AX88190-based PCMCIA
-         (PC-card) Fast Ethernet card to your computer.  These cards are
-         nearly NE2000 compatible but need a separate driver due to a few
-         misfeatures.
-
-         To compile this driver as a module, choose M here: the module will be
-         called axnet_cs.  If unsure, say N.
-
 config ARCNET_COM20020_CS
        tristate "COM20020 ARCnet PCMCIA support"
        depends on ARCNET_COM20020
index 87d2d99f4c147e911904b3be5ca32a9b0a61ae85..618e81667ca0a9545e5bc577c45afee8be27c159 100644 (file)
@@ -3,14 +3,6 @@
 #
 
 # 16-bit client drivers
-obj-$(CONFIG_PCMCIA_3C589)     += 3c589_cs.o
-obj-$(CONFIG_PCMCIA_3C574)     += 3c574_cs.o
-obj-$(CONFIG_PCMCIA_FMVJ18X)   += fmvj18x_cs.o
-obj-$(CONFIG_PCMCIA_NMCLAN)    += nmclan_cs.o
-obj-$(CONFIG_PCMCIA_PCNET)     += pcnet_cs.o
-obj-$(CONFIG_PCMCIA_SMC91C92)  += smc91c92_cs.o
-obj-$(CONFIG_PCMCIA_XIRC2PS)   += xirc2ps_cs.o
 obj-$(CONFIG_ARCNET_COM20020_CS)+= com20020_cs.o
-obj-$(CONFIG_PCMCIA_AXNET)     += axnet_cs.o
 
 obj-$(CONFIG_PCMCIA_IBMTR)     += ibmtr_cs.o
index 16c62659cdd96040e7831d0e7d7e18bc58832752..3d9a4596a423d22029992830e01cecc3dd09efe6 100644 (file)
@@ -167,7 +167,7 @@ static const struct net_device_ops skfp_netdev_ops = {
        .ndo_start_xmit         = skfp_send_pkt,
        .ndo_get_stats          = skfp_ctl_get_stats,
        .ndo_change_mtu         = fddi_change_mtu,
-       .ndo_set_multicast_list = skfp_ctl_set_multicast_list,
+       .ndo_set_rx_mode        = skfp_ctl_set_multicast_list,
        .ndo_set_mac_address    = skfp_ctl_set_mac_address,
        .ndo_do_ioctl           = skfp_ioctl,
 };
index 4c617534f9377a40da2755b77c54dbc7da2cf978..ba08341fb92c6b4f5c3752c316d8de3d156e8c4a 100644 (file)
@@ -562,34 +562,33 @@ static struct rtnl_link_stats64 *
 sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
        struct net_device_stats *devstats = &dev->stats;
-       unsigned long c_rx_dropped = 0;
 #ifdef SL_INCLUDE_CSLIP
-       unsigned long c_rx_fifo_errors = 0;
-       unsigned long c_tx_fifo_errors = 0;
-       unsigned long c_collisions = 0;
        struct slip *sl = netdev_priv(dev);
        struct slcompress *comp = sl->slcomp;
-
-       if (comp) {
-               c_rx_fifo_errors = comp->sls_i_compressed;
-               c_rx_dropped     = comp->sls_i_tossed;
-               c_tx_fifo_errors = comp->sls_o_compressed;
-               c_collisions     = comp->sls_o_misses;
-       }
-       stats->rx_fifo_errors = sl->rx_compressed + c_rx_fifo_errors;
-       stats->tx_fifo_errors = sl->tx_compressed + c_tx_fifo_errors;
-       stats->collisions     = sl->tx_misses + c_collisions;
 #endif
        stats->rx_packets     = devstats->rx_packets;
        stats->tx_packets     = devstats->tx_packets;
        stats->rx_bytes       = devstats->rx_bytes;
        stats->tx_bytes       = devstats->tx_bytes;
-       stats->rx_dropped     = devstats->rx_dropped + c_rx_dropped;
+       stats->rx_dropped     = devstats->rx_dropped;
        stats->tx_dropped     = devstats->tx_dropped;
        stats->tx_errors      = devstats->tx_errors;
        stats->rx_errors      = devstats->rx_errors;
        stats->rx_over_errors = devstats->rx_over_errors;
 
+#ifdef SL_INCLUDE_CSLIP
+       if (comp) {
+               /* Generic compressed statistics */
+               stats->rx_compressed   = comp->sls_i_compressed;
+               stats->tx_compressed   = comp->sls_o_compressed;
+
+               /* Are we really still needs this? */
+               stats->rx_fifo_errors += comp->sls_i_compressed;
+               stats->rx_dropped     += comp->sls_i_tossed;
+               stats->tx_fifo_errors += comp->sls_o_compressed;
+               stats->collisions     += comp->sls_o_misses;
+       }
+#endif
        return stats;
 }
 
index aa0764ce2342e95c449fb4e5b18df98514ffce6b..67673cf1266b3110d47522bb1ab3ed4dd5bfd54c 100644 (file)
@@ -65,15 +65,6 @@ struct slip {
   unsigned char                *xbuff;         /* transmitter buffer           */
   unsigned char         *xhead;         /* pointer to next byte to XMIT */
   int                   xleft;          /* bytes left in XMIT queue     */
-
-  /* SLIP interface statistics. */
-#ifdef SL_INCLUDE_CSLIP
-  unsigned long                tx_compressed;
-  unsigned long                rx_compressed;
-  unsigned long                tx_misses;
-#endif
-  /* Detailed SLIP statistics. */
-
   int                  mtu;            /* Our mtu (to spot changes!)   */
   int                   buffsize;       /* Max buffers sizes            */
 
index d16880d7099b014916a408ac7682b9c748251ca7..58f13adaa5490793ebb01be90b38482ee92ec53b 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/prom.h>
 #endif
 
-#include "sungem_phy.h"
+#include <linux/sungem_phy.h>
 
 /* Link modes of the BCM5400 PHY */
 static const int phy_BCM5400_link_table[8][3] = {
@@ -1156,7 +1156,7 @@ static struct mii_phy_def* mii_phy_table[] = {
        NULL
 };
 
-int mii_phy_probe(struct mii_phy *phy, int mii_id)
+int sungem_phy_probe(struct mii_phy *phy, int mii_id)
 {
        int rc;
        u32 id;
@@ -1195,6 +1195,5 @@ fail:
        return -ENODEV;
 }
 
-EXPORT_SYMBOL(mii_phy_probe);
+EXPORT_SYMBOL(sungem_phy_probe);
 MODULE_LICENSE("GPL");
-
index b6162fe2348ee0d7e11f42758e57d5d3eb890218..ef9fdf3652f6cda144ace331db52ff67a2a2c43a 100644 (file)
@@ -282,7 +282,7 @@ static const struct net_device_ops xl_netdev_ops = {
        .ndo_stop               = xl_close,
        .ndo_start_xmit         = xl_xmit,
        .ndo_change_mtu         = xl_change_mtu,
-       .ndo_set_multicast_list = xl_set_rx_mode,
+       .ndo_set_rx_mode        = xl_set_rx_mode,
        .ndo_set_mac_address    = xl_set_mac_address,
 };
  
index e257a00fe14b33490345b81e44d06fed9f661695..b5c8c18f504608e5e884ac8f232986a8ff1056c9 100644 (file)
@@ -823,7 +823,7 @@ static const struct net_device_ops trdev_netdev_ops = {
        .ndo_open               = tok_open,
        .ndo_stop               = tok_close,
        .ndo_start_xmit         = tok_send_packet,
-       .ndo_set_multicast_list = tok_set_multicast_list,
+       .ndo_set_rx_mode        = tok_set_multicast_list,
        .ndo_change_mtu         = ibmtr_change_mtu,
 };
 
index 9354ca9da576c97f7ff54ed014480d29e877ec48..8d71e0d290626e3ea7cb4c55522da6c2d1222505 100644 (file)
@@ -231,7 +231,7 @@ static const struct net_device_ops streamer_netdev_ops = {
 #if STREAMER_IOCTL
        .ndo_do_ioctl           = streamer_ioctl,
 #endif
-       .ndo_set_multicast_list = streamer_set_rx_mode,
+       .ndo_set_rx_mode        = streamer_set_rx_mode,
        .ndo_set_mac_address    = streamer_set_mac_address,
 };
 
index e3855aeb13d46d80528a0a247536d4f04fdd33fd..fd8dce90c957502eb2e98e2ee4d3f67e8fff2554 100644 (file)
@@ -201,7 +201,7 @@ static const struct net_device_ops olympic_netdev_ops = {
        .ndo_stop               = olympic_close,
        .ndo_start_xmit         = olympic_xmit,
        .ndo_change_mtu         = olympic_change_mtu,
-       .ndo_set_multicast_list = olympic_set_rx_mode,
+       .ndo_set_rx_mode        = olympic_set_rx_mode,
        .ndo_set_mac_address    = olympic_set_mac_address,
 };
 
index d9044aba7afac48eb53da6d7ba201e752112dcd8..029846a98636323bac69ceacdc04b67092b2085a 100644 (file)
@@ -3623,7 +3623,7 @@ static const struct net_device_ops smctr_netdev_ops = {
        .ndo_start_xmit    = smctr_send_packet,
        .ndo_tx_timeout    = smctr_timeout,
        .ndo_get_stats     = smctr_get_stats,
-       .ndo_set_multicast_list = smctr_set_multicast_list,
+       .ndo_set_rx_mode   = smctr_set_multicast_list,
 };
 
 static int __init smctr_probe1(struct net_device *dev, int ioaddr)
index 793020347e543524708512d5ad0e0681ba0ad1fd..65e9cf3a71febcd3049a8e9c3df771f6b1f13940 100644 (file)
@@ -2289,7 +2289,7 @@ const struct net_device_ops tms380tr_netdev_ops = {
        .ndo_start_xmit         = tms380tr_send_packet,
        .ndo_tx_timeout         = tms380tr_timeout,
        .ndo_get_stats          = tms380tr_get_stats,
-       .ndo_set_multicast_list = tms380tr_set_multicast_list,
+       .ndo_set_rx_mode        = tms380tr_set_multicast_list,
        .ndo_set_mac_address    = tms380tr_set_mac_address,
 };
 EXPORT_SYMBOL(tms380tr_netdev_ops);
index 71f3d1a35b74ea4c0d1615bb5326e254a4475e63..7bea9c65119e339326155c45e4af6e268bda0c6c 100644 (file)
@@ -496,7 +496,7 @@ static const struct net_device_ops tap_netdev_ops = {
        .ndo_start_xmit         = tun_net_xmit,
        .ndo_change_mtu         = tun_net_change_mtu,
        .ndo_fix_features       = tun_net_fix_features,
-       .ndo_set_multicast_list = tun_net_mclist,
+       .ndo_set_rx_mode        = tun_net_mclist,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
index c5c4b4def7fbfdb1fe1de2a5f13c19968d55dd12..b843eedd409dd7ef17bd01f04cafcc5422eb5bee 100644 (file)
@@ -872,7 +872,7 @@ static const struct net_device_ops ax88172_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = asix_ioctl,
-       .ndo_set_multicast_list = ax88172_set_multicast,
+       .ndo_set_rx_mode        = ax88172_set_multicast,
 };
 
 static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
@@ -975,7 +975,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
        .ndo_set_mac_address    = asix_set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = asix_ioctl,
-       .ndo_set_multicast_list = asix_set_multicast,
+       .ndo_set_rx_mode        = asix_set_multicast,
 };
 
 static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
@@ -1270,7 +1270,7 @@ static const struct net_device_ops ax88178_netdev_ops = {
        .ndo_tx_timeout         = usbnet_tx_timeout,
        .ndo_set_mac_address    = asix_set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = asix_set_multicast,
+       .ndo_set_rx_mode        = asix_set_multicast,
        .ndo_do_ioctl           = asix_ioctl,
        .ndo_change_mtu         = ax88178_change_mtu,
 };
index 8056f8a27c6a0695f660648875dfeb0f60e7ee7e..a68272c933814d4faa30967c8406d82ea1663842 100644 (file)
@@ -749,7 +749,7 @@ static const struct net_device_ops catc_netdev_ops = {
        .ndo_start_xmit         = catc_start_xmit,
 
        .ndo_tx_timeout         = catc_tx_timeout,
-       .ndo_set_multicast_list = catc_set_multicast_list,
+       .ndo_set_rx_mode        = catc_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
index a03336e086d5ec11423a62b492304c2f00769fc3..f06fb78383a1b865b22c989661a1795f4d7f0368 100644 (file)
@@ -228,23 +228,40 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
        if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) {
 
                if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) {
-                       struct usb_cdc_ncm_ndp_input_size ndp_in_sz;
+                       struct usb_cdc_ncm_ndp_input_size *ndp_in_sz;
+
+                       ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL);
+                       if (!ndp_in_sz) {
+                               err = -ENOMEM;
+                               goto size_err;
+                       }
+
                        err = usb_control_msg(ctx->udev,
                                        usb_sndctrlpipe(ctx->udev, 0),
                                        USB_CDC_SET_NTB_INPUT_SIZE,
                                        USB_TYPE_CLASS | USB_DIR_OUT
                                         | USB_RECIP_INTERFACE,
-                                       0, iface_no, &ndp_in_sz, 8, 1000);
+                                       0, iface_no, ndp_in_sz, 8, 1000);
+                       kfree(ndp_in_sz);
                } else {
-                       __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
+                       __le32 *dwNtbInMaxSize;
+                       dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize),
+                                       GFP_KERNEL);
+                       if (!dwNtbInMaxSize) {
+                               err = -ENOMEM;
+                               goto size_err;
+                       }
+                       *dwNtbInMaxSize = cpu_to_le32(ctx->rx_max);
+
                        err = usb_control_msg(ctx->udev,
                                        usb_sndctrlpipe(ctx->udev, 0),
                                        USB_CDC_SET_NTB_INPUT_SIZE,
                                        USB_TYPE_CLASS | USB_DIR_OUT
                                         | USB_RECIP_INTERFACE,
-                                       0, iface_no, &dwNtbInMaxSize, 4, 1000);
+                                       0, iface_no, dwNtbInMaxSize, 4, 1000);
+                       kfree(dwNtbInMaxSize);
                }
-
+size_err:
                if (err < 0)
                        pr_debug("Setting NTB Input Size failed\n");
        }
@@ -325,19 +342,29 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
 
        /* set Max Datagram Size (MTU) */
        if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) {
-               __le16 max_datagram_size;
+               __le16 *max_datagram_size;
                u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize);
+
+               max_datagram_size = kzalloc(sizeof(*max_datagram_size),
+                               GFP_KERNEL);
+               if (!max_datagram_size) {
+                       err = -ENOMEM;
+                       goto max_dgram_err;
+               }
+
                err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0),
                                USB_CDC_GET_MAX_DATAGRAM_SIZE,
                                USB_TYPE_CLASS | USB_DIR_IN
                                 | USB_RECIP_INTERFACE,
-                               0, iface_no, &max_datagram_size,
+                               0, iface_no, max_datagram_size,
                                2, 1000);
                if (err < 0) {
                        pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n",
                                                CDC_NCM_MIN_DATAGRAM_SIZE);
+                       kfree(max_datagram_size);
                } else {
-                       ctx->max_datagram_size = le16_to_cpu(max_datagram_size);
+                       ctx->max_datagram_size =
+                               le16_to_cpu(*max_datagram_size);
                        /* Check Eth descriptor value */
                        if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) {
                                if (ctx->max_datagram_size > eth_max_sz)
@@ -360,8 +387,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx)
                                                USB_TYPE_CLASS | USB_DIR_OUT
                                                 | USB_RECIP_INTERFACE,
                                                0,
-                                               iface_no, &max_datagram_size,
+                                               iface_no, max_datagram_size,
                                                2, 1000);
+                       kfree(max_datagram_size);
+max_dgram_err:
                        if (err < 0)
                                pr_debug("SET_MAX_DATAGRAM_SIZE failed\n");
                }
index 1d93133e9b744529cb1d72328846be6589417275..fbc0e4def7678d2123a9feb0b8e68ff6aa5b4c99 100644 (file)
@@ -428,7 +428,7 @@ static const struct net_device_ops dm9601_netdev_ops = {
        .ndo_change_mtu         = usbnet_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = dm9601_ioctl,
-       .ndo_set_multicast_list = dm9601_set_multicast,
+       .ndo_set_rx_mode        = dm9601_set_multicast,
        .ndo_set_mac_address    = dm9601_set_mac_address,
 };
 
index be02a25da71a4572fc96ac9d3c699da4db248822..131ac6c172f60c0b69d5837b08471a7c5ffe5546 100644 (file)
@@ -193,7 +193,7 @@ static const struct net_device_ops int51x1_netdev_ops = {
        .ndo_change_mtu         = usbnet_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = int51x1_set_multicast,
+       .ndo_set_rx_mode        = int51x1_set_multicast,
 };
 
 static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf)
index ad0298f9b5f9e6924b634a9fcc673bebecb29afa..582ca2dfa5f911c0b2a7f5cd31b3f82a7cd42447 100644 (file)
@@ -985,7 +985,7 @@ static const struct net_device_ops kaweth_netdev_ops = {
        .ndo_stop =                     kaweth_close,
        .ndo_start_xmit =               kaweth_start_xmit,
        .ndo_tx_timeout =               kaweth_tx_timeout,
-       .ndo_set_multicast_list =       kaweth_set_rx_mode,
+       .ndo_set_rx_mode =              kaweth_set_rx_mode,
        .ndo_get_stats =                kaweth_netdev_stats,
        .ndo_change_mtu =               eth_change_mtu,
        .ndo_set_mac_address =          eth_mac_addr,
index 1d83ccfd72778ea2e2e0ca27f1c490d8eb18c5ca..1e7221951056304162e9d173dea85827234f16c0 100644 (file)
@@ -89,6 +89,8 @@ static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
         * addresses have no meaning, the destination and the source of every
         * packet depend only on whether it is on the IN or OUT endpoint.  */
        dev->net->flags |= IFF_NOARP;
+       /* IPv6 NDP relies on multicast.  Enable it by default. */
+       dev->net->flags |= IFF_MULTICAST;
 
        return ret;
 }
@@ -200,6 +202,14 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                } else {
                        memset(ethhdr->h_source, 0, ETH_ALEN);
                        memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
+
+                       /* Inbound IPv6 packets have an IPv4 ethertype (0x800)
+                        * for some reason.  Peek at the L3 header to check
+                        * for IPv6 packets, and set the ethertype to IPv6
+                        * (0x86dd) so Linux can understand it.
+                        */
+                       if ((buf->data[sizeof(*ethhdr)] & 0xf0) == 0x60)
+                               ethhdr->h_proto = __constant_htons(ETH_P_IPV6);
                }
 
                if (count) {
@@ -297,6 +307,15 @@ encapsulate:
        if (skb->len < full_len) /* Pad */
                skb_put(skb, full_len - skb->len);
 
+       /* The VL600 wants IPv6 packets to have an IPv4 ethertype
+        * Check if this is an IPv6 packet, and set the ethertype
+        * to 0x800
+        */
+       if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) {
+               skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08;
+               skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0;
+       }
+
        return skb;
 }
 
index 2b791392e788ef893657d04056df673fc3ded672..db2cb74bf8549620e39e18b20bd69479a4e8fbfe 100644 (file)
@@ -553,7 +553,7 @@ static const struct net_device_ops mcs7830_netdev_ops = {
        .ndo_change_mtu         = usbnet_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = mcs7830_ioctl,
-       .ndo_set_multicast_list = mcs7830_set_multicast,
+       .ndo_set_rx_mode        = mcs7830_set_multicast,
        .ndo_set_mac_address    = mcs7830_set_mac_address,
 };
 
index ef3667690b12b5f0ee83d45d36bce1d8fd584cf6..769f5090bda1300669dd3ad464e305408d92fb5f 100644 (file)
@@ -1476,7 +1476,7 @@ static const struct net_device_ops pegasus_netdev_ops = {
        .ndo_stop =                     pegasus_close,
        .ndo_do_ioctl =                 pegasus_ioctl,
        .ndo_start_xmit =               pegasus_start_xmit,
-       .ndo_set_multicast_list =       pegasus_set_multicast,
+       .ndo_set_rx_mode =              pegasus_set_multicast,
        .ndo_get_stats =                pegasus_netdev_stats,
        .ndo_tx_timeout =               pegasus_tx_timeout,
        .ndo_change_mtu =               eth_change_mtu,
index ef3b236b51457d49bbd59ddef6a4dbd648c24dd1..b00d692587a28f06731ad752ca5a6f90571b2102 100644 (file)
@@ -899,7 +899,7 @@ static const struct net_device_ops rtl8150_netdev_ops = {
        .ndo_do_ioctl           = rtl8150_ioctl,
        .ndo_start_xmit         = rtl8150_start_xmit,
        .ndo_tx_timeout         = rtl8150_tx_timeout,
-       .ndo_set_multicast_list = rtl8150_set_multicast,
+       .ndo_set_rx_mode        = rtl8150_set_multicast,
        .ndo_set_mac_address    = rtl8150_set_mac_address,
 
        .ndo_change_mtu         = eth_change_mtu,
index 15b3d6888ae9b1997d3c4f09b8968baacef782cc..22a7cf951e728132b6f55d0d99584fc50e374eaa 100644 (file)
@@ -1000,7 +1000,7 @@ static const struct net_device_ops smsc75xx_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = smsc75xx_ioctl,
-       .ndo_set_multicast_list = smsc75xx_set_multicast,
+       .ndo_set_rx_mode        = smsc75xx_set_multicast,
        .ndo_set_features       = smsc75xx_set_features,
 };
 
index f74f3ce7152630fc7adaf43cc6ce107fc8dd6214..eff67678c5a6a582aced31aa27c3dcc569aee768 100644 (file)
@@ -972,7 +972,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = smsc95xx_ioctl,
-       .ndo_set_multicast_list = smsc95xx_set_multicast,
+       .ndo_set_rx_mode        = smsc95xx_set_multicast,
        .ndo_set_features       = smsc95xx_set_features,
 };
 
index ce395fe5de268934b5def60f34462b2f3e74ac84..f1c435ba52848e216d0e63bf0739b9189f074dae 100644 (file)
@@ -1470,7 +1470,7 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
        if (!dev->suspend_count++) {
                spin_lock_irq(&dev->txq.lock);
                /* don't autosuspend while transmitting */
-               if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) {
+               if (dev->txq.qlen && PMSG_IS_AUTO(message)) {
                        spin_unlock_irq(&dev->txq.lock);
                        return -EBUSY;
                } else {
index 0c7321c35ad408ab7ec4ce62383cc2afdf90b541..44ce547ce8fbd4cfd8ff16ada44bbb927ab57962 100644 (file)
@@ -902,12 +902,10 @@ static void virtnet_update_status(struct virtnet_info *vi)
 {
        u16 v;
 
-       if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS))
-               return;
-
-       vi->vdev->config->get(vi->vdev,
+       if (virtio_config_val(vi->vdev, VIRTIO_NET_F_STATUS,
                              offsetof(struct virtio_net_config, status),
-                             &v, sizeof(v));
+                             &v) < 0)
+               return;
 
        /* Ignore unknown (future) status bits */
        v &= VIRTIO_NET_S_LINK_UP;
@@ -949,6 +947,7 @@ static int virtnet_probe(struct virtio_device *vdev)
                return -ENOMEM;
 
        /* Set up network device as normal. */
+       dev->priv_flags |= IFF_UNICAST_FLT;
        dev->netdev_ops = &virtnet_netdev;
        dev->features = NETIF_F_HIGHDMA;
 
@@ -982,11 +981,9 @@ static int virtnet_probe(struct virtio_device *vdev)
        }
 
        /* Configuration may specify what MAC to use.  Otherwise random. */
-       if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
-               vdev->config->get(vdev,
+       if (virtio_config_val_len(vdev, VIRTIO_NET_F_MAC,
                                  offsetof(struct virtio_net_config, mac),
-                                 dev->dev_addr, dev->addr_len);
-       } else
+                                 dev->dev_addr, dev->addr_len) < 0)
                random_ether_addr(dev->dev_addr);
 
        /* Set up our device-specific information */
index 1cbacb3896528e0cc5b54e99abd34b5a809fb714..759c1a49cc7b48ec84a34e909bbad20e154df24c 100644 (file)
@@ -1929,14 +1929,17 @@ static void
 vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-       u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
-       unsigned long flags;
 
-       VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
-       spin_lock_irqsave(&adapter->cmd_lock, flags);
-       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
-                              VMXNET3_CMD_UPDATE_VLAN_FILTERS);
-       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+       if (!(netdev->flags & IFF_PROMISC)) {
+               u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+               unsigned long flags;
+
+               VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
+               spin_lock_irqsave(&adapter->cmd_lock, flags);
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                      VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+               spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+       }
 
        set_bit(vid, adapter->active_vlans);
 }
@@ -1946,14 +1949,17 @@ static void
 vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-       u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
-       unsigned long flags;
 
-       VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid);
-       spin_lock_irqsave(&adapter->cmd_lock, flags);
-       VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
-                              VMXNET3_CMD_UPDATE_VLAN_FILTERS);
-       spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+       if (!(netdev->flags & IFF_PROMISC)) {
+               u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
+               unsigned long flags;
+
+               VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid);
+               spin_lock_irqsave(&adapter->cmd_lock, flags);
+               VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+                                      VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+               spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+       }
 
        clear_bit(vid, adapter->active_vlans);
 }
@@ -2870,7 +2876,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
                .ndo_set_features = vmxnet3_set_features,
                .ndo_get_stats64 = vmxnet3_get_stats64,
                .ndo_tx_timeout = vmxnet3_tx_timeout,
-               .ndo_set_multicast_list = vmxnet3_set_mc,
+               .ndo_set_rx_mode = vmxnet3_set_mc,
                .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid,
                .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid,
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 055a918067e6bd60d5e364918b85263fc2e9ac9d..0d7645581f912d04b79e4374fa46c2ed451b7617 100644 (file)
@@ -515,37 +515,37 @@ static int ppp_rx(struct sk_buff *skb)
        switch (cp->code) {
        case CP_CONF_REQ:
                ppp_cp_parse_cr(dev, pid, cp->id, len, skb->data);
-               goto out;
+               break;
 
        case CP_CONF_ACK:
                if (cp->id == proto->cr_id)
                        ppp_cp_event(dev, pid, RCA, 0, 0, 0, NULL);
-               goto out;
+               break;
 
        case CP_CONF_REJ:
        case CP_CONF_NAK:
                if (cp->id == proto->cr_id)
                        ppp_cp_event(dev, pid, RCN, 0, 0, 0, NULL);
-               goto out;
+               break;
 
        case CP_TERM_REQ:
                ppp_cp_event(dev, pid, RTR, 0, cp->id, 0, NULL);
-               goto out;
+               break;
 
        case CP_TERM_ACK:
                ppp_cp_event(dev, pid, RTA, 0, 0, 0, NULL);
-               goto out;
+               break;
 
        case CP_CODE_REJ:
                ppp_cp_event(dev, pid, RXJ_BAD, 0, 0, 0, NULL);
-               goto out;
+               break;
 
        default:
                len += sizeof(struct cp_header);
                if (len > dev->mtu)
                        len = dev->mtu;
                ppp_cp_event(dev, pid, RUC, 0, 0, len, cp);
-               goto out;
+               break;
        }
        goto out;
 
index 86127bcc9f7a63a504784e6a779b14582bb731c9..783168cce077273e3d9b33e5a218af1677d7f11c 100644 (file)
@@ -212,7 +212,7 @@ static const struct net_device_ops sbni_netdev_ops = {
        .ndo_open               = sbni_open,
        .ndo_stop               = sbni_close,
        .ndo_start_xmit         = sbni_start_xmit,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_do_ioctl           = sbni_ioctl,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
index 298f2b0b6311334094aaf3fb78bca9351ee23d44..9a644d052f1e01482acd0c199b23c76513704c1a 100644 (file)
@@ -599,7 +599,7 @@ void i2400mu_disconnect(struct usb_interface *iface)
  *
  *    As well, the device might refuse going to sleep for whichever
  *    reason. In this case we just fail. For system suspend/hibernate,
- *    we *can't* fail. We check PM_EVENT_AUTO to see if the
+ *    we *can't* fail. We check PMSG_IS_AUTO to see if the
  *    suspend call comes from the USB stack or from the system and act
  *    in consequence.
  *
@@ -615,7 +615,7 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
        struct i2400m *i2400m = &i2400mu->i2400m;
 
 #ifdef CONFIG_PM
-       if (pm_msg.event & PM_EVENT_AUTO)
+       if (PMSG_IS_AUTO(pm_msg))
                is_autosuspend = 1;
 #endif
 
index e1b3e3c134fdfaeccbd2f575734fa9754b9660e6..ac1176a4f4656fd31ed143a5638a53627a8b94ba 100644 (file)
@@ -2754,7 +2754,7 @@ static const struct net_device_ops airo_netdev_ops = {
        .ndo_stop               = airo_close,
        .ndo_start_xmit         = airo_start_xmit,
        .ndo_get_stats          = airo_get_stats,
-       .ndo_set_multicast_list = airo_set_multicast_list,
+       .ndo_set_rx_mode        = airo_set_multicast_list,
        .ndo_set_mac_address    = airo_set_mac_address,
        .ndo_do_ioctl           = airo_ioctl,
        .ndo_change_mtu         = airo_change_mtu,
@@ -2766,7 +2766,7 @@ static const struct net_device_ops mpi_netdev_ops = {
        .ndo_stop               = airo_close,
        .ndo_start_xmit         = mpi_start_xmit,
        .ndo_get_stats          = airo_get_stats,
-       .ndo_set_multicast_list = airo_set_multicast_list,
+       .ndo_set_rx_mode        = airo_set_multicast_list,
        .ndo_set_mac_address    = airo_set_mac_address,
        .ndo_do_ioctl           = airo_ioctl,
        .ndo_change_mtu         = airo_change_mtu,
index d1b23067619ffb76649b1e7dfd43f7b20459c497..073548836413453c8a646c24ab863277147d4780 100644 (file)
@@ -25,5 +25,6 @@ config ATH_DEBUG
 source "drivers/net/wireless/ath/ath5k/Kconfig"
 source "drivers/net/wireless/ath/ath9k/Kconfig"
 source "drivers/net/wireless/ath/carl9170/Kconfig"
+source "drivers/net/wireless/ath/ath6kl/Kconfig"
 
 endif
index 0e8f528c81c06834a8a6e5e6b0145aecd8257a5e..d1214696a35b89411d3d62642032b496b2419415 100644 (file)
@@ -1,6 +1,7 @@
 obj-$(CONFIG_ATH5K)            += ath5k/
 obj-$(CONFIG_ATH9K_HW)         += ath9k/
 obj-$(CONFIG_CARL9170)         += carl9170/
+obj-$(CONFIG_ATH6KL)           += ath6kl/
 
 obj-$(CONFIG_ATH_COMMON)       += ath.o
 
index a2a167363dbfcb7fe8634db1ea7eb192fdea1fa6..e5be7e701816bb7e40c277e1ed884e91d52663c5 100644 (file)
@@ -169,7 +169,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
                        __set_bit(ATH_STAT_2G_DISABLED, ah->status);
        }
 
-       ret = ath5k_init_softc(ah, &ath_ahb_bus_ops);
+       ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
        if (ret != 0) {
                dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
                ret = -ENODEV;
@@ -214,7 +214,7 @@ static int ath_ahb_remove(struct platform_device *pdev)
                __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
        }
 
-       ath5k_deinit_softc(ah);
+       ath5k_deinit_ah(ah);
        platform_set_drvdata(pdev, NULL);
        ieee80211_free_hw(hw);
 
index 603ae15f139b3286bba0bfe72c769901bed179e9..bea90e6be70e07b2fb6afdb075dd58baa40f5727 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include "ath5k.h"
-#include "base.h"
 #include "reg.h"
 #include "debug.h"
 #include "ani.h"
index 0340153970933af5756f2af69995824a6be92e28..7358b6c83c6c219430f15fc47965bb34617de68f 100644 (file)
 #ifndef ANI_H
 #define ANI_H
 
+#include "../ath.h"
+
+enum ath5k_phy_error_code;
+
 /* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */
 #define ATH5K_ANI_LISTEN_PERIOD                100
 #define ATH5K_ANI_OFDM_TRIG_HIGH       500
index 277d5cbe00687a84df5b2759c007fd9b0e120cc7..fecbcd9a4259c87987da0b5cf2021bb8827cadb6 100644 (file)
 #define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)                        \
        ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
 
-/* Access to PHY registers */
-#define AR5K_PHY_READ(ah, _reg)                                        \
-       ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
-
-#define AR5K_PHY_WRITE(ah, _reg, _val)                                 \
-       ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
-
 /* Access QCU registers per queue */
 #define AR5K_REG_READ_Q(ah, _reg, _queue)                              \
        (ath5k_hw_reg_read(ah, _reg) & (1 << _queue))                   \
 #define AR5K_TUNE_DMA_BEACON_RESP              2
 #define AR5K_TUNE_SW_BEACON_RESP               10
 #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF      0
-#define AR5K_TUNE_RADAR_ALERT                  false
 #define AR5K_TUNE_MIN_TX_FIFO_THRES            1
 #define AR5K_TUNE_MAX_TX_FIFO_THRES    ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
 #define AR5K_TUNE_REGISTER_TIMEOUT             20000
@@ -295,17 +287,6 @@ enum ath5k_radio {
  * Common silicon revision/version values
  */
 
-enum ath5k_srev_type {
-       AR5K_VERSION_MAC,
-       AR5K_VERSION_RAD,
-};
-
-struct ath5k_srev_name {
-       const char              *sr_name;
-       enum ath5k_srev_type    sr_type;
-       u_int                   sr_val;
-};
-
 #define AR5K_SREV_UNKNOWN      0xffff
 
 #define AR5K_SREV_AR5210       0x00 /* Crete */
@@ -424,7 +405,6 @@ enum ath5k_driver_mode {
        AR5K_MODE_11A           =       0,
        AR5K_MODE_11B           =       1,
        AR5K_MODE_11G           =       2,
-       AR5K_MODE_XR            =       0,
        AR5K_MODE_MAX           =       3
 };
 
@@ -694,33 +674,6 @@ struct ath5k_gain {
 #define AR5K_SLOT_TIME_20      880
 #define AR5K_SLOT_TIME_MAX     0xffff
 
-/* channel_flags */
-#define        CHANNEL_CW_INT  0x0008  /* Contention Window interference detected */
-#define        CHANNEL_CCK     0x0020  /* CCK channel */
-#define        CHANNEL_OFDM    0x0040  /* OFDM channel */
-#define        CHANNEL_2GHZ    0x0080  /* 2GHz channel. */
-#define        CHANNEL_5GHZ    0x0100  /* 5GHz channel */
-#define        CHANNEL_PASSIVE 0x0200  /* Only passive scan allowed */
-#define        CHANNEL_DYN     0x0400  /* Dynamic CCK-OFDM channel (for g operation) */
-#define        CHANNEL_XR      0x0800  /* XR channel */
-
-#define        CHANNEL_A       (CHANNEL_5GHZ | CHANNEL_OFDM)
-#define        CHANNEL_B       (CHANNEL_2GHZ | CHANNEL_CCK)
-#define        CHANNEL_G       (CHANNEL_2GHZ | CHANNEL_OFDM)
-#define        CHANNEL_X       (CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_XR)
-
-#define        CHANNEL_ALL     (CHANNEL_OFDM | CHANNEL_CCK | \
-                        CHANNEL_2GHZ | CHANNEL_5GHZ)
-
-#define CHANNEL_MODES          CHANNEL_ALL
-
-/*
- * Used internally for ath5k_hw_reset_tx_queue().
- * Also see struct struct ieee80211_channel.
- */
-#define IS_CHAN_XR(_c) ((_c->hw_value & CHANNEL_XR) != 0)
-#define IS_CHAN_B(_c)  ((_c->hw_value & CHANNEL_B) != 0)
-
 /*
  * The following structure is used to map 2GHz channels to
  * 5GHz Atheros channels.
@@ -977,7 +930,7 @@ enum ath5k_power_mode {
 struct ath5k_capabilities {
        /*
         * Supported PHY modes
-        * (ie. CHANNEL_A, CHANNEL_B, ...)
+        * (ie. AR5K_MODE_11A, AR5K_MODE_11B, ...)
         */
        DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
 
@@ -1013,16 +966,6 @@ struct ath5k_nfcal_hist {
        s16 nfval[ATH5K_NF_CAL_HIST_MAX];       /* last few noise floors */
 };
 
-/**
- * struct avg_val - Helper structure for average calculation
- * @avg: contains the actual average value
- * @avg_weight: is used internally during calculation to prevent rounding errors
- */
-struct ath5k_avg_val {
-       int avg;
-       int avg_weight;
-};
-
 #define ATH5K_LED_MAX_NAME_LEN 31
 
 /*
@@ -1148,7 +1091,6 @@ struct ath5k_hw {
        bool                    rx_pending;     /* rx tasklet pending */
        bool                    tx_pending;     /* tx tasklet pending */
 
-       u8                      lladdr[ETH_ALEN];
        u8                      bssidmask[ETH_ALEN];
 
        unsigned int            led_pin,        /* GPIO pin for driving LED */
@@ -1156,7 +1098,6 @@ struct ath5k_hw {
 
        struct work_struct      reset_work;     /* deferred chip reset */
 
-       unsigned int            rxbufsize;      /* rx size based on mtu */
        struct list_head        rxbuf;          /* receive buffer */
        spinlock_t              rxbuflock;
        u32                     *rxlink;        /* link ptr in last RX desc */
@@ -1208,10 +1149,8 @@ struct ath5k_hw {
 
        enum ath5k_version      ah_version;
        enum ath5k_radio        ah_radio;
-       u32                     ah_phy;
        u32                     ah_mac_srev;
        u16                     ah_mac_version;
-       u16                     ah_mac_revision;
        u16                     ah_phy_revision;
        u16                     ah_radio_5ghz_revision;
        u16                     ah_radio_2ghz_revision;
@@ -1279,12 +1218,6 @@ struct ath5k_hw {
                bool            txp_setup;
        } ah_txpower;
 
-       struct {
-               bool            r_enabled;
-               int             r_last_alert;
-               struct ieee80211_channel r_last_channel;
-       } ah_radar;
-
        struct ath5k_nfcal_hist ah_nfcal_hist;
 
        /* average beacon RSSI in our BSS (used by ANI) */
@@ -1327,36 +1260,13 @@ struct ath_bus_ops {
 extern const struct ieee80211_ops ath5k_hw_ops;
 
 /* Initialization and detach functions */
-int ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
-void ath5k_deinit_softc(struct ath5k_hw *ah);
 int ath5k_hw_init(struct ath5k_hw *ah);
 void ath5k_hw_deinit(struct ath5k_hw *ah);
 
 int ath5k_sysfs_register(struct ath5k_hw *ah);
 void ath5k_sysfs_unregister(struct ath5k_hw *ah);
 
-/* base.c */
-struct ath5k_buf;
-struct ath5k_txq;
-
-void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
-bool ath5k_any_vif_assoc(struct ath5k_hw *ah);
-void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-                   struct ath5k_txq *txq);
-int ath5k_start(struct ieee80211_hw *hw);
-void ath5k_stop(struct ieee80211_hw *hw);
-void ath5k_mode_setup(struct ath5k_hw *ah, struct ieee80211_vif *vif);
-void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
-                                       struct ieee80211_vif *vif);
-int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
-void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf);
-int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-void ath5k_beacon_config(struct ath5k_hw *ah);
-void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
-void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
-
 /*Chip id helper functions */
-const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 int ath5k_hw_read_srev(struct ath5k_hw *ah);
 
 /* LED functions */
@@ -1367,7 +1277,7 @@ void ath5k_unregister_leds(struct ath5k_hw *ah);
 
 
 /* Reset Functions */
-int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel);
 int ath5k_hw_on_hold(struct ath5k_hw *ah);
 int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
           struct ieee80211_channel *channel, bool fast, bool skip_pcu);
@@ -1487,13 +1397,13 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
 
 /* PHY functions */
 /* Misc PHY functions */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band);
 int ath5k_hw_phy_disable(struct ath5k_hw *ah);
 /* Gain_F optimization */
 enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
 int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
 /* PHY/RF channel functions */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
+bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel);
 /* PHY calibration */
 void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
 int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
index f8a6b380d96da77053beca25bd9cf307bbc7f57c..91627dd2c26a175ceb6c7168267f1f2e135d2772 100644 (file)
@@ -25,7 +25,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 /**
  * ath5k_hw_post - Power On Self Test helper function
@@ -95,7 +94,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
 /**
  * ath5k_hw_init - Check if hw is supported and init the needed structs
  *
- * @ah: The &struct ath5k_hw we got from the driver's init_softc function
+ * @ah: The &struct ath5k_hw associated with the device
  *
  * Check if the device is supported, perform a POST and initialize the needed
  * structs. Returns -ENOMEM if we don't have memory for the needed structs,
@@ -114,7 +113,6 @@ int ath5k_hw_init(struct ath5k_hw *ah)
        /*
         * HW information
         */
-       ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
        ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
        ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
        ah->ah_imr = 0;
@@ -137,9 +135,8 @@ int ath5k_hw_init(struct ath5k_hw *ah)
        else
                ah->ah_version = AR5K_AR5212;
 
-       /* Get the MAC revision */
+       /* Get the MAC version */
        ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
-       ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
 
        /* Fill the ath5k_hw struct with the needed functions */
        ret = ath5k_hw_init_desc_functions(ah);
@@ -147,7 +144,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
                goto err;
 
        /* Bring device out of sleep and reset its units */
-       ret = ath5k_hw_nic_wakeup(ah, 0, true);
+       ret = ath5k_hw_nic_wakeup(ah, NULL);
        if (ret)
                goto err;
 
@@ -155,8 +152,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
        ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
                        0xffffffff;
        ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
-                       CHANNEL_5GHZ);
-       ah->ah_phy = AR5K_PHY(0);
+                       IEEE80211_BAND_5GHZ);
 
        /* Try to identify radio chip based on its srev */
        switch (ah->ah_radio_5ghz_revision & 0xf0) {
@@ -164,14 +160,14 @@ int ath5k_hw_init(struct ath5k_hw *ah)
                ah->ah_radio = AR5K_RF5111;
                ah->ah_single_chip = false;
                ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                       CHANNEL_2GHZ);
+                                                       IEEE80211_BAND_2GHZ);
                break;
        case AR5K_SREV_RAD_5112:
        case AR5K_SREV_RAD_2112:
                ah->ah_radio = AR5K_RF5112;
                ah->ah_single_chip = false;
                ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                       CHANNEL_2GHZ);
+                                                       IEEE80211_BAND_2GHZ);
                break;
        case AR5K_SREV_RAD_2413:
                ah->ah_radio = AR5K_RF2413;
@@ -208,7 +204,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
                        ah->ah_radio = AR5K_RF5111;
                        ah->ah_single_chip = false;
                        ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                               CHANNEL_2GHZ);
+                                                       IEEE80211_BAND_2GHZ);
                } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
                           ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
                           ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
index c3119a6caaceb2789feb6a1854703e7d54b6dbaa..e9ea38d0fff604359728103ad9051c5ba3e662a8 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/etherdevice.h>
+#include <linux/nl80211.h>
 
 #include <net/ieee80211_radiotap.h>
 
@@ -61,6 +62,8 @@
 #include "reg.h"
 #include "debug.h"
 #include "ani.h"
+#include "ath5k.h"
+#include "../regd.h"
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -272,20 +275,18 @@ static unsigned int
 ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
                unsigned int mode, unsigned int max)
 {
-       unsigned int count, size, chfreq, freq, ch;
+       unsigned int count, size, freq, ch;
        enum ieee80211_band band;
 
        switch (mode) {
        case AR5K_MODE_11A:
                /* 1..220, but 2GHz frequencies are filtered by check_channel */
                size = 220;
-               chfreq = CHANNEL_5GHZ;
                band = IEEE80211_BAND_5GHZ;
                break;
        case AR5K_MODE_11B:
        case AR5K_MODE_11G:
                size = 26;
-               chfreq = CHANNEL_2GHZ;
                band = IEEE80211_BAND_2GHZ;
                break;
        default:
@@ -300,26 +301,19 @@ ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
                if (freq == 0) /* mapping failed - not a standard channel */
                        continue;
 
+               /* Write channel info, needed for ath5k_channel_ok() */
+               channels[count].center_freq = freq;
+               channels[count].band = band;
+               channels[count].hw_value = mode;
+
                /* Check if channel is supported by the chipset */
-               if (!ath5k_channel_ok(ah, freq, chfreq))
+               if (!ath5k_channel_ok(ah, &channels[count]))
                        continue;
 
                if (!modparam_all_channels &&
                    !ath5k_is_standard_channel(ch, band))
                        continue;
 
-               /* Write channel info and increment counter */
-               channels[count].center_freq = freq;
-               channels[count].band = band;
-               switch (mode) {
-               case AR5K_MODE_11A:
-               case AR5K_MODE_11G:
-                       channels[count].hw_value = chfreq | CHANNEL_OFDM;
-                       break;
-               case AR5K_MODE_11B:
-                       channels[count].hw_value = CHANNEL_B;
-               }
-
                count++;
        }
 
@@ -2349,7 +2343,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
 \*************************/
 
 int __devinit
-ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
+ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
 {
        struct ieee80211_hw *hw = ah->hw;
        struct ath_common *common;
@@ -2867,7 +2861,6 @@ ath5k_init(struct ieee80211_hw *hw)
        }
 
        SET_IEEE80211_PERM_ADDR(hw, mac);
-       memcpy(&ah->lladdr, mac, ETH_ALEN);
        /* All MAC address bits matter for ACKs */
        ath5k_update_bssid_mask_and_opmode(ah, NULL);
 
@@ -2903,7 +2896,7 @@ err:
 }
 
 void
-ath5k_deinit_softc(struct ath5k_hw *ah)
+ath5k_deinit_ah(struct ath5k_hw *ah)
 {
        struct ieee80211_hw *hw = ah->hw;
 
index a81f28d5bddc59ab0952a2d4776e18fa342dbcba..6c94c7ff23500abaf5aceed394e0ddb7c381468a 100644 (file)
 /*
  * Definitions for the Atheros Wireless LAN controller driver.
  */
-#ifndef _DEV_ATH_ATHVAR_H
-#define _DEV_ATH_ATHVAR_H
+#ifndef _DEV_ATH5K_BASE_H
+#define _DEV_ATH5K_BASE_H
 
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/wireless.h>
-#include <linux/if_ether.h>
-#include <linux/rfkill.h>
-#include <linux/workqueue.h>
+struct ieee80211_vif;
+struct ieee80211_hw;
+struct ath5k_hw;
+struct ath5k_txq;
+struct ieee80211_channel;
+struct ath_bus_ops;
+enum nl80211_iftype;
 
-#include "ath5k.h"
-#include "../regd.h"
-#include "../ath.h"
+enum ath5k_srev_type {
+       AR5K_VERSION_MAC,
+       AR5K_VERSION_RAD,
+};
+
+struct ath5k_srev_name {
+       const char              *sr_name;
+       enum ath5k_srev_type    sr_type;
+       u_int                   sr_val;
+};
 
 struct ath5k_buf {
        struct list_head        list;
@@ -65,7 +73,6 @@ struct ath5k_vif {
        enum nl80211_iftype     opmode;
        int                     bslot;
        struct ath5k_buf        *bbuf; /* beacon buffer */
-       u8                      lladdr[ETH_ALEN];
 };
 
 struct ath5k_vif_iter_data {
@@ -78,8 +85,30 @@ struct ath5k_vif_iter_data {
        enum nl80211_iftype opmode;
        int n_stas;
 };
+
 void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif);
+bool ath5k_any_vif_assoc(struct ath5k_hw *ah);
+
+int ath5k_start(struct ieee80211_hw *hw);
+void ath5k_stop(struct ieee80211_hw *hw);
+
+void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf);
+int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void ath5k_beacon_config(struct ath5k_hw *ah);
+void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
+
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
+                                       struct ieee80211_vif *vif);
+int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
+void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
+void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
+void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+                   struct ath5k_txq *txq);
+
+const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 
+int ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
+void ath5k_deinit_ah(struct ath5k_hw *ah);
 
 /* Check whether BSSID mask is supported */
 #define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212)
@@ -87,4 +116,4 @@ void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif);
 /* Check whether virtual EOL is supported */
 #define ath5k_hw_hasveol(_ah) (ah->ah_version != AR5K_AR5210)
 
-#endif
+#endif /* _DEV_ATH5K_BASE_H */
index eefe670e28a7e11641c1676a952615fd443bd031..810fba96702bd074150f5255dff1e60131f735a3 100644 (file)
@@ -24,7 +24,7 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
+#include "../regd.h"
 
 /*
  * Fill the capabilities struct
index ccca724de17328c6e86e0e7b195127314df39d2b..fce8c904eea9e70e2656c0b0d9d8f9ddc65d4033 100644 (file)
  * THE POSSIBILITY OF SUCH DAMAGES.
  */
 
-#include "base.h"
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/list.h>
 #include "debug.h"
+#include "ath5k.h"
+#include "reg.h"
+#include "base.h"
 
 static unsigned int ath5k_debug;
 module_param_named(debug, ath5k_debug, uint, 0);
 
 
-#ifdef CONFIG_ATH5K_DEBUG
-
-#include <linux/seq_file.h>
-#include "reg.h"
-#include "ani.h"
-
 static int ath5k_debugfs_open(struct inode *inode, struct file *file)
 {
        file->private_data = inode->i_private;
@@ -1031,5 +1030,3 @@ ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf)
                td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
                done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
 }
-
-#endif /* ifdef CONFIG_ATH5K_DEBUG */
index 846535f59efc54308008eed1df39314266efcd24..7e88dda82221de885efd881f902f6aded91b10e2 100644 (file)
@@ -24,7 +24,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 
 /************************\
index 0d5d4033f12a6c475ae8620ee6bb91abdfcf2703..2481f9c7f4b66c1f46bd47907e1123de56440cb5 100644 (file)
@@ -35,7 +35,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 
 /*********\
index 9068b91652656e4c46e049ed76e202fa199d61a3..cd708c15b77470a53b325e8856a003fc67ad1eaf 100644 (file)
@@ -26,7 +26,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 
 /******************\
@@ -1780,13 +1779,12 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
 int
 ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
 {
-       switch (channel->hw_value & CHANNEL_MODES) {
-       case CHANNEL_A:
-       case CHANNEL_XR:
+       switch (channel->hw_value) {
+       case AR5K_MODE_11A:
                return AR5K_EEPROM_MODE_11A;
-       case CHANNEL_G:
+       case AR5K_MODE_11G:
                return AR5K_EEPROM_MODE_11G;
-       case CHANNEL_B:
+       case AR5K_MODE_11B:
                return AR5K_EEPROM_MODE_11B;
        default:
                return -1;
index bc90503f4b7a9676db2c21dc2ff0dfa5177181c8..8592978119148eba00afcdc1b74e304ff95cf0f5 100644 (file)
@@ -23,7 +23,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 /*
  * Set led state
index 5ab607f40e0e2ad6044472db3e1c90d4a482fb5d..1ffecc0fd3edac5238426bbea33addfe105674f9 100644 (file)
@@ -22,7 +22,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 /*
  * Mode-independent initial register writes
index 8c17a00f7dad64ccd3756f54566b9dc187749820..c1151c72371105aaf19a520334cd2cca854fe45c 100644 (file)
@@ -41,7 +41,6 @@
 
 #include <linux/pci.h>
 #include "ath5k.h"
-#include "base.h"
 
 #define ATH_SDEVICE(subv, subd) \
        .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
index 2a715ca0c5e4f1efddc1f1f0f70c3fe5a9060f7d..0560234ec3f648603e5159dc1f2aa3d9e6425df0 100644 (file)
  *
  */
 
+#include <net/mac80211.h>
 #include <asm/unaligned.h>
 
+#include "ath5k.h"
 #include "base.h"
 #include "reg.h"
 
@@ -137,11 +139,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        /* Any MAC address is fine, all others are included through the
         * filter.
         */
-       memcpy(&ah->lladdr, vif->addr, ETH_ALEN);
        ath5k_hw_set_lladdr(ah, vif->addr);
 
-       memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
-
        ath5k_update_bssid_mask_and_opmode(ah, vif);
        ret = 0;
 end:
index eaf79b49341e3dab89ee95e2ab6bddac8a058ef4..c1dff2ced0446b0869a4c226b66e2deb1404d970 100644 (file)
@@ -261,7 +261,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
        ah->iobase = mem; /* So we can unmap it on detach */
 
        /* Initialize */
-       ret = ath5k_init_softc(ah, &ath_pci_bus_ops);
+       ret = ath5k_init_ah(ah, &ath_pci_bus_ops);
        if (ret)
                goto err_free;
 
@@ -287,7 +287,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
        struct ath5k_hw *ah = hw->priv;
 
-       ath5k_deinit_softc(ah);
+       ath5k_deinit_ah(ah);
        pci_iounmap(pdev, ah->iobase);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
index 067313845060ed9d0aa15b01c035011cb0917da6..a7eafa3edc211127fa48f0d4270bbf2f3b62bf34 100644 (file)
@@ -29,7 +29,6 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 /*
  * AR5212+ can use higher rates for ack transmission
@@ -152,7 +151,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
        case AR5K_BWMODE_DEFAULT:
        default:
                slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
-               if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot)
+               if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot)
                        slot_time = AR5K_INIT_SLOT_TIME_B;
                break;
        }
@@ -183,7 +182,7 @@ unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
        case AR5K_BWMODE_DEFAULT:
                sifs = AR5K_INIT_SIFS_DEFAULT_BG;
        default:
-               if (channel->hw_value & CHANNEL_5GHZ)
+               if (channel->band == IEEE80211_BAND_5GHZ)
                        sifs = AR5K_INIT_SIFS_DEFAULT_A;
                break;
        }
index 81e465e7017546c30e49056e3cf036c3101686b7..01cb72de44cbe675425e4ecf3a8ec0c7427d9c01 100644 (file)
@@ -26,9 +26,9 @@
 
 #include "ath5k.h"
 #include "reg.h"
-#include "base.h"
 #include "rfbuffer.h"
 #include "rfgain.h"
+#include "../regd.h"
 
 
 /******************\
@@ -38,7 +38,7 @@
 /*
  * Get the PHY Chip revision
  */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
 {
        unsigned int i;
        u32 srev;
@@ -47,11 +47,11 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
        /*
         * Set the radio chip access register
         */
-       switch (chan) {
-       case CHANNEL_2GHZ:
+       switch (band) {
+       case IEEE80211_BAND_2GHZ:
                ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
                break;
-       case CHANNEL_5GHZ:
+       case IEEE80211_BAND_5GHZ:
                ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
                break;
        default:
@@ -84,14 +84,16 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
 /*
  * Check if a channel is supported
  */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
+bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 {
+       u16 freq = channel->center_freq;
+
        /* Check if the channel is in our supported range */
-       if (flags & CHANNEL_2GHZ) {
+       if (channel->band == IEEE80211_BAND_2GHZ) {
                if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
                    (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
                        return true;
-       } else if (flags & CHANNEL_5GHZ)
+       } else if (channel->band == IEEE80211_BAND_5GHZ)
                if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
                    (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
                        return true;
@@ -224,7 +226,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
                ds_coef_exp, ds_coef_man, clock;
 
        BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
-               !(channel->hw_value & CHANNEL_OFDM));
+               (channel->hw_value == AR5K_MODE_11B));
 
        /* Get coefficient
         * ALGO: coef = (5 * clock / carrier_freq) / 2
@@ -298,7 +300,7 @@ static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
                u32 delay;
                delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
                        AR5K_PHY_RX_DELAY_M;
-               delay = (channel->hw_value & CHANNEL_CCK) ?
+               delay = (channel->hw_value == AR5K_MODE_11B) ?
                        ((delay << 2) / 22) : (delay / 10);
                if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
                        delay = delay << 1;
@@ -798,9 +800,9 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
        }
 
        /* Set Output and Driver bias current (OB/DB) */
-       if (channel->hw_value & CHANNEL_2GHZ) {
+       if (channel->band == IEEE80211_BAND_2GHZ) {
 
-               if (channel->hw_value & CHANNEL_CCK)
+               if (channel->hw_value == AR5K_MODE_11B)
                        ee_mode = AR5K_EEPROM_MODE_11B;
                else
                        ee_mode = AR5K_EEPROM_MODE_11G;
@@ -825,7 +827,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
                                                AR5K_RF_DB_2GHZ, true);
 
        /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
-       } else if ((channel->hw_value & CHANNEL_5GHZ) ||
+       } else if ((channel->band == IEEE80211_BAND_5GHZ) ||
                        (ah->ah_radio == AR5K_RF5111)) {
 
                /* For 11a, Turbo and XR we need to choose
@@ -857,7 +859,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
        if (ah->ah_radio == AR5K_RF5111) {
 
                /* Set gain_F settings according to current step */
-               if (channel->hw_value & CHANNEL_OFDM) {
+               if (channel->hw_value != AR5K_MODE_11B) {
 
                        AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
                                        AR5K_PHY_FRAME_CTL_TX_CLIP,
@@ -914,7 +916,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
        if (ah->ah_radio == AR5K_RF5112) {
 
                /* Set gain_F settings according to current step */
-               if (channel->hw_value & CHANNEL_OFDM) {
+               if (channel->hw_value != AR5K_MODE_11B) {
 
                        ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
                                                AR5K_RF_MIXGAIN_OVR, true);
@@ -1026,7 +1028,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
        }
 
        if (ah->ah_radio == AR5K_RF5413 &&
-       channel->hw_value & CHANNEL_2GHZ) {
+       channel->band == IEEE80211_BAND_2GHZ) {
 
                ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
                                                                        true);
@@ -1138,7 +1140,7 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
         */
        data0 = data1 = 0;
 
-       if (channel->hw_value & CHANNEL_2GHZ) {
+       if (channel->band == IEEE80211_BAND_2GHZ) {
                /* Map 2GHz channel to 5GHz Atheros channel ID */
                ret = ath5k_hw_rf5111_chan2athchan(
                        ieee80211_frequency_to_channel(channel->center_freq),
@@ -1265,10 +1267,9 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
        int ret;
        /*
         * Check bounds supported by the PHY (we don't care about regulatory
-        * restrictions at this point). Note: hw_value already has the band
-        * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
-        * of the band by that */
-       if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
+        * restrictions at this point).
+        */
+       if (!ath5k_channel_ok(ah, channel)) {
                ATH5K_ERR(ah,
                        "channel frequency (%u MHz) out of supported "
                        "band range\n",
@@ -1614,7 +1615,7 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
        ret = ath5k_hw_rf511x_iq_calibrate(ah);
 
        if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) &&
-           (channel->hw_value & CHANNEL_OFDM))
+           (channel->hw_value != AR5K_MODE_11B))
                ath5k_hw_request_rfgain_probe(ah);
 
        return ret;
@@ -1641,7 +1642,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
        /* Convert current frequency to fbin value (the same way channels
         * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale
         * up by 2 so we can compare it later */
-       if (channel->hw_value & CHANNEL_2GHZ) {
+       if (channel->band == IEEE80211_BAND_2GHZ) {
                chan_fbin = (channel->center_freq - 2300) * 10;
                freq_band = AR5K_EEPROM_BAND_2GHZ;
        } else {
@@ -1703,7 +1704,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
                        spur_freq_sigma_delta = (spur_delta_phase >> 10);
                        symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
                default:
-                       if (channel->hw_value == CHANNEL_A) {
+                       if (channel->band == IEEE80211_BAND_5GHZ) {
                                /* Both sample_freq and chip_freq are 40MHz */
                                spur_delta_phase = (spur_offset << 17) / 25;
                                spur_freq_sigma_delta =
@@ -2226,15 +2227,20 @@ ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
        idx_l = 0;
        idx_r = 0;
 
-       if (!(channel->hw_value & CHANNEL_OFDM)) {
+       switch (channel->hw_value) {
+       case AR5K_EEPROM_MODE_11A:
+               pcinfo = ee->ee_pwr_cal_a;
+               mode = AR5K_EEPROM_MODE_11A;
+               break;
+       case AR5K_EEPROM_MODE_11B:
                pcinfo = ee->ee_pwr_cal_b;
                mode = AR5K_EEPROM_MODE_11B;
-       } else if (channel->hw_value & CHANNEL_2GHZ) {
+               break;
+       case AR5K_EEPROM_MODE_11G:
+       default:
                pcinfo = ee->ee_pwr_cal_g;
                mode = AR5K_EEPROM_MODE_11G;
-       } else {
-               pcinfo = ee->ee_pwr_cal_a;
-               mode = AR5K_EEPROM_MODE_11A;
+               break;
        }
        max = ee->ee_n_piers[mode] - 1;
 
@@ -2303,15 +2309,20 @@ ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
        idx_l = 0;
        idx_r = 0;
 
-       if (!(channel->hw_value & CHANNEL_OFDM)) {
+       switch (channel->hw_value) {
+       case AR5K_MODE_11A:
+               rpinfo = ee->ee_rate_tpwr_a;
+               mode = AR5K_EEPROM_MODE_11A;
+               break;
+       case AR5K_MODE_11B:
                rpinfo = ee->ee_rate_tpwr_b;
                mode = AR5K_EEPROM_MODE_11B;
-       } else if (channel->hw_value & CHANNEL_2GHZ) {
+               break;
+       case AR5K_MODE_11G:
+       default:
                rpinfo = ee->ee_rate_tpwr_g;
                mode = AR5K_EEPROM_MODE_11G;
-       } else {
-               rpinfo = ee->ee_rate_tpwr_a;
-               mode = AR5K_EEPROM_MODE_11A;
+               break;
        }
        max = ee->ee_rate_target_pwr_num[mode] - 1;
 
@@ -2392,24 +2403,22 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
 
        ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
 
-       switch (channel->hw_value & CHANNEL_MODES) {
-       case CHANNEL_A:
+       switch (channel->hw_value) {
+       case AR5K_MODE_11A:
                if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
                        ctl_mode |= AR5K_CTL_TURBO;
                else
                        ctl_mode |= AR5K_CTL_11A;
                break;
-       case CHANNEL_G:
+       case AR5K_MODE_11G:
                if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
                        ctl_mode |= AR5K_CTL_TURBOG;
                else
                        ctl_mode |= AR5K_CTL_11G;
                break;
-       case CHANNEL_B:
+       case AR5K_MODE_11B:
                ctl_mode |= AR5K_CTL_11B;
                break;
-       case CHANNEL_XR:
-               /* Fall through */
        default:
                return;
        }
@@ -3292,7 +3301,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 
        /* Write OFDM timings on 5212*/
        if (ah->ah_version == AR5K_AR5212 &&
-               channel->hw_value & CHANNEL_OFDM) {
+               channel->hw_value != AR5K_MODE_11B) {
 
                ret = ath5k_hw_write_ofdm_timings(ah, channel);
                if (ret)
index 65f10398999e5813e33e1257fa0e1f729ece7e80..776654228eaab7cc4ba7beac04fa52b2930313ca 100644 (file)
@@ -23,7 +23,6 @@ Queue Control Unit, DFS Control Unit Functions
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
-#include "base.h"
 
 
 /******************\
@@ -185,13 +184,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
                case AR5K_TX_QUEUE_CAB:
                        queue = AR5K_TX_QUEUE_ID_CAB;
                        break;
-               case AR5K_TX_QUEUE_XR_DATA:
-                       if (ah->ah_version != AR5K_AR5212)
-                               ATH5K_ERR(ah,
-                                       "XR data queues only supported in"
-                                       " 5212!\n");
-                       queue = AR5K_TX_QUEUE_ID_XR_DATA;
-                       break;
                default:
                        return -EINVAL;
                }
@@ -544,7 +536,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
         *
         * Also we have different lowest rate for 802.11a
         */
-       if (channel->hw_value & CHANNEL_5GHZ)
+       if (channel->band == IEEE80211_BAND_5GHZ)
                rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
        else
                rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
index 0686c5d8d56e612de885b989fc6a38ef238fa9ff..2abac257b4b460ede4c6a46f44986d23bdf28084 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/platform_device.h>
 #include "ath5k.h"
 #include "reg.h"
-#include "base.h"
 #include "debug.h"
 
 
@@ -102,12 +101,18 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
        /*
         * Set core clock frequency
         */
-       if (channel->hw_value & CHANNEL_5GHZ)
-               clock = 40; /* 802.11a */
-       else if (channel->hw_value & CHANNEL_CCK)
-               clock = 22; /* 802.11b */
-       else
-               clock = 44; /* 802.11g */
+       switch (channel->hw_value) {
+       case AR5K_MODE_11A:
+               clock = 40;
+               break;
+       case AR5K_MODE_11B:
+               clock = 22;
+               break;
+       case AR5K_MODE_11G:
+       default:
+               clock = 44;
+               break;
+       }
 
        /* Use clock multiplier for non-default
         * bwmode */
@@ -581,8 +586,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
 
 /*
  * Bring up MAC + PHY Chips and program PLL
+ * Channel is NULL for the initial wakeup.
  */
-int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 {
        struct pci_dev *pdev = ah->pdev;
        u32 turbo, mode, clock, bus_flags;
@@ -592,7 +598,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
        mode = 0;
        clock = 0;
 
-       if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) {
+       if ((ath5k_get_bus_type(ah) != ATH_AHB) || channel) {
                /* Wakeup the device */
                ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
                if (ret) {
@@ -652,7 +658,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 
        /* On initialization skip PLL programming since we don't have
         * a channel / mode set yet */
-       if (initial)
+       if (!channel)
                return 0;
 
        if (ah->ah_version != AR5K_AR5210) {
@@ -668,13 +674,13 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                        clock = AR5K_PHY_PLL_RF5111;            /*Zero*/
                }
 
-               if (flags & CHANNEL_2GHZ) {
+               if (channel->band == IEEE80211_BAND_2GHZ) {
                        mode |= AR5K_PHY_MODE_FREQ_2GHZ;
                        clock |= AR5K_PHY_PLL_44MHZ;
 
-                       if (flags & CHANNEL_CCK) {
+                       if (channel->hw_value == AR5K_MODE_11B) {
                                mode |= AR5K_PHY_MODE_MOD_CCK;
-                       } else if (flags & CHANNEL_OFDM) {
+                       } else {
                                /* XXX Dynamic OFDM/CCK is not supported by the
                                 * AR5211 so we set MOD_OFDM for plain g (no
                                 * CCK headers) operation. We need to test
@@ -686,27 +692,16 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                                        mode |= AR5K_PHY_MODE_MOD_OFDM;
                                else
                                        mode |= AR5K_PHY_MODE_MOD_DYN;
-                       } else {
-                               ATH5K_ERR(ah,
-                                       "invalid radio modulation mode\n");
-                               return -EINVAL;
                        }
-               } else if (flags & CHANNEL_5GHZ) {
-                       mode |= AR5K_PHY_MODE_FREQ_5GHZ;
+               } else if (channel->band == IEEE80211_BAND_5GHZ) {
+                       mode |= (AR5K_PHY_MODE_FREQ_5GHZ |
+                                AR5K_PHY_MODE_MOD_OFDM);
 
                        /* Different PLL setting for 5413 */
                        if (ah->ah_radio == AR5K_RF5413)
                                clock = AR5K_PHY_PLL_40MHZ_5413;
                        else
                                clock |= AR5K_PHY_PLL_40MHZ;
-
-                       if (flags & CHANNEL_OFDM)
-                               mode |= AR5K_PHY_MODE_MOD_OFDM;
-                       else {
-                               ATH5K_ERR(ah,
-                                       "invalid radio modulation mode\n");
-                               return -EINVAL;
-                       }
                } else {
                        ATH5K_ERR(ah, "invalid radio frequency mode\n");
                        return -EINVAL;
@@ -822,7 +817,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
                u32 data;
                ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
                                AR5K_PHY_CCKTXCTL);
-               if (channel->hw_value & CHANNEL_5GHZ)
+               if (channel->band == IEEE80211_BAND_5GHZ)
                        data = 0xffb81020;
                else
                        data = 0xffb80d20;
@@ -905,7 +900,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
        /* Set CCK to OFDM power delta on tx power
         * adjustment register */
        if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
-               if (channel->hw_value == CHANNEL_G)
+               if (channel->hw_value == AR5K_MODE_11G)
                        ath5k_hw_reg_write(ah,
                        AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
                                AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
@@ -1084,37 +1079,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
                ret = 0;
        }
 
-       switch (channel->hw_value & CHANNEL_MODES) {
-       case CHANNEL_A:
-               mode = AR5K_MODE_11A;
+       mode = channel->hw_value;
+       switch (mode) {
+       case AR5K_MODE_11A:
                break;
-       case CHANNEL_G:
-
+       case AR5K_MODE_11G:
                if (ah->ah_version <= AR5K_AR5211) {
                        ATH5K_ERR(ah,
                                "G mode not available on 5210/5211");
                        return -EINVAL;
                }
-
-               mode = AR5K_MODE_11G;
                break;
-       case CHANNEL_B:
-
+       case AR5K_MODE_11B:
                if (ah->ah_version < AR5K_AR5211) {
                        ATH5K_ERR(ah,
                                "B mode not available on 5210");
                        return -EINVAL;
                }
-
-               mode = AR5K_MODE_11B;
-               break;
-       case CHANNEL_XR:
-               if (ah->ah_version == AR5K_AR5211) {
-                       ATH5K_ERR(ah,
-                               "XR mode not available on 5211");
-                       return -EINVAL;
-               }
-               mode = AR5K_MODE_XR;
                break;
        default:
                ATH5K_ERR(ah,
@@ -1200,7 +1181,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
        }
 
        /* Wakeup the device */
-       ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+       ret = ath5k_hw_nic_wakeup(ah, channel);
        if (ret)
                return ret;
 
index 945fc9f21e76253d20960d4e3fb44cf96925e6da..270a319f3aebb903f9d20140f87a3bf57d51f96a 100644 (file)
@@ -33,7 +33,7 @@
  * THE POSSIBILITY OF SUCH DAMAGES.
  */
 
-#include "base.h"
+#include "ath5k.h"
 
 
 static inline void ath5k_rfkill_disable(struct ath5k_hw *ah)
index 0244a36ba958b068129c2224953ce5520977ac02..9364da7bd131dd32d2b6f79715bdff5abf457fab 100644 (file)
@@ -1,7 +1,6 @@
 #include <linux/device.h>
 #include <linux/pci.h>
 
-#include "base.h"
 #include "ath5k.h"
 #include "reg.h"
 
index c741c871f4e9a3cc18786585c5fb1001529a8924..39f002ed4a8803419755c23e55c4de66c33bf29c 100644 (file)
@@ -2,7 +2,6 @@
 #define __TRACE_ATH5K_H
 
 #include <linux/tracepoint.h>
-#include "base.h"
 
 #ifndef CONFIG_ATH5K_TRACER
 #undef TRACE_EVENT
@@ -11,6 +10,8 @@ static inline void trace_ ## name(proto) {}
 #endif
 
 struct sk_buff;
+struct ath5k_txq;
+struct ath5k_tx_status;
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM ath5k
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
new file mode 100644 (file)
index 0000000..3d5f8be
--- /dev/null
@@ -0,0 +1,15 @@
+config ATH6KL
+       tristate "Atheros ath6kl support"
+       depends on MMC
+       depends on CFG80211
+       ---help---
+         This module adds support for wireless adapters based on
+         Atheros AR6003 chipset running over SDIO. If you choose to
+         build it as a module, it will be called ath6kl. Pls note
+         that AR6002 and AR6001 are not supported by this driver.
+
+config ATH6KL_DEBUG
+       bool "Atheros ath6kl debugging"
+       depends on ATH6KL
+       ---help---
+         Enables debug support
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
new file mode 100644 (file)
index 0000000..e1bb07e
--- /dev/null
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# Copyright (c) 2004-2010 Atheros Communications Inc.
+# All rights reserved.
+#
+#
+#
+# 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.
+#
+#
+#
+# Author(s): ="Atheros"
+#------------------------------------------------------------------------------
+
+obj-$(CONFIG_ATH6KL) := ath6kl.o
+ath6kl-y += debug.o
+ath6kl-y += htc_hif.o
+ath6kl-y += htc.o
+ath6kl-y += bmi.o
+ath6kl-y += cfg80211.o
+ath6kl-y += init.o
+ath6kl-y += main.o
+ath6kl-y += txrx.o
+ath6kl-y += wmi.o
+ath6kl-y += node.o
+ath6kl-y += sdio.o
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
new file mode 100644 (file)
index 0000000..8467669
--- /dev/null
@@ -0,0 +1,692 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 "core.h"
+#include "hif-ops.h"
+#include "target.h"
+#include "debug.h"
+
+static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
+{
+       u32 addr;
+       unsigned long timeout;
+       int ret;
+
+       ar->bmi.cmd_credits = 0;
+
+       /* Read the counter register to get the command credits */
+       addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
+
+       timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
+       while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
+
+               /*
+                * Hit the credit counter with a 4-byte access, the first byte
+                * read will hit the counter and cause a decrement, while the
+                * remaining 3 bytes has no effect. The rationale behind this
+                * is to make all HIF accesses 4-byte aligned.
+                */
+               ret = hif_read_write_sync(ar, addr,
+                                        (u8 *)&ar->bmi.cmd_credits, 4,
+                                        HIF_RD_SYNC_BYTE_INC);
+               if (ret) {
+                       ath6kl_err("Unable to decrement the command credit count register: %d\n",
+                                  ret);
+                       return ret;
+               }
+
+               /* The counter is only 8 bits.
+                * Ignore anything in the upper 3 bytes
+                */
+               ar->bmi.cmd_credits &= 0xFF;
+       }
+
+       if (!ar->bmi.cmd_credits) {
+               ath6kl_err("bmi communication timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout)
+{
+       unsigned long timeout;
+       u32 rx_word = 0;
+       int ret = 0;
+
+       timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
+       while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) {
+               ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
+                                         (u8 *)&rx_word, sizeof(rx_word),
+                                         HIF_RD_SYNC_BYTE_INC);
+               if (ret) {
+                       ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
+                       return ret;
+               }
+
+                /* all we really want is one bit */
+               rx_word &= (1 << ENDPOINT1);
+       }
+
+       if (!rx_word) {
+               ath6kl_err("bmi_recv_buf FIFO empty\n");
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
+{
+       int ret;
+       u32 addr;
+
+       ret = ath6kl_get_bmi_cmd_credits(ar);
+       if (ret)
+               return ret;
+
+       addr = ar->mbox_info.htc_addr;
+
+       ret = hif_read_write_sync(ar, addr, buf, len,
+                                 HIF_WR_SYNC_BYTE_INC);
+       if (ret)
+               ath6kl_err("unable to send the bmi data to the device\n");
+
+       return ret;
+}
+
+static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
+                       u8 *buf, u32 len, bool want_timeout)
+{
+       int ret;
+       u32 addr;
+
+       /*
+        * During normal bootup, small reads may be required.
+        * Rather than issue an HIF Read and then wait as the Target
+        * adds successive bytes to the FIFO, we wait here until
+        * we know that response data is available.
+        *
+        * This allows us to cleanly timeout on an unexpected
+        * Target failure rather than risk problems at the HIF level.
+        * In particular, this avoids SDIO timeouts and possibly garbage
+        * data on some host controllers.  And on an interconnect
+        * such as Compact Flash (as well as some SDIO masters) which
+        * does not provide any indication on data timeout, it avoids
+        * a potential hang or garbage response.
+        *
+        * Synchronization is more difficult for reads larger than the
+        * size of the MBOX FIFO (128B), because the Target is unable
+        * to push the 129th byte of data until AFTER the Host posts an
+        * HIF Read and removes some FIFO data.  So for large reads the
+        * Host proceeds to post an HIF Read BEFORE all the data is
+        * actually available to read.  Fortunately, large BMI reads do
+        * not occur in practice -- they're supported for debug/development.
+        *
+        * So Host/Target BMI synchronization is divided into these cases:
+        *  CASE 1: length < 4
+        *        Should not happen
+        *
+        *  CASE 2: 4 <= length <= 128
+        *        Wait for first 4 bytes to be in FIFO
+        *        If CONSERVATIVE_BMI_READ is enabled, also wait for
+        *        a BMI command credit, which indicates that the ENTIRE
+        *        response is available in the the FIFO
+        *
+        *  CASE 3: length > 128
+        *        Wait for the first 4 bytes to be in FIFO
+        *
+        * For most uses, a small timeout should be sufficient and we will
+        * usually see a response quickly; but there may be some unusual
+        * (debug) cases of BMI_EXECUTE where we want an larger timeout.
+        * For now, we use an unbounded busy loop while waiting for
+        * BMI_EXECUTE.
+        *
+        * If BMI_EXECUTE ever needs to support longer-latency execution,
+        * especially in production, this code needs to be enhanced to sleep
+        * and yield.  Also note that BMI_COMMUNICATION_TIMEOUT is currently
+        * a function of Host processor speed.
+        */
+       if (len >= 4) { /* NB: Currently, always true */
+               ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout);
+               if (ret)
+                       return ret;
+       }
+
+       addr = ar->mbox_info.htc_addr;
+       ret = hif_read_write_sync(ar, addr, buf, len,
+                                 HIF_RD_SYNC_BYTE_INC);
+       if (ret) {
+               ath6kl_err("Unable to read the bmi data from the device: %d\n",
+                          ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_done(struct ath6kl *ar)
+{
+       int ret;
+       u32 cid = BMI_DONE;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_dbg(ATH6KL_DBG_BMI, "bmi done skipped\n");
+               return 0;
+       }
+
+       ar->bmi.done_sent = true;
+
+       ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid));
+       if (ret) {
+               ath6kl_err("Unable to send bmi done: %d\n", ret);
+               return ret;
+       }
+
+       ath6kl_bmi_cleanup(ar);
+
+       return 0;
+}
+
+int ath6kl_bmi_get_target_info(struct ath6kl *ar,
+                              struct ath6kl_bmi_target_info *targ_info)
+{
+       int ret;
+       u32 cid = BMI_GET_TARGET_INFO;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid));
+       if (ret) {
+               ath6kl_err("Unable to send get target info: %d\n", ret);
+               return ret;
+       }
+
+       ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
+                       sizeof(targ_info->version), true);
+       if (ret) {
+               ath6kl_err("Unable to recv target info: %d\n", ret);
+               return ret;
+       }
+
+       if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) {
+               /* Determine how many bytes are in the Target's targ_info */
+               ret = ath6kl_bmi_recv_buf(ar,
+                                  (u8 *)&targ_info->byte_count,
+                                  sizeof(targ_info->byte_count),
+                                  true);
+               if (ret) {
+                       ath6kl_err("unable to read target info byte count: %d\n",
+                                  ret);
+                       return ret;
+               }
+
+               /*
+                * The target's targ_info doesn't match the host's targ_info.
+                * We need to do some backwards compatibility to make this work.
+                */
+               if (le32_to_cpu(targ_info->byte_count) != sizeof(*targ_info)) {
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+
+               /* Read the remainder of the targ_info */
+               ret = ath6kl_bmi_recv_buf(ar,
+                                  ((u8 *)targ_info) +
+                                  sizeof(targ_info->byte_count),
+                                  sizeof(*targ_info) -
+                                  sizeof(targ_info->byte_count),
+                                  true);
+
+               if (ret) {
+                       ath6kl_err("Unable to read target info (%d bytes): %d\n",
+                                  targ_info->byte_count, ret);
+                       return ret;
+               }
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n",
+               targ_info->version, targ_info->type);
+
+       return 0;
+}
+
+int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
+{
+       u32 cid = BMI_READ_MEMORY;
+       int ret;
+       u32 offset;
+       u32 len_remain, rx_len;
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = BMI_DATASZ_MAX + sizeof(cid) + sizeof(addr) + sizeof(len);
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI,
+                  "bmi read memory: device: addr: 0x%x, len: %d\n",
+                  addr, len);
+
+       len_remain = len;
+
+       while (len_remain) {
+               rx_len = (len_remain < BMI_DATASZ_MAX) ?
+                                       len_remain : BMI_DATASZ_MAX;
+               offset = 0;
+               memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+               offset += sizeof(cid);
+               memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+               offset += sizeof(addr);
+               memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len));
+               offset += sizeof(len);
+
+               ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+               if (ret) {
+                       ath6kl_err("Unable to write to the device: %d\n",
+                                  ret);
+                       return ret;
+               }
+               ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true);
+               if (ret) {
+                       ath6kl_err("Unable to read from the device: %d\n",
+                                  ret);
+                       return ret;
+               }
+               memcpy(&buf[len - len_remain], ar->bmi.cmd_buf, rx_len);
+               len_remain -= rx_len; addr += rx_len;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
+{
+       u32 cid = BMI_WRITE_MEMORY;
+       int ret;
+       u32 offset;
+       u32 len_remain, tx_len;
+       const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len);
+       u8 aligned_buf[BMI_DATASZ_MAX];
+       u8 *src;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       if ((BMI_DATASZ_MAX + header) > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       memset(ar->bmi.cmd_buf, 0, BMI_DATASZ_MAX + header);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI,
+                 "bmi write memory: addr: 0x%x, len: %d\n", addr, len);
+
+       len_remain = len;
+       while (len_remain) {
+               src = &buf[len - len_remain];
+
+               if (len_remain < (BMI_DATASZ_MAX - header)) {
+                       if (len_remain & 3) {
+                               /* align it with 4 bytes */
+                               len_remain = len_remain +
+                                            (4 - (len_remain & 3));
+                               memcpy(aligned_buf, src, len_remain);
+                               src = aligned_buf;
+                       }
+                       tx_len = len_remain;
+               } else {
+                       tx_len = (BMI_DATASZ_MAX - header);
+               }
+
+               offset = 0;
+               memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+               offset += sizeof(cid);
+               memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+               offset += sizeof(addr);
+               memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
+               offset += sizeof(tx_len);
+               memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len);
+               offset += tx_len;
+
+               ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+               if (ret) {
+                       ath6kl_err("Unable to write to the device: %d\n",
+                                  ret);
+                       return ret;
+               }
+               len_remain -= tx_len; addr += tx_len;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
+{
+       u32 cid = BMI_EXECUTE;
+       int ret;
+       u32 offset;
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = sizeof(cid) + sizeof(addr) + sizeof(param);
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI, "bmi execute: addr: 0x%x, param: %d)\n",
+                  addr, *param);
+
+       offset = 0;
+       memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+       offset += sizeof(cid);
+       memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+       offset += sizeof(addr);
+       memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param));
+       offset += sizeof(*param);
+
+       ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+       if (ret) {
+               ath6kl_err("Unable to write to the device: %d\n", ret);
+               return ret;
+       }
+
+       ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false);
+       if (ret) {
+               ath6kl_err("Unable to read from the device: %d\n", ret);
+               return ret;
+       }
+
+       memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
+
+       return 0;
+}
+
+int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
+{
+       u32 cid = BMI_SET_APP_START;
+       int ret;
+       u32 offset;
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = sizeof(cid) + sizeof(addr);
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI, "bmi set app start: addr: 0x%x\n", addr);
+
+       offset = 0;
+       memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+       offset += sizeof(cid);
+       memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+       offset += sizeof(addr);
+
+       ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+       if (ret) {
+               ath6kl_err("Unable to write to the device: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
+{
+       u32 cid = BMI_READ_SOC_REGISTER;
+       int ret;
+       u32 offset;
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = sizeof(cid) + sizeof(addr);
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI, "bmi read SOC reg: addr: 0x%x\n", addr);
+
+       offset = 0;
+       memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+       offset += sizeof(cid);
+       memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+       offset += sizeof(addr);
+
+       ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+       if (ret) {
+               ath6kl_err("Unable to write to the device: %d\n", ret);
+               return ret;
+       }
+
+       ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true);
+       if (ret) {
+               ath6kl_err("Unable to read from the device: %d\n", ret);
+               return ret;
+       }
+       memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
+
+       return 0;
+}
+
+int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
+{
+       u32 cid = BMI_WRITE_SOC_REGISTER;
+       int ret;
+       u32 offset;
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = sizeof(cid) + sizeof(addr) + sizeof(param);
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI,
+                  "bmi write SOC reg: addr: 0x%x, param: %d\n",
+                   addr, param);
+
+       offset = 0;
+       memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+       offset += sizeof(cid);
+       memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+       offset += sizeof(addr);
+       memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param));
+       offset += sizeof(param);
+
+       ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+       if (ret) {
+               ath6kl_err("Unable to write to the device: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
+{
+       u32 cid = BMI_LZ_DATA;
+       int ret;
+       u32 offset;
+       u32 len_remain, tx_len;
+       const u32 header = sizeof(cid) + sizeof(len);
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = BMI_DATASZ_MAX + header;
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI, "bmi send LZ data: len: %d)\n",
+                  len);
+
+       len_remain = len;
+       while (len_remain) {
+               tx_len = (len_remain < (BMI_DATASZ_MAX - header)) ?
+                         len_remain : (BMI_DATASZ_MAX - header);
+
+               offset = 0;
+               memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+               offset += sizeof(cid);
+               memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
+               offset += sizeof(tx_len);
+               memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain],
+                       tx_len);
+               offset += tx_len;
+
+               ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+               if (ret) {
+                       ath6kl_err("Unable to write to the device: %d\n",
+                                  ret);
+                       return ret;
+               }
+
+               len_remain -= tx_len;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
+{
+       u32 cid = BMI_LZ_STREAM_START;
+       int ret;
+       u32 offset;
+       u16 size;
+
+       if (ar->bmi.done_sent) {
+               ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+               return -EACCES;
+       }
+
+       size = sizeof(cid) + sizeof(addr);
+       if (size > MAX_BMI_CMDBUF_SZ) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       memset(ar->bmi.cmd_buf, 0, size);
+
+       ath6kl_dbg(ATH6KL_DBG_BMI,
+                  "bmi LZ stream start: addr: 0x%x)\n",
+                   addr);
+
+       offset = 0;
+       memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+       offset += sizeof(cid);
+       memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+       offset += sizeof(addr);
+
+       ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+       if (ret) {
+               ath6kl_err("Unable to start LZ stream to the device: %d\n",
+                          ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int ath6kl_bmi_fast_download(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
+{
+       int ret;
+       u32 last_word = 0;
+       u32 last_word_offset = len & ~0x3;
+       u32 unaligned_bytes = len & 0x3;
+
+       ret = ath6kl_bmi_lz_stream_start(ar, addr);
+       if (ret)
+               return ret;
+
+       if (unaligned_bytes) {
+               /* copy the last word into a zero padded buffer */
+               memcpy(&last_word, &buf[last_word_offset], unaligned_bytes);
+       }
+
+       ret = ath6kl_bmi_lz_data(ar, buf, last_word_offset);
+       if (ret)
+               return ret;
+
+       if (unaligned_bytes)
+               ret = ath6kl_bmi_lz_data(ar, (u8 *)&last_word, 4);
+
+       if (!ret) {
+               /* Close compressed stream and open a new (fake) one.
+                * This serves mainly to flush Target caches. */
+               ret = ath6kl_bmi_lz_stream_start(ar, 0x00);
+       }
+       return ret;
+}
+
+int ath6kl_bmi_init(struct ath6kl *ar)
+{
+       ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC);
+
+       if (!ar->bmi.cmd_buf)
+               return -ENOMEM;
+
+       return 0;
+}
+
+void ath6kl_bmi_cleanup(struct ath6kl *ar)
+{
+       kfree(ar->bmi.cmd_buf);
+       ar->bmi.cmd_buf = NULL;
+}
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
new file mode 100644 (file)
index 0000000..83546d7
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 BMI_H
+#define BMI_H
+
+/*
+ * Bootloader Messaging Interface (BMI)
+ *
+ * BMI is a very simple messaging interface used during initialization
+ * to read memory, write memory, execute code, and to define an
+ * application entry PC.
+ *
+ * It is used to download an application to ATH6KL, to provide
+ * patches to code that is already resident on ATH6KL, and generally
+ * to examine and modify state.  The Host has an opportunity to use
+ * BMI only once during bootup.  Once the Host issues a BMI_DONE
+ * command, this opportunity ends.
+ *
+ * The Host writes BMI requests to mailbox0, and reads BMI responses
+ * from mailbox0.   BMI requests all begin with a command
+ * (see below for specific commands), and are followed by
+ * command-specific data.
+ *
+ * Flow control:
+ * The Host can only issue a command once the Target gives it a
+ * "BMI Command Credit", using ATH6KL Counter #4.  As soon as the
+ * Target has completed a command, it issues another BMI Command
+ * Credit (so the Host can issue the next command).
+ *
+ * BMI handles all required Target-side cache flushing.
+ */
+
+#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
+                          (sizeof(u32) * 3 /* cmd + addr + len */))
+
+/* Maximum data size used for BMI transfers */
+#define BMI_DATASZ_MAX                      256
+
+/* BMI Commands */
+
+#define BMI_NO_COMMAND                      0
+
+#define BMI_DONE                            1
+/*
+ * Semantics: Host is done using BMI
+ * Request format:
+ *    u32 command (BMI_DONE)
+ * Response format: none
+ */
+
+#define BMI_READ_MEMORY                     2
+/*
+ * Semantics: Host reads ATH6KL memory
+ * Request format:
+ *    u32 command (BMI_READ_MEMORY)
+ *    u32 address
+ *    u32 length, at most BMI_DATASZ_MAX
+ * Response format:
+ *    u8 data[length]
+ */
+
+#define BMI_WRITE_MEMORY                    3
+/*
+ * Semantics: Host writes ATH6KL memory
+ * Request format:
+ *    u32 command (BMI_WRITE_MEMORY)
+ *    u32 address
+ *    u32 length, at most BMI_DATASZ_MAX
+ *    u8 data[length]
+ * Response format: none
+ */
+
+#define BMI_EXECUTE                         4
+/*
+ * Semantics: Causes ATH6KL to execute code
+ * Request format:
+ *    u32 command (BMI_EXECUTE)
+ *    u32 address
+ *    u32 parameter
+ * Response format:
+ *    u32 return value
+ */
+
+#define BMI_SET_APP_START                   5
+/*
+ * Semantics: Set Target application starting address
+ * Request format:
+ *    u32 command (BMI_SET_APP_START)
+ *    u32 address
+ * Response format: none
+ */
+
+#define BMI_READ_SOC_REGISTER               6
+/*
+ * Semantics: Read a 32-bit Target SOC register.
+ * Request format:
+ *    u32 command (BMI_READ_REGISTER)
+ *    u32 address
+ * Response format:
+ *    u32 value
+ */
+
+#define BMI_WRITE_SOC_REGISTER              7
+/*
+ * Semantics: Write a 32-bit Target SOC register.
+ * Request format:
+ *    u32 command (BMI_WRITE_REGISTER)
+ *    u32 address
+ *    u32 value
+ *
+ * Response format: none
+ */
+
+#define BMI_GET_TARGET_ID                  8
+#define BMI_GET_TARGET_INFO                8
+/*
+ * Semantics: Fetch the 4-byte Target information
+ * Request format:
+ *    u32 command (BMI_GET_TARGET_ID/INFO)
+ * Response format1 (old firmware):
+ *    u32 TargetVersionID
+ * Response format2 (newer firmware):
+ *    u32 TARGET_VERSION_SENTINAL
+ *    struct bmi_target_info;
+ */
+
+#define TARGET_VERSION_SENTINAL 0xffffffff
+#define TARGET_TYPE_AR6003     3
+
+#define BMI_ROMPATCH_INSTALL               9
+/*
+ * Semantics: Install a ROM Patch.
+ * Request format:
+ *    u32 command (BMI_ROMPATCH_INSTALL)
+ *    u32 Target ROM Address
+ *    u32 Target RAM Address or Value (depending on Target Type)
+ *    u32 Size, in bytes
+ *    u32 Activate? 1-->activate;
+ *                            0-->install but do not activate
+ * Response format:
+ *    u32 PatchID
+ */
+
+#define BMI_ROMPATCH_UNINSTALL             10
+/*
+ * Semantics: Uninstall a previously-installed ROM Patch,
+ * automatically deactivating, if necessary.
+ * Request format:
+ *    u32 command (BMI_ROMPATCH_UNINSTALL)
+ *    u32 PatchID
+ *
+ * Response format: none
+ */
+
+#define BMI_ROMPATCH_ACTIVATE              11
+/*
+ * Semantics: Activate a list of previously-installed ROM Patches.
+ * Request format:
+ *    u32 command (BMI_ROMPATCH_ACTIVATE)
+ *    u32 rompatch_count
+ *    u32 PatchID[rompatch_count]
+ *
+ * Response format: none
+ */
+
+#define BMI_ROMPATCH_DEACTIVATE            12
+/*
+ * Semantics: Deactivate a list of active ROM Patches.
+ * Request format:
+ *    u32 command (BMI_ROMPATCH_DEACTIVATE)
+ *    u32 rompatch_count
+ *    u32 PatchID[rompatch_count]
+ *
+ * Response format: none
+ */
+
+
+#define BMI_LZ_STREAM_START                13
+/*
+ * Semantics: Begin an LZ-compressed stream of input
+ * which is to be uncompressed by the Target to an
+ * output buffer at address.  The output buffer must
+ * be sufficiently large to hold the uncompressed
+ * output from the compressed input stream.  This BMI
+ * command should be followed by a series of 1 or more
+ * BMI_LZ_DATA commands.
+ *    u32 command (BMI_LZ_STREAM_START)
+ *    u32 address
+ * Note: Not supported on all versions of ROM firmware.
+ */
+
+#define BMI_LZ_DATA                        14
+/*
+ * Semantics: Host writes ATH6KL memory with LZ-compressed
+ * data which is uncompressed by the Target.  This command
+ * must be preceded by a BMI_LZ_STREAM_START command. A series
+ * of BMI_LZ_DATA commands are considered part of a single
+ * input stream until another BMI_LZ_STREAM_START is issued.
+ * Request format:
+ *    u32 command (BMI_LZ_DATA)
+ *    u32 length (of compressed data),
+ *                  at most BMI_DATASZ_MAX
+ *    u8 CompressedData[length]
+ * Response format: none
+ * Note: Not supported on all versions of ROM firmware.
+ */
+
+#define BMI_COMMUNICATION_TIMEOUT       1000 /* in msec */
+
+struct ath6kl;
+struct ath6kl_bmi_target_info {
+       __le32 byte_count;   /* size of this structure */
+       __le32 version;      /* target version id */
+       __le32 type;         /* target type */
+} __packed;
+
+int ath6kl_bmi_init(struct ath6kl *ar);
+void ath6kl_bmi_cleanup(struct ath6kl *ar);
+int ath6kl_bmi_done(struct ath6kl *ar);
+int ath6kl_bmi_get_target_info(struct ath6kl *ar,
+                              struct ath6kl_bmi_target_info *targ_info);
+int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
+int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
+int ath6kl_bmi_execute(struct ath6kl *ar,
+                      u32 addr, u32 *param);
+int ath6kl_bmi_set_app_start(struct ath6kl *ar,
+                            u32 addr);
+int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param);
+int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param);
+int ath6kl_bmi_lz_data(struct ath6kl *ar,
+                      u8 *buf, u32 len);
+int ath6kl_bmi_lz_stream_start(struct ath6kl *ar,
+                              u32 addr);
+int ath6kl_bmi_fast_download(struct ath6kl *ar,
+                            u32 addr, u8 *buf, u32 len);
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
new file mode 100644 (file)
index 0000000..14559ff
--- /dev/null
@@ -0,0 +1,1538 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 "core.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+#define RATETAB_ENT(_rate, _rateid, _flags) {   \
+       .bitrate    = (_rate),                  \
+       .flags      = (_flags),                 \
+       .hw_value   = (_rateid),                \
+}
+
+#define CHAN2G(_channel, _freq, _flags) {   \
+       .band           = IEEE80211_BAND_2GHZ,  \
+       .hw_value       = (_channel),           \
+       .center_freq    = (_freq),              \
+       .flags          = (_flags),             \
+       .max_antenna_gain   = 0,                \
+       .max_power      = 30,                   \
+}
+
+#define CHAN5G(_channel, _flags) {                 \
+       .band           = IEEE80211_BAND_5GHZ,      \
+       .hw_value       = (_channel),               \
+       .center_freq    = 5000 + (5 * (_channel)),  \
+       .flags          = (_flags),                 \
+       .max_antenna_gain   = 0,                    \
+       .max_power      = 30,                       \
+}
+
+static struct ieee80211_rate ath6kl_rates[] = {
+       RATETAB_ENT(10, 0x1, 0),
+       RATETAB_ENT(20, 0x2, 0),
+       RATETAB_ENT(55, 0x4, 0),
+       RATETAB_ENT(110, 0x8, 0),
+       RATETAB_ENT(60, 0x10, 0),
+       RATETAB_ENT(90, 0x20, 0),
+       RATETAB_ENT(120, 0x40, 0),
+       RATETAB_ENT(180, 0x80, 0),
+       RATETAB_ENT(240, 0x100, 0),
+       RATETAB_ENT(360, 0x200, 0),
+       RATETAB_ENT(480, 0x400, 0),
+       RATETAB_ENT(540, 0x800, 0),
+};
+
+#define ath6kl_a_rates     (ath6kl_rates + 4)
+#define ath6kl_a_rates_size    8
+#define ath6kl_g_rates     (ath6kl_rates + 0)
+#define ath6kl_g_rates_size    12
+
+static struct ieee80211_channel ath6kl_2ghz_channels[] = {
+       CHAN2G(1, 2412, 0),
+       CHAN2G(2, 2417, 0),
+       CHAN2G(3, 2422, 0),
+       CHAN2G(4, 2427, 0),
+       CHAN2G(5, 2432, 0),
+       CHAN2G(6, 2437, 0),
+       CHAN2G(7, 2442, 0),
+       CHAN2G(8, 2447, 0),
+       CHAN2G(9, 2452, 0),
+       CHAN2G(10, 2457, 0),
+       CHAN2G(11, 2462, 0),
+       CHAN2G(12, 2467, 0),
+       CHAN2G(13, 2472, 0),
+       CHAN2G(14, 2484, 0),
+};
+
+static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
+       CHAN5G(34, 0), CHAN5G(36, 0),
+       CHAN5G(38, 0), CHAN5G(40, 0),
+       CHAN5G(42, 0), CHAN5G(44, 0),
+       CHAN5G(46, 0), CHAN5G(48, 0),
+       CHAN5G(52, 0), CHAN5G(56, 0),
+       CHAN5G(60, 0), CHAN5G(64, 0),
+       CHAN5G(100, 0), CHAN5G(104, 0),
+       CHAN5G(108, 0), CHAN5G(112, 0),
+       CHAN5G(116, 0), CHAN5G(120, 0),
+       CHAN5G(124, 0), CHAN5G(128, 0),
+       CHAN5G(132, 0), CHAN5G(136, 0),
+       CHAN5G(140, 0), CHAN5G(149, 0),
+       CHAN5G(153, 0), CHAN5G(157, 0),
+       CHAN5G(161, 0), CHAN5G(165, 0),
+       CHAN5G(184, 0), CHAN5G(188, 0),
+       CHAN5G(192, 0), CHAN5G(196, 0),
+       CHAN5G(200, 0), CHAN5G(204, 0),
+       CHAN5G(208, 0), CHAN5G(212, 0),
+       CHAN5G(216, 0),
+};
+
+static struct ieee80211_supported_band ath6kl_band_2ghz = {
+       .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
+       .channels = ath6kl_2ghz_channels,
+       .n_bitrates = ath6kl_g_rates_size,
+       .bitrates = ath6kl_g_rates,
+};
+
+static struct ieee80211_supported_band ath6kl_band_5ghz = {
+       .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
+       .channels = ath6kl_5ghz_a_channels,
+       .n_bitrates = ath6kl_a_rates_size,
+       .bitrates = ath6kl_a_rates,
+};
+
+static int ath6kl_set_wpa_version(struct ath6kl *ar,
+                                 enum nl80211_wpa_versions wpa_version)
+{
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
+
+       if (!wpa_version) {
+               ar->auth_mode = NONE_AUTH;
+       } else if (wpa_version & NL80211_WPA_VERSION_2) {
+               ar->auth_mode = WPA2_AUTH;
+       } else if (wpa_version & NL80211_WPA_VERSION_1) {
+               ar->auth_mode = WPA_AUTH;
+       } else {
+               ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int ath6kl_set_auth_type(struct ath6kl *ar,
+                               enum nl80211_auth_type auth_type)
+{
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
+
+       switch (auth_type) {
+       case NL80211_AUTHTYPE_OPEN_SYSTEM:
+               ar->dot11_auth_mode = OPEN_AUTH;
+               break;
+       case NL80211_AUTHTYPE_SHARED_KEY:
+               ar->dot11_auth_mode = SHARED_AUTH;
+               break;
+       case NL80211_AUTHTYPE_NETWORK_EAP:
+               ar->dot11_auth_mode = LEAP_AUTH;
+               break;
+
+       case NL80211_AUTHTYPE_AUTOMATIC:
+               ar->dot11_auth_mode = OPEN_AUTH;
+               ar->auto_auth_stage = AUTH_OPEN_IN_PROGRESS;
+               break;
+
+       default:
+               ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
+{
+       u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
+       u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len : &ar->grp_crpto_len;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
+                  __func__, cipher, ucast);
+
+       switch (cipher) {
+       case 0:
+               /* our own hack to use value 0 as no crypto used */
+               *ar_cipher = NONE_CRYPT;
+               *ar_cipher_len = 0;
+               break;
+       case WLAN_CIPHER_SUITE_WEP40:
+               *ar_cipher = WEP_CRYPT;
+               *ar_cipher_len = 5;
+               break;
+       case WLAN_CIPHER_SUITE_WEP104:
+               *ar_cipher = WEP_CRYPT;
+               *ar_cipher_len = 13;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               *ar_cipher = TKIP_CRYPT;
+               *ar_cipher_len = 0;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               *ar_cipher = AES_CRYPT;
+               *ar_cipher_len = 0;
+               break;
+       default:
+               ath6kl_err("cipher 0x%x not supported\n", cipher);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
+{
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
+
+       if (key_mgmt == WLAN_AKM_SUITE_PSK) {
+               if (ar->auth_mode == WPA_AUTH)
+                       ar->auth_mode = WPA_PSK_AUTH;
+               else if (ar->auth_mode == WPA2_AUTH)
+                       ar->auth_mode = WPA2_PSK_AUTH;
+       } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
+               ar->auth_mode = NONE_AUTH;
+       }
+}
+
+static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
+{
+       if (!test_bit(WMI_READY, &ar->flag)) {
+               ath6kl_err("wmi is not ready\n");
+               return false;
+       }
+
+       if (!test_bit(WLAN_ENABLED, &ar->flag)) {
+               ath6kl_err("wlan disabled\n");
+               return false;
+       }
+
+       return true;
+}
+
+static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+                                  struct cfg80211_connect_params *sme)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       int status;
+
+       ar->sme_state = SME_CONNECTING;
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
+               ath6kl_err("destroy in progress\n");
+               return -EBUSY;
+       }
+
+       if (test_bit(SKIP_SCAN, &ar->flag) &&
+           ((sme->channel && sme->channel->center_freq == 0) ||
+            (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
+               ath6kl_err("SkipScan: channel or bssid invalid\n");
+               return -EINVAL;
+       }
+
+       if (down_interruptible(&ar->sem)) {
+               ath6kl_err("busy, couldn't get access\n");
+               return -ERESTARTSYS;
+       }
+
+       if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
+               ath6kl_err("busy, destroy in progress\n");
+               up(&ar->sem);
+               return -EBUSY;
+       }
+
+       if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
+               /*
+                * sleep until the command queue drains
+                */
+               wait_event_interruptible_timeout(ar->event_wq,
+                       ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
+                       WMI_TIMEOUT);
+               if (signal_pending(current)) {
+                       ath6kl_err("cmd queue drain timeout\n");
+                       up(&ar->sem);
+                       return -EINTR;
+               }
+       }
+
+       if (test_bit(CONNECTED, &ar->flag) &&
+           ar->ssid_len == sme->ssid_len &&
+           !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
+               ar->reconnect_flag = true;
+               status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
+                                                 ar->ch_hint);
+
+               up(&ar->sem);
+               if (status) {
+                       ath6kl_err("wmi_reconnect_cmd failed\n");
+                       return -EIO;
+               }
+               return 0;
+       } else if (ar->ssid_len == sme->ssid_len &&
+                  !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
+               ath6kl_disconnect(ar);
+       }
+
+       memset(ar->ssid, 0, sizeof(ar->ssid));
+       ar->ssid_len = sme->ssid_len;
+       memcpy(ar->ssid, sme->ssid, sme->ssid_len);
+
+       if (sme->channel)
+               ar->ch_hint = sme->channel->center_freq;
+
+       memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+       if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
+               memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
+
+       ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
+
+       status = ath6kl_set_auth_type(ar, sme->auth_type);
+       if (status) {
+               up(&ar->sem);
+               return status;
+       }
+
+       if (sme->crypto.n_ciphers_pairwise)
+               ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
+       else
+               ath6kl_set_cipher(ar, 0, true);
+
+       ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
+
+       if (sme->crypto.n_akm_suites)
+               ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
+
+       if ((sme->key_len) &&
+           (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
+               struct ath6kl_key *key = NULL;
+
+               if (sme->key_idx < WMI_MIN_KEY_INDEX ||
+                   sme->key_idx > WMI_MAX_KEY_INDEX) {
+                       ath6kl_err("key index %d out of bounds\n",
+                                  sme->key_idx);
+                       up(&ar->sem);
+                       return -ENOENT;
+               }
+
+               key = &ar->keys[sme->key_idx];
+               key->key_len = sme->key_len;
+               memcpy(key->key, sme->key, key->key_len);
+               key->cipher = ar->prwise_crypto;
+               ar->def_txkey_index = sme->key_idx;
+
+               ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
+                                     ar->prwise_crypto,
+                                     GROUP_USAGE | TX_USAGE,
+                                     key->key_len,
+                                     NULL,
+                                     key->key, KEY_OP_INIT_VAL, NULL,
+                                     NO_SYNC_WMIFLAG);
+       }
+
+       if (!ar->usr_bss_filter) {
+               if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
+                       ath6kl_err("couldn't set bss filtering\n");
+                       up(&ar->sem);
+                       return -EIO;
+               }
+       }
+
+       ar->nw_type = ar->next_mode;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "%s: connect called with authmode %d dot11 auth %d"
+                  " PW crypto %d PW crypto len %d GRP crypto %d"
+                  " GRP crypto len %d channel hint %u\n",
+                  __func__,
+                  ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
+                  ar->prwise_crypto_len, ar->grp_crypto,
+                  ar->grp_crpto_len, ar->ch_hint);
+
+       ar->reconnect_flag = 0;
+       status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
+                                       ar->dot11_auth_mode, ar->auth_mode,
+                                       ar->prwise_crypto,
+                                       ar->prwise_crypto_len,
+                                       ar->grp_crypto, ar->grp_crpto_len,
+                                       ar->ssid_len, ar->ssid,
+                                       ar->req_bssid, ar->ch_hint,
+                                       ar->connect_ctrl_flags);
+
+       up(&ar->sem);
+
+       if (status == -EINVAL) {
+               memset(ar->ssid, 0, sizeof(ar->ssid));
+               ar->ssid_len = 0;
+               ath6kl_err("invalid request\n");
+               return -ENOENT;
+       } else if (status) {
+               ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
+               return -EIO;
+       }
+
+       if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
+           ((ar->auth_mode == WPA_PSK_AUTH)
+            || (ar->auth_mode == WPA2_PSK_AUTH))) {
+               mod_timer(&ar->disconnect_timer,
+                         jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
+       }
+
+       ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
+       set_bit(CONNECT_PEND, &ar->flag);
+
+       return 0;
+}
+
+void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
+                                  u8 *bssid, u16 listen_intvl,
+                                  u16 beacon_intvl,
+                                  enum network_type nw_type,
+                                  u8 beacon_ie_len, u8 assoc_req_len,
+                                  u8 assoc_resp_len, u8 *assoc_info)
+{
+       u16 size = 0;
+       u16 capability = 0;
+       struct cfg80211_bss *bss = NULL;
+       struct ieee80211_mgmt *mgmt = NULL;
+       struct ieee80211_channel *ibss_ch = NULL;
+       s32 signal = 50 * 100;
+       u8 ie_buf_len = 0;
+       unsigned char ie_buf[256];
+       unsigned char *ptr_ie_buf = ie_buf;
+       unsigned char *ieeemgmtbuf = NULL;
+       u8 source_mac[ETH_ALEN];
+       u16 capa_mask;
+       u16 capa_val;
+
+       /* capinfo + listen interval */
+       u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
+
+       /* capinfo + status code +  associd */
+       u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
+
+       u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
+       u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
+           assoc_resp_ie_offset;
+
+       assoc_req_len -= assoc_req_ie_offset;
+       assoc_resp_len -= assoc_resp_ie_offset;
+
+       ar->auto_auth_stage = AUTH_IDLE;
+
+       if (nw_type & ADHOC_NETWORK) {
+               if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
+                       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                                  "%s: ath6k not in ibss mode\n", __func__);
+                       return;
+               }
+       }
+
+       if (nw_type & INFRA_NETWORK) {
+               if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
+                       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                                  "%s: ath6k not in station mode\n", __func__);
+                       return;
+               }
+       }
+
+       if (nw_type & ADHOC_NETWORK) {
+               capa_mask = WLAN_CAPABILITY_IBSS;
+               capa_val = WLAN_CAPABILITY_IBSS;
+       } else {
+               capa_mask = WLAN_CAPABILITY_ESS;
+               capa_val = WLAN_CAPABILITY_ESS;
+       }
+
+       /* Before informing the join/connect event, make sure that
+        * bss entry is present in scan list, if it not present
+        * construct and insert into scan list, otherwise that
+        * event will be dropped on the way by cfg80211, due to
+        * this keys will not be plumbed in case of WEP and
+        * application will not be aware of join/connect status. */
+       bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
+                              ar->wdev->ssid, ar->wdev->ssid_len,
+                              capa_mask, capa_val);
+
+       /*
+        * Earlier we were updating the cfg about bss by making a beacon frame
+        * only if the entry for bss is not there. This can have some issue if
+        * ROAM event is generated and a heavy traffic is ongoing. The ROAM
+        * event is handled through a work queue and by the time it really gets
+        * handled, BSS would have been aged out. So it is better to update the
+        * cfg about BSS irrespective of its entry being present right now or
+        * not.
+        */
+
+       if (nw_type & ADHOC_NETWORK) {
+               /* construct 802.11 mgmt beacon */
+               if (ptr_ie_buf) {
+                       *ptr_ie_buf++ = WLAN_EID_SSID;
+                       *ptr_ie_buf++ = ar->ssid_len;
+                       memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
+                       ptr_ie_buf += ar->ssid_len;
+
+                       *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
+                       *ptr_ie_buf++ = 2;      /* length */
+                       *ptr_ie_buf++ = 0;      /* ATIM window */
+                       *ptr_ie_buf++ = 0;      /* ATIM window */
+
+                       /* TODO: update ibss params and include supported rates,
+                        * DS param set, extened support rates, wmm. */
+
+                       ie_buf_len = ptr_ie_buf - ie_buf;
+               }
+
+               capability |= WLAN_CAPABILITY_IBSS;
+
+               if (ar->prwise_crypto == WEP_CRYPT)
+                       capability |= WLAN_CAPABILITY_PRIVACY;
+
+               memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
+               ptr_ie_buf = ie_buf;
+       } else {
+               capability = *(u16 *) (&assoc_info[beacon_ie_len]);
+               memcpy(source_mac, bssid, ETH_ALEN);
+               ptr_ie_buf = assoc_req_ie;
+               ie_buf_len = assoc_req_len;
+       }
+
+       size = offsetof(struct ieee80211_mgmt, u)
+       + sizeof(mgmt->u.beacon)
+       + ie_buf_len;
+
+       ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
+       if (!ieeemgmtbuf) {
+               ath6kl_err("ieee mgmt buf alloc error\n");
+               cfg80211_put_bss(bss);
+               return;
+       }
+
+       mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+       mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+                                         IEEE80211_STYPE_BEACON);
+       memset(mgmt->da, 0xff, ETH_ALEN);       /* broadcast addr */
+       memcpy(mgmt->sa, source_mac, ETH_ALEN);
+       memcpy(mgmt->bssid, bssid, ETH_ALEN);
+       mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
+       mgmt->u.beacon.capab_info = cpu_to_le16(capability);
+       memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
+
+       ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
+                  __func__, mgmt->bssid, ibss_ch->hw_value,
+                  beacon_intvl, capability);
+
+       bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
+                                       ibss_ch, mgmt,
+                                       size, signal, GFP_KERNEL);
+       kfree(ieeemgmtbuf);
+       cfg80211_put_bss(bss);
+
+       if (nw_type & ADHOC_NETWORK) {
+               cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+               return;
+       }
+
+       if (ar->sme_state == SME_CONNECTING) {
+               /* inform connect result to cfg80211 */
+               ar->sme_state = SME_CONNECTED;
+               cfg80211_connect_result(ar->net_dev, bssid,
+                                       assoc_req_ie, assoc_req_len,
+                                       assoc_resp_ie, assoc_resp_len,
+                                       WLAN_STATUS_SUCCESS, GFP_KERNEL);
+       } else if (ar->sme_state == SME_CONNECTED) {
+               /* inform roam event to cfg80211 */
+               cfg80211_roamed(ar->net_dev, ibss_ch, bssid,
+                               assoc_req_ie, assoc_req_len,
+                               assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
+       }
+}
+
+static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
+                                     struct net_device *dev, u16 reason_code)
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
+                  reason_code);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
+               ath6kl_err("busy, destroy in progress\n");
+               return -EBUSY;
+       }
+
+       if (down_interruptible(&ar->sem)) {
+               ath6kl_err("busy, couldn't get access\n");
+               return -ERESTARTSYS;
+       }
+
+       ar->reconnect_flag = 0;
+       ath6kl_disconnect(ar);
+       memset(ar->ssid, 0, sizeof(ar->ssid));
+       ar->ssid_len = 0;
+
+       if (!test_bit(SKIP_SCAN, &ar->flag))
+               memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+
+       up(&ar->sem);
+
+       return 0;
+}
+
+void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
+                                     u8 *bssid, u8 assoc_resp_len,
+                                     u8 *assoc_info, u16 proto_reason)
+{
+       struct ath6kl_key *key = NULL;
+       u16 status;
+
+       if (ar->scan_req) {
+               cfg80211_scan_done(ar->scan_req, true);
+               ar->scan_req = NULL;
+       }
+
+       if (ar->nw_type & ADHOC_NETWORK) {
+               if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
+                       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                                  "%s: ath6k not in ibss mode\n", __func__);
+                       return;
+               }
+               memset(bssid, 0, ETH_ALEN);
+               cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+               return;
+       }
+
+       if (ar->nw_type & INFRA_NETWORK) {
+               if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
+                       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                                  "%s: ath6k not in station mode\n", __func__);
+                       return;
+               }
+       }
+
+       if (!test_bit(CONNECT_PEND, &ar->flag)) {
+               if (reason != DISCONNECT_CMD)
+                       ath6kl_wmi_disconnect_cmd(ar->wmi);
+
+               return;
+       }
+
+       if (reason == NO_NETWORK_AVAIL) {
+               /* connect cmd failed */
+               ath6kl_wmi_disconnect_cmd(ar->wmi);
+               return;
+       }
+
+       if (reason != DISCONNECT_CMD)
+               return;
+
+       if (!ar->auto_auth_stage) {
+               clear_bit(CONNECT_PEND, &ar->flag);
+
+               if (ar->sme_state == SME_CONNECTING) {
+                       cfg80211_connect_result(ar->net_dev,
+                                               bssid, NULL, 0,
+                                               NULL, 0,
+                                               WLAN_STATUS_UNSPECIFIED_FAILURE,
+                                               GFP_KERNEL);
+               } else {
+                       cfg80211_disconnected(ar->net_dev, reason,
+                                             NULL, 0, GFP_KERNEL);
+               }
+
+               ar->sme_state = SME_DISCONNECTED;
+               return;
+       }
+
+       if (ar->dot11_auth_mode != OPEN_AUTH)
+               return;
+
+       /*
+        * If the current auth algorithm is open, try shared and
+        * make autoAuthStage idle. We do not make it leap for now
+        * being.
+        */
+       key = &ar->keys[ar->def_txkey_index];
+       if (down_interruptible(&ar->sem)) {
+               ath6kl_err("busy, couldn't get access\n");
+               return;
+       }
+
+       ar->dot11_auth_mode = SHARED_AUTH;
+       ar->auto_auth_stage = AUTH_IDLE;
+
+       ath6kl_wmi_addkey_cmd(ar->wmi,
+                             ar->def_txkey_index,
+                             ar->prwise_crypto,
+                             GROUP_USAGE | TX_USAGE,
+                             key->key_len, NULL,
+                             key->key,
+                             KEY_OP_INIT_VAL, NULL,
+                             NO_SYNC_WMIFLAG);
+
+       status = ath6kl_wmi_connect_cmd(ar->wmi,
+                                       ar->nw_type,
+                                       ar->dot11_auth_mode,
+                                       ar->auth_mode,
+                                       ar->prwise_crypto,
+                                       ar->prwise_crypto_len,
+                                       ar->grp_crypto,
+                                       ar->grp_crpto_len,
+                                       ar->ssid_len,
+                                       ar->ssid,
+                                       ar->req_bssid,
+                                       ar->ch_hint,
+                                       ar->connect_ctrl_flags);
+       up(&ar->sem);
+}
+
+static inline bool is_ch_11a(u16 ch)
+{
+       return (!((ch >= 2412) && (ch <= 2484)));
+}
+
+/* struct ath6kl_node_table::nt_nodelock is locked when calling this */
+void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni)
+{
+       u16 size;
+       unsigned char *ieeemgmtbuf = NULL;
+       struct ieee80211_mgmt *mgmt;
+       struct ieee80211_channel *channel;
+       struct ieee80211_supported_band *band;
+       struct ath6kl_common_ie *cie;
+       s32 signal;
+       int freq;
+
+       cie = &ni->ni_cie;
+
+       if (is_ch_11a(cie->ie_chan))
+               band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
+       else if ((cie->ie_erp) || (cie->ie_xrates))
+               band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
+       else
+               band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
+
+       size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
+       ieeemgmtbuf = kmalloc(size, GFP_ATOMIC);
+       if (!ieeemgmtbuf) {
+               ath6kl_err("ieee mgmt buf alloc error\n");
+               return;
+       }
+
+       /*
+        * TODO: Update target to include 802.11 mac header while sending
+        * bss info. Target removes 802.11 mac header while sending the bss
+        * info to host, cfg80211 needs it, for time being just filling the
+        * da, sa and bssid fields alone.
+        */
+       mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+       memset(mgmt->da, 0xff, ETH_ALEN);       /*broadcast addr */
+       memcpy(mgmt->sa, ni->ni_macaddr, ETH_ALEN);
+       memcpy(mgmt->bssid, ni->ni_macaddr, ETH_ALEN);
+       memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
+              ni->ni_buf, ni->ni_framelen);
+
+       freq = cie->ie_chan;
+       channel = ieee80211_get_channel(wiphy, freq);
+       signal = ni->ni_snr * 100;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "%s: bssid %pM ch %d freq %d size %d\n", __func__,
+                  mgmt->bssid, channel->hw_value, freq, size);
+       cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+                                 size, signal, GFP_ATOMIC);
+
+       kfree(ieeemgmtbuf);
+}
+
+static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+                               struct cfg80211_scan_request *request)
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+       int ret = 0;
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (!ar->usr_bss_filter) {
+               if (ath6kl_wmi_bssfilter_cmd(ar->wmi,
+                                            (test_bit(CONNECTED, &ar->flag) ?
+                                            ALL_BUT_BSS_FILTER :
+                                            ALL_BSS_FILTER), 0) != 0) {
+                       ath6kl_err("couldn't set bss filtering\n");
+                       return -EIO;
+               }
+       }
+
+       if (request->n_ssids && request->ssids[0].ssid_len) {
+               u8 i;
+
+               if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
+                       request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
+
+               for (i = 0; i < request->n_ssids; i++)
+                       ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
+                                                 SPECIFIC_SSID_FLAG,
+                                                 request->ssids[i].ssid_len,
+                                                 request->ssids[i].ssid);
+       }
+
+       if (ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
+                                    false, 0, 0, 0, NULL) != 0) {
+               ath6kl_err("wmi_startscan_cmd failed\n");
+               ret = -EIO;
+       }
+
+       ar->scan_req = request;
+
+       return ret;
+}
+
+void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
+{
+       int i;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
+
+       if (!ar->scan_req)
+               return;
+
+       if ((status == -ECANCELED) || (status == -EBUSY)) {
+               cfg80211_scan_done(ar->scan_req, true);
+               goto out;
+       }
+
+       /* Translate data to cfg80211 mgmt format */
+       wlan_iterate_nodes(&ar->scan_table, ar->wdev->wiphy);
+
+       cfg80211_scan_done(ar->scan_req, false);
+
+       if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
+               for (i = 0; i < ar->scan_req->n_ssids; i++) {
+                       ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
+                                                 DISABLE_SSID_FLAG,
+                                                 0, NULL);
+               }
+       }
+
+out:
+       ar->scan_req = NULL;
+}
+
+static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
+                                  u8 key_index, bool pairwise,
+                                  const u8 *mac_addr,
+                                  struct key_params *params)
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+       struct ath6kl_key *key = NULL;
+       u8 key_usage;
+       u8 key_type;
+       int status = 0;
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                          "%s: key index %d out of bounds\n", __func__,
+                          key_index);
+               return -ENOENT;
+       }
+
+       key = &ar->keys[key_index];
+       memset(key, 0, sizeof(struct ath6kl_key));
+
+       if (pairwise)
+               key_usage = PAIRWISE_USAGE;
+       else
+               key_usage = GROUP_USAGE;
+
+       if (params) {
+               if (params->key_len > WLAN_MAX_KEY_LEN ||
+                   params->seq_len > sizeof(key->seq))
+                       return -EINVAL;
+
+               key->key_len = params->key_len;
+               memcpy(key->key, params->key, key->key_len);
+               key->seq_len = params->seq_len;
+               memcpy(key->seq, params->seq, key->seq_len);
+               key->cipher = params->cipher;
+       }
+
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               key_type = WEP_CRYPT;
+               break;
+
+       case WLAN_CIPHER_SUITE_TKIP:
+               key_type = TKIP_CRYPT;
+               break;
+
+       case WLAN_CIPHER_SUITE_CCMP:
+               key_type = AES_CRYPT;
+               break;
+
+       default:
+               return -ENOTSUPP;
+       }
+
+       if (((ar->auth_mode == WPA_PSK_AUTH)
+            || (ar->auth_mode == WPA2_PSK_AUTH))
+           && (key_usage & GROUP_USAGE))
+               del_timer(&ar->disconnect_timer);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
+                  __func__, key_index, key->key_len, key_type,
+                  key_usage, key->seq_len);
+
+       ar->def_txkey_index = key_index;
+       status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
+                                      key_type, key_usage, key->key_len,
+                                      key->seq, key->key, KEY_OP_INIT_VAL,
+                                      (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
+
+       if (status)
+               return -EIO;
+
+       return 0;
+}
+
+static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
+                                  u8 key_index, bool pairwise,
+                                  const u8 *mac_addr)
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                          "%s: key index %d out of bounds\n", __func__,
+                          key_index);
+               return -ENOENT;
+       }
+
+       if (!ar->keys[key_index].key_len) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                          "%s: index %d is empty\n", __func__, key_index);
+               return 0;
+       }
+
+       ar->keys[key_index].key_len = 0;
+
+       return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
+}
+
+static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
+                                  u8 key_index, bool pairwise,
+                                  const u8 *mac_addr, void *cookie,
+                                  void (*callback) (void *cookie,
+                                                    struct key_params *))
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+       struct ath6kl_key *key = NULL;
+       struct key_params params;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                          "%s: key index %d out of bounds\n", __func__,
+                          key_index);
+               return -ENOENT;
+       }
+
+       key = &ar->keys[key_index];
+       memset(&params, 0, sizeof(params));
+       params.cipher = key->cipher;
+       params.key_len = key->key_len;
+       params.seq_len = key->seq_len;
+       params.seq = key->seq;
+       params.key = key->key;
+
+       callback(cookie, &params);
+
+       return key->key_len ? 0 : -ENOENT;
+}
+
+static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
+                                          struct net_device *ndev,
+                                          u8 key_index, bool unicast,
+                                          bool multicast)
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+       struct ath6kl_key *key = NULL;
+       int status = 0;
+       u8 key_usage;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                          "%s: key index %d out of bounds\n",
+                          __func__, key_index);
+               return -ENOENT;
+       }
+
+       if (!ar->keys[key_index].key_len) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
+                          __func__, key_index);
+               return -EINVAL;
+       }
+
+       ar->def_txkey_index = key_index;
+       key = &ar->keys[ar->def_txkey_index];
+       key_usage = GROUP_USAGE;
+       if (ar->prwise_crypto == WEP_CRYPT)
+               key_usage |= TX_USAGE;
+
+       status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
+                                      ar->prwise_crypto, key_usage,
+                                      key->key_len, key->seq, key->key,
+                                      KEY_OP_INIT_VAL, NULL,
+                                      SYNC_BOTH_WMIFLAG);
+       if (status)
+               return -EIO;
+
+       return 0;
+}
+
+void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
+                                      bool ismcast)
+{
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
+
+       cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
+                                    (ismcast ? NL80211_KEYTYPE_GROUP :
+                                     NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
+                                    GFP_KERNEL);
+}
+
+static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+       struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+       int ret;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
+                  changed);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+               ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
+               if (ret != 0) {
+                       ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * The type nl80211_tx_power_setting replaces the following
+ * data type from 2.6.36 onwards
+*/
+static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
+                                      enum nl80211_tx_power_setting type,
+                                      int dbm)
+{
+       struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+       u8 ath6kl_dbm;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
+                  type, dbm);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       switch (type) {
+       case NL80211_TX_POWER_AUTOMATIC:
+               return 0;
+       case NL80211_TX_POWER_LIMITED:
+               ar->tx_pwr = ath6kl_dbm = dbm;
+               break;
+       default:
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
+                          __func__, type);
+               return -EOPNOTSUPP;
+       }
+
+       ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
+
+       return 0;
+}
+
+static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
+{
+       struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (test_bit(CONNECTED, &ar->flag)) {
+               ar->tx_pwr = 0;
+
+               if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
+                       ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
+                       return -EIO;
+               }
+
+               wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
+                                                5 * HZ);
+
+               if (signal_pending(current)) {
+                       ath6kl_err("target did not respond\n");
+                       return -EINTR;
+               }
+       }
+
+       *dbm = ar->tx_pwr;
+       return 0;
+}
+
+static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+                                         struct net_device *dev,
+                                         bool pmgmt, int timeout)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       struct wmi_power_mode_cmd mode;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
+                  __func__, pmgmt, timeout);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       if (pmgmt) {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
+               mode.pwr_mode = REC_POWER;
+       } else {
+               ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
+               mode.pwr_mode = MAX_PERF_POWER;
+       }
+
+       if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
+               ath6kl_err("wmi_powermode_cmd failed\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
+                                       struct net_device *ndev,
+                                       enum nl80211_iftype type, u32 *flags,
+                                       struct vif_params *params)
+{
+       struct ath6kl *ar = ath6kl_priv(ndev);
+       struct wireless_dev *wdev = ar->wdev;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       switch (type) {
+       case NL80211_IFTYPE_STATION:
+               ar->next_mode = INFRA_NETWORK;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               ar->next_mode = ADHOC_NETWORK;
+               break;
+       default:
+               ath6kl_err("invalid interface type %u\n", type);
+               return -EOPNOTSUPP;
+       }
+
+       wdev->iftype = type;
+
+       return 0;
+}
+
+static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
+                                    struct net_device *dev,
+                                    struct cfg80211_ibss_params *ibss_param)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       int status;
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       ar->ssid_len = ibss_param->ssid_len;
+       memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
+
+       if (ibss_param->channel)
+               ar->ch_hint = ibss_param->channel->center_freq;
+
+       if (ibss_param->channel_fixed) {
+               /*
+                * TODO: channel_fixed: The channel should be fixed, do not
+                * search for IBSSs to join on other channels. Target
+                * firmware does not support this feature, needs to be
+                * updated.
+                */
+               return -EOPNOTSUPP;
+       }
+
+       memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+       if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
+               memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
+
+       ath6kl_set_wpa_version(ar, 0);
+
+       status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
+       if (status)
+               return status;
+
+       if (ibss_param->privacy) {
+               ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
+               ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
+       } else {
+               ath6kl_set_cipher(ar, 0, true);
+               ath6kl_set_cipher(ar, 0, false);
+       }
+
+       ar->nw_type = ar->next_mode;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "%s: connect called with authmode %d dot11 auth %d"
+                  " PW crypto %d PW crypto len %d GRP crypto %d"
+                  " GRP crypto len %d channel hint %u\n",
+                  __func__,
+                  ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
+                  ar->prwise_crypto_len, ar->grp_crypto,
+                  ar->grp_crpto_len, ar->ch_hint);
+
+       status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
+                                       ar->dot11_auth_mode, ar->auth_mode,
+                                       ar->prwise_crypto,
+                                       ar->prwise_crypto_len,
+                                       ar->grp_crypto, ar->grp_crpto_len,
+                                       ar->ssid_len, ar->ssid,
+                                       ar->req_bssid, ar->ch_hint,
+                                       ar->connect_ctrl_flags);
+       set_bit(CONNECT_PEND, &ar->flag);
+
+       return 0;
+}
+
+static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
+                                     struct net_device *dev)
+{
+       struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
+
+       if (!ath6kl_cfg80211_ready(ar))
+               return -EIO;
+
+       ath6kl_disconnect(ar);
+       memset(ar->ssid, 0, sizeof(ar->ssid));
+       ar->ssid_len = 0;
+
+       return 0;
+}
+
+static const u32 cipher_suites[] = {
+       WLAN_CIPHER_SUITE_WEP40,
+       WLAN_CIPHER_SUITE_WEP104,
+       WLAN_CIPHER_SUITE_TKIP,
+       WLAN_CIPHER_SUITE_CCMP,
+};
+
+static bool is_rate_legacy(s32 rate)
+{
+       static const s32 legacy[] = { 1000, 2000, 5500, 11000,
+               6000, 9000, 12000, 18000, 24000,
+               36000, 48000, 54000
+       };
+       u8 i;
+
+       for (i = 0; i < ARRAY_SIZE(legacy); i++)
+               if (rate == legacy[i])
+                       return true;
+
+       return false;
+}
+
+static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
+{
+       static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
+               52000, 58500, 65000, 72200
+       };
+       u8 i;
+
+       for (i = 0; i < ARRAY_SIZE(ht20); i++) {
+               if (rate == ht20[i]) {
+                       if (i == ARRAY_SIZE(ht20) - 1)
+                               /* last rate uses sgi */
+                               *sgi = true;
+                       else
+                               *sgi = false;
+
+                       *mcs = i;
+                       return true;
+               }
+       }
+       return false;
+}
+
+static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
+{
+       static const s32 ht40[] = { 13500, 27000, 40500, 54000,
+               81000, 108000, 121500, 135000,
+               150000
+       };
+       u8 i;
+
+       for (i = 0; i < ARRAY_SIZE(ht40); i++) {
+               if (rate == ht40[i]) {
+                       if (i == ARRAY_SIZE(ht40) - 1)
+                               /* last rate uses sgi */
+                               *sgi = true;
+                       else
+                               *sgi = false;
+
+                       *mcs = i;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
+                             u8 *mac, struct station_info *sinfo)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       long left;
+       bool sgi;
+       s32 rate;
+       int ret;
+       u8 mcs;
+
+       if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
+               return -ENOENT;
+
+       if (down_interruptible(&ar->sem))
+               return -EBUSY;
+
+       set_bit(STATS_UPDATE_PEND, &ar->flag);
+
+       ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
+
+       if (ret != 0) {
+               up(&ar->sem);
+               return -EIO;
+       }
+
+       left = wait_event_interruptible_timeout(ar->event_wq,
+                                               !test_bit(STATS_UPDATE_PEND,
+                                                         &ar->flag),
+                                               WMI_TIMEOUT);
+
+       up(&ar->sem);
+
+       if (left == 0)
+               return -ETIMEDOUT;
+       else if (left < 0)
+               return left;
+
+       if (ar->target_stats.rx_byte) {
+               sinfo->rx_bytes = ar->target_stats.rx_byte;
+               sinfo->filled |= STATION_INFO_RX_BYTES;
+               sinfo->rx_packets = ar->target_stats.rx_pkt;
+               sinfo->filled |= STATION_INFO_RX_PACKETS;
+       }
+
+       if (ar->target_stats.tx_byte) {
+               sinfo->tx_bytes = ar->target_stats.tx_byte;
+               sinfo->filled |= STATION_INFO_TX_BYTES;
+               sinfo->tx_packets = ar->target_stats.tx_pkt;
+               sinfo->filled |= STATION_INFO_TX_PACKETS;
+       }
+
+       sinfo->signal = ar->target_stats.cs_rssi;
+       sinfo->filled |= STATION_INFO_SIGNAL;
+
+       rate = ar->target_stats.tx_ucast_rate;
+
+       if (is_rate_legacy(rate)) {
+               sinfo->txrate.legacy = rate / 100;
+       } else if (is_rate_ht20(rate, &mcs, &sgi)) {
+               if (sgi) {
+                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+                       sinfo->txrate.mcs = mcs - 1;
+               } else {
+                       sinfo->txrate.mcs = mcs;
+               }
+
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+       } else if (is_rate_ht40(rate, &mcs, &sgi)) {
+               if (sgi) {
+                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+                       sinfo->txrate.mcs = mcs - 1;
+               } else {
+                       sinfo->txrate.mcs = mcs;
+               }
+
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+       } else {
+               ath6kl_warn("invalid rate: %d\n", rate);
+               return 0;
+       }
+
+       sinfo->filled |= STATION_INFO_TX_BITRATE;
+
+       return 0;
+}
+
+static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+                           struct cfg80211_pmksa *pmksa)
+{
+       struct ath6kl *ar = ath6kl_priv(netdev);
+       return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
+                                      pmksa->pmkid, true);
+}
+
+static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+                           struct cfg80211_pmksa *pmksa)
+{
+       struct ath6kl *ar = ath6kl_priv(netdev);
+       return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
+                                      pmksa->pmkid, false);
+}
+
+static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
+{
+       struct ath6kl *ar = ath6kl_priv(netdev);
+       if (test_bit(CONNECTED, &ar->flag))
+               return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
+       return 0;
+}
+
+static struct cfg80211_ops ath6kl_cfg80211_ops = {
+       .change_virtual_intf = ath6kl_cfg80211_change_iface,
+       .scan = ath6kl_cfg80211_scan,
+       .connect = ath6kl_cfg80211_connect,
+       .disconnect = ath6kl_cfg80211_disconnect,
+       .add_key = ath6kl_cfg80211_add_key,
+       .get_key = ath6kl_cfg80211_get_key,
+       .del_key = ath6kl_cfg80211_del_key,
+       .set_default_key = ath6kl_cfg80211_set_default_key,
+       .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
+       .set_tx_power = ath6kl_cfg80211_set_txpower,
+       .get_tx_power = ath6kl_cfg80211_get_txpower,
+       .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
+       .join_ibss = ath6kl_cfg80211_join_ibss,
+       .leave_ibss = ath6kl_cfg80211_leave_ibss,
+       .get_station = ath6kl_get_station,
+       .set_pmksa = ath6kl_set_pmksa,
+       .del_pmksa = ath6kl_del_pmksa,
+       .flush_pmksa = ath6kl_flush_pmksa,
+};
+
+struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
+{
+       int ret = 0;
+       struct wireless_dev *wdev;
+
+       wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+       if (!wdev) {
+               ath6kl_err("couldn't allocate wireless device\n");
+               return NULL;
+       }
+
+       /* create a new wiphy for use with cfg80211 */
+       wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
+       if (!wdev->wiphy) {
+               ath6kl_err("couldn't allocate wiphy device\n");
+               kfree(wdev);
+               return NULL;
+       }
+
+       /* set device pointer for wiphy */
+       set_wiphy_dev(wdev->wiphy, dev);
+
+       wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+           BIT(NL80211_IFTYPE_ADHOC);
+       /* max num of ssids that can be probed during scanning */
+       wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+       wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
+       wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+       wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+       wdev->wiphy->cipher_suites = cipher_suites;
+       wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+       ret = wiphy_register(wdev->wiphy);
+       if (ret < 0) {
+               ath6kl_err("couldn't register wiphy device\n");
+               wiphy_free(wdev->wiphy);
+               kfree(wdev);
+               return NULL;
+       }
+
+       return wdev;
+}
+
+void ath6kl_cfg80211_deinit(struct ath6kl *ar)
+{
+       struct wireless_dev *wdev = ar->wdev;
+
+       if (ar->scan_req) {
+               cfg80211_scan_done(ar->scan_req, true);
+               ar->scan_req = NULL;
+       }
+
+       if (!wdev)
+               return;
+
+       wiphy_unregister(wdev->wiphy);
+       wiphy_free(wdev->wiphy);
+       kfree(wdev);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
new file mode 100644 (file)
index 0000000..a84adc2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 Atheros Communications 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 ATH6KL_CFG80211_H
+#define ATH6KL_CFG80211_H
+
+struct wireless_dev *ath6kl_cfg80211_init(struct device *dev);
+void ath6kl_cfg80211_deinit(struct ath6kl *ar);
+
+void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status);
+
+void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
+                                  u8 *bssid, u16 listen_intvl,
+                                  u16 beacon_intvl,
+                                  enum network_type nw_type,
+                                  u8 beacon_ie_len, u8 assoc_req_len,
+                                  u8 assoc_resp_len, u8 *assoc_info);
+
+void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
+                                     u8 *bssid, u8 assoc_resp_len,
+                                     u8 *assoc_info, u16 proto_reason);
+
+void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
+                                    bool ismcast);
+
+#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
new file mode 100644 (file)
index 0000000..6b0d456
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications 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 COMMON_H
+#define COMMON_H
+
+#include <linux/netdevice.h>
+
+#define ATH6KL_MAX_IE                  256
+
+extern int ath6kl_printk(const char *level, const char *fmt, ...);
+
+#define A_CACHE_LINE_PAD            128
+
+/*
+ * Reflects the version of binary interface exposed by ATH6KL target
+ * firmware. Needs to be incremented by 1 for any change in the firmware
+ * that requires upgrade of the driver on the host side for the change to
+ * work correctly
+ */
+#define ATH6KL_ABI_VERSION        1
+
+#define SIGNAL_QUALITY_METRICS_NUM_MAX    2
+
+enum {
+       SIGNAL_QUALITY_METRICS_SNR = 0,
+       SIGNAL_QUALITY_METRICS_RSSI,
+       SIGNAL_QUALITY_METRICS_ALL,
+};
+
+/*
+ * Data Path
+ */
+
+#define WMI_MAX_TX_DATA_FRAME_LENGTH         \
+       (1500 + sizeof(struct wmi_data_hdr) + \
+        sizeof(struct ethhdr) +      \
+        sizeof(struct ath6kl_llc_snap_hdr))
+
+/* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
+#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH    \
+       (3840 + sizeof(struct wmi_data_hdr) + \
+        sizeof(struct ethhdr) +      \
+        sizeof(struct ath6kl_llc_snap_hdr))
+
+#define EPPING_ALIGNMENT_PAD                          \
+       (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) \
+        - sizeof(struct htc_frame_hdr))
+
+struct ath6kl_llc_snap_hdr {
+       u8 dsap;
+       u8 ssap;
+       u8 cntl;
+       u8 org_code[3];
+       __be16 eth_type;
+} __packed;
+
+enum crypto_type {
+       NONE_CRYPT          = 0x01,
+       WEP_CRYPT           = 0x02,
+       TKIP_CRYPT          = 0x04,
+       AES_CRYPT           = 0x08,
+};
+
+#define ATH6KL_NODE_HASHSIZE 32
+/* simple hash is enough for variation of macaddr */
+#define ATH6KL_NODE_HASH(addr)   \
+       (((const u8 *)(addr))[ETH_ALEN - 1] % \
+        ATH6KL_NODE_HASHSIZE)
+
+/*
+ * Table of ath6kl_node instances.  Each ieee80211com
+ * has at least one for holding the scan candidates.
+ * When operating as an access point or in ibss mode there
+ * is a second table for associated stations or neighbors.
+ */
+struct ath6kl_node_table {
+       spinlock_t nt_nodelock; /* on node table */
+       struct bss *nt_node_first;      /* information of all nodes */
+       struct bss *nt_node_last;       /* information of all nodes */
+       struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
+       const char *nt_name;    /* for debugging */
+       u32 nt_node_age;                /* node aging time */
+};
+
+#define WLAN_NODE_INACT_TIMEOUT_MSEC    120000
+#define WLAN_NODE_INACT_CNT            4
+
+struct ath6kl_common_ie {
+       u16 ie_chan;
+       u8 *ie_tstamp;
+       u8 *ie_ssid;
+       u8 *ie_rates;
+       u8 *ie_xrates;
+       u8 *ie_country;
+       u8 *ie_wpa;
+       u8 *ie_rsn;
+       u8 *ie_wmm;
+       u8 *ie_ath;
+       u16 ie_capInfo;
+       u16 ie_beaconInt;
+       u8 *ie_tim;
+       u8 *ie_chswitch;
+       u8 ie_erp;
+       u8 *ie_wsc;
+       u8 *ie_htcap;
+       u8 *ie_htop;
+};
+
+struct bss {
+       u8 ni_macaddr[ETH_ALEN];
+       u8 ni_snr;
+       s16 ni_rssi;
+       struct bss *ni_list_next;
+       struct bss *ni_list_prev;
+       struct bss *ni_hash_next;
+       struct bss *ni_hash_prev;
+       struct ath6kl_common_ie ni_cie;
+       u8 *ni_buf;
+       u16 ni_framelen;
+       struct ath6kl_node_table *ni_table;
+       u32 ni_refcnt;
+
+       u32 ni_tstamp;
+       u32 ni_actcnt;
+};
+
+struct htc_endpoint_credit_dist;
+struct ath6kl;
+enum htc_credit_dist_reason;
+struct htc_credit_state_info;
+
+struct bss *wlan_node_alloc(int wh_size);
+void wlan_node_free(struct bss *ni);
+void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
+                    const u8 *mac_addr);
+struct bss *wlan_find_node(struct ath6kl_node_table *nt,
+                          const u8 *mac_addr);
+void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
+void wlan_free_allnodes(struct ath6kl_node_table *nt);
+void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg);
+
+void wlan_node_table_init(struct ath6kl_node_table *nt);
+void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
+
+void wlan_refresh_inactive_nodes(struct ath6kl *ar);
+
+struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
+                                 u32 ssid_len, bool is_wpa2, bool match_ssid);
+
+void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
+
+int ath6k_setup_credit_dist(void *htc_handle,
+                           struct htc_credit_state_info *cred_info);
+void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
+                            struct list_head *epdist_list,
+                            enum htc_credit_dist_reason reason);
+void ath6k_credit_init(struct htc_credit_state_info *cred_inf,
+                      struct list_head *ep_list,
+                      int tot_credits);
+void ath6k_seek_credits(struct htc_credit_state_info *cred_inf,
+                       struct htc_endpoint_credit_dist *ep_dist);
+struct ath6kl *ath6kl_core_alloc(struct device *sdev);
+int ath6kl_core_init(struct ath6kl *ar);
+int ath6kl_unavail_ev(struct ath6kl *ar);
+struct sk_buff *ath6kl_buf_alloc(int size);
+#endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
new file mode 100644 (file)
index 0000000..7417022
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications 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 CORE_H
+#define CORE_H
+
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/firmware.h>
+#include <linux/sched.h>
+#include <net/cfg80211.h>
+#include "htc.h"
+#include "wmi.h"
+#include "bmi.h"
+
+#define MAX_ATH6KL                        1
+#define ATH6KL_MAX_RX_BUFFERS             16
+#define ATH6KL_BUFFER_SIZE                1664
+#define ATH6KL_MAX_AMSDU_RX_BUFFERS       4
+#define ATH6KL_AMSDU_REFILL_THRESHOLD     3
+#define ATH6KL_AMSDU_BUFFER_SIZE     (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
+#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN  1508
+#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN  46
+
+#define USER_SAVEDKEYS_STAT_INIT     0
+#define USER_SAVEDKEYS_STAT_RUN      1
+
+#define ATH6KL_TX_TIMEOUT      10
+#define ATH6KL_MAX_ENDPOINTS   4
+#define MAX_NODE_NUM           15
+
+/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
+#define MAX_DEF_COOKIE_NUM                180
+#define MAX_HI_COOKIE_NUM                 18   /* 10% of MAX_COOKIE_NUM */
+#define MAX_COOKIE_NUM                 (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
+
+#define MAX_DEFAULT_SEND_QUEUE_DEPTH      (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
+
+#define DISCON_TIMER_INTVAL               10000  /* in msec */
+#define A_DEFAULT_LISTEN_INTERVAL         100
+#define A_MAX_WOW_LISTEN_INTERVAL         1000
+
+/* AR6003 1.0 definitions */
+#define AR6003_REV1_VERSION                 0x300002ba
+
+/* AR6003 2.0 definitions */
+#define AR6003_REV2_VERSION                 0x30000384
+#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS  0x57e910
+#define AR6003_REV2_OTP_FILE                "ath6k/AR6003/hw2.0/otp.bin.z77"
+#define AR6003_REV2_FIRMWARE_FILE           "ath6k/AR6003/hw2.0/athwlan.bin.z77"
+#define AR6003_REV2_PATCH_FILE              "ath6k/AR6003/hw2.0/data.patch.bin"
+#define AR6003_REV2_BOARD_DATA_FILE         "ath6k/AR6003/hw2.0/bdata.bin"
+#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
+
+/* AR6003 3.0 definitions */
+#define AR6003_REV3_VERSION                 0x30000582
+#define AR6003_REV3_OTP_FILE                "ath6k/AR6003/hw2.1.1/otp.bin"
+#define AR6003_REV3_FIRMWARE_FILE           "ath6k/AR6003/hw2.1.1/athwlan.bin"
+#define AR6003_REV3_PATCH_FILE            "ath6k/AR6003/hw2.1.1/data.patch.bin"
+#define AR6003_REV3_BOARD_DATA_FILE       "ath6k/AR6003/hw2.1.1/bdata.bin"
+#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE    \
+       "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
+
+/* Per STA data, used in AP mode */
+#define STA_PS_AWAKE           BIT(0)
+#define        STA_PS_SLEEP            BIT(1)
+#define        STA_PS_POLLED           BIT(2)
+
+/* HTC TX packet tagging definitions */
+#define ATH6KL_CONTROL_PKT_TAG    HTC_TX_PACKET_TAG_USER_DEFINED
+#define ATH6KL_DATA_PKT_TAG       (ATH6KL_CONTROL_PKT_TAG + 1)
+
+#define AR6003_CUST_DATA_SIZE 16
+
+#define AGGR_WIN_IDX(x, y)          ((x) % (y))
+#define AGGR_INCR_IDX(x, y)         AGGR_WIN_IDX(((x) + 1), (y))
+#define AGGR_DCRM_IDX(x, y)         AGGR_WIN_IDX(((x) - 1), (y))
+#define ATH6KL_MAX_SEQ_NO              0xFFF
+#define ATH6KL_NEXT_SEQ_NO(x)          (((x) + 1) & ATH6KL_MAX_SEQ_NO)
+
+#define NUM_OF_TIDS         8
+#define AGGR_SZ_DEFAULT     8
+
+#define AGGR_WIN_SZ_MIN     2
+#define AGGR_WIN_SZ_MAX     8
+
+#define TID_WINDOW_SZ(_x)   ((_x) << 1)
+
+#define AGGR_NUM_OF_FREE_NETBUFS    16
+
+#define AGGR_RX_TIMEOUT     400        /* in ms */
+
+#define WMI_TIMEOUT (2 * HZ)
+
+#define MBOX_YIELD_LIMIT 99
+
+/* configuration lags */
+/*
+ * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in
+ * ERP IE of beacon to determine the short premable support when
+ * sending (Re)Assoc req.
+ * ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN: Don't send the power
+ * module state transition failure events which happen during
+ * scan, to the host.
+ */
+#define ATH6KL_CONF_IGNORE_ERP_BARKER          BIT(0)
+#define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN  BIT(1)
+#define ATH6KL_CONF_ENABLE_11N                 BIT(2)
+#define ATH6KL_CONF_ENABLE_TX_BURST            BIT(3)
+
+enum wlan_low_pwr_state {
+       WLAN_POWER_STATE_ON,
+       WLAN_POWER_STATE_CUT_PWR,
+       WLAN_POWER_STATE_DEEP_SLEEP,
+       WLAN_POWER_STATE_WOW
+};
+
+enum sme_state {
+       SME_DISCONNECTED,
+       SME_CONNECTING,
+       SME_CONNECTED
+};
+
+struct skb_hold_q {
+       struct sk_buff *skb;
+       bool is_amsdu;
+       u16 seq_no;
+};
+
+struct rxtid {
+       bool aggr;
+       bool progress;
+       bool timer_mon;
+       u16 win_sz;
+       u16 seq_next;
+       u32 hold_q_sz;
+       struct skb_hold_q *hold_q;
+       struct sk_buff_head q;
+       spinlock_t lock;
+};
+
+struct rxtid_stats {
+       u32 num_into_aggr;
+       u32 num_dups;
+       u32 num_oow;
+       u32 num_mpdu;
+       u32 num_amsdu;
+       u32 num_delivered;
+       u32 num_timeouts;
+       u32 num_hole;
+       u32 num_bar;
+};
+
+struct aggr_info {
+       u8 aggr_sz;
+       u8 timer_scheduled;
+       struct timer_list timer;
+       struct net_device *dev;
+       struct rxtid rx_tid[NUM_OF_TIDS];
+       struct sk_buff_head free_q;
+       struct rxtid_stats stat[NUM_OF_TIDS];
+};
+
+struct ath6kl_wep_key {
+       u8 key_index;
+       u8 key_len;
+       u8 key[64];
+};
+
+#define ATH6KL_KEY_SEQ_LEN 8
+
+struct ath6kl_key {
+       u8 key[WLAN_MAX_KEY_LEN];
+       u8 key_len;
+       u8 seq[ATH6KL_KEY_SEQ_LEN];
+       u8 seq_len;
+       u32 cipher;
+};
+
+struct ath6kl_node_mapping {
+       u8 mac_addr[ETH_ALEN];
+       u8 ep_id;
+       u8 tx_pend;
+};
+
+struct ath6kl_cookie {
+       struct sk_buff *skb;
+       u32 map_no;
+       struct htc_packet htc_pkt;
+       struct ath6kl_cookie *arc_list_next;
+};
+
+struct ath6kl_sta {
+       u16 sta_flags;
+       u8 mac[ETH_ALEN];
+       u8 aid;
+       u8 keymgmt;
+       u8 ucipher;
+       u8 auth;
+       u8 wpa_ie[ATH6KL_MAX_IE];
+       struct sk_buff_head psq;
+       spinlock_t psq_lock;
+};
+
+struct ath6kl_version {
+       u32 target_ver;
+       u32 wlan_ver;
+       u32 abi_ver;
+};
+
+struct ath6kl_bmi {
+       u32 cmd_credits;
+       bool done_sent;
+       u8 *cmd_buf;
+};
+
+struct target_stats {
+       u64 tx_pkt;
+       u64 tx_byte;
+       u64 tx_ucast_pkt;
+       u64 tx_ucast_byte;
+       u64 tx_mcast_pkt;
+       u64 tx_mcast_byte;
+       u64 tx_bcast_pkt;
+       u64 tx_bcast_byte;
+       u64 tx_rts_success_cnt;
+       u64 tx_pkt_per_ac[4];
+
+       u64 tx_err;
+       u64 tx_fail_cnt;
+       u64 tx_retry_cnt;
+       u64 tx_mult_retry_cnt;
+       u64 tx_rts_fail_cnt;
+
+       u64 rx_pkt;
+       u64 rx_byte;
+       u64 rx_ucast_pkt;
+       u64 rx_ucast_byte;
+       u64 rx_mcast_pkt;
+       u64 rx_mcast_byte;
+       u64 rx_bcast_pkt;
+       u64 rx_bcast_byte;
+       u64 rx_frgment_pkt;
+
+       u64 rx_err;
+       u64 rx_crc_err;
+       u64 rx_key_cache_miss;
+       u64 rx_decrypt_err;
+       u64 rx_dupl_frame;
+
+       u64 tkip_local_mic_fail;
+       u64 tkip_cnter_measures_invoked;
+       u64 tkip_replays;
+       u64 tkip_fmt_err;
+       u64 ccmp_fmt_err;
+       u64 ccmp_replays;
+
+       u64 pwr_save_fail_cnt;
+
+       u64 cs_bmiss_cnt;
+       u64 cs_low_rssi_cnt;
+       u64 cs_connect_cnt;
+       u64 cs_discon_cnt;
+
+       s32 tx_ucast_rate;
+       s32 rx_ucast_rate;
+
+       u32 lq_val;
+
+       u32 wow_pkt_dropped;
+       u16 wow_evt_discarded;
+
+       s16 noise_floor_calib;
+       s16 cs_rssi;
+       s16 cs_ave_beacon_rssi;
+       u8 cs_ave_beacon_snr;
+       u8 cs_last_roam_msec;
+       u8 cs_snr;
+
+       u8 wow_host_pkt_wakeups;
+       u8 wow_host_evt_wakeups;
+
+       u32 arp_received;
+       u32 arp_matched;
+       u32 arp_replied;
+};
+
+struct ath6kl_mbox_info {
+       u32 htc_addr;
+       u32 htc_ext_addr;
+       u32 htc_ext_sz;
+
+       u32 block_size;
+
+       u32 gmbox_addr;
+
+       u32 gmbox_sz;
+};
+
+/*
+ * 802.11i defines an extended IV for use with non-WEP ciphers.
+ * When the EXTIV bit is set in the key id byte an additional
+ * 4 bytes immediately follow the IV for TKIP.  For CCMP the
+ * EXTIV bit is likewise set but the 8 bytes represent the
+ * CCMP header rather than IV+extended-IV.
+ */
+
+#define ATH6KL_KEYBUF_SIZE 16
+#define ATH6KL_MICBUF_SIZE (8+8)       /* space for both tx and rx */
+
+#define ATH6KL_KEY_XMIT  0x01
+#define ATH6KL_KEY_RECV  0x02
+#define ATH6KL_KEY_DEFAULT   0x80      /* default xmit key */
+
+/*
+ * WPA/RSN get/set key request.  Specify the key/cipher
+ * type and whether the key is to be used for sending and/or
+ * receiving.  The key index should be set only when working
+ * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
+ * Otherwise a unicast/pairwise key is specified by the bssid
+ * (on a station) or mac address (on an ap).  They key length
+ * must include any MIC key data; otherwise it should be no
+ * more than ATH6KL_KEYBUF_SIZE.
+ */
+struct ath6kl_req_key {
+       u8 ik_type;     /* key/cipher type */
+       u8 ik_pad;
+       u16 ik_keyix;   /* key index */
+       u8 ik_keylen;   /* key length in bytes */
+       u8 ik_flags;
+       u8 ik_macaddr[ETH_ALEN];
+       u64 ik_keyrsc;  /* key receive sequence counter */
+       u64 ik_keytsc;  /* key transmit sequence counter */
+       u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
+};
+
+/* Flag info */
+#define WMI_ENABLED    0
+#define WMI_READY      1
+#define CONNECTED      2
+#define STATS_UPDATE_PEND 3
+#define CONNECT_PEND     4
+#define WMM_ENABLED      5
+#define NETQ_STOPPED     6
+#define WMI_CTRL_EP_FULL  7
+#define DTIM_EXPIRED     8
+#define DESTROY_IN_PROGRESS  9
+#define NETDEV_REGISTERED    10
+#define SKIP_SCAN           11
+#define WLAN_ENABLED        12
+
+struct ath6kl {
+       struct device *dev;
+       struct net_device *net_dev;
+       struct ath6kl_bmi bmi;
+       const struct ath6kl_hif_ops *hif_ops;
+       struct wmi *wmi;
+       int tx_pending[ENDPOINT_MAX];
+       int total_tx_data_pend;
+       struct htc_target *htc_target;
+       void *hif_priv;
+       spinlock_t lock;
+       struct semaphore sem;
+       int ssid_len;
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+       u8 next_mode;
+       u8 nw_type;
+       u8 dot11_auth_mode;
+       u8 auth_mode;
+       u8 prwise_crypto;
+       u8 prwise_crypto_len;
+       u8 grp_crypto;
+       u8 grp_crpto_len;
+       u8 def_txkey_index;
+       struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
+       u8 bssid[ETH_ALEN];
+       u8 req_bssid[ETH_ALEN];
+       u16 ch_hint;
+       u16 bss_ch;
+       u16 listen_intvl_b;
+       u16 listen_intvl_t;
+       struct ath6kl_version version;
+       u32 target_type;
+       u8 tx_pwr;
+       struct net_device_stats net_stats;
+       struct target_stats target_stats;
+       struct ath6kl_node_mapping node_map[MAX_NODE_NUM];
+       u8 ibss_ps_enable;
+       u8 node_num;
+       u8 next_ep_id;
+       struct ath6kl_cookie *cookie_list;
+       u32 cookie_count;
+       enum htc_endpoint_id ac2ep_map[WMM_NUM_AC];
+       bool ac_stream_active[WMM_NUM_AC];
+       u8 ac_stream_pri_map[WMM_NUM_AC];
+       u8 hiac_stream_active_pri;
+       u8 ep2ac_map[ENDPOINT_MAX];
+       enum htc_endpoint_id ctrl_ep;
+       struct htc_credit_state_info credit_state_info;
+       u32 connect_ctrl_flags;
+       u32 user_key_ctrl;
+       u8 usr_bss_filter;
+       struct ath6kl_sta sta_list[AP_MAX_NUM_STA];
+       u8 sta_list_index;
+       struct ath6kl_req_key ap_mode_bkey;
+       struct sk_buff_head mcastpsq;
+       spinlock_t mcastpsq_lock;
+       u8 intra_bss;
+       struct aggr_info *aggr_cntxt;
+       struct wmi_ap_mode_stat ap_stats;
+       u8 ap_country_code[3];
+       struct list_head amsdu_rx_buffer_queue;
+       struct timer_list disconnect_timer;
+       u8 rx_meta_ver;
+       struct wireless_dev *wdev;
+       struct cfg80211_scan_request *scan_req;
+       struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
+       enum sme_state sme_state;
+       enum wlan_low_pwr_state wlan_pwr_state;
+       struct wmi_scan_params_cmd sc_params;
+#define AR_MCAST_FILTER_MAC_ADDR_SIZE  4
+       u8 auto_auth_stage;
+
+       u16 conf_flags;
+       wait_queue_head_t event_wq;
+       struct ath6kl_mbox_info mbox_info;
+
+       struct ath6kl_cookie cookie_mem[MAX_COOKIE_NUM];
+       int reconnect_flag;
+       unsigned long flag;
+
+       u8 *fw_board;
+       size_t fw_board_len;
+
+       u8 *fw_otp;
+       size_t fw_otp_len;
+
+       u8 *fw;
+       size_t fw_len;
+
+       u8 *fw_patch;
+       size_t fw_patch_len;
+
+       struct workqueue_struct *ath6kl_wq;
+
+       struct ath6kl_node_table scan_table;
+};
+
+static inline void *ath6kl_priv(struct net_device *dev)
+{
+       return wdev_priv(dev->ieee80211_ptr);
+}
+
+static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
+                                              *cred_info,
+                                              struct htc_endpoint_credit_dist
+                                              *ep_dist, int credits)
+{
+       ep_dist->credits += credits;
+       ep_dist->cred_assngd += credits;
+       cred_info->cur_free_credits -= credits;
+}
+
+void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
+int ath6kl_configure_target(struct ath6kl *ar);
+void ath6kl_detect_error(unsigned long ptr);
+void disconnect_timer_handler(unsigned long ptr);
+void init_netdev(struct net_device *dev);
+void ath6kl_cookie_init(struct ath6kl *ar);
+void ath6kl_cookie_cleanup(struct ath6kl *ar);
+void ath6kl_rx(struct htc_target *target, struct htc_packet *packet);
+void ath6kl_tx_complete(void *context, struct list_head *packet_queue);
+enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
+                                              struct htc_packet *packet);
+void ath6kl_stop_txrx(struct ath6kl *ar);
+void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
+int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
+                          u8 *data, u32 length, bool read);
+int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data);
+void ath6kl_init_profile_info(struct ath6kl *ar);
+void ath6kl_tx_data_cleanup(struct ath6kl *ar);
+void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
+                         bool get_dbglogs);
+
+struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
+void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
+int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
+
+struct aggr_info *aggr_init(struct net_device *dev);
+void ath6kl_rx_refill(struct htc_target *target,
+                     enum htc_endpoint_id endpoint);
+void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
+struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
+                                           enum htc_endpoint_id endpoint,
+                                           int len);
+void aggr_module_destroy(struct aggr_info *aggr_info);
+void aggr_reset_state(struct aggr_info *aggr_info);
+
+struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 * node_addr);
+struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
+
+void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
+int ath6kl_control_tx(void *devt, struct sk_buff *skb,
+                     enum htc_endpoint_id eid);
+void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
+                         u8 *bssid, u16 listen_int,
+                         u16 beacon_int, enum network_type net_type,
+                         u8 beacon_ie_len, u8 assoc_req_len,
+                         u8 assoc_resp_len, u8 *assoc_info);
+void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
+                            u8 *bssid, u8 assoc_resp_len,
+                            u8 *assoc_info, u16 prot_reason_status);
+void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast);
+void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr);
+void ath6kl_scan_complete_evt(struct ath6kl *ar, int status);
+void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len);
+void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active);
+enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac);
+
+void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
+
+void ath6kl_dtimexpiry_event(struct ath6kl *ar);
+void ath6kl_disconnect(struct ath6kl *ar);
+void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
+void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
+                            u8 win_sz);
+void ath6kl_wakeup_event(void *dev);
+void ath6kl_target_failure(struct ath6kl *ar);
+
+void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni);
+#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
new file mode 100644 (file)
index 0000000..316136c
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 "core.h"
+#include "debug.h"
+
+int ath6kl_printk(const char *level, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+       int rtn;
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       rtn = printk("%sath6kl: %pV", level, &vaf);
+
+       va_end(args);
+
+       return rtn;
+}
+
+#ifdef CONFIG_ATH6KL_DEBUG
+void ath6kl_dump_registers(struct ath6kl_device *dev,
+                          struct ath6kl_irq_proc_registers *irq_proc_reg,
+                          struct ath6kl_irq_enable_reg *irq_enable_reg)
+{
+
+       ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
+
+       if (irq_proc_reg != NULL) {
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                       "Host Int status:           0x%x\n",
+                       irq_proc_reg->host_int_status);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "CPU Int status:            0x%x\n",
+                       irq_proc_reg->cpu_int_status);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Error Int status:          0x%x\n",
+                       irq_proc_reg->error_int_status);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Counter Int status:        0x%x\n",
+                       irq_proc_reg->counter_int_status);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Mbox Frame:                0x%x\n",
+                       irq_proc_reg->mbox_frame);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Rx Lookahead Valid:        0x%x\n",
+                       irq_proc_reg->rx_lkahd_valid);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Rx Lookahead 0:            0x%x\n",
+                       irq_proc_reg->rx_lkahd[0]);
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Rx Lookahead 1:            0x%x\n",
+                       irq_proc_reg->rx_lkahd[1]);
+
+               if (dev->ar->mbox_info.gmbox_addr != 0) {
+                       /*
+                        * If the target supports GMBOX hardware, dump some
+                        * additional state.
+                        */
+                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                               "GMBOX Host Int status 2:   0x%x\n",
+                               irq_proc_reg->host_int_status2);
+                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                               "GMBOX RX Avail:            0x%x\n",
+                               irq_proc_reg->gmbox_rx_avail);
+                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                               "GMBOX lookahead alias 0:   0x%x\n",
+                               irq_proc_reg->rx_gmbox_lkahd_alias[0]);
+                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                               "GMBOX lookahead alias 1:   0x%x\n",
+                               irq_proc_reg->rx_gmbox_lkahd_alias[1]);
+               }
+
+       }
+
+       if (irq_enable_reg != NULL) {
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                       "Int status Enable:         0x%x\n",
+                       irq_enable_reg->int_status_en);
+               ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
+                       irq_enable_reg->cntr_int_status_en);
+       }
+       ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
+}
+
+static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
+{
+       ath6kl_dbg(ATH6KL_DBG_ANY,
+                  "--- endpoint: %d  svc_id: 0x%X ---\n",
+                  ep_dist->endpoint, ep_dist->svc_id);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags     : 0x%X\n",
+                  ep_dist->dist_flags);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm      : %d\n",
+                  ep_dist->cred_norm);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min       : %d\n",
+                  ep_dist->cred_min);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " credits        : %d\n",
+                  ep_dist->credits);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd    : %d\n",
+                  ep_dist->cred_assngd);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred      : %d\n",
+                  ep_dist->seek_cred);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz        : %d\n",
+                  ep_dist->cred_sz);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg   : %d\n",
+                  ep_dist->cred_per_msg);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist   : %d\n",
+                  ep_dist->cred_to_dist);
+       ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth      : %d\n",
+                  get_queue_depth(&((struct htc_endpoint *)
+                                    ep_dist->htc_rsvd)->txq));
+       ath6kl_dbg(ATH6KL_DBG_ANY,
+                  "----------------------------------\n");
+}
+
+void dump_cred_dist_stats(struct htc_target *target)
+{
+       struct htc_endpoint_credit_dist *ep_list;
+
+       if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC))
+               return;
+
+       list_for_each_entry(ep_list, &target->cred_dist_list, list)
+               dump_cred_dist(ep_list);
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:%p dist:%p\n",
+                  target->cred_dist_cntxt, NULL);
+       ath6kl_dbg(ATH6KL_DBG_TRC, "credit distribution, total : %d, free : %d\n",
+                  target->cred_dist_cntxt->total_avail_credits,
+                  target->cred_dist_cntxt->cur_free_credits);
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
new file mode 100644 (file)
index 0000000..66b3999
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2011 Atheros Communications 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 DEBUG_H
+#define DEBUG_H
+
+#include "htc_hif.h"
+
+enum ATH6K_DEBUG_MASK {
+       ATH6KL_DBG_WLAN_CONNECT = BIT(0),     /* wlan connect */
+       ATH6KL_DBG_WLAN_SCAN    = BIT(1),     /* wlan scan */
+       ATH6KL_DBG_WLAN_TX      = BIT(2),     /* wlan tx */
+       ATH6KL_DBG_WLAN_RX      = BIT(3),     /* wlan rx */
+       ATH6KL_DBG_BMI          = BIT(4),     /* bmi tracing */
+       ATH6KL_DBG_HTC_SEND     = BIT(5),     /* htc send */
+       ATH6KL_DBG_HTC_RECV     = BIT(6),     /* htc recv */
+       ATH6KL_DBG_IRQ          = BIT(7),     /* interrupt processing */
+       ATH6KL_DBG_PM           = BIT(8),     /* power management */
+       ATH6KL_DBG_WLAN_NODE    = BIT(9),     /* general wlan node tracing */
+       ATH6KL_DBG_WMI          = BIT(10),    /* wmi tracing */
+       ATH6KL_DBG_TRC          = BIT(11),    /* generic func tracing */
+       ATH6KL_DBG_SCATTER      = BIT(12),    /* hif scatter tracing */
+       ATH6KL_DBG_WLAN_CFG     = BIT(13),    /* cfg80211 i/f file tracing */
+       ATH6KL_DBG_RAW_BYTES    = BIT(14),    /* dump tx/rx and wmi frames */
+       ATH6KL_DBG_AGGR         = BIT(15),    /* aggregation */
+       ATH6KL_DBG_ANY          = 0xffffffff  /* enable all logs */
+};
+
+extern unsigned int debug_mask;
+extern int ath6kl_printk(const char *level, const char *fmt, ...)
+       __attribute__ ((format (printf, 2, 3)));
+
+#define ath6kl_info(fmt, ...)                          \
+       ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
+#define ath6kl_err(fmt, ...)                                   \
+       ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
+#define ath6kl_warn(fmt, ...)                                  \
+       ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
+
+#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
+
+#ifdef CONFIG_ATH6KL_DEBUG
+#define ath6kl_dbg(mask, fmt, ...)                                     \
+       ({                                                              \
+        int rtn;                                                       \
+        if (debug_mask & mask)                                         \
+               rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__);    \
+        else                                                           \
+               rtn = 0;                                                \
+                                                                       \
+        rtn;                                                           \
+        })
+
+static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+                                  const char *msg, const void *buf,
+                                  size_t len)
+{
+       if (debug_mask & mask) {
+               ath6kl_dbg(mask, "%s\n", msg);
+               print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
+       }
+}
+
+void ath6kl_dump_registers(struct ath6kl_device *dev,
+                          struct ath6kl_irq_proc_registers *irq_proc_reg,
+                          struct ath6kl_irq_enable_reg *irq_en_reg);
+void dump_cred_dist_stats(struct htc_target *target);
+#else
+static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
+                            const char *fmt, ...)
+{
+       return 0;
+}
+
+static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+                                  const char *msg, const void *buf,
+                                  size_t len)
+{
+}
+
+static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
+               struct ath6kl_irq_proc_registers *irq_proc_reg,
+               struct ath6kl_irq_enable_reg *irq_en_reg)
+{
+
+}
+static inline void dump_cred_dist_stats(struct htc_target *target)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
new file mode 100644 (file)
index 0000000..c923979
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 HIF_OPS_H
+#define HIF_OPS_H
+
+#include "hif.h"
+
+static inline int hif_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
+                                     u32 len, u32 request)
+{
+       return ar->hif_ops->read_write_sync(ar, addr, buf, len, request);
+}
+
+static inline int hif_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
+                                 u32 length, u32 request,
+                                 struct htc_packet *packet)
+{
+       return ar->hif_ops->write_async(ar, address, buffer, length,
+                                       request, packet);
+}
+static inline void ath6kl_hif_irq_enable(struct ath6kl *ar)
+{
+       return ar->hif_ops->irq_enable(ar);
+}
+
+static inline void ath6kl_hif_irq_disable(struct ath6kl *ar)
+{
+       return ar->hif_ops->irq_disable(ar);
+}
+
+static inline struct hif_scatter_req *hif_scatter_req_get(struct ath6kl *ar)
+{
+       return ar->hif_ops->scatter_req_get(ar);
+}
+
+static inline void hif_scatter_req_add(struct ath6kl *ar,
+                                      struct hif_scatter_req *s_req)
+{
+       return ar->hif_ops->scatter_req_add(ar, s_req);
+}
+
+static inline int ath6kl_hif_enable_scatter(struct ath6kl *ar)
+{
+       return ar->hif_ops->enable_scatter(ar);
+}
+
+static inline int ath6kl_hif_scat_req_rw(struct ath6kl *ar,
+                                        struct hif_scatter_req *scat_req)
+{
+       return ar->hif_ops->scat_req_rw(ar, scat_req);
+}
+
+static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
+{
+       return ar->hif_ops->cleanup_scatter(ar);
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
new file mode 100644 (file)
index 0000000..5ceff54
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 HIF_H
+#define HIF_H
+
+#include "common.h"
+#include "core.h"
+
+#include <linux/scatterlist.h>
+
+#define BUS_REQUEST_MAX_NUM                64
+#define HIF_MBOX_BLOCK_SIZE                128
+#define HIF_MBOX0_BLOCK_SIZE               1
+
+#define HIF_DMA_BUFFER_SIZE (32 * 1024)
+#define CMD53_FIXED_ADDRESS 1
+#define CMD53_INCR_ADDRESS  2
+
+#define MAX_SCATTER_REQUESTS             4
+#define MAX_SCATTER_ENTRIES_PER_REQ      16
+#define MAX_SCATTER_REQ_TRANSFER_SIZE    (32 * 1024)
+
+#define MANUFACTURER_ID_AR6003_BASE        0x300
+    /* SDIO manufacturer ID and Codes */
+#define MANUFACTURER_ID_ATH6KL_BASE_MASK     0xFF00
+#define MANUFACTURER_CODE                  0x271       /* Atheros */
+
+/* Mailbox address in SDIO address space */
+#define HIF_MBOX_BASE_ADDR                 0x800
+#define HIF_MBOX_WIDTH                     0x800
+
+#define HIF_MBOX_END_ADDR  (HTC_MAILBOX_NUM_MAX * HIF_MBOX_WIDTH - 1)
+
+/* version 1 of the chip has only a 12K extended mbox range */
+#define HIF_MBOX0_EXT_BASE_ADDR  0x4000
+#define HIF_MBOX0_EXT_WIDTH      (12*1024)
+
+/* GMBOX addresses */
+#define HIF_GMBOX_BASE_ADDR                0x7000
+#define HIF_GMBOX_WIDTH                    0x4000
+
+/* interrupt mode register */
+#define CCCR_SDIO_IRQ_MODE_REG         0xF0
+
+/* mode to enable special 4-bit interrupt assertion without clock */
+#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ   (1 << 0)
+
+struct bus_request {
+       struct list_head list;
+
+       /* request data */
+       u32 address;
+
+       u8 *buffer;
+       u32 length;
+       u32 request;
+       struct htc_packet *packet;
+       int status;
+
+       /* this is a scatter request */
+       struct hif_scatter_req *scat_req;
+};
+
+/* direction of transfer (read/write) */
+#define HIF_READ                    0x00000001
+#define HIF_WRITE                   0x00000002
+#define HIF_DIR_MASK                (HIF_READ | HIF_WRITE)
+
+/*
+ *     emode - This indicates the whether the command is to be executed in a
+ *             blocking or non-blocking fashion (HIF_SYNCHRONOUS/
+ *             HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
+ *             implemented using the asynchronous mode allowing the the bus
+ *             driver to indicate the completion of operation through the
+ *             registered callback routine. The requirement primarily comes
+ *             from the contexts these operations get called from (a driver's
+ *             transmit context or the ISR context in case of receive).
+ *             Support for both of these modes is essential.
+ */
+#define HIF_SYNCHRONOUS             0x00000010
+#define HIF_ASYNCHRONOUS            0x00000020
+#define HIF_EMODE_MASK              (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
+
+/*
+ *     dmode - An interface may support different kinds of commands based on
+ *             the tradeoff between the amount of data it can carry and the
+ *             setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
+ *             HIF_BLOCK_BASIS). In case of latter, the data is rounded off
+ *             to the nearest block size by padding. The size of the block is
+ *             configurable at compile time using the HIF_BLOCK_SIZE and is
+ *             negotiated with the target during initialization after the
+ *             ATH6KL interrupts are enabled.
+ */
+#define HIF_BYTE_BASIS              0x00000040
+#define HIF_BLOCK_BASIS             0x00000080
+#define HIF_DMODE_MASK              (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
+
+/*
+ *     amode - This indicates if the address has to be incremented on ATH6KL
+ *             after every read/write operation (HIF?FIXED_ADDRESS/
+ *             HIF_INCREMENTAL_ADDRESS).
+ */
+#define HIF_FIXED_ADDRESS           0x00000100
+#define HIF_INCREMENTAL_ADDRESS     0x00000200
+#define HIF_AMODE_MASK           (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_ASYNC_BYTE_INC                                  \
+       (HIF_WRITE | HIF_ASYNCHRONOUS |                         \
+        HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_ASYNC_BLOCK_INC                                 \
+       (HIF_WRITE | HIF_ASYNCHRONOUS |                         \
+        HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_SYNC_BYTE_FIX                                   \
+       (HIF_WRITE | HIF_SYNCHRONOUS |                          \
+        HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+
+#define HIF_WR_SYNC_BYTE_INC                                   \
+       (HIF_WRITE | HIF_SYNCHRONOUS |                          \
+        HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_SYNC_BLOCK_INC                                  \
+       (HIF_WRITE | HIF_SYNCHRONOUS |                          \
+        HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_RD_SYNC_BYTE_INC                                           \
+       (HIF_READ | HIF_SYNCHRONOUS |                                   \
+        HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_RD_SYNC_BYTE_FIX                                           \
+       (HIF_READ | HIF_SYNCHRONOUS |                                   \
+        HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+
+#define HIF_RD_ASYNC_BLOCK_FIX                                         \
+       (HIF_READ | HIF_ASYNCHRONOUS |                                  \
+        HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+
+#define HIF_RD_SYNC_BLOCK_FIX                                          \
+       (HIF_READ | HIF_SYNCHRONOUS |                                   \
+        HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+
+struct hif_scatter_item {
+       u8 *buf;
+       int len;
+       struct htc_packet *packet;
+};
+
+struct hif_scatter_req {
+       struct list_head list;
+       /* address for the read/write operation */
+       u32 addr;
+
+       /* request flags */
+       u32 req;
+
+       /* total length of entire transfer */
+       u32 len;
+
+       bool virt_scat;
+
+       void (*complete) (struct htc_target *, struct hif_scatter_req *);
+       int status;
+       int scat_entries;
+
+       struct bus_request *busrequest;
+       struct scatterlist *sgentries;
+
+       /* bounce buffer for upper layers to copy to/from */
+       u8 *virt_dma_buf;
+
+       struct hif_scatter_item scat_list[1];
+};
+
+struct ath6kl_hif_ops {
+       int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf,
+                              u32 len, u32 request);
+       int (*write_async)(struct ath6kl *ar, u32 address, u8 *buffer,
+                          u32 length, u32 request, struct htc_packet *packet);
+
+       void (*irq_enable)(struct ath6kl *ar);
+       void (*irq_disable)(struct ath6kl *ar);
+
+       struct hif_scatter_req *(*scatter_req_get)(struct ath6kl *ar);
+       void (*scatter_req_add)(struct ath6kl *ar,
+                               struct hif_scatter_req *s_req);
+       int (*enable_scatter)(struct ath6kl *ar);
+       int (*scat_req_rw) (struct ath6kl *ar,
+                           struct hif_scatter_req *scat_req);
+       void (*cleanup_scatter)(struct ath6kl *ar);
+};
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
new file mode 100644 (file)
index 0000000..a8dc5c3
--- /dev/null
@@ -0,0 +1,2457 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications 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 "core.h"
+#include "htc_hif.h"
+#include "debug.h"
+#include "hif-ops.h"
+#include <asm/unaligned.h>
+
+#define CALC_TXRX_PADDED_LEN(dev, len)  (__ALIGN_MASK((len), (dev)->block_mask))
+
+static void htc_prep_send_pkt(struct htc_packet *packet, u8 flags, int ctrl0,
+                             int ctrl1)
+{
+       struct htc_frame_hdr *hdr;
+
+       packet->buf -= HTC_HDR_LENGTH;
+       hdr =  (struct htc_frame_hdr *)packet->buf;
+
+       /* Endianess? */
+       put_unaligned((u16)packet->act_len, &hdr->payld_len);
+       hdr->flags = flags;
+       hdr->eid = packet->endpoint;
+       hdr->ctrl[0] = ctrl0;
+       hdr->ctrl[1] = ctrl1;
+}
+
+static void htc_reclaim_txctrl_buf(struct htc_target *target,
+                                  struct htc_packet *pkt)
+{
+       spin_lock_bh(&target->htc_lock);
+       list_add_tail(&pkt->list, &target->free_ctrl_txbuf);
+       spin_unlock_bh(&target->htc_lock);
+}
+
+static struct htc_packet *htc_get_control_buf(struct htc_target *target,
+                                             bool tx)
+{
+       struct htc_packet *packet = NULL;
+       struct list_head *buf_list;
+
+       buf_list = tx ? &target->free_ctrl_txbuf : &target->free_ctrl_rxbuf;
+
+       spin_lock_bh(&target->htc_lock);
+
+       if (list_empty(buf_list)) {
+               spin_unlock_bh(&target->htc_lock);
+               return NULL;
+       }
+
+       packet = list_first_entry(buf_list, struct htc_packet, list);
+       list_del(&packet->list);
+       spin_unlock_bh(&target->htc_lock);
+
+       if (tx)
+               packet->buf = packet->buf_start + HTC_HDR_LENGTH;
+
+       return packet;
+}
+
+static void htc_tx_comp_update(struct htc_target *target,
+                              struct htc_endpoint *endpoint,
+                              struct htc_packet *packet)
+{
+       packet->completion = NULL;
+       packet->buf += HTC_HDR_LENGTH;
+
+       if (!packet->status)
+               return;
+
+       ath6kl_err("req failed (status:%d, ep:%d, len:%d creds:%d)\n",
+                  packet->status, packet->endpoint, packet->act_len,
+                  packet->info.tx.cred_used);
+
+       /* on failure to submit, reclaim credits for this packet */
+       spin_lock_bh(&target->tx_lock);
+       endpoint->cred_dist.cred_to_dist +=
+                               packet->info.tx.cred_used;
+       endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq);
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+                  target->cred_dist_cntxt, &target->cred_dist_list);
+
+       ath6k_credit_distribute(target->cred_dist_cntxt,
+                               &target->cred_dist_list,
+                               HTC_CREDIT_DIST_SEND_COMPLETE);
+
+       spin_unlock_bh(&target->tx_lock);
+}
+
+static void htc_tx_complete(struct htc_endpoint *endpoint,
+                           struct list_head *txq)
+{
+       if (list_empty(txq))
+               return;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                  "send complete ep %d, (%d pkts)\n",
+                  endpoint->eid, get_queue_depth(txq));
+
+       ath6kl_tx_complete(endpoint->target->dev->ar, txq);
+}
+
+static void htc_tx_comp_handler(struct htc_target *target,
+                               struct htc_packet *packet)
+{
+       struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint];
+       struct list_head container;
+
+       htc_tx_comp_update(target, endpoint, packet);
+       INIT_LIST_HEAD(&container);
+       list_add_tail(&packet->list, &container);
+       /* do completion */
+       htc_tx_complete(endpoint, &container);
+}
+
+static void htc_async_tx_scat_complete(struct htc_target *target,
+                                      struct hif_scatter_req *scat_req)
+{
+       struct htc_endpoint *endpoint;
+       struct htc_packet *packet;
+       struct list_head tx_compq;
+       int i;
+
+       INIT_LIST_HEAD(&tx_compq);
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+               "htc_async_tx_scat_complete  total len: %d  entries: %d\n",
+               scat_req->len, scat_req->scat_entries);
+
+       if (scat_req->status)
+               ath6kl_err("send scatter req failed: %d\n", scat_req->status);
+
+       packet = scat_req->scat_list[0].packet;
+       endpoint = &target->endpoint[packet->endpoint];
+
+       /* walk through the scatter list and process */
+       for (i = 0; i < scat_req->scat_entries; i++) {
+               packet = scat_req->scat_list[i].packet;
+               if (!packet) {
+                       WARN_ON(1);
+                       return;
+               }
+
+               packet->status = scat_req->status;
+               htc_tx_comp_update(target, endpoint, packet);
+               list_add_tail(&packet->list, &tx_compq);
+       }
+
+       /* free scatter request */
+       hif_scatter_req_add(target->dev->ar, scat_req);
+
+       /* complete all packets */
+       htc_tx_complete(endpoint, &tx_compq);
+}
+
+static int htc_issue_send(struct htc_target *target, struct htc_packet *packet)
+{
+       int status;
+       bool sync = false;
+       u32 padded_len, send_len;
+
+       if (!packet->completion)
+               sync = true;
+
+       send_len = packet->act_len + HTC_HDR_LENGTH;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s: transmit len : %d (%s)\n",
+                  __func__, send_len, sync ? "sync" : "async");
+
+       padded_len = CALC_TXRX_PADDED_LEN(target, send_len);
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+               "DevSendPacket, padded len: %d mbox:0x%X (mode:%s)\n",
+               padded_len,
+               target->dev->ar->mbox_info.htc_addr,
+               sync ? "sync" : "async");
+
+       if (sync) {
+               status = hif_read_write_sync(target->dev->ar,
+                               target->dev->ar->mbox_info.htc_addr,
+                                packet->buf, padded_len,
+                                HIF_WR_SYNC_BLOCK_INC);
+
+               packet->status = status;
+                packet->buf += HTC_HDR_LENGTH;
+       } else
+               status = hif_write_async(target->dev->ar,
+                               target->dev->ar->mbox_info.htc_addr,
+                               packet->buf, padded_len,
+                               HIF_WR_ASYNC_BLOCK_INC, packet);
+
+       return status;
+}
+
+static int htc_check_credits(struct htc_target *target,
+                            struct htc_endpoint *ep, u8 *flags,
+                            enum htc_endpoint_id eid, unsigned int len,
+                            int *req_cred)
+{
+
+       *req_cred = (len > target->tgt_cred_sz) ?
+                    DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "creds required:%d got:%d\n",
+                  *req_cred, ep->cred_dist.credits);
+
+       if (ep->cred_dist.credits < *req_cred) {
+               if (eid == ENDPOINT_0)
+                       return -EINVAL;
+
+               /* Seek more credits */
+               ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+                          target->cred_dist_cntxt, &ep->cred_dist);
+
+               ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+
+               ep->cred_dist.seek_cred = 0;
+
+               if (ep->cred_dist.credits < *req_cred) {
+                       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                                  "not enough credits for ep %d - leaving packet in queue\n",
+                                  eid);
+                       return -EINVAL;
+               }
+       }
+
+       ep->cred_dist.credits -= *req_cred;
+       ep->ep_st.cred_cosumd += *req_cred;
+
+        /* When we are getting low on credits, ask for more */
+       if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
+               ep->cred_dist.seek_cred =
+               ep->cred_dist.cred_per_msg - ep->cred_dist.credits;
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+                          target->cred_dist_cntxt, &ep->cred_dist);
+
+               ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+
+               /* see if we were successful in getting more */
+               if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
+                       /* tell the target we need credits ASAP! */
+                       *flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
+                       ep->ep_st.cred_low_indicate += 1;
+                       ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "host needs credits\n");
+               }
+       }
+
+       return 0;
+}
+
+static void htc_tx_pkts_get(struct htc_target *target,
+                           struct htc_endpoint *endpoint,
+                           struct list_head *queue)
+{
+       int req_cred;
+       u8 flags;
+       struct htc_packet *packet;
+       unsigned int len;
+
+       while (true) {
+
+               flags = 0;
+
+               if (list_empty(&endpoint->txq))
+                       break;
+               packet = list_first_entry(&endpoint->txq, struct htc_packet,
+                                         list);
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                       "got head pkt:0x%p , queue depth: %d\n",
+                       packet, get_queue_depth(&endpoint->txq));
+
+               len = CALC_TXRX_PADDED_LEN(target,
+                                          packet->act_len + HTC_HDR_LENGTH);
+
+               if (htc_check_credits(target, endpoint, &flags,
+                                     packet->endpoint, len, &req_cred))
+                       break;
+
+               /* now we can fully move onto caller's queue */
+               packet = list_first_entry(&endpoint->txq, struct htc_packet,
+                                         list);
+               list_move_tail(&packet->list, queue);
+
+               /* save the number of credits this packet consumed */
+               packet->info.tx.cred_used = req_cred;
+
+               /* all TX packets are handled asynchronously */
+               packet->completion = htc_tx_comp_handler;
+               packet->context = target;
+               endpoint->ep_st.tx_issued += 1;
+
+               /* save send flags */
+               packet->info.tx.flags = flags;
+               packet->info.tx.seqno = endpoint->seqno;
+               endpoint->seqno++;
+       }
+}
+
+/* See if the padded tx length falls on a credit boundary */
+static int htc_get_credit_padding(unsigned int cred_sz, int *len,
+                                 struct htc_endpoint *ep)
+{
+       int rem_cred, cred_pad;
+
+       rem_cred = *len % cred_sz;
+
+       /* No padding needed */
+       if  (!rem_cred)
+               return 0;
+
+       if (!(ep->conn_flags & HTC_FLGS_TX_BNDL_PAD_EN))
+               return -1;
+
+       /*
+        * The transfer consumes a "partial" credit, this
+        * packet cannot be bundled unless we add
+        * additional "dummy" padding (max 255 bytes) to
+        * consume the entire credit.
+        */
+       cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred;
+
+       if ((cred_pad > 0) && (cred_pad <= 255))
+               *len += cred_pad;
+       else
+               /* The amount of padding is too large, send as non-bundled */
+               return -1;
+
+       return cred_pad;
+}
+
+static int htc_setup_send_scat_list(struct htc_target *target,
+                                   struct htc_endpoint *endpoint,
+                                   struct hif_scatter_req *scat_req,
+                                   int n_scat,
+                                   struct list_head *queue)
+{
+       struct htc_packet *packet;
+       int i, len, rem_scat, cred_pad;
+       int status = 0;
+
+       rem_scat = target->max_tx_bndl_sz;
+
+       for (i = 0; i < n_scat; i++) {
+               scat_req->scat_list[i].packet = NULL;
+
+               if (list_empty(queue))
+                       break;
+
+               packet = list_first_entry(queue, struct htc_packet, list);
+               len = CALC_TXRX_PADDED_LEN(target,
+                                          packet->act_len + HTC_HDR_LENGTH);
+
+               cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
+                                                 &len, endpoint);
+               if (cred_pad < 0) {
+                       status = -EINVAL;
+                       break;
+               }
+
+               if (rem_scat < len) {
+                       /* exceeds what we can transfer */
+                       status = -ENOSPC;
+                       break;
+               }
+
+               rem_scat -= len;
+               /* now remove it from the queue */
+               packet = list_first_entry(queue, struct htc_packet, list);
+               list_del(&packet->list);
+
+               scat_req->scat_list[i].packet = packet;
+               /* prepare packet and flag message as part of a send bundle */
+               htc_prep_send_pkt(packet,
+                               packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
+                               cred_pad, packet->info.tx.seqno);
+               scat_req->scat_list[i].buf = packet->buf;
+               scat_req->scat_list[i].len = len;
+
+               scat_req->len += len;
+               scat_req->scat_entries++;
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                          "%d, adding pkt : 0x%p len:%d (remaining space:%d)\n",
+                          i, packet, len, rem_scat);
+       }
+
+       /* Roll back scatter setup in case of any failure */
+       if (status || (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
+               for (i = scat_req->scat_entries - 1; i >= 0; i--) {
+                       packet = scat_req->scat_list[i].packet;
+                       if (packet) {
+                               packet->buf += HTC_HDR_LENGTH;
+                               list_add(&packet->list, queue);
+                       }
+               }
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * htc_issue_send_bundle: drain a queue and send as bundles
+ * this function may return without fully draining the queue
+ * when
+ *
+ *    1. scatter resources are exhausted
+ *    2. a message that will consume a partial credit will stop the
+ *    bundling process early
+ *    3. we drop below the minimum number of messages for a bundle
+ */
+static void htc_issue_send_bundle(struct htc_endpoint *endpoint,
+                                 struct list_head *queue,
+                                 int *sent_bundle, int *n_bundle_pkts)
+{
+       struct htc_target *target = endpoint->target;
+       struct hif_scatter_req *scat_req = NULL;
+       int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
+
+       while (true) {
+               n_scat = get_queue_depth(queue);
+               n_scat = min(n_scat, target->msg_per_bndl_max);
+
+               if (n_scat < HTC_MIN_HTC_MSGS_TO_BUNDLE)
+                       /* not enough to bundle */
+                       break;
+
+               scat_req = hif_scatter_req_get(target->dev->ar);
+
+               if (!scat_req) {
+                       /* no scatter resources  */
+                       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                               "no more scatter resources\n");
+                       break;
+               }
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "pkts to scatter: %d\n",
+                          n_scat);
+
+               scat_req->len = 0;
+               scat_req->scat_entries = 0;
+
+               if (htc_setup_send_scat_list(target, endpoint, scat_req,
+                                            n_scat, queue)) {
+                       hif_scatter_req_add(target->dev->ar, scat_req);
+                       break;
+               }
+
+               /* send path is always asynchronous */
+               scat_req->complete = htc_async_tx_scat_complete;
+               n_sent_bundle++;
+               tot_pkts_bundle += scat_req->scat_entries;
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                          "send scatter total bytes: %d , entries: %d\n",
+                          scat_req->len, scat_req->scat_entries);
+               ath6kldev_submit_scat_req(target->dev, scat_req, false);
+       }
+
+       *sent_bundle = n_sent_bundle;
+       *n_bundle_pkts = tot_pkts_bundle;
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_issue_send_bundle (sent:%d)\n",
+                  n_sent_bundle);
+
+       return;
+}
+
+static void htc_tx_from_ep_txq(struct htc_target *target,
+                              struct htc_endpoint *endpoint)
+{
+       struct list_head txq;
+       struct htc_packet *packet;
+       int bundle_sent;
+       int n_pkts_bundle;
+
+       spin_lock_bh(&target->tx_lock);
+
+       endpoint->tx_proc_cnt++;
+       if (endpoint->tx_proc_cnt > 1) {
+               endpoint->tx_proc_cnt--;
+               spin_unlock_bh(&target->tx_lock);
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_try_send (busy)\n");
+               return;
+       }
+
+       /*
+        * drain the endpoint TX queue for transmission as long
+        * as we have enough credits.
+        */
+       INIT_LIST_HEAD(&txq);
+
+       while (true) {
+
+               if (list_empty(&endpoint->txq))
+                       break;
+
+               htc_tx_pkts_get(target, endpoint, &txq);
+
+               if (list_empty(&txq))
+                       break;
+
+               spin_unlock_bh(&target->tx_lock);
+
+               bundle_sent = 0;
+               n_pkts_bundle = 0;
+
+               while (true) {
+                       /* try to send a bundle on each pass */
+                       if ((target->tx_bndl_enable) &&
+                           (get_queue_depth(&txq) >=
+                           HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
+                               int temp1 = 0, temp2 = 0;
+
+                               htc_issue_send_bundle(endpoint, &txq,
+                                                     &temp1, &temp2);
+                               bundle_sent += temp1;
+                               n_pkts_bundle += temp2;
+                       }
+
+                       if (list_empty(&txq))
+                               break;
+
+                       packet = list_first_entry(&txq, struct htc_packet,
+                                                 list);
+                       list_del(&packet->list);
+
+                       htc_prep_send_pkt(packet, packet->info.tx.flags,
+                                         0, packet->info.tx.seqno);
+                       htc_issue_send(target, packet);
+               }
+
+               spin_lock_bh(&target->tx_lock);
+
+               endpoint->ep_st.tx_bundles += bundle_sent;
+               endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;
+       }
+
+       endpoint->tx_proc_cnt = 0;
+       spin_unlock_bh(&target->tx_lock);
+}
+
+static bool htc_try_send(struct htc_target *target,
+                        struct htc_endpoint *endpoint,
+                        struct htc_packet *tx_pkt)
+{
+       struct htc_ep_callbacks ep_cb;
+       int txq_depth;
+       bool overflow = false;
+
+       ep_cb = endpoint->ep_cb;
+
+       spin_lock_bh(&target->tx_lock);
+       txq_depth = get_queue_depth(&endpoint->txq);
+       spin_unlock_bh(&target->tx_lock);
+
+       if (txq_depth >= endpoint->max_txq_depth)
+               overflow = true;
+
+       if (overflow)
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                          "ep %d, tx queue will overflow :%d , tx depth:%d, max:%d\n",
+                          endpoint->eid, overflow, txq_depth,
+                          endpoint->max_txq_depth);
+
+       if (overflow && ep_cb.tx_full) {
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                          "indicating overflowed tx packet: 0x%p\n", tx_pkt);
+
+               if (ep_cb.tx_full(endpoint->target, tx_pkt) ==
+                   HTC_SEND_FULL_DROP) {
+                       endpoint->ep_st.tx_dropped += 1;
+                       return false;
+               }
+       }
+
+       spin_lock_bh(&target->tx_lock);
+       list_add_tail(&tx_pkt->list, &endpoint->txq);
+       spin_unlock_bh(&target->tx_lock);
+
+       htc_tx_from_ep_txq(target, endpoint);
+
+       return true;
+}
+
+static void htc_chk_ep_txq(struct htc_target *target)
+{
+       struct htc_endpoint *endpoint;
+       struct htc_endpoint_credit_dist *cred_dist;
+
+       /*
+        * Run through the credit distribution list to see if there are
+        * packets queued. NOTE: no locks need to be taken since the
+        * distribution list is not dynamic (cannot be re-ordered) and we
+        * are not modifying any state.
+        */
+       list_for_each_entry(cred_dist, &target->cred_dist_list, list) {
+               endpoint = (struct htc_endpoint *)cred_dist->htc_rsvd;
+
+               spin_lock_bh(&target->tx_lock);
+               if (!list_empty(&endpoint->txq)) {
+                       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                                  "ep %d has %d credits and %d packets in tx queue\n",
+                                  cred_dist->endpoint,
+                                  endpoint->cred_dist.credits,
+                                  get_queue_depth(&endpoint->txq));
+                       spin_unlock_bh(&target->tx_lock);
+                       /*
+                        * Try to start the stalled queue, this list is
+                        * ordered by priority. If there are credits
+                        * available the highest priority queue will get a
+                        * chance to reclaim credits from lower priority
+                        * ones.
+                        */
+                       htc_tx_from_ep_txq(target, endpoint);
+                       spin_lock_bh(&target->tx_lock);
+               }
+               spin_unlock_bh(&target->tx_lock);
+       }
+}
+
+static int htc_setup_tx_complete(struct htc_target *target)
+{
+       struct htc_packet *send_pkt = NULL;
+       int status;
+
+       send_pkt = htc_get_control_buf(target, true);
+
+       if (!send_pkt)
+               return -ENOMEM;
+
+       if (target->htc_tgt_ver >= HTC_VERSION_2P1) {
+               struct htc_setup_comp_ext_msg *setup_comp_ext;
+               u32 flags = 0;
+
+               setup_comp_ext =
+                   (struct htc_setup_comp_ext_msg *)send_pkt->buf;
+               memset(setup_comp_ext, 0, sizeof(*setup_comp_ext));
+               setup_comp_ext->msg_id =
+                       cpu_to_le16(HTC_MSG_SETUP_COMPLETE_EX_ID);
+
+               if (target->msg_per_bndl_max > 0) {
+                       /* Indicate HTC bundling to the target */
+                       flags |= HTC_SETUP_COMP_FLG_RX_BNDL_EN;
+                       setup_comp_ext->msg_per_rxbndl =
+                                               target->msg_per_bndl_max;
+               }
+
+               memcpy(&setup_comp_ext->flags, &flags,
+                      sizeof(setup_comp_ext->flags));
+               set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
+                                      sizeof(struct htc_setup_comp_ext_msg),
+                                      ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
+
+       } else {
+               struct htc_setup_comp_msg *setup_comp;
+               setup_comp = (struct htc_setup_comp_msg *)send_pkt->buf;
+               memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
+               setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
+               set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
+                                      sizeof(struct htc_setup_comp_msg),
+                                      ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
+       }
+
+       /* we want synchronous operation */
+       send_pkt->completion = NULL;
+       htc_prep_send_pkt(send_pkt, 0, 0, 0);
+       status = htc_issue_send(target, send_pkt);
+
+       if (send_pkt != NULL)
+               htc_reclaim_txctrl_buf(target, send_pkt);
+
+       return status;
+}
+
+void ath6kl_htc_set_credit_dist(struct htc_target *target,
+                               struct htc_credit_state_info *cred_dist_cntxt,
+                               u16 srvc_pri_order[], int list_len)
+{
+       struct htc_endpoint *endpoint;
+       int i, ep;
+
+       target->cred_dist_cntxt = cred_dist_cntxt;
+
+       list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list,
+                     &target->cred_dist_list);
+
+       for (i = 0; i < list_len; i++) {
+               for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
+                       endpoint = &target->endpoint[ep];
+                       if (endpoint->svc_id == srvc_pri_order[i]) {
+                               list_add_tail(&endpoint->cred_dist.list,
+                                             &target->cred_dist_list);
+                               break;
+                       }
+               }
+               if (ep >= ENDPOINT_MAX) {
+                       WARN_ON(1);
+                       return;
+               }
+       }
+}
+
+int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
+{
+       struct htc_endpoint *endpoint;
+       struct list_head queue;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                  "htc_tx: ep id: %d, buf: 0x%p, len: %d\n",
+                  packet->endpoint, packet->buf, packet->act_len);
+
+       if (packet->endpoint >= ENDPOINT_MAX) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       endpoint = &target->endpoint[packet->endpoint];
+
+       if (!htc_try_send(target, endpoint, packet)) {
+               packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
+                                -ECANCELED : -ENOSPC;
+               INIT_LIST_HEAD(&queue);
+               list_add(&packet->list, &queue);
+               htc_tx_complete(endpoint, &queue);
+       }
+
+       return 0;
+}
+
+/* flush endpoint TX queue */
+void ath6kl_htc_flush_txep(struct htc_target *target,
+                          enum htc_endpoint_id eid, u16 tag)
+{
+       struct htc_packet *packet, *tmp_pkt;
+       struct list_head discard_q, container;
+       struct htc_endpoint *endpoint = &target->endpoint[eid];
+
+       if (!endpoint->svc_id) {
+               WARN_ON(1);
+               return;
+       }
+
+       /* initialize the discard queue */
+       INIT_LIST_HEAD(&discard_q);
+
+       spin_lock_bh(&target->tx_lock);
+
+       list_for_each_entry_safe(packet, tmp_pkt, &endpoint->txq, list) {
+               if ((tag == HTC_TX_PACKET_TAG_ALL) ||
+                   (tag == packet->info.tx.tag))
+                       list_move_tail(&packet->list, &discard_q);
+       }
+
+       spin_unlock_bh(&target->tx_lock);
+
+       list_for_each_entry_safe(packet, tmp_pkt, &discard_q, list) {
+               packet->status = -ECANCELED;
+               list_del(&packet->list);
+               ath6kl_dbg(ATH6KL_DBG_TRC,
+                       "flushing tx pkt:0x%p, len:%d, ep:%d tag:0x%X\n",
+                       packet, packet->act_len,
+                       packet->endpoint, packet->info.tx.tag);
+
+               INIT_LIST_HEAD(&container);
+               list_add_tail(&packet->list, &container);
+               htc_tx_complete(endpoint, &container);
+       }
+
+}
+
+static void ath6kl_htc_flush_txep_all(struct htc_target *target)
+{
+       struct htc_endpoint *endpoint;
+       int i;
+
+       dump_cred_dist_stats(target);
+
+       for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+               endpoint = &target->endpoint[i];
+               if (endpoint->svc_id == 0)
+                       /* not in use.. */
+                       continue;
+               ath6kl_htc_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL);
+       }
+}
+
+void ath6kl_htc_indicate_activity_change(struct htc_target *target,
+                                        enum htc_endpoint_id eid, bool active)
+{
+       struct htc_endpoint *endpoint = &target->endpoint[eid];
+       bool dist = false;
+
+       if (endpoint->svc_id == 0) {
+               WARN_ON(1);
+               return;
+       }
+
+       spin_lock_bh(&target->tx_lock);
+
+       if (active) {
+               if (!(endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE)) {
+                       endpoint->cred_dist.dist_flags |= HTC_EP_ACTIVE;
+                       dist = true;
+               }
+       } else {
+               if (endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE) {
+                       endpoint->cred_dist.dist_flags &= ~HTC_EP_ACTIVE;
+                       dist = true;
+               }
+       }
+
+       if (dist) {
+               endpoint->cred_dist.txq_depth =
+                       get_queue_depth(&endpoint->txq);
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+                          target->cred_dist_cntxt, &target->cred_dist_list);
+
+               ath6k_credit_distribute(target->cred_dist_cntxt,
+                                       &target->cred_dist_list,
+                                       HTC_CREDIT_DIST_ACTIVITY_CHANGE);
+       }
+
+       spin_unlock_bh(&target->tx_lock);
+
+       if (dist && !active)
+               htc_chk_ep_txq(target);
+}
+
+/* HTC Rx */
+
+static inline void htc_update_rx_stats(struct htc_endpoint *endpoint,
+                                      int n_look_ahds)
+{
+       endpoint->ep_st.rx_pkts++;
+       if (n_look_ahds == 1)
+               endpoint->ep_st.rx_lkahds++;
+       else if (n_look_ahds > 1)
+               endpoint->ep_st.rx_bundle_lkahd++;
+}
+
+static inline bool htc_valid_rx_frame_len(struct htc_target *target,
+                                         enum htc_endpoint_id eid, int len)
+{
+       return (eid == target->dev->ar->ctrl_ep) ?
+               len <= ATH6KL_BUFFER_SIZE : len <= ATH6KL_AMSDU_BUFFER_SIZE;
+}
+
+static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
+{
+       struct list_head queue;
+
+       INIT_LIST_HEAD(&queue);
+       list_add_tail(&packet->list, &queue);
+       return ath6kl_htc_add_rxbuf_multiple(target, &queue);
+}
+
+static void htc_reclaim_rxbuf(struct htc_target *target,
+                             struct htc_packet *packet,
+                             struct htc_endpoint *ep)
+{
+       if (packet->info.rx.rx_flags & HTC_RX_PKT_NO_RECYCLE) {
+               htc_rxpkt_reset(packet);
+               packet->status = -ECANCELED;
+               ep->ep_cb.rx(ep->target, packet);
+       } else {
+               htc_rxpkt_reset(packet);
+               htc_add_rxbuf((void *)(target), packet);
+       }
+}
+
+static void reclaim_rx_ctrl_buf(struct htc_target *target,
+                               struct htc_packet *packet)
+{
+       spin_lock_bh(&target->htc_lock);
+       list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
+       spin_unlock_bh(&target->htc_lock);
+}
+
+static int dev_rx_pkt(struct htc_target *target, struct htc_packet *packet,
+                     u32 rx_len)
+{
+       struct ath6kl_device *dev = target->dev;
+       u32 padded_len;
+       int status;
+
+       padded_len = CALC_TXRX_PADDED_LEN(target, rx_len);
+
+       if (padded_len > packet->buf_len) {
+               ath6kl_err("not enough receive space for packet - padlen:%d recvlen:%d bufferlen:%d\n",
+                          padded_len, rx_len, packet->buf_len);
+               return -ENOMEM;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                  "dev_rx_pkt (0x%p : hdr:0x%X) padded len: %d mbox:0x%X (mode:%s)\n",
+                  packet, packet->info.rx.exp_hdr,
+                  padded_len, dev->ar->mbox_info.htc_addr, "sync");
+
+       status = hif_read_write_sync(dev->ar,
+                                    dev->ar->mbox_info.htc_addr,
+                                    packet->buf, padded_len,
+                                    HIF_RD_SYNC_BLOCK_FIX);
+
+       packet->status = status;
+
+       return status;
+}
+
+/*
+ * optimization for recv packets, we can indicate a
+ * "hint" that there are more  single-packets to fetch
+ * on this endpoint.
+ */
+static void set_rxpkt_indication_flag(u32 lk_ahd,
+                                     struct htc_endpoint *endpoint,
+                                     struct htc_packet *packet)
+{
+       struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;
+
+       if (htc_hdr->eid == packet->endpoint) {
+               if (!list_empty(&endpoint->rx_bufq))
+                       packet->info.rx.indicat_flags |=
+                                       HTC_RX_FLAGS_INDICATE_MORE_PKTS;
+       }
+}
+
+static void chk_rx_water_mark(struct htc_endpoint *endpoint)
+{
+       struct htc_ep_callbacks ep_cb = endpoint->ep_cb;
+
+       if (ep_cb.rx_refill_thresh > 0) {
+               spin_lock_bh(&endpoint->target->rx_lock);
+               if (get_queue_depth(&endpoint->rx_bufq)
+                   < ep_cb.rx_refill_thresh) {
+                       spin_unlock_bh(&endpoint->target->rx_lock);
+                       ep_cb.rx_refill(endpoint->target, endpoint->eid);
+                       return;
+               }
+               spin_unlock_bh(&endpoint->target->rx_lock);
+       }
+}
+
+/* This function is called with rx_lock held */
+static int htc_setup_rxpkts(struct htc_target *target, struct htc_endpoint *ep,
+                           u32 *lk_ahds, struct list_head *queue, int n_msg)
+{
+       struct htc_packet *packet;
+       /* FIXME: type of lk_ahds can't be right */
+       struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)lk_ahds;
+       struct htc_ep_callbacks ep_cb;
+       int status = 0, j, full_len;
+       bool no_recycle;
+
+       full_len = CALC_TXRX_PADDED_LEN(target,
+                                       le16_to_cpu(htc_hdr->payld_len) +
+                                       sizeof(*htc_hdr));
+
+       if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) {
+               ath6kl_warn("Rx buffer requested with invalid length\n");
+               return -EINVAL;
+       }
+
+       ep_cb = ep->ep_cb;
+       for (j = 0; j < n_msg; j++) {
+
+               /*
+                * Reset flag, any packets allocated using the
+                * rx_alloc() API cannot be recycled on
+                * cleanup,they must be explicitly returned.
+                */
+               no_recycle = false;
+
+               if (ep_cb.rx_allocthresh &&
+                   (full_len > ep_cb.rx_alloc_thresh)) {
+                       ep->ep_st.rx_alloc_thresh_hit += 1;
+                       ep->ep_st.rxalloc_thresh_byte +=
+                               le16_to_cpu(htc_hdr->payld_len);
+
+                       spin_unlock_bh(&target->rx_lock);
+                       no_recycle = true;
+
+                       packet = ep_cb.rx_allocthresh(ep->target, ep->eid,
+                                                     full_len);
+                       spin_lock_bh(&target->rx_lock);
+               } else {
+                       /* refill handler is being used */
+                       if (list_empty(&ep->rx_bufq)) {
+                               if (ep_cb.rx_refill) {
+                                       spin_unlock_bh(&target->rx_lock);
+                                       ep_cb.rx_refill(ep->target, ep->eid);
+                                       spin_lock_bh(&target->rx_lock);
+                               }
+                       }
+
+                       if (list_empty(&ep->rx_bufq))
+                               packet = NULL;
+                       else {
+                               packet = list_first_entry(&ep->rx_bufq,
+                                               struct htc_packet, list);
+                               list_del(&packet->list);
+                       }
+               }
+
+               if (!packet) {
+                       target->rx_st_flags |= HTC_RECV_WAIT_BUFFERS;
+                       target->ep_waiting = ep->eid;
+                       return -ENOSPC;
+               }
+
+               /* clear flags */
+               packet->info.rx.rx_flags = 0;
+               packet->info.rx.indicat_flags = 0;
+               packet->status = 0;
+
+               if (no_recycle)
+                       /*
+                        * flag that these packets cannot be
+                        * recycled, they have to be returned to
+                        * the user
+                        */
+                       packet->info.rx.rx_flags |= HTC_RX_PKT_NO_RECYCLE;
+
+               /* Caller needs to free this upon any failure */
+               list_add_tail(&packet->list, queue);
+
+               if (target->htc_flags & HTC_OP_STATE_STOPPING) {
+                       status = -ECANCELED;
+                       break;
+               }
+
+               if (j) {
+                       packet->info.rx.rx_flags |= HTC_RX_PKT_REFRESH_HDR;
+                       packet->info.rx.exp_hdr = 0xFFFFFFFF;
+               } else
+                       /* set expected look ahead */
+                       packet->info.rx.exp_hdr = *lk_ahds;
+
+               packet->act_len = le16_to_cpu(htc_hdr->payld_len) +
+                       HTC_HDR_LENGTH;
+       }
+
+       return status;
+}
+
+static int alloc_and_prep_rxpkts(struct htc_target *target,
+                                u32 lk_ahds[], int msg,
+                                struct htc_endpoint *endpoint,
+                                struct list_head *queue)
+{
+       int status = 0;
+       struct htc_packet *packet, *tmp_pkt;
+       struct htc_frame_hdr *htc_hdr;
+       int i, n_msg;
+
+       spin_lock_bh(&target->rx_lock);
+
+       for (i = 0; i < msg; i++) {
+
+               htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
+
+               if (htc_hdr->eid >= ENDPOINT_MAX) {
+                       ath6kl_err("invalid ep in look-ahead: %d\n",
+                                  htc_hdr->eid);
+                       status = -ENOMEM;
+                       break;
+               }
+
+               if (htc_hdr->eid != endpoint->eid) {
+                       ath6kl_err("invalid ep in look-ahead: %d should be : %d (index:%d)\n",
+                                  htc_hdr->eid, endpoint->eid, i);
+                       status = -ENOMEM;
+                       break;
+               }
+
+               if (le16_to_cpu(htc_hdr->payld_len) > HTC_MAX_PAYLOAD_LENGTH) {
+                       ath6kl_err("payload len %d exceeds max htc : %d !\n",
+                                  htc_hdr->payld_len,
+                                  (u32) HTC_MAX_PAYLOAD_LENGTH);
+                       status = -ENOMEM;
+                       break;
+               }
+
+               if (endpoint->svc_id == 0) {
+                       ath6kl_err("ep %d is not connected !\n", htc_hdr->eid);
+                       status = -ENOMEM;
+                       break;
+               }
+
+               if (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) {
+                       /*
+                        * HTC header indicates that every packet to follow
+                        * has the same padded length so that it can be
+                        * optimally fetched as a full bundle.
+                        */
+                       n_msg = (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) >>
+                               HTC_FLG_RX_BNDL_CNT_S;
+
+                       /* the count doesn't include the starter frame */
+                       n_msg++;
+                       if (n_msg > target->msg_per_bndl_max) {
+                               status = -ENOMEM;
+                               break;
+                       }
+
+                       endpoint->ep_st.rx_bundle_from_hdr += 1;
+                       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                                  "htc hdr indicates :%d msg can be fetched as a bundle\n",
+                                  n_msg);
+               } else
+                       /* HTC header only indicates 1 message to fetch */
+                       n_msg = 1;
+
+               /* Setup packet buffers for each message */
+               status = htc_setup_rxpkts(target, endpoint, &lk_ahds[i], queue,
+                                         n_msg);
+
+               /*
+                * This is due to unavailabilty of buffers to rx entire data.
+                * Return no error so that free buffers from queue can be used
+                * to receive partial data.
+                */
+               if (status == -ENOSPC) {
+                       spin_unlock_bh(&target->rx_lock);
+                       return 0;
+               }
+
+               if (status)
+                       break;
+       }
+
+       spin_unlock_bh(&target->rx_lock);
+
+       if (status) {
+               list_for_each_entry_safe(packet, tmp_pkt, queue, list) {
+                       list_del(&packet->list);
+                       htc_reclaim_rxbuf(target, packet,
+                                         &target->endpoint[packet->endpoint]);
+               }
+       }
+
+       return status;
+}
+
+static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
+{
+       if (packets->endpoint != ENDPOINT_0) {
+               WARN_ON(1);
+               return;
+       }
+
+       if (packets->status == -ECANCELED) {
+               reclaim_rx_ctrl_buf(context, packets);
+               return;
+       }
+
+       if (packets->act_len > 0) {
+               ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
+                       packets->act_len + HTC_HDR_LENGTH);
+
+               ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
+                            "Unexpected ENDPOINT 0 Message",
+                            packets->buf - HTC_HDR_LENGTH,
+                            packets->act_len + HTC_HDR_LENGTH);
+       }
+
+       htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
+}
+
+static void htc_proc_cred_rpt(struct htc_target *target,
+                             struct htc_credit_report *rpt,
+                             int n_entries,
+                             enum htc_endpoint_id from_ep)
+{
+       struct htc_endpoint *endpoint;
+       int tot_credits = 0, i;
+       bool dist = false;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                  "htc_proc_cred_rpt, credit report entries:%d\n", n_entries);
+
+       spin_lock_bh(&target->tx_lock);
+
+       for (i = 0; i < n_entries; i++, rpt++) {
+               if (rpt->eid >= ENDPOINT_MAX) {
+                       WARN_ON(1);
+                       spin_unlock_bh(&target->tx_lock);
+                       return;
+               }
+
+               endpoint = &target->endpoint[rpt->eid];
+
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, " ep %d got %d credits\n",
+                       rpt->eid, rpt->credits);
+
+               endpoint->ep_st.tx_cred_rpt += 1;
+               endpoint->ep_st.cred_retnd += rpt->credits;
+
+               if (from_ep == rpt->eid) {
+                       /*
+                        * This credit report arrived on the same endpoint
+                        * indicating it arrived in an RX packet.
+                        */
+                       endpoint->ep_st.cred_from_rx += rpt->credits;
+                       endpoint->ep_st.cred_rpt_from_rx += 1;
+               } else if (from_ep == ENDPOINT_0) {
+                       /* credit arrived on endpoint 0 as a NULL message */
+                       endpoint->ep_st.cred_from_ep0 += rpt->credits;
+                       endpoint->ep_st.cred_rpt_ep0 += 1;
+               } else {
+                       endpoint->ep_st.cred_from_other += rpt->credits;
+                       endpoint->ep_st.cred_rpt_from_other += 1;
+               }
+
+               if (rpt->eid == ENDPOINT_0)
+                       /* always give endpoint 0 credits back */
+                       endpoint->cred_dist.credits += rpt->credits;
+               else {
+                       endpoint->cred_dist.cred_to_dist += rpt->credits;
+                       dist = true;
+               }
+
+               /*
+                * Refresh tx depth for distribution function that will
+                * recover these credits NOTE: this is only valid when
+                * there are credits to recover!
+                */
+               endpoint->cred_dist.txq_depth =
+                       get_queue_depth(&endpoint->txq);
+
+               tot_credits += rpt->credits;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+                  "report indicated %d credits to distribute\n",
+                  tot_credits);
+
+       if (dist) {
+               /*
+                * This was a credit return based on a completed send
+                * operations note, this is done with the lock held
+                */
+               ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+                          target->cred_dist_cntxt, &target->cred_dist_list);
+
+               ath6k_credit_distribute(target->cred_dist_cntxt,
+                                       &target->cred_dist_list,
+                                       HTC_CREDIT_DIST_SEND_COMPLETE);
+       }
+
+       spin_unlock_bh(&target->tx_lock);
+
+       if (tot_credits)
+               htc_chk_ep_txq(target);
+}
+
+static int htc_parse_trailer(struct htc_target *target,
+                            struct htc_record_hdr *record,
+                            u8 *record_buf, u32 *next_lk_ahds,
+                            enum htc_endpoint_id endpoint,
+                            int *n_lk_ahds)
+{
+       struct htc_bundle_lkahd_rpt *bundle_lkahd_rpt;
+       struct htc_lookahead_report *lk_ahd;
+       int len;
+
+       switch (record->rec_id) {
+       case HTC_RECORD_CREDITS:
+               len = record->len / sizeof(struct htc_credit_report);
+               if (!len) {
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+
+               htc_proc_cred_rpt(target,
+                                 (struct htc_credit_report *) record_buf,
+                                 len, endpoint);
+               break;
+       case HTC_RECORD_LOOKAHEAD:
+               len = record->len / sizeof(*lk_ahd);
+               if (!len) {
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+
+               lk_ahd = (struct htc_lookahead_report *) record_buf;
+               if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF))
+                   && next_lk_ahds) {
+
+                       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                                  "lk_ahd report found (pre valid:0x%X, post valid:0x%X)\n",
+                                  lk_ahd->pre_valid, lk_ahd->post_valid);
+
+                       /* look ahead bytes are valid, copy them over */
+                       memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);
+
+                       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead",
+                                       next_lk_ahds, 4);
+
+                       *n_lk_ahds = 1;
+               }
+               break;
+       case HTC_RECORD_LOOKAHEAD_BUNDLE:
+               len = record->len / sizeof(*bundle_lkahd_rpt);
+               if (!len || (len > HTC_HOST_MAX_MSG_PER_BUNDLE)) {
+                       WARN_ON(1);
+                       return -EINVAL;
+               }
+
+               if (next_lk_ahds) {
+                       int i;
+
+                       bundle_lkahd_rpt =
+                               (struct htc_bundle_lkahd_rpt *) record_buf;
+
+                       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd",
+                                       record_buf, record->len);
+
+                       for (i = 0; i < len; i++) {
+                               memcpy((u8 *)&next_lk_ahds[i],
+                                      bundle_lkahd_rpt->lk_ahd, 4);
+                               bundle_lkahd_rpt++;
+                       }
+
+                       *n_lk_ahds = i;
+               }
+               break;
+       default:
+               ath6kl_err("unhandled record: id:%d len:%d\n",
+                          record->rec_id, record->len);
+               break;
+       }
+
+       return 0;
+
+}
+
+static int htc_proc_trailer(struct htc_target *target,
+                           u8 *buf, int len, u32 *next_lk_ahds,
+                           int *n_lk_ahds, enum htc_endpoint_id endpoint)
+{
+       struct htc_record_hdr *record;
+       int orig_len;
+       int status;
+       u8 *record_buf;
+       u8 *orig_buf;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len);
+
+       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", buf, len);
+
+       orig_buf = buf;
+       orig_len = len;
+       status = 0;
+
+       while (len > 0) {
+
+               if (len < sizeof(struct htc_record_hdr)) {
+                       status = -ENOMEM;
+                       break;
+               }
+               /* these are byte aligned structs */
+               record = (struct htc_record_hdr *) buf;
+               len -= sizeof(struct htc_record_hdr);
+               buf += sizeof(struct htc_record_hdr);
+
+               if (record->len > len) {
+                       ath6kl_err("invalid record len: %d (id:%d) buf has: %d bytes left\n",
+                                  record->len, record->rec_id, len);
+                       status = -ENOMEM;
+                       break;
+               }
+               record_buf = buf;
+
+               status = htc_parse_trailer(target, record, record_buf,
+                                          next_lk_ahds, endpoint, n_lk_ahds);
+
+               if (status)
+                       break;
+
+               /* advance buffer past this record for next time around */
+               buf += record->len;
+               len -= record->len;
+       }
+
+       if (status)
+               ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer",
+                               orig_buf, orig_len);
+
+       return status;
+}
+
+static int htc_proc_rxhdr(struct htc_target *target,
+                         struct htc_packet *packet,
+                         u32 *next_lkahds, int *n_lkahds)
+{
+       int status = 0;
+       u16 payload_len;
+       u32 lk_ahd;
+       struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)packet->buf;
+
+       if (n_lkahds != NULL)
+               *n_lkahds = 0;
+
+       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", packet->buf,
+                       packet->act_len);
+
+       /*
+        * NOTE: we cannot assume the alignment of buf, so we use the safe
+        * macros to retrieve 16 bit fields.
+        */
+       payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
+
+       memcpy((u8 *)&lk_ahd, packet->buf, sizeof(lk_ahd));
+
+       if (packet->info.rx.rx_flags & HTC_RX_PKT_REFRESH_HDR) {
+               /*
+                * Refresh the expected header and the actual length as it
+                * was unknown when this packet was grabbed as part of the
+                * bundle.
+                */
+               packet->info.rx.exp_hdr = lk_ahd;
+               packet->act_len = payload_len + HTC_HDR_LENGTH;
+
+               /* validate the actual header that was refreshed  */
+               if (packet->act_len > packet->buf_len) {
+                       ath6kl_err("refreshed hdr payload len (%d) in bundled recv is invalid (hdr: 0x%X)\n",
+                                  payload_len, lk_ahd);
+                       /*
+                        * Limit this to max buffer just to print out some
+                        * of the buffer.
+                        */
+                       packet->act_len = min(packet->act_len, packet->buf_len);
+                       status = -ENOMEM;
+                       goto fail_rx;
+               }
+
+               if (packet->endpoint != htc_hdr->eid) {
+                       ath6kl_err("refreshed hdr ep (%d) does not match expected ep (%d)\n",
+                                  htc_hdr->eid, packet->endpoint);
+                       status = -ENOMEM;
+                       goto fail_rx;
+               }
+       }
+
+       if (lk_ahd != packet->info.rx.exp_hdr) {
+               ath6kl_err("htc_proc_rxhdr, lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
+                          packet, packet->info.rx.rx_flags);
+               ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd",
+                               &packet->info.rx.exp_hdr, 4);
+               ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header",
+                               (u8 *)&lk_ahd, sizeof(lk_ahd));
+               status = -ENOMEM;
+               goto fail_rx;
+       }
+
+       if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
+               if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
+                   htc_hdr->ctrl[0] > payload_len) {
+                       ath6kl_err("htc_proc_rxhdr, invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
+                                  payload_len, htc_hdr->ctrl[0]);
+                       status = -ENOMEM;
+                       goto fail_rx;
+               }
+
+               if (packet->info.rx.rx_flags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
+                       next_lkahds = NULL;
+                       n_lkahds = NULL;
+               }
+
+               status = htc_proc_trailer(target, packet->buf + HTC_HDR_LENGTH
+                                         + payload_len - htc_hdr->ctrl[0],
+                                         htc_hdr->ctrl[0], next_lkahds,
+                                          n_lkahds, packet->endpoint);
+
+               if (status)
+                       goto fail_rx;
+
+               packet->act_len -= htc_hdr->ctrl[0];
+       }
+
+       packet->buf += HTC_HDR_LENGTH;
+       packet->act_len -= HTC_HDR_LENGTH;
+
+fail_rx:
+       if (status)
+               ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT",
+                               packet->buf,
+                               packet->act_len < 256 ? packet->act_len : 256);
+       else {
+               if (packet->act_len > 0)
+                       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
+                                       "HTC - Application Msg",
+                                       packet->buf, packet->act_len);
+       }
+
+       return status;
+}
+
+static void do_rx_completion(struct htc_endpoint *endpoint,
+                            struct htc_packet *packet)
+{
+               ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                          "htc calling ep %d recv callback on packet 0x%p\n",
+                          endpoint->eid, packet);
+               endpoint->ep_cb.rx(endpoint->target, packet);
+}
+
+static int htc_issue_rxpkt_bundle(struct htc_target *target,
+                                 struct list_head *rxq,
+                                 struct list_head *sync_compq,
+                                 int *n_pkt_fetched, bool part_bundle)
+{
+       struct hif_scatter_req *scat_req;
+       struct htc_packet *packet;
+       int rem_space = target->max_rx_bndl_sz;
+       int n_scat_pkt, status = 0, i, len;
+
+       n_scat_pkt = get_queue_depth(rxq);
+       n_scat_pkt = min(n_scat_pkt, target->msg_per_bndl_max);
+
+       if ((get_queue_depth(rxq) - n_scat_pkt) > 0) {
+               /*
+                * We were forced to split this bundle receive operation
+                * all packets in this partial bundle must have their
+                * lookaheads ignored.
+                */
+               part_bundle = true;
+
+               /*
+                * This would only happen if the target ignored our max
+                * bundle limit.
+                */
+               ath6kl_warn("htc_issue_rxpkt_bundle : partial bundle detected num:%d , %d\n",
+                           get_queue_depth(rxq), n_scat_pkt);
+       }
+
+       len = 0;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+               "htc_issue_rxpkt_bundle (numpackets: %d , actual : %d)\n",
+               get_queue_depth(rxq), n_scat_pkt);
+
+       scat_req = hif_scatter_req_get(target->dev->ar);
+
+       if (scat_req == NULL)
+               goto fail_rx_pkt;
+
+       for (i = 0; i < n_scat_pkt; i++) {
+               int pad_len;
+
+               packet = list_first_entry(rxq, struct htc_packet, list);
+               list_del(&packet->list);
+
+               pad_len = CALC_TXRX_PADDED_LEN(target,
+                                                  packet->act_len);
+
+               if ((rem_space - pad_len) < 0) {
+                       list_add(&packet->list, rxq);
+                       break;
+               }
+
+               rem_space -= pad_len;
+
+               if (part_bundle || (i < (n_scat_pkt - 1)))
+                       /*
+                        * Packet 0..n-1 cannot be checked for look-aheads
+                        * since we are fetching a bundle the last packet
+                        * however can have it's lookahead used
+                        */
+                       packet->info.rx.rx_flags |=
+                           HTC_RX_PKT_IGNORE_LOOKAHEAD;
+
+               /* NOTE: 1 HTC packet per scatter entry */
+               scat_req->scat_list[i].buf = packet->buf;
+               scat_req->scat_list[i].len = pad_len;
+
+               packet->info.rx.rx_flags |= HTC_RX_PKT_PART_OF_BUNDLE;
+
+               list_add_tail(&packet->list, sync_compq);
+
+               WARN_ON(!scat_req->scat_list[i].len);
+               len += scat_req->scat_list[i].len;
+       }
+
+       scat_req->len = len;
+       scat_req->scat_entries = i;
+
+       status = ath6kldev_submit_scat_req(target->dev, scat_req, true);
+
+       if (!status)
+               *n_pkt_fetched = i;
+
+       /* free scatter request */
+       hif_scatter_req_add(target->dev->ar, scat_req);
+
+fail_rx_pkt:
+
+       return status;
+}
+
+static int htc_proc_fetched_rxpkts(struct htc_target *target,
+                                  struct list_head *comp_pktq, u32 lk_ahds[],
+                                  int *n_lk_ahd)
+{
+       struct htc_packet *packet, *tmp_pkt;
+       struct htc_endpoint *ep;
+       int status = 0;
+
+       list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
+               list_del(&packet->list);
+               ep = &target->endpoint[packet->endpoint];
+
+               /* process header for each of the recv packet */
+               status = htc_proc_rxhdr(target, packet, lk_ahds, n_lk_ahd);
+               if (status)
+                       return status;
+
+               if (list_empty(comp_pktq)) {
+                       /*
+                        * Last packet's more packet flag is set
+                        * based on the lookahead.
+                        */
+                       if (*n_lk_ahd > 0)
+                               set_rxpkt_indication_flag(lk_ahds[0],
+                                                         ep, packet);
+               } else
+                       /*
+                        * Packets in a bundle automatically have
+                        * this flag set.
+                        */
+                       packet->info.rx.indicat_flags |=
+                               HTC_RX_FLAGS_INDICATE_MORE_PKTS;
+
+               htc_update_rx_stats(ep, *n_lk_ahd);
+
+               if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
+                       ep->ep_st.rx_bundl += 1;
+
+               do_rx_completion(ep, packet);
+       }
+
+       return status;
+}
+
+static int htc_fetch_rxpkts(struct htc_target *target,
+                           struct list_head *rx_pktq,
+                           struct list_head *comp_pktq)
+{
+       int fetched_pkts;
+       bool part_bundle = false;
+       int status = 0;
+
+       /* now go fetch the list of HTC packets */
+       while (!list_empty(rx_pktq)) {
+               fetched_pkts = 0;
+
+               if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) {
+                       /*
+                        * There are enough packets to attempt a
+                        * bundle transfer and recv bundling is
+                        * allowed.
+                        */
+                       status = htc_issue_rxpkt_bundle(target, rx_pktq,
+                                                       comp_pktq,
+                                                       &fetched_pkts,
+                                                       part_bundle);
+                       if (status)
+                               return status;
+
+                       if (!list_empty(rx_pktq))
+                               part_bundle = true;
+               }
+
+               if (!fetched_pkts) {
+                       struct htc_packet *packet;
+
+                       packet = list_first_entry(rx_pktq, struct htc_packet,
+                                                  list);
+
+                       list_del(&packet->list);
+
+                       /* fully synchronous */
+                       packet->completion = NULL;
+
+                       if (!list_empty(rx_pktq))
+                               /*
+                                * look_aheads in all packet
+                                * except the last one in the
+                                * bundle must be ignored
+                                */
+                               packet->info.rx.rx_flags |=
+                                       HTC_RX_PKT_IGNORE_LOOKAHEAD;
+
+                       /* go fetch the packet */
+                       status = dev_rx_pkt(target, packet, packet->act_len);
+                       if (status)
+                               return status;
+
+                       list_add_tail(&packet->list, comp_pktq);
+               }
+       }
+
+       return status;
+}
+
+int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
+                                    u32 msg_look_ahead[], int *num_pkts)
+{
+       struct htc_packet *packets, *tmp_pkt;
+       struct htc_endpoint *endpoint;
+       struct list_head rx_pktq, comp_pktq;
+       int status = 0;
+       u32 look_aheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
+       int num_look_ahead = 1;
+       enum htc_endpoint_id id;
+       int n_fetched = 0;
+
+       *num_pkts = 0;
+
+       /*
+        * On first entry copy the look_aheads into our temp array for
+        * processing
+        */
+       memcpy(look_aheads, msg_look_ahead, sizeof(look_aheads));
+
+       while (true) {
+
+               /*
+                * First lookahead sets the expected endpoint IDs for all
+                * packets in a bundle.
+                */
+               id = ((struct htc_frame_hdr *)&look_aheads[0])->eid;
+               endpoint = &target->endpoint[id];
+
+               if (id >= ENDPOINT_MAX) {
+                       ath6kl_err("MsgPend, invalid endpoint in look-ahead: %d\n",
+                                  id);
+                       status = -ENOMEM;
+                       break;
+               }
+
+               INIT_LIST_HEAD(&rx_pktq);
+               INIT_LIST_HEAD(&comp_pktq);
+
+               /*
+                * Try to allocate as many HTC RX packets indicated by the
+                * look_aheads.
+                */
+               status = alloc_and_prep_rxpkts(target, look_aheads,
+                                              num_look_ahead, endpoint,
+                                              &rx_pktq);
+               if (status)
+                       break;
+
+               if (get_queue_depth(&rx_pktq) >= 2)
+                       /*
+                        * A recv bundle was detected, force IRQ status
+                        * re-check again
+                        */
+                       target->chk_irq_status_cnt = 1;
+
+               n_fetched += get_queue_depth(&rx_pktq);
+
+               num_look_ahead = 0;
+
+               status = htc_fetch_rxpkts(target, &rx_pktq, &comp_pktq);
+
+               if (!status)
+                       chk_rx_water_mark(endpoint);
+
+               /* Process fetched packets */
+               status = htc_proc_fetched_rxpkts(target, &comp_pktq,
+                                                look_aheads, &num_look_ahead);
+
+               if (!num_look_ahead || status)
+                       break;
+
+               /*
+                * For SYNCH processing, if we get here, we are running
+                * through the loop again due to a detected lookahead. Set
+                * flag that we should re-check IRQ status registers again
+                * before leaving IRQ processing, this can net better
+                * performance in high throughput situations.
+                */
+               target->chk_irq_status_cnt = 1;
+       }
+
+       if (status) {
+               ath6kl_err("failed to get pending recv messages: %d\n",
+                          status);
+               /*
+                * Cleanup any packets we allocated but didn't use to
+                * actually fetch any packets.
+                */
+               list_for_each_entry_safe(packets, tmp_pkt, &rx_pktq, list) {
+                       list_del(&packets->list);
+                       htc_reclaim_rxbuf(target, packets,
+                                       &target->endpoint[packets->endpoint]);
+               }
+
+               /* cleanup any packets in sync completion queue */
+               list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) {
+                       list_del(&packets->list);
+                       htc_reclaim_rxbuf(target, packets,
+                                         &target->endpoint[packets->endpoint]);
+               }
+
+               if (target->htc_flags & HTC_OP_STATE_STOPPING) {
+                       ath6kl_warn("host is going to stop blocking receiver for htc_stop\n");
+                       ath6kldev_rx_control(target->dev, false);
+               }
+       }
+
+       /*
+        * Before leaving, check to see if host ran out of buffers and
+        * needs to stop the receiver.
+        */
+       if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
+               ath6kl_warn("host has no rx buffers blocking receiver to prevent overrun\n");
+               ath6kldev_rx_control(target->dev, false);
+       }
+       *num_pkts = n_fetched;
+
+       return status;
+}
+
+/*
+ * Synchronously wait for a control message from the target,
+ * This function is used at initialization time ONLY.  At init messages
+ * on ENDPOINT 0 are expected.
+ */
+static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
+{
+       struct htc_packet *packet = NULL;
+       struct htc_frame_hdr *htc_hdr;
+       u32 look_ahead;
+
+       if (ath6kldev_poll_mboxmsg_rx(target->dev, &look_ahead,
+                              HTC_TARGET_RESPONSE_TIMEOUT))
+               return NULL;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+               "htc_wait_for_ctrl_msg: look_ahead : 0x%X\n", look_ahead);
+
+       htc_hdr = (struct htc_frame_hdr *)&look_ahead;
+
+       if (htc_hdr->eid != ENDPOINT_0)
+               return NULL;
+
+       packet = htc_get_control_buf(target, false);
+
+       if (!packet)
+               return NULL;
+
+       packet->info.rx.rx_flags = 0;
+       packet->info.rx.exp_hdr = look_ahead;
+       packet->act_len = le16_to_cpu(htc_hdr->payld_len) + HTC_HDR_LENGTH;
+
+       if (packet->act_len > packet->buf_len)
+               goto fail_ctrl_rx;
+
+       /* we want synchronous operation */
+       packet->completion = NULL;
+
+       /* get the message from the device, this will block */
+       if (dev_rx_pkt(target, packet, packet->act_len))
+               goto fail_ctrl_rx;
+
+       /* process receive header */
+       packet->status = htc_proc_rxhdr(target, packet, NULL, NULL);
+
+       if (packet->status) {
+               ath6kl_err("htc_wait_for_ctrl_msg, htc_proc_rxhdr failed (status = %d)\n",
+                          packet->status);
+               goto fail_ctrl_rx;
+       }
+
+       return packet;
+
+fail_ctrl_rx:
+       if (packet != NULL) {
+               htc_rxpkt_reset(packet);
+               reclaim_rx_ctrl_buf(target, packet);
+       }
+
+       return NULL;
+}
+
+int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
+                                 struct list_head *pkt_queue)
+{
+       struct htc_endpoint *endpoint;
+       struct htc_packet *first_pkt;
+       bool rx_unblock = false;
+       int status = 0, depth;
+
+       if (list_empty(pkt_queue))
+               return -ENOMEM;
+
+       first_pkt = list_first_entry(pkt_queue, struct htc_packet, list);
+
+       if (first_pkt->endpoint >= ENDPOINT_MAX)
+               return status;
+
+       depth = get_queue_depth(pkt_queue);
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+               "htc_add_rxbuf_multiple: ep id: %d, cnt:%d, len: %d\n",
+               first_pkt->endpoint, depth, first_pkt->buf_len);
+
+       endpoint = &target->endpoint[first_pkt->endpoint];
+
+       if (target->htc_flags & HTC_OP_STATE_STOPPING) {
+               struct htc_packet *packet, *tmp_pkt;
+
+               /* walk through queue and mark each one canceled */
+               list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
+                       packet->status = -ECANCELED;
+                       list_del(&packet->list);
+                       do_rx_completion(endpoint, packet);
+               }
+
+               return status;
+       }
+
+       spin_lock_bh(&target->rx_lock);
+
+       list_splice_tail_init(pkt_queue, &endpoint->rx_bufq);
+
+       /* check if we are blocked waiting for a new buffer */
+       if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
+               if (target->ep_waiting == first_pkt->endpoint) {
+                       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                               "receiver was blocked on ep:%d, unblocking.\n",
+                               target->ep_waiting);
+                       target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
+                       target->ep_waiting = ENDPOINT_MAX;
+                       rx_unblock = true;
+               }
+       }
+
+       spin_unlock_bh(&target->rx_lock);
+
+       if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING))
+               /* TODO : implement a buffer threshold count? */
+               ath6kldev_rx_control(target->dev, true);
+
+       return status;
+}
+
+void ath6kl_htc_flush_rx_buf(struct htc_target *target)
+{
+       struct htc_endpoint *endpoint;
+       struct htc_packet *packet, *tmp_pkt;
+       int i;
+
+       for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+               endpoint = &target->endpoint[i];
+               if (!endpoint->svc_id)
+                       /* not in use.. */
+                       continue;
+
+               spin_lock_bh(&target->rx_lock);
+               list_for_each_entry_safe(packet, tmp_pkt,
+                                        &endpoint->rx_bufq, list) {
+                       list_del(&packet->list);
+                       spin_unlock_bh(&target->rx_lock);
+                       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                                  "flushing rx pkt:0x%p, len:%d, ep:%d\n",
+                                  packet, packet->buf_len,
+                                  packet->endpoint);
+                       dev_kfree_skb(packet->pkt_cntxt);
+                       spin_lock_bh(&target->rx_lock);
+               }
+               spin_unlock_bh(&target->rx_lock);
+       }
+}
+
+int ath6kl_htc_conn_service(struct htc_target *target,
+                           struct htc_service_connect_req *conn_req,
+                           struct htc_service_connect_resp *conn_resp)
+{
+       struct htc_packet *rx_pkt = NULL;
+       struct htc_packet *tx_pkt = NULL;
+       struct htc_conn_service_resp *resp_msg;
+       struct htc_conn_service_msg *conn_msg;
+       struct htc_endpoint *endpoint;
+       enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
+       unsigned int max_msg_sz = 0;
+       int status = 0;
+
+       ath6kl_dbg(ATH6KL_DBG_TRC,
+                  "htc_conn_service, target:0x%p service id:0x%X\n",
+                  target, conn_req->svc_id);
+
+       if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) {
+               /* special case for pseudo control service */
+               assigned_ep = ENDPOINT_0;
+               max_msg_sz = HTC_MAX_CTRL_MSG_LEN;
+       } else {
+               /* allocate a packet to send to the target */
+               tx_pkt = htc_get_control_buf(target, true);
+
+               if (!tx_pkt)
+                       return -ENOMEM;
+
+               conn_msg = (struct htc_conn_service_msg *)tx_pkt->buf;
+               memset(conn_msg, 0, sizeof(*conn_msg));
+               conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID);
+               conn_msg->svc_id = cpu_to_le16(conn_req->svc_id);
+               conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags);
+
+               set_htc_pkt_info(tx_pkt, NULL, (u8 *) conn_msg,
+                                sizeof(*conn_msg) + conn_msg->svc_meta_len,
+                                ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
+
+               /* we want synchronous operation */
+               tx_pkt->completion = NULL;
+               htc_prep_send_pkt(tx_pkt, 0, 0, 0);
+               status = htc_issue_send(target, tx_pkt);
+
+               if (status)
+                       goto fail_tx;
+
+               /* wait for response */
+               rx_pkt = htc_wait_for_ctrl_msg(target);
+
+               if (!rx_pkt) {
+                       status = -ENOMEM;
+                       goto fail_tx;
+               }
+
+               resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
+
+               if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID)
+                   || (rx_pkt->act_len < sizeof(*resp_msg))) {
+                       status = -ENOMEM;
+                       goto fail_tx;
+               }
+
+               conn_resp->resp_code = resp_msg->status;
+               /* check response status */
+               if (resp_msg->status != HTC_SERVICE_SUCCESS) {
+                       ath6kl_err("target failed service 0x%X connect request (status:%d)\n",
+                                  resp_msg->svc_id, resp_msg->status);
+                       status = -ENOMEM;
+                       goto fail_tx;
+               }
+
+               assigned_ep = (enum htc_endpoint_id)resp_msg->eid;
+               max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
+       }
+
+       if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) {
+               status = -ENOMEM;
+               goto fail_tx;
+       }
+
+       endpoint = &target->endpoint[assigned_ep];
+       endpoint->eid = assigned_ep;
+       if (endpoint->svc_id) {
+               status = -ENOMEM;
+               goto fail_tx;
+       }
+
+       /* return assigned endpoint to caller */
+       conn_resp->endpoint = assigned_ep;
+       conn_resp->len_max = max_msg_sz;
+
+       /* setup the endpoint */
+
+       /* this marks the endpoint in use */
+       endpoint->svc_id = conn_req->svc_id;
+
+       endpoint->max_txq_depth = conn_req->max_txq_depth;
+       endpoint->len_max = max_msg_sz;
+       endpoint->ep_cb = conn_req->ep_cb;
+       endpoint->cred_dist.svc_id = conn_req->svc_id;
+       endpoint->cred_dist.htc_rsvd = endpoint;
+       endpoint->cred_dist.endpoint = assigned_ep;
+       endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
+
+       if (conn_req->max_rxmsg_sz) {
+               /*
+                * Override cred_per_msg calculation, this optimizes
+                * the credit-low indications since the host will actually
+                * issue smaller messages in the Send path.
+                */
+               if (conn_req->max_rxmsg_sz > max_msg_sz) {
+                       status = -ENOMEM;
+                       goto fail_tx;
+               }
+               endpoint->cred_dist.cred_per_msg =
+                   conn_req->max_rxmsg_sz / target->tgt_cred_sz;
+       } else
+               endpoint->cred_dist.cred_per_msg =
+                   max_msg_sz / target->tgt_cred_sz;
+
+       if (!endpoint->cred_dist.cred_per_msg)
+               endpoint->cred_dist.cred_per_msg = 1;
+
+       /* save local connection flags */
+       endpoint->conn_flags = conn_req->flags;
+
+fail_tx:
+       if (tx_pkt)
+               htc_reclaim_txctrl_buf(target, tx_pkt);
+
+       if (rx_pkt) {
+               htc_rxpkt_reset(rx_pkt);
+               reclaim_rx_ctrl_buf(target, rx_pkt);
+       }
+
+       return status;
+}
+
+static void reset_ep_state(struct htc_target *target)
+{
+       struct htc_endpoint *endpoint;
+       int i;
+
+       for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+               endpoint = &target->endpoint[i];
+               memset(&endpoint->cred_dist, 0, sizeof(endpoint->cred_dist));
+               endpoint->svc_id = 0;
+               endpoint->len_max = 0;
+               endpoint->max_txq_depth = 0;
+               memset(&endpoint->ep_st, 0,
+                      sizeof(endpoint->ep_st));
+               INIT_LIST_HEAD(&endpoint->rx_bufq);
+               INIT_LIST_HEAD(&endpoint->txq);
+               endpoint->target = target;
+       }
+
+       /* reset distribution list */
+       INIT_LIST_HEAD(&target->cred_dist_list);
+}
+
+int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
+                            enum htc_endpoint_id endpoint)
+{
+       int num;
+
+       spin_lock_bh(&target->rx_lock);
+       num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq));
+       spin_unlock_bh(&target->rx_lock);
+       return num;
+}
+
+static void htc_setup_msg_bndl(struct htc_target *target)
+{
+       /* limit what HTC can handle */
+       target->msg_per_bndl_max = min(HTC_HOST_MAX_MSG_PER_BUNDLE,
+                                      target->msg_per_bndl_max);
+
+       if (ath6kl_hif_enable_scatter(target->dev->ar)) {
+               target->msg_per_bndl_max = 0;
+               return;
+       }
+
+       /* limit bundle what the device layer can handle */
+       target->msg_per_bndl_max = min(target->max_scat_entries,
+                                      target->msg_per_bndl_max);
+
+       ath6kl_dbg(ATH6KL_DBG_TRC,
+                  "htc bundling allowed. max msg per htc bundle: %d\n",
+                  target->msg_per_bndl_max);
+
+       /* Max rx bundle size is limited by the max tx bundle size */
+       target->max_rx_bndl_sz = target->max_xfer_szper_scatreq;
+       /* Max tx bundle size if limited by the extended mbox address range */
+       target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH,
+                                    target->max_xfer_szper_scatreq);
+
+       ath6kl_dbg(ATH6KL_DBG_ANY, "max recv: %d max send: %d\n",
+                  target->max_rx_bndl_sz, target->max_tx_bndl_sz);
+
+       if (target->max_tx_bndl_sz)
+               target->tx_bndl_enable = true;
+
+       if (target->max_rx_bndl_sz)
+               target->rx_bndl_enable = true;
+
+       if ((target->tgt_cred_sz % target->block_sz) != 0) {
+               ath6kl_warn("credit size: %d is not block aligned! Disabling send bundling\n",
+                           target->tgt_cred_sz);
+
+               /*
+                * Disallow send bundling since the credit size is
+                * not aligned to a block size the I/O block
+                * padding will spill into the next credit buffer
+                * which is fatal.
+                */
+               target->tx_bndl_enable = false;
+       }
+}
+
+int ath6kl_htc_wait_target(struct htc_target *target)
+{
+       struct htc_packet *packet = NULL;
+       struct htc_ready_ext_msg *rdy_msg;
+       struct htc_service_connect_req connect;
+       struct htc_service_connect_resp resp;
+       int status;
+
+       /* we should be getting 1 control message that the target is ready */
+       packet = htc_wait_for_ctrl_msg(target);
+
+       if (!packet)
+               return -ENOMEM;
+
+       /* we controlled the buffer creation so it's properly aligned */
+       rdy_msg = (struct htc_ready_ext_msg *)packet->buf;
+
+       if ((le16_to_cpu(rdy_msg->ver2_0_info.msg_id) != HTC_MSG_READY_ID) ||
+           (packet->act_len < sizeof(struct htc_ready_msg))) {
+               status = -ENOMEM;
+               goto fail_wait_target;
+       }
+
+       if (!rdy_msg->ver2_0_info.cred_cnt || !rdy_msg->ver2_0_info.cred_sz) {
+               status = -ENOMEM;
+               goto fail_wait_target;
+       }
+
+       target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt);
+       target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz);
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                  "target ready: credits: %d credit size: %d\n",
+                  target->tgt_creds, target->tgt_cred_sz);
+
+       /* check if this is an extended ready message */
+       if (packet->act_len >= sizeof(struct htc_ready_ext_msg)) {
+               /* this is an extended message */
+               target->htc_tgt_ver = rdy_msg->htc_ver;
+               target->msg_per_bndl_max = rdy_msg->msg_per_htc_bndl;
+       } else {
+               /* legacy */
+               target->htc_tgt_ver = HTC_VERSION_2P0;
+               target->msg_per_bndl_max = 0;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "using htc protocol version : %s (%d)\n",
+                 (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
+                 target->htc_tgt_ver);
+
+       if (target->msg_per_bndl_max > 0)
+               htc_setup_msg_bndl(target);
+
+       /* setup our pseudo HTC control endpoint connection */
+       memset(&connect, 0, sizeof(connect));
+       memset(&resp, 0, sizeof(resp));
+       connect.ep_cb.rx = htc_ctrl_rx;
+       connect.ep_cb.rx_refill = NULL;
+       connect.ep_cb.tx_full = NULL;
+       connect.max_txq_depth = NUM_CONTROL_BUFFERS;
+       connect.svc_id = HTC_CTRL_RSVD_SVC;
+
+       /* connect fake service */
+       status = ath6kl_htc_conn_service((void *)target, &connect, &resp);
+
+       if (status)
+               ath6kl_hif_cleanup_scatter(target->dev->ar);
+
+fail_wait_target:
+       if (packet) {
+               htc_rxpkt_reset(packet);
+               reclaim_rx_ctrl_buf(target, packet);
+       }
+
+       return status;
+}
+
+/*
+ * Start HTC, enable interrupts and let the target know
+ * host has finished setup.
+ */
+int ath6kl_htc_start(struct htc_target *target)
+{
+       struct htc_packet *packet;
+       int status;
+
+       /* Disable interrupts at the chip level */
+       ath6kldev_disable_intrs(target->dev);
+
+       target->htc_flags = 0;
+       target->rx_st_flags = 0;
+
+       /* Push control receive buffers into htc control endpoint */
+       while ((packet = htc_get_control_buf(target, false)) != NULL) {
+               status = htc_add_rxbuf(target, packet);
+               if (status)
+                       return status;
+       }
+
+       /* NOTE: the first entry in the distribution list is ENDPOINT_0 */
+       ath6k_credit_init(target->cred_dist_cntxt, &target->cred_dist_list,
+                         target->tgt_creds);
+
+       dump_cred_dist_stats(target);
+
+       /* Indicate to the target of the setup completion */
+       status = htc_setup_tx_complete(target);
+
+       if (status)
+               return status;
+
+       /* unmask interrupts */
+       status = ath6kldev_unmask_intrs(target->dev);
+
+       if (status)
+               ath6kl_htc_stop(target);
+
+       return status;
+}
+
+/* htc_stop: stop interrupt reception, and flush all queued buffers */
+void ath6kl_htc_stop(struct htc_target *target)
+{
+       spin_lock_bh(&target->htc_lock);
+       target->htc_flags |= HTC_OP_STATE_STOPPING;
+       spin_unlock_bh(&target->htc_lock);
+
+       /*
+        * Masking interrupts is a synchronous operation, when this
+        * function returns all pending HIF I/O has completed, we can
+        * safely flush the queues.
+        */
+       ath6kldev_mask_intrs(target->dev);
+
+       ath6kl_htc_flush_txep_all(target);
+
+       ath6kl_htc_flush_rx_buf(target);
+
+       reset_ep_state(target);
+}
+
+void *ath6kl_htc_create(struct ath6kl *ar)
+{
+       struct htc_target *target = NULL;
+       struct htc_packet *packet;
+       int status = 0, i = 0;
+       u32 block_size, ctrl_bufsz;
+
+       target = kzalloc(sizeof(*target), GFP_KERNEL);
+       if (!target) {
+               ath6kl_err("unable to allocate memory\n");
+               return NULL;
+       }
+
+       target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
+       if (!target->dev) {
+               ath6kl_err("unable to allocate memory\n");
+               status = -ENOMEM;
+               goto fail_create_htc;
+       }
+
+       spin_lock_init(&target->htc_lock);
+       spin_lock_init(&target->rx_lock);
+       spin_lock_init(&target->tx_lock);
+
+       INIT_LIST_HEAD(&target->free_ctrl_txbuf);
+       INIT_LIST_HEAD(&target->free_ctrl_rxbuf);
+       INIT_LIST_HEAD(&target->cred_dist_list);
+
+       target->dev->ar = ar;
+       target->dev->htc_cnxt = target;
+       target->ep_waiting = ENDPOINT_MAX;
+
+       reset_ep_state(target);
+
+       status = ath6kldev_setup(target->dev);
+
+       if (status)
+               goto fail_create_htc;
+
+       block_size = ar->mbox_info.block_size;
+
+       ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ?
+                     (block_size + HTC_HDR_LENGTH) :
+                     (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH);
+
+       for (i = 0; i < NUM_CONTROL_BUFFERS; i++) {
+               packet = kzalloc(sizeof(*packet), GFP_KERNEL);
+               if (!packet)
+                       break;
+
+               packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL);
+               if (!packet->buf_start) {
+                       kfree(packet);
+                       break;
+               }
+
+               packet->buf_len = ctrl_bufsz;
+               if (i < NUM_CONTROL_RX_BUFFERS) {
+                       packet->act_len = 0;
+                       packet->buf = packet->buf_start;
+                       packet->endpoint = ENDPOINT_0;
+                       list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
+               } else
+                       list_add_tail(&packet->list, &target->free_ctrl_txbuf);
+       }
+
+fail_create_htc:
+       if (i != NUM_CONTROL_BUFFERS || status) {
+               if (target) {
+                       ath6kl_htc_cleanup(target);
+                       target = NULL;
+               }
+       }
+
+       return target;
+}
+
+/* cleanup the HTC instance */
+void ath6kl_htc_cleanup(struct htc_target *target)
+{
+       struct htc_packet *packet, *tmp_packet;
+
+       ath6kl_hif_cleanup_scatter(target->dev->ar);
+
+       list_for_each_entry_safe(packet, tmp_packet,
+                       &target->free_ctrl_txbuf, list) {
+               list_del(&packet->list);
+               kfree(packet->buf_start);
+               kfree(packet);
+       }
+
+       list_for_each_entry_safe(packet, tmp_packet,
+                       &target->free_ctrl_rxbuf, list) {
+               list_del(&packet->list);
+               kfree(packet->buf_start);
+               kfree(packet);
+       }
+
+       kfree(target->dev);
+       kfree(target);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
new file mode 100644 (file)
index 0000000..8ce0c2c
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 HTC_H
+#define HTC_H
+
+#include "common.h"
+
+/* frame header flags */
+
+/* send direction */
+#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
+#define HTC_FLAGS_SEND_BUNDLE        (1 << 1)
+
+/* receive direction */
+#define HTC_FLG_RX_UNUSED        (1 << 0)
+#define HTC_FLG_RX_TRAILER       (1 << 1)
+/* Bundle count maske and shift */
+#define HTC_FLG_RX_BNDL_CNT     (0xF0)
+#define HTC_FLG_RX_BNDL_CNT_S   4
+
+#define HTC_HDR_LENGTH  (sizeof(struct htc_frame_hdr))
+#define HTC_MAX_PAYLOAD_LENGTH   (4096 - sizeof(struct htc_frame_hdr))
+
+/* HTC control message IDs */
+
+#define HTC_MSG_READY_ID               1
+#define HTC_MSG_CONN_SVC_ID            2
+#define HTC_MSG_CONN_SVC_RESP_ID       3
+#define HTC_MSG_SETUP_COMPLETE_ID      4
+#define HTC_MSG_SETUP_COMPLETE_EX_ID   5
+
+#define HTC_MAX_CTRL_MSG_LEN  256
+
+#define HTC_VERSION_2P0  0x00
+#define HTC_VERSION_2P1  0x01
+
+#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
+
+#define HTC_CONN_FLGS_THRESH_LVL_QUAT          0x0
+#define HTC_CONN_FLGS_THRESH_LVL_HALF          0x1
+#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT    0x2
+#define HTC_CONN_FLGS_REDUCE_CRED_DRIB         0x4
+#define HTC_CONN_FLGS_THRESH_MASK              0x3
+
+/* connect response status codes */
+#define HTC_SERVICE_SUCCESS      0
+#define HTC_SERVICE_NOT_FOUND    1
+#define HTC_SERVICE_FAILED       2
+
+/* no resources (i.e. no more endpoints) */
+#define HTC_SERVICE_NO_RESOURCES 3
+
+/* specific service is not allowing any more endpoints */
+#define HTC_SERVICE_NO_MORE_EP   4
+
+/* report record IDs */
+#define HTC_RECORD_NULL             0
+#define HTC_RECORD_CREDITS          1
+#define HTC_RECORD_LOOKAHEAD        2
+#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
+
+#define HTC_SETUP_COMP_FLG_RX_BNDL_EN     (1 << 0)
+
+#define MAKE_SERVICE_ID(group, index) \
+       (int)(((int)group << 8) | (int)(index))
+
+/* NOTE: service ID of 0x0000 is reserved and should never be used */
+#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
+#define WMI_CONTROL_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
+#define WMI_DATA_BE_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
+#define WMI_DATA_BK_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
+#define WMI_DATA_VI_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
+#define WMI_DATA_VO_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
+#define WMI_MAX_SERVICES  5
+
+/* reserved and used to flush ALL packets */
+#define HTC_TX_PACKET_TAG_ALL          0
+#define HTC_SERVICE_TX_PACKET_TAG      1
+#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_SERVICE_TX_PACKET_TAG + 9)
+
+/* more packets on this endpoint are being fetched */
+#define HTC_RX_FLAGS_INDICATE_MORE_PKTS  (1 << 0)
+
+/* TODO.. for BMI */
+#define ENDPOINT1 0
+/* TODO -remove me, but we have to fix BMI first */
+#define HTC_MAILBOX_NUM_MAX    4
+
+/* enable send bundle padding for this endpoint */
+#define HTC_FLGS_TX_BNDL_PAD_EN         (1 << 0)
+#define HTC_EP_ACTIVE                            ((u32) (1u << 31))
+
+/* HTC operational parameters */
+#define HTC_TARGET_RESPONSE_TIMEOUT        2000        /* in ms */
+#define HTC_TARGET_DEBUG_INTR_MASK         0x01
+#define HTC_TARGET_CREDIT_INTR_MASK        0xF0
+
+#define HTC_HOST_MAX_MSG_PER_BUNDLE        8
+#define HTC_MIN_HTC_MSGS_TO_BUNDLE         2
+
+/* packet flags */
+
+#define HTC_RX_PKT_IGNORE_LOOKAHEAD      (1 << 0)
+#define HTC_RX_PKT_REFRESH_HDR           (1 << 1)
+#define HTC_RX_PKT_PART_OF_BUNDLE        (1 << 2)
+#define HTC_RX_PKT_NO_RECYCLE            (1 << 3)
+
+#define NUM_CONTROL_BUFFERS     8
+#define NUM_CONTROL_TX_BUFFERS  2
+#define NUM_CONTROL_RX_BUFFERS  (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
+
+#define HTC_RECV_WAIT_BUFFERS        (1 << 0)
+#define HTC_OP_STATE_STOPPING        (1 << 0)
+
+/*
+ * The frame header length and message formats defined herein were selected
+ * to accommodate optimal alignment for target processing. This reduces
+ * code size and improves performance. Any changes to the header length may
+ * alter the alignment and cause exceptions on the target. When adding to
+ * the messagestructures insure that fields are properly aligned.
+ */
+
+/* HTC frame header
+ *
+ * NOTE: do not remove or re-arrange the fields, these are minimally
+ * required to take advantage of 4-byte lookaheads in some hardware
+ * implementations.
+ */
+struct htc_frame_hdr {
+       u8 eid;
+       u8 flags;
+
+       /* length of data (including trailer) that follows the header */
+       __le16 payld_len;
+
+       /* end of 4-byte lookahead */
+
+       u8 ctrl[2];
+} __packed;
+
+/* HTC ready message */
+struct htc_ready_msg {
+       __le16 msg_id;
+       __le16 cred_cnt;
+       __le16 cred_sz;
+       u8 max_ep;
+       u8 pad;
+} __packed;
+
+/* extended HTC ready message */
+struct htc_ready_ext_msg {
+       struct htc_ready_msg ver2_0_info;
+       u8 htc_ver;
+       u8 msg_per_htc_bndl;
+} __packed;
+
+/* connect service */
+struct htc_conn_service_msg {
+       __le16 msg_id;
+       __le16 svc_id;
+       __le16 conn_flags;
+       u8 svc_meta_len;
+       u8 pad;
+} __packed;
+
+/* connect response */
+struct htc_conn_service_resp {
+       __le16 msg_id;
+       __le16 svc_id;
+       u8 status;
+       u8 eid;
+       __le16 max_msg_sz;
+       u8 svc_meta_len;
+       u8 pad;
+} __packed;
+
+struct htc_setup_comp_msg {
+       __le16 msg_id;
+} __packed;
+
+/* extended setup completion message */
+struct htc_setup_comp_ext_msg {
+       __le16 msg_id;
+       __le32 flags;
+       u8 msg_per_rxbndl;
+       u8 Rsvd[3];
+} __packed;
+
+struct htc_record_hdr {
+       u8 rec_id;
+       u8 len;
+} __packed;
+
+struct htc_credit_report {
+       u8 eid;
+       u8 credits;
+} __packed;
+
+/*
+ * NOTE: The lk_ahd array is guarded by a pre_valid
+ * and Post Valid guard bytes. The pre_valid bytes must
+ * equal the inverse of the post_valid byte.
+ */
+struct htc_lookahead_report {
+       u8 pre_valid;
+       u8 lk_ahd[4];
+       u8 post_valid;
+} __packed;
+
+struct htc_bundle_lkahd_rpt {
+       u8 lk_ahd[4];
+} __packed;
+
+/* Current service IDs */
+
+enum htc_service_grp_ids {
+       RSVD_SERVICE_GROUP = 0,
+       WMI_SERVICE_GROUP = 1,
+
+       HTC_TEST_GROUP = 254,
+       HTC_SERVICE_GROUP_LAST = 255
+};
+
+/* ------ endpoint IDS ------ */
+
+enum htc_endpoint_id {
+       ENDPOINT_UNUSED = -1,
+       ENDPOINT_0 = 0,
+       ENDPOINT_1 = 1,
+       ENDPOINT_2 = 2,
+       ENDPOINT_3,
+       ENDPOINT_4,
+       ENDPOINT_5,
+       ENDPOINT_6,
+       ENDPOINT_7,
+       ENDPOINT_8,
+       ENDPOINT_MAX,
+};
+
+struct htc_tx_packet_info {
+       u16 tag;
+       int cred_used;
+       u8 flags;
+       int seqno;
+};
+
+struct htc_rx_packet_info {
+       u32 exp_hdr;
+       u32 rx_flags;
+       u32 indicat_flags;
+};
+
+struct htc_target;
+
+/* wrapper around endpoint-specific packets */
+struct htc_packet {
+       struct list_head list;
+
+       /* caller's per packet specific context */
+       void *pkt_cntxt;
+
+       /*
+        * the true buffer start , the caller can store the real
+        * buffer start here.  In receive callbacks, the HTC layer
+        * sets buf to the start of the payload past the header.
+        * This field allows the caller to reset buf when it recycles
+        * receive packets back to HTC.
+        */
+       u8 *buf_start;
+
+       /*
+        * Pointer to the start of the buffer. In the transmit
+        * direction this points to the start of the payload. In the
+        * receive direction, however, the buffer when queued up
+        * points to the start of the HTC header but when returned
+        * to the caller points to the start of the payload
+        */
+       u8 *buf;
+       u32 buf_len;
+
+       /* actual length of payload */
+       u32 act_len;
+
+       /* endpoint that this packet was sent/recv'd from */
+       enum htc_endpoint_id endpoint;
+
+       /* completion status */
+
+       int status;
+       union {
+               struct htc_tx_packet_info tx;
+               struct htc_rx_packet_info rx;
+       } info;
+
+       void (*completion) (struct htc_target *, struct htc_packet *);
+       struct htc_target *context;
+};
+
+enum htc_send_full_action {
+       HTC_SEND_FULL_KEEP = 0,
+       HTC_SEND_FULL_DROP = 1,
+};
+
+struct htc_ep_callbacks {
+       void (*rx) (struct htc_target *, struct htc_packet *);
+       void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint);
+       enum htc_send_full_action (*tx_full) (struct htc_target *,
+                                             struct htc_packet *);
+       struct htc_packet *(*rx_allocthresh) (struct htc_target *,
+                                             enum htc_endpoint_id, int);
+       int rx_alloc_thresh;
+       int rx_refill_thresh;
+};
+
+/* service connection information */
+struct htc_service_connect_req {
+       u16 svc_id;
+       u16 conn_flags;
+       struct htc_ep_callbacks ep_cb;
+       int max_txq_depth;
+       u32 flags;
+       unsigned int max_rxmsg_sz;
+};
+
+/* service connection response information */
+struct htc_service_connect_resp {
+       u8 buf_len;
+       u8 act_len;
+       enum htc_endpoint_id endpoint;
+       unsigned int len_max;
+       u8 resp_code;
+};
+
+/* endpoint distributionstructure */
+struct htc_endpoint_credit_dist {
+       struct list_head list;
+
+       /* Service ID (set by HTC) */
+       u16 svc_id;
+
+       /* endpoint for this distributionstruct (set by HTC) */
+       enum htc_endpoint_id endpoint;
+
+       u32 dist_flags;
+
+       /*
+        * credits for normal operation, anything above this
+        * indicates the endpoint is over-subscribed.
+        */
+       int cred_norm;
+
+       /* floor for credit distribution */
+       int cred_min;
+
+       int cred_assngd;
+
+       /* current credits available */
+       int credits;
+
+       /*
+        * pending credits to distribute on this endpoint, this
+        * is set by HTC when credit reports arrive.  The credit
+        * distribution functions sets this to zero when it distributes
+        * the credits.
+        */
+       int cred_to_dist;
+
+       /*
+        * the number of credits that the current pending TX packet needs
+        * to transmit. This is set by HTC when endpoint needs credits in
+        * order to transmit.
+        */
+       int seek_cred;
+
+       /* size in bytes of each credit */
+       int cred_sz;
+
+       /* credits required for a maximum sized messages */
+       int cred_per_msg;
+
+       /* reserved for HTC use */
+       void *htc_rsvd;
+
+       /*
+        * current depth of TX queue , i.e. messages waiting for credits
+        * This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
+        * or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
+        * that has non-zero credits to recover.
+        */
+       int txq_depth;
+};
+
+/*
+ * credit distibution code that is passed into the distrbution function,
+ * there are mandatory and optional codes that must be handled
+ */
+enum htc_credit_dist_reason {
+       HTC_CREDIT_DIST_SEND_COMPLETE = 0,
+       HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1,
+       HTC_CREDIT_DIST_SEEK_CREDITS,
+};
+
+struct htc_credit_state_info {
+       int total_avail_credits;
+       int cur_free_credits;
+       struct list_head lowestpri_ep_dist;
+};
+
+/* endpoint statistics */
+struct htc_endpoint_stats {
+       /*
+        * number of times the host set the credit-low flag in a send
+        * message on this endpoint
+        */
+       u32 cred_low_indicate;
+
+       u32 tx_issued;
+       u32 tx_pkt_bundled;
+       u32 tx_bundles;
+       u32 tx_dropped;
+
+       /* running count of total credit reports received for this endpoint */
+       u32 tx_cred_rpt;
+
+       /* credit reports received from this endpoint's RX packets */
+       u32 cred_rpt_from_rx;
+
+       /* credit reports received from RX packets of other endpoints */
+       u32 cred_rpt_from_other;
+
+       /* credit reports received from endpoint 0 RX packets */
+       u32 cred_rpt_ep0;
+
+       /* count of credits received via Rx packets on this endpoint */
+       u32 cred_from_rx;
+
+       /* count of credits received via another endpoint */
+       u32 cred_from_other;
+
+       /* count of credits received via another endpoint */
+       u32 cred_from_ep0;
+
+       /* count of consummed credits */
+       u32 cred_cosumd;
+
+       /* count of credits returned */
+       u32 cred_retnd;
+
+       u32 rx_pkts;
+
+       /* count of lookahead records found in Rx msg */
+       u32 rx_lkahds;
+
+       /* count of recv packets received in a bundle */
+       u32 rx_bundl;
+
+       /* count of number of bundled lookaheads */
+       u32 rx_bundle_lkahd;
+
+       /* count of the number of bundle indications from the HTC header */
+       u32 rx_bundle_from_hdr;
+
+       /* the number of times the recv allocation threshold was hit */
+       u32 rx_alloc_thresh_hit;
+
+       /* total number of bytes */
+       u32 rxalloc_thresh_byte;
+};
+
+struct htc_endpoint {
+       enum htc_endpoint_id eid;
+       u16 svc_id;
+       struct list_head txq;
+       struct list_head rx_bufq;
+       struct htc_endpoint_credit_dist cred_dist;
+       struct htc_ep_callbacks ep_cb;
+       int max_txq_depth;
+       int len_max;
+       int tx_proc_cnt;
+       int rx_proc_cnt;
+       struct htc_target *target;
+       u8 seqno;
+       u32 conn_flags;
+       struct htc_endpoint_stats ep_st;
+};
+
+struct htc_control_buffer {
+       struct htc_packet packet;
+       u8 *buf;
+};
+
+struct ath6kl_device;
+
+/* our HTC target state */
+struct htc_target {
+       struct htc_endpoint endpoint[ENDPOINT_MAX];
+       struct list_head cred_dist_list;
+       struct list_head free_ctrl_txbuf;
+       struct list_head free_ctrl_rxbuf;
+       struct htc_credit_state_info *cred_dist_cntxt;
+       int tgt_creds;
+       unsigned int tgt_cred_sz;
+       spinlock_t htc_lock;
+       spinlock_t rx_lock;
+       spinlock_t tx_lock;
+       struct ath6kl_device *dev;
+       u32 htc_flags;
+       u32 rx_st_flags;
+       enum htc_endpoint_id ep_waiting;
+       u8 htc_tgt_ver;
+
+       /* max messages per bundle for HTC */
+       int msg_per_bndl_max;
+
+       bool tx_bndl_enable;
+       int rx_bndl_enable;
+       int max_rx_bndl_sz;
+       int max_tx_bndl_sz;
+
+       u32 block_sz;
+       u32 block_mask;
+
+       int max_scat_entries;
+       int max_xfer_szper_scatreq;
+
+       int chk_irq_status_cnt;
+};
+
+void *ath6kl_htc_create(struct ath6kl *ar);
+void ath6kl_htc_set_credit_dist(struct htc_target *target,
+                               struct htc_credit_state_info *cred_info,
+                               u16 svc_pri_order[], int len);
+int ath6kl_htc_wait_target(struct htc_target *target);
+int ath6kl_htc_start(struct htc_target *target);
+int ath6kl_htc_conn_service(struct htc_target *target,
+                           struct htc_service_connect_req *req,
+                           struct htc_service_connect_resp *resp);
+int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet);
+void ath6kl_htc_stop(struct htc_target *target);
+void ath6kl_htc_cleanup(struct htc_target *target);
+void ath6kl_htc_flush_txep(struct htc_target *target,
+                          enum htc_endpoint_id endpoint, u16 tag);
+void ath6kl_htc_flush_rx_buf(struct htc_target *target);
+void ath6kl_htc_indicate_activity_change(struct htc_target *target,
+                                        enum htc_endpoint_id endpoint,
+                                        bool active);
+int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
+                            enum htc_endpoint_id endpoint);
+int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
+                                 struct list_head *pktq);
+int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
+                                    u32 msg_look_ahead[], int *n_pkts);
+
+static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
+                                   u8 *buf, unsigned int len,
+                                   enum htc_endpoint_id eid, u16 tag)
+{
+       packet->pkt_cntxt = context;
+       packet->buf = buf;
+       packet->act_len = len;
+       packet->endpoint = eid;
+       packet->info.tx.tag = tag;
+}
+
+static inline void htc_rxpkt_reset(struct htc_packet *packet)
+{
+       packet->buf = packet->buf_start;
+       packet->act_len = 0;
+}
+
+static inline void set_htc_rxpkt_info(struct htc_packet *packet, void *context,
+                                     u8 *buf, unsigned long len,
+                                     enum htc_endpoint_id eid)
+{
+       packet->pkt_cntxt = context;
+       packet->buf = buf;
+       packet->buf_start = buf;
+       packet->buf_len = len;
+       packet->endpoint = eid;
+}
+
+static inline int get_queue_depth(struct list_head *queue)
+{
+       struct list_head *tmp_list;
+       int depth = 0;
+
+       list_for_each(tmp_list, queue)
+           depth++;
+
+       return depth;
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc_hif.c b/drivers/net/wireless/ath/ath6kl/htc_hif.c
new file mode 100644 (file)
index 0000000..86b1cc7
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications 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 "core.h"
+#include "target.h"
+#include "hif-ops.h"
+#include "htc_hif.h"
+#include "debug.h"
+
+#define MAILBOX_FOR_BLOCK_SIZE          1
+
+#define ATH6KL_TIME_QUANTUM    10  /* in ms */
+
+static int ath6kldev_cp_scat_dma_buf(struct hif_scatter_req *req, bool from_dma)
+{
+       u8 *buf;
+       int i;
+
+       buf = req->virt_dma_buf;
+
+       for (i = 0; i < req->scat_entries; i++) {
+
+               if (from_dma)
+                       memcpy(req->scat_list[i].buf, buf,
+                              req->scat_list[i].len);
+               else
+                       memcpy(buf, req->scat_list[i].buf,
+                              req->scat_list[i].len);
+
+               buf += req->scat_list[i].len;
+       }
+
+       return 0;
+}
+
+int ath6kldev_rw_comp_handler(void *context, int status)
+{
+       struct htc_packet *packet = context;
+
+       ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+                  "ath6kldev_rw_comp_handler (pkt:0x%p , status: %d\n",
+                  packet, status);
+
+       packet->status = status;
+       packet->completion(packet->context, packet);
+
+       return 0;
+}
+
+static int ath6kldev_proc_dbg_intr(struct ath6kl_device *dev)
+{
+       u32 dummy;
+       int status;
+
+       ath6kl_err("target debug interrupt\n");
+
+       ath6kl_target_failure(dev->ar);
+
+       /*
+        * read counter to clear the interrupt, the debug error interrupt is
+        * counter 0.
+        */
+       status = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
+                                    (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC);
+       if (status)
+               WARN_ON(1);
+
+       return status;
+}
+
+/* mailbox recv message polling */
+int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd,
+                             int timeout)
+{
+       struct ath6kl_irq_proc_registers *rg;
+       int status = 0, i;
+       u8 htc_mbox = 1 << HTC_MAILBOX;
+
+       for (i = timeout / ATH6KL_TIME_QUANTUM; i > 0; i--) {
+               /* this is the standard HIF way, load the reg table */
+               status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
+                                            (u8 *) &dev->irq_proc_reg,
+                                            sizeof(dev->irq_proc_reg),
+                                            HIF_RD_SYNC_BYTE_INC);
+
+               if (status) {
+                       ath6kl_err("failed to read reg table\n");
+                       return status;
+               }
+
+               /* check for MBOX data and valid lookahead */
+               if (dev->irq_proc_reg.host_int_status & htc_mbox) {
+                       if (dev->irq_proc_reg.rx_lkahd_valid &
+                           htc_mbox) {
+                               /*
+                                * Mailbox has a message and the look ahead
+                                * is valid.
+                                */
+                               rg = &dev->irq_proc_reg;
+                               *lk_ahd =
+                                       le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
+                               break;
+                       }
+               }
+
+               /* delay a little  */
+               mdelay(ATH6KL_TIME_QUANTUM);
+               ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "retry mbox poll : %d\n", i);
+       }
+
+       if (i == 0) {
+               ath6kl_err("timeout waiting for recv message\n");
+               status = -ETIME;
+               /* check if the target asserted */
+               if (dev->irq_proc_reg.counter_int_status &
+                   ATH6KL_TARGET_DEBUG_INTR_MASK)
+                       /*
+                        * Target failure handler will be called in case of
+                        * an assert.
+                        */
+                       ath6kldev_proc_dbg_intr(dev);
+       }
+
+       return status;
+}
+
+/*
+ * Disable packet reception (used in case the host runs out of buffers)
+ * using the interrupt enable registers through the host I/F
+ */
+int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx)
+{
+       struct ath6kl_irq_enable_reg regs;
+       int status = 0;
+
+       /* take the lock to protect interrupt enable shadows */
+       spin_lock_bh(&dev->lock);
+
+       if (enable_rx)
+               dev->irq_en_reg.int_status_en |=
+                       SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
+       else
+               dev->irq_en_reg.int_status_en &=
+                   ~SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
+
+       memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
+
+       spin_unlock_bh(&dev->lock);
+
+       status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
+                                    &regs.int_status_en,
+                                    sizeof(struct ath6kl_irq_enable_reg),
+                                    HIF_WR_SYNC_BYTE_INC);
+
+       return status;
+}
+
+int ath6kldev_submit_scat_req(struct ath6kl_device *dev,
+                             struct hif_scatter_req *scat_req, bool read)
+{
+       int status = 0;
+
+       if (read) {
+               scat_req->req = HIF_RD_SYNC_BLOCK_FIX;
+               scat_req->addr = dev->ar->mbox_info.htc_addr;
+       } else {
+               scat_req->req = HIF_WR_ASYNC_BLOCK_INC;
+
+               scat_req->addr =
+                       (scat_req->len > HIF_MBOX_WIDTH) ?
+                       dev->ar->mbox_info.htc_ext_addr :
+                       dev->ar->mbox_info.htc_addr;
+       }
+
+       ath6kl_dbg((ATH6KL_DBG_HTC_RECV | ATH6KL_DBG_HTC_SEND),
+                  "ath6kldev_submit_scat_req, entries: %d, total len: %d mbox:0x%X (mode: %s : %s)\n",
+                  scat_req->scat_entries, scat_req->len,
+                  scat_req->addr, !read ? "async" : "sync",
+                  (read) ? "rd" : "wr");
+
+       if (!read && scat_req->virt_scat) {
+               status = ath6kldev_cp_scat_dma_buf(scat_req, false);
+               if (status) {
+                       scat_req->status = status;
+                       scat_req->complete(dev->ar->htc_target, scat_req);
+                       return 0;
+               }
+       }
+
+       status = ath6kl_hif_scat_req_rw(dev->ar, scat_req);
+
+       if (read) {
+               /* in sync mode, we can touch the scatter request */
+               scat_req->status = status;
+               if (!status && scat_req->virt_scat)
+                       scat_req->status =
+                               ath6kldev_cp_scat_dma_buf(scat_req, true);
+       }
+
+       return status;
+}
+
+static int ath6kldev_proc_counter_intr(struct ath6kl_device *dev)
+{
+       u8 counter_int_status;
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ, "counter interrupt\n");
+
+       counter_int_status = dev->irq_proc_reg.counter_int_status &
+                            dev->irq_en_reg.cntr_int_status_en;
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ,
+               "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
+               counter_int_status);
+
+       /*
+        * NOTE: other modules like GMBOX may use the counter interrupt for
+        * credit flow control on other counters, we only need to check for
+        * the debug assertion counter interrupt.
+        */
+       if (counter_int_status & ATH6KL_TARGET_DEBUG_INTR_MASK)
+               return ath6kldev_proc_dbg_intr(dev);
+
+       return 0;
+}
+
+static int ath6kldev_proc_err_intr(struct ath6kl_device *dev)
+{
+       int status;
+       u8 error_int_status;
+       u8 reg_buf[4];
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ, "error interrupt\n");
+
+       error_int_status = dev->irq_proc_reg.error_int_status & 0x0F;
+       if (!error_int_status) {
+               WARN_ON(1);
+               return -EIO;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ,
+                  "valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
+                  error_int_status);
+
+       if (MS(ERROR_INT_STATUS_WAKEUP, error_int_status))
+               ath6kl_dbg(ATH6KL_DBG_IRQ, "error : wakeup\n");
+
+       if (MS(ERROR_INT_STATUS_RX_UNDERFLOW, error_int_status))
+               ath6kl_err("rx underflow\n");
+
+       if (MS(ERROR_INT_STATUS_TX_OVERFLOW, error_int_status))
+               ath6kl_err("tx overflow\n");
+
+       /* Clear the interrupt */
+       dev->irq_proc_reg.error_int_status &= ~error_int_status;
+
+       /* set W1C value to clear the interrupt, this hits the register first */
+       reg_buf[0] = error_int_status;
+       reg_buf[1] = 0;
+       reg_buf[2] = 0;
+       reg_buf[3] = 0;
+
+       status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
+                                    reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
+
+       if (status)
+               WARN_ON(1);
+
+       return status;
+}
+
+static int ath6kldev_proc_cpu_intr(struct ath6kl_device *dev)
+{
+       int status;
+       u8 cpu_int_status;
+       u8 reg_buf[4];
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ, "cpu interrupt\n");
+
+       cpu_int_status = dev->irq_proc_reg.cpu_int_status &
+                        dev->irq_en_reg.cpu_int_status_en;
+       if (!cpu_int_status) {
+               WARN_ON(1);
+               return -EIO;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ,
+               "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
+               cpu_int_status);
+
+       /* Clear the interrupt */
+       dev->irq_proc_reg.cpu_int_status &= ~cpu_int_status;
+
+       /*
+        * Set up the register transfer buffer to hit the register 4 times ,
+        * this is done to make the access 4-byte aligned to mitigate issues
+        * with host bus interconnects that restrict bus transfer lengths to
+        * be a multiple of 4-bytes.
+        */
+
+       /* set W1C value to clear the interrupt, this hits the register first */
+       reg_buf[0] = cpu_int_status;
+       /* the remaining are set to zero which have no-effect  */
+       reg_buf[1] = 0;
+       reg_buf[2] = 0;
+       reg_buf[3] = 0;
+
+       status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
+                                    reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
+
+       if (status)
+               WARN_ON(1);
+
+       return status;
+}
+
+/* process pending interrupts synchronously */
+static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
+{
+       struct ath6kl_irq_proc_registers *rg;
+       int status = 0;
+       u8 host_int_status = 0;
+       u32 lk_ahd = 0;
+       u8 htc_mbox = 1 << HTC_MAILBOX;
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ, "proc_pending_irqs: (dev: 0x%p)\n", dev);
+
+       /*
+        * NOTE: HIF implementation guarantees that the context of this
+        * call allows us to perform SYNCHRONOUS I/O, that is we can block,
+        * sleep or call any API that can block or switch thread/task
+        * contexts. This is a fully schedulable context.
+        */
+
+       /*
+        * Process pending intr only when int_status_en is clear, it may
+        * result in unnecessary bus transaction otherwise. Target may be
+        * unresponsive at the time.
+        */
+       if (dev->irq_en_reg.int_status_en) {
+               /*
+                * Read the first 28 bytes of the HTC register table. This
+                * will yield us the value of different int status
+                * registers and the lookahead registers.
+                *
+                *    length = sizeof(int_status) + sizeof(cpu_int_status)
+                *             + sizeof(error_int_status) +
+                *             sizeof(counter_int_status) +
+                *             sizeof(mbox_frame) + sizeof(rx_lkahd_valid)
+                *             + sizeof(hole) + sizeof(rx_lkahd) +
+                *             sizeof(int_status_en) +
+                *             sizeof(cpu_int_status_en) +
+                *             sizeof(err_int_status_en) +
+                *             sizeof(cntr_int_status_en);
+                */
+               status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
+                                            (u8 *) &dev->irq_proc_reg,
+                                            sizeof(dev->irq_proc_reg),
+                                            HIF_RD_SYNC_BYTE_INC);
+               if (status)
+                       goto out;
+
+               if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ))
+                       ath6kl_dump_registers(dev, &dev->irq_proc_reg,
+                                        &dev->irq_en_reg);
+
+               /* Update only those registers that are enabled */
+               host_int_status = dev->irq_proc_reg.host_int_status &
+                                 dev->irq_en_reg.int_status_en;
+
+               /* Look at mbox status */
+               if (host_int_status & htc_mbox) {
+                       /*
+                        * Mask out pending mbox value, we use "lookAhead as
+                        * the real flag for mbox processing.
+                        */
+                       host_int_status &= ~htc_mbox;
+                       if (dev->irq_proc_reg.rx_lkahd_valid &
+                           htc_mbox) {
+                               rg = &dev->irq_proc_reg;
+                               lk_ahd = le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
+                               if (!lk_ahd)
+                                       ath6kl_err("lookAhead is zero!\n");
+                       }
+               }
+       }
+
+       if (!host_int_status && !lk_ahd) {
+               *done = true;
+               goto out;
+       }
+
+       if (lk_ahd) {
+               int fetched = 0;
+
+               ath6kl_dbg(ATH6KL_DBG_IRQ,
+                          "pending mailbox msg, lk_ahd: 0x%X\n", lk_ahd);
+               /*
+                * Mailbox Interrupt, the HTC layer may issue async
+                * requests to empty the mailbox. When emptying the recv
+                * mailbox we use the async handler above called from the
+                * completion routine of the callers read request. This can
+                * improve performance by reducing context switching when
+                * we rapidly pull packets.
+                */
+               status = ath6kl_htc_rxmsg_pending_handler(dev->htc_cnxt,
+                                                         &lk_ahd, &fetched);
+               if (status)
+                       goto out;
+
+               if (!fetched)
+                       /*
+                        * HTC could not pull any messages out due to lack
+                        * of resources.
+                        */
+                       dev->htc_cnxt->chk_irq_status_cnt = 0;
+       }
+
+       /* now handle the rest of them */
+       ath6kl_dbg(ATH6KL_DBG_IRQ,
+                  "valid interrupt source(s) for other interrupts: 0x%x\n",
+                  host_int_status);
+
+       if (MS(HOST_INT_STATUS_CPU, host_int_status)) {
+               /* CPU Interrupt */
+               status = ath6kldev_proc_cpu_intr(dev);
+               if (status)
+                       goto out;
+       }
+
+       if (MS(HOST_INT_STATUS_ERROR, host_int_status)) {
+               /* Error Interrupt */
+               status = ath6kldev_proc_err_intr(dev);
+               if (status)
+                       goto out;
+       }
+
+       if (MS(HOST_INT_STATUS_COUNTER, host_int_status))
+               /* Counter Interrupt */
+               status = ath6kldev_proc_counter_intr(dev);
+
+out:
+       /*
+        * An optimization to bypass reading the IRQ status registers
+        * unecessarily which can re-wake the target, if upper layers
+        * determine that we are in a low-throughput mode, we can rely on
+        * taking another interrupt rather than re-checking the status
+        * registers which can re-wake the target.
+        *
+        * NOTE : for host interfaces that makes use of detecting pending
+        * mbox messages at hif can not use this optimization due to
+        * possible side effects, SPI requires the host to drain all
+        * messages from the mailbox before exiting the ISR routine.
+        */
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ,
+                  "bypassing irq status re-check, forcing done\n");
+
+       if (!dev->htc_cnxt->chk_irq_status_cnt)
+               *done = true;
+
+       ath6kl_dbg(ATH6KL_DBG_IRQ,
+                  "proc_pending_irqs: (done:%d, status=%d\n", *done, status);
+
+       return status;
+}
+
+/* interrupt handler, kicks off all interrupt processing */
+int ath6kldev_intr_bh_handler(struct ath6kl *ar)
+{
+       struct ath6kl_device *dev = ar->htc_target->dev;
+       int status = 0;
+       bool done = false;
+
+       /*
+        * Reset counter used to flag a re-scan of IRQ status registers on
+        * the target.
+        */
+       dev->htc_cnxt->chk_irq_status_cnt = 0;
+
+       /*
+        * IRQ processing is synchronous, interrupt status registers can be
+        * re-read.
+        */
+       while (!done) {
+               status = proc_pending_irqs(dev, &done);
+               if (status)
+                       break;
+       }
+
+       return status;
+}
+
+static int ath6kldev_enable_intrs(struct ath6kl_device *dev)
+{
+       struct ath6kl_irq_enable_reg regs;
+       int status;
+
+       spin_lock_bh(&dev->lock);
+
+       /* Enable all but ATH6KL CPU interrupts */
+       dev->irq_en_reg.int_status_en =
+                       SM(INT_STATUS_ENABLE_ERROR, 0x01) |
+                       SM(INT_STATUS_ENABLE_CPU, 0x01) |
+                       SM(INT_STATUS_ENABLE_COUNTER, 0x01);
+
+       /*
+        * NOTE: There are some cases where HIF can do detection of
+        * pending mbox messages which is disabled now.
+        */
+       dev->irq_en_reg.int_status_en |= SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
+
+       /* Set up the CPU Interrupt status Register */
+       dev->irq_en_reg.cpu_int_status_en = 0;
+
+       /* Set up the Error Interrupt status Register */
+       dev->irq_en_reg.err_int_status_en =
+               SM(ERROR_STATUS_ENABLE_RX_UNDERFLOW, 0x01) |
+               SM(ERROR_STATUS_ENABLE_TX_OVERFLOW, 0x1);
+
+       /*
+        * Enable Counter interrupt status register to get fatal errors for
+        * debugging.
+        */
+       dev->irq_en_reg.cntr_int_status_en = SM(COUNTER_INT_STATUS_ENABLE_BIT,
+                                               ATH6KL_TARGET_DEBUG_INTR_MASK);
+       memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
+
+       spin_unlock_bh(&dev->lock);
+
+       status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
+                                    &regs.int_status_en, sizeof(regs),
+                                    HIF_WR_SYNC_BYTE_INC);
+
+       if (status)
+               ath6kl_err("failed to update interrupt ctl reg err: %d\n",
+                          status);
+
+       return status;
+}
+
+int ath6kldev_disable_intrs(struct ath6kl_device *dev)
+{
+       struct ath6kl_irq_enable_reg regs;
+
+       spin_lock_bh(&dev->lock);
+       /* Disable all interrupts */
+       dev->irq_en_reg.int_status_en = 0;
+       dev->irq_en_reg.cpu_int_status_en = 0;
+       dev->irq_en_reg.err_int_status_en = 0;
+       dev->irq_en_reg.cntr_int_status_en = 0;
+       memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
+       spin_unlock_bh(&dev->lock);
+
+       return hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
+                                  &regs.int_status_en, sizeof(regs),
+                                  HIF_WR_SYNC_BYTE_INC);
+}
+
+/* enable device interrupts */
+int ath6kldev_unmask_intrs(struct ath6kl_device *dev)
+{
+       int status = 0;
+
+       /*
+        * Make sure interrupt are disabled before unmasking at the HIF
+        * layer. The rationale here is that between device insertion
+        * (where we clear the interrupts the first time) and when HTC
+        * is finally ready to handle interrupts, other software can perform
+        * target "soft" resets. The ATH6KL interrupt enables reset back to an
+        * "enabled" state when this happens.
+        */
+       ath6kldev_disable_intrs(dev);
+
+       /* unmask the host controller interrupts */
+       ath6kl_hif_irq_enable(dev->ar);
+       status = ath6kldev_enable_intrs(dev);
+
+       return status;
+}
+
+/* disable all device interrupts */
+int ath6kldev_mask_intrs(struct ath6kl_device *dev)
+{
+       /*
+        * Mask the interrupt at the HIF layer to avoid any stray interrupt
+        * taken while we zero out our shadow registers in
+        * ath6kldev_disable_intrs().
+        */
+       ath6kl_hif_irq_disable(dev->ar);
+
+       return ath6kldev_disable_intrs(dev);
+}
+
+int ath6kldev_setup(struct ath6kl_device *dev)
+{
+       int status = 0;
+
+       spin_lock_init(&dev->lock);
+
+       /*
+        * NOTE: we actually get the block size of a mailbox other than 0,
+        * for SDIO the block size on mailbox 0 is artificially set to 1.
+        * So we use the block size that is set for the other 3 mailboxes.
+        */
+       dev->htc_cnxt->block_sz = dev->ar->mbox_info.block_size;
+
+       /* must be a power of 2 */
+       if ((dev->htc_cnxt->block_sz & (dev->htc_cnxt->block_sz - 1)) != 0) {
+               WARN_ON(1);
+               goto fail_setup;
+       }
+
+       /* assemble mask, used for padding to a block */
+       dev->htc_cnxt->block_mask = dev->htc_cnxt->block_sz - 1;
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "block size: %d, mbox addr:0x%X\n",
+                  dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
+
+       ath6kl_dbg(ATH6KL_DBG_TRC,
+                  "hif interrupt processing is sync only\n");
+
+       status = ath6kldev_disable_intrs(dev);
+
+fail_setup:
+       return status;
+
+}
diff --git a/drivers/net/wireless/ath/ath6kl/htc_hif.h b/drivers/net/wireless/ath/ath6kl/htc_hif.h
new file mode 100644 (file)
index 0000000..171ad63
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications 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 HTC_HIF_H
+#define HTC_HIF_H
+
+#include "htc.h"
+#include "hif.h"
+
+#define ATH6KL_MAILBOXES       4
+
+/* HTC runs over mailbox 0 */
+#define HTC_MAILBOX    0
+
+#define ATH6KL_TARGET_DEBUG_INTR_MASK     0x01
+
+#define OTHER_INTS_ENABLED             (INT_STATUS_ENABLE_ERROR_MASK | \
+                                       INT_STATUS_ENABLE_CPU_MASK   |  \
+                                       INT_STATUS_ENABLE_COUNTER_MASK)
+
+#define ATH6KL_REG_IO_BUFFER_SIZE                      32
+#define ATH6KL_MAX_REG_IO_BUFFERS                      8
+#define ATH6KL_SCATTER_ENTRIES_PER_REQ            16
+#define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER      (16 * 1024)
+#define ATH6KL_SCATTER_REQS                       4
+
+#ifndef A_CACHE_LINE_PAD
+#define A_CACHE_LINE_PAD                        128
+#endif
+#define ATH6KL_MIN_SCATTER_ENTRIES_PER_REQ        2
+#define ATH6KL_MIN_TRANSFER_SIZE_PER_SCATTER      (4 * 1024)
+
+struct ath6kl_irq_proc_registers {
+       u8 host_int_status;
+       u8 cpu_int_status;
+       u8 error_int_status;
+       u8 counter_int_status;
+       u8 mbox_frame;
+       u8 rx_lkahd_valid;
+       u8 host_int_status2;
+       u8 gmbox_rx_avail;
+       __le32 rx_lkahd[2];
+       __le32 rx_gmbox_lkahd_alias[2];
+} __packed;
+
+struct ath6kl_irq_enable_reg {
+       u8 int_status_en;
+       u8 cpu_int_status_en;
+       u8 err_int_status_en;
+       u8 cntr_int_status_en;
+} __packed;
+
+struct ath6kl_device {
+       spinlock_t lock;
+       u8 pad1[A_CACHE_LINE_PAD];
+       struct ath6kl_irq_proc_registers irq_proc_reg;
+       u8 pad2[A_CACHE_LINE_PAD];
+       struct ath6kl_irq_enable_reg irq_en_reg;
+       u8 pad3[A_CACHE_LINE_PAD];
+       struct htc_target *htc_cnxt;
+       struct ath6kl *ar;
+};
+
+int ath6kldev_setup(struct ath6kl_device *dev);
+int ath6kldev_unmask_intrs(struct ath6kl_device *dev);
+int ath6kldev_mask_intrs(struct ath6kl_device *dev);
+int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev,
+                             u32 *lk_ahd, int timeout);
+int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx);
+int ath6kldev_disable_intrs(struct ath6kl_device *dev);
+
+int ath6kldev_rw_comp_handler(void *context, int status);
+int ath6kldev_intr_bh_handler(struct ath6kl *ar);
+
+/* Scatter Function and Definitions */
+int ath6kldev_submit_scat_req(struct ath6kl_device *dev,
+                           struct hif_scatter_req *scat_req, bool read);
+
+#endif /*ATH6KL_H_ */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
new file mode 100644 (file)
index 0000000..9d10322
--- /dev/null
@@ -0,0 +1,1303 @@
+
+/*
+ * Copyright (c) 2011 Atheros Communications 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 <linux/mmc/sdio_func.h>
+#include "core.h"
+#include "cfg80211.h"
+#include "target.h"
+#include "debug.h"
+#include "hif-ops.h"
+
+unsigned int debug_mask;
+
+module_param(debug_mask, uint, 0644);
+
+/*
+ * Include definitions here that can be used to tune the WLAN module
+ * behavior. Different customers can tune the behavior as per their needs,
+ * here.
+ */
+
+/*
+ * This configuration item enable/disable keepalive support.
+ * Keepalive support: In the absence of any data traffic to AP, null
+ * frames will be sent to the AP at periodic interval, to keep the association
+ * active. This configuration item defines the periodic interval.
+ * Use value of zero to disable keepalive support
+ * Default: 60 seconds
+ */
+#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
+
+/*
+ * This configuration item sets the value of disconnect timeout
+ * Firmware delays sending the disconnec event to the host for this
+ * timeout after is gets disconnected from the current AP.
+ * If the firmware successly roams within the disconnect timeout
+ * it sends a new connect event
+ */
+#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
+
+#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
+
+enum addr_type {
+       DATASET_PATCH_ADDR,
+       APP_LOAD_ADDR,
+       APP_START_OVERRIDE_ADDR,
+};
+
+#define ATH6KL_DATA_OFFSET    64
+struct sk_buff *ath6kl_buf_alloc(int size)
+{
+       struct sk_buff *skb;
+       u16 reserved;
+
+       /* Add chacheline space at front and back of buffer */
+       reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
+                  sizeof(struct htc_packet);
+       skb = dev_alloc_skb(size + reserved);
+
+       if (skb)
+               skb_reserve(skb, reserved - L1_CACHE_BYTES);
+       return skb;
+}
+
+void ath6kl_init_profile_info(struct ath6kl *ar)
+{
+       ar->ssid_len = 0;
+       memset(ar->ssid, 0, sizeof(ar->ssid));
+
+       ar->dot11_auth_mode = OPEN_AUTH;
+       ar->auth_mode = NONE_AUTH;
+       ar->prwise_crypto = NONE_CRYPT;
+       ar->prwise_crypto_len = 0;
+       ar->grp_crypto = NONE_CRYPT;
+       ar->grp_crpto_len = 0;
+       memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+       memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+       memset(ar->bssid, 0, sizeof(ar->bssid));
+       ar->bss_ch = 0;
+       ar->nw_type = ar->next_mode = INFRA_NETWORK;
+}
+
+static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
+{
+       switch (ar->nw_type) {
+       case INFRA_NETWORK:
+               return HI_OPTION_FW_MODE_BSS_STA;
+       case ADHOC_NETWORK:
+               return HI_OPTION_FW_MODE_IBSS;
+       case AP_NETWORK:
+               return HI_OPTION_FW_MODE_AP;
+       default:
+               ath6kl_err("Unsupported interface type :%d\n", ar->nw_type);
+               return 0xff;
+       }
+}
+
+static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
+                                         u32 item_offset)
+{
+       u32 addr = 0;
+
+       if (ar->target_type == TARGET_TYPE_AR6003)
+               addr = ATH6KL_HI_START_ADDR + item_offset;
+
+       return addr;
+}
+
+static int ath6kl_set_host_app_area(struct ath6kl *ar)
+{
+       u32 address, data;
+       struct host_app_area host_app_area;
+
+       /* Fetch the address of the host_app_area_s
+        * instance in the host interest area */
+       address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
+       address = TARG_VTOP(address);
+
+       if (ath6kl_read_reg_diag(ar, &address, &data))
+               return -EIO;
+
+       address = TARG_VTOP(data);
+       host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
+       if (ath6kl_access_datadiag(ar, address,
+                               (u8 *)&host_app_area,
+                               sizeof(struct host_app_area), false))
+               return -EIO;
+
+       return 0;
+}
+
+static inline void set_ac2_ep_map(struct ath6kl *ar,
+                                 u8 ac,
+                                 enum htc_endpoint_id ep)
+{
+       ar->ac2ep_map[ac] = ep;
+       ar->ep2ac_map[ep] = ac;
+}
+
+/* connect to a service */
+static int ath6kl_connectservice(struct ath6kl *ar,
+                                struct htc_service_connect_req  *con_req,
+                                char *desc)
+{
+       int status;
+       struct htc_service_connect_resp response;
+
+       memset(&response, 0, sizeof(response));
+
+       status = ath6kl_htc_conn_service(ar->htc_target, con_req, &response);
+       if (status) {
+               ath6kl_err("failed to connect to %s service status:%d\n",
+                          desc, status);
+               return status;
+       }
+
+       switch (con_req->svc_id) {
+       case WMI_CONTROL_SVC:
+               if (test_bit(WMI_ENABLED, &ar->flag))
+                       ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
+               ar->ctrl_ep = response.endpoint;
+               break;
+       case WMI_DATA_BE_SVC:
+               set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
+               break;
+       case WMI_DATA_BK_SVC:
+               set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
+               break;
+       case WMI_DATA_VI_SVC:
+               set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
+               break;
+       case WMI_DATA_VO_SVC:
+               set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
+               break;
+       default:
+               ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int ath6kl_init_service_ep(struct ath6kl *ar)
+{
+       struct htc_service_connect_req connect;
+
+       memset(&connect, 0, sizeof(connect));
+
+       /* these fields are the same for all service endpoints */
+       connect.ep_cb.rx = ath6kl_rx;
+       connect.ep_cb.rx_refill = ath6kl_rx_refill;
+       connect.ep_cb.tx_full = ath6kl_tx_queue_full;
+
+       /*
+        * Set the max queue depth so that our ath6kl_tx_queue_full handler
+        * gets called.
+       */
+       connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
+       connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
+       if (!connect.ep_cb.rx_refill_thresh)
+               connect.ep_cb.rx_refill_thresh++;
+
+       /* connect to control service */
+       connect.svc_id = WMI_CONTROL_SVC;
+       if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
+               return -EIO;
+
+       connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
+
+       /*
+        * Limit the HTC message size on the send path, although e can
+        * receive A-MSDU frames of 4K, we will only send ethernet-sized
+        * (802.3) frames on the send path.
+        */
+       connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
+
+       /*
+        * To reduce the amount of committed memory for larger A_MSDU
+        * frames, use the recv-alloc threshold mechanism for larger
+        * packets.
+        */
+       connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
+       connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
+
+       /*
+        * For the remaining data services set the connection flag to
+        * reduce dribbling, if configured to do so.
+        */
+       connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
+       connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
+       connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
+
+       connect.svc_id = WMI_DATA_BE_SVC;
+
+       if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
+               return -EIO;
+
+       /* connect to back-ground map this to WMI LOW_PRI */
+       connect.svc_id = WMI_DATA_BK_SVC;
+       if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
+               return -EIO;
+
+       /* connect to Video service, map this to to HI PRI */
+       connect.svc_id = WMI_DATA_VI_SVC;
+       if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
+               return -EIO;
+
+       /*
+        * Connect to VO service, this is currently not mapped to a WMI
+        * priority stream due to historical reasons. WMI originally
+        * defined 3 priorities over 3 mailboxes We can change this when
+        * WMI is reworked so that priorities are not dependent on
+        * mailboxes.
+        */
+       connect.svc_id = WMI_DATA_VO_SVC;
+       if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
+               return -EIO;
+
+       return 0;
+}
+
+static void ath6kl_init_control_info(struct ath6kl *ar)
+{
+       u8 ctr;
+
+       clear_bit(WMI_ENABLED, &ar->flag);
+       ath6kl_init_profile_info(ar);
+       ar->def_txkey_index = 0;
+       memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+       ar->ch_hint = 0;
+       ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
+       ar->listen_intvl_b = 0;
+       ar->tx_pwr = 0;
+       clear_bit(SKIP_SCAN, &ar->flag);
+       set_bit(WMM_ENABLED, &ar->flag);
+       ar->intra_bss = 1;
+       memset(&ar->sc_params, 0, sizeof(ar->sc_params));
+       ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
+       ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
+
+       memset((u8 *)ar->sta_list, 0,
+              AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
+
+       spin_lock_init(&ar->mcastpsq_lock);
+
+       /* Init the PS queues */
+       for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+               spin_lock_init(&ar->sta_list[ctr].psq_lock);
+               skb_queue_head_init(&ar->sta_list[ctr].psq);
+       }
+
+       skb_queue_head_init(&ar->mcastpsq);
+
+       memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
+}
+
+/*
+ * Set HTC/Mbox operational parameters, this can only be called when the
+ * target is in the BMI phase.
+ */
+static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
+                                u8 htc_ctrl_buf)
+{
+       int status;
+       u32 blk_size;
+
+       blk_size = ar->mbox_info.block_size;
+
+       if (htc_ctrl_buf)
+               blk_size |=  ((u32)htc_ctrl_buf) << 16;
+
+       /* set the host interest area for the block size */
+       status = ath6kl_bmi_write(ar,
+                       ath6kl_get_hi_item_addr(ar,
+                       HI_ITEM(hi_mbox_io_block_sz)),
+                       (u8 *)&blk_size,
+                       4);
+       if (status) {
+               ath6kl_err("bmi_write_memory for IO block size failed\n");
+               goto out;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
+                  blk_size,
+                  ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
+
+       if (mbox_isr_yield_val) {
+               /* set the host interest area for the mbox ISR yield limit */
+               status = ath6kl_bmi_write(ar,
+                               ath6kl_get_hi_item_addr(ar,
+                               HI_ITEM(hi_mbox_isr_yield_limit)),
+                               (u8 *)&mbox_isr_yield_val,
+                               4);
+               if (status) {
+                       ath6kl_err("bmi_write_memory for yield limit failed\n");
+                       goto out;
+               }
+       }
+
+out:
+       return status;
+}
+
+#define REG_DUMP_COUNT_AR6003   60
+#define REGISTER_DUMP_LEN_MAX   60
+
+static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
+{
+       u32 address;
+       u32 regdump_loc = 0;
+       int status;
+       u32 regdump_val[REGISTER_DUMP_LEN_MAX];
+       u32 i;
+
+       if (ar->target_type != TARGET_TYPE_AR6003)
+               return;
+
+       /* the reg dump pointer is copied to the host interest area */
+       address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
+       address = TARG_VTOP(address);
+
+       /* read RAM location through diagnostic window */
+       status = ath6kl_read_reg_diag(ar, &address, &regdump_loc);
+
+       if (status || !regdump_loc) {
+               ath6kl_err("failed to get ptr to register dump area\n");
+               return;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
+               regdump_loc);
+
+       regdump_loc = TARG_VTOP(regdump_loc);
+
+       /* fetch register dump data */
+       status = ath6kl_access_datadiag(ar,
+                                       regdump_loc,
+                                       (u8 *)&regdump_val[0],
+                                       REG_DUMP_COUNT_AR6003 * (sizeof(u32)),
+                                       true);
+
+       if (status) {
+               ath6kl_err("failed to get register dump\n");
+               return;
+       }
+       ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n");
+
+       for (i = 0; i < REG_DUMP_COUNT_AR6003; i++)
+               ath6kl_dbg(ATH6KL_DBG_TRC, " %d :  0x%8.8X\n",
+                          i, regdump_val[i]);
+
+}
+
+void ath6kl_target_failure(struct ath6kl *ar)
+{
+       ath6kl_err("target asserted\n");
+
+       /* try dumping target assertion information (if any) */
+       ath6kl_dump_target_assert_info(ar);
+
+}
+
+static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
+{
+       int status = 0;
+
+       /*
+        * Configure the device for rx dot11 header rules. "0,0" are the
+        * default values. Required if checksum offload is needed. Set
+        * RxMetaVersion to 2.
+        */
+       if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+                                              ar->rx_meta_ver, 0, 0)) {
+               ath6kl_err("unable to set the rx frame format\n");
+               status = -EIO;
+       }
+
+       if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
+               if ((ath6kl_wmi_pmparams_cmd(ar->wmi, 0, 1, 0, 0, 1,
+                    IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
+                       ath6kl_err("unable to set power save fail event policy\n");
+                       status = -EIO;
+               }
+
+       if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
+               if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, 0,
+                    WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
+                       ath6kl_err("unable to set barker preamble policy\n");
+                       status = -EIO;
+               }
+
+       if (ath6kl_wmi_set_keepalive_cmd(ar->wmi,
+                       WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
+               ath6kl_err("unable to set keep alive interval\n");
+               status = -EIO;
+       }
+
+       if (ath6kl_wmi_disctimeout_cmd(ar->wmi,
+                       WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
+               ath6kl_err("unable to set disconnect timeout\n");
+               status = -EIO;
+       }
+
+       if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
+               if (ath6kl_wmi_set_wmm_txop(ar->wmi, WMI_TXOP_DISABLED)) {
+                       ath6kl_err("unable to set txop bursting\n");
+                       status = -EIO;
+               }
+
+       return status;
+}
+
+int ath6kl_configure_target(struct ath6kl *ar)
+{
+       u32 param, ram_reserved_size;
+       u8 fw_iftype;
+
+       fw_iftype = ath6kl_get_fw_iftype(ar);
+       if (fw_iftype == 0xff)
+               return -EINVAL;
+
+       /* Tell target which HTC version it is used*/
+       param = HTC_PROTOCOL_VERSION;
+       if (ath6kl_bmi_write(ar,
+                            ath6kl_get_hi_item_addr(ar,
+                            HI_ITEM(hi_app_host_interest)),
+                            (u8 *)&param, 4) != 0) {
+               ath6kl_err("bmi_write_memory for htc version failed\n");
+               return -EIO;
+       }
+
+       /* set the firmware mode to STA/IBSS/AP */
+       param = 0;
+
+       if (ath6kl_bmi_read(ar,
+                           ath6kl_get_hi_item_addr(ar,
+                           HI_ITEM(hi_option_flag)),
+                           (u8 *)&param, 4) != 0) {
+               ath6kl_err("bmi_read_memory for setting fwmode failed\n");
+               return -EIO;
+       }
+
+       param |= (1 << HI_OPTION_NUM_DEV_SHIFT);
+       param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT);
+       param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
+       param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
+
+       if (ath6kl_bmi_write(ar,
+                            ath6kl_get_hi_item_addr(ar,
+                            HI_ITEM(hi_option_flag)),
+                            (u8 *)&param,
+                            4) != 0) {
+               ath6kl_err("bmi_write_memory for setting fwmode failed\n");
+               return -EIO;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
+
+       /*
+        * Hardcode the address use for the extended board data
+        * Ideally this should be pre-allocate by the OS at boot time
+        * But since it is a new feature and board data is loaded
+        * at init time, we have to workaround this from host.
+        * It is difficult to patch the firmware boot code,
+        * but possible in theory.
+        */
+
+       if (ar->target_type == TARGET_TYPE_AR6003) {
+               if (ar->version.target_ver == AR6003_REV2_VERSION) {
+                       param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
+                       ram_reserved_size =  AR6003_REV2_RAM_RESERVE_SIZE;
+               } else {
+                       param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
+                       ram_reserved_size =  AR6003_REV3_RAM_RESERVE_SIZE;
+               }
+
+               if (ath6kl_bmi_write(ar,
+                                    ath6kl_get_hi_item_addr(ar,
+                                    HI_ITEM(hi_board_ext_data)),
+                                    (u8 *)&param, 4) != 0) {
+                       ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
+                       return -EIO;
+               }
+               if (ath6kl_bmi_write(ar,
+                                    ath6kl_get_hi_item_addr(ar,
+                                    HI_ITEM(hi_end_ram_reserve_sz)),
+                                    (u8 *)&ram_reserved_size, 4) != 0) {
+                       ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
+                       return -EIO;
+               }
+       }
+
+       /* set the block size for the target */
+       if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
+               /* use default number of control buffers */
+               return -EIO;
+
+       return 0;
+}
+
+struct ath6kl *ath6kl_core_alloc(struct device *sdev)
+{
+       struct net_device *dev;
+       struct ath6kl *ar;
+       struct wireless_dev *wdev;
+
+       wdev = ath6kl_cfg80211_init(sdev);
+       if (!wdev) {
+               ath6kl_err("ath6kl_cfg80211_init failed\n");
+               return NULL;
+       }
+
+       ar = wdev_priv(wdev);
+       ar->dev = sdev;
+       ar->wdev = wdev;
+       wdev->iftype = NL80211_IFTYPE_STATION;
+
+       dev = alloc_netdev(0, "wlan%d", ether_setup);
+       if (!dev) {
+               ath6kl_err("no memory for network device instance\n");
+               ath6kl_cfg80211_deinit(ar);
+               return NULL;
+       }
+
+       dev->ieee80211_ptr = wdev;
+       SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+       wdev->netdev = dev;
+       ar->sme_state = SME_DISCONNECTED;
+       ar->auto_auth_stage = AUTH_IDLE;
+
+       init_netdev(dev);
+
+       ar->net_dev = dev;
+       set_bit(WLAN_ENABLED, &ar->flag);
+
+       ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
+
+       spin_lock_init(&ar->lock);
+
+       ath6kl_init_control_info(ar);
+       init_waitqueue_head(&ar->event_wq);
+       sema_init(&ar->sem, 1);
+       clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+       INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
+
+       setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
+                   (unsigned long) dev);
+
+       return ar;
+}
+
+int ath6kl_unavail_ev(struct ath6kl *ar)
+{
+       ath6kl_destroy(ar->net_dev, 1);
+
+       return 0;
+}
+
+/* firmware upload */
+static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
+{
+       WARN_ON(target_ver != AR6003_REV2_VERSION &&
+               target_ver != AR6003_REV3_VERSION);
+
+       switch (type) {
+       case DATASET_PATCH_ADDR:
+               return (target_ver == AR6003_REV2_VERSION) ?
+                       AR6003_REV2_DATASET_PATCH_ADDRESS :
+                       AR6003_REV3_DATASET_PATCH_ADDRESS;
+       case APP_LOAD_ADDR:
+               return (target_ver == AR6003_REV2_VERSION) ?
+                       AR6003_REV2_APP_LOAD_ADDRESS :
+                       0x1234;
+       case APP_START_OVERRIDE_ADDR:
+               return (target_ver == AR6003_REV2_VERSION) ?
+                       AR6003_REV2_APP_START_OVERRIDE :
+                       AR6003_REV3_APP_START_OVERRIDE;
+       default:
+               return 0;
+       }
+}
+
+static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
+                        u8 **fw, size_t *fw_len)
+{
+       const struct firmware *fw_entry;
+       int ret;
+
+       ret = request_firmware(&fw_entry, filename, ar->dev);
+       if (ret)
+               return ret;
+
+       *fw_len = fw_entry->size;
+       *fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
+
+       if (*fw == NULL)
+               ret = -ENOMEM;
+
+       release_firmware(fw_entry);
+
+       return ret;
+}
+
+static int ath6kl_fetch_board_file(struct ath6kl *ar)
+{
+       const char *filename;
+       int ret;
+
+       switch (ar->version.target_ver) {
+       case AR6003_REV2_VERSION:
+               filename = AR6003_REV2_BOARD_DATA_FILE;
+               break;
+       default:
+               filename = AR6003_REV3_BOARD_DATA_FILE;
+               break;
+       }
+
+       ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
+                           &ar->fw_board_len);
+       if (ret == 0) {
+               /* managed to get proper board file */
+               return 0;
+       }
+
+       /* there was no proper board file, try to use default instead */
+       ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
+                   filename, ret);
+
+       switch (ar->version.target_ver) {
+       case AR6003_REV2_VERSION:
+               filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE;
+               break;
+       default:
+               filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE;
+               break;
+       }
+
+       ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
+                           &ar->fw_board_len);
+       if (ret) {
+               ath6kl_err("Failed to get default board file %s: %d\n",
+                          filename, ret);
+               return ret;
+       }
+
+       ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
+       ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
+
+       return 0;
+}
+
+
+static int ath6kl_upload_board_file(struct ath6kl *ar)
+{
+       u32 board_address, board_ext_address, param;
+       int ret;
+
+       if (ar->fw_board == NULL) {
+               ret = ath6kl_fetch_board_file(ar);
+               if (ret)
+                       return ret;
+       }
+
+       /* Determine where in Target RAM to write Board Data */
+       ath6kl_bmi_read(ar,
+                       ath6kl_get_hi_item_addr(ar,
+                       HI_ITEM(hi_board_data)),
+                       (u8 *) &board_address, 4);
+       ath6kl_dbg(ATH6KL_DBG_TRC, "board data download addr: 0x%x\n",
+                  board_address);
+
+       /* determine where in target ram to write extended board data */
+       ath6kl_bmi_read(ar,
+                       ath6kl_get_hi_item_addr(ar,
+                       HI_ITEM(hi_board_ext_data)),
+                       (u8 *) &board_ext_address, 4);
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "board file download addr: 0x%x\n",
+                  board_ext_address);
+
+       if (board_ext_address == 0) {
+               ath6kl_err("Failed to get board file target address.\n");
+               return -EINVAL;
+       }
+
+       if (ar->fw_board_len == (AR6003_BOARD_DATA_SZ +
+                                AR6003_BOARD_EXT_DATA_SZ)) {
+               /* write extended board data */
+               ret = ath6kl_bmi_write(ar, board_ext_address,
+                                      ar->fw_board + AR6003_BOARD_DATA_SZ,
+                                      AR6003_BOARD_EXT_DATA_SZ);
+
+               if (ret) {
+                       ath6kl_err("Failed to write extended board data: %d\n",
+                                  ret);
+                       return ret;
+               }
+
+               /* record that extended board data is initialized */
+               param = (AR6003_BOARD_EXT_DATA_SZ << 16) | 1;
+               ath6kl_bmi_write(ar,
+                                ath6kl_get_hi_item_addr(ar,
+                                HI_ITEM(hi_board_ext_data_config)),
+                                (unsigned char *) &param, 4);
+       }
+
+       if (ar->fw_board_len < AR6003_BOARD_DATA_SZ) {
+               ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
+               ret = -EINVAL;
+               return ret;
+       }
+
+       ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
+                              AR6003_BOARD_DATA_SZ);
+
+       if (ret) {
+               ath6kl_err("Board file bmi write failed: %d\n", ret);
+               return ret;
+       }
+
+       /* record the fact that Board Data IS initialized */
+       param = 1;
+       ath6kl_bmi_write(ar,
+                        ath6kl_get_hi_item_addr(ar,
+                        HI_ITEM(hi_board_data_initialized)),
+                        (u8 *)&param, 4);
+
+       return ret;
+}
+
+static int ath6kl_upload_otp(struct ath6kl *ar)
+{
+       const char *filename;
+       u32 address, param;
+       int ret;
+
+       switch (ar->version.target_ver) {
+       case AR6003_REV2_VERSION:
+               filename = AR6003_REV2_OTP_FILE;
+               break;
+       default:
+               filename = AR6003_REV3_OTP_FILE;
+               break;
+       }
+
+       if (ar->fw_otp == NULL) {
+               ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
+                                   &ar->fw_otp_len);
+               if (ret) {
+                       ath6kl_err("Failed to get OTP file %s: %d\n",
+                                  filename, ret);
+                       return ret;
+               }
+       }
+
+       address = ath6kl_get_load_address(ar->version.target_ver,
+                                         APP_LOAD_ADDR);
+
+       ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
+                                      ar->fw_otp_len);
+       if (ret) {
+               ath6kl_err("Failed to upload OTP file: %d\n", ret);
+               return ret;
+       }
+
+       /* execute the OTP code */
+       param = 0;
+       address = ath6kl_get_load_address(ar->version.target_ver,
+                                         APP_START_OVERRIDE_ADDR);
+       ath6kl_bmi_execute(ar, address, &param);
+
+       return ret;
+}
+
+static int ath6kl_upload_firmware(struct ath6kl *ar)
+{
+       const char *filename;
+       u32 address;
+       int ret;
+
+       switch (ar->version.target_ver) {
+       case AR6003_REV2_VERSION:
+               filename = AR6003_REV2_FIRMWARE_FILE;
+               break;
+       default:
+               filename = AR6003_REV3_FIRMWARE_FILE;
+               break;
+       }
+
+       if (ar->fw == NULL) {
+               ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
+               if (ret) {
+                       ath6kl_err("Failed to get firmware file %s: %d\n",
+                                  filename, ret);
+                       return ret;
+               }
+       }
+
+       address = ath6kl_get_load_address(ar->version.target_ver,
+                                         APP_LOAD_ADDR);
+
+       ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
+
+       if (ret) {
+               ath6kl_err("Failed to write firmware: %d\n", ret);
+               return ret;
+       }
+
+       /* Set starting address for firmware */
+       address = ath6kl_get_load_address(ar->version.target_ver,
+                                         APP_START_OVERRIDE_ADDR);
+       ath6kl_bmi_set_app_start(ar, address);
+
+       return ret;
+}
+
+static int ath6kl_upload_patch(struct ath6kl *ar)
+{
+       const char *filename;
+       u32 address, param;
+       int ret;
+
+       switch (ar->version.target_ver) {
+       case AR6003_REV2_VERSION:
+               filename = AR6003_REV2_PATCH_FILE;
+               break;
+       default:
+               filename = AR6003_REV3_PATCH_FILE;
+               break;
+       }
+
+       if (ar->fw_patch == NULL) {
+               ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
+                                   &ar->fw_patch_len);
+               if (ret) {
+                       ath6kl_err("Failed to get patch file %s: %d\n",
+                                  filename, ret);
+                       return ret;
+               }
+       }
+
+       address = ath6kl_get_load_address(ar->version.target_ver,
+                                         DATASET_PATCH_ADDR);
+
+       ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
+       if (ret) {
+               ath6kl_err("Failed to write patch file: %d\n", ret);
+               return ret;
+       }
+
+       param = address;
+       ath6kl_bmi_write(ar,
+                        ath6kl_get_hi_item_addr(ar,
+                        HI_ITEM(hi_dset_list_head)),
+                        (unsigned char *) &param, 4);
+
+       return 0;
+}
+
+static int ath6kl_init_upload(struct ath6kl *ar)
+{
+       u32 param, options, sleep, address;
+       int status = 0;
+
+       if (ar->target_type != TARGET_TYPE_AR6003)
+               return -EINVAL;
+
+       /* temporarily disable system sleep */
+       address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
+       status = ath6kl_bmi_reg_read(ar, address, &param);
+       if (status)
+               return status;
+
+       options = param;
+
+       param |= ATH6KL_OPTION_SLEEP_DISABLE;
+       status = ath6kl_bmi_reg_write(ar, address, param);
+       if (status)
+               return status;
+
+       address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
+       status = ath6kl_bmi_reg_read(ar, address, &param);
+       if (status)
+               return status;
+
+       sleep = param;
+
+       param |= SM(SYSTEM_SLEEP_DISABLE, 1);
+       status = ath6kl_bmi_reg_write(ar, address, param);
+       if (status)
+               return status;
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
+                  options, sleep);
+
+       /* program analog PLL register */
+       status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
+                                     0xF9104001);
+       if (status)
+               return status;
+
+       /* Run at 80/88MHz by default */
+       param = SM(CPU_CLOCK_STANDARD, 1);
+
+       address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
+       status = ath6kl_bmi_reg_write(ar, address, param);
+       if (status)
+               return status;
+
+       param = 0;
+       address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
+       param = SM(LPO_CAL_ENABLE, 1);
+       status = ath6kl_bmi_reg_write(ar, address, param);
+       if (status)
+               return status;
+
+       /* WAR to avoid SDIO CRC err */
+       if (ar->version.target_ver == AR6003_REV2_VERSION) {
+               ath6kl_err("temporary war to avoid sdio crc error\n");
+
+               param = 0x20;
+
+               address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
+               status = ath6kl_bmi_reg_write(ar, address, param);
+               if (status)
+                       return status;
+
+               address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
+               status = ath6kl_bmi_reg_write(ar, address, param);
+               if (status)
+                       return status;
+
+               address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
+               status = ath6kl_bmi_reg_write(ar, address, param);
+               if (status)
+                       return status;
+
+               address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
+               status = ath6kl_bmi_reg_write(ar, address, param);
+               if (status)
+                       return status;
+       }
+
+       /* write EEPROM data to Target RAM */
+       status = ath6kl_upload_board_file(ar);
+       if (status)
+               return status;
+
+       /* transfer One time Programmable data */
+       status = ath6kl_upload_otp(ar);
+       if (status)
+               return status;
+
+       /* Download Target firmware */
+       status = ath6kl_upload_firmware(ar);
+       if (status)
+               return status;
+
+       status = ath6kl_upload_patch(ar);
+       if (status)
+               return status;
+
+       /* Restore system sleep */
+       address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
+       status = ath6kl_bmi_reg_write(ar, address, sleep);
+       if (status)
+               return status;
+
+       address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
+       param = options | 0x20;
+       status = ath6kl_bmi_reg_write(ar, address, param);
+       if (status)
+               return status;
+
+       /* Configure GPIO AR6003 UART */
+       param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
+       status = ath6kl_bmi_write(ar,
+                                 ath6kl_get_hi_item_addr(ar,
+                                 HI_ITEM(hi_dbg_uart_txpin)),
+                                 (u8 *)&param, 4);
+
+       return status;
+}
+
+static int ath6kl_init(struct net_device *dev)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       int status = 0;
+       s32 timeleft;
+
+       if (!ar)
+               return -EIO;
+
+       /* Do we need to finish the BMI phase */
+       if (ath6kl_bmi_done(ar)) {
+               status = -EIO;
+               goto ath6kl_init_done;
+       }
+
+       /* Indicate that WMI is enabled (although not ready yet) */
+       set_bit(WMI_ENABLED, &ar->flag);
+       ar->wmi = ath6kl_wmi_init(ar);
+       if (!ar->wmi) {
+               ath6kl_err("failed to initialize wmi\n");
+               status = -EIO;
+               goto ath6kl_init_done;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
+
+       wlan_node_table_init(&ar->scan_table);
+
+       /*
+        * The reason we have to wait for the target here is that the
+        * driver layer has to init BMI in order to set the host block
+        * size.
+        */
+       if (ath6kl_htc_wait_target(ar->htc_target)) {
+               status = -EIO;
+               goto err_node_cleanup;
+       }
+
+       if (ath6kl_init_service_ep(ar)) {
+               status = -EIO;
+               goto err_cleanup_scatter;
+       }
+
+       /* setup access class priority mappings */
+       ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest  */
+       ar->ac_stream_pri_map[WMM_AC_BE] = 1;
+       ar->ac_stream_pri_map[WMM_AC_VI] = 2;
+       ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
+
+       /* give our connected endpoints some buffers */
+       ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
+       ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
+
+       /* allocate some buffers that handle larger AMSDU frames */
+       ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
+
+       /* setup credit distribution */
+       ath6k_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
+
+       ath6kl_cookie_init(ar);
+
+       /* start HTC */
+       status = ath6kl_htc_start(ar->htc_target);
+
+       if (status) {
+               ath6kl_cookie_cleanup(ar);
+               goto err_rxbuf_cleanup;
+       }
+
+       /* Wait for Wmi event to be ready */
+       timeleft = wait_event_interruptible_timeout(ar->event_wq,
+                                                   test_bit(WMI_READY,
+                                                            &ar->flag),
+                                                   WMI_TIMEOUT);
+
+       if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
+               ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
+                          ATH6KL_ABI_VERSION, ar->version.abi_ver);
+               status = -EIO;
+               goto err_htc_stop;
+       }
+
+       if (!timeleft || signal_pending(current)) {
+               ath6kl_err("wmi is not ready or wait was interrupted\n");
+               status = -EIO;
+               goto err_htc_stop;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
+
+       /* communicate the wmi protocol verision to the target */
+       if ((ath6kl_set_host_app_area(ar)) != 0)
+               ath6kl_err("unable to set the host app area\n");
+
+       ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
+                        ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
+
+       status = ath6kl_target_config_wlan_params(ar);
+       if (!status)
+               goto ath6kl_init_done;
+
+err_htc_stop:
+       ath6kl_htc_stop(ar->htc_target);
+err_rxbuf_cleanup:
+       ath6kl_htc_flush_rx_buf(ar->htc_target);
+       ath6kl_cleanup_amsdu_rxbufs(ar);
+err_cleanup_scatter:
+       ath6kl_hif_cleanup_scatter(ar);
+err_node_cleanup:
+       wlan_node_table_cleanup(&ar->scan_table);
+       ath6kl_wmi_shutdown(ar->wmi);
+       clear_bit(WMI_ENABLED, &ar->flag);
+       ar->wmi = NULL;
+
+ath6kl_init_done:
+       return status;
+}
+
+int ath6kl_core_init(struct ath6kl *ar)
+{
+       int ret = 0;
+       struct ath6kl_bmi_target_info targ_info;
+
+       ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
+       if (!ar->ath6kl_wq)
+               return -ENOMEM;
+
+       ret = ath6kl_bmi_init(ar);
+       if (ret)
+               goto err_wq;
+
+       ret = ath6kl_bmi_get_target_info(ar, &targ_info);
+       if (ret)
+               goto err_bmi_cleanup;
+
+       ar->version.target_ver = le32_to_cpu(targ_info.version);
+       ar->target_type = le32_to_cpu(targ_info.type);
+       ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
+
+       ret = ath6kl_configure_target(ar);
+       if (ret)
+               goto err_bmi_cleanup;
+
+       ar->htc_target = ath6kl_htc_create(ar);
+
+       if (!ar->htc_target) {
+               ret = -ENOMEM;
+               goto err_bmi_cleanup;
+       }
+
+       ar->aggr_cntxt = aggr_init(ar->net_dev);
+       if (!ar->aggr_cntxt) {
+               ath6kl_err("failed to initialize aggr\n");
+               ret = -ENOMEM;
+               goto err_htc_cleanup;
+       }
+
+       ret = ath6kl_init_upload(ar);
+       if (ret)
+               goto err_htc_cleanup;
+
+       ret = ath6kl_init(ar->net_dev);
+       if (ret)
+               goto err_htc_cleanup;
+
+       /* This runs the init function if registered */
+       ret = register_netdev(ar->net_dev);
+       if (ret) {
+               ath6kl_err("register_netdev failed\n");
+               ath6kl_destroy(ar->net_dev, 0);
+               return ret;
+       }
+
+       set_bit(NETDEV_REGISTERED, &ar->flag);
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
+                       __func__, ar->net_dev->name, ar->net_dev, ar);
+
+       return ret;
+
+err_htc_cleanup:
+       ath6kl_htc_cleanup(ar->htc_target);
+err_bmi_cleanup:
+       ath6kl_bmi_cleanup(ar);
+err_wq:
+       destroy_workqueue(ar->ath6kl_wq);
+       return ret;
+}
+
+void ath6kl_stop_txrx(struct ath6kl *ar)
+{
+       struct net_device *ndev = ar->net_dev;
+
+       if (!ndev)
+               return;
+
+       set_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+       if (down_interruptible(&ar->sem)) {
+               ath6kl_err("down_interruptible failed\n");
+               return;
+       }
+
+       if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
+               ath6kl_stop_endpoint(ndev, false, true);
+
+       clear_bit(WLAN_ENABLED, &ar->flag);
+}
+
+/*
+ * We need to differentiate between the surprise and planned removal of the
+ * device because of the following consideration:
+ *
+ * - In case of surprise removal, the hcd already frees up the pending
+ *   for the device and hence there is no need to unregister the function
+ *   driver inorder to get these requests. For planned removal, the function
+ *   driver has to explicitly unregister itself to have the hcd return all the
+ *   pending requests before the data structures for the devices are freed up.
+ *   Note that as per the current implementation, the function driver will
+ *   end up releasing all the devices since there is no API to selectively
+ *   release a particular device.
+ *
+ * - Certain commands issued to the target can be skipped for surprise
+ *   removal since they will anyway not go through.
+ */
+void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
+{
+       struct ath6kl *ar;
+
+       if (!dev || !ath6kl_priv(dev)) {
+               ath6kl_err("failed to get device structure\n");
+               return;
+       }
+
+       ar = ath6kl_priv(dev);
+
+       destroy_workqueue(ar->ath6kl_wq);
+
+       if (ar->htc_target)
+               ath6kl_htc_cleanup(ar->htc_target);
+
+       aggr_module_destroy(ar->aggr_cntxt);
+
+       ath6kl_cookie_cleanup(ar);
+
+       ath6kl_cleanup_amsdu_rxbufs(ar);
+
+       ath6kl_bmi_cleanup(ar);
+
+       if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) {
+               unregister_netdev(dev);
+               clear_bit(NETDEV_REGISTERED, &ar->flag);
+       }
+
+       free_netdev(dev);
+
+       wlan_node_table_cleanup(&ar->scan_table);
+
+       kfree(ar->fw_board);
+       kfree(ar->fw_otp);
+       kfree(ar->fw);
+       kfree(ar->fw_patch);
+
+       ath6kl_cfg80211_deinit(ar);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
new file mode 100644 (file)
index 0000000..c336eae
--- /dev/null
@@ -0,0 +1,1337 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 "core.h"
+#include "hif-ops.h"
+#include "cfg80211.h"
+#include "target.h"
+#include "debug.h"
+
+struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 *node_addr)
+{
+       struct ath6kl_sta *conn = NULL;
+       u8 i, max_conn;
+
+       max_conn = (ar->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;
+
+       for (i = 0; i < max_conn; i++) {
+               if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {
+                       conn = &ar->sta_list[i];
+                       break;
+               }
+       }
+
+       return conn;
+}
+
+struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
+{
+       struct ath6kl_sta *conn = NULL;
+       u8 ctr;
+
+       for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+               if (ar->sta_list[ctr].aid == aid) {
+                       conn = &ar->sta_list[ctr];
+                       break;
+               }
+       }
+       return conn;
+}
+
+static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
+                       u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
+{
+       struct ath6kl_sta *sta;
+       u8 free_slot;
+
+       free_slot = aid - 1;
+
+       sta = &ar->sta_list[free_slot];
+       memcpy(sta->mac, mac, ETH_ALEN);
+       memcpy(sta->wpa_ie, wpaie, ielen);
+       sta->aid = aid;
+       sta->keymgmt = keymgmt;
+       sta->ucipher = ucipher;
+       sta->auth = auth;
+
+       ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
+       ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
+}
+
+static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
+{
+       struct ath6kl_sta *sta = &ar->sta_list[i];
+
+       /* empty the queued pkts in the PS queue if any */
+       spin_lock_bh(&sta->psq_lock);
+       skb_queue_purge(&sta->psq);
+       spin_unlock_bh(&sta->psq_lock);
+
+       memset(&ar->ap_stats.sta[sta->aid - 1], 0,
+              sizeof(struct wmi_per_sta_stat));
+       memset(sta->mac, 0, ETH_ALEN);
+       memset(sta->wpa_ie, 0, ATH6KL_MAX_IE);
+       sta->aid = 0;
+       sta->sta_flags = 0;
+
+       ar->sta_list_index = ar->sta_list_index & ~(1 << i);
+
+}
+
+static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
+{
+       u8 i, removed = 0;
+
+       if (is_zero_ether_addr(mac))
+               return removed;
+
+       if (is_broadcast_ether_addr(mac)) {
+               ath6kl_dbg(ATH6KL_DBG_TRC, "deleting all station\n");
+
+               for (i = 0; i < AP_MAX_NUM_STA; i++) {
+                       if (!is_zero_ether_addr(ar->sta_list[i].mac)) {
+                               ath6kl_sta_cleanup(ar, i);
+                               removed = 1;
+                       }
+               }
+       } else {
+               for (i = 0; i < AP_MAX_NUM_STA; i++) {
+                       if (memcmp(ar->sta_list[i].mac, mac, ETH_ALEN) == 0) {
+                               ath6kl_dbg(ATH6KL_DBG_TRC,
+                                          "deleting station %pM aid=%d reason=%d\n",
+                                          mac, ar->sta_list[i].aid, reason);
+                               ath6kl_sta_cleanup(ar, i);
+                               removed = 1;
+                               break;
+                       }
+               }
+       }
+
+       return removed;
+}
+
+enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac)
+{
+       struct ath6kl *ar = devt;
+       return ar->ac2ep_map[ac];
+}
+
+struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar)
+{
+       struct ath6kl_cookie *cookie;
+
+       cookie = ar->cookie_list;
+       if (cookie != NULL) {
+               ar->cookie_list = cookie->arc_list_next;
+               ar->cookie_count--;
+       }
+
+       return cookie;
+}
+
+void ath6kl_cookie_init(struct ath6kl *ar)
+{
+       u32 i;
+
+       ar->cookie_list = NULL;
+       ar->cookie_count = 0;
+
+       memset(ar->cookie_mem, 0, sizeof(ar->cookie_mem));
+
+       for (i = 0; i < MAX_COOKIE_NUM; i++)
+               ath6kl_free_cookie(ar, &ar->cookie_mem[i]);
+}
+
+void ath6kl_cookie_cleanup(struct ath6kl *ar)
+{
+       ar->cookie_list = NULL;
+       ar->cookie_count = 0;
+}
+
+void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
+{
+       /* Insert first */
+
+       if (!ar || !cookie)
+               return;
+
+       cookie->arc_list_next = ar->cookie_list;
+       ar->cookie_list = cookie;
+       ar->cookie_count++;
+}
+
+/* set the window address register (using 4-byte register access ). */
+static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
+{
+       int status;
+       u8 addr_val[4];
+       s32 i;
+
+       /*
+        * Write bytes 1,2,3 of the register to set the upper address bytes,
+        * the LSB is written last to initiate the access cycle
+        */
+
+       for (i = 1; i <= 3; i++) {
+               /*
+                * Fill the buffer with the address byte value we want to
+                * hit 4 times.
+                */
+               memset(addr_val, ((u8 *)&addr)[i], 4);
+
+               /*
+                * Hit each byte of the register address with a 4-byte
+                * write operation to the same address, this is a harmless
+                * operation.
+                */
+               status = hif_read_write_sync(ar, reg_addr + i, addr_val,
+                                            4, HIF_WR_SYNC_BYTE_FIX);
+               if (status)
+                       break;
+       }
+
+       if (status) {
+               ath6kl_err("failed to write initial bytes of 0x%x to window reg: 0x%X\n",
+                          addr, reg_addr);
+               return status;
+       }
+
+       /*
+        * Write the address register again, this time write the whole
+        * 4-byte value. The effect here is that the LSB write causes the
+        * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
+        * effect since we are writing the same values again
+        */
+       status = hif_read_write_sync(ar, reg_addr, (u8 *)(&addr),
+                                    4, HIF_WR_SYNC_BYTE_INC);
+
+       if (status) {
+               ath6kl_err("failed to write 0x%x to window reg: 0x%X\n",
+                          addr, reg_addr);
+               return status;
+       }
+
+       return 0;
+}
+
+/*
+ * Read from the ATH6KL through its diagnostic window. No cooperation from
+ * the Target is required for this.
+ */
+int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
+{
+       int status;
+
+       /* set window register to start read cycle */
+       status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS,
+                                       *address);
+
+       if (status)
+               return status;
+
+       /* read the data */
+       status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
+                                    sizeof(u32), HIF_RD_SYNC_BYTE_INC);
+       if (status) {
+               ath6kl_err("failed to read from window data addr\n");
+               return status;
+       }
+
+       return status;
+}
+
+
+/*
+ * Write to the ATH6KL through its diagnostic window. No cooperation from
+ * the Target is required for this.
+ */
+static int ath6kl_write_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
+{
+       int status;
+
+       /* set write data */
+       status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
+                                    sizeof(u32), HIF_WR_SYNC_BYTE_INC);
+       if (status) {
+               ath6kl_err("failed to write 0x%x to window data addr\n", *data);
+               return status;
+       }
+
+       /* set window register, which starts the write cycle */
+       return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
+                                     *address);
+}
+
+int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
+                          u8 *data, u32 length, bool read)
+{
+       u32 count;
+       int status = 0;
+
+       for (count = 0; count < length; count += 4, address += 4) {
+               if (read) {
+                       status = ath6kl_read_reg_diag(ar, &address,
+                                                     (u32 *) &data[count]);
+                       if (status)
+                               break;
+               } else {
+                       status = ath6kl_write_reg_diag(ar, &address,
+                                                      (u32 *) &data[count]);
+                       if (status)
+                               break;
+               }
+       }
+
+       return status;
+}
+
+static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
+                               bool wait_fot_compltn, bool cold_reset)
+{
+       int status = 0;
+       u32 address;
+       u32 data;
+
+       if (target_type != TARGET_TYPE_AR6003)
+               return;
+
+       data = cold_reset ? RESET_CONTROL_COLD_RST : RESET_CONTROL_MBOX_RST;
+
+       address = RTC_BASE_ADDRESS;
+       status = ath6kl_write_reg_diag(ar, &address, &data);
+
+       if (status)
+               ath6kl_err("failed to reset target\n");
+}
+
+void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
+                         bool get_dbglogs)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+       bool discon_issued;
+
+       netif_stop_queue(dev);
+
+       /* disable the target and the interrupts associated with it */
+       if (test_bit(WMI_READY, &ar->flag)) {
+               discon_issued = (test_bit(CONNECTED, &ar->flag) ||
+                                test_bit(CONNECT_PEND, &ar->flag));
+               ath6kl_disconnect(ar);
+               if (!keep_profile)
+                       ath6kl_init_profile_info(ar);
+
+               del_timer(&ar->disconnect_timer);
+
+               clear_bit(WMI_READY, &ar->flag);
+               ath6kl_wmi_shutdown(ar->wmi);
+               clear_bit(WMI_ENABLED, &ar->flag);
+               ar->wmi = NULL;
+
+               /*
+                * After wmi_shudown all WMI events will be dropped. We
+                * need to cleanup the buffers allocated in AP mode and
+                * give disconnect notification to stack, which usually
+                * happens in the disconnect_event. Simulate the disconnect
+                * event by calling the function directly. Sometimes
+                * disconnect_event will be received when the debug logs
+                * are collected.
+                */
+               if (discon_issued)
+                       ath6kl_disconnect_event(ar, DISCONNECT_CMD,
+                                               (ar->nw_type & AP_NETWORK) ?
+                                               bcast_mac : ar->bssid,
+                                               0, NULL, 0);
+
+               ar->user_key_ctrl = 0;
+
+       } else {
+               ath6kl_dbg(ATH6KL_DBG_TRC,
+                          "%s: wmi is not ready 0x%p 0x%p\n",
+                          __func__, ar, ar->wmi);
+
+               /* Shut down WMI if we have started it */
+               if (test_bit(WMI_ENABLED, &ar->flag)) {
+                       ath6kl_dbg(ATH6KL_DBG_TRC,
+                                  "%s: shut down wmi\n", __func__);
+                       ath6kl_wmi_shutdown(ar->wmi);
+                       clear_bit(WMI_ENABLED, &ar->flag);
+                       ar->wmi = NULL;
+               }
+       }
+
+       if (ar->htc_target) {
+               ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
+               ath6kl_htc_stop(ar->htc_target);
+       }
+
+       /*
+        * Try to reset the device if we can. The driver may have been
+        * configure NOT to reset the target during a debug session.
+        */
+       ath6kl_dbg(ATH6KL_DBG_TRC,
+                  "attempting to reset target on instance destroy\n");
+       ath6kl_reset_device(ar, ar->target_type, true, true);
+}
+
+static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
+{
+       u8 index;
+       u8 keyusage;
+
+       for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+               if (ar->wep_key_list[index].key_len) {
+                       keyusage = GROUP_USAGE;
+                       if (index == ar->def_txkey_index)
+                               keyusage |= TX_USAGE;
+
+                       ath6kl_wmi_addkey_cmd(ar->wmi,
+                                             index,
+                                             WEP_CRYPT,
+                                             keyusage,
+                                             ar->wep_key_list[index].key_len,
+                                             NULL,
+                                             ar->wep_key_list[index].key,
+                                             KEY_OP_INIT_VAL, NULL,
+                                             NO_SYNC_WMIFLAG);
+               }
+       }
+}
+
+static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid,
+                                  u16 listen_int, u16 beacon_int,
+                                  u8 assoc_resp_len, u8 *assoc_info)
+{
+       struct net_device *dev = ar->net_dev;
+       struct station_info sinfo;
+       struct ath6kl_req_key *ik;
+       enum crypto_type keyType = NONE_CRYPT;
+
+       if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) {
+               ik = &ar->ap_mode_bkey;
+
+               switch (ar->auth_mode) {
+               case NONE_AUTH:
+                       if (ar->prwise_crypto == WEP_CRYPT)
+                               ath6kl_install_static_wep_keys(ar);
+                       break;
+               case WPA_PSK_AUTH:
+               case WPA2_PSK_AUTH:
+               case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
+                       switch (ik->ik_type) {
+                       case ATH6KL_CIPHER_TKIP:
+                               keyType = TKIP_CRYPT;
+                               break;
+                       case ATH6KL_CIPHER_AES_CCM:
+                               keyType = AES_CRYPT;
+                               break;
+                       default:
+                               goto skip_key;
+                       }
+                       ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
+                                             GROUP_USAGE, ik->ik_keylen,
+                                             (u8 *)&ik->ik_keyrsc,
+                                             ik->ik_keydata,
+                                             KEY_OP_INIT_VAL, ik->ik_macaddr,
+                                             SYNC_BOTH_WMIFLAG);
+                       break;
+               }
+skip_key:
+               set_bit(CONNECTED, &ar->flag);
+               return;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n",
+                  bssid, channel);
+
+       ath6kl_add_new_sta(ar, bssid, channel, assoc_info, assoc_resp_len,
+                          listen_int & 0xFF, beacon_int,
+                          (listen_int >> 8) & 0xFF);
+
+       /* send event to application */
+       memset(&sinfo, 0, sizeof(sinfo));
+
+       /* TODO: sinfo.generation */
+       /* TODO: need to deliver (Re)AssocReq IEs somehow.. change in
+        * cfg80211 needed, e.g., by adding those into sinfo
+        */
+       cfg80211_new_sta(ar->net_dev, bssid, &sinfo, GFP_KERNEL);
+
+       netif_wake_queue(ar->net_dev);
+
+       return;
+}
+
+/* Functions for Tx credit handling */
+void ath6k_credit_init(struct htc_credit_state_info *cred_info,
+                      struct list_head *ep_list,
+                      int tot_credits)
+{
+       struct htc_endpoint_credit_dist *cur_ep_dist;
+       int count;
+
+       cred_info->cur_free_credits = tot_credits;
+       cred_info->total_avail_credits = tot_credits;
+
+       list_for_each_entry(cur_ep_dist, ep_list, list) {
+               if (cur_ep_dist->endpoint == ENDPOINT_0)
+                       continue;
+
+               cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
+
+               if (tot_credits > 4)
+                       if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
+                           (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
+                               ath6kl_deposit_credit_to_ep(cred_info,
+                                               cur_ep_dist,
+                                               cur_ep_dist->cred_min);
+                               cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
+                       }
+
+               if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
+                       ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
+                                                   cur_ep_dist->cred_min);
+                       /*
+                        * Control service is always marked active, it
+                        * never goes inactive EVER.
+                        */
+                       cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
+               } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
+                       /* this is the lowest priority data endpoint */
+                       cred_info->lowestpri_ep_dist = cur_ep_dist->list;
+
+               /*
+                * Streams have to be created (explicit | implicit) for all
+                * kinds of traffic. BE endpoints are also inactive in the
+                * beginning. When BE traffic starts it creates implicit
+                * streams that redistributes credits.
+                *
+                * Note: all other endpoints have minimums set but are
+                * initially given NO credits. credits will be distributed
+                * as traffic activity demands
+                */
+       }
+
+       WARN_ON(cred_info->cur_free_credits <= 0);
+
+       list_for_each_entry(cur_ep_dist, ep_list, list) {
+               if (cur_ep_dist->endpoint == ENDPOINT_0)
+                       continue;
+
+               if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
+                       cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
+               else {
+                       /*
+                        * For the remaining data endpoints, we assume that
+                        * each cred_per_msg are the same. We use a simple
+                        * calculation here, we take the remaining credits
+                        * and determine how many max messages this can
+                        * cover and then set each endpoint's normal value
+                        * equal to 3/4 this amount.
+                        */
+                       count = (cred_info->cur_free_credits /
+                                cur_ep_dist->cred_per_msg)
+                               * cur_ep_dist->cred_per_msg;
+                       count = (count * 3) >> 2;
+                       count = max(count, cur_ep_dist->cred_per_msg);
+                       cur_ep_dist->cred_norm = count;
+
+               }
+       }
+}
+
+/* initialize and setup credit distribution */
+int ath6k_setup_credit_dist(void *htc_handle,
+                           struct htc_credit_state_info *cred_info)
+{
+       u16 servicepriority[5];
+
+       memset(cred_info, 0, sizeof(struct htc_credit_state_info));
+
+       servicepriority[0] = WMI_CONTROL_SVC;  /* highest */
+       servicepriority[1] = WMI_DATA_VO_SVC;
+       servicepriority[2] = WMI_DATA_VI_SVC;
+       servicepriority[3] = WMI_DATA_BE_SVC;
+       servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
+
+       /* set priority list */
+       ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5);
+
+       return 0;
+}
+
+/* reduce an ep's credits back to a set limit */
+static void ath6k_reduce_credits(struct htc_credit_state_info *cred_info,
+                                struct htc_endpoint_credit_dist  *ep_dist,
+                                int limit)
+{
+       int credits;
+
+       ep_dist->cred_assngd = limit;
+
+       if (ep_dist->credits <= limit)
+               return;
+
+       credits = ep_dist->credits - limit;
+       ep_dist->credits -= credits;
+       cred_info->cur_free_credits += credits;
+}
+
+static void ath6k_credit_update(struct htc_credit_state_info *cred_info,
+                               struct list_head *epdist_list)
+{
+       struct htc_endpoint_credit_dist *cur_dist_list;
+
+       list_for_each_entry(cur_dist_list, epdist_list, list) {
+               if (cur_dist_list->endpoint == ENDPOINT_0)
+                       continue;
+
+               if (cur_dist_list->cred_to_dist > 0) {
+                       cur_dist_list->credits +=
+                                       cur_dist_list->cred_to_dist;
+                       cur_dist_list->cred_to_dist = 0;
+                       if (cur_dist_list->credits >
+                           cur_dist_list->cred_assngd)
+                               ath6k_reduce_credits(cred_info,
+                                               cur_dist_list,
+                                               cur_dist_list->cred_assngd);
+
+                       if (cur_dist_list->credits >
+                           cur_dist_list->cred_norm)
+                               ath6k_reduce_credits(cred_info, cur_dist_list,
+                                                    cur_dist_list->cred_norm);
+
+                       if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
+                               if (cur_dist_list->txq_depth == 0)
+                                       ath6k_reduce_credits(cred_info,
+                                                            cur_dist_list, 0);
+                       }
+               }
+       }
+}
+
+/*
+ * HTC has an endpoint that needs credits, ep_dist is the endpoint in
+ * question.
+ */
+void ath6k_seek_credits(struct htc_credit_state_info *cred_info,
+                       struct htc_endpoint_credit_dist *ep_dist)
+{
+       struct htc_endpoint_credit_dist *curdist_list;
+       int credits = 0;
+       int need;
+
+       if (ep_dist->svc_id == WMI_CONTROL_SVC)
+               goto out;
+
+       if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
+           (ep_dist->svc_id == WMI_DATA_VO_SVC))
+               if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
+                       goto out;
+
+       /*
+        * For all other services, we follow a simple algorithm of:
+        *
+        * 1. checking the free pool for credits
+        * 2. checking lower priority endpoints for credits to take
+        */
+
+       credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
+
+       if (credits >= ep_dist->seek_cred)
+               goto out;
+
+       /*
+        * We don't have enough in the free pool, try taking away from
+        * lower priority services The rule for taking away credits:
+        *
+        *   1. Only take from lower priority endpoints
+        *   2. Only take what is allocated above the minimum (never
+        *      starve an endpoint completely)
+        *   3. Only take what you need.
+        */
+
+       list_for_each_entry_reverse(curdist_list,
+                                   &cred_info->lowestpri_ep_dist,
+                                   list) {
+               if (curdist_list == ep_dist)
+                       break;
+
+               need = ep_dist->seek_cred - cred_info->cur_free_credits;
+
+               if ((curdist_list->cred_assngd - need) >=
+                    curdist_list->cred_min) {
+                       /*
+                        * The current one has been allocated more than
+                        * it's minimum and it has enough credits assigned
+                        * above it's minimum to fulfill our need try to
+                        * take away just enough to fulfill our need.
+                        */
+                       ath6k_reduce_credits(cred_info, curdist_list,
+                                       curdist_list->cred_assngd - need);
+
+                       if (cred_info->cur_free_credits >=
+                           ep_dist->seek_cred)
+                               break;
+               }
+
+               if (curdist_list->endpoint == ENDPOINT_0)
+                       break;
+       }
+
+       credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
+
+out:
+       /* did we find some credits? */
+       if (credits)
+               ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits);
+
+       ep_dist->seek_cred = 0;
+}
+
+/* redistribute credits based on activity change */
+static void ath6k_redistribute_credits(struct htc_credit_state_info *info,
+                                      struct list_head *ep_dist_list)
+{
+       struct htc_endpoint_credit_dist *curdist_list;
+
+       list_for_each_entry(curdist_list, ep_dist_list, list) {
+               if (curdist_list->endpoint == ENDPOINT_0)
+                       continue;
+
+               if ((curdist_list->svc_id == WMI_DATA_BK_SVC)  ||
+                   (curdist_list->svc_id == WMI_DATA_BE_SVC))
+                       curdist_list->dist_flags |= HTC_EP_ACTIVE;
+
+               if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
+                   !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
+                       if (curdist_list->txq_depth == 0)
+                               ath6k_reduce_credits(info,
+                                               curdist_list, 0);
+                       else
+                               ath6k_reduce_credits(info,
+                                               curdist_list,
+                                               curdist_list->cred_min);
+               }
+       }
+}
+
+/*
+ *
+ * This function is invoked whenever endpoints require credit
+ * distributions. A lock is held while this function is invoked, this
+ * function shall NOT block. The ep_dist_list is a list of distribution
+ * structures in prioritized order as defined by the call to the
+ * htc_set_credit_dist() api.
+ */
+void ath6k_credit_distribute(struct htc_credit_state_info *cred_info,
+                            struct list_head *ep_dist_list,
+                            enum htc_credit_dist_reason reason)
+{
+       switch (reason) {
+       case HTC_CREDIT_DIST_SEND_COMPLETE:
+               ath6k_credit_update(cred_info, ep_dist_list);
+               break;
+       case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
+               ath6k_redistribute_credits(cred_info, ep_dist_list);
+               break;
+       default:
+               break;
+       }
+
+       WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
+       WARN_ON(cred_info->cur_free_credits < 0);
+}
+
+void disconnect_timer_handler(unsigned long ptr)
+{
+       struct net_device *dev = (struct net_device *)ptr;
+       struct ath6kl *ar = ath6kl_priv(dev);
+
+       ath6kl_init_profile_info(ar);
+       ath6kl_disconnect(ar);
+}
+
+void ath6kl_disconnect(struct ath6kl *ar)
+{
+       if (test_bit(CONNECTED, &ar->flag) ||
+           test_bit(CONNECT_PEND, &ar->flag)) {
+               ath6kl_wmi_disconnect_cmd(ar->wmi);
+               /*
+                * Disconnect command is issued, clear the connect pending
+                * flag. The connected flag will be cleared in
+                * disconnect event notification.
+                */
+               clear_bit(CONNECT_PEND, &ar->flag);
+       }
+}
+
+/* WMI Event handlers */
+
+static const char *get_hw_id_string(u32 id)
+{
+       switch (id) {
+       case AR6003_REV1_VERSION:
+               return "1.0";
+       case AR6003_REV2_VERSION:
+               return "2.0";
+       case AR6003_REV3_VERSION:
+               return "2.1.1";
+       default:
+               return "unknown";
+       }
+}
+
+void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
+{
+       struct ath6kl *ar = devt;
+       struct net_device *dev = ar->net_dev;
+
+       memcpy(dev->dev_addr, datap, ETH_ALEN);
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
+                  __func__, dev->dev_addr);
+
+       ar->version.wlan_ver = sw_ver;
+       ar->version.abi_ver = abi_ver;
+
+       snprintf(ar->wdev->wiphy->fw_version,
+                sizeof(ar->wdev->wiphy->fw_version),
+                "%u.%u.%u.%u",
+                (ar->version.wlan_ver & 0xf0000000) >> 28,
+                (ar->version.wlan_ver & 0x0f000000) >> 24,
+                (ar->version.wlan_ver & 0x00ff0000) >> 16,
+                (ar->version.wlan_ver & 0x0000ffff));
+
+       /* indicate to the waiting thread that the ready event was received */
+       set_bit(WMI_READY, &ar->flag);
+       wake_up(&ar->event_wq);
+
+       ath6kl_info("hw %s fw %s\n",
+                   get_hw_id_string(ar->wdev->wiphy->hw_version),
+                   ar->wdev->wiphy->fw_version);
+}
+
+void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
+{
+       ath6kl_cfg80211_scan_complete_event(ar, status);
+
+       if (!ar->usr_bss_filter)
+               ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
+}
+
+void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
+                         u16 listen_int, u16 beacon_int,
+                         enum network_type net_type, u8 beacon_ie_len,
+                         u8 assoc_req_len, u8 assoc_resp_len,
+                         u8 *assoc_info)
+{
+       unsigned long flags;
+
+       if (ar->nw_type == AP_NETWORK) {
+               ath6kl_connect_ap_mode(ar, channel, bssid, listen_int,
+                                      beacon_int, assoc_resp_len,
+                                      assoc_info);
+               return;
+       }
+
+       ath6kl_cfg80211_connect_event(ar, channel, bssid,
+                                     listen_int, beacon_int,
+                                     net_type, beacon_ie_len,
+                                     assoc_req_len, assoc_resp_len,
+                                     assoc_info);
+
+       memcpy(ar->bssid, bssid, sizeof(ar->bssid));
+       ar->bss_ch = channel;
+
+       if ((ar->nw_type == INFRA_NETWORK))
+               ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t,
+                                             ar->listen_intvl_b);
+
+       netif_wake_queue(ar->net_dev);
+
+       /* Update connect & link status atomically */
+       spin_lock_irqsave(&ar->lock, flags);
+       set_bit(CONNECTED, &ar->flag);
+       clear_bit(CONNECT_PEND, &ar->flag);
+       netif_carrier_on(ar->net_dev);
+       spin_unlock_irqrestore(&ar->lock, flags);
+
+       aggr_reset_state(ar->aggr_cntxt);
+       ar->reconnect_flag = 0;
+
+       if ((ar->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
+               memset(ar->node_map, 0, sizeof(ar->node_map));
+               ar->node_num = 0;
+               ar->next_ep_id = ENDPOINT_2;
+       }
+
+       if (!ar->usr_bss_filter)
+               ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+}
+
+void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
+{
+       struct ath6kl_sta *sta;
+       u8 tsc[6];
+       /*
+        * For AP case, keyid will have aid of STA which sent pkt with
+        * MIC error. Use this aid to get MAC & send it to hostapd.
+        */
+       if (ar->nw_type == AP_NETWORK) {
+               sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));
+               if (!sta)
+                       return;
+
+               ath6kl_dbg(ATH6KL_DBG_TRC,
+                          "ap tkip mic error received from aid=%d\n", keyid);
+
+               memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */
+               cfg80211_michael_mic_failure(ar->net_dev, sta->mac,
+                                            NL80211_KEYTYPE_PAIRWISE, keyid,
+                                            tsc, GFP_KERNEL);
+       } else
+               ath6kl_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
+
+}
+
+static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
+{
+       struct wmi_target_stats *tgt_stats =
+               (struct wmi_target_stats *) ptr;
+       struct target_stats *stats = &ar->target_stats;
+       struct tkip_ccmp_stats *ccmp_stats;
+       struct bss *conn_bss = NULL;
+       struct cserv_stats *c_stats;
+       u8 ac;
+
+       if (len < sizeof(*tgt_stats))
+               return;
+
+       /* update the RSSI of the connected bss */
+       if (test_bit(CONNECTED, &ar->flag)) {
+               conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
+               if (conn_bss) {
+                       c_stats = &tgt_stats->cserv_stats;
+                       conn_bss->ni_rssi =
+                               a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
+                       conn_bss->ni_snr =
+                               tgt_stats->cserv_stats.cs_ave_beacon_snr;
+                       ath6kl_wmi_node_return(ar->wmi, conn_bss);
+               }
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
+
+       stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
+       stats->tx_byte += le32_to_cpu(tgt_stats->stats.tx.byte);
+       stats->tx_ucast_pkt += le32_to_cpu(tgt_stats->stats.tx.ucast_pkt);
+       stats->tx_ucast_byte += le32_to_cpu(tgt_stats->stats.tx.ucast_byte);
+       stats->tx_mcast_pkt += le32_to_cpu(tgt_stats->stats.tx.mcast_pkt);
+       stats->tx_mcast_byte += le32_to_cpu(tgt_stats->stats.tx.mcast_byte);
+       stats->tx_bcast_pkt  += le32_to_cpu(tgt_stats->stats.tx.bcast_pkt);
+       stats->tx_bcast_byte += le32_to_cpu(tgt_stats->stats.tx.bcast_byte);
+       stats->tx_rts_success_cnt +=
+               le32_to_cpu(tgt_stats->stats.tx.rts_success_cnt);
+
+       for (ac = 0; ac < WMM_NUM_AC; ac++)
+               stats->tx_pkt_per_ac[ac] +=
+                       le32_to_cpu(tgt_stats->stats.tx.pkt_per_ac[ac]);
+
+       stats->tx_err += le32_to_cpu(tgt_stats->stats.tx.err);
+       stats->tx_fail_cnt += le32_to_cpu(tgt_stats->stats.tx.fail_cnt);
+       stats->tx_retry_cnt += le32_to_cpu(tgt_stats->stats.tx.retry_cnt);
+       stats->tx_mult_retry_cnt +=
+               le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
+       stats->tx_rts_fail_cnt +=
+               le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
+       stats->tx_ucast_rate =
+           ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
+
+       stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
+       stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
+       stats->rx_ucast_pkt += le32_to_cpu(tgt_stats->stats.rx.ucast_pkt);
+       stats->rx_ucast_byte += le32_to_cpu(tgt_stats->stats.rx.ucast_byte);
+       stats->rx_mcast_pkt += le32_to_cpu(tgt_stats->stats.rx.mcast_pkt);
+       stats->rx_mcast_byte += le32_to_cpu(tgt_stats->stats.rx.mcast_byte);
+       stats->rx_bcast_pkt += le32_to_cpu(tgt_stats->stats.rx.bcast_pkt);
+       stats->rx_bcast_byte += le32_to_cpu(tgt_stats->stats.rx.bcast_byte);
+       stats->rx_frgment_pkt += le32_to_cpu(tgt_stats->stats.rx.frgment_pkt);
+       stats->rx_err += le32_to_cpu(tgt_stats->stats.rx.err);
+       stats->rx_crc_err += le32_to_cpu(tgt_stats->stats.rx.crc_err);
+       stats->rx_key_cache_miss +=
+               le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
+       stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
+       stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
+       stats->rx_ucast_rate =
+           ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
+
+       ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
+
+       stats->tkip_local_mic_fail +=
+               le32_to_cpu(ccmp_stats->tkip_local_mic_fail);
+       stats->tkip_cnter_measures_invoked +=
+               le32_to_cpu(ccmp_stats->tkip_cnter_measures_invoked);
+       stats->tkip_fmt_err += le32_to_cpu(ccmp_stats->tkip_fmt_err);
+
+       stats->ccmp_fmt_err += le32_to_cpu(ccmp_stats->ccmp_fmt_err);
+       stats->ccmp_replays += le32_to_cpu(ccmp_stats->ccmp_replays);
+
+       stats->pwr_save_fail_cnt +=
+               le32_to_cpu(tgt_stats->pm_stats.pwr_save_failure_cnt);
+       stats->noise_floor_calib =
+               a_sle32_to_cpu(tgt_stats->noise_floor_calib);
+
+       stats->cs_bmiss_cnt +=
+               le32_to_cpu(tgt_stats->cserv_stats.cs_bmiss_cnt);
+       stats->cs_low_rssi_cnt +=
+               le32_to_cpu(tgt_stats->cserv_stats.cs_low_rssi_cnt);
+       stats->cs_connect_cnt +=
+               le16_to_cpu(tgt_stats->cserv_stats.cs_connect_cnt);
+       stats->cs_discon_cnt +=
+               le16_to_cpu(tgt_stats->cserv_stats.cs_discon_cnt);
+
+       stats->cs_ave_beacon_rssi =
+               a_sle16_to_cpu(tgt_stats->cserv_stats.cs_ave_beacon_rssi);
+
+       stats->cs_last_roam_msec =
+               tgt_stats->cserv_stats.cs_last_roam_msec;
+       stats->cs_snr = tgt_stats->cserv_stats.cs_snr;
+       stats->cs_rssi = a_sle16_to_cpu(tgt_stats->cserv_stats.cs_rssi);
+
+       stats->lq_val = le32_to_cpu(tgt_stats->lq_val);
+
+       stats->wow_pkt_dropped +=
+               le32_to_cpu(tgt_stats->wow_stats.wow_pkt_dropped);
+       stats->wow_host_pkt_wakeups +=
+               tgt_stats->wow_stats.wow_host_pkt_wakeups;
+       stats->wow_host_evt_wakeups +=
+               tgt_stats->wow_stats.wow_host_evt_wakeups;
+       stats->wow_evt_discarded +=
+               le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);
+
+       if (test_bit(STATS_UPDATE_PEND, &ar->flag)) {
+               clear_bit(STATS_UPDATE_PEND, &ar->flag);
+               wake_up(&ar->event_wq);
+       }
+}
+
+static void ath6kl_add_le32(__le32 *var, __le32 val)
+{
+       *var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));
+}
+
+void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len)
+{
+       struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
+       struct wmi_ap_mode_stat *ap = &ar->ap_stats;
+       struct wmi_per_sta_stat *st_ap, *st_p;
+       u8 ac;
+
+       if (ar->nw_type == AP_NETWORK) {
+               if (len < sizeof(*p))
+                       return;
+
+               for (ac = 0; ac < AP_MAX_NUM_STA; ac++) {
+                       st_ap = &ap->sta[ac];
+                       st_p = &p->sta[ac];
+
+                       ath6kl_add_le32(&st_ap->tx_bytes, st_p->tx_bytes);
+                       ath6kl_add_le32(&st_ap->tx_pkts, st_p->tx_pkts);
+                       ath6kl_add_le32(&st_ap->tx_error, st_p->tx_error);
+                       ath6kl_add_le32(&st_ap->tx_discard, st_p->tx_discard);
+                       ath6kl_add_le32(&st_ap->rx_bytes, st_p->rx_bytes);
+                       ath6kl_add_le32(&st_ap->rx_pkts, st_p->rx_pkts);
+                       ath6kl_add_le32(&st_ap->rx_error, st_p->rx_error);
+                       ath6kl_add_le32(&st_ap->rx_discard, st_p->rx_discard);
+               }
+
+       } else {
+               ath6kl_update_target_stats(ar, ptr, len);
+       }
+}
+
+void ath6kl_wakeup_event(void *dev)
+{
+       struct ath6kl *ar = (struct ath6kl *) dev;
+
+       wake_up(&ar->event_wq);
+}
+
+void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
+{
+       struct ath6kl *ar = (struct ath6kl *) devt;
+
+       ar->tx_pwr = tx_pwr;
+       wake_up(&ar->event_wq);
+}
+
+void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
+{
+       struct ath6kl_sta *conn;
+       struct sk_buff *skb;
+       bool psq_empty = false;
+
+       conn = ath6kl_find_sta_by_aid(ar, aid);
+
+       if (!conn)
+               return;
+       /*
+        * Send out a packet queued on ps queue. When the ps queue
+        * becomes empty update the PVB for this station.
+        */
+       spin_lock_bh(&conn->psq_lock);
+       psq_empty  = skb_queue_empty(&conn->psq);
+       spin_unlock_bh(&conn->psq_lock);
+
+       if (psq_empty)
+               /* TODO: Send out a NULL data frame */
+               return;
+
+       spin_lock_bh(&conn->psq_lock);
+       skb = skb_dequeue(&conn->psq);
+       spin_unlock_bh(&conn->psq_lock);
+
+       conn->sta_flags |= STA_PS_POLLED;
+       ath6kl_data_tx(skb, ar->net_dev);
+       conn->sta_flags &= ~STA_PS_POLLED;
+
+       spin_lock_bh(&conn->psq_lock);
+       psq_empty  = skb_queue_empty(&conn->psq);
+       spin_unlock_bh(&conn->psq_lock);
+
+       if (psq_empty)
+               ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
+}
+
+void ath6kl_dtimexpiry_event(struct ath6kl *ar)
+{
+       bool mcastq_empty = false;
+       struct sk_buff *skb;
+
+       /*
+        * If there are no associated STAs, ignore the DTIM expiry event.
+        * There can be potential race conditions where the last associated
+        * STA may disconnect & before the host could clear the 'Indicate
+        * DTIM' request to the firmware, the firmware would have just
+        * indicated a DTIM expiry event. The race is between 'clear DTIM
+        * expiry cmd' going from the host to the firmware & the DTIM
+        * expiry event happening from the firmware to the host.
+        */
+       if (!ar->sta_list_index)
+               return;
+
+       spin_lock_bh(&ar->mcastpsq_lock);
+       mcastq_empty = skb_queue_empty(&ar->mcastpsq);
+       spin_unlock_bh(&ar->mcastpsq_lock);
+
+       if (mcastq_empty)
+               return;
+
+       /* set the STA flag to dtim_expired for the frame to go out */
+       set_bit(DTIM_EXPIRED, &ar->flag);
+
+       spin_lock_bh(&ar->mcastpsq_lock);
+       while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
+               spin_unlock_bh(&ar->mcastpsq_lock);
+
+               ath6kl_data_tx(skb, ar->net_dev);
+
+               spin_lock_bh(&ar->mcastpsq_lock);
+       }
+       spin_unlock_bh(&ar->mcastpsq_lock);
+
+       clear_bit(DTIM_EXPIRED, &ar->flag);
+
+       /* clear the LSB of the BitMapCtl field of the TIM IE */
+       ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
+}
+
+void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
+                            u8 assoc_resp_len, u8 *assoc_info,
+                            u16 prot_reason_status)
+{
+       struct bss *wmi_ssid_node = NULL;
+       unsigned long flags;
+
+       if (ar->nw_type == AP_NETWORK) {
+               if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
+                       return;
+
+               /* if no more associated STAs, empty the mcast PS q */
+               if (ar->sta_list_index == 0) {
+                       spin_lock_bh(&ar->mcastpsq_lock);
+                       skb_queue_purge(&ar->mcastpsq);
+                       spin_unlock_bh(&ar->mcastpsq_lock);
+
+                       /* clear the LSB of the TIM IE's BitMapCtl field */
+                       if (test_bit(WMI_READY, &ar->flag))
+                               ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
+               }
+
+               if (!is_broadcast_ether_addr(bssid)) {
+                       /* send event to application */
+                       cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
+               }
+
+               clear_bit(CONNECTED, &ar->flag);
+               return;
+       }
+
+       ath6kl_cfg80211_disconnect_event(ar, reason, bssid,
+                                      assoc_resp_len, assoc_info,
+                                      prot_reason_status);
+
+       aggr_reset_state(ar->aggr_cntxt);
+
+       del_timer(&ar->disconnect_timer);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CONNECT,
+                  "disconnect reason is %d\n", reason);
+
+       /*
+        * If the event is due to disconnect cmd from the host, only they
+        * the target would stop trying to connect. Under any other
+        * condition, target would keep trying to connect.
+        */
+       if (reason == DISCONNECT_CMD) {
+               if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
+                       ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+       } else {
+               set_bit(CONNECT_PEND, &ar->flag);
+               if (((reason == ASSOC_FAILED) &&
+                   (prot_reason_status == 0x11)) ||
+                   ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
+                    && (ar->reconnect_flag == 1))) {
+                       set_bit(CONNECTED, &ar->flag);
+                       return;
+               }
+       }
+
+       if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag))  {
+               ath6kl_wmi_node_free(ar->wmi, bssid);
+
+               /*
+                * In case any other same SSID nodes are present remove it,
+                * since those nodes also not available now.
+                */
+               do {
+                       /*
+                        * Find the nodes based on SSID and remove it
+                        *
+                        * Note: This case will not work out for
+                        * Hidden-SSID
+                        */
+                       wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
+                                                                 ar->ssid,
+                                                                 ar->ssid_len,
+                                                                 false,
+                                                                 true);
+
+                       if (wmi_ssid_node)
+                               ath6kl_wmi_node_free(ar->wmi,
+                                                    wmi_ssid_node->ni_macaddr);
+
+               } while (wmi_ssid_node);
+       }
+
+       /* update connect & link status atomically */
+       spin_lock_irqsave(&ar->lock, flags);
+       clear_bit(CONNECTED, &ar->flag);
+       netif_carrier_off(ar->net_dev);
+       spin_unlock_irqrestore(&ar->lock, flags);
+
+       if ((reason != CSERV_DISCONNECT) || (ar->reconnect_flag != 1))
+               ar->reconnect_flag = 0;
+
+       if (reason != CSERV_DISCONNECT)
+               ar->user_key_ctrl = 0;
+
+       netif_stop_queue(ar->net_dev);
+       memset(ar->bssid, 0, sizeof(ar->bssid));
+       ar->bss_ch = 0;
+
+       ath6kl_tx_data_cleanup(ar);
+}
+
+static int ath6kl_open(struct net_device *dev)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&ar->lock, flags);
+
+       set_bit(WLAN_ENABLED, &ar->flag);
+
+       if (test_bit(CONNECTED, &ar->flag)) {
+               netif_carrier_on(dev);
+               netif_wake_queue(dev);
+       } else
+               netif_carrier_off(dev);
+
+       spin_unlock_irqrestore(&ar->lock, flags);
+
+       return 0;
+}
+
+static int ath6kl_close(struct net_device *dev)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+
+       netif_stop_queue(dev);
+
+       ath6kl_disconnect(ar);
+
+       if (test_bit(WMI_READY, &ar->flag)) {
+               if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0,
+                                             0, 0, 0))
+                       return -EIO;
+
+               clear_bit(WLAN_ENABLED, &ar->flag);
+       }
+
+       ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
+
+       return 0;
+}
+
+static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+
+       return &ar->net_stats;
+}
+
+static struct net_device_ops ath6kl_netdev_ops = {
+       .ndo_open               = ath6kl_open,
+       .ndo_stop               = ath6kl_close,
+       .ndo_start_xmit         = ath6kl_data_tx,
+       .ndo_get_stats          = ath6kl_get_stats,
+};
+
+void init_netdev(struct net_device *dev)
+{
+       dev->netdev_ops = &ath6kl_netdev_ops;
+       dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
+
+       dev->needed_headroom = ETH_HLEN;
+       dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
+                               sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
+                               + WMI_MAX_TX_META_SZ;
+
+       return;
+}
diff --git a/drivers/net/wireless/ath/ath6kl/node.c b/drivers/net/wireless/ath/ath6kl/node.c
new file mode 100644 (file)
index 0000000..131205c
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 "htc.h"
+#include "wmi.h"
+#include "debug.h"
+
+struct bss *wlan_node_alloc(int wh_size)
+{
+       struct bss *ni;
+
+       ni = kzalloc(sizeof(struct bss), GFP_ATOMIC);
+
+       if ((ni != NULL) && wh_size) {
+               ni->ni_buf = kmalloc(wh_size, GFP_ATOMIC);
+               if (ni->ni_buf == NULL) {
+                       kfree(ni);
+                       return NULL;
+               }
+       }
+
+       return ni;
+}
+
+void wlan_node_free(struct bss *ni)
+{
+       kfree(ni->ni_buf);
+       kfree(ni);
+}
+
+void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
+                    const u8 *mac_addr)
+{
+       int hash;
+
+       memcpy(ni->ni_macaddr, mac_addr, ETH_ALEN);
+       hash = ATH6KL_NODE_HASH(mac_addr);
+       ni->ni_refcnt = 1;
+
+       ni->ni_tstamp = jiffies_to_msecs(jiffies);
+       ni->ni_actcnt = WLAN_NODE_INACT_CNT;
+
+       spin_lock_bh(&nt->nt_nodelock);
+
+       /* insert at the end of the node list */
+       ni->ni_list_next = NULL;
+       ni->ni_list_prev = nt->nt_node_last;
+       if (nt->nt_node_last != NULL)
+               nt->nt_node_last->ni_list_next = ni;
+
+       nt->nt_node_last = ni;
+       if (nt->nt_node_first == NULL)
+               nt->nt_node_first = ni;
+
+       /* insert into the hash list */
+       ni->ni_hash_next = nt->nt_hash[hash];
+       if (ni->ni_hash_next != NULL)
+               nt->nt_hash[hash]->ni_hash_prev = ni;
+
+       ni->ni_hash_prev = NULL;
+       nt->nt_hash[hash] = ni;
+
+       spin_unlock_bh(&nt->nt_nodelock);
+}
+
+struct bss *wlan_find_node(struct ath6kl_node_table *nt,
+                          const u8 *mac_addr)
+{
+       struct bss *ni, *found_ni = NULL;
+       int hash;
+
+       spin_lock_bh(&nt->nt_nodelock);
+
+       hash = ATH6KL_NODE_HASH(mac_addr);
+       for (ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
+               if (memcmp(ni->ni_macaddr, mac_addr, ETH_ALEN) == 0) {
+                       ni->ni_refcnt++;
+                       found_ni = ni;
+                       break;
+               }
+       }
+
+       spin_unlock_bh(&nt->nt_nodelock);
+
+       return found_ni;
+}
+
+void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni)
+{
+       int hash;
+
+       spin_lock_bh(&nt->nt_nodelock);
+
+       if (ni->ni_list_prev == NULL)
+               /* fix list head */
+               nt->nt_node_first = ni->ni_list_next;
+       else
+               ni->ni_list_prev->ni_list_next = ni->ni_list_next;
+
+       if (ni->ni_list_next == NULL)
+               /* fix list tail */
+               nt->nt_node_last = ni->ni_list_prev;
+       else
+               ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
+
+       if (ni->ni_hash_prev == NULL) {
+               /* first in list so fix the list head */
+               hash = ATH6KL_NODE_HASH(ni->ni_macaddr);
+               nt->nt_hash[hash] = ni->ni_hash_next;
+       } else {
+               ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
+       }
+
+       if (ni->ni_hash_next != NULL)
+               ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
+
+       wlan_node_free(ni);
+
+       spin_unlock_bh(&nt->nt_nodelock);
+}
+
+static void wlan_node_dec_free(struct bss *ni)
+{
+       if ((ni->ni_refcnt--) == 1)
+               wlan_node_free(ni);
+}
+
+void wlan_free_allnodes(struct ath6kl_node_table *nt)
+{
+       struct bss *ni;
+
+       while ((ni = nt->nt_node_first) != NULL)
+               wlan_node_reclaim(nt, ni);
+}
+
+void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg)
+{
+       struct bss *ni;
+
+       spin_lock_bh(&nt->nt_nodelock);
+       for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+                       ni->ni_refcnt++;
+                       ath6kl_cfg80211_scan_node(arg, ni);
+                       wlan_node_dec_free(ni);
+       }
+       spin_unlock_bh(&nt->nt_nodelock);
+}
+
+void wlan_node_table_init(struct ath6kl_node_table *nt)
+{
+       ath6kl_dbg(ATH6KL_DBG_WLAN_NODE, "node table = 0x%lx\n",
+                  (unsigned long)nt);
+
+       memset(nt, 0, sizeof(struct ath6kl_node_table));
+
+       spin_lock_init(&nt->nt_nodelock);
+
+       nt->nt_node_age = WLAN_NODE_INACT_TIMEOUT_MSEC;
+}
+
+void wlan_refresh_inactive_nodes(struct ath6kl *ar)
+{
+       struct ath6kl_node_table *nt = &ar->scan_table;
+       struct bss *bss;
+       u32 now;
+
+       now = jiffies_to_msecs(jiffies);
+       bss = nt->nt_node_first;
+       while (bss != NULL) {
+               /* refresh all nodes except the current bss */
+               if (memcmp(ar->bssid, bss->ni_macaddr, ETH_ALEN) != 0) {
+                       if (((now - bss->ni_tstamp) > nt->nt_node_age)
+                           || --bss->ni_actcnt == 0) {
+                               wlan_node_reclaim(nt, bss);
+                       }
+               }
+               bss = bss->ni_list_next;
+       }
+}
+
+void wlan_node_table_cleanup(struct ath6kl_node_table *nt)
+{
+       wlan_free_allnodes(nt);
+}
+
+struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 * ssid,
+                               u32 ssid_len, bool is_wpa2, bool match_ssid)
+{
+       struct bss *ni, *found_ni = NULL;
+       u8 *ie_ssid;
+
+       spin_lock_bh(&nt->nt_nodelock);
+
+       for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+
+               ie_ssid = ni->ni_cie.ie_ssid;
+
+               if ((ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
+                   (memcmp(ssid, &ie_ssid[2], ssid_len) == 0)) {
+
+                               if (match_ssid ||
+                                   (is_wpa2 && ni->ni_cie.ie_rsn != NULL) ||
+                                   (!is_wpa2 && ni->ni_cie.ie_wpa != NULL)) {
+                                       ni->ni_refcnt++;
+                                       found_ni = ni;
+                                       break;
+                               }
+               }
+       }
+
+       spin_unlock_bh(&nt->nt_nodelock);
+
+       return found_ni;
+}
+
+void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni)
+{
+       spin_lock_bh(&nt->nt_nodelock);
+       wlan_node_dec_free(ni);
+       spin_unlock_bh(&nt->nt_nodelock);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
new file mode 100644 (file)
index 0000000..3417160
--- /dev/null
@@ -0,0 +1,912 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sd.h>
+#include "htc_hif.h"
+#include "hif-ops.h"
+#include "target.h"
+#include "debug.h"
+
+struct ath6kl_sdio {
+       struct sdio_func *func;
+
+       spinlock_t lock;
+
+       /* free list */
+       struct list_head bus_req_freeq;
+
+       /* available bus requests */
+       struct bus_request bus_req[BUS_REQUEST_MAX_NUM];
+
+       struct ath6kl *ar;
+       u8 *dma_buffer;
+
+       /* scatter request list head */
+       struct list_head scat_req;
+
+       spinlock_t scat_lock;
+       bool is_disabled;
+       atomic_t irq_handling;
+       const struct sdio_device_id *id;
+       struct work_struct wr_async_work;
+       struct list_head wr_asyncq;
+       spinlock_t wr_async_lock;
+};
+
+#define CMD53_ARG_READ          0
+#define CMD53_ARG_WRITE         1
+#define CMD53_ARG_BLOCK_BASIS   1
+#define CMD53_ARG_FIXED_ADDRESS 0
+#define CMD53_ARG_INCR_ADDRESS  1
+
+static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar)
+{
+       return ar->hif_priv;
+}
+
+/*
+ * Macro to check if DMA buffer is WORD-aligned and DMA-able.
+ * Most host controllers assume the buffer is DMA'able and will
+ * bug-check otherwise (i.e. buffers on the stack). virt_addr_valid
+ * check fails on stack memory.
+ */
+static inline bool buf_needs_bounce(u8 *buf)
+{
+       return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf);
+}
+
+static void ath6kl_sdio_set_mbox_info(struct ath6kl *ar)
+{
+       struct ath6kl_mbox_info *mbox_info = &ar->mbox_info;
+
+       /* EP1 has an extended range */
+       mbox_info->htc_addr = HIF_MBOX_BASE_ADDR;
+       mbox_info->htc_ext_addr = HIF_MBOX0_EXT_BASE_ADDR;
+       mbox_info->htc_ext_sz = HIF_MBOX0_EXT_WIDTH;
+       mbox_info->block_size = HIF_MBOX_BLOCK_SIZE;
+       mbox_info->gmbox_addr = HIF_GMBOX_BASE_ADDR;
+       mbox_info->gmbox_sz = HIF_GMBOX_WIDTH;
+}
+
+static inline void ath6kl_sdio_set_cmd53_arg(u32 *arg, u8 rw, u8 func,
+                                            u8 mode, u8 opcode, u32 addr,
+                                            u16 blksz)
+{
+       *arg = (((rw & 1) << 31) |
+               ((func & 0x7) << 28) |
+               ((mode & 1) << 27) |
+               ((opcode & 1) << 26) |
+               ((addr & 0x1FFFF) << 9) |
+               (blksz & 0x1FF));
+}
+
+static inline void ath6kl_sdio_set_cmd52_arg(u32 *arg, u8 write, u8 raw,
+                                            unsigned int address,
+                                            unsigned char val)
+{
+       const u8 func = 0;
+
+       *arg = ((write & 1) << 31) |
+              ((func & 0x7) << 28) |
+              ((raw & 1) << 27) |
+              (1 << 26) |
+              ((address & 0x1FFFF) << 9) |
+              (1 << 8) |
+              (val & 0xFF);
+}
+
+static int ath6kl_sdio_func0_cmd52_wr_byte(struct mmc_card *card,
+                                          unsigned int address,
+                                          unsigned char byte)
+{
+       struct mmc_command io_cmd;
+
+       memset(&io_cmd, 0, sizeof(io_cmd));
+       ath6kl_sdio_set_cmd52_arg(&io_cmd.arg, 1, 0, address, byte);
+       io_cmd.opcode = SD_IO_RW_DIRECT;
+       io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
+
+       return mmc_wait_for_cmd(card->host, &io_cmd, 0);
+}
+
+static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
+                         u8 *buf, u32 len)
+{
+       int ret = 0;
+
+       if (request & HIF_WRITE) {
+               if (addr >= HIF_MBOX_BASE_ADDR &&
+                   addr <= HIF_MBOX_END_ADDR)
+                       addr += (HIF_MBOX_WIDTH - len);
+
+               if (addr == HIF_MBOX0_EXT_BASE_ADDR)
+                       addr += HIF_MBOX0_EXT_WIDTH - len;
+
+               if (request & HIF_FIXED_ADDRESS)
+                       ret = sdio_writesb(func, addr, buf, len);
+               else
+                       ret = sdio_memcpy_toio(func, addr, buf, len);
+       } else {
+               if (request & HIF_FIXED_ADDRESS)
+                       ret = sdio_readsb(func, buf, addr, len);
+               else
+                       ret = sdio_memcpy_fromio(func, buf, addr, len);
+       }
+
+       return ret;
+}
+
+static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
+{
+       struct bus_request *bus_req;
+       unsigned long flag;
+
+       spin_lock_irqsave(&ar_sdio->lock, flag);
+
+       if (list_empty(&ar_sdio->bus_req_freeq)) {
+               spin_unlock_irqrestore(&ar_sdio->lock, flag);
+               return NULL;
+       }
+
+       bus_req = list_first_entry(&ar_sdio->bus_req_freeq,
+                                  struct bus_request, list);
+       list_del(&bus_req->list);
+
+       spin_unlock_irqrestore(&ar_sdio->lock, flag);
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
+
+       return bus_req;
+}
+
+static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
+                                    struct bus_request *bus_req)
+{
+       unsigned long flag;
+
+       ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
+
+       spin_lock_irqsave(&ar_sdio->lock, flag);
+       list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq);
+       spin_unlock_irqrestore(&ar_sdio->lock, flag);
+}
+
+static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
+                                       struct mmc_data *data)
+{
+       struct scatterlist *sg;
+       int i;
+
+       data->blksz = HIF_MBOX_BLOCK_SIZE;
+       data->blocks = scat_req->len / HIF_MBOX_BLOCK_SIZE;
+
+       ath6kl_dbg(ATH6KL_DBG_SCATTER,
+                  "hif-scatter: (%s) addr: 0x%X, (block len: %d, block count: %d) , (tot:%d,sg:%d)\n",
+                  (scat_req->req & HIF_WRITE) ? "WR" : "RD", scat_req->addr,
+                  data->blksz, data->blocks, scat_req->len,
+                  scat_req->scat_entries);
+
+       data->flags = (scat_req->req & HIF_WRITE) ? MMC_DATA_WRITE :
+                                                   MMC_DATA_READ;
+
+       /* fill SG entries */
+       sg = scat_req->sgentries;
+       sg_init_table(sg, scat_req->scat_entries);
+
+       /* assemble SG list */
+       for (i = 0; i < scat_req->scat_entries; i++, sg++) {
+               if ((unsigned long)scat_req->scat_list[i].buf & 0x3)
+                       /*
+                        * Some scatter engines can handle unaligned
+                        * buffers, print this as informational only.
+                        */
+                       ath6kl_dbg(ATH6KL_DBG_SCATTER,
+                                  "(%s) scatter buffer is unaligned 0x%p\n",
+                                  scat_req->req & HIF_WRITE ? "WR" : "RD",
+                                  scat_req->scat_list[i].buf);
+
+               ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
+                          i, scat_req->scat_list[i].buf,
+                          scat_req->scat_list[i].len);
+
+               sg_set_buf(sg, scat_req->scat_list[i].buf,
+                          scat_req->scat_list[i].len);
+       }
+
+       /* set scatter-gather table for request */
+       data->sg = scat_req->sgentries;
+       data->sg_len = scat_req->scat_entries;
+}
+
+static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
+                              struct bus_request *req)
+{
+       struct mmc_request mmc_req;
+       struct mmc_command cmd;
+       struct mmc_data data;
+       struct hif_scatter_req *scat_req;
+       u8 opcode, rw;
+       int status, len;
+
+       scat_req = req->scat_req;
+
+       if (scat_req->virt_scat) {
+               len = scat_req->len;
+               if (scat_req->req & HIF_BLOCK_BASIS)
+                       len = round_down(len, HIF_MBOX_BLOCK_SIZE);
+
+               status = ath6kl_sdio_io(ar_sdio->func, scat_req->req,
+                                       scat_req->addr, scat_req->virt_dma_buf,
+                                       len);
+               goto scat_complete;
+       }
+
+       memset(&mmc_req, 0, sizeof(struct mmc_request));
+       memset(&cmd, 0, sizeof(struct mmc_command));
+       memset(&data, 0, sizeof(struct mmc_data));
+
+       ath6kl_sdio_setup_scat_data(scat_req, &data);
+
+       opcode = (scat_req->req & HIF_FIXED_ADDRESS) ?
+                 CMD53_ARG_FIXED_ADDRESS : CMD53_ARG_INCR_ADDRESS;
+
+       rw = (scat_req->req & HIF_WRITE) ? CMD53_ARG_WRITE : CMD53_ARG_READ;
+
+       /* Fixup the address so that the last byte will fall on MBOX EOM */
+       if (scat_req->req & HIF_WRITE) {
+               if (scat_req->addr == HIF_MBOX_BASE_ADDR)
+                       scat_req->addr += HIF_MBOX_WIDTH - scat_req->len;
+               else
+                       /* Uses extended address range */
+                       scat_req->addr += HIF_MBOX0_EXT_WIDTH - scat_req->len;
+       }
+
+       /* set command argument */
+       ath6kl_sdio_set_cmd53_arg(&cmd.arg, rw, ar_sdio->func->num,
+                                 CMD53_ARG_BLOCK_BASIS, opcode, scat_req->addr,
+                                 data.blocks);
+
+       cmd.opcode = SD_IO_RW_EXTENDED;
+       cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+       mmc_req.cmd = &cmd;
+       mmc_req.data = &data;
+
+       mmc_set_data_timeout(&data, ar_sdio->func->card);
+       /* synchronous call to process request */
+       mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
+
+       status = cmd.error ? cmd.error : data.error;
+
+scat_complete:
+       scat_req->status = status;
+
+       if (scat_req->status)
+               ath6kl_err("Scatter write request failed:%d\n",
+                          scat_req->status);
+
+       if (scat_req->req & HIF_ASYNCHRONOUS)
+               scat_req->complete(ar_sdio->ar->htc_target, scat_req);
+
+       return status;
+}
+
+static int ath6kl_sdio_alloc_prep_scat_req(struct ath6kl_sdio *ar_sdio,
+                                          int n_scat_entry, int n_scat_req,
+                                          bool virt_scat)
+{
+       struct hif_scatter_req *s_req;
+       struct bus_request *bus_req;
+       int i, scat_req_sz, scat_list_sz, sg_sz, buf_sz;
+       u8 *virt_buf;
+
+       scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
+       scat_req_sz = sizeof(*s_req) + scat_list_sz;
+
+       if (!virt_scat)
+               sg_sz = sizeof(struct scatterlist) * n_scat_entry;
+       else
+               buf_sz =  2 * L1_CACHE_BYTES +
+                         ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
+
+       for (i = 0; i < n_scat_req; i++) {
+               /* allocate the scatter request */
+               s_req = kzalloc(scat_req_sz, GFP_KERNEL);
+               if (!s_req)
+                       return -ENOMEM;
+
+               if (virt_scat) {
+                       virt_buf = kzalloc(buf_sz, GFP_KERNEL);
+                       if (!virt_buf) {
+                               kfree(s_req);
+                               return -ENOMEM;
+                       }
+
+                       s_req->virt_dma_buf =
+                               (u8 *)L1_CACHE_ALIGN((unsigned long)virt_buf);
+               } else {
+                       /* allocate sglist */
+                       s_req->sgentries = kzalloc(sg_sz, GFP_KERNEL);
+
+                       if (!s_req->sgentries) {
+                               kfree(s_req);
+                               return -ENOMEM;
+                       }
+               }
+
+               /* allocate a bus request for this scatter request */
+               bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
+               if (!bus_req) {
+                       kfree(s_req->sgentries);
+                       kfree(s_req->virt_dma_buf);
+                       kfree(s_req);
+                       return -ENOMEM;
+               }
+
+               /* assign the scatter request to this bus request */
+               bus_req->scat_req = s_req;
+               s_req->busrequest = bus_req;
+
+               s_req->virt_scat = virt_scat;
+
+               /* add it to the scatter pool */
+               hif_scatter_req_add(ar_sdio->ar, s_req);
+       }
+
+       return 0;
+}
+
+static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
+                                      u32 len, u32 request)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       u8  *tbuf = NULL;
+       int ret;
+       bool bounced = false;
+
+       if (request & HIF_BLOCK_BASIS)
+               len = round_down(len, HIF_MBOX_BLOCK_SIZE);
+
+       if (buf_needs_bounce(buf)) {
+               if (!ar_sdio->dma_buffer)
+                       return -ENOMEM;
+               tbuf = ar_sdio->dma_buffer;
+               memcpy(tbuf, buf, len);
+               bounced = true;
+       } else
+               tbuf = buf;
+
+       sdio_claim_host(ar_sdio->func);
+       ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len);
+       if ((request & HIF_READ) && bounced)
+               memcpy(buf, tbuf, len);
+       sdio_release_host(ar_sdio->func);
+
+       return ret;
+}
+
+static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
+                                     struct bus_request *req)
+{
+       if (req->scat_req)
+               ath6kl_sdio_scat_rw(ar_sdio, req);
+       else {
+               void *context;
+               int status;
+
+               status = ath6kl_sdio_read_write_sync(ar_sdio->ar, req->address,
+                                                    req->buffer, req->length,
+                                                    req->request);
+               context = req->packet;
+               ath6kl_sdio_free_bus_req(ar_sdio, req);
+               ath6kldev_rw_comp_handler(context, status);
+       }
+}
+
+static void ath6kl_sdio_write_async_work(struct work_struct *work)
+{
+       struct ath6kl_sdio *ar_sdio;
+       unsigned long flags;
+       struct bus_request *req, *tmp_req;
+
+       ar_sdio = container_of(work, struct ath6kl_sdio, wr_async_work);
+       sdio_claim_host(ar_sdio->func);
+
+       spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+       list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) {
+               list_del(&req->list);
+               spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+               __ath6kl_sdio_write_async(ar_sdio, req);
+               spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+       }
+       spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+
+       sdio_release_host(ar_sdio->func);
+}
+
+static void ath6kl_sdio_irq_handler(struct sdio_func *func)
+{
+       int status;
+       struct ath6kl_sdio *ar_sdio;
+
+       ar_sdio = sdio_get_drvdata(func);
+       atomic_set(&ar_sdio->irq_handling, 1);
+
+       /*
+        * Release the host during interrups so we can pick it back up when
+        * we process commands.
+        */
+       sdio_release_host(ar_sdio->func);
+
+       status = ath6kldev_intr_bh_handler(ar_sdio->ar);
+       sdio_claim_host(ar_sdio->func);
+       atomic_set(&ar_sdio->irq_handling, 0);
+       WARN_ON(status && status != -ECANCELED);
+}
+
+static int ath6kl_sdio_power_on(struct ath6kl_sdio *ar_sdio)
+{
+       struct sdio_func *func = ar_sdio->func;
+       int ret = 0;
+
+       if (!ar_sdio->is_disabled)
+               return 0;
+
+       sdio_claim_host(func);
+
+       ret = sdio_enable_func(func);
+       if (ret) {
+               ath6kl_err("Unable to enable sdio func: %d)\n", ret);
+               sdio_release_host(func);
+               return ret;
+       }
+
+       sdio_release_host(func);
+
+       /*
+        * Wait for hardware to initialise. It should take a lot less than
+        * 10 ms but let's be conservative here.
+        */
+       msleep(10);
+
+       ar_sdio->is_disabled = false;
+
+       return ret;
+}
+
+static int ath6kl_sdio_power_off(struct ath6kl_sdio *ar_sdio)
+{
+       int ret;
+
+       if (ar_sdio->is_disabled)
+               return 0;
+
+       /* Disable the card */
+       sdio_claim_host(ar_sdio->func);
+       ret = sdio_disable_func(ar_sdio->func);
+       sdio_release_host(ar_sdio->func);
+
+       if (ret)
+               return ret;
+
+       ar_sdio->is_disabled = true;
+
+       return ret;
+}
+
+static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
+                                  u32 length, u32 request,
+                                  struct htc_packet *packet)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       struct bus_request *bus_req;
+       unsigned long flags;
+
+       bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
+
+       if (!bus_req)
+               return -ENOMEM;
+
+       bus_req->address = address;
+       bus_req->buffer = buffer;
+       bus_req->length = length;
+       bus_req->request = request;
+       bus_req->packet = packet;
+
+       spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+       list_add_tail(&bus_req->list, &ar_sdio->wr_asyncq);
+       spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+       queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
+
+       return 0;
+}
+
+static void ath6kl_sdio_irq_enable(struct ath6kl *ar)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       int ret;
+
+       sdio_claim_host(ar_sdio->func);
+
+       /* Register the isr */
+       ret =  sdio_claim_irq(ar_sdio->func, ath6kl_sdio_irq_handler);
+       if (ret)
+               ath6kl_err("Failed to claim sdio irq: %d\n", ret);
+
+       sdio_release_host(ar_sdio->func);
+}
+
+static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       int ret;
+
+       sdio_claim_host(ar_sdio->func);
+
+       /* Mask our function IRQ */
+       while (atomic_read(&ar_sdio->irq_handling)) {
+               sdio_release_host(ar_sdio->func);
+               schedule_timeout(HZ / 10);
+               sdio_claim_host(ar_sdio->func);
+       }
+
+       ret = sdio_release_irq(ar_sdio->func);
+       if (ret)
+               ath6kl_err("Failed to release sdio irq: %d\n", ret);
+
+       sdio_release_host(ar_sdio->func);
+}
+
+static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       struct hif_scatter_req *node = NULL;
+       unsigned long flag;
+
+       spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+
+       if (!list_empty(&ar_sdio->scat_req)) {
+               node = list_first_entry(&ar_sdio->scat_req,
+                                       struct hif_scatter_req, list);
+               list_del(&node->list);
+       }
+
+       spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+
+       return node;
+}
+
+static void ath6kl_sdio_scatter_req_add(struct ath6kl *ar,
+                                       struct hif_scatter_req *s_req)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       unsigned long flag;
+
+       spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+
+       list_add_tail(&s_req->list, &ar_sdio->scat_req);
+
+       spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+
+}
+
+/* scatter gather read write request */
+static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar,
+                                       struct hif_scatter_req *scat_req)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       u32 request = scat_req->req;
+       int status = 0;
+       unsigned long flags;
+
+       if (!scat_req->len)
+               return -EINVAL;
+
+       ath6kl_dbg(ATH6KL_DBG_SCATTER,
+               "hif-scatter: total len: %d scatter entries: %d\n",
+               scat_req->len, scat_req->scat_entries);
+
+       if (request & HIF_SYNCHRONOUS) {
+               sdio_claim_host(ar_sdio->func);
+               status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
+               sdio_release_host(ar_sdio->func);
+       } else {
+               spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+               list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq);
+               spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+               queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
+       }
+
+       return status;
+}
+
+/* clean up scatter support */
+static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       struct hif_scatter_req *s_req, *tmp_req;
+       unsigned long flag;
+
+       /* empty the free list */
+       spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+       list_for_each_entry_safe(s_req, tmp_req, &ar_sdio->scat_req, list) {
+               list_del(&s_req->list);
+               spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+
+               if (s_req->busrequest)
+                       ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest);
+               kfree(s_req->virt_dma_buf);
+               kfree(s_req->sgentries);
+               kfree(s_req);
+
+               spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+       }
+       spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+}
+
+/* setup of HIF scatter resources */
+static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
+{
+       struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+       struct htc_target *target = ar->htc_target;
+       int ret;
+       bool virt_scat = false;
+
+       /* check if host supports scatter and it meets our requirements */
+       if (ar_sdio->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
+               ath6kl_err("host only supports scatter of :%d entries, need: %d\n",
+                          ar_sdio->func->card->host->max_segs,
+                          MAX_SCATTER_ENTRIES_PER_REQ);
+               virt_scat = true;
+       }
+
+       if (!virt_scat) {
+               ret = ath6kl_sdio_alloc_prep_scat_req(ar_sdio,
+                               MAX_SCATTER_ENTRIES_PER_REQ,
+                               MAX_SCATTER_REQUESTS, virt_scat);
+
+               if (!ret) {
+                       ath6kl_dbg(ATH6KL_DBG_ANY,
+                                  "hif-scatter enabled: max scatter req : %d entries: %d\n",
+                                  MAX_SCATTER_REQUESTS,
+                                  MAX_SCATTER_ENTRIES_PER_REQ);
+
+                       target->max_scat_entries = MAX_SCATTER_ENTRIES_PER_REQ;
+                       target->max_xfer_szper_scatreq =
+                                               MAX_SCATTER_REQ_TRANSFER_SIZE;
+               } else {
+                       ath6kl_sdio_cleanup_scatter(ar);
+                       ath6kl_warn("hif scatter resource setup failed, trying virtual scatter method\n");
+               }
+       }
+
+       if (virt_scat || ret) {
+               ret = ath6kl_sdio_alloc_prep_scat_req(ar_sdio,
+                               ATH6KL_SCATTER_ENTRIES_PER_REQ,
+                               ATH6KL_SCATTER_REQS, virt_scat);
+
+               if (ret) {
+                       ath6kl_err("failed to alloc virtual scatter resources !\n");
+                       ath6kl_sdio_cleanup_scatter(ar);
+                       return ret;
+               }
+
+               ath6kl_dbg(ATH6KL_DBG_ANY,
+                          "Vitual scatter enabled, max_scat_req:%d, entries:%d\n",
+                          ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ);
+
+               target->max_scat_entries = ATH6KL_SCATTER_ENTRIES_PER_REQ;
+               target->max_xfer_szper_scatreq =
+                                       ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
+       }
+
+       return 0;
+}
+
+static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
+       .read_write_sync = ath6kl_sdio_read_write_sync,
+       .write_async = ath6kl_sdio_write_async,
+       .irq_enable = ath6kl_sdio_irq_enable,
+       .irq_disable = ath6kl_sdio_irq_disable,
+       .scatter_req_get = ath6kl_sdio_scatter_req_get,
+       .scatter_req_add = ath6kl_sdio_scatter_req_add,
+       .enable_scatter = ath6kl_sdio_enable_scatter,
+       .scat_req_rw = ath6kl_sdio_async_rw_scatter,
+       .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
+};
+
+static int ath6kl_sdio_probe(struct sdio_func *func,
+                            const struct sdio_device_id *id)
+{
+       int ret;
+       struct ath6kl_sdio *ar_sdio;
+       struct ath6kl *ar;
+       int count;
+
+       ath6kl_dbg(ATH6KL_DBG_TRC,
+                  "%s: func: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n",
+                  __func__, func->num, func->vendor,
+                  func->device, func->max_blksize, func->cur_blksize);
+
+       ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL);
+       if (!ar_sdio)
+               return -ENOMEM;
+
+       ar_sdio->dma_buffer = kzalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
+       if (!ar_sdio->dma_buffer) {
+               ret = -ENOMEM;
+               goto err_hif;
+       }
+
+       ar_sdio->func = func;
+       sdio_set_drvdata(func, ar_sdio);
+
+       ar_sdio->id = id;
+       ar_sdio->is_disabled = true;
+
+       spin_lock_init(&ar_sdio->lock);
+       spin_lock_init(&ar_sdio->scat_lock);
+       spin_lock_init(&ar_sdio->wr_async_lock);
+
+       INIT_LIST_HEAD(&ar_sdio->scat_req);
+       INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
+       INIT_LIST_HEAD(&ar_sdio->wr_asyncq);
+
+       INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work);
+
+       for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
+               ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
+
+       ar = ath6kl_core_alloc(&ar_sdio->func->dev);
+       if (!ar) {
+               ath6kl_err("Failed to alloc ath6kl core\n");
+               ret = -ENOMEM;
+               goto err_dma;
+       }
+
+       ar_sdio->ar = ar;
+       ar->hif_priv = ar_sdio;
+       ar->hif_ops = &ath6kl_sdio_ops;
+
+       ath6kl_sdio_set_mbox_info(ar);
+
+       sdio_claim_host(func);
+
+       if ((ar_sdio->id->device & MANUFACTURER_ID_ATH6KL_BASE_MASK) >=
+           MANUFACTURER_ID_AR6003_BASE) {
+               /* enable 4-bit ASYNC interrupt on AR6003 or later */
+               ret = ath6kl_sdio_func0_cmd52_wr_byte(func->card,
+                                               CCCR_SDIO_IRQ_MODE_REG,
+                                               SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
+               if (ret) {
+                       ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
+                                  ret);
+                       sdio_release_host(func);
+                       goto err_dma;
+               }
+
+               ath6kl_dbg(ATH6KL_DBG_TRC, "4-bit async irq mode enabled\n");
+       }
+
+       /* give us some time to enable, in ms */
+       func->enable_timeout = 100;
+
+       sdio_release_host(func);
+
+       ret = ath6kl_sdio_power_on(ar_sdio);
+       if (ret)
+               goto err_dma;
+
+       sdio_claim_host(func);
+
+       ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
+       if (ret) {
+               ath6kl_err("Set sdio block size %d failed: %d)\n",
+                          HIF_MBOX_BLOCK_SIZE, ret);
+               sdio_release_host(func);
+               goto err_off;
+       }
+
+       sdio_release_host(func);
+
+       ret = ath6kl_core_init(ar);
+       if (ret) {
+               ath6kl_err("Failed to init ath6kl core\n");
+               goto err_off;
+       }
+
+       return ret;
+
+err_off:
+       ath6kl_sdio_power_off(ar_sdio);
+err_dma:
+       kfree(ar_sdio->dma_buffer);
+err_hif:
+       kfree(ar_sdio);
+
+       return ret;
+}
+
+static void ath6kl_sdio_remove(struct sdio_func *func)
+{
+       struct ath6kl_sdio *ar_sdio;
+
+       ar_sdio = sdio_get_drvdata(func);
+
+       ath6kl_stop_txrx(ar_sdio->ar);
+       cancel_work_sync(&ar_sdio->wr_async_work);
+
+       ath6kl_unavail_ev(ar_sdio->ar);
+
+       ath6kl_sdio_power_off(ar_sdio);
+
+       kfree(ar_sdio->dma_buffer);
+       kfree(ar_sdio);
+}
+
+static const struct sdio_device_id ath6kl_sdio_devices[] = {
+       {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))},
+       {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))},
+       {},
+};
+
+MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
+
+static struct sdio_driver ath6kl_sdio_driver = {
+       .name = "ath6kl_sdio",
+       .id_table = ath6kl_sdio_devices,
+       .probe = ath6kl_sdio_probe,
+       .remove = ath6kl_sdio_remove,
+};
+
+static int __init ath6kl_sdio_init(void)
+{
+       int ret;
+
+       ret = sdio_register_driver(&ath6kl_sdio_driver);
+       if (ret)
+               ath6kl_err("sdio driver registration failed: %d\n", ret);
+
+       return ret;
+}
+
+static void __exit ath6kl_sdio_exit(void)
+{
+       sdio_unregister_driver(&ath6kl_sdio_driver);
+}
+
+module_init(ath6kl_sdio_init);
+module_exit(ath6kl_sdio_exit);
+
+MODULE_AUTHOR("Atheros Communications, Inc.");
+MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
+MODULE_LICENSE("Dual BSD/GPL");
+
+MODULE_FIRMWARE(AR6003_REV2_OTP_FILE);
+MODULE_FIRMWARE(AR6003_REV2_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_REV2_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_REV2_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6003_REV2_DEFAULT_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6003_REV3_OTP_FILE);
+MODULE_FIRMWARE(AR6003_REV3_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_REV3_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_REV3_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6003_REV3_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
new file mode 100644 (file)
index 0000000..519a013
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2004-2010 Atheros Communications 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 TARGET_H
+#define TARGET_H
+
+#define AR6003_BOARD_DATA_SZ           1024
+#define AR6003_BOARD_EXT_DATA_SZ       768
+
+#define RESET_CONTROL_ADDRESS          0x00000000
+#define RESET_CONTROL_COLD_RST         0x00000100
+#define RESET_CONTROL_MBOX_RST         0x00000004
+
+#define CPU_CLOCK_STANDARD_S           0
+#define CPU_CLOCK_STANDARD             0x00000003
+#define CPU_CLOCK_ADDRESS              0x00000020
+
+#define CLOCK_CONTROL_ADDRESS          0x00000028
+#define CLOCK_CONTROL_LF_CLK32_S       2
+#define CLOCK_CONTROL_LF_CLK32         0x00000004
+
+#define SYSTEM_SLEEP_ADDRESS           0x000000c4
+#define SYSTEM_SLEEP_DISABLE_S         0
+#define SYSTEM_SLEEP_DISABLE           0x00000001
+
+#define LPO_CAL_ADDRESS                        0x000000e0
+#define LPO_CAL_ENABLE_S               20
+#define LPO_CAL_ENABLE                 0x00100000
+
+#define GPIO_PIN10_ADDRESS             0x00000050
+#define GPIO_PIN11_ADDRESS             0x00000054
+#define GPIO_PIN12_ADDRESS             0x00000058
+#define GPIO_PIN13_ADDRESS             0x0000005c
+
+#define HOST_INT_STATUS_ADDRESS                0x00000400
+#define HOST_INT_STATUS_ERROR_S                7
+#define HOST_INT_STATUS_ERROR          0x00000080
+
+#define HOST_INT_STATUS_CPU_S          6
+#define HOST_INT_STATUS_CPU            0x00000040
+
+#define HOST_INT_STATUS_COUNTER_S      4
+#define HOST_INT_STATUS_COUNTER                0x00000010
+
+#define CPU_INT_STATUS_ADDRESS         0x00000401
+
+#define ERROR_INT_STATUS_ADDRESS       0x00000402
+#define ERROR_INT_STATUS_WAKEUP_S      2
+#define ERROR_INT_STATUS_WAKEUP                0x00000004
+
+#define ERROR_INT_STATUS_RX_UNDERFLOW_S        1
+#define ERROR_INT_STATUS_RX_UNDERFLOW  0x00000002
+
+#define ERROR_INT_STATUS_TX_OVERFLOW_S 0
+#define ERROR_INT_STATUS_TX_OVERFLOW   0x00000001
+
+#define COUNTER_INT_STATUS_ADDRESS     0x00000403
+#define COUNTER_INT_STATUS_COUNTER_S   0
+#define COUNTER_INT_STATUS_COUNTER     0x000000ff
+
+#define RX_LOOKAHEAD_VALID_ADDRESS     0x00000405
+
+#define INT_STATUS_ENABLE_ADDRESS      0x00000418
+#define INT_STATUS_ENABLE_ERROR_S      7
+#define INT_STATUS_ENABLE_ERROR                0x00000080
+
+#define INT_STATUS_ENABLE_CPU_S                6
+#define INT_STATUS_ENABLE_CPU          0x00000040
+
+#define INT_STATUS_ENABLE_INT_S                5
+#define INT_STATUS_ENABLE_INT          0x00000020
+#define INT_STATUS_ENABLE_COUNTER_S    4
+#define INT_STATUS_ENABLE_COUNTER      0x00000010
+
+#define INT_STATUS_ENABLE_MBOX_DATA_S  0
+#define INT_STATUS_ENABLE_MBOX_DATA    0x0000000f
+
+#define CPU_INT_STATUS_ENABLE_ADDRESS  0x00000419
+#define CPU_INT_STATUS_ENABLE_BIT_S    0
+#define CPU_INT_STATUS_ENABLE_BIT      0x000000ff
+
+#define ERROR_STATUS_ENABLE_ADDRESS            0x0000041a
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_S     1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW       0x00000002
+
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_S      0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW                0x00000001
+
+#define COUNTER_INT_STATUS_ENABLE_ADDRESS      0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_BIT_S                0
+#define COUNTER_INT_STATUS_ENABLE_BIT          0x000000ff
+
+#define COUNT_ADDRESS                  0x00000420
+
+#define COUNT_DEC_ADDRESS              0x00000440
+
+#define WINDOW_DATA_ADDRESS            0x00000474
+#define WINDOW_WRITE_ADDR_ADDRESS      0x00000478
+#define WINDOW_READ_ADDR_ADDRESS       0x0000047c
+#define CPU_DBG_SEL_ADDRESS            0x00000483
+#define CPU_DBG_ADDRESS                        0x00000484
+
+#define LOCAL_SCRATCH_ADDRESS          0x000000c0
+#define ATH6KL_OPTION_SLEEP_DISABLE    0x08
+
+#define RTC_BASE_ADDRESS               0x00004000
+#define GPIO_BASE_ADDRESS              0x00014000
+#define MBOX_BASE_ADDRESS              0x00018000
+#define ANALOG_INTF_BASE_ADDRESS       0x0001c000
+
+/* real name of the register is unknown */
+#define ATH6KL_ANALOG_PLL_REGISTER     (ANALOG_INTF_BASE_ADDRESS + 0x284)
+
+#define SM(f, v)       (((v) << f##_S) & f)
+#define MS(f, v)       (((v) & f) >> f##_S)
+
+/*
+ * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
+ * host_interest structure.
+ *
+ * Host Interest is shared between Host and Target in order to coordinate
+ * between the two, and is intended to remain constant (with additions only
+ * at the end).
+ */
+#define ATH6KL_HI_START_ADDR           0x00540600
+
+/*
+ * These are items that the Host may need to access
+ * via BMI or via the Diagnostic Window. The position
+ * of items in this structure must remain constant.
+ * across firmware revisions!
+ *
+ * Types for each item must be fixed size across target and host platforms.
+ * The structure is used only to calculate offset for each register with
+ * HI_ITEM() macro, no values are stored to it.
+ *
+ * More items may be added at the end.
+ */
+struct host_interest {
+       /*
+        * Pointer to application-defined area, if any.
+        * Set by Target application during startup.
+        */
+       u32 hi_app_host_interest;                      /* 0x00 */
+
+       /* Pointer to register dump area, valid after Target crash. */
+       u32 hi_failure_state;                          /* 0x04 */
+
+       /* Pointer to debug logging header */
+       u32 hi_dbglog_hdr;                             /* 0x08 */
+
+       u32 hi_unused1;                       /* 0x0c */
+
+       /*
+        * General-purpose flag bits, similar to ATH6KL_OPTION_* flags.
+        * Can be used by application rather than by OS.
+        */
+       u32 hi_option_flag;                            /* 0x10 */
+
+       /*
+        * Boolean that determines whether or not to
+        * display messages on the serial port.
+        */
+       u32 hi_serial_enable;                          /* 0x14 */
+
+       /* Start address of DataSet index, if any */
+       u32 hi_dset_list_head;                         /* 0x18 */
+
+       /* Override Target application start address */
+       u32 hi_app_start;                              /* 0x1c */
+
+       /* Clock and voltage tuning */
+       u32 hi_skip_clock_init;                        /* 0x20 */
+       u32 hi_core_clock_setting;                     /* 0x24 */
+       u32 hi_cpu_clock_setting;                      /* 0x28 */
+       u32 hi_system_sleep_setting;                   /* 0x2c */
+       u32 hi_xtal_control_setting;                   /* 0x30 */
+       u32 hi_pll_ctrl_setting_24ghz;                 /* 0x34 */
+       u32 hi_pll_ctrl_setting_5ghz;                  /* 0x38 */
+       u32 hi_ref_voltage_trim_setting;               /* 0x3c */
+       u32 hi_clock_info;                             /* 0x40 */
+
+       /*
+        * Flash configuration overrides, used only
+        * when firmware is not executing from flash.
+        * (When using flash, modify the global variables
+        * with equivalent names.)
+        */
+       u32 hi_bank0_addr_value;                       /* 0x44 */
+       u32 hi_bank0_read_value;                       /* 0x48 */
+       u32 hi_bank0_write_value;                      /* 0x4c */
+       u32 hi_bank0_config_value;                     /* 0x50 */
+
+       /* Pointer to Board Data  */
+       u32 hi_board_data;                             /* 0x54 */
+       u32 hi_board_data_initialized;                 /* 0x58 */
+
+       u32 hi_dset_ram_index_tbl;                     /* 0x5c */
+
+       u32 hi_desired_baud_rate;                      /* 0x60 */
+       u32 hi_dbglog_config;                          /* 0x64 */
+       u32 hi_end_ram_reserve_sz;                     /* 0x68 */
+       u32 hi_mbox_io_block_sz;                       /* 0x6c */
+
+       u32 hi_num_bpatch_streams;                     /* 0x70 -- unused */
+       u32 hi_mbox_isr_yield_limit;                   /* 0x74 */
+
+       u32 hi_refclk_hz;                              /* 0x78 */
+       u32 hi_ext_clk_detected;                       /* 0x7c */
+       u32 hi_dbg_uart_txpin;                         /* 0x80 */
+       u32 hi_dbg_uart_rxpin;                         /* 0x84 */
+       u32 hi_hci_uart_baud;                          /* 0x88 */
+       u32 hi_hci_uart_pin_assignments;               /* 0x8C */
+       /*
+        * NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts
+        * pin
+        */
+       u32 hi_hci_uart_baud_scale_val;                /* 0x90 */
+       u32 hi_hci_uart_baud_step_val;                 /* 0x94 */
+
+       u32 hi_allocram_start;                         /* 0x98 */
+       u32 hi_allocram_sz;                            /* 0x9c */
+       u32 hi_hci_bridge_flags;                       /* 0xa0 */
+       u32 hi_hci_uart_support_pins;                  /* 0xa4 */
+       /*
+        * NOTE: byte [0] = RESET pin (bit 7 is polarity),
+        * bytes[1]..bytes[3] are for future use
+        */
+       u32 hi_hci_uart_pwr_mgmt_params;               /* 0xa8 */
+       /*
+        * 0xa8   - [1]: 0 = UART FC active low, 1 = UART FC active high
+        *      [31:16]: wakeup timeout in ms
+        */
+
+       /* Pointer to extended board data */
+       u32 hi_board_ext_data;                /* 0xac */
+       u32 hi_board_ext_data_config;         /* 0xb0 */
+
+       /*
+        * Bit [0]  :   valid
+        * Bit[31:16:   size
+        */
+       /*
+        * hi_reset_flag is used to do some stuff when target reset.
+        * such as restore app_start after warm reset or
+        * preserve host Interest area, or preserve ROM data, literals etc.
+        */
+       u32 hi_reset_flag;                            /* 0xb4 */
+       /* indicate hi_reset_flag is valid */
+       u32 hi_reset_flag_valid;                      /* 0xb8 */
+       u32 hi_hci_uart_pwr_mgmt_params_ext;           /* 0xbc */
+       /*
+        * 0xbc - [31:0]: idle timeout in ms
+        */
+       /* ACS flags */
+       u32 hi_acs_flags;                              /* 0xc0 */
+       u32 hi_console_flags;                          /* 0xc4 */
+       u32 hi_nvram_state;                            /* 0xc8 */
+       u32 hi_option_flag2;                           /* 0xcc */
+
+       /* If non-zero, override values sent to Host in WMI_READY event. */
+       u32 hi_sw_version_override;                    /* 0xd0 */
+       u32 hi_abi_version_override;                   /* 0xd4 */
+
+       /*
+        * Percentage of high priority RX traffic to total expected RX traffic -
+        * applicable only to ar6004
+        */
+       u32 hi_hp_rx_traffic_ratio;                    /* 0xd8 */
+
+       /* test applications flags */
+       u32 hi_test_apps_related    ;                  /* 0xdc */
+       /* location of test script */
+       u32 hi_ota_testscript;                         /* 0xe0 */
+       /* location of CAL data */
+       u32 hi_cal_data;                               /* 0xe4 */
+       /* Number of packet log buffers */
+       u32 hi_pktlog_num_buffers;                     /* 0xe8 */
+
+} __packed;
+
+#define HI_ITEM(item)  offsetof(struct host_interest, item)
+
+#define HI_OPTION_MAC_ADDR_METHOD_SHIFT        3
+
+#define HI_OPTION_FW_MODE_IBSS    0x0
+#define HI_OPTION_FW_MODE_BSS_STA 0x1
+#define HI_OPTION_FW_MODE_AP      0x2
+
+#define HI_OPTION_NUM_DEV_SHIFT   0x9
+
+#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
+
+/* Fw Mode/SubMode Mask
+|------------------------------------------------------------------------------|
+|   SUB   |   SUB   |   SUB   |  SUB    |         |         |         |
+| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
+|   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)
+|------------------------------------------------------------------------------|
+*/
+#define HI_OPTION_FW_MODE_SHIFT        0xC
+
+/* Convert a Target virtual address into a Target physical address */
+#define TARG_VTOP(vaddr)   (vaddr & 0x001fffff)
+
+#define AR6003_REV2_APP_START_OVERRIDE          0x944C00
+#define AR6003_REV2_APP_LOAD_ADDRESS            0x543180
+#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS      0x57E500
+#define AR6003_REV2_DATASET_PATCH_ADDRESS       0x57e884
+#define AR6003_REV2_RAM_RESERVE_SIZE            6912
+
+#define AR6003_REV3_APP_START_OVERRIDE          0x945d00
+#define AR6003_REV3_APP_LOAD_ADDRESS            0x545000
+#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS      0x542330
+#define AR6003_REV3_DATASET_PATCH_ADDRESS       0x57FF74
+#define AR6003_REV3_RAM_RESERVE_SIZE            512
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
new file mode 100644 (file)
index 0000000..167bdb9
--- /dev/null
@@ -0,0 +1,1457 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 "core.h"
+#include "debug.h"
+
+static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
+                              u32 *map_no)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       struct ethhdr *eth_hdr;
+       u32 i, ep_map = -1;
+       u8 *datap;
+
+       *map_no = 0;
+       datap = skb->data;
+       eth_hdr = (struct ethhdr *) (datap + sizeof(struct wmi_data_hdr));
+
+       if (is_multicast_ether_addr(eth_hdr->h_dest))
+               return ENDPOINT_2;
+
+       for (i = 0; i < ar->node_num; i++) {
+               if (memcmp(eth_hdr->h_dest, ar->node_map[i].mac_addr,
+                          ETH_ALEN) == 0) {
+                       *map_no = i + 1;
+                       ar->node_map[i].tx_pend++;
+                       return ar->node_map[i].ep_id;
+               }
+
+               if ((ep_map == -1) && !ar->node_map[i].tx_pend)
+                       ep_map = i;
+       }
+
+       if (ep_map == -1) {
+               ep_map = ar->node_num;
+               ar->node_num++;
+               if (ar->node_num > MAX_NODE_NUM)
+                       return ENDPOINT_UNUSED;
+       }
+
+       memcpy(ar->node_map[ep_map].mac_addr, eth_hdr->h_dest, ETH_ALEN);
+
+       for (i = ENDPOINT_2; i <= ENDPOINT_5; i++) {
+               if (!ar->tx_pending[i]) {
+                       ar->node_map[ep_map].ep_id = i;
+                       break;
+               }
+
+               /*
+                * No free endpoint is available, start redistribution on
+                * the inuse endpoints.
+                */
+               if (i == ENDPOINT_5) {
+                       ar->node_map[ep_map].ep_id = ar->next_ep_id;
+                       ar->next_ep_id++;
+                       if (ar->next_ep_id > ENDPOINT_5)
+                               ar->next_ep_id = ENDPOINT_2;
+               }
+       }
+
+       *map_no = ep_map + 1;
+       ar->node_map[ep_map].tx_pend++;
+
+       return ar->node_map[ep_map].ep_id;
+}
+
+static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
+                               bool *more_data)
+{
+       struct ethhdr *datap = (struct ethhdr *) skb->data;
+       struct ath6kl_sta *conn = NULL;
+       bool ps_queued = false, is_psq_empty = false;
+
+       if (is_multicast_ether_addr(datap->h_dest)) {
+               u8 ctr = 0;
+               bool q_mcast = false;
+
+               for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+                       if (ar->sta_list[ctr].sta_flags & STA_PS_SLEEP) {
+                               q_mcast = true;
+                               break;
+                       }
+               }
+
+               if (q_mcast) {
+                       /*
+                        * If this transmit is not because of a Dtim Expiry
+                        * q it.
+                        */
+                       if (!test_bit(DTIM_EXPIRED, &ar->flag)) {
+                               bool is_mcastq_empty = false;
+
+                               spin_lock_bh(&ar->mcastpsq_lock);
+                               is_mcastq_empty =
+                                       skb_queue_empty(&ar->mcastpsq);
+                               skb_queue_tail(&ar->mcastpsq, skb);
+                               spin_unlock_bh(&ar->mcastpsq_lock);
+
+                               /*
+                                * If this is the first Mcast pkt getting
+                                * queued indicate to the target to set the
+                                * BitmapControl LSB of the TIM IE.
+                                */
+                               if (is_mcastq_empty)
+                                       ath6kl_wmi_set_pvb_cmd(ar->wmi,
+                                                              MCAST_AID, 1);
+
+                               ps_queued = true;
+                       } else {
+                               /*
+                                * This transmit is because of Dtim expiry.
+                                * Determine if MoreData bit has to be set.
+                                */
+                               spin_lock_bh(&ar->mcastpsq_lock);
+                               if (!skb_queue_empty(&ar->mcastpsq))
+                                       *more_data = true;
+                               spin_unlock_bh(&ar->mcastpsq_lock);
+                       }
+               }
+       } else {
+               conn = ath6kl_find_sta(ar, datap->h_dest);
+               if (!conn) {
+                       dev_kfree_skb(skb);
+
+                       /* Inform the caller that the skb is consumed */
+                       return true;
+               }
+
+               if (conn->sta_flags & STA_PS_SLEEP) {
+                       if (!(conn->sta_flags & STA_PS_POLLED)) {
+                               /* Queue the frames if the STA is sleeping */
+                               spin_lock_bh(&conn->psq_lock);
+                               is_psq_empty = skb_queue_empty(&conn->psq);
+                               skb_queue_tail(&conn->psq, skb);
+                               spin_unlock_bh(&conn->psq_lock);
+
+                               /*
+                                * If this is the first pkt getting queued
+                                * for this STA, update the PVB for this
+                                * STA.
+                                */
+                               if (is_psq_empty)
+                                       ath6kl_wmi_set_pvb_cmd(ar->wmi,
+                                                              conn->aid, 1);
+
+                               ps_queued = true;
+                       } else {
+                               /*
+                                * This tx is because of a PsPoll.
+                                * Determine if MoreData bit has to be set.
+                                */
+                               spin_lock_bh(&conn->psq_lock);
+                               if (!skb_queue_empty(&conn->psq))
+                                       *more_data = true;
+                               spin_unlock_bh(&conn->psq_lock);
+                       }
+               }
+       }
+
+       return ps_queued;
+}
+
+/* Tx functions */
+
+int ath6kl_control_tx(void *devt, struct sk_buff *skb,
+                     enum htc_endpoint_id eid)
+{
+       struct ath6kl *ar = devt;
+       int status = 0;
+       struct ath6kl_cookie *cookie = NULL;
+
+       spin_lock_bh(&ar->lock);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+                  "%s: skb=0x%p, len=0x%x eid =%d\n", __func__,
+                  skb, skb->len, eid);
+
+       if (test_bit(WMI_CTRL_EP_FULL, &ar->flag) && (eid == ar->ctrl_ep)) {
+               /*
+                * Control endpoint is full, don't allocate resources, we
+                * are just going to drop this packet.
+                */
+               cookie = NULL;
+               ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
+                          skb, skb->len);
+       } else
+               cookie = ath6kl_alloc_cookie(ar);
+
+       if (cookie == NULL) {
+               spin_unlock_bh(&ar->lock);
+               status = -ENOMEM;
+               goto fail_ctrl_tx;
+       }
+
+       ar->tx_pending[eid]++;
+
+       if (eid != ar->ctrl_ep)
+               ar->total_tx_data_pend++;
+
+       spin_unlock_bh(&ar->lock);
+
+       cookie->skb = skb;
+       cookie->map_no = 0;
+       set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
+                        eid, ATH6KL_CONTROL_PKT_TAG);
+
+       /*
+        * This interface is asynchronous, if there is an error, cleanup
+        * will happen in the TX completion callback.
+        */
+       ath6kl_htc_tx(ar->htc_target, &cookie->htc_pkt);
+
+       return 0;
+
+fail_ctrl_tx:
+       dev_kfree_skb(skb);
+       return status;
+}
+
+int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       struct ath6kl_cookie *cookie = NULL;
+       enum htc_endpoint_id eid = ENDPOINT_UNUSED;
+       u32 map_no = 0;
+       u16 htc_tag = ATH6KL_DATA_PKT_TAG;
+       u8 ac = 99 ; /* initialize to unmapped ac */
+       bool chk_adhoc_ps_mapping = false, more_data = false;
+       struct wmi_tx_meta_v2 meta_v2;
+       int ret;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+                  "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
+                  skb, skb->data, skb->len);
+
+       /* If target is not associated */
+       if (!test_bit(CONNECTED, &ar->flag)) {
+               dev_kfree_skb(skb);
+               return 0;
+       }
+
+       if (!test_bit(WMI_READY, &ar->flag))
+               goto fail_tx;
+
+       /* AP mode Power saving processing */
+       if (ar->nw_type == AP_NETWORK) {
+               if (ath6kl_powersave_ap(ar, skb, &more_data))
+                       return 0;
+       }
+
+       if (test_bit(WMI_ENABLED, &ar->flag)) {
+               memset(&meta_v2, 0, sizeof(meta_v2));
+
+               if (skb_headroom(skb) < dev->needed_headroom) {
+                       WARN_ON(1);
+                       goto fail_tx;
+               }
+
+               if (ath6kl_wmi_dix_2_dot3(ar->wmi, skb)) {
+                       ath6kl_err("ath6kl_wmi_dix_2_dot3 failed\n");
+                       goto fail_tx;
+               }
+
+               if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE,
+                                           more_data, 0, 0, NULL)) {
+                       ath6kl_err("wmi_data_hdr_add failed\n");
+                       goto fail_tx;
+               }
+
+               if ((ar->nw_type == ADHOC_NETWORK) &&
+                    ar->ibss_ps_enable && test_bit(CONNECTED, &ar->flag))
+                       chk_adhoc_ps_mapping = true;
+               else {
+                       /* get the stream mapping */
+                       ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, skb,
+                                   0, test_bit(WMM_ENABLED, &ar->flag), &ac);
+                       if (ret)
+                               goto fail_tx;
+               }
+       } else
+               goto fail_tx;
+
+       spin_lock_bh(&ar->lock);
+
+       if (chk_adhoc_ps_mapping)
+               eid = ath6kl_ibss_map_epid(skb, dev, &map_no);
+       else
+               eid = ar->ac2ep_map[ac];
+
+       if (eid == 0 || eid == ENDPOINT_UNUSED) {
+               ath6kl_err("eid %d is not mapped!\n", eid);
+               spin_unlock_bh(&ar->lock);
+               goto fail_tx;
+       }
+
+       /* allocate resource for this packet */
+       cookie = ath6kl_alloc_cookie(ar);
+
+       if (!cookie) {
+               spin_unlock_bh(&ar->lock);
+               goto fail_tx;
+       }
+
+       /* update counts while the lock is held */
+       ar->tx_pending[eid]++;
+       ar->total_tx_data_pend++;
+
+       spin_unlock_bh(&ar->lock);
+
+       cookie->skb = skb;
+       cookie->map_no = map_no;
+       set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
+                        eid, htc_tag);
+
+       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
+
+       /*
+        * HTC interface is asynchronous, if this fails, cleanup will
+        * happen in the ath6kl_tx_complete callback.
+        */
+       ath6kl_htc_tx(ar->htc_target, &cookie->htc_pkt);
+
+       return 0;
+
+fail_tx:
+       dev_kfree_skb(skb);
+
+       ar->net_stats.tx_dropped++;
+       ar->net_stats.tx_aborted_errors++;
+
+       return 0;
+}
+
+/* indicate tx activity or inactivity on a WMI stream */
+void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active)
+{
+       struct ath6kl *ar = devt;
+       enum htc_endpoint_id eid;
+       int i;
+
+       eid = ar->ac2ep_map[traffic_class];
+
+       if (!test_bit(WMI_ENABLED, &ar->flag))
+               goto notify_htc;
+
+       spin_lock_bh(&ar->lock);
+
+       ar->ac_stream_active[traffic_class] = active;
+
+       if (active) {
+               /*
+                * Keep track of the active stream with the highest
+                * priority.
+                */
+               if (ar->ac_stream_pri_map[traffic_class] >
+                   ar->hiac_stream_active_pri)
+                       /* set the new highest active priority */
+                       ar->hiac_stream_active_pri =
+                                       ar->ac_stream_pri_map[traffic_class];
+
+       } else {
+               /*
+                * We may have to search for the next active stream
+                * that is the highest priority.
+                */
+               if (ar->hiac_stream_active_pri ==
+                       ar->ac_stream_pri_map[traffic_class]) {
+                       /*
+                        * The highest priority stream just went inactive
+                        * reset and search for the "next" highest "active"
+                        * priority stream.
+                        */
+                       ar->hiac_stream_active_pri = 0;
+
+                       for (i = 0; i < WMM_NUM_AC; i++) {
+                               if (ar->ac_stream_active[i] &&
+                                   (ar->ac_stream_pri_map[i] >
+                                    ar->hiac_stream_active_pri))
+                                       /*
+                                        * Set the new highest active
+                                        * priority.
+                                        */
+                                       ar->hiac_stream_active_pri =
+                                               ar->ac_stream_pri_map[i];
+                       }
+               }
+       }
+
+       spin_unlock_bh(&ar->lock);
+
+notify_htc:
+       /* notify HTC, this may cause credit distribution changes */
+       ath6kl_htc_indicate_activity_change(ar->htc_target, eid, active);
+}
+
+enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
+                                              struct htc_packet *packet)
+{
+       struct ath6kl *ar = target->dev->ar;
+       enum htc_endpoint_id endpoint = packet->endpoint;
+
+       if (endpoint == ar->ctrl_ep) {
+               /*
+                * Under normal WMI if this is getting full, then something
+                * is running rampant the host should not be exhausting the
+                * WMI queue with too many commands the only exception to
+                * this is during testing using endpointping.
+                */
+               spin_lock_bh(&ar->lock);
+               set_bit(WMI_CTRL_EP_FULL, &ar->flag);
+               spin_unlock_bh(&ar->lock);
+               ath6kl_err("wmi ctrl ep is full\n");
+               return HTC_SEND_FULL_KEEP;
+       }
+
+       if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG)
+               return HTC_SEND_FULL_KEEP;
+
+       if (ar->nw_type == ADHOC_NETWORK)
+               /*
+                * In adhoc mode, we cannot differentiate traffic
+                * priorities so there is no need to continue, however we
+                * should stop the network.
+                */
+               goto stop_net_queues;
+
+       /*
+        * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for
+        * the highest active stream.
+        */
+       if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
+           ar->hiac_stream_active_pri &&
+           ar->cookie_count <= MAX_HI_COOKIE_NUM)
+               /*
+                * Give preference to the highest priority stream by
+                * dropping the packets which overflowed.
+                */
+               return HTC_SEND_FULL_DROP;
+
+stop_net_queues:
+       spin_lock_bh(&ar->lock);
+       set_bit(NETQ_STOPPED, &ar->flag);
+       spin_unlock_bh(&ar->lock);
+       netif_stop_queue(ar->net_dev);
+
+       return HTC_SEND_FULL_KEEP;
+}
+
+/* TODO this needs to be looked at */
+static void ath6kl_tx_clear_node_map(struct ath6kl *ar,
+                                    enum htc_endpoint_id eid, u32 map_no)
+{
+       u32 i;
+
+       if (ar->nw_type != ADHOC_NETWORK)
+               return;
+
+       if (!ar->ibss_ps_enable)
+               return;
+
+       if (eid == ar->ctrl_ep)
+               return;
+
+       if (map_no == 0)
+               return;
+
+       map_no--;
+       ar->node_map[map_no].tx_pend--;
+
+       if (ar->node_map[map_no].tx_pend)
+               return;
+
+       if (map_no != (ar->node_num - 1))
+               return;
+
+       for (i = ar->node_num; i > 0; i--) {
+               if (ar->node_map[i - 1].tx_pend)
+                       break;
+
+               memset(&ar->node_map[i - 1], 0,
+                      sizeof(struct ath6kl_node_mapping));
+               ar->node_num--;
+       }
+}
+
+void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
+{
+       struct ath6kl *ar = context;
+       struct sk_buff_head skb_queue;
+       struct htc_packet *packet;
+       struct sk_buff *skb;
+       struct ath6kl_cookie *ath6kl_cookie;
+       u32 map_no = 0;
+       int status;
+       enum htc_endpoint_id eid;
+       bool wake_event = false;
+       bool flushing = false;
+
+       skb_queue_head_init(&skb_queue);
+
+       /* lock the driver as we update internal state */
+       spin_lock_bh(&ar->lock);
+
+       /* reap completed packets */
+       while (!list_empty(packet_queue)) {
+
+               packet = list_first_entry(packet_queue, struct htc_packet,
+                                         list);
+               list_del(&packet->list);
+
+               ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
+               if (!ath6kl_cookie)
+                       goto fatal;
+
+               status = packet->status;
+               skb = ath6kl_cookie->skb;
+               eid = packet->endpoint;
+               map_no = ath6kl_cookie->map_no;
+
+               if (!skb || !skb->data)
+                       goto fatal;
+
+               packet->buf = skb->data;
+
+               __skb_queue_tail(&skb_queue, skb);
+
+               if (!status && (packet->act_len != skb->len))
+                       goto fatal;
+
+               ar->tx_pending[eid]--;
+
+               if (eid != ar->ctrl_ep)
+                       ar->total_tx_data_pend--;
+
+               if (eid == ar->ctrl_ep) {
+                       if (test_bit(WMI_CTRL_EP_FULL, &ar->flag))
+                               clear_bit(WMI_CTRL_EP_FULL, &ar->flag);
+
+                       if (ar->tx_pending[eid] == 0)
+                               wake_event = true;
+               }
+
+               if (status) {
+                       if (status == -ECANCELED)
+                               /* a packet was flushed  */
+                               flushing = true;
+
+                       ar->net_stats.tx_errors++;
+
+                       if (status != -ENOSPC)
+                               ath6kl_err("tx error, status: 0x%x\n", status);
+                       ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+                                  "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
+                                  __func__, skb, packet->buf, packet->act_len,
+                                  eid, "error!");
+               } else {
+                       ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+                                  "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
+                                  __func__, skb, packet->buf, packet->act_len,
+                                  eid, "OK");
+
+                       flushing = false;
+                       ar->net_stats.tx_packets++;
+                       ar->net_stats.tx_bytes += skb->len;
+               }
+
+               ath6kl_tx_clear_node_map(ar, eid, map_no);
+
+               ath6kl_free_cookie(ar, ath6kl_cookie);
+
+               if (test_bit(NETQ_STOPPED, &ar->flag))
+                       clear_bit(NETQ_STOPPED, &ar->flag);
+       }
+
+       spin_unlock_bh(&ar->lock);
+
+       __skb_queue_purge(&skb_queue);
+
+       if (test_bit(CONNECTED, &ar->flag)) {
+               if (!flushing)
+                       netif_wake_queue(ar->net_dev);
+       }
+
+       if (wake_event)
+               wake_up(&ar->event_wq);
+
+       return;
+
+fatal:
+       WARN_ON(1);
+       spin_unlock_bh(&ar->lock);
+       return;
+}
+
+void ath6kl_tx_data_cleanup(struct ath6kl *ar)
+{
+       int i;
+
+       /* flush all the data (non-control) streams */
+       for (i = 0; i < WMM_NUM_AC; i++)
+               ath6kl_htc_flush_txep(ar->htc_target, ar->ac2ep_map[i],
+                                     ATH6KL_DATA_PKT_TAG);
+}
+
+/* Rx functions */
+
+static void ath6kl_deliver_frames_to_nw_stack(struct net_device *dev,
+                                             struct sk_buff *skb)
+{
+       if (!skb)
+               return;
+
+       skb->dev = dev;
+
+       if (!(skb->dev->flags & IFF_UP)) {
+               dev_kfree_skb(skb);
+               return;
+       }
+
+       skb->protocol = eth_type_trans(skb, skb->dev);
+
+       netif_rx_ni(skb);
+}
+
+static void ath6kl_alloc_netbufs(struct sk_buff_head *q, u16 num)
+{
+       struct sk_buff *skb;
+
+       while (num) {
+               skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
+               if (!skb) {
+                       ath6kl_err("netbuf allocation failed\n");
+                       return;
+               }
+               skb_queue_tail(q, skb);
+               num--;
+       }
+}
+
+static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
+{
+       struct sk_buff *skb = NULL;
+
+       if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2))
+               ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+
+       skb = skb_dequeue(&p_aggr->free_q);
+
+       return skb;
+}
+
+void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
+{
+       struct ath6kl *ar = target->dev->ar;
+       struct sk_buff *skb;
+       int rx_buf;
+       int n_buf_refill;
+       struct htc_packet *packet;
+       struct list_head queue;
+
+       n_buf_refill = ATH6KL_MAX_RX_BUFFERS -
+                         ath6kl_htc_get_rxbuf_num(ar->htc_target, endpoint);
+
+       if (n_buf_refill <= 0)
+               return;
+
+       INIT_LIST_HEAD(&queue);
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
+                  "%s: providing htc with %d buffers at eid=%d\n",
+                  __func__, n_buf_refill, endpoint);
+
+       for (rx_buf = 0; rx_buf < n_buf_refill; rx_buf++) {
+               skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
+               if (!skb)
+                       break;
+
+               packet = (struct htc_packet *) skb->head;
+               set_htc_rxpkt_info(packet, skb, skb->data,
+                               ATH6KL_BUFFER_SIZE, endpoint);
+               list_add_tail(&packet->list, &queue);
+       }
+
+       if (!list_empty(&queue))
+               ath6kl_htc_add_rxbuf_multiple(ar->htc_target, &queue);
+}
+
+void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
+{
+       struct htc_packet *packet;
+       struct sk_buff *skb;
+
+       while (count) {
+               skb = ath6kl_buf_alloc(ATH6KL_AMSDU_BUFFER_SIZE);
+               if (!skb)
+                       return;
+
+               packet = (struct htc_packet *) skb->head;
+               set_htc_rxpkt_info(packet, skb, skb->data,
+                                  ATH6KL_AMSDU_BUFFER_SIZE, 0);
+               spin_lock_bh(&ar->lock);
+               list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue);
+               spin_unlock_bh(&ar->lock);
+               count--;
+       }
+}
+
+/*
+ * Callback to allocate a receive buffer for a pending packet. We use a
+ * pre-allocated list of buffers of maximum AMSDU size (4K).
+ */
+struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
+                                           enum htc_endpoint_id endpoint,
+                                           int len)
+{
+       struct ath6kl *ar = target->dev->ar;
+       struct htc_packet *packet = NULL;
+       struct list_head *pkt_pos;
+       int refill_cnt = 0, depth = 0;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: eid=%d, len:%d\n",
+                  __func__, endpoint, len);
+
+       if ((len <= ATH6KL_BUFFER_SIZE) ||
+           (len > ATH6KL_AMSDU_BUFFER_SIZE))
+               return NULL;
+
+       spin_lock_bh(&ar->lock);
+
+       if (list_empty(&ar->amsdu_rx_buffer_queue)) {
+               spin_unlock_bh(&ar->lock);
+               refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS;
+               goto refill_buf;
+       }
+
+       packet = list_first_entry(&ar->amsdu_rx_buffer_queue,
+                                 struct htc_packet, list);
+       list_del(&packet->list);
+       list_for_each(pkt_pos, &ar->amsdu_rx_buffer_queue)
+               depth++;
+
+       refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS - depth;
+       spin_unlock_bh(&ar->lock);
+
+       /* set actual endpoint ID */
+       packet->endpoint = endpoint;
+
+refill_buf:
+       if (refill_cnt >= ATH6KL_AMSDU_REFILL_THRESHOLD)
+               ath6kl_refill_amsdu_rxbufs(ar, refill_cnt);
+
+       return packet;
+}
+
+static void aggr_slice_amsdu(struct aggr_info *p_aggr,
+                            struct rxtid *rxtid, struct sk_buff *skb)
+{
+       struct sk_buff *new_skb;
+       struct ethhdr *hdr;
+       u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
+       u8 *framep;
+
+       mac_hdr_len = sizeof(struct ethhdr);
+       framep = skb->data + mac_hdr_len;
+       amsdu_len = skb->len - mac_hdr_len;
+
+       while (amsdu_len > mac_hdr_len) {
+               hdr = (struct ethhdr *) framep;
+               payload_8023_len = ntohs(hdr->h_proto);
+
+               if (payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN ||
+                   payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
+                       ath6kl_err("802.3 AMSDU frame bound check failed. len %d\n",
+                                  payload_8023_len);
+                       break;
+               }
+
+               frame_8023_len = payload_8023_len + mac_hdr_len;
+               new_skb = aggr_get_free_skb(p_aggr);
+               if (!new_skb) {
+                       ath6kl_err("no buffer available\n");
+                       break;
+               }
+
+               memcpy(new_skb->data, framep, frame_8023_len);
+               skb_put(new_skb, frame_8023_len);
+               if (ath6kl_wmi_dot3_2_dix(new_skb)) {
+                       ath6kl_err("dot3_2_dix error\n");
+                       dev_kfree_skb(new_skb);
+                       break;
+               }
+
+               skb_queue_tail(&rxtid->q, new_skb);
+
+               /* Is this the last subframe within this aggregate ? */
+               if ((amsdu_len - frame_8023_len) == 0)
+                       break;
+
+               /* Add the length of A-MSDU subframe padding bytes -
+                * Round to nearest word.
+                */
+               frame_8023_len = ALIGN(frame_8023_len + 3, 3);
+
+               framep += frame_8023_len;
+               amsdu_len -= frame_8023_len;
+       }
+
+       dev_kfree_skb(skb);
+}
+
+static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
+                           u16 seq_no, u8 order)
+{
+       struct sk_buff *skb;
+       struct rxtid *rxtid;
+       struct skb_hold_q *node;
+       u16 idx, idx_end, seq_end;
+       struct rxtid_stats *stats;
+
+       if (!p_aggr)
+               return;
+
+       rxtid = &p_aggr->rx_tid[tid];
+       stats = &p_aggr->stat[tid];
+
+       idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
+
+       /*
+        * idx_end is typically the last possible frame in the window,
+        * but changes to 'the' seq_no, when BAR comes. If seq_no
+        * is non-zero, we will go up to that and stop.
+        * Note: last seq no in current window will occupy the same
+        * index position as index that is just previous to start.
+        * An imp point : if win_sz is 7, for seq_no space of 4095,
+        * then, there would be holes when sequence wrap around occurs.
+        * Target should judiciously choose the win_sz, based on
+        * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
+        * 2, 4, 8, 16 win_sz works fine).
+        * We must deque from "idx" to "idx_end", including both.
+        */
+       seq_end = seq_no ? seq_no : rxtid->seq_next;
+       idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
+
+       spin_lock_bh(&rxtid->lock);
+
+       do {
+               node = &rxtid->hold_q[idx];
+               if ((order == 1) && (!node->skb))
+                       break;
+
+               if (node->skb) {
+                       if (node->is_amsdu)
+                               aggr_slice_amsdu(p_aggr, rxtid, node->skb);
+                       else
+                               skb_queue_tail(&rxtid->q, node->skb);
+                       node->skb = NULL;
+               } else
+                       stats->num_hole++;
+
+               rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
+               idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
+       } while (idx != idx_end);
+
+       spin_unlock_bh(&rxtid->lock);
+
+       stats->num_delivered += skb_queue_len(&rxtid->q);
+
+       while ((skb = skb_dequeue(&rxtid->q)))
+               ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb);
+}
+
+static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
+                                 u16 seq_no,
+                                 bool is_amsdu, struct sk_buff *frame)
+{
+       struct rxtid *rxtid;
+       struct rxtid_stats *stats;
+       struct sk_buff *skb;
+       struct skb_hold_q *node;
+       u16 idx, st, cur, end;
+       bool is_queued = false;
+       u16 extended_end;
+
+       rxtid = &agg_info->rx_tid[tid];
+       stats = &agg_info->stat[tid];
+
+       stats->num_into_aggr++;
+
+       if (!rxtid->aggr) {
+               if (is_amsdu) {
+                       aggr_slice_amsdu(agg_info, rxtid, frame);
+                       is_queued = true;
+                       stats->num_amsdu++;
+                       while ((skb = skb_dequeue(&rxtid->q)))
+                               ath6kl_deliver_frames_to_nw_stack(agg_info->dev,
+                                                                 skb);
+               }
+               return is_queued;
+       }
+
+       /* Check the incoming sequence no, if it's in the window */
+       st = rxtid->seq_next;
+       cur = seq_no;
+       end = (st + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO;
+
+       if (((st < end) && (cur < st || cur > end)) ||
+           ((st > end) && (cur > end) && (cur < st))) {
+               extended_end = (end + rxtid->hold_q_sz - 1) &
+                       ATH6KL_MAX_SEQ_NO;
+
+               if (((end < extended_end) &&
+                    (cur < end || cur > extended_end)) ||
+                   ((end > extended_end) && (cur > extended_end) &&
+                    (cur < end))) {
+                       aggr_deque_frms(agg_info, tid, 0, 0);
+                       if (cur >= rxtid->hold_q_sz - 1)
+                               rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
+                       else
+                               rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
+                                                 (rxtid->hold_q_sz - 2 - cur);
+               } else {
+                       /*
+                        * Dequeue only those frames that are outside the
+                        * new shifted window.
+                        */
+                       if (cur >= rxtid->hold_q_sz - 1)
+                               st = cur - (rxtid->hold_q_sz - 1);
+                       else
+                               st = ATH6KL_MAX_SEQ_NO -
+                                       (rxtid->hold_q_sz - 2 - cur);
+
+                       aggr_deque_frms(agg_info, tid, st, 0);
+               }
+
+               stats->num_oow++;
+       }
+
+       idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
+
+       node = &rxtid->hold_q[idx];
+
+       spin_lock_bh(&rxtid->lock);
+
+       /*
+        * Is the cur frame duplicate or something beyond our window(hold_q
+        * -> which is 2x, already)?
+        *
+        * 1. Duplicate is easy - drop incoming frame.
+        * 2. Not falling in current sliding window.
+        *  2a. is the frame_seq_no preceding current tid_seq_no?
+        *      -> drop the frame. perhaps sender did not get our ACK.
+        *         this is taken care of above.
+        *  2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
+        *      -> Taken care of it above, by moving window forward.
+        */
+       dev_kfree_skb(node->skb);
+       stats->num_dups++;
+
+       node->skb = frame;
+       is_queued = true;
+       node->is_amsdu = is_amsdu;
+       node->seq_no = seq_no;
+
+       if (node->is_amsdu)
+               stats->num_amsdu++;
+       else
+               stats->num_mpdu++;
+
+       spin_unlock_bh(&rxtid->lock);
+
+       aggr_deque_frms(agg_info, tid, 0, 1);
+
+       if (agg_info->timer_scheduled)
+               rxtid->progress = true;
+       else
+               for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
+                       if (rxtid->hold_q[idx].skb) {
+                               /*
+                                * There is a frame in the queue and no
+                                * timer so start a timer to ensure that
+                                * the frame doesn't remain stuck
+                                * forever.
+                                */
+                               agg_info->timer_scheduled = true;
+                               mod_timer(&agg_info->timer,
+                                         (jiffies +
+                                          HZ * (AGGR_RX_TIMEOUT) / 1000));
+                               rxtid->progress = false;
+                               rxtid->timer_mon = true;
+                               break;
+                       }
+               }
+
+       return is_queued;
+}
+
+void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
+{
+       struct ath6kl *ar = target->dev->ar;
+       struct sk_buff *skb = packet->pkt_cntxt;
+       struct wmi_rx_meta_v2 *meta;
+       struct wmi_data_hdr *dhdr;
+       int min_hdr_len;
+       u8 meta_type, dot11_hdr = 0;
+       int status = packet->status;
+       enum htc_endpoint_id ept = packet->endpoint;
+       bool is_amsdu, prev_ps, ps_state = false;
+       struct ath6kl_sta *conn = NULL;
+       struct sk_buff *skb1 = NULL;
+       struct ethhdr *datap = NULL;
+       u16 seq_no, offset;
+       u8 tid;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
+                  "%s: ar=0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
+                  __func__, ar, ept, skb, packet->buf,
+                  packet->act_len, status);
+
+       if (status || !(skb->data + HTC_HDR_LENGTH)) {
+               ar->net_stats.rx_errors++;
+               dev_kfree_skb(skb);
+               return;
+       }
+
+       /*
+        * Take lock to protect buffer counts and adaptive power throughput
+        * state.
+        */
+       spin_lock_bh(&ar->lock);
+
+       ar->net_stats.rx_packets++;
+       ar->net_stats.rx_bytes += packet->act_len;
+
+       skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
+       skb_pull(skb, HTC_HDR_LENGTH);
+
+       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
+
+       spin_unlock_bh(&ar->lock);
+
+       skb->dev = ar->net_dev;
+
+       if (!test_bit(WMI_ENABLED, &ar->flag)) {
+               if (EPPING_ALIGNMENT_PAD > 0)
+                       skb_pull(skb, EPPING_ALIGNMENT_PAD);
+               ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
+               return;
+       }
+
+       if (ept == ar->ctrl_ep) {
+               ath6kl_wmi_control_rx(ar->wmi, skb);
+               return;
+       }
+
+       min_hdr_len = sizeof(struct ethhdr);
+       min_hdr_len += sizeof(struct wmi_data_hdr) +
+                      sizeof(struct ath6kl_llc_snap_hdr);
+
+       dhdr = (struct wmi_data_hdr *) skb->data;
+
+       /*
+        * In the case of AP mode we may receive NULL data frames
+        * that do not have LLC hdr. They are 16 bytes in size.
+        * Allow these frames in the AP mode.
+        */
+       if (ar->nw_type != AP_NETWORK &&
+           ((packet->act_len < min_hdr_len) ||
+            (packet->act_len > WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))) {
+               ath6kl_info("frame len is too short or too long\n");
+               ar->net_stats.rx_errors++;
+               ar->net_stats.rx_length_errors++;
+               dev_kfree_skb(skb);
+               return;
+       }
+
+       /* Get the Power save state of the STA */
+       if (ar->nw_type == AP_NETWORK) {
+               meta_type = wmi_data_hdr_get_meta(dhdr);
+
+               ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
+                             WMI_DATA_HDR_PS_MASK);
+
+               offset = sizeof(struct wmi_data_hdr);
+
+               switch (meta_type) {
+               case 0:
+                       break;
+               case WMI_META_VERSION_1:
+                       offset += sizeof(struct wmi_rx_meta_v1);
+                       break;
+               case WMI_META_VERSION_2:
+                       offset += sizeof(struct wmi_rx_meta_v2);
+                       break;
+               default:
+                       break;
+               }
+
+               datap = (struct ethhdr *) (skb->data + offset);
+               conn = ath6kl_find_sta(ar, datap->h_source);
+
+               if (!conn) {
+                       dev_kfree_skb(skb);
+                       return;
+               }
+
+               /*
+                * If there is a change in PS state of the STA,
+                * take appropriate steps:
+                *
+                * 1. If Sleep-->Awake, flush the psq for the STA
+                *    Clear the PVB for the STA.
+                * 2. If Awake-->Sleep, Starting queueing frames
+                *    the STA.
+                */
+               prev_ps = !!(conn->sta_flags & STA_PS_SLEEP);
+
+               if (ps_state)
+                       conn->sta_flags |= STA_PS_SLEEP;
+               else
+                       conn->sta_flags &= ~STA_PS_SLEEP;
+
+               if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
+                       if (!(conn->sta_flags & STA_PS_SLEEP)) {
+                               struct sk_buff *skbuff = NULL;
+
+                               spin_lock_bh(&conn->psq_lock);
+                               while ((skbuff = skb_dequeue(&conn->psq))
+                                      != NULL) {
+                                       spin_unlock_bh(&conn->psq_lock);
+                                       ath6kl_data_tx(skbuff, ar->net_dev);
+                                       spin_lock_bh(&conn->psq_lock);
+                               }
+                               spin_unlock_bh(&conn->psq_lock);
+                               /* Clear the PVB for this STA */
+                               ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
+                       }
+               }
+
+               /* drop NULL data frames here */
+               if ((packet->act_len < min_hdr_len) ||
+                   (packet->act_len >
+                    WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH)) {
+                       dev_kfree_skb(skb);
+                       return;
+               }
+       }
+
+       is_amsdu = wmi_data_hdr_is_amsdu(dhdr) ? true : false;
+       tid = wmi_data_hdr_get_up(dhdr);
+       seq_no = wmi_data_hdr_get_seqno(dhdr);
+       meta_type = wmi_data_hdr_get_meta(dhdr);
+       dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
+
+       ath6kl_wmi_data_hdr_remove(ar->wmi, skb);
+
+       switch (meta_type) {
+       case WMI_META_VERSION_1:
+               skb_pull(skb, sizeof(struct wmi_rx_meta_v1));
+               break;
+       case WMI_META_VERSION_2:
+               meta = (struct wmi_rx_meta_v2 *) skb->data;
+               if (meta->csum_flags & 0x1) {
+                       skb->ip_summed = CHECKSUM_COMPLETE;
+                       skb->csum = (__force __wsum) meta->csum;
+               }
+               skb_pull(skb, sizeof(struct wmi_rx_meta_v2));
+               break;
+       default:
+               break;
+       }
+
+       if (dot11_hdr)
+               status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb);
+       else if (!is_amsdu)
+               status = ath6kl_wmi_dot3_2_dix(skb);
+
+       if (status) {
+               /*
+                * Drop frames that could not be processed (lack of
+                * memory, etc.)
+                */
+               dev_kfree_skb(skb);
+               return;
+       }
+
+       if (!(ar->net_dev->flags & IFF_UP)) {
+               dev_kfree_skb(skb);
+               return;
+       }
+
+       if (ar->nw_type == AP_NETWORK) {
+               datap = (struct ethhdr *) skb->data;
+               if (is_multicast_ether_addr(datap->h_dest))
+                       /*
+                        * Bcast/Mcast frames should be sent to the
+                        * OS stack as well as on the air.
+                        */
+                       skb1 = skb_copy(skb, GFP_ATOMIC);
+               else {
+                       /*
+                        * Search for a connected STA with dstMac
+                        * as the Mac address. If found send the
+                        * frame to it on the air else send the
+                        * frame up the stack.
+                        */
+                       struct ath6kl_sta *conn = NULL;
+                       conn = ath6kl_find_sta(ar, datap->h_dest);
+
+                       if (conn && ar->intra_bss) {
+                               skb1 = skb;
+                               skb = NULL;
+                       } else if (conn && !ar->intra_bss) {
+                               dev_kfree_skb(skb);
+                               skb = NULL;
+                       }
+               }
+               if (skb1)
+                       ath6kl_data_tx(skb1, ar->net_dev);
+       }
+
+       if (!aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no,
+                                  is_amsdu, skb))
+               ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
+}
+
+static void aggr_timeout(unsigned long arg)
+{
+       u8 i, j;
+       struct aggr_info *p_aggr = (struct aggr_info *) arg;
+       struct rxtid *rxtid;
+       struct rxtid_stats *stats;
+
+       for (i = 0; i < NUM_OF_TIDS; i++) {
+               rxtid = &p_aggr->rx_tid[i];
+               stats = &p_aggr->stat[i];
+
+               if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
+                       continue;
+
+               /*
+                * FIXME: these timeouts happen quite fruently, something
+                * line once within 60 seconds. Investigate why.
+                */
+               stats->num_timeouts++;
+               ath6kl_dbg(ATH6KL_DBG_AGGR,
+                          "aggr timeout (st %d end %d)\n",
+                          rxtid->seq_next,
+                          ((rxtid->seq_next + rxtid->hold_q_sz-1) &
+                           ATH6KL_MAX_SEQ_NO));
+               aggr_deque_frms(p_aggr, i, 0, 0);
+       }
+
+       p_aggr->timer_scheduled = false;
+
+       for (i = 0; i < NUM_OF_TIDS; i++) {
+               rxtid = &p_aggr->rx_tid[i];
+
+               if (rxtid->aggr && rxtid->hold_q) {
+                       for (j = 0; j < rxtid->hold_q_sz; j++) {
+                               if (rxtid->hold_q[j].skb) {
+                                       p_aggr->timer_scheduled = true;
+                                       rxtid->timer_mon = true;
+                                       rxtid->progress = false;
+                                       break;
+                               }
+                       }
+
+                       if (j >= rxtid->hold_q_sz)
+                               rxtid->timer_mon = false;
+               }
+       }
+
+       if (p_aggr->timer_scheduled)
+               mod_timer(&p_aggr->timer,
+                         jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
+}
+
+static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
+{
+       struct rxtid *rxtid;
+       struct rxtid_stats *stats;
+
+       if (!p_aggr || tid >= NUM_OF_TIDS)
+               return;
+
+       rxtid = &p_aggr->rx_tid[tid];
+       stats = &p_aggr->stat[tid];
+
+       if (rxtid->aggr)
+               aggr_deque_frms(p_aggr, tid, 0, 0);
+
+       rxtid->aggr = false;
+       rxtid->progress = false;
+       rxtid->timer_mon = false;
+       rxtid->win_sz = 0;
+       rxtid->seq_next = 0;
+       rxtid->hold_q_sz = 0;
+
+       kfree(rxtid->hold_q);
+       rxtid->hold_q = NULL;
+
+       memset(stats, 0, sizeof(struct rxtid_stats));
+}
+
+void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, u8 win_sz)
+{
+       struct aggr_info *p_aggr = ar->aggr_cntxt;
+       struct rxtid *rxtid;
+       struct rxtid_stats *stats;
+       u16 hold_q_size;
+
+       if (!p_aggr)
+               return;
+
+       rxtid = &p_aggr->rx_tid[tid];
+       stats = &p_aggr->stat[tid];
+
+       if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
+               ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
+                          __func__, win_sz, tid);
+
+       if (rxtid->aggr)
+               aggr_delete_tid_state(p_aggr, tid);
+
+       rxtid->seq_next = seq_no;
+       hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
+       rxtid->hold_q = kzalloc(hold_q_size, GFP_KERNEL);
+       if (!rxtid->hold_q)
+               return;
+
+       rxtid->win_sz = win_sz;
+       rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
+       if (!skb_queue_empty(&rxtid->q))
+               return;
+
+       rxtid->aggr = true;
+}
+
+struct aggr_info *aggr_init(struct net_device *dev)
+{
+       struct aggr_info *p_aggr = NULL;
+       struct rxtid *rxtid;
+       u8 i;
+
+       p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
+       if (!p_aggr) {
+               ath6kl_err("failed to alloc memory for aggr_node\n");
+               return NULL;
+       }
+
+       p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
+       p_aggr->dev = dev;
+       init_timer(&p_aggr->timer);
+       p_aggr->timer.function = aggr_timeout;
+       p_aggr->timer.data = (unsigned long) p_aggr;
+
+       p_aggr->timer_scheduled = false;
+       skb_queue_head_init(&p_aggr->free_q);
+
+       ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+
+       for (i = 0; i < NUM_OF_TIDS; i++) {
+               rxtid = &p_aggr->rx_tid[i];
+               rxtid->aggr = false;
+               rxtid->progress = false;
+               rxtid->timer_mon = false;
+               skb_queue_head_init(&rxtid->q);
+               spin_lock_init(&rxtid->lock);
+       }
+
+       return p_aggr;
+}
+
+void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid)
+{
+       struct aggr_info *p_aggr = ar->aggr_cntxt;
+       struct rxtid *rxtid;
+
+       if (!p_aggr)
+               return;
+
+       rxtid = &p_aggr->rx_tid[tid];
+
+       if (rxtid->aggr)
+               aggr_delete_tid_state(p_aggr, tid);
+}
+
+void aggr_reset_state(struct aggr_info *aggr_info)
+{
+       u8 tid;
+
+       for (tid = 0; tid < NUM_OF_TIDS; tid++)
+               aggr_delete_tid_state(aggr_info, tid);
+}
+
+/* clean up our amsdu buffer list */
+void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
+{
+       struct htc_packet *packet, *tmp_pkt;
+
+       spin_lock_bh(&ar->lock);
+       if (list_empty(&ar->amsdu_rx_buffer_queue)) {
+               spin_unlock_bh(&ar->lock);
+               return;
+       }
+
+       list_for_each_entry_safe(packet, tmp_pkt, &ar->amsdu_rx_buffer_queue,
+                                list) {
+               list_del(&packet->list);
+               spin_unlock_bh(&ar->lock);
+               dev_kfree_skb(packet->pkt_cntxt);
+               spin_lock_bh(&ar->lock);
+       }
+
+       spin_unlock_bh(&ar->lock);
+}
+
+void aggr_module_destroy(struct aggr_info *aggr_info)
+{
+       struct rxtid *rxtid;
+       u8 i, k;
+
+       if (!aggr_info)
+               return;
+
+       if (aggr_info->timer_scheduled) {
+               del_timer(&aggr_info->timer);
+               aggr_info->timer_scheduled = false;
+       }
+
+       for (i = 0; i < NUM_OF_TIDS; i++) {
+               rxtid = &aggr_info->rx_tid[i];
+               if (rxtid->hold_q) {
+                       for (k = 0; k < rxtid->hold_q_sz; k++)
+                               dev_kfree_skb(rxtid->hold_q[k].skb);
+                       kfree(rxtid->hold_q);
+               }
+
+               skb_queue_purge(&rxtid->q);
+       }
+
+       skb_queue_purge(&aggr_info->free_q);
+       kfree(aggr_info);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
new file mode 100644 (file)
index 0000000..f5aa33d
--- /dev/null
@@ -0,0 +1,2743 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications 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 <linux/ip.h>
+#include "core.h"
+#include "debug.h"
+
+static int ath6kl_wmi_sync_point(struct wmi *wmi);
+
+static const s32 wmi_rate_tbl[][2] = {
+       /* {W/O SGI, with SGI} */
+       {1000, 1000},
+       {2000, 2000},
+       {5500, 5500},
+       {11000, 11000},
+       {6000, 6000},
+       {9000, 9000},
+       {12000, 12000},
+       {18000, 18000},
+       {24000, 24000},
+       {36000, 36000},
+       {48000, 48000},
+       {54000, 54000},
+       {6500, 7200},
+       {13000, 14400},
+       {19500, 21700},
+       {26000, 28900},
+       {39000, 43300},
+       {52000, 57800},
+       {58500, 65000},
+       {65000, 72200},
+       {13500, 15000},
+       {27000, 30000},
+       {40500, 45000},
+       {54000, 60000},
+       {81000, 90000},
+       {108000, 120000},
+       {121500, 135000},
+       {135000, 150000},
+       {0, 0}
+};
+
+/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
+static const u8 up_to_ac[] = {
+       WMM_AC_BE,
+       WMM_AC_BK,
+       WMM_AC_BK,
+       WMM_AC_BE,
+       WMM_AC_VI,
+       WMM_AC_VI,
+       WMM_AC_VO,
+       WMM_AC_VO,
+};
+
+void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id)
+{
+       if (WARN_ON(ep_id == ENDPOINT_UNUSED || ep_id >= ENDPOINT_MAX))
+               return;
+
+       wmi->ep_id = ep_id;
+}
+
+enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)
+{
+       return wmi->ep_id;
+}
+
+/*  Performs DIX to 802.3 encapsulation for transmit packets.
+ *  Assumes the entire DIX header is contigous and that there is
+ *  enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
+ */
+int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb)
+{
+       struct ath6kl_llc_snap_hdr *llc_hdr;
+       struct ethhdr *eth_hdr;
+       size_t new_len;
+       __be16 type;
+       u8 *datap;
+       u16 size;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       size = sizeof(struct ath6kl_llc_snap_hdr) + sizeof(struct wmi_data_hdr);
+       if (skb_headroom(skb) < size)
+               return -ENOMEM;
+
+       eth_hdr = (struct ethhdr *) skb->data;
+       type = eth_hdr->h_proto;
+
+       if (!is_ethertype(be16_to_cpu(type))) {
+               ath6kl_dbg(ATH6KL_DBG_WMI,
+                       "%s: pkt is already in 802.3 format\n", __func__);
+               return 0;
+       }
+
+       new_len = skb->len - sizeof(*eth_hdr) + sizeof(*llc_hdr);
+
+       skb_push(skb, sizeof(struct ath6kl_llc_snap_hdr));
+       datap = skb->data;
+
+       eth_hdr->h_proto = cpu_to_be16(new_len);
+
+       memcpy(datap, eth_hdr, sizeof(*eth_hdr));
+
+       llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap + sizeof(*eth_hdr));
+       llc_hdr->dsap = 0xAA;
+       llc_hdr->ssap = 0xAA;
+       llc_hdr->cntl = 0x03;
+       llc_hdr->org_code[0] = 0x0;
+       llc_hdr->org_code[1] = 0x0;
+       llc_hdr->org_code[2] = 0x0;
+       llc_hdr->eth_type = type;
+
+       return 0;
+}
+
+static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
+                              u8 *version, void *tx_meta_info)
+{
+       struct wmi_tx_meta_v1 *v1;
+       struct wmi_tx_meta_v2 *v2;
+
+       if (WARN_ON(skb == NULL || version == NULL))
+               return -EINVAL;
+
+       switch (*version) {
+       case WMI_META_VERSION_1:
+               skb_push(skb, WMI_MAX_TX_META_SZ);
+               v1 = (struct wmi_tx_meta_v1 *) skb->data;
+               v1->pkt_id = 0;
+               v1->rate_plcy_id = 0;
+               *version = WMI_META_VERSION_1;
+               break;
+       case WMI_META_VERSION_2:
+               skb_push(skb, WMI_MAX_TX_META_SZ);
+               v2 = (struct wmi_tx_meta_v2 *) skb->data;
+               memcpy(v2, (struct wmi_tx_meta_v2 *) tx_meta_info,
+                      sizeof(struct wmi_tx_meta_v2));
+               break;
+       }
+
+       return 0;
+}
+
+int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
+                           u8 msg_type, bool more_data,
+                           enum wmi_data_hdr_data_type data_type,
+                           u8 meta_ver, void *tx_meta_info)
+{
+       struct wmi_data_hdr *data_hdr;
+       int ret;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
+       if (ret)
+               return ret;
+
+       skb_push(skb, sizeof(struct wmi_data_hdr));
+
+       data_hdr = (struct wmi_data_hdr *)skb->data;
+       memset(data_hdr, 0, sizeof(struct wmi_data_hdr));
+
+       data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
+       data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
+
+       if (more_data)
+               data_hdr->info |=
+                   WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
+
+       data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
+       data_hdr->info3 = 0;
+
+       return 0;
+}
+
+static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
+{
+       struct iphdr *ip_hdr = (struct iphdr *) pkt;
+       u8 ip_pri;
+
+       /*
+        * Determine IPTOS priority
+        *
+        * IP-TOS - 8bits
+        *          : DSCP(6-bits) ECN(2-bits)
+        *          : DSCP - P2 P1 P0 X X X
+        * where (P2 P1 P0) form 802.1D
+        */
+       ip_pri = ip_hdr->tos >> 5;
+       ip_pri &= 0x7;
+
+       if ((layer2_pri & 0x7) > ip_pri)
+               return (u8) layer2_pri & 0x7;
+       else
+               return ip_pri;
+}
+
+int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
+                                      u32 layer2_priority, bool wmm_enabled,
+                                      u8 *ac)
+{
+       struct wmi_data_hdr *data_hdr;
+       struct ath6kl_llc_snap_hdr *llc_hdr;
+       struct wmi_create_pstream_cmd cmd;
+       u32 meta_size, hdr_size;
+       u16 ip_type = IP_ETHERTYPE;
+       u8 stream_exist, usr_pri;
+       u8 traffic_class = WMM_AC_BE;
+       u8 *datap;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       datap = skb->data;
+       data_hdr = (struct wmi_data_hdr *) datap;
+
+       meta_size = ((le16_to_cpu(data_hdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
+                    WMI_DATA_HDR_META_MASK) ? WMI_MAX_TX_META_SZ : 0;
+
+       if (!wmm_enabled) {
+               /* If WMM is disabled all traffic goes as BE traffic */
+               usr_pri = 0;
+       } else {
+               hdr_size = sizeof(struct ethhdr);
+
+               llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap +
+                                                        sizeof(struct
+                                                               wmi_data_hdr) +
+                                                        meta_size + hdr_size);
+
+               if (llc_hdr->eth_type == htons(ip_type)) {
+                       /*
+                        * Extract the endpoint info from the TOS field
+                        * in the IP header.
+                        */
+                       usr_pri =
+                          ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
+                                       sizeof(struct ath6kl_llc_snap_hdr),
+                                       layer2_priority);
+               } else
+                       usr_pri = layer2_priority & 0x7;
+       }
+
+       /* workaround for WMM S5 */
+       if ((wmi->traffic_class == WMM_AC_VI) &&
+           ((usr_pri == 5) || (usr_pri == 4)))
+               usr_pri = 1;
+
+       /* Convert user priority to traffic class */
+       traffic_class = up_to_ac[usr_pri & 0x7];
+
+       wmi_data_hdr_set_up(data_hdr, usr_pri);
+
+       spin_lock_bh(&wmi->lock);
+       stream_exist = wmi->fat_pipe_exist;
+       spin_unlock_bh(&wmi->lock);
+
+       if (!(stream_exist & (1 << traffic_class))) {
+               memset(&cmd, 0, sizeof(cmd));
+               cmd.traffic_class = traffic_class;
+               cmd.user_pri = usr_pri;
+               cmd.inactivity_int =
+                       cpu_to_le32(WMI_IMPLICIT_PSTREAM_INACTIVITY_INT);
+               /* Implicit streams are created with TSID 0xFF */
+               cmd.tsid = WMI_IMPLICIT_PSTREAM;
+               ath6kl_wmi_create_pstream_cmd(wmi, &cmd);
+       }
+
+       *ac = traffic_class;
+
+       return 0;
+}
+
+int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
+{
+       struct ieee80211_hdr_3addr *pwh, wh;
+       struct ath6kl_llc_snap_hdr *llc_hdr;
+       struct ethhdr eth_hdr;
+       u32 hdr_size;
+       u8 *datap;
+       __le16 sub_type;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       datap = skb->data;
+       pwh = (struct ieee80211_hdr_3addr *) datap;
+
+       sub_type = pwh->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
+
+       memcpy((u8 *) &wh, datap, sizeof(struct ieee80211_hdr_3addr));
+
+       /* Strip off the 802.11 header */
+       if (sub_type == cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
+               hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
+                                  sizeof(u32));
+               skb_pull(skb, hdr_size);
+       } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA))
+               skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
+
+       datap = skb->data;
+       llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap);
+
+       memset(&eth_hdr, 0, sizeof(eth_hdr));
+       eth_hdr.h_proto = llc_hdr->eth_type;
+
+       switch ((le16_to_cpu(wh.frame_control)) &
+               (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
+       case 0:
+               memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
+               memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
+               break;
+       case IEEE80211_FCTL_TODS:
+               memcpy(eth_hdr.h_dest, wh.addr3, ETH_ALEN);
+               memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
+               break;
+       case IEEE80211_FCTL_FROMDS:
+               memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
+               memcpy(eth_hdr.h_source, wh.addr3, ETH_ALEN);
+               break;
+       case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
+               break;
+       }
+
+       skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
+       skb_push(skb, sizeof(eth_hdr));
+
+       datap = skb->data;
+
+       memcpy(datap, &eth_hdr, sizeof(eth_hdr));
+
+       return 0;
+}
+
+/*
+ * Performs 802.3 to DIX encapsulation for received packets.
+ * Assumes the entire 802.3 header is contigous.
+ */
+int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
+{
+       struct ath6kl_llc_snap_hdr *llc_hdr;
+       struct ethhdr eth_hdr;
+       u8 *datap;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       datap = skb->data;
+
+       memcpy(&eth_hdr, datap, sizeof(eth_hdr));
+
+       llc_hdr = (struct ath6kl_llc_snap_hdr *) (datap + sizeof(eth_hdr));
+       eth_hdr.h_proto = llc_hdr->eth_type;
+
+       skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
+       datap = skb->data;
+
+       memcpy(datap, &eth_hdr, sizeof(eth_hdr));
+
+       return 0;
+}
+
+int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
+{
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       skb_pull(skb, sizeof(struct wmi_data_hdr));
+
+       return 0;
+}
+
+static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
+                                                  u8 *datap)
+{
+       struct wmi_bss_info_hdr2 bih2;
+       struct wmi_bss_info_hdr *bih;
+
+       memcpy(&bih2, datap, sizeof(struct wmi_bss_info_hdr2));
+
+       skb_push(skb, 4);
+       bih = (struct wmi_bss_info_hdr *) skb->data;
+
+       bih->ch = bih2.ch;
+       bih->frame_type = bih2.frame_type;
+       bih->snr = bih2.snr;
+       bih->rssi = a_cpu_to_sle16(bih2.snr - 95);
+       bih->ie_mask = cpu_to_le32(le16_to_cpu(bih2.ie_mask));
+       memcpy(bih->bssid, bih2.bssid, ETH_ALEN);
+}
+
+static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
+{
+       struct tx_complete_msg_v1 *msg_v1;
+       struct wmi_tx_complete_event *evt;
+       int index;
+       u16 size;
+
+       evt = (struct wmi_tx_complete_event *) datap;
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
+                  evt->num_msg, evt->msg_len, evt->msg_type);
+
+       if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
+               return 0;
+
+       for (index = 0; index < evt->num_msg; index++) {
+               size = sizeof(struct wmi_tx_complete_event) +
+                   (index * sizeof(struct tx_complete_msg_v1));
+               msg_v1 = (struct tx_complete_msg_v1 *)(datap + size);
+
+               ath6kl_dbg(ATH6KL_DBG_WMI, "msg: %d %d %d %d\n",
+                          msg_v1->status, msg_v1->pkt_id,
+                          msg_v1->rate_idx, msg_v1->ack_failures);
+       }
+
+       return 0;
+}
+
+static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
+{
+       struct sk_buff *skb;
+
+       skb = ath6kl_buf_alloc(size);
+       if (!skb)
+               return NULL;
+
+       skb_put(skb, size);
+       if (size)
+               memset(skb->data, 0, size);
+
+       return skb;
+}
+
+/* Send a "simple" wmi command -- one with no arguments */
+static int ath6kl_wmi_simple_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id)
+{
+       struct sk_buff *skb;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(0);
+       if (!skb)
+               return -ENOMEM;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, cmd_id, NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_ready_event_2 *ev = (struct wmi_ready_event_2 *) datap;
+
+       if (len < sizeof(struct wmi_ready_event_2))
+               return -EINVAL;
+
+       wmi->ready = true;
+       ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
+                          le32_to_cpu(ev->sw_version),
+                          le32_to_cpu(ev->abi_version));
+
+       return 0;
+}
+
+static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_connect_event *ev;
+       u8 *pie, *peie;
+
+       if (len < sizeof(struct wmi_connect_event))
+               return -EINVAL;
+
+       ev = (struct wmi_connect_event *) datap;
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM\n",
+                  __func__, ev->ch, ev->bssid);
+
+       /* Start of assoc rsp IEs */
+       pie = ev->assoc_info + ev->beacon_ie_len +
+             ev->assoc_req_len + (sizeof(u16) * 3); /* capinfo, status, aid */
+
+       /* End of assoc rsp IEs */
+       peie = ev->assoc_info + ev->beacon_ie_len + ev->assoc_req_len +
+           ev->assoc_resp_len;
+
+       while (pie < peie) {
+               switch (*pie) {
+               case WLAN_EID_VENDOR_SPECIFIC:
+                       if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 &&
+                           pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) {
+                               /* WMM OUT (00:50:F2) */
+                               if (pie[1] > 5
+                                   && pie[6] == WMM_PARAM_OUI_SUBTYPE)
+                                       wmi->is_wmm_enabled = true;
+                       }
+                       break;
+               }
+
+               if (wmi->is_wmm_enabled)
+                       break;
+
+               pie += pie[1] + 2;
+       }
+
+       ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->ch), ev->bssid,
+                            le16_to_cpu(ev->listen_intvl),
+                            le16_to_cpu(ev->beacon_intvl),
+                            le32_to_cpu(ev->nw_type),
+                            ev->beacon_ie_len, ev->assoc_req_len,
+                            ev->assoc_resp_len, ev->assoc_info);
+
+       return 0;
+}
+
+static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_disconnect_event *ev;
+       wmi->traffic_class = 100;
+
+       if (len < sizeof(struct wmi_disconnect_event))
+               return -EINVAL;
+
+       ev = (struct wmi_disconnect_event *) datap;
+
+       wmi->is_wmm_enabled = false;
+       wmi->pair_crypto_type = NONE_CRYPT;
+       wmi->grp_crypto_type = NONE_CRYPT;
+
+       ath6kl_disconnect_event(wmi->parent_dev, ev->disconn_reason,
+                               ev->bssid, ev->assoc_resp_len, ev->assoc_info,
+                               le16_to_cpu(ev->proto_reason_status));
+
+       return 0;
+}
+
+static int ath6kl_wmi_peer_node_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_peer_node_event *ev;
+
+       if (len < sizeof(struct wmi_peer_node_event))
+               return -EINVAL;
+
+       ev = (struct wmi_peer_node_event *) datap;
+
+       if (ev->event_code == PEER_NODE_JOIN_EVENT)
+               ath6kl_dbg(ATH6KL_DBG_WMI, "joined node with mac addr: %pM\n",
+                          ev->peer_mac_addr);
+       else if (ev->event_code == PEER_NODE_LEAVE_EVENT)
+               ath6kl_dbg(ATH6KL_DBG_WMI, "left node with mac addr: %pM\n",
+                          ev->peer_mac_addr);
+
+       return 0;
+}
+
+static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_tkip_micerr_event *ev;
+
+       if (len < sizeof(struct wmi_tkip_micerr_event))
+               return -EINVAL;
+
+       ev = (struct wmi_tkip_micerr_event *) datap;
+
+       ath6kl_tkip_micerr_event(wmi->parent_dev, ev->key_id, ev->is_mcast);
+
+       return 0;
+}
+
+static int ath6kl_wlan_parse_beacon(u8 *buf, int frame_len,
+                                   struct ath6kl_common_ie *cie)
+{
+       u8 *frm, *efrm;
+       u8 elemid_ssid = false;
+
+       frm = buf;
+       efrm = (u8 *) (frm + frame_len);
+
+       /*
+        * beacon/probe response frame format
+        *  [8] time stamp
+        *  [2] beacon interval
+        *  [2] capability information
+        *  [tlv] ssid
+        *  [tlv] supported rates
+        *  [tlv] country information
+        *  [tlv] parameter set (FH/DS)
+        *  [tlv] erp information
+        *  [tlv] extended supported rates
+        *  [tlv] WMM
+        *  [tlv] WPA or RSN
+        *  [tlv] Atheros Advanced Capabilities
+        */
+       if ((efrm - frm) < 12)
+               return -EINVAL;
+
+       memset(cie, 0, sizeof(*cie));
+
+       cie->ie_tstamp = frm;
+       frm += 8;
+       cie->ie_beaconInt = *(u16 *) frm;
+       frm += 2;
+       cie->ie_capInfo = *(u16 *) frm;
+       frm += 2;
+       cie->ie_chan = 0;
+
+       while (frm < efrm) {
+               switch (*frm) {
+               case WLAN_EID_SSID:
+                       if (!elemid_ssid) {
+                               cie->ie_ssid = frm;
+                               elemid_ssid = true;
+                       }
+                       break;
+               case WLAN_EID_SUPP_RATES:
+                       cie->ie_rates = frm;
+                       break;
+               case WLAN_EID_COUNTRY:
+                       cie->ie_country = frm;
+                       break;
+               case WLAN_EID_FH_PARAMS:
+                       break;
+               case WLAN_EID_DS_PARAMS:
+                       cie->ie_chan = frm[2];
+                       break;
+               case WLAN_EID_TIM:
+                       cie->ie_tim = frm;
+                       break;
+               case WLAN_EID_IBSS_PARAMS:
+                       break;
+               case WLAN_EID_EXT_SUPP_RATES:
+                       cie->ie_xrates = frm;
+                       break;
+               case WLAN_EID_ERP_INFO:
+                       if (frm[1] != 1)
+                               return -EINVAL;
+
+                       cie->ie_erp = frm[2];
+                       break;
+               case WLAN_EID_RSN:
+                       cie->ie_rsn = frm;
+                       break;
+               case WLAN_EID_HT_CAPABILITY:
+                       cie->ie_htcap = frm;
+                       break;
+               case WLAN_EID_HT_INFORMATION:
+                       cie->ie_htop = frm;
+                       break;
+               case WLAN_EID_VENDOR_SPECIFIC:
+                       if (frm[1] > 3 && frm[2] == 0x00 && frm[3] == 0x50 &&
+                           frm[4] == 0xf2) {
+                               /* OUT Type (00:50:F2) */
+
+                               if (frm[5] == WPA_OUI_TYPE) {
+                                       /* WPA OUT */
+                                       cie->ie_wpa = frm;
+                               } else if (frm[5] == WMM_OUI_TYPE) {
+                                       /* WMM OUT */
+                                       cie->ie_wmm = frm;
+                               } else if (frm[5] == WSC_OUT_TYPE) {
+                                       /* WSC OUT */
+                                       cie->ie_wsc = frm;
+                               }
+
+                       } else if (frm[1] > 3 && frm[2] == 0x00
+                                  && frm[3] == 0x03 && frm[4] == 0x7f
+                                  && frm[5] == ATH_OUI_TYPE) {
+                               /* Atheros OUI (00:03:7f) */
+                               cie->ie_ath = frm;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               frm += frm[1] + 2;
+       }
+
+       if ((cie->ie_rates == NULL)
+           || (cie->ie_rates[1] > ATH6KL_RATE_MAXSIZE))
+               return -EINVAL;
+
+       if ((cie->ie_ssid == NULL)
+           || (cie->ie_ssid[1] > IEEE80211_MAX_SSID_LEN))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct bss *bss = NULL;
+       struct wmi_bss_info_hdr *bih;
+       u8 cached_ssid_len = 0;
+       u8 cached_ssid[IEEE80211_MAX_SSID_LEN] = { 0 };
+       u8 beacon_ssid_len = 0;
+       u8 *buf, *ie_ssid;
+       u8 *ni_buf;
+       int buf_len;
+
+       int ret;
+
+       if (len <= sizeof(struct wmi_bss_info_hdr))
+               return -EINVAL;
+
+       bih = (struct wmi_bss_info_hdr *) datap;
+       bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
+
+       if (a_sle16_to_cpu(bih->rssi) > 0) {
+               if (bss == NULL)
+                       return 0;
+               else
+                       bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
+       }
+
+       buf = datap + sizeof(struct wmi_bss_info_hdr);
+       len -= sizeof(struct wmi_bss_info_hdr);
+
+       ath6kl_dbg(ATH6KL_DBG_WMI,
+                  "bss info evt - ch %u, rssi %02x, bssid \"%pM\"\n",
+                  bih->ch, a_sle16_to_cpu(bih->rssi), bih->bssid);
+
+       if (bss != NULL) {
+               /*
+                * Free up the node. We are about to allocate a new node.
+                * In case of hidden AP, beacon will not have ssid,
+                * but a directed probe response will have it,
+                * so cache the probe-resp-ssid if already present.
+                */
+               if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE)) {
+                       ie_ssid = bss->ni_cie.ie_ssid;
+                       if (ie_ssid && (ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
+                           (ie_ssid[2] != 0)) {
+                               cached_ssid_len = ie_ssid[1];
+                               memcpy(cached_ssid, ie_ssid + 2,
+                                      cached_ssid_len);
+                       }
+               }
+
+               /*
+                * Use the current average rssi of associated AP base on
+                * assumption
+                *   1. Most os with GUI will update RSSI by
+                *      ath6kl_wmi_get_stats_cmd() periodically.
+                *   2. ath6kl_wmi_get_stats_cmd(..) will be called when calling
+                *      ath6kl_wmi_startscan_cmd(...)
+                * The average value of RSSI give end-user better feeling for
+                * instance value of scan result. It also sync up RSSI info
+                * in GUI between scan result and RSSI signal icon.
+                */
+               if (memcmp(wmi->parent_dev->bssid, bih->bssid, ETH_ALEN) == 0) {
+                       bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
+                       bih->snr = bss->ni_snr;
+               }
+
+               wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
+       }
+
+       /*
+        * beacon/probe response frame format
+        *  [8] time stamp
+        *  [2] beacon interval
+        *  [2] capability information
+        *  [tlv] ssid
+        */
+       beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
+
+       /*
+        * If ssid is cached for this hidden AP, then change
+        * buffer len accordingly.
+        */
+       if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
+           (cached_ssid_len != 0) &&
+           (beacon_ssid_len == 0 || (cached_ssid_len > beacon_ssid_len &&
+                                     buf[SSID_IE_LEN_INDEX + 1] == 0))) {
+
+               len += (cached_ssid_len - beacon_ssid_len);
+       }
+
+       bss = wlan_node_alloc(len);
+       if (!bss)
+               return -ENOMEM;
+
+       bss->ni_snr = bih->snr;
+       bss->ni_rssi = a_sle16_to_cpu(bih->rssi);
+
+       if (WARN_ON(!bss->ni_buf))
+               return -EINVAL;
+
+       /*
+        * In case of hidden AP, beacon will not have ssid,
+        * but a directed probe response will have it,
+        * so place the cached-ssid(probe-resp) in the bss info.
+        */
+       if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
+           (cached_ssid_len != 0) &&
+           (beacon_ssid_len == 0 || (beacon_ssid_len &&
+                                     buf[SSID_IE_LEN_INDEX + 1] == 0))) {
+               ni_buf = bss->ni_buf;
+               buf_len = len;
+
+               /*
+                * Copy the first 14 bytes:
+                * time-stamp(8), beacon-interval(2),
+                * cap-info(2), ssid-id(1), ssid-len(1).
+                */
+               memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
+
+               ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
+               ni_buf += (SSID_IE_LEN_INDEX + 1);
+
+               buf += (SSID_IE_LEN_INDEX + 1);
+               buf_len -= (SSID_IE_LEN_INDEX + 1);
+
+               memcpy(ni_buf, cached_ssid, cached_ssid_len);
+               ni_buf += cached_ssid_len;
+
+               buf += beacon_ssid_len;
+               buf_len -= beacon_ssid_len;
+
+               if (cached_ssid_len > beacon_ssid_len)
+                       buf_len -= (cached_ssid_len - beacon_ssid_len);
+
+               memcpy(ni_buf, buf, buf_len);
+       } else
+               memcpy(bss->ni_buf, buf, len);
+
+       bss->ni_framelen = len;
+
+       ret = ath6kl_wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie);
+       if (ret) {
+               wlan_node_free(bss);
+               return -EINVAL;
+       }
+
+       /*
+        * Update the frequency in ie_chan, overwriting of channel number
+        * which is done in ath6kl_wlan_parse_beacon
+        */
+       bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
+       wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
+
+       return 0;
+}
+
+static int ath6kl_wmi_opt_frame_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct bss *bss;
+       struct wmi_opt_rx_info_hdr *bih;
+       u8 *buf;
+
+       if (len <= sizeof(struct wmi_opt_rx_info_hdr))
+               return -EINVAL;
+
+       bih = (struct wmi_opt_rx_info_hdr *) datap;
+       buf = datap + sizeof(struct wmi_opt_rx_info_hdr);
+       len -= sizeof(struct wmi_opt_rx_info_hdr);
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "opt frame event %2.2x:%2.2x\n",
+                  bih->bssid[4], bih->bssid[5]);
+
+       bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
+       if (bss != NULL) {
+               /* Free up the node. We are about to allocate a new node. */
+               wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
+       }
+
+       bss = wlan_node_alloc(len);
+       if (!bss)
+               return -ENOMEM;
+
+       bss->ni_snr = bih->snr;
+       bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
+
+       if (WARN_ON(!bss->ni_buf))
+               return -EINVAL;
+
+       memcpy(bss->ni_buf, buf, len);
+       wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
+
+       return 0;
+}
+
+/* Inactivity timeout of a fatpipe(pstream) at the target */
+static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap,
+                                              int len)
+{
+       struct wmi_pstream_timeout_event *ev;
+
+       if (len < sizeof(struct wmi_pstream_timeout_event))
+               return -EINVAL;
+
+       ev = (struct wmi_pstream_timeout_event *) datap;
+
+       /*
+        * When the pstream (fat pipe == AC) timesout, it means there were
+        * no thinStreams within this pstream & it got implicitly created
+        * due to data flow on this AC. We start the inactivity timer only
+        * for implicitly created pstream. Just reset the host state.
+        */
+       spin_lock_bh(&wmi->lock);
+       wmi->stream_exist_for_ac[ev->traffic_class] = 0;
+       wmi->fat_pipe_exist &= ~(1 << ev->traffic_class);
+       spin_unlock_bh(&wmi->lock);
+
+       /* Indicate inactivity to driver layer for this fatpipe (pstream) */
+       ath6kl_indicate_tx_activity(wmi->parent_dev, ev->traffic_class, false);
+
+       return 0;
+}
+
+static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_bit_rate_reply *reply;
+       s32 rate;
+       u32 sgi, index;
+
+       if (len < sizeof(struct wmi_bit_rate_reply))
+               return -EINVAL;
+
+       reply = (struct wmi_bit_rate_reply *) datap;
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "rateindex %d\n", reply->rate_index);
+
+       if (reply->rate_index == (s8) RATE_AUTO) {
+               rate = RATE_AUTO;
+       } else {
+               index = reply->rate_index & 0x7f;
+               sgi = (reply->rate_index & 0x80) ? 1 : 0;
+               rate = wmi_rate_tbl[index][sgi];
+       }
+
+       ath6kl_wakeup_event(wmi->parent_dev);
+
+       return 0;
+}
+
+static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       if (len < sizeof(struct wmi_fix_rates_reply))
+               return -EINVAL;
+
+       ath6kl_wakeup_event(wmi->parent_dev);
+
+       return 0;
+}
+
+static int ath6kl_wmi_ch_list_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       if (len < sizeof(struct wmi_channel_list_reply))
+               return -EINVAL;
+
+       ath6kl_wakeup_event(wmi->parent_dev);
+
+       return 0;
+}
+
+static int ath6kl_wmi_tx_pwr_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_tx_pwr_reply *reply;
+
+       if (len < sizeof(struct wmi_tx_pwr_reply))
+               return -EINVAL;
+
+       reply = (struct wmi_tx_pwr_reply *) datap;
+       ath6kl_txpwr_rx_evt(wmi->parent_dev, reply->dbM);
+
+       return 0;
+}
+
+static int ath6kl_wmi_keepalive_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       if (len < sizeof(struct wmi_get_keepalive_cmd))
+               return -EINVAL;
+
+       ath6kl_wakeup_event(wmi->parent_dev);
+
+       return 0;
+}
+
+static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_scan_complete_event *ev;
+
+       ev = (struct wmi_scan_complete_event *) datap;
+
+       if (a_sle32_to_cpu(ev->status) == 0)
+               wlan_refresh_inactive_nodes(wmi->parent_dev);
+
+       ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status));
+       wmi->is_probe_ssid = false;
+
+       return 0;
+}
+
+/*
+ * Target is reporting a programming error.  This is for
+ * developer aid only.  Target only checks a few common violations
+ * and it is responsibility of host to do all error checking.
+ * Behavior of target after wmi error event is undefined.
+ * A reset is recommended.
+ */
+static int ath6kl_wmi_error_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       const char *type = "unknown error";
+       struct wmi_cmd_error_event *ev;
+       ev = (struct wmi_cmd_error_event *) datap;
+
+       switch (ev->err_code) {
+       case INVALID_PARAM:
+               type = "invalid parameter";
+               break;
+       case ILLEGAL_STATE:
+               type = "invalid state";
+               break;
+       case INTERNAL_ERROR:
+               type = "internal error";
+               break;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "programming error, cmd=%d %s\n",
+                  ev->cmd_id, type);
+
+       return 0;
+}
+
+static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       ath6kl_tgt_stats_event(wmi->parent_dev, datap, len);
+
+       return 0;
+}
+
+static u8 ath6kl_wmi_get_upper_threshold(s16 rssi,
+                                        struct sq_threshold_params *sq_thresh,
+                                        u32 size)
+{
+       u32 index;
+       u8 threshold = (u8) sq_thresh->upper_threshold[size - 1];
+
+       /* The list is already in sorted order. Get the next lower value */
+       for (index = 0; index < size; index++) {
+               if (rssi < sq_thresh->upper_threshold[index]) {
+                       threshold = (u8) sq_thresh->upper_threshold[index];
+                       break;
+               }
+       }
+
+       return threshold;
+}
+
+static u8 ath6kl_wmi_get_lower_threshold(s16 rssi,
+                                        struct sq_threshold_params *sq_thresh,
+                                        u32 size)
+{
+       u32 index;
+       u8 threshold = (u8) sq_thresh->lower_threshold[size - 1];
+
+       /* The list is already in sorted order. Get the next lower value */
+       for (index = 0; index < size; index++) {
+               if (rssi > sq_thresh->lower_threshold[index]) {
+                       threshold = (u8) sq_thresh->lower_threshold[index];
+                       break;
+               }
+       }
+
+       return threshold;
+}
+
+static int ath6kl_wmi_send_rssi_threshold_params(struct wmi *wmi,
+                       struct wmi_rssi_threshold_params_cmd *rssi_cmd)
+{
+       struct sk_buff *skb;
+       struct wmi_rssi_threshold_params_cmd *cmd;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_rssi_threshold_params_cmd *) skb->data;
+       memcpy(cmd, rssi_cmd, sizeof(struct wmi_rssi_threshold_params_cmd));
+
+       return ath6kl_wmi_cmd_send(wmi, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
+static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
+                                             int len)
+{
+       struct wmi_rssi_threshold_event *reply;
+       struct wmi_rssi_threshold_params_cmd cmd;
+       struct sq_threshold_params *sq_thresh;
+       enum wmi_rssi_threshold_val new_threshold;
+       u8 upper_rssi_threshold, lower_rssi_threshold;
+       s16 rssi;
+       int ret;
+
+       if (len < sizeof(struct wmi_rssi_threshold_event))
+               return -EINVAL;
+
+       reply = (struct wmi_rssi_threshold_event *) datap;
+       new_threshold = (enum wmi_rssi_threshold_val) reply->range;
+       rssi = a_sle16_to_cpu(reply->rssi);
+
+       sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_RSSI];
+
+       /*
+        * Identify the threshold breached and communicate that to the app.
+        * After that install a new set of thresholds based on the signal
+        * quality reported by the target
+        */
+       if (new_threshold) {
+               /* Upper threshold breached */
+               if (rssi < sq_thresh->upper_threshold[0]) {
+                       ath6kl_dbg(ATH6KL_DBG_WMI,
+                               "spurious upper rssi threshold event: %d\n",
+                               rssi);
+               } else if ((rssi < sq_thresh->upper_threshold[1]) &&
+                          (rssi >= sq_thresh->upper_threshold[0])) {
+                       new_threshold = WMI_RSSI_THRESHOLD1_ABOVE;
+               } else if ((rssi < sq_thresh->upper_threshold[2]) &&
+                          (rssi >= sq_thresh->upper_threshold[1])) {
+                       new_threshold = WMI_RSSI_THRESHOLD2_ABOVE;
+               } else if ((rssi < sq_thresh->upper_threshold[3]) &&
+                          (rssi >= sq_thresh->upper_threshold[2])) {
+                       new_threshold = WMI_RSSI_THRESHOLD3_ABOVE;
+               } else if ((rssi < sq_thresh->upper_threshold[4]) &&
+                          (rssi >= sq_thresh->upper_threshold[3])) {
+                       new_threshold = WMI_RSSI_THRESHOLD4_ABOVE;
+               } else if ((rssi < sq_thresh->upper_threshold[5]) &&
+                          (rssi >= sq_thresh->upper_threshold[4])) {
+                       new_threshold = WMI_RSSI_THRESHOLD5_ABOVE;
+               } else if (rssi >= sq_thresh->upper_threshold[5]) {
+                       new_threshold = WMI_RSSI_THRESHOLD6_ABOVE;
+               }
+       } else {
+               /* Lower threshold breached */
+               if (rssi > sq_thresh->lower_threshold[0]) {
+                       ath6kl_dbg(ATH6KL_DBG_WMI,
+                               "spurious lower rssi threshold event: %d %d\n",
+                               rssi, sq_thresh->lower_threshold[0]);
+               } else if ((rssi > sq_thresh->lower_threshold[1]) &&
+                          (rssi <= sq_thresh->lower_threshold[0])) {
+                       new_threshold = WMI_RSSI_THRESHOLD6_BELOW;
+               } else if ((rssi > sq_thresh->lower_threshold[2]) &&
+                          (rssi <= sq_thresh->lower_threshold[1])) {
+                       new_threshold = WMI_RSSI_THRESHOLD5_BELOW;
+               } else if ((rssi > sq_thresh->lower_threshold[3]) &&
+                          (rssi <= sq_thresh->lower_threshold[2])) {
+                       new_threshold = WMI_RSSI_THRESHOLD4_BELOW;
+               } else if ((rssi > sq_thresh->lower_threshold[4]) &&
+                          (rssi <= sq_thresh->lower_threshold[3])) {
+                       new_threshold = WMI_RSSI_THRESHOLD3_BELOW;
+               } else if ((rssi > sq_thresh->lower_threshold[5]) &&
+                          (rssi <= sq_thresh->lower_threshold[4])) {
+                       new_threshold = WMI_RSSI_THRESHOLD2_BELOW;
+               } else if (rssi <= sq_thresh->lower_threshold[5]) {
+                       new_threshold = WMI_RSSI_THRESHOLD1_BELOW;
+               }
+       }
+
+       /* Calculate and install the next set of thresholds */
+       lower_rssi_threshold = ath6kl_wmi_get_lower_threshold(rssi, sq_thresh,
+                                      sq_thresh->lower_threshold_valid_count);
+       upper_rssi_threshold = ath6kl_wmi_get_upper_threshold(rssi, sq_thresh,
+                                      sq_thresh->upper_threshold_valid_count);
+
+       /* Issue a wmi command to install the thresholds */
+       cmd.thresh_above1_val = a_cpu_to_sle16(upper_rssi_threshold);
+       cmd.thresh_below1_val = a_cpu_to_sle16(lower_rssi_threshold);
+       cmd.weight = sq_thresh->weight;
+       cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
+
+       ret = ath6kl_wmi_send_rssi_threshold_params(wmi, &cmd);
+       if (ret) {
+               ath6kl_err("unable to configure rssi thresholds\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_cac_event *reply;
+       struct ieee80211_tspec_ie *ts;
+       u16 active_tsids, tsinfo;
+       u8 tsid, index;
+       u8 ts_id;
+
+       if (len < sizeof(struct wmi_cac_event))
+               return -EINVAL;
+
+       reply = (struct wmi_cac_event *) datap;
+
+       if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
+           (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
+
+               ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
+               tsinfo = le16_to_cpu(ts->tsinfo);
+               tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
+                       IEEE80211_WMM_IE_TSPEC_TID_MASK;
+
+               ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, tsid);
+       } else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
+               /*
+                * Following assumes that there is only one outstanding
+                * ADDTS request when this event is received
+                */
+               spin_lock_bh(&wmi->lock);
+               active_tsids = wmi->stream_exist_for_ac[reply->ac];
+               spin_unlock_bh(&wmi->lock);
+
+               for (index = 0; index < sizeof(active_tsids) * 8; index++) {
+                       if ((active_tsids >> index) & 1)
+                               break;
+               }
+               if (index < (sizeof(active_tsids) * 8))
+                       ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, index);
+       }
+
+       /*
+        * Clear active tsids and Add missing handling
+        * for delete qos stream from AP
+        */
+       else if (reply->cac_indication == CAC_INDICATION_DELETE) {
+
+               ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
+               tsinfo = le16_to_cpu(ts->tsinfo);
+               ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
+                        IEEE80211_WMM_IE_TSPEC_TID_MASK);
+
+               spin_lock_bh(&wmi->lock);
+               wmi->stream_exist_for_ac[reply->ac] &= ~(1 << ts_id);
+               active_tsids = wmi->stream_exist_for_ac[reply->ac];
+               spin_unlock_bh(&wmi->lock);
+
+               /* Indicate stream inactivity to driver layer only if all tsids
+                * within this AC are deleted.
+                */
+               if (!active_tsids) {
+                       ath6kl_indicate_tx_activity(wmi->parent_dev, reply->ac,
+                                                   false);
+                       wmi->fat_pipe_exist &= ~(1 << reply->ac);
+               }
+       }
+
+       return 0;
+}
+
+static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
+                       struct wmi_snr_threshold_params_cmd *snr_cmd)
+{
+       struct sk_buff *skb;
+       struct wmi_snr_threshold_params_cmd *cmd;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_snr_threshold_params_cmd *) skb->data;
+       memcpy(cmd, snr_cmd, sizeof(struct wmi_snr_threshold_params_cmd));
+
+       return ath6kl_wmi_cmd_send(wmi, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
+static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
+                                            int len)
+{
+       struct wmi_snr_threshold_event *reply;
+       struct sq_threshold_params *sq_thresh;
+       struct wmi_snr_threshold_params_cmd cmd;
+       enum wmi_snr_threshold_val new_threshold;
+       u8 upper_snr_threshold, lower_snr_threshold;
+       s16 snr;
+       int ret;
+
+       if (len < sizeof(struct wmi_snr_threshold_event))
+               return -EINVAL;
+
+       reply = (struct wmi_snr_threshold_event *) datap;
+
+       new_threshold = (enum wmi_snr_threshold_val) reply->range;
+       snr = reply->snr;
+
+       sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_SNR];
+
+       /*
+        * Identify the threshold breached and communicate that to the app.
+        * After that install a new set of thresholds based on the signal
+        * quality reported by the target.
+        */
+       if (new_threshold) {
+               /* Upper threshold breached */
+               if (snr < sq_thresh->upper_threshold[0]) {
+                       ath6kl_dbg(ATH6KL_DBG_WMI,
+                               "spurious upper snr threshold event: %d\n",
+                               snr);
+               } else if ((snr < sq_thresh->upper_threshold[1]) &&
+                          (snr >= sq_thresh->upper_threshold[0])) {
+                       new_threshold = WMI_SNR_THRESHOLD1_ABOVE;
+               } else if ((snr < sq_thresh->upper_threshold[2]) &&
+                          (snr >= sq_thresh->upper_threshold[1])) {
+                       new_threshold = WMI_SNR_THRESHOLD2_ABOVE;
+               } else if ((snr < sq_thresh->upper_threshold[3]) &&
+                          (snr >= sq_thresh->upper_threshold[2])) {
+                       new_threshold = WMI_SNR_THRESHOLD3_ABOVE;
+               } else if (snr >= sq_thresh->upper_threshold[3]) {
+                       new_threshold = WMI_SNR_THRESHOLD4_ABOVE;
+               }
+       } else {
+               /* Lower threshold breached */
+               if (snr > sq_thresh->lower_threshold[0]) {
+                       ath6kl_dbg(ATH6KL_DBG_WMI,
+                               "spurious lower snr threshold event: %d\n",
+                               sq_thresh->lower_threshold[0]);
+               } else if ((snr > sq_thresh->lower_threshold[1]) &&
+                          (snr <= sq_thresh->lower_threshold[0])) {
+                       new_threshold = WMI_SNR_THRESHOLD4_BELOW;
+               } else if ((snr > sq_thresh->lower_threshold[2]) &&
+                          (snr <= sq_thresh->lower_threshold[1])) {
+                       new_threshold = WMI_SNR_THRESHOLD3_BELOW;
+               } else if ((snr > sq_thresh->lower_threshold[3]) &&
+                          (snr <= sq_thresh->lower_threshold[2])) {
+                       new_threshold = WMI_SNR_THRESHOLD2_BELOW;
+               } else if (snr <= sq_thresh->lower_threshold[3]) {
+                       new_threshold = WMI_SNR_THRESHOLD1_BELOW;
+               }
+       }
+
+       /* Calculate and install the next set of thresholds */
+       lower_snr_threshold = ath6kl_wmi_get_lower_threshold(snr, sq_thresh,
+                                      sq_thresh->lower_threshold_valid_count);
+       upper_snr_threshold = ath6kl_wmi_get_upper_threshold(snr, sq_thresh,
+                                      sq_thresh->upper_threshold_valid_count);
+
+       /* Issue a wmi command to install the thresholds */
+       cmd.thresh_above1_val = upper_snr_threshold;
+       cmd.thresh_below1_val = lower_snr_threshold;
+       cmd.weight = sq_thresh->weight;
+       cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
+
+       ath6kl_dbg(ATH6KL_DBG_WMI,
+                  "snr: %d, threshold: %d, lower: %d, upper: %d\n",
+                  snr, new_threshold,
+                  lower_snr_threshold, upper_snr_threshold);
+
+       ret = ath6kl_wmi_send_snr_threshold_params(wmi, &cmd);
+       if (ret) {
+               ath6kl_err("unable to configure snr threshold\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       u16 ap_info_entry_size;
+       struct wmi_aplist_event *ev = (struct wmi_aplist_event *) datap;
+       struct wmi_ap_info_v1 *ap_info_v1;
+       u8 index;
+
+       if (len < sizeof(struct wmi_aplist_event) ||
+           ev->ap_list_ver != APLIST_VER1)
+               return -EINVAL;
+
+       ap_info_entry_size = sizeof(struct wmi_ap_info_v1);
+       ap_info_v1 = (struct wmi_ap_info_v1 *) ev->ap_list;
+
+       ath6kl_dbg(ATH6KL_DBG_WMI,
+                  "number of APs in aplist event: %d\n", ev->num_ap);
+
+       if (len < (int) (sizeof(struct wmi_aplist_event) +
+                        (ev->num_ap - 1) * ap_info_entry_size))
+               return -EINVAL;
+
+       /* AP list version 1 contents */
+       for (index = 0; index < ev->num_ap; index++) {
+               ath6kl_dbg(ATH6KL_DBG_WMI, "AP#%d BSSID %pM Channel %d\n",
+                          index, ap_info_v1->bssid, ap_info_v1->channel);
+               ap_info_v1++;
+       }
+
+       return 0;
+}
+
+int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
+                       enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag)
+{
+       struct wmi_cmd_hdr *cmd_hdr;
+       enum htc_endpoint_id ep_id = wmi->ep_id;
+       int ret;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       if (sync_flag >= END_WMIFLAG) {
+               dev_kfree_skb(skb);
+               return -EINVAL;
+       }
+
+       if ((sync_flag == SYNC_BEFORE_WMIFLAG) ||
+           (sync_flag == SYNC_BOTH_WMIFLAG)) {
+               /*
+                * Make sure all data currently queued is transmitted before
+                * the cmd execution.  Establish a new sync point.
+                */
+               ath6kl_wmi_sync_point(wmi);
+       }
+
+       skb_push(skb, sizeof(struct wmi_cmd_hdr));
+
+       cmd_hdr = (struct wmi_cmd_hdr *) skb->data;
+       cmd_hdr->cmd_id = cpu_to_le16(cmd_id);
+       cmd_hdr->info1 = 0;     /* added for virtual interface */
+
+       /* Only for OPT_TX_CMD, use BE endpoint. */
+       if (cmd_id == WMI_OPT_TX_FRAME_CMDID) {
+               ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE,
+                                             false, false, 0, NULL);
+               if (ret) {
+                       dev_kfree_skb(skb);
+                       return ret;
+               }
+               ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, WMM_AC_BE);
+       }
+
+       ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
+
+       if ((sync_flag == SYNC_AFTER_WMIFLAG) ||
+           (sync_flag == SYNC_BOTH_WMIFLAG)) {
+               /*
+                * Make sure all new data queued waits for the command to
+                * execute. Establish a new sync point.
+                */
+               ath6kl_wmi_sync_point(wmi);
+       }
+
+       return 0;
+}
+
+int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
+                          enum dot11_auth_mode dot11_auth_mode,
+                          enum auth_mode auth_mode,
+                          enum crypto_type pairwise_crypto,
+                          u8 pairwise_crypto_len,
+                          enum crypto_type group_crypto,
+                          u8 group_crypto_len, int ssid_len, u8 *ssid,
+                          u8 *bssid, u16 channel, u32 ctrl_flags)
+{
+       struct sk_buff *skb;
+       struct wmi_connect_cmd *cc;
+       int ret;
+
+       wmi->traffic_class = 100;
+
+       if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT))
+               return -EINVAL;
+
+       if ((pairwise_crypto != NONE_CRYPT) && (group_crypto == NONE_CRYPT))
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_connect_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cc = (struct wmi_connect_cmd *) skb->data;
+
+       if (ssid_len)
+               memcpy(cc->ssid, ssid, ssid_len);
+
+       cc->ssid_len = ssid_len;
+       cc->nw_type = nw_type;
+       cc->dot11_auth_mode = dot11_auth_mode;
+       cc->auth_mode = auth_mode;
+       cc->prwise_crypto_type = pairwise_crypto;
+       cc->prwise_crypto_len = pairwise_crypto_len;
+       cc->grp_crypto_type = group_crypto;
+       cc->grp_crypto_len = group_crypto_len;
+       cc->ch = cpu_to_le16(channel);
+       cc->ctrl_flags = cpu_to_le32(ctrl_flags);
+
+       if (bssid != NULL)
+               memcpy(cc->bssid, bssid, ETH_ALEN);
+
+       wmi->pair_crypto_type = pairwise_crypto;
+       wmi->grp_crypto_type = group_crypto;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
+{
+       struct sk_buff *skb;
+       struct wmi_reconnect_cmd *cc;
+       int ret;
+
+       wmi->traffic_class = 100;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cc = (struct wmi_reconnect_cmd *) skb->data;
+       cc->channel = cpu_to_le16(channel);
+
+       if (bssid != NULL)
+               memcpy(cc->bssid, bssid, ETH_ALEN);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RECONNECT_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
+{
+       int ret;
+
+       wmi->traffic_class = 100;
+
+       /* Disconnect command does not need to do a SYNC before. */
+       ret = ath6kl_wmi_simple_cmd(wmi, WMI_DISCONNECT_CMDID);
+
+       return ret;
+}
+
+int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
+                            u32 force_fgscan, u32 is_legacy,
+                            u32 home_dwell_time, u32 force_scan_interval,
+                            s8 num_chan, u16 *ch_list)
+{
+       struct sk_buff *skb;
+       struct wmi_start_scan_cmd *sc;
+       s8 size;
+       int ret;
+
+       size = sizeof(struct wmi_start_scan_cmd);
+
+       if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
+               return -EINVAL;
+
+       if (num_chan > WMI_MAX_CHANNELS)
+               return -EINVAL;
+
+       if (num_chan)
+               size += sizeof(u16) * (num_chan - 1);
+
+       skb = ath6kl_wmi_get_new_buf(size);
+       if (!skb)
+               return -ENOMEM;
+
+       sc = (struct wmi_start_scan_cmd *) skb->data;
+       sc->scan_type = scan_type;
+       sc->force_fg_scan = cpu_to_le32(force_fgscan);
+       sc->is_legacy = cpu_to_le32(is_legacy);
+       sc->home_dwell_time = cpu_to_le32(home_dwell_time);
+       sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
+       sc->num_ch = num_chan;
+
+       if (num_chan)
+               memcpy(sc->ch_list, ch_list, num_chan * sizeof(u16));
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
+                             u16 fg_end_sec, u16 bg_sec,
+                             u16 minact_chdw_msec, u16 maxact_chdw_msec,
+                             u16 pas_chdw_msec, u8 short_scan_ratio,
+                             u8 scan_ctrl_flag, u32 max_dfsch_act_time,
+                             u16 maxact_scan_per_ssid)
+{
+       struct sk_buff *skb;
+       struct wmi_scan_params_cmd *sc;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*sc));
+       if (!skb)
+               return -ENOMEM;
+
+       sc = (struct wmi_scan_params_cmd *) skb->data;
+       sc->fg_start_period = cpu_to_le16(fg_start_sec);
+       sc->fg_end_period = cpu_to_le16(fg_end_sec);
+       sc->bg_period = cpu_to_le16(bg_sec);
+       sc->minact_chdwell_time = cpu_to_le16(minact_chdw_msec);
+       sc->maxact_chdwell_time = cpu_to_le16(maxact_chdw_msec);
+       sc->pas_chdwell_time = cpu_to_le16(pas_chdw_msec);
+       sc->short_scan_ratio = short_scan_ratio;
+       sc->scan_ctrl_flags = scan_ctrl_flag;
+       sc->max_dfsch_act_time = cpu_to_le32(max_dfsch_act_time);
+       sc->maxact_scan_per_ssid = cpu_to_le16(maxact_scan_per_ssid);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_SCAN_PARAMS_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask)
+{
+       struct sk_buff *skb;
+       struct wmi_bss_filter_cmd *cmd;
+       int ret;
+
+       if (filter >= LAST_BSS_FILTER)
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_bss_filter_cmd *) skb->data;
+       cmd->bss_filter = filter;
+       cmd->ie_mask = cpu_to_le32(ie_mask);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_BSS_FILTER_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
+                             u8 ssid_len, u8 *ssid)
+{
+       struct sk_buff *skb;
+       struct wmi_probed_ssid_cmd *cmd;
+       int ret;
+
+       if (index > MAX_PROBED_SSID_INDEX)
+               return -EINVAL;
+
+       if (ssid_len > sizeof(cmd->ssid))
+               return -EINVAL;
+
+       if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssid_len > 0))
+               return -EINVAL;
+
+       if ((flag & SPECIFIC_SSID_FLAG) && !ssid_len)
+               return -EINVAL;
+
+       if (flag & SPECIFIC_SSID_FLAG)
+               wmi->is_probe_ssid = true;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_probed_ssid_cmd *) skb->data;
+       cmd->entry_index = index;
+       cmd->flag = flag;
+       cmd->ssid_len = ssid_len;
+       memcpy(cmd->ssid, ssid, ssid_len);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PROBED_SSID_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
+                                 u16 listen_beacons)
+{
+       struct sk_buff *skb;
+       struct wmi_listen_int_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_listen_int_cmd *) skb->data;
+       cmd->listen_intvl = cpu_to_le16(listen_interval);
+       cmd->num_beacons = cpu_to_le16(listen_beacons);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LISTEN_INT_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode)
+{
+       struct sk_buff *skb;
+       struct wmi_power_mode_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_power_mode_cmd *) skb->data;
+       cmd->pwr_mode = pwr_mode;
+       wmi->pwr_mode = pwr_mode;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_MODE_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
+                           u16 ps_poll_num, u16 dtim_policy,
+                           u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
+                           u16 ps_fail_event_policy)
+{
+       struct sk_buff *skb;
+       struct wmi_power_params_cmd *pm;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*pm));
+       if (!skb)
+               return -ENOMEM;
+
+       pm = (struct wmi_power_params_cmd *)skb->data;
+       pm->idle_period = cpu_to_le16(idle_period);
+       pm->pspoll_number = cpu_to_le16(ps_poll_num);
+       pm->dtim_policy = cpu_to_le16(dtim_policy);
+       pm->tx_wakeup_policy = cpu_to_le16(tx_wakeup_policy);
+       pm->num_tx_to_wakeup = cpu_to_le16(num_tx_to_wakeup);
+       pm->ps_fail_event_policy = cpu_to_le16(ps_fail_event_policy);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_PARAMS_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
+{
+       struct sk_buff *skb;
+       struct wmi_disc_timeout_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_disc_timeout_cmd *) skb->data;
+       cmd->discon_timeout = timeout;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_DISC_TIMEOUT_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
+                         enum crypto_type key_type,
+                         u8 key_usage, u8 key_len,
+                         u8 *key_rsc, u8 *key_material,
+                         u8 key_op_ctrl, u8 *mac_addr,
+                         enum wmi_sync_flag sync_flag)
+{
+       struct sk_buff *skb;
+       struct wmi_add_cipher_key_cmd *cmd;
+       int ret;
+
+       if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
+           (key_material == NULL))
+               return -EINVAL;
+
+       if ((WEP_CRYPT != key_type) && (NULL == key_rsc))
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_add_cipher_key_cmd *) skb->data;
+       cmd->key_index = key_index;
+       cmd->key_type = key_type;
+       cmd->key_usage = key_usage;
+       cmd->key_len = key_len;
+       memcpy(cmd->key, key_material, key_len);
+
+       if (key_rsc != NULL)
+               memcpy(cmd->key_rsc, key_rsc, sizeof(cmd->key_rsc));
+
+       cmd->key_op_ctrl = key_op_ctrl;
+
+       if (mac_addr)
+               memcpy(cmd->key_mac_addr, mac_addr, ETH_ALEN);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_CIPHER_KEY_CMDID,
+                                 sync_flag);
+
+       return ret;
+}
+
+int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk)
+{
+       struct sk_buff *skb;
+       struct wmi_add_krk_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_add_krk_cmd *) skb->data;
+       memcpy(cmd->krk, krk, WMI_KRK_LEN);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index)
+{
+       struct sk_buff *skb;
+       struct wmi_delete_cipher_key_cmd *cmd;
+       int ret;
+
+       if (key_index > WMI_MAX_KEY_INDEX)
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_delete_cipher_key_cmd *) skb->data;
+       cmd->key_index = key_index;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_CIPHER_KEY_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
+                           const u8 *pmkid, bool set)
+{
+       struct sk_buff *skb;
+       struct wmi_setpmkid_cmd *cmd;
+       int ret;
+
+       if (bssid == NULL)
+               return -EINVAL;
+
+       if (set && pmkid == NULL)
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_setpmkid_cmd *) skb->data;
+       memcpy(cmd->bssid, bssid, ETH_ALEN);
+       if (set) {
+               memcpy(cmd->pmkid, pmkid, sizeof(cmd->pmkid));
+               cmd->enable = PMKID_ENABLE;
+       } else {
+               memset(cmd->pmkid, 0, sizeof(cmd->pmkid));
+               cmd->enable = PMKID_DISABLE;
+       }
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PMKID_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
+                             enum htc_endpoint_id ep_id)
+{
+       struct wmi_data_hdr *data_hdr;
+       int ret;
+
+       if (WARN_ON(skb == NULL || ep_id == wmi->ep_id))
+               return -EINVAL;
+
+       skb_push(skb, sizeof(struct wmi_data_hdr));
+
+       data_hdr = (struct wmi_data_hdr *) skb->data;
+       data_hdr->info = SYNC_MSGTYPE << WMI_DATA_HDR_MSG_TYPE_SHIFT;
+       data_hdr->info3 = 0;
+
+       ret = ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
+
+       return ret;
+}
+
+static int ath6kl_wmi_sync_point(struct wmi *wmi)
+{
+       struct sk_buff *skb;
+       struct wmi_sync_cmd *cmd;
+       struct wmi_data_sync_bufs data_sync_bufs[WMM_NUM_AC];
+       enum htc_endpoint_id ep_id;
+       u8 index, num_pri_streams = 0;
+       int ret = 0;
+
+       memset(data_sync_bufs, 0, sizeof(data_sync_bufs));
+
+       spin_lock_bh(&wmi->lock);
+
+       for (index = 0; index < WMM_NUM_AC; index++) {
+               if (wmi->fat_pipe_exist & (1 << index)) {
+                       num_pri_streams++;
+                       data_sync_bufs[num_pri_streams - 1].traffic_class =
+                           index;
+               }
+       }
+
+       spin_unlock_bh(&wmi->lock);
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb) {
+               ret = -ENOMEM;
+               goto free_skb;
+       }
+
+       cmd = (struct wmi_sync_cmd *) skb->data;
+
+       /*
+        * In the SYNC cmd sent on the control Ep, send a bitmap
+        * of the data eps on which the Data Sync will be sent
+        */
+       cmd->data_sync_map = wmi->fat_pipe_exist;
+
+       for (index = 0; index < num_pri_streams; index++) {
+               data_sync_bufs[index].skb = ath6kl_buf_alloc(0);
+               if (data_sync_bufs[index].skb == NULL) {
+                       ret = -ENOMEM;
+                       break;
+               }
+       }
+
+       /*
+        * If buffer allocation for any of the dataSync fails,
+        * then do not send the Synchronize cmd on the control ep
+        */
+       if (ret)
+               goto free_skb;
+
+       /*
+        * Send sync cmd followed by sync data messages on all
+        * endpoints being used
+        */
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SYNCHRONIZE_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       if (ret)
+               goto free_skb;
+
+       /* cmd buffer sent, we no longer own it */
+       skb = NULL;
+
+       for (index = 0; index < num_pri_streams; index++) {
+
+               if (WARN_ON(!data_sync_bufs[index].skb))
+                       break;
+
+               ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
+                                              data_sync_bufs[index].
+                                              traffic_class);
+               ret =
+                   ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
+                                             ep_id);
+
+               if (ret)
+                       break;
+
+               data_sync_bufs[index].skb = NULL;
+       }
+
+free_skb:
+       /* free up any resources left over (possibly due to an error) */
+       if (skb)
+               dev_kfree_skb(skb);
+
+       for (index = 0; index < num_pri_streams; index++) {
+               if (data_sync_bufs[index].skb != NULL) {
+                       dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
+                                     skb);
+               }
+       }
+
+       return ret;
+}
+
+int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
+                                 struct wmi_create_pstream_cmd *params)
+{
+       struct sk_buff *skb;
+       struct wmi_create_pstream_cmd *cmd;
+       u8 fatpipe_exist_for_ac = 0;
+       s32 min_phy = 0;
+       s32 nominal_phy = 0;
+       int ret;
+
+       if (!((params->user_pri < 8) &&
+             (params->user_pri <= 0x7) &&
+             (up_to_ac[params->user_pri & 0x7] == params->traffic_class) &&
+             (params->traffic_direc == UPLINK_TRAFFIC ||
+              params->traffic_direc == DNLINK_TRAFFIC ||
+              params->traffic_direc == BIDIR_TRAFFIC) &&
+             (params->traffic_type == TRAFFIC_TYPE_APERIODIC ||
+              params->traffic_type == TRAFFIC_TYPE_PERIODIC) &&
+             (params->voice_psc_cap == DISABLE_FOR_THIS_AC ||
+              params->voice_psc_cap == ENABLE_FOR_THIS_AC ||
+              params->voice_psc_cap == ENABLE_FOR_ALL_AC) &&
+             (params->tsid == WMI_IMPLICIT_PSTREAM ||
+              params->tsid <= WMI_MAX_THINSTREAM))) {
+               return -EINVAL;
+       }
+
+       /*
+        * Check nominal PHY rate is >= minimalPHY,
+        * so that DUT can allow TSRS IE
+        */
+
+       /* Get the physical rate (units of bps) */
+       min_phy = ((le32_to_cpu(params->min_phy_rate) / 1000) / 1000);
+
+       /* Check minimal phy < nominal phy rate */
+       if (params->nominal_phy >= min_phy) {
+               /* unit of 500 kbps */
+               nominal_phy = (params->nominal_phy * 1000) / 500;
+               ath6kl_dbg(ATH6KL_DBG_WMI,
+                          "TSRS IE enabled::MinPhy %x->NominalPhy ===> %x\n",
+                          min_phy, nominal_phy);
+
+               params->nominal_phy = nominal_phy;
+       } else {
+               params->nominal_phy = 0;
+       }
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       ath6kl_dbg(ATH6KL_DBG_WMI,
+                  "sending create_pstream_cmd: ac=%d  tsid:%d\n",
+                  params->traffic_class, params->tsid);
+
+       cmd = (struct wmi_create_pstream_cmd *) skb->data;
+       memcpy(cmd, params, sizeof(*cmd));
+
+       /* This is an implicitly created Fat pipe */
+       if ((u32) params->tsid == (u32) WMI_IMPLICIT_PSTREAM) {
+               spin_lock_bh(&wmi->lock);
+               fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
+                                       (1 << params->traffic_class));
+               wmi->fat_pipe_exist |= (1 << params->traffic_class);
+               spin_unlock_bh(&wmi->lock);
+       } else {
+               /* explicitly created thin stream within a fat pipe */
+               spin_lock_bh(&wmi->lock);
+               fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
+                                       (1 << params->traffic_class));
+               wmi->stream_exist_for_ac[params->traffic_class] |=
+                   (1 << params->tsid);
+               /*
+                * If a thinstream becomes active, the fat pipe automatically
+                * becomes active
+                */
+               wmi->fat_pipe_exist |= (1 << params->traffic_class);
+               spin_unlock_bh(&wmi->lock);
+       }
+
+       /*
+        * Indicate activty change to driver layer only if this is the
+        * first TSID to get created in this AC explicitly or an implicit
+        * fat pipe is getting created.
+        */
+       if (!fatpipe_exist_for_ac)
+               ath6kl_indicate_tx_activity(wmi->parent_dev,
+                                           params->traffic_class, true);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CREATE_PSTREAM_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid)
+{
+       struct sk_buff *skb;
+       struct wmi_delete_pstream_cmd *cmd;
+       u16 active_tsids = 0;
+       int ret;
+
+       if (traffic_class > 3) {
+               ath6kl_err("invalid traffic class: %d\n", traffic_class);
+               return -EINVAL;
+       }
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_delete_pstream_cmd *) skb->data;
+       cmd->traffic_class = traffic_class;
+       cmd->tsid = tsid;
+
+       spin_lock_bh(&wmi->lock);
+       active_tsids = wmi->stream_exist_for_ac[traffic_class];
+       spin_unlock_bh(&wmi->lock);
+
+       if (!(active_tsids & (1 << tsid))) {
+               dev_kfree_skb(skb);
+               ath6kl_dbg(ATH6KL_DBG_WMI,
+                          "TSID %d doesn't exist for traffic class: %d\n",
+                          tsid, traffic_class);
+               return -ENODATA;
+       }
+
+       ath6kl_dbg(ATH6KL_DBG_WMI,
+                  "sending delete_pstream_cmd: traffic class: %d tsid=%d\n",
+                  traffic_class, tsid);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_PSTREAM_CMDID,
+                                 SYNC_BEFORE_WMIFLAG);
+
+       spin_lock_bh(&wmi->lock);
+       wmi->stream_exist_for_ac[traffic_class] &= ~(1 << tsid);
+       active_tsids = wmi->stream_exist_for_ac[traffic_class];
+       spin_unlock_bh(&wmi->lock);
+
+       /*
+        * Indicate stream inactivity to driver layer only if all tsids
+        * within this AC are deleted.
+        */
+       if (!active_tsids) {
+               ath6kl_indicate_tx_activity(wmi->parent_dev,
+                                           traffic_class, false);
+               wmi->fat_pipe_exist &= ~(1 << traffic_class);
+       }
+
+       return ret;
+}
+
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
+{
+       struct sk_buff *skb;
+       struct wmi_set_ip_cmd *cmd;
+       int ret;
+
+       /* Multicast address are not valid */
+       if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) ||
+           (*((u8 *) &ip_cmd->ips[1]) >= 0xE0))
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_ip_cmd *) skb->data;
+       memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd));
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+static int ath6kl_wmi_get_wow_list_event_rx(struct wmi *wmi, u8 * datap,
+                                           int len)
+{
+       if (len < sizeof(struct wmi_get_wow_list_reply))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ath6kl_wmi_cmd_send_xtnd(struct wmi *wmi, struct sk_buff *skb,
+                                   enum wmix_command_id cmd_id,
+                                   enum wmi_sync_flag sync_flag)
+{
+       struct wmix_cmd_hdr *cmd_hdr;
+       int ret;
+
+       skb_push(skb, sizeof(struct wmix_cmd_hdr));
+
+       cmd_hdr = (struct wmix_cmd_hdr *) skb->data;
+       cmd_hdr->cmd_id = cpu_to_le32(cmd_id);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_EXTENSION_CMDID, sync_flag);
+
+       return ret;
+}
+
+int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
+{
+       struct sk_buff *skb;
+       struct wmix_hb_challenge_resp_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmix_hb_challenge_resp_cmd *) skb->data;
+       cmd->cookie = cpu_to_le32(cookie);
+       cmd->source = cpu_to_le32(source);
+
+       ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_HB_CHALLENGE_RESP_CMDID,
+                                      NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
+{
+       return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
+}
+
+int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
+{
+       struct sk_buff *skb;
+       struct wmi_set_tx_pwr_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_tx_pwr_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_tx_pwr_cmd *) skb->data;
+       cmd->dbM = dbM;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_TX_PWR_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi)
+{
+       return ath6kl_wmi_simple_cmd(wmi, WMI_GET_TX_PWR_CMDID);
+}
+
+int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
+{
+       struct sk_buff *skb;
+       struct wmi_set_lpreamble_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_lpreamble_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_lpreamble_cmd *) skb->data;
+       cmd->status = status;
+       cmd->preamble_policy = preamble_policy;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LPREAMBLE_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold)
+{
+       struct sk_buff *skb;
+       struct wmi_set_rts_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_rts_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_rts_cmd *) skb->data;
+       cmd->threshold = cpu_to_le16(threshold);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_RTS_CMDID, NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg)
+{
+       struct sk_buff *skb;
+       struct wmi_set_wmm_txop_cmd *cmd;
+       int ret;
+
+       if (!((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)))
+               return -EINVAL;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_wmm_txop_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_wmm_txop_cmd *) skb->data;
+       cmd->txop_enable = cfg;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_WMM_TXOP_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
+{
+       struct sk_buff *skb;
+       struct wmi_set_keepalive_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_keepalive_cmd *) skb->data;
+       cmd->keep_alive_intvl = keep_alive_intvl;
+       wmi->keep_alive_intvl = keep_alive_intvl;
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_KEEPALIVE_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
+s32 ath6kl_wmi_get_rate(s8 rate_index)
+{
+       if (rate_index == RATE_AUTO)
+               return 0;
+
+       return wmi_rate_tbl[(u32) rate_index][0];
+}
+
+void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss)
+{
+       if (bss)
+               wlan_node_return(&wmi->parent_dev->scan_table, bss);
+}
+
+struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 * ssid,
+                                     u32 ssid_len, bool is_wpa2,
+                                     bool match_ssid)
+{
+       struct bss *node = NULL;
+
+       node = wlan_find_ssid_node(&wmi->parent_dev->scan_table, ssid,
+                                 ssid_len, is_wpa2, match_ssid);
+       return node;
+}
+
+struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 * mac_addr)
+{
+       struct bss *ni = NULL;
+
+       ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
+
+       return ni;
+}
+
+void ath6kl_wmi_node_free(struct wmi *wmi, const u8 * mac_addr)
+{
+       struct bss *ni = NULL;
+
+       ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
+       if (ni != NULL)
+               wlan_node_reclaim(&wmi->parent_dev->scan_table, ni);
+
+       return;
+}
+
+static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
+                                             u32 len)
+{
+       struct wmi_pmkid_list_reply *reply;
+       u32 expected_len;
+
+       if (len < sizeof(struct wmi_pmkid_list_reply))
+               return -EINVAL;
+
+       reply = (struct wmi_pmkid_list_reply *)datap;
+       expected_len = sizeof(reply->num_pmkid) +
+               le32_to_cpu(reply->num_pmkid) * WMI_PMKID_LEN;
+
+       if (len < expected_len)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap;
+
+       aggr_recv_addba_req_evt(wmi->parent_dev, cmd->tid,
+                               le16_to_cpu(cmd->st_seq_no), cmd->win_sz);
+
+       return 0;
+}
+
+static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap;
+
+       aggr_recv_delba_req_evt(wmi->parent_dev, cmd->tid);
+
+       return 0;
+}
+
+/*  AP mode functions */
+static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       struct wmi_pspoll_event *ev;
+
+       if (len < sizeof(struct wmi_pspoll_event))
+               return -EINVAL;
+
+       ev = (struct wmi_pspoll_event *) datap;
+
+       ath6kl_pspoll_event(wmi->parent_dev, le16_to_cpu(ev->aid));
+
+       return 0;
+}
+
+static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+       ath6kl_dtimexpiry_event(wmi->parent_dev);
+
+       return 0;
+}
+
+int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
+{
+       struct sk_buff *skb;
+       struct wmi_ap_set_pvb_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_ap_set_pvb_cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_ap_set_pvb_cmd *) skb->data;
+       cmd->aid = cpu_to_le16(aid);
+       cmd->flag = cpu_to_le32(flag);
+
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return 0;
+}
+
+int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
+                                      bool rx_dot11_hdr, bool defrag_on_host)
+{
+       struct sk_buff *skb;
+       struct wmi_rx_frame_format_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_rx_frame_format_cmd *) skb->data;
+       cmd->dot11_hdr = rx_dot11_hdr ? 1 : 0;
+       cmd->defrag_on_host = defrag_on_host ? 1 : 0;
+       cmd->meta_ver = rx_meta_ver;
+
+       /* Delete the local aggr state, on host */
+       ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RX_FRAME_FORMAT_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
+{
+       struct wmix_cmd_hdr *cmd;
+       u32 len;
+       u16 id;
+       u8 *datap;
+       int ret = 0;
+
+       if (skb->len < sizeof(struct wmix_cmd_hdr)) {
+               ath6kl_err("bad packet 1\n");
+               wmi->stat.cmd_len_err++;
+               return -EINVAL;
+       }
+
+       cmd = (struct wmix_cmd_hdr *) skb->data;
+       id = le32_to_cpu(cmd->cmd_id);
+
+       skb_pull(skb, sizeof(struct wmix_cmd_hdr));
+
+       datap = skb->data;
+       len = skb->len;
+
+       switch (id) {
+       case WMIX_HB_CHALLENGE_RESP_EVENTID:
+               break;
+       case WMIX_DBGLOG_EVENTID:
+               break;
+       default:
+               ath6kl_err("unknown cmd id 0x%x\n", id);
+               wmi->stat.cmd_id_err++;
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+/* Control Path */
+int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
+{
+       struct wmi_cmd_hdr *cmd;
+       u32 len;
+       u16 id;
+       u8 *datap;
+       int ret = 0;
+
+       if (WARN_ON(skb == NULL))
+               return -EINVAL;
+
+       if (skb->len < sizeof(struct wmi_cmd_hdr)) {
+               ath6kl_err("bad packet 1\n");
+               dev_kfree_skb(skb);
+               wmi->stat.cmd_len_err++;
+               return -EINVAL;
+       }
+
+       cmd = (struct wmi_cmd_hdr *) skb->data;
+       id = le16_to_cpu(cmd->cmd_id);
+
+       skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+
+       datap = skb->data;
+       len = skb->len;
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "%s: wmi id: %d\n", __func__, id);
+       ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "msg payload ", datap, len);
+
+       switch (id) {
+       case WMI_GET_BITRATE_CMDID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
+               ret = ath6kl_wmi_bitrate_reply_rx(wmi, datap, len);
+               break;
+       case WMI_GET_CHANNEL_LIST_CMDID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_CHANNEL_LIST_CMDID\n");
+               ret = ath6kl_wmi_ch_list_reply_rx(wmi, datap, len);
+               break;
+       case WMI_GET_TX_PWR_CMDID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_TX_PWR_CMDID\n");
+               ret = ath6kl_wmi_tx_pwr_reply_rx(wmi, datap, len);
+               break;
+       case WMI_READY_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n");
+               ret = ath6kl_wmi_ready_event_rx(wmi, datap, len);
+               break;
+       case WMI_CONNECT_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
+               ret = ath6kl_wmi_connect_event_rx(wmi, datap, len);
+               break;
+       case WMI_DISCONNECT_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
+               ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len);
+               break;
+       case WMI_PEER_NODE_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
+               ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len);
+               break;
+       case WMI_TKIP_MICERR_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
+               ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len);
+               break;
+       case WMI_BSSINFO_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
+               ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(skb, datap);
+               ret = ath6kl_wmi_bssinfo_event_rx(wmi, skb->data, skb->len);
+               break;
+       case WMI_REGDOMAIN_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
+               break;
+       case WMI_PSTREAM_TIMEOUT_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
+               ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len);
+               break;
+       case WMI_NEIGHBOR_REPORT_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
+               break;
+       case WMI_SCAN_COMPLETE_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
+               ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len);
+               break;
+       case WMI_CMDERROR_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
+               ret = ath6kl_wmi_error_event_rx(wmi, datap, len);
+               break;
+       case WMI_REPORT_STATISTICS_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
+               ret = ath6kl_wmi_stats_event_rx(wmi, datap, len);
+               break;
+       case WMI_RSSI_THRESHOLD_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
+               ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len);
+               break;
+       case WMI_ERROR_REPORT_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ERROR_REPORT_EVENTID\n");
+               break;
+       case WMI_OPT_RX_FRAME_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
+               ret = ath6kl_wmi_opt_frame_event_rx(wmi, datap, len);
+               break;
+       case WMI_REPORT_ROAM_TBL_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
+               break;
+       case WMI_EXTENSION_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
+               ret = ath6kl_wmi_control_rx_xtnd(wmi, skb);
+               break;
+       case WMI_CAC_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
+               ret = ath6kl_wmi_cac_event_rx(wmi, datap, len);
+               break;
+       case WMI_CHANNEL_CHANGE_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
+               break;
+       case WMI_REPORT_ROAM_DATA_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n");
+               break;
+       case WMI_GET_FIXRATES_CMDID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
+               ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len);
+               break;
+       case WMI_TX_RETRY_ERR_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_RETRY_ERR_EVENTID\n");
+               break;
+       case WMI_SNR_THRESHOLD_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SNR_THRESHOLD_EVENTID\n");
+               ret = ath6kl_wmi_snr_threshold_event_rx(wmi, datap, len);
+               break;
+       case WMI_LQ_THRESHOLD_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_LQ_THRESHOLD_EVENTID\n");
+               break;
+       case WMI_APLIST_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_APLIST_EVENTID\n");
+               ret = ath6kl_wmi_aplist_event_rx(wmi, datap, len);
+               break;
+       case WMI_GET_KEEPALIVE_CMDID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_KEEPALIVE_CMDID\n");
+               ret = ath6kl_wmi_keepalive_reply_rx(wmi, datap, len);
+               break;
+       case WMI_GET_WOW_LIST_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_WOW_LIST_EVENTID\n");
+               ret = ath6kl_wmi_get_wow_list_event_rx(wmi, datap, len);
+               break;
+       case WMI_GET_PMKID_LIST_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n");
+               ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len);
+               break;
+       case WMI_PSPOLL_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
+               ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len);
+               break;
+       case WMI_DTIMEXPIRY_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
+               ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len);
+               break;
+       case WMI_SET_PARAMS_REPLY_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
+               break;
+       case WMI_ADDBA_REQ_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
+               ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len);
+               break;
+       case WMI_ADDBA_RESP_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
+               break;
+       case WMI_DELBA_REQ_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
+               ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len);
+               break;
+       case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI,
+                          "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n");
+               break;
+       case WMI_REPORT_BTCOEX_STATS_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI,
+                          "WMI_REPORT_BTCOEX_STATS_EVENTID\n");
+               break;
+       case WMI_TX_COMPLETE_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
+               ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
+               break;
+       default:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
+               wmi->stat.cmd_id_err++;
+               ret = -EINVAL;
+               break;
+       }
+
+       dev_kfree_skb(skb);
+
+       return ret;
+}
+
+static void ath6kl_wmi_qos_state_init(struct wmi *wmi)
+{
+       if (!wmi)
+               return;
+
+       spin_lock_bh(&wmi->lock);
+
+       wmi->fat_pipe_exist = 0;
+       memset(wmi->stream_exist_for_ac, 0, sizeof(wmi->stream_exist_for_ac));
+
+       spin_unlock_bh(&wmi->lock);
+}
+
+void *ath6kl_wmi_init(struct ath6kl *dev)
+{
+       struct wmi *wmi;
+
+       wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
+       if (!wmi)
+               return NULL;
+
+       spin_lock_init(&wmi->lock);
+
+       wmi->parent_dev = dev;
+
+       ath6kl_wmi_qos_state_init(wmi);
+
+       wmi->pwr_mode = REC_POWER;
+       wmi->phy_mode = WMI_11G_MODE;
+
+       wmi->pair_crypto_type = NONE_CRYPT;
+       wmi->grp_crypto_type = NONE_CRYPT;
+
+       wmi->ht_allowed[A_BAND_24GHZ] = 1;
+       wmi->ht_allowed[A_BAND_5GHZ] = 1;
+
+       return wmi;
+}
+
+void ath6kl_wmi_shutdown(struct wmi *wmi)
+{
+       if (!wmi)
+               return;
+
+       kfree(wmi);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
new file mode 100644 (file)
index 0000000..fe3ddce
--- /dev/null
@@ -0,0 +1,2018 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications 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.
+ */
+
+/*
+ * This file contains the definitions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI).  It includes definitions of all the
+ * commands and events. Commands are messages from the host to the WM.
+ * Events and Replies are messages from the WM to the host.
+ */
+
+#ifndef WMI_H
+#define WMI_H
+
+#include <linux/ieee80211.h>
+
+#include "htc.h"
+
+#define HTC_PROTOCOL_VERSION           0x0002
+#define WMI_PROTOCOL_VERSION           0x0002
+#define WMI_CONTROL_MSG_MAX_LEN                256
+#define is_ethertype(type_or_len)      ((type_or_len) >= 0x0600)
+
+#define IP_ETHERTYPE           0x0800
+
+#define WMI_IMPLICIT_PSTREAM   0xFF
+#define WMI_MAX_THINSTREAM     15
+
+#define SSID_IE_LEN_INDEX      13
+
+/* Host side link management data structures */
+#define SIG_QUALITY_THRESH_LVLS                6
+#define SIG_QUALITY_UPPER_THRESH_LVLS  SIG_QUALITY_THRESH_LVLS
+#define SIG_QUALITY_LOWER_THRESH_LVLS  SIG_QUALITY_THRESH_LVLS
+
+#define A_BAND_24GHZ           0
+#define A_BAND_5GHZ            1
+#define A_NUM_BANDS            2
+
+/* in ms */
+#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000
+
+/*
+ * There are no signed versions of __le16 and __le32, so for a temporary
+ * solution come up with our own version. The idea is from fs/ntfs/types.h.
+ *
+ * Use a_ prefix so that it doesn't conflict if we get proper support to
+ * linux/types.h.
+ */
+typedef __s16 __bitwise a_sle16;
+typedef __s32 __bitwise a_sle32;
+
+static inline a_sle32 a_cpu_to_sle32(s32 val)
+{
+       return (__force a_sle32) cpu_to_le32(val);
+}
+
+static inline s32 a_sle32_to_cpu(a_sle32 val)
+{
+       return le32_to_cpu((__force __le32) val);
+}
+
+static inline a_sle16 a_cpu_to_sle16(s16 val)
+{
+       return (__force a_sle16) cpu_to_le16(val);
+}
+
+static inline s16 a_sle16_to_cpu(a_sle16 val)
+{
+       return le16_to_cpu((__force __le16) val);
+}
+
+struct sq_threshold_params {
+       s16 upper_threshold[SIG_QUALITY_UPPER_THRESH_LVLS];
+       s16 lower_threshold[SIG_QUALITY_LOWER_THRESH_LVLS];
+       u32 upper_threshold_valid_count;
+       u32 lower_threshold_valid_count;
+       u32 polling_interval;
+       u8 weight;
+       u8 last_rssi;
+       u8 last_rssi_poll_event;
+};
+
+struct wmi_stats {
+       u32 cmd_len_err;
+       u32 cmd_id_err;
+};
+
+struct wmi_data_sync_bufs {
+       u8 traffic_class;
+       struct sk_buff *skb;
+};
+
+/* WMM stream classes */
+#define WMM_NUM_AC  4
+#define WMM_AC_BE   0          /* best effort */
+#define WMM_AC_BK   1          /* background */
+#define WMM_AC_VI   2          /* video */
+#define WMM_AC_VO   3          /* voice */
+
+struct wmi {
+       bool ready;
+       u16 stream_exist_for_ac[WMM_NUM_AC];
+       u8 fat_pipe_exist;
+       struct ath6kl *parent_dev;
+       struct wmi_stats stat;
+       u8 pwr_mode;
+       u8 phy_mode;
+       u8 keep_alive_intvl;
+       spinlock_t lock;
+       enum htc_endpoint_id ep_id;
+       struct sq_threshold_params
+           sq_threshld[SIGNAL_QUALITY_METRICS_NUM_MAX];
+       enum crypto_type pair_crypto_type;
+       enum crypto_type grp_crypto_type;
+       bool is_wmm_enabled;
+       u8 ht_allowed[A_NUM_BANDS];
+       u8 traffic_class;
+       bool is_probe_ssid;
+};
+
+struct host_app_area {
+       u32 wmi_protocol_ver;
+};
+
+enum wmi_msg_type {
+       DATA_MSGTYPE = 0x0,
+       CNTL_MSGTYPE,
+       SYNC_MSGTYPE,
+       OPT_MSGTYPE,
+};
+
+/*
+ * Macros for operating on WMI_DATA_HDR (info) field
+ */
+
+#define WMI_DATA_HDR_MSG_TYPE_MASK  0x03
+#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
+#define WMI_DATA_HDR_UP_MASK        0x07
+#define WMI_DATA_HDR_UP_SHIFT       2
+
+/* In AP mode, the same bit (b5) is used to indicate Power save state in
+ * the Rx dir and More data bit state in the tx direction.
+ */
+#define WMI_DATA_HDR_PS_MASK        0x1
+#define WMI_DATA_HDR_PS_SHIFT       5
+
+#define WMI_DATA_HDR_MORE_MASK      0x1
+#define WMI_DATA_HDR_MORE_SHIFT     5
+
+enum wmi_data_hdr_data_type {
+       WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
+       WMI_DATA_HDR_DATA_TYPE_802_11,
+
+       /* used to be used for the PAL */
+       WMI_DATA_HDR_DATA_TYPE_ACL,
+};
+
+#define WMI_DATA_HDR_DATA_TYPE_MASK     0x3
+#define WMI_DATA_HDR_DATA_TYPE_SHIFT    6
+
+/* Macros for operating on WMI_DATA_HDR (info2) field */
+#define WMI_DATA_HDR_SEQNO_MASK     0xFFF
+#define WMI_DATA_HDR_SEQNO_SHIFT    0
+
+#define WMI_DATA_HDR_AMSDU_MASK     0x1
+#define WMI_DATA_HDR_AMSDU_SHIFT    12
+
+#define WMI_DATA_HDR_META_MASK      0x7
+#define WMI_DATA_HDR_META_SHIFT     13
+
+struct wmi_data_hdr {
+       s8 rssi;
+
+       /*
+        * usage of 'info' field(8-bit):
+        *
+        *  b1:b0       - WMI_MSG_TYPE
+        *  b4:b3:b2    - UP(tid)
+        *  b5          - Used in AP mode.
+        *  More-data in tx dir, PS in rx.
+        *  b7:b6       - Dot3 header(0),
+        *                Dot11 Header(1),
+        *                ACL data(2)
+        */
+       u8 info;
+
+       /*
+        * usage of 'info2' field(16-bit):
+        *
+        * b11:b0       - seq_no
+        * b12          - A-MSDU?
+        * b15:b13      - META_DATA_VERSION 0 - 7
+        */
+       __le16 info2;
+       __le16 info3;
+} __packed;
+
+static inline u8 wmi_data_hdr_get_up(struct wmi_data_hdr *dhdr)
+{
+       return (dhdr->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK;
+}
+
+static inline void wmi_data_hdr_set_up(struct wmi_data_hdr *dhdr,
+                                      u8 usr_pri)
+{
+       dhdr->info &= ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT);
+       dhdr->info |= usr_pri << WMI_DATA_HDR_UP_SHIFT;
+}
+
+static inline u8 wmi_data_hdr_get_dot11(struct wmi_data_hdr *dhdr)
+{
+       u8 data_type;
+
+       data_type = (dhdr->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) &
+                                  WMI_DATA_HDR_DATA_TYPE_MASK;
+       return (data_type == WMI_DATA_HDR_DATA_TYPE_802_11);
+}
+
+static inline u16 wmi_data_hdr_get_seqno(struct wmi_data_hdr *dhdr)
+{
+       return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_SEQNO_SHIFT) &
+                               WMI_DATA_HDR_SEQNO_MASK;
+}
+
+static inline u8 wmi_data_hdr_is_amsdu(struct wmi_data_hdr *dhdr)
+{
+       return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_AMSDU_SHIFT) &
+                              WMI_DATA_HDR_AMSDU_MASK;
+}
+
+static inline u8 wmi_data_hdr_get_meta(struct wmi_data_hdr *dhdr)
+{
+       return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
+                              WMI_DATA_HDR_META_MASK;
+}
+
+/* Tx meta version definitions */
+#define WMI_MAX_TX_META_SZ     12
+#define WMI_META_VERSION_1     0x01
+#define WMI_META_VERSION_2     0x02
+
+struct wmi_tx_meta_v1 {
+       /* packet ID to identify the tx request */
+       u8 pkt_id;
+
+       /* rate policy to be used for the tx of this frame */
+       u8 rate_plcy_id;
+} __packed;
+
+struct wmi_tx_meta_v2 {
+       /*
+        * Offset from start of the WMI header for csum calculation to
+        * begin.
+        */
+       u8 csum_start;
+
+       /* offset from start of WMI header where final csum goes */
+       u8 csum_dest;
+
+       /* no of bytes over which csum is calculated */
+       u8 csum_flags;
+} __packed;
+
+struct wmi_rx_meta_v1 {
+       u8 status;
+
+       /* rate index mapped to rate at which this packet was received. */
+       u8 rix;
+
+       /* rssi of packet */
+       u8 rssi;
+
+       /* rf channel during packet reception */
+       u8 channel;
+
+       __le16 flags;
+} __packed;
+
+struct wmi_rx_meta_v2 {
+       __le16 csum;
+
+       /* bit 0 set -partial csum valid bit 1 set -test mode */
+       u8 csum_flags;
+} __packed;
+
+/* Control Path */
+struct wmi_cmd_hdr {
+       __le16 cmd_id;
+
+       /* info1 - 16 bits
+        * b03:b00 - id
+        * b15:b04 - unused */
+       __le16 info1;
+
+       /* for alignment */
+       __le16 reserved;
+} __packed;
+
+/* List of WMI commands */
+enum wmi_cmd_id {
+       WMI_CONNECT_CMDID = 0x0001,
+       WMI_RECONNECT_CMDID,
+       WMI_DISCONNECT_CMDID,
+       WMI_SYNCHRONIZE_CMDID,
+       WMI_CREATE_PSTREAM_CMDID,
+       WMI_DELETE_PSTREAM_CMDID,
+       WMI_START_SCAN_CMDID,
+       WMI_SET_SCAN_PARAMS_CMDID,
+       WMI_SET_BSS_FILTER_CMDID,
+       WMI_SET_PROBED_SSID_CMDID,      /* 10 */
+       WMI_SET_LISTEN_INT_CMDID,
+       WMI_SET_BMISS_TIME_CMDID,
+       WMI_SET_DISC_TIMEOUT_CMDID,
+       WMI_GET_CHANNEL_LIST_CMDID,
+       WMI_SET_BEACON_INT_CMDID,
+       WMI_GET_STATISTICS_CMDID,
+       WMI_SET_CHANNEL_PARAMS_CMDID,
+       WMI_SET_POWER_MODE_CMDID,
+       WMI_SET_IBSS_PM_CAPS_CMDID,
+       WMI_SET_POWER_PARAMS_CMDID,     /* 20 */
+       WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
+       WMI_ADD_CIPHER_KEY_CMDID,
+       WMI_DELETE_CIPHER_KEY_CMDID,
+       WMI_ADD_KRK_CMDID,
+       WMI_DELETE_KRK_CMDID,
+       WMI_SET_PMKID_CMDID,
+       WMI_SET_TX_PWR_CMDID,
+       WMI_GET_TX_PWR_CMDID,
+       WMI_SET_ASSOC_INFO_CMDID,
+       WMI_ADD_BAD_AP_CMDID,           /* 30 */
+       WMI_DELETE_BAD_AP_CMDID,
+       WMI_SET_TKIP_COUNTERMEASURES_CMDID,
+       WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+       WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
+       WMI_SET_ACCESS_PARAMS_CMDID,
+       WMI_SET_RETRY_LIMITS_CMDID,
+       WMI_SET_OPT_MODE_CMDID,
+       WMI_OPT_TX_FRAME_CMDID,
+       WMI_SET_VOICE_PKT_SIZE_CMDID,
+       WMI_SET_MAX_SP_LEN_CMDID,       /* 40 */
+       WMI_SET_ROAM_CTRL_CMDID,
+       WMI_GET_ROAM_TBL_CMDID,
+       WMI_GET_ROAM_DATA_CMDID,
+       WMI_ENABLE_RM_CMDID,
+       WMI_SET_MAX_OFFHOME_DURATION_CMDID,
+       WMI_EXTENSION_CMDID,    /* Non-wireless extensions */
+       WMI_SNR_THRESHOLD_PARAMS_CMDID,
+       WMI_LQ_THRESHOLD_PARAMS_CMDID,
+       WMI_SET_LPREAMBLE_CMDID,
+       WMI_SET_RTS_CMDID,              /* 50 */
+       WMI_CLR_RSSI_SNR_CMDID,
+       WMI_SET_FIXRATES_CMDID,
+       WMI_GET_FIXRATES_CMDID,
+       WMI_SET_AUTH_MODE_CMDID,
+       WMI_SET_REASSOC_MODE_CMDID,
+       WMI_SET_WMM_CMDID,
+       WMI_SET_WMM_TXOP_CMDID,
+       WMI_TEST_CMDID,
+
+       /* COEX AR6002 only */
+       WMI_SET_BT_STATUS_CMDID,
+       WMI_SET_BT_PARAMS_CMDID,        /* 60 */
+
+       WMI_SET_KEEPALIVE_CMDID,
+       WMI_GET_KEEPALIVE_CMDID,
+       WMI_SET_APPIE_CMDID,
+       WMI_GET_APPIE_CMDID,
+       WMI_SET_WSC_STATUS_CMDID,
+
+       /* Wake on Wireless */
+       WMI_SET_HOST_SLEEP_MODE_CMDID,
+       WMI_SET_WOW_MODE_CMDID,
+       WMI_GET_WOW_LIST_CMDID,
+       WMI_ADD_WOW_PATTERN_CMDID,
+       WMI_DEL_WOW_PATTERN_CMDID,      /* 70 */
+
+       WMI_SET_FRAMERATES_CMDID,
+       WMI_SET_AP_PS_CMDID,
+       WMI_SET_QOS_SUPP_CMDID,
+
+       /* WMI_THIN_RESERVED_... mark the start and end
+        * values for WMI_THIN_RESERVED command IDs. These
+        * command IDs can be found in wmi_thin.h */
+       WMI_THIN_RESERVED_START = 0x8000,
+       WMI_THIN_RESERVED_END = 0x8fff,
+
+       /* Developer commands starts at 0xF000 */
+       WMI_SET_BITRATE_CMDID = 0xF000,
+       WMI_GET_BITRATE_CMDID,
+       WMI_SET_WHALPARAM_CMDID,
+       WMI_SET_MAC_ADDRESS_CMDID,
+       WMI_SET_AKMP_PARAMS_CMDID,
+       WMI_SET_PMKID_LIST_CMDID,
+       WMI_GET_PMKID_LIST_CMDID,
+       WMI_ABORT_SCAN_CMDID,
+       WMI_SET_TARGET_EVENT_REPORT_CMDID,
+
+       /* Unused */
+       WMI_UNUSED1,
+       WMI_UNUSED2,
+
+       /* AP mode commands */
+       WMI_AP_HIDDEN_SSID_CMDID,
+       WMI_AP_SET_NUM_STA_CMDID,
+       WMI_AP_ACL_POLICY_CMDID,
+       WMI_AP_ACL_MAC_LIST_CMDID,
+       WMI_AP_CONFIG_COMMIT_CMDID,
+       WMI_AP_SET_MLME_CMDID,
+       WMI_AP_SET_PVB_CMDID,
+       WMI_AP_CONN_INACT_CMDID,
+       WMI_AP_PROT_SCAN_TIME_CMDID,
+       WMI_AP_SET_COUNTRY_CMDID,
+       WMI_AP_SET_DTIM_CMDID,
+       WMI_AP_MODE_STAT_CMDID,
+
+       WMI_SET_IP_CMDID,
+       WMI_SET_PARAMS_CMDID,
+       WMI_SET_MCAST_FILTER_CMDID,
+       WMI_DEL_MCAST_FILTER_CMDID,
+
+       WMI_ALLOW_AGGR_CMDID,
+       WMI_ADDBA_REQ_CMDID,
+       WMI_DELBA_REQ_CMDID,
+       WMI_SET_HT_CAP_CMDID,
+       WMI_SET_HT_OP_CMDID,
+       WMI_SET_TX_SELECT_RATES_CMDID,
+       WMI_SET_TX_SGI_PARAM_CMDID,
+       WMI_SET_RATE_POLICY_CMDID,
+
+       WMI_HCI_CMD_CMDID,
+       WMI_RX_FRAME_FORMAT_CMDID,
+       WMI_SET_THIN_MODE_CMDID,
+       WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
+
+       WMI_AP_SET_11BG_RATESET_CMDID,
+       WMI_SET_PMK_CMDID,
+       WMI_MCAST_FILTER_CMDID,
+
+       /* COEX CMDID AR6003 */
+       WMI_SET_BTCOEX_FE_ANT_CMDID,
+       WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
+       WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
+       WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
+       WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
+       WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
+       WMI_SET_BTCOEX_DEBUG_CMDID,
+       WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
+       WMI_GET_BTCOEX_STATS_CMDID,
+       WMI_GET_BTCOEX_CONFIG_CMDID,
+
+       WMI_SET_DFS_ENABLE_CMDID,       /* F034 */
+       WMI_SET_DFS_MINRSSITHRESH_CMDID,
+       WMI_SET_DFS_MAXPULSEDUR_CMDID,
+       WMI_DFS_RADAR_DETECTED_CMDID,
+
+       /* P2P commands */
+       WMI_P2P_SET_CONFIG_CMDID,       /* F038 */
+       WMI_WPS_SET_CONFIG_CMDID,
+       WMI_SET_REQ_DEV_ATTR_CMDID,
+       WMI_P2P_FIND_CMDID,
+       WMI_P2P_STOP_FIND_CMDID,
+       WMI_P2P_GO_NEG_START_CMDID,
+       WMI_P2P_LISTEN_CMDID,
+
+       WMI_CONFIG_TX_MAC_RULES_CMDID,  /* F040 */
+       WMI_SET_PROMISCUOUS_MODE_CMDID,
+       WMI_RX_FRAME_FILTER_CMDID,
+       WMI_SET_CHANNEL_CMDID,
+
+       /* WAC commands */
+       WMI_ENABLE_WAC_CMDID,
+       WMI_WAC_SCAN_REPLY_CMDID,
+       WMI_WAC_CTRL_REQ_CMDID,
+       WMI_SET_DIV_PARAMS_CMDID,
+
+       WMI_GET_PMK_CMDID,
+       WMI_SET_PASSPHRASE_CMDID,
+       WMI_SEND_ASSOC_RES_CMDID,
+       WMI_SET_ASSOC_REQ_RELAY_CMDID,
+       WMI_GET_RFKILL_MODE_CMDID,
+
+       /* ACS command, consists of sub-commands */
+       WMI_ACS_CTRL_CMDID,
+
+       /* Ultra low power store / recall commands */
+       WMI_STORERECALL_CONFIGURE_CMDID,
+       WMI_STORERECALL_RECALL_CMDID,
+       WMI_STORERECALL_HOST_READY_CMDID,
+       WMI_FORCE_TARGET_ASSERT_CMDID,
+       WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
+};
+
+/* WMI_CONNECT_CMDID  */
+enum network_type {
+       INFRA_NETWORK = 0x01,
+       ADHOC_NETWORK = 0x02,
+       ADHOC_CREATOR = 0x04,
+       AP_NETWORK = 0x10,
+};
+
+enum dot11_auth_mode {
+       OPEN_AUTH = 0x01,
+       SHARED_AUTH = 0x02,
+
+       /* different from IEEE_AUTH_MODE definitions */
+       LEAP_AUTH = 0x04,
+};
+
+enum {
+       AUTH_IDLE,
+       AUTH_OPEN_IN_PROGRESS,
+};
+
+enum auth_mode {
+       NONE_AUTH = 0x01,
+       WPA_AUTH = 0x02,
+       WPA2_AUTH = 0x04,
+       WPA_PSK_AUTH = 0x08,
+       WPA2_PSK_AUTH = 0x10,
+       WPA_AUTH_CCKM = 0x20,
+       WPA2_AUTH_CCKM = 0x40,
+};
+
+#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
+#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
+
+#define WMI_MIN_KEY_INDEX   0
+#define WMI_MAX_KEY_INDEX   3
+
+#define WMI_MAX_KEY_LEN     32
+
+/*
+ * NB: these values are ordered carefully; there are lots of
+ * of implications in any reordering.  In particular beware
+ * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
+ */
+#define ATH6KL_CIPHER_WEP            0
+#define ATH6KL_CIPHER_TKIP           1
+#define ATH6KL_CIPHER_AES_OCB        2
+#define ATH6KL_CIPHER_AES_CCM        3
+#define ATH6KL_CIPHER_CKIP           5
+#define ATH6KL_CIPHER_CCKM_KRK       6
+#define ATH6KL_CIPHER_NONE           7 /* pseudo value */
+
+/*
+ * 802.11 rate set.
+ */
+#define ATH6KL_RATE_MAXSIZE  15        /* max rates we'll handle */
+
+#define ATH_OUI_TYPE            0x01
+#define WPA_OUI_TYPE            0x01
+#define WMM_PARAM_OUI_SUBTYPE   0x01
+#define WMM_OUI_TYPE            0x02
+#define WSC_OUT_TYPE            0x04
+
+enum wmi_connect_ctrl_flags_bits {
+       CONNECT_ASSOC_POLICY_USER = 0x0001,
+       CONNECT_SEND_REASSOC = 0x0002,
+       CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
+       CONNECT_PROFILE_MATCH_DONE = 0x0008,
+       CONNECT_IGNORE_AAC_BEACON = 0x0010,
+       CONNECT_CSA_FOLLOW_BSS = 0x0020,
+       CONNECT_DO_WPA_OFFLOAD = 0x0040,
+       CONNECT_DO_NOT_DEAUTH = 0x0080,
+};
+
+struct wmi_connect_cmd {
+       u8 nw_type;
+       u8 dot11_auth_mode;
+       u8 auth_mode;
+       u8 prwise_crypto_type;
+       u8 prwise_crypto_len;
+       u8 grp_crypto_type;
+       u8 grp_crypto_len;
+       u8 ssid_len;
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+       __le16 ch;
+       u8 bssid[ETH_ALEN];
+       __le32 ctrl_flags;
+} __packed;
+
+/* WMI_RECONNECT_CMDID */
+struct wmi_reconnect_cmd {
+       /* channel hint */
+       __le16 channel;
+
+       /* mandatory if set */
+       u8 bssid[ETH_ALEN];
+} __packed;
+
+/* WMI_ADD_CIPHER_KEY_CMDID */
+enum key_usage {
+       PAIRWISE_USAGE = 0x00,
+       GROUP_USAGE = 0x01,
+
+       /* default Tx Key - static WEP only */
+       TX_USAGE = 0x02,
+};
+
+/*
+ * Bit Flag
+ * Bit 0 - Initialise TSC - default is Initialize
+ */
+#define KEY_OP_INIT_TSC     0x01
+#define KEY_OP_INIT_RSC     0x02
+
+/* default initialise the TSC & RSC */
+#define KEY_OP_INIT_VAL     0x03
+#define KEY_OP_VALID_MASK   0x03
+
+struct wmi_add_cipher_key_cmd {
+       u8 key_index;
+       u8 key_type;
+
+       /* enum key_usage */
+       u8 key_usage;
+
+       u8 key_len;
+
+       /* key replay sequence counter */
+       u8 key_rsc[8];
+
+       u8 key[WLAN_MAX_KEY_LEN];
+
+       /* additional key control info */
+       u8 key_op_ctrl;
+
+       u8 key_mac_addr[ETH_ALEN];
+} __packed;
+
+/* WMI_DELETE_CIPHER_KEY_CMDID */
+struct wmi_delete_cipher_key_cmd {
+       u8 key_index;
+} __packed;
+
+#define WMI_KRK_LEN     16
+
+/* WMI_ADD_KRK_CMDID */
+struct wmi_add_krk_cmd {
+       u8 krk[WMI_KRK_LEN];
+} __packed;
+
+/* WMI_SETPMKID_CMDID */
+
+#define WMI_PMKID_LEN 16
+
+enum pmkid_enable_flg {
+       PMKID_DISABLE = 0,
+       PMKID_ENABLE = 1,
+};
+
+struct wmi_setpmkid_cmd {
+       u8 bssid[ETH_ALEN];
+
+       /* enum pmkid_enable_flg */
+       u8 enable;
+
+       u8 pmkid[WMI_PMKID_LEN];
+} __packed;
+
+/* WMI_START_SCAN_CMD */
+enum wmi_scan_type {
+       WMI_LONG_SCAN = 0,
+       WMI_SHORT_SCAN = 1,
+};
+
+struct wmi_start_scan_cmd {
+       __le32 force_fg_scan;
+
+       /* for legacy cisco AP compatibility */
+       __le32 is_legacy;
+
+       /* max duration in the home channel(msec) */
+       __le32 home_dwell_time;
+
+       /* time interval between scans (msec) */
+       __le32 force_scan_intvl;
+
+       /* enum wmi_scan_type */
+       u8 scan_type;
+
+       /* how many channels follow */
+       u8 num_ch;
+
+       /* channels in Mhz */
+       __le16 ch_list[1];
+} __packed;
+
+/* WMI_SET_SCAN_PARAMS_CMDID */
+#define WMI_SHORTSCANRATIO_DEFAULT      3
+
+/*
+ *  Warning: scan control flag value of 0xFF is used to disable
+ *  all flags in WMI_SCAN_PARAMS_CMD. Do not add any more
+ *  flags here
+ */
+enum wmi_scan_ctrl_flags_bits {
+
+       /* set if can scan in the connect cmd */
+       CONNECT_SCAN_CTRL_FLAGS = 0x01,
+
+       /* set if scan for the SSID it is already connected to */
+       SCAN_CONNECTED_CTRL_FLAGS = 0x02,
+
+       /* set if enable active scan */
+       ACTIVE_SCAN_CTRL_FLAGS = 0x04,
+
+       /* set if enable roam scan when bmiss and lowrssi */
+       ROAM_SCAN_CTRL_FLAGS = 0x08,
+
+       /* set if follows customer BSSINFO reporting rule */
+       REPORT_BSSINFO_CTRL_FLAGS = 0x10,
+
+       /* if disabled, target doesn't scan after a disconnect event  */
+       ENABLE_AUTO_CTRL_FLAGS = 0x20,
+
+       /*
+        * Scan complete event with canceled status will be generated when
+        * a scan is prempted before it gets completed.
+        */
+       ENABLE_SCAN_ABORT_EVENT = 0x40
+};
+
+#define DEFAULT_SCAN_CTRL_FLAGS                        \
+       (CONNECT_SCAN_CTRL_FLAGS |              \
+        SCAN_CONNECTED_CTRL_FLAGS |            \
+        ACTIVE_SCAN_CTRL_FLAGS |               \
+        ROAM_SCAN_CTRL_FLAGS |                 \
+        ENABLE_AUTO_CTRL_FLAGS)
+
+struct wmi_scan_params_cmd {
+         /* sec */
+       __le16 fg_start_period;
+
+       /* sec */
+       __le16 fg_end_period;
+
+       /* sec */
+       __le16 bg_period;
+
+       /* msec */
+       __le16 maxact_chdwell_time;
+
+       /* msec */
+       __le16 pas_chdwell_time;
+
+         /* how many shorts scan for one long */
+       u8 short_scan_ratio;
+
+       u8 scan_ctrl_flags;
+
+       /* msec */
+       __le16 minact_chdwell_time;
+
+       /* max active scans per ssid */
+       __le16 maxact_scan_per_ssid;
+
+       /* msecs */
+       __le32 max_dfsch_act_time;
+} __packed;
+
+/* WMI_SET_BSS_FILTER_CMDID */
+enum wmi_bss_filter {
+       /* no beacons forwarded */
+       NONE_BSS_FILTER = 0x0,
+
+       /* all beacons forwarded */
+       ALL_BSS_FILTER,
+
+       /* only beacons matching profile */
+       PROFILE_FILTER,
+
+       /* all but beacons matching profile */
+       ALL_BUT_PROFILE_FILTER,
+
+       /* only beacons matching current BSS */
+       CURRENT_BSS_FILTER,
+
+       /* all but beacons matching BSS */
+       ALL_BUT_BSS_FILTER,
+
+       /* beacons matching probed ssid */
+       PROBED_SSID_FILTER,
+
+       /* marker only */
+       LAST_BSS_FILTER,
+};
+
+struct wmi_bss_filter_cmd {
+       /* see, enum wmi_bss_filter */
+       u8 bss_filter;
+
+       /* for alignment */
+       u8 reserved1;
+
+       /* for alignment */
+       __le16 reserved2;
+
+       __le32 ie_mask;
+} __packed;
+
+/* WMI_SET_PROBED_SSID_CMDID */
+#define MAX_PROBED_SSID_INDEX   9
+
+enum wmi_ssid_flag {
+       /* disables entry */
+       DISABLE_SSID_FLAG = 0,
+
+       /* probes specified ssid */
+       SPECIFIC_SSID_FLAG = 0x01,
+
+       /* probes for any ssid */
+       ANY_SSID_FLAG = 0x02,
+};
+
+struct wmi_probed_ssid_cmd {
+       /* 0 to MAX_PROBED_SSID_INDEX */
+       u8 entry_index;
+
+       /* see, enum wmi_ssid_flg */
+       u8 flag;
+
+       u8 ssid_len;
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+} __packed;
+
+/*
+ * WMI_SET_LISTEN_INT_CMDID
+ * The Listen interval is between 15 and 3000 TUs
+ */
+struct wmi_listen_int_cmd {
+       __le16 listen_intvl;
+       __le16 num_beacons;
+} __packed;
+
+/* WMI_SET_POWER_MODE_CMDID */
+enum wmi_power_mode {
+       REC_POWER = 0x01,
+       MAX_PERF_POWER,
+};
+
+struct wmi_power_mode_cmd {
+       /* see, enum wmi_power_mode */
+       u8 pwr_mode;
+} __packed;
+
+/*
+ * Policy to determnine whether power save failure event should be sent to
+ * host during scanning
+ */
+enum power_save_fail_event_policy {
+       SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
+       IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
+};
+
+struct wmi_power_params_cmd {
+       /* msec */
+       __le16 idle_period;
+
+       __le16 pspoll_number;
+       __le16 dtim_policy;
+       __le16 tx_wakeup_policy;
+       __le16 num_tx_to_wakeup;
+       __le16 ps_fail_event_policy;
+} __packed;
+
+/* WMI_SET_DISC_TIMEOUT_CMDID */
+struct wmi_disc_timeout_cmd {
+       /* seconds */
+       u8 discon_timeout;
+} __packed;
+
+enum dir_type {
+       UPLINK_TRAFFIC = 0,
+       DNLINK_TRAFFIC = 1,
+       BIDIR_TRAFFIC = 2,
+};
+
+enum voiceps_cap_type {
+       DISABLE_FOR_THIS_AC = 0,
+       ENABLE_FOR_THIS_AC = 1,
+       ENABLE_FOR_ALL_AC = 2,
+};
+
+enum traffic_type {
+       TRAFFIC_TYPE_APERIODIC = 0,
+       TRAFFIC_TYPE_PERIODIC = 1,
+};
+
+/* WMI_SYNCHRONIZE_CMDID */
+struct wmi_sync_cmd {
+       u8 data_sync_map;
+} __packed;
+
+/* WMI_CREATE_PSTREAM_CMDID */
+struct wmi_create_pstream_cmd {
+       /* msec */
+       __le32 min_service_int;
+
+       /* msec */
+       __le32 max_service_int;
+
+       /* msec */
+       __le32 inactivity_int;
+
+       /* msec */
+       __le32 suspension_int;
+
+       __le32 service_start_time;
+
+       /* in bps */
+       __le32 min_data_rate;
+
+       /* in bps */
+       __le32 mean_data_rate;
+
+       /* in bps */
+       __le32 peak_data_rate;
+
+       __le32 max_burst_size;
+       __le32 delay_bound;
+
+       /* in bps */
+       __le32 min_phy_rate;
+
+       __le32 sba;
+       __le32 medium_time;
+
+       /* in octects */
+       __le16 nominal_msdu;
+
+       /* in octects */
+       __le16 max_msdu;
+
+       u8 traffic_class;
+
+       /* see, enum dir_type */
+       u8 traffic_direc;
+
+       u8 rx_queue_num;
+
+       /* see, enum traffic_type */
+       u8 traffic_type;
+
+       /* see, enum voiceps_cap_type */
+       u8 voice_psc_cap;
+       u8 tsid;
+
+       /* 802.1D user priority */
+       u8 user_pri;
+
+       /* nominal phy rate */
+       u8 nominal_phy;
+} __packed;
+
+/* WMI_DELETE_PSTREAM_CMDID */
+struct wmi_delete_pstream_cmd {
+       u8 tx_queue_num;
+       u8 rx_queue_num;
+       u8 traffic_direc;
+       u8 traffic_class;
+       u8 tsid;
+} __packed;
+
+/* WMI_SET_CHANNEL_PARAMS_CMDID */
+enum wmi_phy_mode {
+       WMI_11A_MODE = 0x1,
+       WMI_11G_MODE = 0x2,
+       WMI_11AG_MODE = 0x3,
+       WMI_11B_MODE = 0x4,
+       WMI_11GONLY_MODE = 0x5,
+};
+
+#define WMI_MAX_CHANNELS        32
+
+/*
+ *  WMI_RSSI_THRESHOLD_PARAMS_CMDID
+ *  Setting the polltime to 0 would disable polling. Threshold values are
+ *  in the ascending order, and should agree to:
+ *  (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
+ *   < highThreshold_upperVal)
+ */
+
+struct wmi_rssi_threshold_params_cmd {
+       /* polling time as a factor of LI */
+       __le32 poll_time;
+
+       /* lowest of upper */
+       a_sle16 thresh_above1_val;
+
+       a_sle16 thresh_above2_val;
+       a_sle16 thresh_above3_val;
+       a_sle16 thresh_above4_val;
+       a_sle16 thresh_above5_val;
+
+       /* highest of upper */
+       a_sle16 thresh_above6_val;
+
+       /* lowest of bellow */
+       a_sle16 thresh_below1_val;
+
+       a_sle16 thresh_below2_val;
+       a_sle16 thresh_below3_val;
+       a_sle16 thresh_below4_val;
+       a_sle16 thresh_below5_val;
+
+       /* highest of bellow */
+       a_sle16 thresh_below6_val;
+
+       /* "alpha" */
+       u8 weight;
+
+       u8 reserved[3];
+} __packed;
+
+/*
+ *  WMI_SNR_THRESHOLD_PARAMS_CMDID
+ *  Setting the polltime to 0 would disable polling.
+ */
+
+struct wmi_snr_threshold_params_cmd {
+       /* polling time as a factor of LI */
+       __le32 poll_time;
+
+       /* "alpha" */
+       u8 weight;
+
+       /* lowest of uppper */
+       u8 thresh_above1_val;
+
+       u8 thresh_above2_val;
+       u8 thresh_above3_val;
+
+       /* highest of upper */
+       u8 thresh_above4_val;
+
+       /* lowest of bellow */
+       u8 thresh_below1_val;
+
+       u8 thresh_below2_val;
+       u8 thresh_below3_val;
+
+       /* highest of bellow */
+       u8 thresh_below4_val;
+
+       u8 reserved[3];
+} __packed;
+
+enum wmi_preamble_policy {
+       WMI_IGNORE_BARKER_IN_ERP = 0,
+       WMI_DONOT_IGNORE_BARKER_IN_ERP
+};
+
+struct wmi_set_lpreamble_cmd {
+       u8 status;
+       u8 preamble_policy;
+} __packed;
+
+struct wmi_set_rts_cmd {
+       __le16 threshold;
+} __packed;
+
+/* WMI_SET_TX_PWR_CMDID */
+struct wmi_set_tx_pwr_cmd {
+       /* in dbM units */
+       u8 dbM;
+} __packed;
+
+struct wmi_tx_pwr_reply {
+       /* in dbM units */
+       u8 dbM;
+} __packed;
+
+struct wmi_report_sleep_state_event {
+       __le32 sleep_state;
+};
+
+enum wmi_report_sleep_status {
+       WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP = 0,
+       WMI_REPORT_SLEEP_STATUS_IS_AWAKE
+};
+enum target_event_report_config {
+       /* default */
+       DISCONN_EVT_IN_RECONN = 0,
+
+       NO_DISCONN_EVT_IN_RECONN
+};
+
+/* Command Replies */
+
+/* WMI_GET_CHANNEL_LIST_CMDID reply */
+struct wmi_channel_list_reply {
+       u8 reserved;
+
+       /* number of channels in reply */
+       u8 num_ch;
+
+       /* channel in Mhz */
+       __le16 ch_list[1];
+} __packed;
+
+/* List of Events (target to host) */
+enum wmi_event_id {
+       WMI_READY_EVENTID = 0x1001,
+       WMI_CONNECT_EVENTID,
+       WMI_DISCONNECT_EVENTID,
+       WMI_BSSINFO_EVENTID,
+       WMI_CMDERROR_EVENTID,
+       WMI_REGDOMAIN_EVENTID,
+       WMI_PSTREAM_TIMEOUT_EVENTID,
+       WMI_NEIGHBOR_REPORT_EVENTID,
+       WMI_TKIP_MICERR_EVENTID,
+       WMI_SCAN_COMPLETE_EVENTID,      /* 0x100a */
+       WMI_REPORT_STATISTICS_EVENTID,
+       WMI_RSSI_THRESHOLD_EVENTID,
+       WMI_ERROR_REPORT_EVENTID,
+       WMI_OPT_RX_FRAME_EVENTID,
+       WMI_REPORT_ROAM_TBL_EVENTID,
+       WMI_EXTENSION_EVENTID,
+       WMI_CAC_EVENTID,
+       WMI_SNR_THRESHOLD_EVENTID,
+       WMI_LQ_THRESHOLD_EVENTID,
+       WMI_TX_RETRY_ERR_EVENTID,       /* 0x1014 */
+       WMI_REPORT_ROAM_DATA_EVENTID,
+       WMI_TEST_EVENTID,
+       WMI_APLIST_EVENTID,
+       WMI_GET_WOW_LIST_EVENTID,
+       WMI_GET_PMKID_LIST_EVENTID,
+       WMI_CHANNEL_CHANGE_EVENTID,
+       WMI_PEER_NODE_EVENTID,
+       WMI_PSPOLL_EVENTID,
+       WMI_DTIMEXPIRY_EVENTID,
+       WMI_WLAN_VERSION_EVENTID,
+       WMI_SET_PARAMS_REPLY_EVENTID,
+       WMI_ADDBA_REQ_EVENTID,          /*0x1020 */
+       WMI_ADDBA_RESP_EVENTID,
+       WMI_DELBA_REQ_EVENTID,
+       WMI_TX_COMPLETE_EVENTID,
+       WMI_HCI_EVENT_EVENTID,
+       WMI_ACL_DATA_EVENTID,
+       WMI_REPORT_SLEEP_STATE_EVENTID,
+       WMI_REPORT_BTCOEX_STATS_EVENTID,
+       WMI_REPORT_BTCOEX_CONFIG_EVENTID,
+       WMI_GET_PMK_EVENTID,
+
+       /* DFS Events */
+       WMI_DFS_HOST_ATTACH_EVENTID,
+       WMI_DFS_HOST_INIT_EVENTID,
+       WMI_DFS_RESET_DELAYLINES_EVENTID,
+       WMI_DFS_RESET_RADARQ_EVENTID,
+       WMI_DFS_RESET_AR_EVENTID,
+       WMI_DFS_RESET_ARQ_EVENTID,
+       WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
+       WMI_DFS_SET_BANGRADAR_EVENTID,
+       WMI_DFS_SET_DEBUGLEVEL_EVENTID,
+       WMI_DFS_PHYERR_EVENTID,
+
+       /* CCX Evants */
+       WMI_CCX_RM_STATUS_EVENTID,
+
+       /* P2P Events */
+       WMI_P2P_GO_NEG_RESULT_EVENTID,
+
+       WMI_WAC_SCAN_DONE_EVENTID,
+       WMI_WAC_REPORT_BSS_EVENTID,
+       WMI_WAC_START_WPS_EVENTID,
+       WMI_WAC_CTRL_REQ_REPLY_EVENTID,
+
+       /* RFKILL Events */
+       WMI_RFKILL_STATE_CHANGE_EVENTID,
+       WMI_RFKILL_GET_MODE_CMD_EVENTID,
+       WMI_THIN_RESERVED_START_EVENTID = 0x8000,
+
+       /*
+        * Events in this range are reserved for thinmode
+        * See wmi_thin.h for actual definitions
+        */
+       WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
+
+       WMI_SET_CHANNEL_EVENTID,
+       WMI_ASSOC_REQ_EVENTID,
+
+       /* Generic ACS event */
+       WMI_ACS_EVENTID,
+       WMI_REPORT_WMM_PARAMS_EVENTID
+};
+
+struct wmi_ready_event_2 {
+       __le32 sw_version;
+       __le32 abi_version;
+       u8 mac_addr[ETH_ALEN];
+       u8 phy_cap;
+} __packed;
+
+/* Connect Event */
+struct wmi_connect_event {
+       __le16 ch;
+       u8 bssid[ETH_ALEN];
+       __le16 listen_intvl;
+       __le16 beacon_intvl;
+       __le32 nw_type;
+       u8 beacon_ie_len;
+       u8 assoc_req_len;
+       u8 assoc_resp_len;
+       u8 assoc_info[1];
+} __packed;
+
+/* Disconnect Event */
+enum wmi_disconnect_reason {
+       NO_NETWORK_AVAIL = 0x01,
+
+       /* bmiss */
+       LOST_LINK = 0x02,
+
+       DISCONNECT_CMD = 0x03,
+       BSS_DISCONNECTED = 0x04,
+       AUTH_FAILED = 0x05,
+       ASSOC_FAILED = 0x06,
+       NO_RESOURCES_AVAIL = 0x07,
+       CSERV_DISCONNECT = 0x08,
+       INVALID_PROFILE = 0x0a,
+       DOT11H_CHANNEL_SWITCH = 0x0b,
+       PROFILE_MISMATCH = 0x0c,
+       CONNECTION_EVICTED = 0x0d,
+       IBSS_MERGE = 0xe,
+};
+
+struct wmi_disconnect_event {
+       /* reason code, see 802.11 spec. */
+       __le16 proto_reason_status;
+
+       /* set if known */
+       u8 bssid[ETH_ALEN];
+
+       /* see WMI_DISCONNECT_REASON */
+       u8 disconn_reason;
+
+       u8 assoc_resp_len;
+       u8 assoc_info[1];
+} __packed;
+
+/*
+ * BSS Info Event.
+ * Mechanism used to inform host of the presence and characteristic of
+ * wireless networks present.  Consists of bss info header followed by
+ * the beacon or probe-response frame body.  The 802.11 header is no included.
+ */
+enum wmi_bi_ftype {
+       BEACON_FTYPE = 0x1,
+       PROBERESP_FTYPE,
+       ACTION_MGMT_FTYPE,
+       PROBEREQ_FTYPE,
+};
+
+struct wmi_bss_info_hdr {
+       __le16 ch;
+
+       /* see, enum wmi_bi_ftype */
+       u8 frame_type;
+
+       u8 snr;
+       a_sle16 rssi;
+       u8 bssid[ETH_ALEN];
+       __le32 ie_mask;
+} __packed;
+
+/*
+ * BSS INFO HDR version 2.0
+ * With 6 bytes HTC header and 6 bytes of WMI header
+ * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
+ * header space.
+ * - Reduce the ie_mask to 2 bytes as only two bit flags are used
+ * - Remove rssi and compute it on the host. rssi = snr - 95
+ */
+struct wmi_bss_info_hdr2 {
+       __le16 ch;
+
+       /* see, enum wmi_bi_ftype */
+       u8 frame_type;
+
+       u8 snr;
+       u8 bssid[ETH_ALEN];
+       __le16 ie_mask;
+} __packed;
+
+/* Command Error Event */
+enum wmi_error_code {
+       INVALID_PARAM = 0x01,
+       ILLEGAL_STATE = 0x02,
+       INTERNAL_ERROR = 0x03,
+};
+
+struct wmi_cmd_error_event {
+       __le16 cmd_id;
+       u8 err_code;
+} __packed;
+
+struct wmi_pstream_timeout_event {
+       u8 tx_queue_num;
+       u8 rx_queue_num;
+       u8 traffic_direc;
+       u8 traffic_class;
+} __packed;
+
+/*
+ * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
+ * the host of BSS's it has found that matches the current profile.
+ * It can be used by the host to cache PMKs and/to initiate pre-authentication
+ * if the BSS supports it.  The first bssid is always the current associated
+ * BSS.
+ * The bssid and bssFlags information repeats according to the number
+ * or APs reported.
+ */
+enum wmi_bss_flags {
+       WMI_DEFAULT_BSS_FLAGS = 0x00,
+       WMI_PREAUTH_CAPABLE_BSS = 0x01,
+       WMI_PMKID_VALID_BSS = 0x02,
+};
+
+/* TKIP MIC Error Event */
+struct wmi_tkip_micerr_event {
+       u8 key_id;
+       u8 is_mcast;
+} __packed;
+
+/* WMI_SCAN_COMPLETE_EVENTID */
+struct wmi_scan_complete_event {
+       a_sle32 status;
+} __packed;
+
+#define MAX_OPT_DATA_LEN 1400
+
+/*
+ * Special frame receive Event.
+ * Mechanism used to inform host of the receiption of the special frames.
+ * Consists of special frame info header followed by special frame body.
+ * The 802.11 header is not included.
+ */
+struct wmi_opt_rx_info_hdr {
+       __le16 ch;
+       u8 frame_type;
+       s8 snr;
+       u8 src_addr[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+} __packed;
+
+/* Reporting statistic */
+struct tx_stats {
+       __le32 pkt;
+       __le32 byte;
+       __le32 ucast_pkt;
+       __le32 ucast_byte;
+       __le32 mcast_pkt;
+       __le32 mcast_byte;
+       __le32 bcast_pkt;
+       __le32 bcast_byte;
+       __le32 rts_success_cnt;
+       __le32 pkt_per_ac[4];
+       __le32 err_per_ac[4];
+
+       __le32 err;
+       __le32 fail_cnt;
+       __le32 retry_cnt;
+       __le32 mult_retry_cnt;
+       __le32 rts_fail_cnt;
+       a_sle32 ucast_rate;
+} __packed;
+
+struct rx_stats {
+       __le32 pkt;
+       __le32 byte;
+       __le32 ucast_pkt;
+       __le32 ucast_byte;
+       __le32 mcast_pkt;
+       __le32 mcast_byte;
+       __le32 bcast_pkt;
+       __le32 bcast_byte;
+       __le32 frgment_pkt;
+
+       __le32 err;
+       __le32 crc_err;
+       __le32 key_cache_miss;
+       __le32 decrypt_err;
+       __le32 dupl_frame;
+       a_sle32 ucast_rate;
+} __packed;
+
+struct tkip_ccmp_stats {
+       __le32 tkip_local_mic_fail;
+       __le32 tkip_cnter_measures_invoked;
+       __le32 tkip_replays;
+       __le32 tkip_fmt_err;
+       __le32 ccmp_fmt_err;
+       __le32 ccmp_replays;
+} __packed;
+
+struct pm_stats {
+       __le32 pwr_save_failure_cnt;
+       __le16 stop_tx_failure_cnt;
+       __le16 atim_tx_failure_cnt;
+       __le16 atim_rx_failure_cnt;
+       __le16 bcn_rx_failure_cnt;
+} __packed;
+
+struct cserv_stats {
+       __le32 cs_bmiss_cnt;
+       __le32 cs_low_rssi_cnt;
+       __le16 cs_connect_cnt;
+       __le16 cs_discon_cnt;
+       a_sle16 cs_ave_beacon_rssi;
+       __le16 cs_roam_count;
+       a_sle16 cs_rssi;
+       u8 cs_snr;
+       u8 cs_ave_beacon_snr;
+       u8 cs_last_roam_msec;
+} __packed;
+
+struct wlan_net_stats {
+       struct tx_stats tx;
+       struct rx_stats rx;
+       struct tkip_ccmp_stats tkip_ccmp_stats;
+} __packed;
+
+struct arp_stats {
+       __le32 arp_received;
+       __le32 arp_matched;
+       __le32 arp_replied;
+} __packed;
+
+struct wlan_wow_stats {
+       __le32 wow_pkt_dropped;
+       __le16 wow_evt_discarded;
+       u8 wow_host_pkt_wakeups;
+       u8 wow_host_evt_wakeups;
+} __packed;
+
+struct wmi_target_stats {
+       __le32 lq_val;
+       a_sle32 noise_floor_calib;
+       struct pm_stats pm_stats;
+       struct wlan_net_stats stats;
+       struct wlan_wow_stats wow_stats;
+       struct arp_stats arp_stats;
+       struct cserv_stats cserv_stats;
+} __packed;
+
+/*
+ * WMI_RSSI_THRESHOLD_EVENTID.
+ * Indicate the RSSI events to host. Events are indicated when we breach a
+ * thresold value.
+ */
+enum wmi_rssi_threshold_val {
+       WMI_RSSI_THRESHOLD1_ABOVE = 0,
+       WMI_RSSI_THRESHOLD2_ABOVE,
+       WMI_RSSI_THRESHOLD3_ABOVE,
+       WMI_RSSI_THRESHOLD4_ABOVE,
+       WMI_RSSI_THRESHOLD5_ABOVE,
+       WMI_RSSI_THRESHOLD6_ABOVE,
+       WMI_RSSI_THRESHOLD1_BELOW,
+       WMI_RSSI_THRESHOLD2_BELOW,
+       WMI_RSSI_THRESHOLD3_BELOW,
+       WMI_RSSI_THRESHOLD4_BELOW,
+       WMI_RSSI_THRESHOLD5_BELOW,
+       WMI_RSSI_THRESHOLD6_BELOW
+};
+
+struct wmi_rssi_threshold_event {
+       a_sle16 rssi;
+       u8 range;
+} __packed;
+
+enum wmi_snr_threshold_val {
+       WMI_SNR_THRESHOLD1_ABOVE = 1,
+       WMI_SNR_THRESHOLD1_BELOW,
+       WMI_SNR_THRESHOLD2_ABOVE,
+       WMI_SNR_THRESHOLD2_BELOW,
+       WMI_SNR_THRESHOLD3_ABOVE,
+       WMI_SNR_THRESHOLD3_BELOW,
+       WMI_SNR_THRESHOLD4_ABOVE,
+       WMI_SNR_THRESHOLD4_BELOW
+};
+
+struct wmi_snr_threshold_event {
+       /* see, enum wmi_snr_threshold_val */
+       u8 range;
+
+       u8 snr;
+} __packed;
+
+/* WMI_REPORT_ROAM_TBL_EVENTID */
+#define MAX_ROAM_TBL_CAND   5
+
+struct wmi_bss_roam_info {
+       a_sle32 roam_util;
+       u8 bssid[ETH_ALEN];
+       s8 rssi;
+       s8 rssidt;
+       s8 last_rssi;
+       s8 util;
+       s8 bias;
+
+       /* for alignment */
+       u8 reserved;
+} __packed;
+
+/* WMI_CAC_EVENTID */
+enum cac_indication {
+       CAC_INDICATION_ADMISSION = 0x00,
+       CAC_INDICATION_ADMISSION_RESP = 0x01,
+       CAC_INDICATION_DELETE = 0x02,
+       CAC_INDICATION_NO_RESP = 0x03,
+};
+
+#define WMM_TSPEC_IE_LEN   63
+
+struct wmi_cac_event {
+       u8 ac;
+       u8 cac_indication;
+       u8 status_code;
+       u8 tspec_suggestion[WMM_TSPEC_IE_LEN];
+} __packed;
+
+/* WMI_APLIST_EVENTID */
+
+enum aplist_ver {
+       APLIST_VER1 = 1,
+};
+
+struct wmi_ap_info_v1 {
+       u8 bssid[ETH_ALEN];
+       __le16 channel;
+} __packed;
+
+union wmi_ap_info {
+       struct wmi_ap_info_v1 ap_info_v1;
+} __packed;
+
+struct wmi_aplist_event {
+       u8 ap_list_ver;
+       u8 num_ap;
+       union wmi_ap_info ap_list[1];
+} __packed;
+
+/* Developer Commands */
+
+/*
+ * WMI_SET_BITRATE_CMDID
+ *
+ * Get bit rate cmd uses same definition as set bit rate cmd
+ */
+enum wmi_bit_rate {
+       RATE_AUTO = -1,
+       RATE_1Mb = 0,
+       RATE_2Mb = 1,
+       RATE_5_5Mb = 2,
+       RATE_11Mb = 3,
+       RATE_6Mb = 4,
+       RATE_9Mb = 5,
+       RATE_12Mb = 6,
+       RATE_18Mb = 7,
+       RATE_24Mb = 8,
+       RATE_36Mb = 9,
+       RATE_48Mb = 10,
+       RATE_54Mb = 11,
+       RATE_MCS_0_20 = 12,
+       RATE_MCS_1_20 = 13,
+       RATE_MCS_2_20 = 14,
+       RATE_MCS_3_20 = 15,
+       RATE_MCS_4_20 = 16,
+       RATE_MCS_5_20 = 17,
+       RATE_MCS_6_20 = 18,
+       RATE_MCS_7_20 = 19,
+       RATE_MCS_0_40 = 20,
+       RATE_MCS_1_40 = 21,
+       RATE_MCS_2_40 = 22,
+       RATE_MCS_3_40 = 23,
+       RATE_MCS_4_40 = 24,
+       RATE_MCS_5_40 = 25,
+       RATE_MCS_6_40 = 26,
+       RATE_MCS_7_40 = 27,
+};
+
+struct wmi_bit_rate_reply {
+       /* see, enum wmi_bit_rate */
+       s8 rate_index;
+} __packed;
+
+/*
+ * WMI_SET_FIXRATES_CMDID
+ *
+ * Get fix rates cmd uses same definition as set fix rates cmd
+ */
+struct wmi_fix_rates_reply {
+       /* see wmi_bit_rate */
+       __le32 fix_rate_mask;
+} __packed;
+
+enum roam_data_type {
+       /* get the roam time data */
+       ROAM_DATA_TIME = 1,
+};
+
+struct wmi_target_roam_time {
+       __le32 disassoc_time;
+       __le32 no_txrx_time;
+       __le32 assoc_time;
+       __le32 allow_txrx_time;
+       u8 disassoc_bssid[ETH_ALEN];
+       s8 disassoc_bss_rssi;
+       u8 assoc_bssid[ETH_ALEN];
+       s8 assoc_bss_rssi;
+} __packed;
+
+enum wmi_txop_cfg {
+       WMI_TXOP_DISABLED = 0,
+       WMI_TXOP_ENABLED
+};
+
+struct wmi_set_wmm_txop_cmd {
+       u8 txop_enable;
+} __packed;
+
+struct wmi_set_keepalive_cmd {
+       u8 keep_alive_intvl;
+} __packed;
+
+struct wmi_get_keepalive_cmd {
+       __le32 configured;
+       u8 keep_alive_intvl;
+} __packed;
+
+/* Notify the WSC registration status to the target */
+#define WSC_REG_ACTIVE     1
+#define WSC_REG_INACTIVE   0
+
+#define WOW_MAX_FILTER_LISTS    1
+#define WOW_MAX_FILTERS_PER_LIST 4
+#define WOW_PATTERN_SIZE        64
+#define WOW_MASK_SIZE           64
+
+#define MAC_MAX_FILTERS_PER_LIST 4
+
+struct wow_filter {
+       u8 wow_valid_filter;
+       u8 wow_filter_id;
+       u8 wow_filter_size;
+       u8 wow_filter_offset;
+       u8 wow_filter_mask[WOW_MASK_SIZE];
+       u8 wow_filter_pattern[WOW_PATTERN_SIZE];
+} __packed;
+
+#define MAX_IP_ADDRS  2
+
+struct wmi_set_ip_cmd {
+       /* IP in network byte order */
+       __le32 ips[MAX_IP_ADDRS];
+} __packed;
+
+/* WMI_GET_WOW_LIST_CMD reply  */
+struct wmi_get_wow_list_reply {
+       /* number of patterns in reply */
+       u8 num_filters;
+
+       /* this is filter # x of total num_filters */
+       u8 this_filter_num;
+
+       u8 wow_mode;
+       u8 host_mode;
+       struct wow_filter wow_filters[1];
+} __packed;
+
+/* WMI_SET_AKMP_PARAMS_CMD */
+
+struct wmi_pmkid {
+       u8 pmkid[WMI_PMKID_LEN];
+} __packed;
+
+/* WMI_GET_PMKID_LIST_CMD  Reply */
+struct wmi_pmkid_list_reply {
+       __le32 num_pmkid;
+       u8 bssid_list[ETH_ALEN][1];
+       struct wmi_pmkid pmkid_list[1];
+} __packed;
+
+/* WMI_ADDBA_REQ_EVENTID */
+struct wmi_addba_req_event {
+       u8 tid;
+       u8 win_sz;
+       __le16 st_seq_no;
+
+       /* f/w response for ADDBA Req; OK (0) or failure (!=0) */
+       u8 status;
+} __packed;
+
+/* WMI_ADDBA_RESP_EVENTID */
+struct wmi_addba_resp_event {
+       u8 tid;
+
+       /* OK (0), failure (!=0) */
+       u8 status;
+
+       /* three values: not supported(0), 3839, 8k */
+       __le16 amsdu_sz;
+} __packed;
+
+/* WMI_DELBA_EVENTID
+ * f/w received a DELBA for peer and processed it.
+ * Host is notified of this
+ */
+struct wmi_delba_event {
+       u8 tid;
+       u8 is_peer_initiator;
+       __le16 reason_code;
+} __packed;
+
+#define PEER_NODE_JOIN_EVENT           0x00
+#define PEER_NODE_LEAVE_EVENT          0x01
+#define PEER_FIRST_NODE_JOIN_EVENT     0x10
+#define PEER_LAST_NODE_LEAVE_EVENT     0x11
+
+struct wmi_peer_node_event {
+       u8 event_code;
+       u8 peer_mac_addr[ETH_ALEN];
+} __packed;
+
+/* Transmit complete event data structure(s) */
+
+/* version 1 of tx complete msg */
+struct tx_complete_msg_v1 {
+#define TX_COMPLETE_STATUS_SUCCESS 0
+#define TX_COMPLETE_STATUS_RETRIES 1
+#define TX_COMPLETE_STATUS_NOLINK  2
+#define TX_COMPLETE_STATUS_TIMEOUT 3
+#define TX_COMPLETE_STATUS_OTHER   4
+
+       u8 status;
+
+       /* packet ID to identify parent packet */
+       u8 pkt_id;
+
+       /* rate index on successful transmission */
+       u8 rate_idx;
+
+       /* number of ACK failures in tx attempt */
+       u8 ack_failures;
+} __packed;
+
+struct wmi_tx_complete_event {
+       /* no of tx comp msgs following this struct */
+       u8 num_msg;
+
+       /* length in bytes for each individual msg following this struct */
+       u8 msg_len;
+
+       /* version of tx complete msg data following this struct */
+       u8 msg_type;
+
+       /* individual messages follow this header */
+       u8 reserved;
+} __packed;
+
+/*
+ * ------- AP Mode definitions --------------
+ */
+
+/*
+ * !!! Warning !!!
+ * -Changing the following values needs compilation of both driver and firmware
+ */
+#define AP_MAX_NUM_STA          8
+
+/* Spl. AID used to set DTIM flag in the beacons */
+#define MCAST_AID               0xFF
+
+#define DEF_AP_COUNTRY_CODE     "US "
+
+/* Used with WMI_AP_SET_NUM_STA_CMDID */
+
+struct wmi_ap_set_pvb_cmd {
+       __le32 flag;
+       __le16 aid;
+} __packed;
+
+struct wmi_rx_frame_format_cmd {
+       /* version of meta data for rx packets <0 = default> (0-7 = valid) */
+       u8 meta_ver;
+
+       /*
+        * 1 == leave .11 header intact,
+        * 0 == replace .11 header with .3 <default>
+        */
+       u8 dot11_hdr;
+
+       /*
+        * 1 == defragmentation is performed by host,
+        * 0 == performed by target <default>
+        */
+       u8 defrag_on_host;
+
+       /* for alignment */
+       u8 reserved[1];
+} __packed;
+
+/* AP mode events */
+
+/* WMI_PS_POLL_EVENT */
+struct wmi_pspoll_event {
+       __le16 aid;
+} __packed;
+
+struct wmi_per_sta_stat {
+       __le32 tx_bytes;
+       __le32 tx_pkts;
+       __le32 tx_error;
+       __le32 tx_discard;
+       __le32 rx_bytes;
+       __le32 rx_pkts;
+       __le32 rx_error;
+       __le32 rx_discard;
+       __le32 aid;
+} __packed;
+
+struct wmi_ap_mode_stat {
+       __le32 action;
+       struct wmi_per_sta_stat sta[AP_MAX_NUM_STA + 1];
+} __packed;
+
+/* End of AP mode definitions */
+
+/* Extended WMI (WMIX)
+ *
+ * Extended WMIX commands are encapsulated in a WMI message with
+ * cmd=WMI_EXTENSION_CMD.
+ *
+ * Extended WMI commands are those that are needed during wireless
+ * operation, but which are not really wireless commands.  This allows,
+ * for instance, platform-specific commands.  Extended WMI commands are
+ * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
+ * Extended WMI events are similarly embedded in a WMI event message with
+ * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
+ */
+struct wmix_cmd_hdr {
+       __le32 cmd_id;
+} __packed;
+
+enum wmix_command_id {
+       WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
+       WMIX_DSETDATA_REPLY_CMDID,
+       WMIX_GPIO_OUTPUT_SET_CMDID,
+       WMIX_GPIO_INPUT_GET_CMDID,
+       WMIX_GPIO_REGISTER_SET_CMDID,
+       WMIX_GPIO_REGISTER_GET_CMDID,
+       WMIX_GPIO_INTR_ACK_CMDID,
+       WMIX_HB_CHALLENGE_RESP_CMDID,
+       WMIX_DBGLOG_CFG_MODULE_CMDID,
+       WMIX_PROF_CFG_CMDID,    /* 0x200a */
+       WMIX_PROF_ADDR_SET_CMDID,
+       WMIX_PROF_START_CMDID,
+       WMIX_PROF_STOP_CMDID,
+       WMIX_PROF_COUNT_GET_CMDID,
+};
+
+enum wmix_event_id {
+       WMIX_DSETOPENREQ_EVENTID = 0x3001,
+       WMIX_DSETCLOSE_EVENTID,
+       WMIX_DSETDATAREQ_EVENTID,
+       WMIX_GPIO_INTR_EVENTID,
+       WMIX_GPIO_DATA_EVENTID,
+       WMIX_GPIO_ACK_EVENTID,
+       WMIX_HB_CHALLENGE_RESP_EVENTID,
+       WMIX_DBGLOG_EVENTID,
+       WMIX_PROF_COUNT_EVENTID,
+};
+
+/*
+ * ------Error Detection support-------
+ */
+
+/*
+ * WMIX_HB_CHALLENGE_RESP_CMDID
+ * Heartbeat Challenge Response command
+ */
+struct wmix_hb_challenge_resp_cmd {
+       __le32 cookie;
+       __le32 source;
+} __packed;
+
+/* End of Extended WMI (WMIX) */
+
+enum wmi_sync_flag {
+       NO_SYNC_WMIFLAG = 0,
+
+       /* transmit all queued data before cmd */
+       SYNC_BEFORE_WMIFLAG,
+
+       /* any new data waits until cmd execs */
+       SYNC_AFTER_WMIFLAG,
+
+       SYNC_BOTH_WMIFLAG,
+
+       /* end marker */
+       END_WMIFLAG
+};
+
+enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
+void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
+int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
+int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
+                           u8 msg_type, bool more_data,
+                           enum wmi_data_hdr_data_type data_type,
+                           u8 meta_ver, void *tx_meta_info);
+
+int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
+int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
+int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
+int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
+                                      u32 layer2_priority, bool wmm_enabled,
+                                      u8 *ac);
+
+int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
+struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 *mac_addr);
+void ath6kl_wmi_node_free(struct wmi *wmi, const u8 *mac_addr);
+
+int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
+                       enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
+
+int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
+                          enum dot11_auth_mode dot11_auth_mode,
+                          enum auth_mode auth_mode,
+                          enum crypto_type pairwise_crypto,
+                          u8 pairwise_crypto_len,
+                          enum crypto_type group_crypto,
+                          u8 group_crypto_len, int ssid_len, u8 *ssid,
+                          u8 *bssid, u16 channel, u32 ctrl_flags);
+
+int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel);
+int ath6kl_wmi_disconnect_cmd(struct wmi *wmi);
+int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
+                            u32 force_fgscan, u32 is_legacy,
+                            u32 home_dwell_time, u32 force_scan_interval,
+                            s8 num_chan, u16 *ch_list);
+int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
+                             u16 fg_end_sec, u16 bg_sec,
+                             u16 minact_chdw_msec, u16 maxact_chdw_msec,
+                             u16 pas_chdw_msec, u8 short_scan_ratio,
+                             u8 scan_ctrl_flag, u32 max_dfsch_act_time,
+                             u16 maxact_scan_per_ssid);
+int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask);
+int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
+                             u8 ssid_len, u8 *ssid);
+int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
+                                 u16 listen_beacons);
+int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode);
+int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
+                           u16 ps_poll_num, u16 dtim_policy,
+                           u16 tx_wakup_policy, u16 num_tx_to_wakeup,
+                           u16 ps_fail_event_policy);
+int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout);
+int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
+                                 struct wmi_create_pstream_cmd *pstream);
+int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid);
+
+int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold);
+int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
+                                u8 preamble_policy);
+
+int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
+
+int ath6kl_wmi_get_stats_cmd(struct wmi *wmi);
+int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
+                         enum crypto_type key_type,
+                         u8 key_usage, u8 key_len,
+                         u8 *key_rsc, u8 *key_material,
+                         u8 key_op_ctrl, u8 *mac_addr,
+                         enum wmi_sync_flag sync_flag);
+int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk);
+int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index);
+int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
+                           const u8 *pmkid, bool set);
+int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM);
+int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
+
+int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
+int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
+
+s32 ath6kl_wmi_get_rate(s8 rate_index);
+
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
+
+struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 *ssid,
+                                     u32 ssid_len, bool is_wpa2,
+                                     bool match_ssid);
+
+void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss);
+
+/* AP mode */
+int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag);
+
+int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version,
+                                      bool rx_dot11_hdr, bool defrag_on_host);
+
+void *ath6kl_wmi_init(struct ath6kl *devt);
+void ath6kl_wmi_shutdown(struct wmi *wmi);
+
+#endif /* WMI_H */
index 0b36fcf8a280c66e43bb1888e1193fc414a10e02..85a54cd2b0831c4a5f24f93c2dccb1bd2f1e1a0f 100644 (file)
@@ -133,7 +133,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
                goto err_free_hw;
        }
 
-       ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops);
+       ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
        if (ret) {
                dev_err(&pdev->dev, "failed to initialize device\n");
                goto err_irq;
index 44d9d8d56490c8a5bbe1b1fac4bc74c364ce92c1..b54ab78fb092231f16dc8f33039bad8f6f1f0435 100644 (file)
@@ -303,17 +303,13 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
  * register as the other analog registers.  Hence the 9 writes.
  */
 static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
-                                        int restore,
-                                        int power_off)
+                                        bool power_off)
 {
        u8 i;
        u32 val;
 
-       if (ah->is_pciexpress != true || ah->aspm_enabled != true)
-               return;
-
        /* Nothing to do on restore for 11N */
-       if (!restore) {
+       if (!power_off /* !restore */) {
                if (AR_SREV_9280_20_OR_LATER(ah)) {
                        /*
                         * AR9280 2.0 or later chips use SerDes values from the
index 2339728a7306f521b3846fb8295afcc70dbef490..a0aadaddd0710691967564c59a01399245418634 100644 (file)
@@ -835,108 +835,108 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
 
 static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
        {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
-       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
-       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
-       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
-       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
-       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
-       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
-       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
-       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
-       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
-       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
-       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
-       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
-       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
-       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
-       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
-       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
-       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
-       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
-       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
-       {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
-       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
-       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
-       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
-       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
-       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
-       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
-       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
-       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
-       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
-       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
-       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
-       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
-       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
-       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
-       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
-       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
-       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
-       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
-       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
-       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
-       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
-       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
-       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
-       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
-       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
-       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
-       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
-       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
-       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
-       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
-       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
-       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
-       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+       {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+       {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+       {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+       {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+       {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
        {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
-       {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
-       {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
-       {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
-       {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
-       {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
-       {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
-       {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-       {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+       {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+       {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
        {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
-       {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
-       {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
        {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
-       {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-       {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-       {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-       {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-       {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-       {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
-       {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
-       {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
-       {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
 static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
index c34bef1bf2b08e29219fa03d692deeb88da45ea5..3b4ae07d69507fc4d1d8b756560624c165b7f66d 100644 (file)
@@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(int32_t x,
 static const struct ar9300_eeprom ar9300_default = {
        .eepromVersion = 2,
        .templateVersion = 2,
-       .macAddr = {1, 2, 3, 4, 5, 6},
+       .macAddr = {0, 2, 3, 4, 5, 6},
        .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        .baseEepHeader = {
@@ -3418,6 +3418,133 @@ static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
        return true;
 }
 
+#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size,
+                                   struct ar9300_modal_eep_header *modal_hdr)
+{
+       PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
+       PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
+       PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
+       PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
+       PR_EEP("Ant. Common Control2", le32_to_cpu(modal_hdr->antCtrlCommon2));
+       PR_EEP("Ant. Gain", modal_hdr->antennaGain);
+       PR_EEP("Switch Settle", modal_hdr->switchSettling);
+       PR_EEP("Chain0 xatten1DB", modal_hdr->xatten1DB[0]);
+       PR_EEP("Chain1 xatten1DB", modal_hdr->xatten1DB[1]);
+       PR_EEP("Chain2 xatten1DB", modal_hdr->xatten1DB[2]);
+       PR_EEP("Chain0 xatten1Margin", modal_hdr->xatten1Margin[0]);
+       PR_EEP("Chain1 xatten1Margin", modal_hdr->xatten1Margin[1]);
+       PR_EEP("Chain2 xatten1Margin", modal_hdr->xatten1Margin[2]);
+       PR_EEP("Temp Slope", modal_hdr->tempSlope);
+       PR_EEP("Volt Slope", modal_hdr->voltSlope);
+       PR_EEP("spur Channels0", modal_hdr->spurChans[0]);
+       PR_EEP("spur Channels1", modal_hdr->spurChans[1]);
+       PR_EEP("spur Channels2", modal_hdr->spurChans[2]);
+       PR_EEP("spur Channels3", modal_hdr->spurChans[3]);
+       PR_EEP("spur Channels4", modal_hdr->spurChans[4]);
+       PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
+       PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
+       PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
+       PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
+       PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
+       PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
+       PR_EEP("txClip", modal_hdr->txClip);
+       PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
+       PR_EEP("Chain0 ob", modal_hdr->ob[0]);
+       PR_EEP("Chain1 ob", modal_hdr->ob[1]);
+       PR_EEP("Chain2 ob", modal_hdr->ob[2]);
+
+       PR_EEP("Chain0 db_stage2", modal_hdr->db_stage2[0]);
+       PR_EEP("Chain1 db_stage2", modal_hdr->db_stage2[1]);
+       PR_EEP("Chain2 db_stage2", modal_hdr->db_stage2[2]);
+       PR_EEP("Chain0 db_stage3", modal_hdr->db_stage3[0]);
+       PR_EEP("Chain1 db_stage3", modal_hdr->db_stage3[1]);
+       PR_EEP("Chain2 db_stage3", modal_hdr->db_stage3[2]);
+       PR_EEP("Chain0 db_stage4", modal_hdr->db_stage4[0]);
+       PR_EEP("Chain1 db_stage4", modal_hdr->db_stage4[1]);
+       PR_EEP("Chain2 db_stage4", modal_hdr->db_stage4[2]);
+
+       return len;
+}
+
+static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                      u8 *buf, u32 len, u32 size)
+{
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+       struct ar9300_base_eep_hdr *pBase;
+
+       if (!dump_base_hdr) {
+               len += snprintf(buf + len, size - len,
+                               "%20s :\n", "2GHz modal Header");
+               len += ar9003_dump_modal_eeprom(buf, len, size,
+                                               &eep->modalHeader2G);
+               len += snprintf(buf + len, size - len,
+                               "%20s :\n", "5GHz modal Header");
+               len += ar9003_dump_modal_eeprom(buf, len, size,
+                                               &eep->modalHeader5G);
+               goto out;
+       }
+
+       pBase = &eep->baseEepHeader;
+
+       PR_EEP("EEPROM Version", ah->eeprom.ar9300_eep.eepromVersion);
+       PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
+       PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
+       PR_EEP("TX Mask", (pBase->txrxMask >> 4));
+       PR_EEP("RX Mask", (pBase->txrxMask & 0x0f));
+       PR_EEP("Allow 5GHz", !!(pBase->opCapFlags.opFlags &
+                               AR5416_OPFLAGS_11A));
+       PR_EEP("Allow 2GHz", !!(pBase->opCapFlags.opFlags &
+                               AR5416_OPFLAGS_11G));
+       PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags.opFlags &
+                                       AR5416_OPFLAGS_N_2G_HT20));
+       PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags.opFlags &
+                                       AR5416_OPFLAGS_N_2G_HT40));
+       PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags.opFlags &
+                                       AR5416_OPFLAGS_N_5G_HT20));
+       PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
+                                       AR5416_OPFLAGS_N_5G_HT40));
+       PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
+       PR_EEP("RF Silent", pBase->rfSilent);
+       PR_EEP("BT option", pBase->blueToothOptions);
+       PR_EEP("Device Cap", pBase->deviceCap);
+       PR_EEP("Device Type", pBase->deviceType);
+       PR_EEP("Power Table Offset", pBase->pwrTableOffset);
+       PR_EEP("Tuning Caps1", pBase->params_for_tuning_caps[0]);
+       PR_EEP("Tuning Caps2", pBase->params_for_tuning_caps[1]);
+       PR_EEP("Enable Tx Temp Comp", !!(pBase->featureEnable & BIT(0)));
+       PR_EEP("Enable Tx Volt Comp", !!(pBase->featureEnable & BIT(1)));
+       PR_EEP("Enable fast clock", !!(pBase->featureEnable & BIT(2)));
+       PR_EEP("Enable doubling", !!(pBase->featureEnable & BIT(3)));
+       PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4)));
+       PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5)));
+       PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0)));
+       PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1);
+       PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio);
+       PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio);
+       PR_EEP("WLAN LED Gpio", pBase->wlanLedGpio);
+       PR_EEP("Rx Band Select Gpio", pBase->rxBandSelectGpio);
+       PR_EEP("Tx Gain", pBase->txrxgain >> 4);
+       PR_EEP("Rx Gain", pBase->txrxgain & 0xf);
+       PR_EEP("SW Reg", le32_to_cpu(pBase->swreg));
+
+       len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
+                       ah->eeprom.ar9300_eep.macAddr);
+out:
+       if (len > size)
+               len = size;
+
+       return len;
+}
+#else
+static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                      u8 *buf, u32 len, u32 size)
+{
+       return 0;
+}
+#endif
+
 /* XXX: review hardware docs */
 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
 {
@@ -4061,7 +4188,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
         /* Write the power for duplicated frames - HT40 */
 
         /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
-       REG_WRITE(ah, 0xa3e0,
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE(8),
                  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
                  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
                  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24],  8) |
@@ -4922,25 +5049,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
                        "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
        }
 
-       /*
-        * This is the TX power we send back to driver core,
-        * and it can use to pass to userspace to display our
-        * currently configured TX power setting.
-        *
-        * Since power is rate dependent, use one of the indices
-        * from the AR9300_Rates enum to select an entry from
-        * targetPowerValT2[] to report. Currently returns the
-        * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
-        * as CCK power is less interesting (?).
-        */
-       i = ALL_TARGET_LEGACY_6_24; /* legacy */
-       if (IS_CHAN_HT40(chan))
-               i = ALL_TARGET_HT40_0_8_16; /* ht40 */
-       else if (IS_CHAN_HT20(chan))
-               i = ALL_TARGET_HT20_0_8_16; /* ht20 */
-
-       ah->txpower_limit = targetPowerValT2[i];
-       regulatory->max_power_level = targetPowerValT2[i];
+       ah->txpower_limit = regulatory->max_power_level;
 
        /* Write target power array to registers */
        ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
@@ -5015,6 +5124,7 @@ const struct eeprom_ops eep_ar9300_ops = {
        .check_eeprom = ath9k_hw_ar9300_check_eeprom,
        .get_eeprom = ath9k_hw_ar9300_get_eeprom,
        .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
+       .dump_eeprom = ath9k_hw_ar9003_dump_eeprom,
        .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
        .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
        .set_board_values = ath9k_hw_ar9300_set_board_values,
index ad2bb2bf4e8a8ff86242ee99bd4a92b8dbb395c2..9cf5d13529c2d7813ff31daa1fb0cdb2e51d9fc5 100644 (file)
@@ -516,14 +516,10 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
  * register as the other analog registers.  Hence the 9 writes.
  */
 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
-                                        int restore,
-                                        int power_off)
+                                        bool power_off)
 {
-       if (ah->is_pciexpress != true || ah->aspm_enabled != true)
-               return;
-
        /* Nothing to do on restore for 11N */
-       if (!restore) {
+       if (!power_off /* !restore */) {
                /* set bit 19 to allow forcing of pcie core into L1 state */
                REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
 
index 8ff0b88a29b9ab4c436870ad3ea6d2d09b030f67..1aadc4757e672a1cf9b93eb502c4b6a527c0fb76 100644 (file)
@@ -531,17 +531,18 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
 
        /* TODO: byte swap on big endian for ar9300_10 */
 
-       if ((rxsp->status11 & AR_RxDone) == 0)
-               return -EINPROGRESS;
+       if (!rxs) {
+               if ((rxsp->status11 & AR_RxDone) == 0)
+                       return -EINPROGRESS;
 
-       if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
-               return -EINVAL;
+               if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
+                       return -EINVAL;
 
-       if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
-               return -EINPROGRESS;
+               if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
+                       return -EINPROGRESS;
 
-       if (!rxs)
                return 0;
+       }
 
        rxs->rs_status = 0;
        rxs->rs_flags =  0;
index 1baca8e4715d9ad62e97c8ef8b9e0b4ec431f240..a0aaa6855486cb9914fa3445368fa48890a2db94 100644 (file)
@@ -370,7 +370,7 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
                        else
                                spur_subchannel_sd = 0;
 
-                       spur_freq_sd = ((freq_offset + 10) << 9) / 11;
+                       spur_freq_sd = (freq_offset << 9) / 11;
 
                } else {
                        if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
@@ -379,7 +379,7 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
                        else
                                spur_subchannel_sd = 1;
 
-                       spur_freq_sd = ((freq_offset - 10) << 9) / 11;
+                       spur_freq_sd = (freq_offset << 9) / 11;
 
                }
 
index 46393f90f16c5f96d59389bbffa9483381428772..c03949eb37c893ea102879484d486ac7a4ea9be0 100644 (file)
@@ -217,7 +217,6 @@ struct ath_buf_state {
        u8 bf_type;
        u8 bfs_paprd;
        unsigned long bfs_paprd_timestamp;
-       enum ath9k_internal_frame_type bfs_ftype;
 };
 
 struct ath_buf {
@@ -273,8 +272,6 @@ struct ath_node {
 struct ath_tx_control {
        struct ath_txq *txq;
        struct ath_node *an;
-       int if_id;
-       enum ath9k_internal_frame_type frame_type;
        u8 paprd;
 };
 
@@ -570,7 +567,6 @@ struct ath_ant_comb {
 #define PS_WAIT_FOR_PSPOLL_DATA   BIT(2)
 #define PS_WAIT_FOR_TX_ACK        BIT(3)
 #define PS_BEACON_SYNC            BIT(4)
-#define PS_TSFOOR_SYNC            BIT(5)
 
 struct ath_rate_table;
 
@@ -669,7 +665,7 @@ extern bool is_ath9k_unloaded;
 
 irqreturn_t ath_isr(int irq, void *dev);
 void ath9k_init_crypto(struct ath_softc *sc);
-int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+int ath9k_init_device(u16 devid, struct ath_softc *sc,
                    const struct ath_bus_ops *bus_ops);
 void ath9k_deinit_device(struct ath_softc *sc);
 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
index 0d13ff74a68be4b55dd7150dc3bf85971a489f12..086c9c816bf78b0e0210869936c3feed40772ee1 100644 (file)
@@ -522,6 +522,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
        ath9k_beacon_init(sc, nexttbtt, intval);
        sc->beacon.bmisscnt = 0;
        ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 }
 
 /*
@@ -648,12 +649,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
        ath9k_hw_set_sta_beacon_timers(ah, &bs);
        ah->imask |= ATH9K_INT_BMISS;
 
-       /*
-        * If the beacon config is called beacause of TSFOOR,
-        * Interrupts will be enabled back at the end of ath9k_tasklet
-        */
-       if (!(sc->ps_flags & PS_TSFOOR_SYNC))
-               ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 }
 
 static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -687,12 +684,9 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
        ath9k_hw_disable_interrupts(ah);
        ath9k_beacon_init(sc, nexttbtt, intval);
        sc->beacon.bmisscnt = 0;
-       /*
-        * If the beacon config is called beacause of TSFOOR,
-        * Interrupts will be enabled back at the end of ath9k_tasklet
-        */
-       if (!(sc->ps_flags & PS_TSFOOR_SYNC))
-               ath9k_hw_set_interrupts(ah, ah->imask);
+
+       ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 }
 
 static bool ath9k_allow_beacon_config(struct ath_softc *sc,
index a1250c586e40884989a853845e1c68230434f6c2..ac2da3cce7889f0430837660314a1d92073c26e8 100644 (file)
@@ -63,6 +63,19 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
        return ath9k_hw_get_nf_limits(ah, chan)->nominal;
 }
 
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       s8 noise = ATH_DEFAULT_NOISE_FLOOR;
+
+       if (chan && chan->noisefloor) {
+               s8 delta = chan->noisefloor -
+                          ath9k_hw_get_default_nf(ah, chan);
+               if (delta > 0)
+                       noise += delta;
+       }
+       return noise;
+}
+EXPORT_SYMBOL(ath9k_hw_getchan_noise);
 
 static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
                                              struct ath9k_hw_cal_data *cal,
@@ -378,6 +391,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
 
        if (!caldata) {
                chan->noisefloor = nf;
+               ah->noise = ath9k_hw_getchan_noise(ah, chan);
                return false;
        }
 
@@ -385,6 +399,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
        caldata->nfcal_pending = false;
        ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
        chan->noisefloor = h[0].privNF;
+       ah->noise = ath9k_hw_getchan_noise(ah, chan);
        return true;
 }
 
index 1bef41d1b1ffb250d38f490a395d6c79e033b019..05b9dbf818507535288360bfdff4379aa7bf9970 100644 (file)
@@ -108,6 +108,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
 void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
 void ath9k_hw_reset_calibration(struct ath_hw *ah,
                                struct ath9k_cal_list *currCal);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
 
 
 #endif /* CALIB_H */
index d1eb89611ff7982f5e1434685672d1591036368c..9bec3b89fb684030087f502270143b6b5c9047ec 100644 (file)
@@ -1163,6 +1163,62 @@ static const struct file_operations fops_regdump = {
        .llseek = default_llseek,/* read accesses f_pos */
 };
 
+static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
+                                    size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_hw *ah = sc->sc_ah;
+       u32 len = 0, size = 1500;
+       ssize_t retval = 0;
+       char *buf;
+
+       buf = kzalloc(size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size);
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
+}
+
+static const struct file_operations fops_base_eeprom = {
+       .read = read_file_base_eeprom,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
+static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
+                                     size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_hw *ah = sc->sc_ah;
+       u32 len = 0, size = 6000;
+       char *buf;
+       size_t retval;
+
+       buf = kzalloc(size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size);
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
+}
+
+static const struct file_operations fops_modal_eeprom = {
+       .read = read_file_modal_eeprom,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
 int ath9k_init_debug(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -1206,6 +1262,10 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &ah->config.cwm_ignore_extcca);
        debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_regdump);
+       debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
+                           &fops_base_eeprom);
+       debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
+                           &fops_modal_eeprom);
 
        debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
                           sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
index de99c0da52e4e33c412086f346673d1d49211015..a3c7d0c247a32fd4eca87317dd587cdc64bbac84 100644 (file)
@@ -649,6 +649,8 @@ struct eeprom_ops {
        int (*check_eeprom)(struct ath_hw *hw);
        u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
        bool (*fill_eeprom)(struct ath_hw *hw);
+       u32 (*dump_eeprom)(struct ath_hw *hw, bool dump_base_hdr, u8 *buf,
+                          u32 len, u32 size);
        int (*get_eeprom_ver)(struct ath_hw *hw);
        int (*get_eeprom_rev)(struct ath_hw *hw);
        void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
index 47cc95086e6e950e4ca7c89c9801707a15572aa6..ea658e794cbdf70f8dc8c1f016afb96a59f5d106 100644 (file)
@@ -72,6 +72,117 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
                return __ath9k_hw_4k_fill_eeprom(ah);
 }
 
+#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
+                                     struct modal_eep_4k_header *modal_hdr)
+{
+       PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
+       PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
+       PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
+       PR_EEP("Switch Settle", modal_hdr->switchSettling);
+       PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
+       PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
+       PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
+       PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
+       PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
+       PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
+       PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
+       PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
+       PR_EEP("CCA Threshold)", modal_hdr->thresh62);
+       PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
+       PR_EEP("xpdGain", modal_hdr->xpdGain);
+       PR_EEP("External PD", modal_hdr->xpd);
+       PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
+       PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
+       PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
+       PR_EEP("O/D Bias Version", modal_hdr->version);
+       PR_EEP("CCK OutputBias", modal_hdr->ob_0);
+       PR_EEP("BPSK OutputBias", modal_hdr->ob_1);
+       PR_EEP("QPSK OutputBias", modal_hdr->ob_2);
+       PR_EEP("16QAM OutputBias", modal_hdr->ob_3);
+       PR_EEP("64QAM OutputBias", modal_hdr->ob_4);
+       PR_EEP("CCK Driver1_Bias", modal_hdr->db1_0);
+       PR_EEP("BPSK Driver1_Bias", modal_hdr->db1_1);
+       PR_EEP("QPSK Driver1_Bias", modal_hdr->db1_2);
+       PR_EEP("16QAM Driver1_Bias", modal_hdr->db1_3);
+       PR_EEP("64QAM Driver1_Bias", modal_hdr->db1_4);
+       PR_EEP("CCK Driver2_Bias", modal_hdr->db2_0);
+       PR_EEP("BPSK Driver2_Bias", modal_hdr->db2_1);
+       PR_EEP("QPSK Driver2_Bias", modal_hdr->db2_2);
+       PR_EEP("16QAM Driver2_Bias", modal_hdr->db2_3);
+       PR_EEP("64QAM Driver2_Bias", modal_hdr->db2_4);
+       PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
+       PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
+       PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
+       PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
+       PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
+       PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
+       PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
+       PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
+       PR_EEP("Ant. Diversity ctl1", modal_hdr->antdiv_ctl1);
+       PR_EEP("Ant. Diversity ctl2", modal_hdr->antdiv_ctl2);
+       PR_EEP("TX Diversity", modal_hdr->tx_diversity);
+
+       return len;
+}
+
+static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                      u8 *buf, u32 len, u32 size)
+{
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+
+       if (!dump_base_hdr) {
+               len += snprintf(buf + len, size - len,
+                               "%20s :\n", "2GHz modal Header");
+               len += ath9k_dump_4k_modal_eeprom(buf, len, size,
+                                                 &eep->modalHeader);
+               goto out;
+       }
+
+       PR_EEP("Major Version", pBase->version >> 12);
+       PR_EEP("Minor Version", pBase->version & 0xFFF);
+       PR_EEP("Checksum", pBase->checksum);
+       PR_EEP("Length", pBase->length);
+       PR_EEP("RegDomain1", pBase->regDmn[0]);
+       PR_EEP("RegDomain2", pBase->regDmn[1]);
+       PR_EEP("TX Mask", pBase->txMask);
+       PR_EEP("RX Mask", pBase->rxMask);
+       PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
+       PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
+       PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_2G_HT20));
+       PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_2G_HT40));
+       PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_5G_HT20));
+       PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_5G_HT40));
+       PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
+       PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
+       PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
+       PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
+       PR_EEP("TX Gain type", pBase->txGainType);
+
+       len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
+                       pBase->macAddr);
+
+out:
+       if (len > size)
+               len = size;
+
+       return len;
+}
+#else
+static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                      u8 *buf, u32 len, u32 size)
+{
+       return 0;
+}
+#endif
+
+
 #undef SIZE_EEPROM_4K
 
 static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
@@ -238,18 +349,14 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
        case EEP_ANT_DIV_CTL1:
                return pModal->antdiv_ctl1;
        case EEP_TXGAIN_TYPE:
-               if (ver_minor >= AR5416_EEP_MINOR_VER_19)
-                       return pBase->txGainType;
-               else
-                       return AR5416_EEP_TXGAIN_ORIGINAL;
+               return pBase->txGainType;
        default:
                return 0;
        }
 }
 
 static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 int16_t *pTxPowerIndexOffset)
+                                 struct ath9k_channel *chan)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -356,8 +463,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
                        REGWRITE_BUFFER_FLUSH(ah);
                }
        }
-
-       *pTxPowerIndexOffset = 0;
 }
 
 static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
@@ -580,7 +685,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
        struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
        struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
        int16_t ratesArray[Ar5416RateSize];
-       int16_t txPowerIndexOffset = 0;
        u8 ht40PowerIncForPdadc = 2;
        int i;
 
@@ -597,11 +701,10 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
                                             twiceMaxRegulatoryPower,
                                             powerLimit);
 
-       ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+       ath9k_hw_set_4k_power_cal_table(ah, chan);
 
        regulatory->max_power_level = 0;
        for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
                if (ratesArray[i] > MAX_RATE_POWER)
                        ratesArray[i] = MAX_RATE_POWER;
 
@@ -612,15 +715,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
        if (test)
            return;
 
-       /* Update regulatory */
-       i = rate6mb;
-       if (IS_CHAN_HT40(chan))
-               i = rateHt40_0;
-       else if (IS_CHAN_HT20(chan))
-               i = rateHt20_0;
-
-       regulatory->max_power_level = ratesArray[i];
-
        if (AR_SREV_9280_20_OR_LATER(ah)) {
                for (i = 0; i < Ar5416RateSize; i++)
                        ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
@@ -1063,6 +1157,7 @@ const struct eeprom_ops eep_4k_ops = {
        .check_eeprom           = ath9k_hw_4k_check_eeprom,
        .get_eeprom             = ath9k_hw_4k_get_eeprom,
        .fill_eeprom            = ath9k_hw_4k_fill_eeprom,
+       .dump_eeprom            = ath9k_hw_4k_dump_eeprom,
        .get_eeprom_ver         = ath9k_hw_4k_get_eeprom_ver,
        .get_eeprom_rev         = ath9k_hw_4k_get_eeprom_rev,
        .set_board_values       = ath9k_hw_4k_set_board_values,
index d6f6b192f4507008df5b2feee95183bb6413b07f..21f180db23810dddf52ffd2eed2364d75e3cb82d 100644 (file)
@@ -76,6 +76,111 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
                return __ath9k_hw_ar9287_fill_eeprom(ah);
 }
 
+#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size,
+                                   struct modal_eep_ar9287_header *modal_hdr)
+{
+       PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
+       PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
+       PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
+       PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
+       PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
+       PR_EEP("Switch Settle", modal_hdr->switchSettling);
+       PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
+       PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);
+       PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
+       PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);
+       PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
+       PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
+       PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
+       PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
+       PR_EEP("CCA Threshold)", modal_hdr->thresh62);
+       PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
+       PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
+       PR_EEP("xpdGain", modal_hdr->xpdGain);
+       PR_EEP("External PD", modal_hdr->xpd);
+       PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
+       PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);
+       PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
+       PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);
+       PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
+       PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
+       PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
+       PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
+       PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
+       PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);
+       PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
+       PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);
+       PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
+       PR_EEP("AR92x7 Version", modal_hdr->version);
+       PR_EEP("DriverBias1", modal_hdr->db1);
+       PR_EEP("DriverBias2", modal_hdr->db1);
+       PR_EEP("CCK OutputBias", modal_hdr->ob_cck);
+       PR_EEP("PSK OutputBias", modal_hdr->ob_psk);
+       PR_EEP("QAM OutputBias", modal_hdr->ob_qam);
+       PR_EEP("PAL_OFF OutputBias", modal_hdr->ob_pal_off);
+
+       return len;
+}
+
+static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                      u8 *buf, u32 len, u32 size)
+{
+       struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+       struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
+
+       if (!dump_base_hdr) {
+               len += snprintf(buf + len, size - len,
+                               "%20s :\n", "2GHz modal Header");
+               len += ar9287_dump_modal_eeprom(buf, len, size,
+                                               &eep->modalHeader);
+               goto out;
+       }
+
+       PR_EEP("Major Version", pBase->version >> 12);
+       PR_EEP("Minor Version", pBase->version & 0xFFF);
+       PR_EEP("Checksum", pBase->checksum);
+       PR_EEP("Length", pBase->length);
+       PR_EEP("RegDomain1", pBase->regDmn[0]);
+       PR_EEP("RegDomain2", pBase->regDmn[1]);
+       PR_EEP("TX Mask", pBase->txMask);
+       PR_EEP("RX Mask", pBase->rxMask);
+       PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
+       PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
+       PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_2G_HT20));
+       PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_2G_HT40));
+       PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_5G_HT20));
+       PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_5G_HT40));
+       PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
+       PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
+       PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
+       PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
+       PR_EEP("Power Table Offset", pBase->pwrTableOffset);
+       PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
+
+       len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
+                       pBase->macAddr);
+
+out:
+       if (len > size)
+               len = size;
+
+       return len;
+}
+#else
+static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                      u8 *buf, u32 len, u32 size)
+{
+       return 0;
+}
+#endif
+
+
 static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
 {
        u32 sum = 0, el, integer;
@@ -307,8 +412,7 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
 }
 
 static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
-                                               struct ath9k_channel *chan,
-                                               int16_t *pTxPowerIndexOffset)
+                                               struct ath9k_channel *chan)
 {
        struct cal_data_per_freq_ar9287 *pRawDataset;
        struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
@@ -444,8 +548,6 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
                        REGWRITE_BUFFER_FLUSH(ah);
                }
        }
-
-       *pTxPowerIndexOffset = 0;
 }
 
 static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
@@ -720,7 +822,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
        struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
        struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
        int16_t ratesArray[Ar5416RateSize];
-       int16_t txPowerIndexOffset = 0;
        u8 ht40PowerIncForPdadc = 2;
        int i;
 
@@ -736,11 +837,10 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
                                                 twiceMaxRegulatoryPower,
                                                 powerLimit);
 
-       ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
+       ath9k_hw_set_ar9287_power_cal_table(ah, chan);
 
        regulatory->max_power_level = 0;
        for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
                if (ratesArray[i] > MAX_RATE_POWER)
                        ratesArray[i] = MAX_RATE_POWER;
 
@@ -751,13 +851,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
        if (test)
                return;
 
-       if (IS_CHAN_2GHZ(chan))
-               i = rate1l;
-       else
-               i = rate6mb;
-
-       regulatory->max_power_level = ratesArray[i];
-
        if (AR_SREV_9280_20_OR_LATER(ah)) {
                for (i = 0; i < Ar5416RateSize; i++)
                        ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
@@ -1003,6 +1096,7 @@ const struct eeprom_ops eep_ar9287_ops = {
        .check_eeprom           = ath9k_hw_ar9287_check_eeprom,
        .get_eeprom             = ath9k_hw_ar9287_get_eeprom,
        .fill_eeprom            = ath9k_hw_ar9287_fill_eeprom,
+       .dump_eeprom            = ath9k_hw_ar9287_dump_eeprom,
        .get_eeprom_ver         = ath9k_hw_ar9287_get_eeprom_ver,
        .get_eeprom_rev         = ath9k_hw_ar9287_get_eeprom_rev,
        .set_board_values       = ath9k_hw_ar9287_set_board_values,
index b9540a992616c6241258b96add5858d44bf91017..e7e84be8beed32d2768d08888a7083427338997b 100644 (file)
@@ -133,6 +133,136 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
 
 #undef SIZE_EEPROM_DEF
 
+#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
+                                      struct modal_eep_header *modal_hdr)
+{
+       PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
+       PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
+       PR_EEP("Chain2 Ant. Control", modal_hdr->antCtrlChain[2]);
+       PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
+       PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
+       PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
+       PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]);
+       PR_EEP("Switch Settle", modal_hdr->switchSettling);
+       PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
+       PR_EEP("Chain1 TxRxAtten", modal_hdr->txRxAttenCh[1]);
+       PR_EEP("Chain2 TxRxAtten", modal_hdr->txRxAttenCh[2]);
+       PR_EEP("Chain0 RxTxMargin", modal_hdr->rxTxMarginCh[0]);
+       PR_EEP("Chain1 RxTxMargin", modal_hdr->rxTxMarginCh[1]);
+       PR_EEP("Chain2 RxTxMargin", modal_hdr->rxTxMarginCh[2]);
+       PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize);
+       PR_EEP("PGA Desired size", modal_hdr->pgaDesiredSize);
+       PR_EEP("Chain0 xlna Gain", modal_hdr->xlnaGainCh[0]);
+       PR_EEP("Chain1 xlna Gain", modal_hdr->xlnaGainCh[1]);
+       PR_EEP("Chain2 xlna Gain", modal_hdr->xlnaGainCh[2]);
+       PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff);
+       PR_EEP("txEndToRxOn", modal_hdr->txEndToRxOn);
+       PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn);
+       PR_EEP("CCA Threshold)", modal_hdr->thresh62);
+       PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]);
+       PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]);
+       PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]);
+       PR_EEP("xpdGain", modal_hdr->xpdGain);
+       PR_EEP("External PD", modal_hdr->xpd);
+       PR_EEP("Chain0 I Coefficient", modal_hdr->iqCalICh[0]);
+       PR_EEP("Chain1 I Coefficient", modal_hdr->iqCalICh[1]);
+       PR_EEP("Chain2 I Coefficient", modal_hdr->iqCalICh[2]);
+       PR_EEP("Chain0 Q Coefficient", modal_hdr->iqCalQCh[0]);
+       PR_EEP("Chain1 Q Coefficient", modal_hdr->iqCalQCh[1]);
+       PR_EEP("Chain2 Q Coefficient", modal_hdr->iqCalQCh[2]);
+       PR_EEP("pdGainOverlap", modal_hdr->pdGainOverlap);
+       PR_EEP("Chain0 OutputBias", modal_hdr->ob);
+       PR_EEP("Chain0 DriverBias", modal_hdr->db);
+       PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl);
+       PR_EEP("2chain pwr decrease", modal_hdr->pwrDecreaseFor2Chain);
+       PR_EEP("3chain pwr decrease", modal_hdr->pwrDecreaseFor3Chain);
+       PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn);
+       PR_EEP("HT40 Power Inc.", modal_hdr->ht40PowerIncForPdadc);
+       PR_EEP("Chain0 bswAtten", modal_hdr->bswAtten[0]);
+       PR_EEP("Chain1 bswAtten", modal_hdr->bswAtten[1]);
+       PR_EEP("Chain2 bswAtten", modal_hdr->bswAtten[2]);
+       PR_EEP("Chain0 bswMargin", modal_hdr->bswMargin[0]);
+       PR_EEP("Chain1 bswMargin", modal_hdr->bswMargin[1]);
+       PR_EEP("Chain2 bswMargin", modal_hdr->bswMargin[2]);
+       PR_EEP("HT40 Switch Settle", modal_hdr->swSettleHt40);
+       PR_EEP("Chain0 xatten2Db", modal_hdr->xatten2Db[0]);
+       PR_EEP("Chain1 xatten2Db", modal_hdr->xatten2Db[1]);
+       PR_EEP("Chain2 xatten2Db", modal_hdr->xatten2Db[2]);
+       PR_EEP("Chain0 xatten2Margin", modal_hdr->xatten2Margin[0]);
+       PR_EEP("Chain1 xatten2Margin", modal_hdr->xatten2Margin[1]);
+       PR_EEP("Chain2 xatten2Margin", modal_hdr->xatten2Margin[2]);
+       PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1);
+       PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1);
+       PR_EEP("LNA Control", modal_hdr->lna_ctl);
+       PR_EEP("XPA Bias Freq0", modal_hdr->xpaBiasLvlFreq[0]);
+       PR_EEP("XPA Bias Freq1", modal_hdr->xpaBiasLvlFreq[1]);
+       PR_EEP("XPA Bias Freq2", modal_hdr->xpaBiasLvlFreq[2]);
+
+       return len;
+}
+
+static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                   u8 *buf, u32 len, u32 size)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+
+       if (!dump_base_hdr) {
+               len += snprintf(buf + len, size - len,
+                               "%20s :\n", "2GHz modal Header");
+               len += ath9k_def_dump_modal_eeprom(buf, len, size,
+                                                  &eep->modalHeader[0]);
+               len += snprintf(buf + len, size - len,
+                               "%20s :\n", "5GHz modal Header");
+               len += ath9k_def_dump_modal_eeprom(buf, len, size,
+                                                  &eep->modalHeader[1]);
+               goto out;
+       }
+
+       PR_EEP("Major Version", pBase->version >> 12);
+       PR_EEP("Minor Version", pBase->version & 0xFFF);
+       PR_EEP("Checksum", pBase->checksum);
+       PR_EEP("Length", pBase->length);
+       PR_EEP("RegDomain1", pBase->regDmn[0]);
+       PR_EEP("RegDomain2", pBase->regDmn[1]);
+       PR_EEP("TX Mask", pBase->txMask);
+       PR_EEP("RX Mask", pBase->rxMask);
+       PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
+       PR_EEP("Allow 2GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
+       PR_EEP("Disable 2GHz HT20", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_2G_HT20));
+       PR_EEP("Disable 2GHz HT40", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_2G_HT40));
+       PR_EEP("Disable 5Ghz HT20", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_5G_HT20));
+       PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
+                                       AR5416_OPFLAGS_N_5G_HT40));
+       PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
+       PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
+       PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
+       PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
+       PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
+
+       len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
+                       pBase->macAddr);
+
+out:
+       if (len > size)
+               len = size;
+
+       return len;
+}
+#else
+static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
+                                   u8 *buf, u32 len, u32 size)
+{
+       return 0;
+}
+#endif
+
+
 static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
 {
        struct ar5416_eeprom_def *eep =
@@ -693,8 +823,7 @@ static void ath9k_adjust_pdadc_values(struct ath_hw *ah,
 }
 
 static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 int16_t *pTxPowerIndexOffset)
+                                 struct ath9k_channel *chan)
 {
 #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
 #define SM_PDGAIN_B(x, y) \
@@ -855,7 +984,6 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
                }
        }
 
-       *pTxPowerIndexOffset = 0;
 #undef SM_PD_GAIN
 #undef SM_PDGAIN_B
 }
@@ -1143,7 +1271,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
        struct modal_eep_header *pModal =
                &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
        int16_t ratesArray[Ar5416RateSize];
-       int16_t txPowerIndexOffset = 0;
        u8 ht40PowerIncForPdadc = 2;
        int i, cck_ofdm_delta = 0;
 
@@ -1160,28 +1287,16 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
                                               twiceMaxRegulatoryPower,
                                               powerLimit);
 
-       ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+       ath9k_hw_set_def_power_cal_table(ah, chan);
 
        regulatory->max_power_level = 0;
        for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
                if (ratesArray[i] > MAX_RATE_POWER)
                        ratesArray[i] = MAX_RATE_POWER;
                if (ratesArray[i] > regulatory->max_power_level)
                        regulatory->max_power_level = ratesArray[i];
        }
 
-       if (!test) {
-               i = rate6mb;
-
-               if (IS_CHAN_HT40(chan))
-                       i = rateHt40_0;
-               else if (IS_CHAN_HT20(chan))
-                       i = rateHt20_0;
-
-               regulatory->max_power_level = ratesArray[i];
-       }
-
        switch(ar5416_get_ntxchains(ah->txchainmask)) {
        case 1:
                break;
@@ -1336,6 +1451,7 @@ const struct eeprom_ops eep_def_ops = {
        .check_eeprom           = ath9k_hw_def_check_eeprom,
        .get_eeprom             = ath9k_hw_def_get_eeprom,
        .fill_eeprom            = ath9k_hw_def_fill_eeprom,
+       .dump_eeprom            = ath9k_hw_def_dump_eeprom,
        .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
        .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
        .set_board_values       = ath9k_hw_def_set_board_values,
index bc713fc28191b2baf4e1992365902cfbce25fd07..5113dd80c99fb707946f69e073f59fbcc0f6613e 100644 (file)
@@ -149,6 +149,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
                ath9k_hw_disable_interrupts(ah);
                ah->imask |= ATH9K_INT_GENTIMER;
                ath9k_hw_set_interrupts(ah, ah->imask);
+               ath9k_hw_enable_interrupts(ah);
        }
 }
 
@@ -163,6 +164,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
                ath9k_hw_disable_interrupts(ah);
                ah->imask &= ~ATH9K_INT_GENTIMER;
                ath9k_hw_set_interrupts(ah, ah->imask);
+               ath9k_hw_enable_interrupts(ah);
        }
 }
 
index 5bc022087e651e8be0a8097ca17af1257c1b4f45..da5596766d8219791948a2f2ca26c719ec9ee7aa 100644 (file)
@@ -521,8 +521,6 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
 
 int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
                                u8 enable_coex);
-void ath9k_htc_station_work(struct work_struct *work);
-void ath9k_htc_aggr_work(struct work_struct *work);
 void ath9k_htc_ani_work(struct work_struct *work);
 void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
 void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
@@ -542,7 +540,6 @@ int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv);
 void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);
 void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
 void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
-void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv);
 void ath9k_tx_failed_tasklet(unsigned long data);
 void ath9k_htc_tx_cleanup_timer(unsigned long data);
 
index 3bea7ea86f0a855f7aa0f9f7d91b4c1b13384522..19aa5b7248875f0169d68898d07db4b4b0644746 100644 (file)
@@ -666,7 +666,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
                return -ENOMEM;
 
        ah->hw_version.devid = devid;
-       ah->hw_version.subsysid = 0; /* FIXME */
        ah->hw_version.usbdev = drv_info;
        ah->ah_flags |= AH_USE_EEPROM;
        ah->reg_ops.read = ath9k_regread;
index cb29e8875386d7966334273748f2e7c97abab69d..dd9003ee123bfbe6701eedd519cdb749c643960a 100644 (file)
 /* Hardware core and driver accessible callbacks */
 
 static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
-                                              int restore,
-                                              int power_off)
+                                              bool power_off)
 {
-       ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
+       if (ah->aspm_enabled != true)
+               return;
+
+       ath9k_hw_ops(ah)->config_pci_powersave(ah, power_off);
 }
 
 static inline void ath9k_hw_rxena(struct ath_hw *ah)
index 8dcefe74f4c39ec768bc06979e3c305d086090b3..875faf6894aeb64469f3bb9d489bbf9ad5850e53 100644 (file)
@@ -603,10 +603,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 
        ath9k_hw_init_mode_regs(ah);
 
-
-       if (ah->is_pciexpress)
-               ath9k_hw_aspm_init(ah);
-       else
+       if (!ah->is_pciexpress)
                ath9k_hw_disablepcie(ah);
 
        if (!AR_SREV_9300_20_OR_LATER(ah))
@@ -621,6 +618,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
        if (r)
                return r;
 
+       if (ah->is_pciexpress)
+               ath9k_hw_aspm_init(ah);
+
        r = ath9k_hw_init_macaddr(ah);
        if (r) {
                ath_err(common, "Failed to initialize MAC address\n");
@@ -1486,6 +1486,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                memset(caldata, 0, sizeof(*caldata));
                ath9k_init_nfcal_hist_buffer(ah, chan);
        }
+       ah->noise = ath9k_hw_getchan_noise(ah, chan);
 
        if (bChannelChange &&
            (ah->chip_fullsleep != true) &&
@@ -2439,15 +2440,18 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
        struct ath9k_channel *chan = ah->curchan;
        struct ieee80211_channel *channel = chan->chan;
+       int reg_pwr = min_t(int, MAX_RATE_POWER, regulatory->power_limit);
+       int chan_pwr = channel->max_power * 2;
+
+       if (test)
+               reg_pwr = chan_pwr = MAX_RATE_POWER;
 
        regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
 
        ah->eep_ops->set_txpower(ah, chan,
                                 ath9k_regd_get_ctl(regulatory, chan),
                                 channel->max_antenna_gain * 2,
-                                channel->max_power * 2,
-                                min((u32) MAX_RATE_POWER,
-                                (u32) regulatory->power_limit), test);
+                                chan_pwr, reg_pwr, test);
 }
 EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
 
index c79889036ec40be88bbfec9ed81640ee366c91a4..ee0d9441209b0b5d72074785c1ed2e289f68c700 100644 (file)
                        (_ah)->reg_ops.write_flush((_ah));      \
        } while (0)
 
+#define PR_EEP(_s, _val)                                               \
+       do {                                                            \
+               len += snprintf(buf + len, size - len, "%20s : %10d\n", \
+                               _s, (_val));                            \
+       } while (0)
+
 #define SM(_v, _f)  (((_v) << _f##_S) & _f)
 #define MS(_v, _f)  (((_v) & _f) >> _f##_S)
 #define REG_RMW_FIELD(_a, _r, _f, _v) \
@@ -438,7 +444,6 @@ struct ath9k_hw_version {
        u16 phyRev;
        u16 analog5GhzRev;
        u16 analog2GhzRev;
-       u16 subsysid;
        enum ath_usb_dev usbdev;
 };
 
@@ -601,8 +606,7 @@ struct ath_hw_private_ops {
  */
 struct ath_hw_ops {
        void (*config_pci_powersave)(struct ath_hw *ah,
-                                    int restore,
-                                    int power_off);
+                                    bool power_off);
        void (*rx_enable)(struct ath_hw *ah);
        void (*set_desc_link)(void *ds, u32 link);
        bool (*calibrate)(struct ath_hw *ah,
@@ -690,6 +694,7 @@ struct ath_hw {
        enum nl80211_iftype opmode;
        enum ath9k_power_mode power_mode;
 
+       s8 noise;
        struct ath9k_hw_cal_data *caldata;
        struct ath9k_pacal_info pacal_info;
        struct ar5416Stats stats;
@@ -703,6 +708,7 @@ struct ath_hw {
        u32 txdesc_interrupt_mask;
        u32 txeol_interrupt_mask;
        u32 txurn_interrupt_mask;
+       atomic_t intr_ref_cnt;
        bool chip_fullsleep;
        u32 atim_window;
 
@@ -1030,10 +1036,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
 void ath9k_hw_proc_mib_event(struct ath_hw *ah);
 void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
 
-#define ATH_PCIE_CAP_LINK_CTRL 0x70
-#define ATH_PCIE_CAP_LINK_L0S  1
-#define ATH_PCIE_CAP_LINK_L1   2
-
 #define ATH9K_CLOCK_RATE_CCK           22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
index aa0ff7e2c922223759c298d69ccce3a39441a69b..db38a58e752d4a001ffd9b22a909b6f3c55669cd 100644 (file)
@@ -548,7 +548,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
                sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
 }
 
-static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
+static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
                            const struct ath_bus_ops *bus_ops)
 {
        struct ath9k_platform_data *pdata = sc->dev->platform_data;
@@ -563,10 +563,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 
        ah->hw = sc->hw;
        ah->hw_version.devid = devid;
-       ah->hw_version.subsysid = subsysid;
        ah->reg_ops.read = ath9k_ioread32;
        ah->reg_ops.write = ath9k_iowrite32;
        ah->reg_ops.rmw = ath9k_reg_rmw;
+       atomic_set(&ah->intr_ref_cnt, -1);
        sc->sc_ah = ah;
 
        if (!pdata) {
@@ -743,7 +743,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
 }
 
-int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
+int ath9k_init_device(u16 devid, struct ath_softc *sc,
                    const struct ath_bus_ops *bus_ops)
 {
        struct ieee80211_hw *hw = sc->hw;
@@ -753,7 +753,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        struct ath_regulatory *reg;
 
        /* Bring up device */
-       error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
+       error = ath9k_init_softc(devid, sc, bus_ops);
        if (error != 0)
                goto error_init;
 
index b6b523a897e54db4f2673e9597583576da145917..0f90e1521ffeb61865ed8ee1ce473aea5c255349 100644 (file)
@@ -800,6 +800,11 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
 
+       if (!(ah->imask & ATH9K_INT_GLOBAL))
+               atomic_set(&ah->intr_ref_cnt, -1);
+       else
+               atomic_dec(&ah->intr_ref_cnt);
+
        ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n");
        REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
        (void) REG_READ(ah, AR_IER);
@@ -821,6 +826,13 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
        if (!(ah->imask & ATH9K_INT_GLOBAL))
                return;
 
+       if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+               ath_dbg(common, ATH_DBG_INTERRUPT,
+                       "Do not enable IER ref count %d\n",
+                       atomic_read(&ah->intr_ref_cnt));
+               return;
+       }
+
        if (AR_SREV_9340(ah))
                sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
 
@@ -852,7 +864,6 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 
        ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
 
-       /* TODO: global int Ref count */
        mask = ints & ATH9K_INT_COMMON;
        mask2 = 0;
 
@@ -929,9 +940,6 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
                        REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
        }
 
-       if (ints & ATH9K_INT_GLOBAL)
-               ath9k_hw_enable_interrupts(ah);
-
        return;
 }
 EXPORT_SYMBOL(ath9k_hw_set_interrupts);
index 9098aaad97a92707bdf62d2dcbdcc4dcb38a7a15..781af25f440d81898b99934aaceef455f9a325cb 100644 (file)
@@ -163,7 +163,7 @@ static void ath_update_survey_nf(struct ath_softc *sc, int channel)
 
        if (chan->noisefloor) {
                survey->filled |= SURVEY_INFO_NOISE_DBM;
-               survey->noise = chan->noisefloor;
+               survey->noise = ath9k_hw_getchan_noise(ah, chan);
        }
 }
 
@@ -294,6 +294,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
        ath9k_cmn_update_txpow(ah, sc->curtxpow,
                               sc->config.txpowlimit, &sc->curtxpow);
        ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 
        if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
                if (sc->sc_flags & SC_OP_BEACONS)
@@ -706,8 +707,7 @@ void ath9k_tasklet(unsigned long data)
                 */
                ath_dbg(common, ATH_DBG_PS,
                        "TSFOOR - Sync with next Beacon\n");
-               sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC |
-                               PS_TSFOOR_SYNC;
+               sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
        }
 
        if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
@@ -886,8 +886,9 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 
        ath9k_ps_wakeup(sc);
        spin_lock_bh(&sc->sc_pcu_lock);
+       atomic_set(&ah->intr_ref_cnt, -1);
 
-       ath9k_hw_configpcipowersave(ah, 0, 0);
+       ath9k_hw_configpcipowersave(ah, false);
 
        if (!ah->curchan)
                ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah);
@@ -910,6 +911,7 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 
        /* Re-Enable  interrupts */
        ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 
        /* Enable LED */
        ath9k_hw_cfg_output(ah, ah->led_pin,
@@ -967,7 +969,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
 
        ath9k_hw_phy_disable(ah);
 
-       ath9k_hw_configpcipowersave(ah, 1, 1);
+       ath9k_hw_configpcipowersave(ah, true);
 
        spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
@@ -1016,6 +1018,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
                ath_set_beacon(sc);     /* restart beacons */
 
        ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 
        if (retry_tx) {
                int i;
@@ -1066,7 +1069,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
        init_channel = ath9k_cmn_get_curchannel(hw, ah);
 
        /* Reset SERDES registers */
-       ath9k_hw_configpcipowersave(ah, 0, 0);
+       ath9k_hw_configpcipowersave(ah, false);
 
        /*
         * The basic interface to setting the hardware in a good
@@ -1130,6 +1133,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
        /* Disable BMISS interrupt when we're not associated */
        ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
        ath9k_hw_set_interrupts(ah, ah->imask);
+       ath9k_hw_enable_interrupts(ah);
 
        ieee80211_wake_queues(hw);
 
@@ -1141,8 +1145,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
                                           AR_STOMP_LOW_WLAN_WGHT);
                ath9k_hw_btcoex_enable(ah);
 
-               if (common->bus_ops->bt_coex_prep)
-                       common->bus_ops->bt_coex_prep(common);
                if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
                        ath9k_btcoex_timer_resume(sc);
        }
index be4ea132981343dde6ebd521c0bd436dc538438c..daa26b5d745501d9f0ac4e6783a5540f5408345c 100644 (file)
@@ -35,6 +35,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
        { 0 }
 };
 
+
 /* return bus cachesize in 4B word units */
 static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
 {
@@ -88,23 +89,6 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
        return true;
 }
 
-/*
- * Bluetooth coexistance requires disabling ASPM.
- */
-static void ath_pci_bt_coex_prep(struct ath_common *common)
-{
-       struct ath_softc *sc = (struct ath_softc *) common->priv;
-       struct pci_dev *pdev = to_pci_dev(sc->dev);
-       u8 aspm;
-
-       if (!pci_is_pcie(pdev))
-               return;
-
-       pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
-       aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
-       pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
-}
-
 static void ath_pci_extn_synch_enable(struct ath_common *common)
 {
        struct ath_softc *sc = (struct ath_softc *) common->priv;
@@ -116,6 +100,7 @@ static void ath_pci_extn_synch_enable(struct ath_common *common)
        pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
 }
 
+/* Need to be called after we discover btcoex capabilities */
 static void ath_pci_aspm_init(struct ath_common *common)
 {
        struct ath_softc *sc = (struct ath_softc *) common->priv;
@@ -125,10 +110,33 @@ static void ath_pci_aspm_init(struct ath_common *common)
        int pos;
        u8 aspm;
 
-       if (!pci_is_pcie(pdev))
+       pos = pci_pcie_cap(pdev);
+       if (!pos)
                return;
 
        parent = pdev->bus->self;
+
+       if (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) {
+               /* Bluetooth coexistance requires disabling ASPM. */
+               pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
+               aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
+               pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm);
+
+               /*
+                * Both upstream and downstream PCIe components should
+                * have the same ASPM settings.
+                */
+               if (WARN_ON(!parent))
+                       return;
+
+               pos = pci_pcie_cap(parent);
+               pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
+               aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
+               pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm);
+
+               return;
+       }
+
        if (WARN_ON(!parent))
                return;
 
@@ -137,7 +145,7 @@ static void ath_pci_aspm_init(struct ath_common *common)
        if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
                ah->aspm_enabled = true;
                /* Initialize PCIe PM and SERDES registers. */
-               ath9k_hw_configpcipowersave(ah, 0, 0);
+               ath9k_hw_configpcipowersave(ah, false);
        }
 }
 
@@ -145,7 +153,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = {
        .ath_bus_type = ATH_PCI,
        .read_cachesize = ath_pci_read_cachesize,
        .eeprom_read = ath_pci_eeprom_read,
-       .bt_coex_prep = ath_pci_bt_coex_prep,
        .extn_synch_en = ath_pci_extn_synch_enable,
        .aspm_init = ath_pci_aspm_init,
 };
@@ -156,7 +163,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        struct ath_softc *sc;
        struct ieee80211_hw *hw;
        u8 csz;
-       u16 subsysid;
        u32 val;
        int ret = 0;
        char hw_name[64];
@@ -250,8 +256,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        sc->irq = pdev->irq;
 
-       pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
-       ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
+       ret = ath9k_init_device(id->device, sc, &ath_pci_bus_ops);
        if (ret) {
                dev_err(&pdev->dev, "Failed to initialize device\n");
                goto err_init;
index c04a6c3cac7f62d3aa88ff186a29b88ee52146a5..9e3649a3d5ca310fa72b08d48aee15783a67334e 100644 (file)
@@ -1484,7 +1484,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
        if (rc->rate_table == NULL)
                return 0;
 
-       max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
+       max = 80 + rc->rate_table_size * 1024 + 1;
        buf = kmalloc(max, GFP_KERNEL);
        if (buf == NULL)
                return -ENOMEM;
@@ -1494,7 +1494,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
                       "HT", "MCS", "Rate",
                       "Success", "Retries", "XRetries", "PER");
 
-       for (i = 0; i < rc->rate_table->rate_cnt; i++) {
+       for (i = 0; i < rc->rate_table_size; i++) {
                u32 ratekbps = rc->rate_table->info[i].ratekbps;
                struct ath_rc_stats *stats = &rc->rcstats[i];
                char mcs[5];
index c3d850207bee0375c9f806cc37fea898e1985bd1..b7a4bcd3eec70f02c62f11e0a23ea7ff843813f2 100644 (file)
@@ -221,12 +221,6 @@ struct ath_rate_priv {
        struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 };
 
-enum ath9k_internal_frame_type {
-       ATH9K_IFT_NOT_INTERNAL,
-       ATH9K_IFT_PAUSE,
-       ATH9K_IFT_UNPAUSE
-};
-
 #ifdef CONFIG_ATH9K_RATE_CONTROL
 int ath_rate_control_register(void);
 void ath_rate_control_unregister(void);
index 9a4850154fb251246d07d6c3ae3935fb889769a7..74094022b654980b823e258033d7acce058b62b1 100644 (file)
@@ -601,7 +601,6 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
                ath_dbg(common, ATH_DBG_PS,
                        "Reconfigure Beacon timers based on timestamp from the AP\n");
                ath_set_beacon(sc);
-               sc->ps_flags &= ~PS_TSFOOR_SYNC;
        }
 
        if (ath_beacon_dtim_pending_cab(skb)) {
@@ -995,6 +994,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
                                   struct ieee80211_rx_status *rx_status,
                                   bool *decrypt_error)
 {
+       struct ath_hw *ah = common->ah;
+
        memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
 
        /*
@@ -1015,7 +1016,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
 
        rx_status->band = hw->conf.channel->band;
        rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
+       rx_status->signal = ah->noise + rx_stats->rs_rssi;
        rx_status->antenna = rx_stats->rs_antenna;
        rx_status->flag |= RX_FLAG_MACTIME_MPDU;
 
@@ -1783,11 +1784,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
        struct ieee80211_rx_status *rxs;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       /*
-        * The hw can technically differ from common->hw when using ath9k
-        * virtual wiphy so to account for that we iterate over the active
-        * wiphys and find the appropriate wiphy and therefore hw.
-        */
        struct ieee80211_hw *hw = sc->hw;
        struct ieee80211_hdr *hdr;
        int retval;
index cc595712f5180479c39871bd0f18af6ff2b5be2c..e1d1e903229b69c994ecc881d0632542b56d6ad5 100644 (file)
@@ -551,7 +551,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                if (clear_filter)
                        tid->ac->clear_ps_filter = true;
                list_splice(&bf_pending, &tid->buf_q);
-               ath_tx_queue_tid(txq, tid);
+               if (!an->sleeping)
+                       ath_tx_queue_tid(txq, tid);
                spin_unlock_bh(&txq->axq_lock);
        }
 
@@ -1413,7 +1414,8 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
                 */
                TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
                list_add_tail(&bf->list, &tid->buf_q);
-               ath_tx_queue_tid(txctl->txq, tid);
+               if (!txctl->an || !txctl->an->sleeping)
+                       ath_tx_queue_tid(txctl->txq, tid);
                return;
        }
 
@@ -1777,7 +1779,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
                INIT_LIST_HEAD(&bf_head);
                list_add_tail(&bf->list, &bf_head);
 
-               bf->bf_state.bfs_ftype = txctl->frame_type;
                bf->bf_state.bfs_paprd = txctl->paprd;
 
                if (bf->bf_state.bfs_paprd)
@@ -1876,7 +1877,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 /*****************/
 
 static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-                           int tx_flags, int ftype, struct ath_txq *txq)
+                           int tx_flags, struct ath_txq *txq)
 {
        struct ieee80211_hw *hw = sc->hw;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1961,8 +1962,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
                        complete(&sc->paprd_complete);
        } else {
                ath_debug_stat_tx(sc, bf, ts, txq);
-               ath_tx_complete(sc, skb, tx_flags,
-                               bf->bf_state.bfs_ftype, txq);
+               ath_tx_complete(sc, skb, tx_flags, txq);
        }
        /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
         * accidentally reference it later.
index 172f63f671cff13ba1ec728b933caddeff41d6b9..03a8268ccf21a7ca9d9c8ccf9a836c7b0d402d57 100644 (file)
@@ -101,7 +101,7 @@ enum CountryCode {
        CTRY_GERMANY = 276,
        CTRY_GREECE = 300,
        CTRY_GREENLAND = 304,
-       CTRY_GRENEDA = 308,
+       CTRY_GRENADA = 308,
        CTRY_GUAM = 316,
        CTRY_GUATEMALA = 320,
        CTRY_HAITI = 332,
index 24b53839fc3ae43176743739c510f2902f0c4aa2..bdd2b4d61f2f0f797dc40f9fe49b5d549ed6c129 100644 (file)
@@ -332,7 +332,7 @@ static struct country_code_to_enum_rd allCountries[] = {
        {CTRY_GERMANY, ETSI1_WORLD, "DE"},
        {CTRY_GREECE, ETSI1_WORLD, "GR"},
        {CTRY_GREENLAND, ETSI1_WORLD, "GL"},
-       {CTRY_GRENEDA, FCC3_FCCA, "GD"},
+       {CTRY_GRENADA, FCC3_FCCA, "GD"},
        {CTRY_GUAM, FCC1_FCCA, "GU"},
        {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
        {CTRY_HAITI, ETSI1_WORLD, "HT"},
index 3cab843afb0503f1062a41107290ca735d3e35b8..b81a2a1c26181cd1135d005903736f1f19e4d0a5 100644 (file)
@@ -114,13 +114,13 @@ config B43_PHY_N
          affect other devices support and may provide support for basic needs.
 
 config B43_PHY_LP
-       bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
-       depends on B43 && EXPERIMENTAL
+       bool "Support for low-power (LP-PHY) devices"
+       depends on B43
        default y
        ---help---
          Support for the LP-PHY.
          The LP-PHY is a low-power PHY built into some notebooks
-         and embedded devices. It supports 802.11a/g
+         and embedded devices. It supports 802.11a/b/g
          (802.11a support is optional, and currently disabled).
 
 config B43_PHY_HT
index c818b0bc88ec84fce7eb7db11d39220ff7900c08..f4e9d8b7d9f86b4b3b2c8323c45b2f820c9d3989 100644 (file)
@@ -694,6 +694,12 @@ struct b43_firmware_file {
        enum b43_firmware_file_type type;
 };
 
+enum b43_firmware_hdr_format {
+       B43_FW_HDR_598,
+       B43_FW_HDR_410,
+       B43_FW_HDR_351,
+};
+
 /* Pointers to the firmware data and meta information about it. */
 struct b43_firmware {
        /* Microcode */
@@ -710,6 +716,9 @@ struct b43_firmware {
        /* Firmware patchlevel */
        u16 patch;
 
+       /* Format of header used by firmware */
+       enum b43_firmware_hdr_format hdr_format;
+
        /* Set to true, if we are using an opensource firmware.
         * Use this to check for proprietary vs opensource. */
        bool opensource;
@@ -875,7 +884,7 @@ struct b43_wl {
        struct b43_leds leds;
 
        /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
-       u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
+       u8 pio_scratchspace[118] __attribute__((__aligned__(8)));
        u8 pio_tailspace[4] __attribute__((__aligned__(8)));
 };
 
index 481e534534eb3a437a732509c80bba6db73ff2e1..5151c7f035bde99c4bc1c7d97e38114021596843 100644 (file)
@@ -872,8 +872,17 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                ring->current_slot = -1;
        } else {
                if (ring->index == 0) {
-                       ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE;
-                       ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET;
+                       switch (dev->fw.hdr_format) {
+                       case B43_FW_HDR_598:
+                               ring->rx_buffersize = B43_DMA0_RX_FW598_BUFSIZE;
+                               ring->frameoffset = B43_DMA0_RX_FW598_FO;
+                               break;
+                       case B43_FW_HDR_410:
+                       case B43_FW_HDR_351:
+                               ring->rx_buffersize = B43_DMA0_RX_FW351_BUFSIZE;
+                               ring->frameoffset = B43_DMA0_RX_FW351_FO;
+                               break;
+                       }
                } else
                        B43_WARN_ON(1);
        }
index cdf87094efe8270a9b20c06c66a5b59e125c9f18..546d19cbf5d59ef76e907988f059581d475b7b61 100644 (file)
@@ -162,12 +162,15 @@ struct b43_dmadesc_generic {
 
 /* Misc DMA constants */
 #define B43_DMA_RINGMEMSIZE            PAGE_SIZE
-#define B43_DMA0_RX_FRAMEOFFSET                30
+/* Offset of frame with actual data */
+#define B43_DMA0_RX_FW598_FO           38
+#define B43_DMA0_RX_FW351_FO           30
 
 /* DMA engine tuning knobs */
 #define B43_TXRING_SLOTS               256
 #define B43_RXRING_SLOTS               64
-#define B43_DMA0_RX_BUFFERSIZE         (B43_DMA0_RX_FRAMEOFFSET + IEEE80211_MAX_FRAME_LEN)
+#define B43_DMA0_RX_FW598_BUFSIZE      (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
+#define B43_DMA0_RX_FW351_BUFSIZE      (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
 
 /* Pointer poison */
 #define B43_DMA_PTR_POISON             ((void *)ERR_PTR(-ENOMEM))
index 26f1ab840cc7b60c162c43d67b567de2d9b76f06..b5e83057dab3719f38afc558dafc04811ce37e9e 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
-#include <linux/wireless.h>
 #include <linux/workqueue.h>
 #include <linux/skbuff.h>
 #include <linux/io.h>
@@ -115,6 +114,7 @@ MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
 #ifdef CONFIG_B43_BCMA
 static const struct bcma_device_id b43_bcma_tbl[] = {
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
@@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev);
 static int b43_wireless_core_init(struct b43_wldev *dev);
 static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
 static int b43_wireless_core_start(struct b43_wldev *dev);
+static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_bss_conf *conf,
+                                   u32 changed);
 
 static int b43_ratelimit(struct b43_wl *wl)
 {
@@ -2510,6 +2514,12 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        }
        dev->fw.rev = fwrev;
        dev->fw.patch = fwpatch;
+       if (dev->fw.rev >= 598)
+               dev->fw.hdr_format = B43_FW_HDR_598;
+       else if (dev->fw.rev >= 410)
+               dev->fw.hdr_format = B43_FW_HDR_410;
+       else
+               dev->fw.hdr_format = B43_FW_HDR_351;
        dev->fw.opensource = (fwdate == 0xFFFF);
 
        /* Default to use-all-queues. */
@@ -2557,7 +2567,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
                        dev->fw.rev, dev->fw.patch);
        wiphy->hw_version = dev->dev->core_id;
 
-       if (b43_is_old_txhdr_format(dev)) {
+       if (dev->fw.hdr_format == B43_FW_HDR_351) {
                /* We're over the deadline, but we keep support for old fw
                 * until it turns out to be in major conflict with something new. */
                b43warn(dev->wl, "You are using an old firmware image. "
@@ -2943,6 +2953,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
        case B43_PHYTYPE_G:
        case B43_PHYTYPE_N:
        case B43_PHYTYPE_LP:
+       case B43_PHYTYPE_HT:
                b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
                b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
                b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
@@ -3778,14 +3789,24 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        struct ieee80211_conf *conf = &hw->conf;
        int antenna;
        int err = 0;
+       bool reload_bss = false;
 
        mutex_lock(&wl->mutex);
 
+       dev = wl->current_dev;
+
        /* Switch the band (if necessary). This might change the active core. */
        err = b43_switch_band(wl, conf->channel);
        if (err)
                goto out_unlock_mutex;
-       dev = wl->current_dev;
+
+       /* Need to reload all settings if the core changed */
+       if (dev != wl->current_dev) {
+               dev = wl->current_dev;
+               changed = ~0;
+               reload_bss = true;
+       }
+
        phy = &dev->phy;
 
        if (conf_is_ht(conf))
@@ -3846,6 +3867,9 @@ out_mac_enable:
 out_unlock_mutex:
        mutex_unlock(&wl->mutex);
 
+       if (wl->vif && reload_bss)
+               b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
+
        return err;
 }
 
@@ -3934,7 +3958,8 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_BEACON_INT &&
            (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
             b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
-            b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+            b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
+           conf->beacon_int)
                b43_set_beacon_int(dev, conf->beacon_int);
 
        if (changed & BSS_CHANGED_BASIC_RATES)
@@ -4702,6 +4727,9 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
  out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
+       if (err == 0)
+               b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
+
        return err;
 }
 
@@ -4772,6 +4800,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
  out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
+       /* reload configuration */
+       b43_op_config(hw, ~0);
+
        return err;
 }
 
@@ -4928,10 +4959,18 @@ out:
        if (err)
                wl->current_dev = NULL; /* Failed to init the dev. */
        mutex_unlock(&wl->mutex);
-       if (err)
+
+       if (err) {
                b43err(wl, "Controller restart FAILED\n");
-       else
-               b43info(wl, "Controller restarted\n");
+               return;
+       }
+
+       /* reload configuration */
+       b43_op_config(wl->hw, ~0);
+       if (wl->vif)
+               b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
+
+       b43info(wl, "Controller restarted\n");
 }
 
 static int b43_setup_bands(struct b43_wldev *dev,
index 07f009ff5ee2bfdf58a87002a24b6702c24e2b85..3ea44bb036844ef4a5da47b91ffd80ec8a18ec31 100644 (file)
@@ -448,6 +448,38 @@ bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
                channel_type == NL80211_CHAN_HT40PLUS);
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
+void b43_phy_force_clock(struct b43_wldev *dev, bool force)
+{
+       u32 tmp;
+
+       WARN_ON(dev->phy.type != B43_PHYTYPE_N &&
+               dev->phy.type != B43_PHYTYPE_HT);
+
+       switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+       case B43_BUS_BCMA:
+               tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
+               if (force)
+                       tmp |= BCMA_IOCTL_FGC;
+               else
+                       tmp &= ~BCMA_IOCTL_FGC;
+               bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
+               break;
+#endif
+#ifdef CONFIG_B43_SSB
+       case B43_BUS_SSB:
+               tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
+               if (force)
+                       tmp |= SSB_TMSLOW_FGC;
+               else
+                       tmp &= ~SSB_TMSLOW_FGC;
+               ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
+               break;
+#endif
+       }
+}
+
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
 struct b43_c32 b43_cordic(int theta)
 {
index aa77ba612a92fac3e127c8a6f4a505e922438aba..9233b13fc16d8a205eb474a3870f59bc3b6b7e8c 100644 (file)
@@ -444,6 +444,8 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
 
 bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
 
+void b43_phy_force_clock(struct b43_wldev *dev, bool force);
+
 struct b43_c32 b43_cordic(int theta);
 
 #endif /* LINUX_B43_PHY_COMMON_H_ */
index 7c40919651a741d5eca93cf9d447275591a425e0..62a90842ebfcd2031fed4fbf91cba30c6ac41eaf 100644 (file)
@@ -151,6 +151,64 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
        b43_radio_mask(dev, 0x11, ~0x0008);
 }
 
+/**************************************************
+ * Various PHY ops
+ **************************************************/
+
+static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
+{
+       u8 i, j;
+       u16 base[] = { 0x40, 0x60, 0x80 };
+
+       for (i = 0; i < ARRAY_SIZE(base); i++) {
+               for (j = 0; j < 4; j++)
+                       b43_phy_write(dev, B43_PHY_EXTG(base[i] + j), 0);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(base); i++)
+               b43_phy_write(dev, B43_PHY_EXTG(base[i] + 0xc), 0);
+}
+
+/* Some unknown AFE (Analog Frondned) op */
+static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
+{
+       u8 i;
+
+       const u16 ctl_regs[3][2] = {
+               { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 },
+               { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 },
+               { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6},
+       };
+
+       for (i = 0; i < 3; i++) {
+               /* TODO: verify masks&sets */
+               b43_phy_set(dev, ctl_regs[i][1], 0x4);
+               b43_phy_set(dev, ctl_regs[i][0], 0x4);
+               b43_phy_mask(dev, ctl_regs[i][1], ~0x1);
+               b43_phy_set(dev, ctl_regs[i][0], 0x1);
+               b43_httab_write(dev, B43_HTTAB16(8, 5 + (i * 0x10)), 0);
+               b43_phy_mask(dev, ctl_regs[i][0], ~0x4);
+       }
+}
+
+static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
+{
+       unsigned int i;
+       u16 val;
+
+       val = 0x1E1F;
+       for (i = 0; i < 16; i++) {
+               b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
+               val -= 0x202;
+       }
+       val = 0x3E3F;
+       for (i = 0; i < 16; i++) {
+               b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val);
+               val -= 0x202;
+       }
+       b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
+}
+
 /**************************************************
  * Channel switching ops.
  **************************************************/
@@ -255,8 +313,130 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
 
 static int b43_phy_ht_op_init(struct b43_wldev *dev)
 {
+       u8 i;
+       u16 tmp;
+
        b43_phy_ht_tables_init(dev);
 
+       b43_phy_mask(dev, 0x0be, ~0x2);
+       b43_phy_set(dev, 0x23f, 0x7ff);
+       b43_phy_set(dev, 0x240, 0x7ff);
+       b43_phy_set(dev, 0x241, 0x7ff);
+
+       b43_phy_ht_zero_extg(dev);
+
+       b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);
+
+       b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0);
+       b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0);
+       b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0);
+
+       b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
+       b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
+       b43_phy_write(dev, 0x20d, 0xb8);
+       b43_phy_write(dev, B43_PHY_EXTG(0x14f), 0xc8);
+       b43_phy_write(dev, 0x70, 0x50);
+       b43_phy_write(dev, 0x1ff, 0x30);
+
+       if (0) /* TODO: condition */
+               ; /* TODO: PHY op on reg 0x217 */
+
+       b43_phy_read(dev, 0xb0); /* TODO: what for? */
+       b43_phy_set(dev, 0xb0, 0x1);
+
+       b43_phy_set(dev, 0xb1, 0x91);
+       b43_phy_write(dev, 0x32f, 0x0003);
+       b43_phy_write(dev, 0x077, 0x0010);
+       b43_phy_write(dev, 0x0b4, 0x0258);
+       b43_phy_mask(dev, 0x17e, ~0x4000);
+
+       b43_phy_write(dev, 0x0b9, 0x0072);
+
+       b43_httab_write_few(dev, B43_HTTAB16(7, 0x14e), 2, 0x010f, 0x010f);
+       b43_httab_write_few(dev, B43_HTTAB16(7, 0x15e), 2, 0x010f, 0x010f);
+       b43_httab_write_few(dev, B43_HTTAB16(7, 0x16e), 2, 0x010f, 0x010f);
+
+       b43_phy_ht_afe_unk1(dev);
+
+       b43_httab_write_few(dev, B43_HTTAB16(7, 0x130), 9, 0x777, 0x111, 0x111,
+                           0x777, 0x111, 0x111, 0x777, 0x111, 0x111);
+
+       b43_httab_write(dev, B43_HTTAB16(7, 0x120), 0x0777);
+       b43_httab_write(dev, B43_HTTAB16(7, 0x124), 0x0777);
+
+       b43_httab_write(dev, B43_HTTAB16(8, 0x00), 0x02);
+       b43_httab_write(dev, B43_HTTAB16(8, 0x10), 0x02);
+       b43_httab_write(dev, B43_HTTAB16(8, 0x20), 0x02);
+
+       b43_httab_write_few(dev, B43_HTTAB16(8, 0x08), 4,
+                           0x8e, 0x96, 0x96, 0x96);
+       b43_httab_write_few(dev, B43_HTTAB16(8, 0x18), 4,
+                           0x8f, 0x9f, 0x9f, 0x9f);
+       b43_httab_write_few(dev, B43_HTTAB16(8, 0x28), 4,
+                           0x8f, 0x9f, 0x9f, 0x9f);
+
+       b43_httab_write_few(dev, B43_HTTAB16(8, 0x0c), 4, 0x2, 0x2, 0x2, 0x2);
+       b43_httab_write_few(dev, B43_HTTAB16(8, 0x1c), 4, 0x2, 0x2, 0x2, 0x2);
+       b43_httab_write_few(dev, B43_HTTAB16(8, 0x2c), 4, 0x2, 0x2, 0x2, 0x2);
+
+       b43_phy_maskset(dev, 0x0280, 0xff00, 0x3e);
+       b43_phy_maskset(dev, 0x0283, 0xff00, 0x3e);
+       b43_phy_maskset(dev, B43_PHY_OFDM(0x0141), 0xff00, 0x46);
+       b43_phy_maskset(dev, 0x0283, 0xff00, 0x40);
+
+       b43_httab_write_few(dev, B43_HTTAB16(00, 0x8), 4,
+                           0x09, 0x0e, 0x13, 0x18);
+       b43_httab_write_few(dev, B43_HTTAB16(01, 0x8), 4,
+                           0x09, 0x0e, 0x13, 0x18);
+       /* TODO: Did wl mean 2 instead of 40? */
+       b43_httab_write_few(dev, B43_HTTAB16(40, 0x8), 4,
+                           0x09, 0x0e, 0x13, 0x18);
+
+       b43_phy_maskset(dev, B43_PHY_OFDM(0x24), 0x3f, 0xd);
+       b43_phy_maskset(dev, B43_PHY_OFDM(0x64), 0x3f, 0xd);
+       b43_phy_maskset(dev, B43_PHY_OFDM(0xa4), 0x3f, 0xd);
+
+       b43_phy_set(dev, B43_PHY_EXTG(0x060), 0x1);
+       b43_phy_set(dev, B43_PHY_EXTG(0x064), 0x1);
+       b43_phy_set(dev, B43_PHY_EXTG(0x080), 0x1);
+       b43_phy_set(dev, B43_PHY_EXTG(0x084), 0x1);
+
+       /* Copy some tables entries */
+       tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x144));
+       b43_httab_write(dev, B43_HTTAB16(7, 0x14a), tmp);
+       tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x154));
+       b43_httab_write(dev, B43_HTTAB16(7, 0x15a), tmp);
+       tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x164));
+       b43_httab_write(dev, B43_HTTAB16(7, 0x16a), tmp);
+
+       /* Reset CCA */
+       b43_phy_force_clock(dev, true);
+       tmp = b43_phy_read(dev, B43_PHY_HT_BBCFG);
+       b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp | B43_PHY_HT_BBCFG_RSTCCA);
+       b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp & ~B43_PHY_HT_BBCFG_RSTCCA);
+       b43_phy_force_clock(dev, false);
+
+       b43_mac_phy_clock_set(dev, true);
+
+       for (i = 0; i < 2; i++) {
+               tmp = b43_phy_read(dev, B43_PHY_EXTG(0));
+               b43_phy_set(dev, B43_PHY_EXTG(0), 0x3);
+               b43_phy_set(dev, B43_PHY_EXTG(3), i ? 0x20 : 0x1);
+               /* FIXME: wait for some bit to be cleared (find out which) */
+               b43_phy_read(dev, B43_PHY_EXTG(4));
+               b43_phy_write(dev, B43_PHY_EXTG(0), tmp);
+       }
+
+       /* TODO: PHY op on reg 0xb0 */
+
+       /* TODO: PHY ops on regs 0x40e, 0x44e, 0x48e */
+
+       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+               b43_phy_ht_bphy_init(dev);
+
+       b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0),
+                       B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late);
+
        return 0;
 }
 
index 7ad7affc8df08b8bc9e2caa7a03f5cb4e4e8e431..f70af0caaa334596447bea3618f4dfdea64d7814 100644 (file)
@@ -4,7 +4,11 @@
 #include "phy_common.h"
 
 
+#define B43_PHY_HT_BBCFG                       0x001 /* BB config */
+#define  B43_PHY_HT_BBCFG_RSTCCA               0x4000 /* Reset CCA */
+#define  B43_PHY_HT_BBCFG_RSTRX                        0x8000 /* Reset RX */
 #define B43_PHY_HT_BANDCTL                     0x009 /* Band control */
+#define  B43_PHY_HT_BANDCTL_5GHZ               0x0001 /* Use the 5GHz band */
 #define B43_PHY_HT_TABLE_ADDR                  0x072 /* Table address */
 #define B43_PHY_HT_TABLE_DATALO                        0x073 /* Table data low */
 #define B43_PHY_HT_TABLE_DATAHI                        0x074 /* Table data high */
index 3b46360da99b5790dac9020ceaa055dad8131f2b..2eadadf5f4fc375ced006719086846a624182a04 100644 (file)
@@ -600,49 +600,17 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
        }
 }
 
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
-static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
-{
-       u32 tmp;
-
-       if (dev->phy.type != B43_PHYTYPE_N)
-               return;
-
-       switch (dev->dev->bus_type) {
-#ifdef CONFIG_B43_BCMA
-       case B43_BUS_BCMA:
-               tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
-               if (force)
-                       tmp |= BCMA_IOCTL_FGC;
-               else
-                       tmp &= ~BCMA_IOCTL_FGC;
-               bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
-               break;
-#endif
-#ifdef CONFIG_B43_SSB
-       case B43_BUS_SSB:
-               tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
-               if (force)
-                       tmp |= SSB_TMSLOW_FGC;
-               else
-                       tmp &= ~SSB_TMSLOW_FGC;
-               ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
-               break;
-#endif
-       }
-}
-
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
 static void b43_nphy_reset_cca(struct b43_wldev *dev)
 {
        u16 bbcfg;
 
-       b43_nphy_bmac_clock_fgc(dev, 1);
+       b43_phy_force_clock(dev, 1);
        bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
        b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA);
        udelay(1);
        b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
-       b43_nphy_bmac_clock_fgc(dev, 0);
+       b43_phy_force_clock(dev, 0);
        b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
 }
 
@@ -3715,11 +3683,11 @@ int b43_phy_initn(struct b43_wldev *dev)
        b43_nphy_workarounds(dev);
 
        /* Reset CCA, in init code it differs a little from standard way */
-       b43_nphy_bmac_clock_fgc(dev, 1);
+       b43_phy_force_clock(dev, 1);
        tmp = b43_phy_read(dev, B43_NPHY_BBCFG);
        b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA);
        b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
-       b43_nphy_bmac_clock_fgc(dev, 0);
+       b43_phy_force_clock(dev, 0);
 
        b43_mac_phy_clock_set(dev, true);
 
index 6e4228c3ed1bde3b6e143bd06add80399ff334fe..ce8a4bdc7e1dbe5e1364b36f5d730c50161d9ed7 100644 (file)
@@ -676,7 +676,15 @@ data_ready:
                goto rx_error;
        }
 
-       macstat = le32_to_cpu(rxhdr->mac_status);
+       switch (dev->fw.hdr_format) {
+       case B43_FW_HDR_598:
+               macstat = le32_to_cpu(rxhdr->format_598.mac_status);
+               break;
+       case B43_FW_HDR_410:
+       case B43_FW_HDR_351:
+               macstat = le32_to_cpu(rxhdr->format_351.mac_status);
+               break;
+       }
        if (macstat & B43_RX_MAC_FCSERR) {
                if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
                        /* Drop frames with failed FCS. */
index 603938657b159d77f4dc91c8a70abe65de14a610..2127bd2ad87700dc0e3a1d48974c6dd891a0d0d1 100644 (file)
@@ -574,6 +574,42 @@ static const u32 b43_httab_0x24[] = {
        0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c,
 };
 
+/* Some late-init table */
+const u32 b43_httab_0x1a_0xc0_late[] = {
+       0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
+       0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
+       0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
+       0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
+       0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
+       0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
+       0x10390038, 0x10390035, 0x1031003a, 0x10310036,
+       0x10310033, 0x1029003a, 0x10290037, 0x10290034,
+       0x10290031, 0x10210039, 0x10210036, 0x10210033,
+       0x10210030, 0x1019003c, 0x10190039, 0x10190036,
+       0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
+       0x10190028, 0x1011003a, 0x10110036, 0x10110033,
+       0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
+       0x10110027, 0x10110024, 0x10110022, 0x10110020,
+       0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
+       0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
+       0x10090029, 0x10090027, 0x10090025, 0x10090023,
+       0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
+       0x1009001a, 0x10090018, 0x10090017, 0x10090016,
+       0x10090015, 0x10090013, 0x10090012, 0x10090011,
+       0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
+       0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
+       0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
+       0x10090008, 0x10090008, 0x10090007, 0x10090007,
+       0x10090007, 0x10090006, 0x10090006, 0x10090005,
+       0x10090005, 0x10090005, 0x10090005, 0x10090004,
+       0x10090004, 0x10090004, 0x10090004, 0x10090003,
+       0x10090003, 0x10090003, 0x10090003, 0x10090003,
+       0x10090003, 0x10090002, 0x10090002, 0x10090002,
+       0x10090002, 0x10090002, 0x10090002, 0x10090002,
+       0x10090002, 0x10090002, 0x10090001, 0x10090001,
+       0x10090001, 0x10090001, 0x10090001, 0x10090001,
+};
+
 /**************************************************
  * R/W ops.
  **************************************************/
@@ -723,6 +759,9 @@ void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
        } while (0)
 void b43_phy_ht_tables_init(struct b43_wldev *dev)
 {
+       BUILD_BUG_ON(ARRAY_SIZE(b43_httab_0x1a_0xc0_late) !=
+                       B43_HTTAB_1A_C0_LATE_SIZE);
+
        httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12);
        httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27);
        httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26);
index ea3be382c8945b70e010925c94ad446c59a1a70a..bd20e9a818ea62bdb1da39b0ebe11004b3d5fb5f 100644 (file)
@@ -19,4 +19,7 @@ void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
 
 void b43_phy_ht_tables_init(struct b43_wldev *dev);
 
+#define B43_HTTAB_1A_C0_LATE_SIZE              128
+extern const u32 b43_httab_0x1a_0xc0_late[];
+
 #endif /* B43_TABLES_PHY_HT_H_ */
index b74f25ec1ab4a89b4c1380b9ca9213b396a0ca49..b8de62c22479409a3d57904d41e8871d1ff4a716 100644 (file)
@@ -337,12 +337,19 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                        memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
                }
        }
-       if (b43_is_old_txhdr_format(dev)) {
-               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
+       switch (dev->fw.hdr_format) {
+       case B43_FW_HDR_598:
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_598.plcp),
                                      plcp_fragment_len, rate);
-       } else {
-               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->new_format.plcp),
+               break;
+       case B43_FW_HDR_351:
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_351.plcp),
+                                     plcp_fragment_len, rate);
+               break;
+       case B43_FW_HDR_410:
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_410.plcp),
                                      plcp_fragment_len, rate);
+               break;
        }
        b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
                              plcp_fragment_len, rate_fb);
@@ -415,10 +422,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
            (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
                unsigned int len;
-               struct ieee80211_hdr *hdr;
+               struct ieee80211_hdr *uninitialized_var(hdr);
                int rts_rate, rts_rate_fb;
                int rts_rate_ofdm, rts_rate_fb_ofdm;
-               struct b43_plcp_hdr6 *plcp;
+               struct b43_plcp_hdr6 *uninitialized_var(plcp);
                struct ieee80211_rate *rts_cts_rate;
 
                rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
@@ -429,14 +436,21 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
 
                if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-                       struct ieee80211_cts *cts;
+                       struct ieee80211_cts *uninitialized_var(cts);
 
-                       if (b43_is_old_txhdr_format(dev)) {
+                       switch (dev->fw.hdr_format) {
+                       case B43_FW_HDR_598:
                                cts = (struct ieee80211_cts *)
-                                       (txhdr->old_format.rts_frame);
-                       } else {
+                                       (txhdr->format_598.rts_frame);
+                               break;
+                       case B43_FW_HDR_351:
                                cts = (struct ieee80211_cts *)
-                                       (txhdr->new_format.rts_frame);
+                                       (txhdr->format_351.rts_frame);
+                               break;
+                       case B43_FW_HDR_410:
+                               cts = (struct ieee80211_cts *)
+                                       (txhdr->format_410.rts_frame);
+                               break;
                        }
                        ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
                                                fragment_data, fragment_len,
@@ -444,14 +458,21 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                        mac_ctl |= B43_TXH_MAC_SENDCTS;
                        len = sizeof(struct ieee80211_cts);
                } else {
-                       struct ieee80211_rts *rts;
+                       struct ieee80211_rts *uninitialized_var(rts);
 
-                       if (b43_is_old_txhdr_format(dev)) {
+                       switch (dev->fw.hdr_format) {
+                       case B43_FW_HDR_598:
                                rts = (struct ieee80211_rts *)
-                                       (txhdr->old_format.rts_frame);
-                       } else {
+                                       (txhdr->format_598.rts_frame);
+                               break;
+                       case B43_FW_HDR_351:
+                               rts = (struct ieee80211_rts *)
+                                       (txhdr->format_351.rts_frame);
+                               break;
+                       case B43_FW_HDR_410:
                                rts = (struct ieee80211_rts *)
-                                       (txhdr->new_format.rts_frame);
+                                       (txhdr->format_410.rts_frame);
+                               break;
                        }
                        ieee80211_rts_get(dev->wl->hw, info->control.vif,
                                          fragment_data, fragment_len,
@@ -462,22 +483,36 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                len += FCS_LEN;
 
                /* Generate the PLCP headers for the RTS/CTS frame */
-               if (b43_is_old_txhdr_format(dev))
-                       plcp = &txhdr->old_format.rts_plcp;
-               else
-                       plcp = &txhdr->new_format.rts_plcp;
+               switch (dev->fw.hdr_format) {
+               case B43_FW_HDR_598:
+                       plcp = &txhdr->format_598.rts_plcp;
+                       break;
+               case B43_FW_HDR_351:
+                       plcp = &txhdr->format_351.rts_plcp;
+                       break;
+               case B43_FW_HDR_410:
+                       plcp = &txhdr->format_410.rts_plcp;
+                       break;
+               }
                b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
                                      len, rts_rate);
                plcp = &txhdr->rts_plcp_fb;
                b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
                                      len, rts_rate_fb);
 
-               if (b43_is_old_txhdr_format(dev)) {
+               switch (dev->fw.hdr_format) {
+               case B43_FW_HDR_598:
                        hdr = (struct ieee80211_hdr *)
-                               (&txhdr->old_format.rts_frame);
-               } else {
+                               (&txhdr->format_598.rts_frame);
+                       break;
+               case B43_FW_HDR_351:
+                       hdr = (struct ieee80211_hdr *)
+                               (&txhdr->format_351.rts_frame);
+                       break;
+               case B43_FW_HDR_410:
                        hdr = (struct ieee80211_hdr *)
-                               (&txhdr->new_format.rts_frame);
+                               (&txhdr->format_410.rts_frame);
+                       break;
                }
                txhdr->rts_dur_fb = hdr->duration_id;
 
@@ -505,10 +540,17 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        }
 
        /* Magic cookie */
-       if (b43_is_old_txhdr_format(dev))
-               txhdr->old_format.cookie = cpu_to_le16(cookie);
-       else
-               txhdr->new_format.cookie = cpu_to_le16(cookie);
+       switch (dev->fw.hdr_format) {
+       case B43_FW_HDR_598:
+               txhdr->format_598.cookie = cpu_to_le16(cookie);
+               break;
+       case B43_FW_HDR_351:
+               txhdr->format_351.cookie = cpu_to_le16(cookie);
+               break;
+       case B43_FW_HDR_410:
+               txhdr->format_410.cookie = cpu_to_le16(cookie);
+               break;
+       }
 
        if (phy->type == B43_PHYTYPE_N) {
                txhdr->phy_ctl1 =
@@ -611,8 +653,9 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
        struct ieee80211_hdr *wlhdr;
        const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
        __le16 fctl;
-       u16 phystat0, phystat3, chanstat, mactime;
-       u32 macstat;
+       u16 phystat0, phystat3;
+       u16 uninitialized_var(chanstat), uninitialized_var(mactime);
+       u32 uninitialized_var(macstat);
        u16 chanid;
        u16 phytype;
        int padding;
@@ -622,9 +665,19 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
        /* Get metadata about the frame from the header. */
        phystat0 = le16_to_cpu(rxhdr->phy_status0);
        phystat3 = le16_to_cpu(rxhdr->phy_status3);
-       macstat = le32_to_cpu(rxhdr->mac_status);
-       mactime = le16_to_cpu(rxhdr->mac_time);
-       chanstat = le16_to_cpu(rxhdr->channel);
+       switch (dev->fw.hdr_format) {
+       case B43_FW_HDR_598:
+               macstat = le32_to_cpu(rxhdr->format_598.mac_status);
+               mactime = le16_to_cpu(rxhdr->format_598.mac_time);
+               chanstat = le16_to_cpu(rxhdr->format_598.channel);
+               break;
+       case B43_FW_HDR_410:
+       case B43_FW_HDR_351:
+               macstat = le32_to_cpu(rxhdr->format_351.mac_status);
+               mactime = le16_to_cpu(rxhdr->format_351.mac_time);
+               chanstat = le16_to_cpu(rxhdr->format_351.channel);
+               break;
+       }
        phytype = chanstat & B43_RX_CHAN_PHYTYPE;
 
        if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
@@ -744,6 +797,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
                break;
        case B43_PHYTYPE_N:
        case B43_PHYTYPE_LP:
+       case B43_PHYTYPE_HT:
                /* chanid is the SHM channel cookie. Which is the plain
                 * channel number in b43. */
                if (chanstat & B43_RX_CHAN_5GHZ) {
index 42debb5cd6fad0b042c579079ae325f2ecbb0a50..f6e8bc436d5a20028818e155369600279db285af 100644 (file)
@@ -46,7 +46,24 @@ struct b43_txhdr {
        __le32 timeout;                 /* Timeout */
 
        union {
-               /* The new r410 format. */
+               /* Tested with 598.314, 644.1001 and 666.2 */
+               struct {
+                       __le16 mimo_antenna;            /* MIMO antenna select */
+                       __le16 preload_size;            /* Preload size */
+                       PAD_BYTES(2);
+                       __le16 cookie;                  /* TX frame cookie */
+                       __le16 tx_status;               /* TX status */
+                       __le16 max_n_mpdus;
+                       __le16 max_a_bytes_mrt;
+                       __le16 max_a_bytes_fbr;
+                       __le16 min_m_bytes;
+                       struct b43_plcp_hdr6 rts_plcp;  /* RTS PLCP header */
+                       __u8 rts_frame[16];             /* The RTS frame (if used) */
+                       PAD_BYTES(2);
+                       struct b43_plcp_hdr6 plcp;      /* Main PLCP header */
+               } format_598 __packed;
+
+               /* Tested with 410.2160, 478.104 and 508.* */
                struct {
                        __le16 mimo_antenna;            /* MIMO antenna select */
                        __le16 preload_size;            /* Preload size */
@@ -57,9 +74,9 @@ struct b43_txhdr {
                        __u8 rts_frame[16];             /* The RTS frame (if used) */
                        PAD_BYTES(2);
                        struct b43_plcp_hdr6 plcp;      /* Main PLCP header */
-               } new_format __packed;
+               } format_410 __packed;
 
-               /* The old r351 format. */
+               /* Tested with 351.126 */
                struct {
                        PAD_BYTES(2);
                        __le16 cookie;                  /* TX frame cookie */
@@ -68,7 +85,7 @@ struct b43_txhdr {
                        __u8 rts_frame[16];             /* The RTS frame (if used) */
                        PAD_BYTES(2);
                        struct b43_plcp_hdr6 plcp;      /* Main PLCP header */
-               } old_format __packed;
+               } format_351 __packed;
 
        } __packed;
 } __packed;
@@ -166,19 +183,18 @@ struct b43_tx_legacy_rate_phy_ctl_entry {
 #define  B43_TXH_PHY1_MODUL_QAM256     0x2000 /* QAM256 */
 
 
-/* r351 firmware compatibility stuff. */
-static inline
-bool b43_is_old_txhdr_format(struct b43_wldev *dev)
-{
-       return (dev->fw.rev <= 351);
-}
-
 static inline
 size_t b43_txhdr_size(struct b43_wldev *dev)
 {
-       if (b43_is_old_txhdr_format(dev))
+       switch (dev->fw.hdr_format) {
+       case B43_FW_HDR_598:
+               return 112 + sizeof(struct b43_plcp_hdr6);
+       case B43_FW_HDR_410:
+               return 104 + sizeof(struct b43_plcp_hdr6);
+       case B43_FW_HDR_351:
                return 100 + sizeof(struct b43_plcp_hdr6);
-       return 104 + sizeof(struct b43_plcp_hdr6);
+       }
+       return 0;
 }
 
 
@@ -234,9 +250,23 @@ struct b43_rxhdr_fw4 {
        } __packed;
        __le16 phy_status2;     /* PHY RX Status 2 */
        __le16 phy_status3;     /* PHY RX Status 3 */
-       __le32 mac_status;      /* MAC RX status */
-       __le16 mac_time;
-       __le16 channel;
+       union {
+               /* Tested with 598.314, 644.1001 and 666.2 */
+               struct {
+                       __le16 phy_status4;     /* PHY RX Status 4 */
+                       __le16 phy_status5;     /* PHY RX Status 5 */
+                       __le32 mac_status;      /* MAC RX status */
+                       __le16 mac_time;
+                       __le16 channel;
+               } format_598 __packed;
+
+               /* Tested with 351.126, 410.2160, 478.104 and 508.* */
+               struct {
+                       __le32 mac_status;      /* MAC RX status */
+                       __le16 mac_time;
+                       __le16 channel;
+               } format_351 __packed;
+       } __packed;
 } __packed;
 
 /* PHY RX Status 0 */
index a610a352102aebf3d9d5136cf0e4abd215bec782..ad4e743e476586554a25d523c7055bb78eab3499 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_driver_chipcommon.h>
 
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 
 #include "debugfs.h"
index 5010c477abdfe2f63fbc4e56e6d76d8be5c4b3e9..c5535adf69914fcb6c4890a05d3a9472514de2a4 100644 (file)
 
 /* 32bit DMA ops. */
 static
-struct b43legacy_dmadesc_generic *op32_idx2desc(
-                                       struct b43legacy_dmaring *ring,
-                                       int slot,
-                                       struct b43legacy_dmadesc_meta **meta)
+struct b43legacy_dmadesc32 *op32_idx2desc(struct b43legacy_dmaring *ring,
+                                         int slot,
+                                         struct b43legacy_dmadesc_meta **meta)
 {
        struct b43legacy_dmadesc32 *desc;
 
@@ -53,11 +52,11 @@ struct b43legacy_dmadesc_generic *op32_idx2desc(
        desc = ring->descbase;
        desc = &(desc[slot]);
 
-       return (struct b43legacy_dmadesc_generic *)desc;
+       return (struct b43legacy_dmadesc32 *)desc;
 }
 
 static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
-                                struct b43legacy_dmadesc_generic *desc,
+                                struct b43legacy_dmadesc32 *desc,
                                 dma_addr_t dmaaddr, u16 bufsize,
                                 int start, int end, int irq)
 {
@@ -67,7 +66,7 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
        u32 addr;
        u32 addrext;
 
-       slot = (int)(&(desc->dma32) - descbase);
+       slot = (int)(desc - descbase);
        B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
 
        addr = (u32)(dmaaddr & ~SSB_DMA_TRANSLATION_MASK);
@@ -87,8 +86,8 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
        ctl |= (addrext << B43legacy_DMA32_DCTL_ADDREXT_SHIFT)
               & B43legacy_DMA32_DCTL_ADDREXT_MASK;
 
-       desc->dma32.control = cpu_to_le32(ctl);
-       desc->dma32.address = cpu_to_le32(addr);
+       desc->control = cpu_to_le32(ctl);
+       desc->address = cpu_to_le32(addr);
 }
 
 static void op32_poke_tx(struct b43legacy_dmaring *ring, int slot)
@@ -128,121 +127,6 @@ static void op32_set_current_rxslot(struct b43legacy_dmaring *ring,
                            (u32)(slot * sizeof(struct b43legacy_dmadesc32)));
 }
 
-static const struct b43legacy_dma_ops dma32_ops = {
-       .idx2desc               = op32_idx2desc,
-       .fill_descriptor        = op32_fill_descriptor,
-       .poke_tx                = op32_poke_tx,
-       .tx_suspend             = op32_tx_suspend,
-       .tx_resume              = op32_tx_resume,
-       .get_current_rxslot     = op32_get_current_rxslot,
-       .set_current_rxslot     = op32_set_current_rxslot,
-};
-
-/* 64bit DMA ops. */
-static
-struct b43legacy_dmadesc_generic *op64_idx2desc(
-                                       struct b43legacy_dmaring *ring,
-                                       int slot,
-                                       struct b43legacy_dmadesc_meta
-                                       **meta)
-{
-       struct b43legacy_dmadesc64 *desc;
-
-       *meta = &(ring->meta[slot]);
-       desc = ring->descbase;
-       desc = &(desc[slot]);
-
-       return (struct b43legacy_dmadesc_generic *)desc;
-}
-
-static void op64_fill_descriptor(struct b43legacy_dmaring *ring,
-                                struct b43legacy_dmadesc_generic *desc,
-                                dma_addr_t dmaaddr, u16 bufsize,
-                                int start, int end, int irq)
-{
-       struct b43legacy_dmadesc64 *descbase = ring->descbase;
-       int slot;
-       u32 ctl0 = 0;
-       u32 ctl1 = 0;
-       u32 addrlo;
-       u32 addrhi;
-       u32 addrext;
-
-       slot = (int)(&(desc->dma64) - descbase);
-       B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
-
-       addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
-       addrhi = (((u64)dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
-       addrext = (((u64)dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
-                 >> SSB_DMA_TRANSLATION_SHIFT;
-       addrhi |= ring->dev->dma.translation;
-       if (slot == ring->nr_slots - 1)
-               ctl0 |= B43legacy_DMA64_DCTL0_DTABLEEND;
-       if (start)
-               ctl0 |= B43legacy_DMA64_DCTL0_FRAMESTART;
-       if (end)
-               ctl0 |= B43legacy_DMA64_DCTL0_FRAMEEND;
-       if (irq)
-               ctl0 |= B43legacy_DMA64_DCTL0_IRQ;
-       ctl1 |= (bufsize - ring->frameoffset)
-               & B43legacy_DMA64_DCTL1_BYTECNT;
-       ctl1 |= (addrext << B43legacy_DMA64_DCTL1_ADDREXT_SHIFT)
-               & B43legacy_DMA64_DCTL1_ADDREXT_MASK;
-
-       desc->dma64.control0 = cpu_to_le32(ctl0);
-       desc->dma64.control1 = cpu_to_le32(ctl1);
-       desc->dma64.address_low = cpu_to_le32(addrlo);
-       desc->dma64.address_high = cpu_to_le32(addrhi);
-}
-
-static void op64_poke_tx(struct b43legacy_dmaring *ring, int slot)
-{
-       b43legacy_dma_write(ring, B43legacy_DMA64_TXINDEX,
-                           (u32)(slot * sizeof(struct b43legacy_dmadesc64)));
-}
-
-static void op64_tx_suspend(struct b43legacy_dmaring *ring)
-{
-       b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL,
-                           b43legacy_dma_read(ring, B43legacy_DMA64_TXCTL)
-                           | B43legacy_DMA64_TXSUSPEND);
-}
-
-static void op64_tx_resume(struct b43legacy_dmaring *ring)
-{
-       b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL,
-                           b43legacy_dma_read(ring, B43legacy_DMA64_TXCTL)
-                           & ~B43legacy_DMA64_TXSUSPEND);
-}
-
-static int op64_get_current_rxslot(struct b43legacy_dmaring *ring)
-{
-       u32 val;
-
-       val = b43legacy_dma_read(ring, B43legacy_DMA64_RXSTATUS);
-       val &= B43legacy_DMA64_RXSTATDPTR;
-
-       return (val / sizeof(struct b43legacy_dmadesc64));
-}
-
-static void op64_set_current_rxslot(struct b43legacy_dmaring *ring,
-                                   int slot)
-{
-       b43legacy_dma_write(ring, B43legacy_DMA64_RXINDEX,
-                           (u32)(slot * sizeof(struct b43legacy_dmadesc64)));
-}
-
-static const struct b43legacy_dma_ops dma64_ops = {
-       .idx2desc               = op64_idx2desc,
-       .fill_descriptor        = op64_fill_descriptor,
-       .poke_tx                = op64_poke_tx,
-       .tx_suspend             = op64_tx_suspend,
-       .tx_resume              = op64_tx_resume,
-       .get_current_rxslot     = op64_get_current_rxslot,
-       .set_current_rxslot     = op64_set_current_rxslot,
-};
-
-
 static inline int free_slots(struct b43legacy_dmaring *ring)
 {
        return (ring->nr_slots - ring->used_slots);
@@ -358,14 +242,6 @@ return 0;
 static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type,
                                        int controller_idx)
 {
-       static const u16 map64[] = {
-               B43legacy_MMIO_DMA64_BASE0,
-               B43legacy_MMIO_DMA64_BASE1,
-               B43legacy_MMIO_DMA64_BASE2,
-               B43legacy_MMIO_DMA64_BASE3,
-               B43legacy_MMIO_DMA64_BASE4,
-               B43legacy_MMIO_DMA64_BASE5,
-       };
        static const u16 map32[] = {
                B43legacy_MMIO_DMA32_BASE0,
                B43legacy_MMIO_DMA32_BASE1,
@@ -375,11 +251,6 @@ static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type,
                B43legacy_MMIO_DMA32_BASE5,
        };
 
-       if (type == B43legacy_DMA_64BIT) {
-               B43legacy_WARN_ON(!(controller_idx >= 0 &&
-                                 controller_idx < ARRAY_SIZE(map64)));
-               return map64[controller_idx];
-       }
        B43legacy_WARN_ON(!(controller_idx >= 0 &&
                          controller_idx < ARRAY_SIZE(map32)));
        return map32[controller_idx];
@@ -491,25 +362,15 @@ static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev,
 
        might_sleep();
 
-       offset = (type == B43legacy_DMA_64BIT) ?
-                B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL;
+       offset = B43legacy_DMA32_RXCTL;
        b43legacy_write32(dev, mmio_base + offset, 0);
        for (i = 0; i < 10; i++) {
-               offset = (type == B43legacy_DMA_64BIT) ?
-                        B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS;
+               offset = B43legacy_DMA32_RXSTATUS;
                value = b43legacy_read32(dev, mmio_base + offset);
-               if (type == B43legacy_DMA_64BIT) {
-                       value &= B43legacy_DMA64_RXSTAT;
-                       if (value == B43legacy_DMA64_RXSTAT_DISABLED) {
-                               i = -1;
-                               break;
-                       }
-               } else {
-                       value &= B43legacy_DMA32_RXSTATE;
-                       if (value == B43legacy_DMA32_RXSTAT_DISABLED) {
-                               i = -1;
-                               break;
-                       }
+               value &= B43legacy_DMA32_RXSTATE;
+               if (value == B43legacy_DMA32_RXSTAT_DISABLED) {
+                       i = -1;
+                       break;
                }
                msleep(1);
        }
@@ -533,43 +394,24 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
        might_sleep();
 
        for (i = 0; i < 10; i++) {
-               offset = (type == B43legacy_DMA_64BIT) ?
-                        B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
+               offset = B43legacy_DMA32_TXSTATUS;
                value = b43legacy_read32(dev, mmio_base + offset);
-               if (type == B43legacy_DMA_64BIT) {
-                       value &= B43legacy_DMA64_TXSTAT;
-                       if (value == B43legacy_DMA64_TXSTAT_DISABLED ||
-                           value == B43legacy_DMA64_TXSTAT_IDLEWAIT ||
-                           value == B43legacy_DMA64_TXSTAT_STOPPED)
-                               break;
-               } else {
-                       value &= B43legacy_DMA32_TXSTATE;
-                       if (value == B43legacy_DMA32_TXSTAT_DISABLED ||
-                           value == B43legacy_DMA32_TXSTAT_IDLEWAIT ||
-                           value == B43legacy_DMA32_TXSTAT_STOPPED)
-                               break;
-               }
+               value &= B43legacy_DMA32_TXSTATE;
+               if (value == B43legacy_DMA32_TXSTAT_DISABLED ||
+                   value == B43legacy_DMA32_TXSTAT_IDLEWAIT ||
+                   value == B43legacy_DMA32_TXSTAT_STOPPED)
+                       break;
                msleep(1);
        }
-       offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL :
-                                                B43legacy_DMA32_TXCTL;
+       offset = B43legacy_DMA32_TXCTL;
        b43legacy_write32(dev, mmio_base + offset, 0);
        for (i = 0; i < 10; i++) {
-               offset = (type == B43legacy_DMA_64BIT) ?
-                        B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS;
+               offset = B43legacy_DMA32_TXSTATUS;
                value = b43legacy_read32(dev, mmio_base + offset);
-               if (type == B43legacy_DMA_64BIT) {
-                       value &= B43legacy_DMA64_TXSTAT;
-                       if (value == B43legacy_DMA64_TXSTAT_DISABLED) {
-                               i = -1;
-                               break;
-                       }
-               } else {
-                       value &= B43legacy_DMA32_TXSTATE;
-                       if (value == B43legacy_DMA32_TXSTAT_DISABLED) {
-                               i = -1;
-                               break;
-                       }
+               value &= B43legacy_DMA32_TXSTATE;
+               if (value == B43legacy_DMA32_TXSTAT_DISABLED) {
+                       i = -1;
+                       break;
                }
                msleep(1);
        }
@@ -601,9 +443,6 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
                if ((u64)addr + buffersize > (1ULL << 32))
                        goto address_error;
                break;
-       case B43legacy_DMA_64BIT:
-               /* Currently we can't have addresses beyond 64 bits in the kernel. */
-               break;
        }
 
        /* The address is OK. */
@@ -617,7 +456,7 @@ address_error:
 }
 
 static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
-                              struct b43legacy_dmadesc_generic *desc,
+                              struct b43legacy_dmadesc32 *desc,
                               struct b43legacy_dmadesc_meta *meta,
                               gfp_t gfp_flags)
 {
@@ -653,8 +492,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
 
        meta->skb = skb;
        meta->dmaaddr = dmaaddr;
-       ring->ops->fill_descriptor(ring, desc, dmaaddr,
-                                  ring->rx_buffersize, 0, 0, 0);
+       op32_fill_descriptor(ring, desc, dmaaddr, ring->rx_buffersize, 0, 0, 0);
 
        rxhdr = (struct b43legacy_rxhdr_fw3 *)(skb->data);
        rxhdr->frame_len = 0;
@@ -671,11 +509,11 @@ static int alloc_initial_descbuffers(struct b43legacy_dmaring *ring)
 {
        int i;
        int err = -ENOMEM;
-       struct b43legacy_dmadesc_generic *desc;
+       struct b43legacy_dmadesc32 *desc;
        struct b43legacy_dmadesc_meta *meta;
 
        for (i = 0; i < ring->nr_slots; i++) {
-               desc = ring->ops->idx2desc(ring, i, &meta);
+               desc = op32_idx2desc(ring, i, &meta);
 
                err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
                if (err) {
@@ -692,7 +530,7 @@ out:
 
 err_unwind:
        for (i--; i >= 0; i--) {
-               desc = ring->ops->idx2desc(ring, i, &meta);
+               desc = op32_idx2desc(ring, i, &meta);
 
                unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
                dev_kfree_skb(meta->skb);
@@ -710,83 +548,35 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
        u32 value;
        u32 addrext;
        u32 trans = ring->dev->dma.translation;
+       u32 ringbase = (u32)(ring->dmabase);
 
        if (ring->tx) {
-               if (ring->type == B43legacy_DMA_64BIT) {
-                       u64 ringbase = (u64)(ring->dmabase);
-
-                       addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
-                                 >> SSB_DMA_TRANSLATION_SHIFT;
-                       value = B43legacy_DMA64_TXENABLE;
-                       value |= (addrext << B43legacy_DMA64_TXADDREXT_SHIFT)
-                               & B43legacy_DMA64_TXADDREXT_MASK;
-                       b43legacy_dma_write(ring, B43legacy_DMA64_TXCTL,
-                                           value);
-                       b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO,
-                                           (ringbase & 0xFFFFFFFF));
-                       b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI,
-                                           ((ringbase >> 32)
-                                           & ~SSB_DMA_TRANSLATION_MASK)
-                                           | trans);
-               } else {
-                       u32 ringbase = (u32)(ring->dmabase);
-
-                       addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
-                                 >> SSB_DMA_TRANSLATION_SHIFT;
-                       value = B43legacy_DMA32_TXENABLE;
-                       value |= (addrext << B43legacy_DMA32_TXADDREXT_SHIFT)
-                               & B43legacy_DMA32_TXADDREXT_MASK;
-                       b43legacy_dma_write(ring, B43legacy_DMA32_TXCTL,
-                                           value);
-                       b43legacy_dma_write(ring, B43legacy_DMA32_TXRING,
-                                           (ringbase &
-                                           ~SSB_DMA_TRANSLATION_MASK)
-                                           | trans);
-               }
+               addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
+                         >> SSB_DMA_TRANSLATION_SHIFT;
+               value = B43legacy_DMA32_TXENABLE;
+               value |= (addrext << B43legacy_DMA32_TXADDREXT_SHIFT)
+                       & B43legacy_DMA32_TXADDREXT_MASK;
+               b43legacy_dma_write(ring, B43legacy_DMA32_TXCTL, value);
+               b43legacy_dma_write(ring, B43legacy_DMA32_TXRING,
+                                   (ringbase & ~SSB_DMA_TRANSLATION_MASK)
+                                   | trans);
        } else {
                err = alloc_initial_descbuffers(ring);
                if (err)
                        goto out;
-               if (ring->type == B43legacy_DMA_64BIT) {
-                       u64 ringbase = (u64)(ring->dmabase);
-
-                       addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
-                                 >> SSB_DMA_TRANSLATION_SHIFT;
-                       value = (ring->frameoffset <<
-                                B43legacy_DMA64_RXFROFF_SHIFT);
-                       value |= B43legacy_DMA64_RXENABLE;
-                       value |= (addrext << B43legacy_DMA64_RXADDREXT_SHIFT)
-                               & B43legacy_DMA64_RXADDREXT_MASK;
-                       b43legacy_dma_write(ring, B43legacy_DMA64_RXCTL,
-                                           value);
-                       b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO,
-                                           (ringbase & 0xFFFFFFFF));
-                       b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI,
-                                           ((ringbase >> 32) &
-                                           ~SSB_DMA_TRANSLATION_MASK) |
-                                           trans);
-                       b43legacy_dma_write(ring, B43legacy_DMA64_RXINDEX,
-                                           200);
-               } else {
-                       u32 ringbase = (u32)(ring->dmabase);
-
-                       addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
-                                 >> SSB_DMA_TRANSLATION_SHIFT;
-                       value = (ring->frameoffset <<
-                                B43legacy_DMA32_RXFROFF_SHIFT);
-                       value |= B43legacy_DMA32_RXENABLE;
-                       value |= (addrext <<
-                                B43legacy_DMA32_RXADDREXT_SHIFT)
-                                & B43legacy_DMA32_RXADDREXT_MASK;
-                       b43legacy_dma_write(ring, B43legacy_DMA32_RXCTL,
-                                           value);
-                       b43legacy_dma_write(ring, B43legacy_DMA32_RXRING,
-                                           (ringbase &
-                                           ~SSB_DMA_TRANSLATION_MASK)
-                                           | trans);
-                       b43legacy_dma_write(ring, B43legacy_DMA32_RXINDEX,
-                                           200);
-               }
+
+               addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
+                         >> SSB_DMA_TRANSLATION_SHIFT;
+               value = (ring->frameoffset <<
+                        B43legacy_DMA32_RXFROFF_SHIFT);
+               value |= B43legacy_DMA32_RXENABLE;
+               value |= (addrext << B43legacy_DMA32_RXADDREXT_SHIFT)
+                        & B43legacy_DMA32_RXADDREXT_MASK;
+               b43legacy_dma_write(ring, B43legacy_DMA32_RXCTL, value);
+               b43legacy_dma_write(ring, B43legacy_DMA32_RXRING,
+                                   (ringbase & ~SSB_DMA_TRANSLATION_MASK)
+                                   | trans);
+               b43legacy_dma_write(ring, B43legacy_DMA32_RXINDEX, 200);
        }
 
 out:
@@ -799,19 +589,11 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring)
        if (ring->tx) {
                b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base,
                                                 ring->type);
-               if (ring->type == B43legacy_DMA_64BIT) {
-                       b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0);
-                       b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0);
-               } else
-                       b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0);
+               b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0);
        } else {
                b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base,
                                                 ring->type);
-               if (ring->type == B43legacy_DMA_64BIT) {
-                       b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0);
-                       b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0);
-               } else
-                       b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, 0);
+               b43legacy_dma_write(ring, B43legacy_DMA32_RXRING, 0);
        }
 }
 
@@ -823,7 +605,7 @@ static void free_all_descbuffers(struct b43legacy_dmaring *ring)
        if (!ring->used_slots)
                return;
        for (i = 0; i < ring->nr_slots; i++) {
-               ring->ops->idx2desc(ring, i, &meta);
+               op32_idx2desc(ring, i, &meta);
 
                if (!meta->skb) {
                        B43legacy_WARN_ON(!ring->tx);
@@ -844,9 +626,6 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
        u32 tmp;
        u16 mmio_base;
 
-       tmp = b43legacy_read32(dev, SSB_TMSHIGH);
-       if (tmp & SSB_TMSHIGH_DMA64)
-               return DMA_BIT_MASK(64);
        mmio_base = b43legacy_dmacontroller_base(0, 0);
        b43legacy_write32(dev,
                        mmio_base + B43legacy_DMA32_TXCTL,
@@ -865,8 +644,6 @@ static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
                return B43legacy_DMA_30BIT;
        if (dmamask == DMA_BIT_MASK(32))
                return B43legacy_DMA_32BIT;
-       if (dmamask == DMA_BIT_MASK(64))
-               return B43legacy_DMA_64BIT;
        B43legacy_WARN_ON(1);
        return B43legacy_DMA_30BIT;
 }
@@ -937,10 +714,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
        ring->nr_slots = nr_slots;
        ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
        ring->index = controller_index;
-       if (type == B43legacy_DMA_64BIT)
-               ring->ops = &dma64_ops;
-       else
-               ring->ops = &dma32_ops;
        if (for_tx) {
                ring->tx = 1;
                ring->current_slot = -1;
@@ -1247,12 +1020,11 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
                            struct sk_buff **in_skb)
 {
        struct sk_buff *skb = *in_skb;
-       const struct b43legacy_dma_ops *ops = ring->ops;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        u8 *header;
        int slot, old_top_slot, old_used_slots;
        int err;
-       struct b43legacy_dmadesc_generic *desc;
+       struct b43legacy_dmadesc32 *desc;
        struct b43legacy_dmadesc_meta *meta;
        struct b43legacy_dmadesc_meta *meta_hdr;
        struct sk_buff *bounce_skb;
@@ -1265,7 +1037,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
 
        /* Get a slot for the header. */
        slot = request_slot(ring);
-       desc = ops->idx2desc(ring, slot, &meta_hdr);
+       desc = op32_idx2desc(ring, slot, &meta_hdr);
        memset(meta_hdr, 0, sizeof(*meta_hdr));
 
        header = &(ring->txhdr_cache[slot * sizeof(
@@ -1287,12 +1059,12 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
                ring->used_slots = old_used_slots;
                return -EIO;
        }
-       ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
+       op32_fill_descriptor(ring, desc, meta_hdr->dmaaddr,
                             sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0);
 
        /* Get a slot for the payload. */
        slot = request_slot(ring);
-       desc = ops->idx2desc(ring, slot, &meta);
+       desc = op32_idx2desc(ring, slot, &meta);
        memset(meta, 0, sizeof(*meta));
 
        meta->skb = skb;
@@ -1328,12 +1100,12 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
                }
        }
 
-       ops->fill_descriptor(ring, desc, meta->dmaaddr,
+       op32_fill_descriptor(ring, desc, meta->dmaaddr,
                             skb->len, 0, 1, 1);
 
        wmb();  /* previous stuff MUST be done */
        /* Now transfer the whole frame. */
-       ops->poke_tx(ring, next_slot(ring, slot));
+       op32_poke_tx(ring, next_slot(ring, slot));
        return 0;
 
 out_free_bounce:
@@ -1429,7 +1201,6 @@ out_unlock:
 void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
                                 const struct b43legacy_txstatus *status)
 {
-       const struct b43legacy_dma_ops *ops;
        struct b43legacy_dmaring *ring;
        struct b43legacy_dmadesc_meta *meta;
        int retry_limit;
@@ -1442,10 +1213,9 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
        spin_lock(&ring->lock);
 
        B43legacy_WARN_ON(!ring->tx);
-       ops = ring->ops;
        while (1) {
                B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
-               ops->idx2desc(ring, slot, &meta);
+               op32_idx2desc(ring, slot, &meta);
 
                if (meta->skb)
                        unmap_descbuffer(ring, meta->dmaaddr,
@@ -1528,8 +1298,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
 static void dma_rx(struct b43legacy_dmaring *ring,
                   int *slot)
 {
-       const struct b43legacy_dma_ops *ops = ring->ops;
-       struct b43legacy_dmadesc_generic *desc;
+       struct b43legacy_dmadesc32 *desc;
        struct b43legacy_dmadesc_meta *meta;
        struct b43legacy_rxhdr_fw3 *rxhdr;
        struct sk_buff *skb;
@@ -1537,7 +1306,7 @@ static void dma_rx(struct b43legacy_dmaring *ring,
        int err;
        dma_addr_t dmaaddr;
 
-       desc = ops->idx2desc(ring, *slot, &meta);
+       desc = op32_idx2desc(ring, *slot, &meta);
 
        sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
        skb = meta->skb;
@@ -1589,7 +1358,7 @@ static void dma_rx(struct b43legacy_dmaring *ring,
                s32 tmp = len;
 
                while (1) {
-                       desc = ops->idx2desc(ring, *slot, &meta);
+                       desc = op32_idx2desc(ring, *slot, &meta);
                        /* recycle the descriptor buffer. */
                        sync_descbuffer_for_device(ring, meta->dmaaddr,
                                                   ring->rx_buffersize);
@@ -1626,13 +1395,12 @@ drop:
 
 void b43legacy_dma_rx(struct b43legacy_dmaring *ring)
 {
-       const struct b43legacy_dma_ops *ops = ring->ops;
        int slot;
        int current_slot;
        int used_slots = 0;
 
        B43legacy_WARN_ON(ring->tx);
-       current_slot = ops->get_current_rxslot(ring);
+       current_slot = op32_get_current_rxslot(ring);
        B43legacy_WARN_ON(!(current_slot >= 0 && current_slot <
                           ring->nr_slots));
 
@@ -1641,7 +1409,7 @@ void b43legacy_dma_rx(struct b43legacy_dmaring *ring)
                dma_rx(ring, &slot);
                update_max_used_slots(ring, ++used_slots);
        }
-       ops->set_current_rxslot(ring, slot);
+       op32_set_current_rxslot(ring, slot);
        ring->current_slot = slot;
 }
 
@@ -1651,7 +1419,7 @@ static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring)
 
        spin_lock_irqsave(&ring->lock, flags);
        B43legacy_WARN_ON(!ring->tx);
-       ring->ops->tx_suspend(ring);
+       op32_tx_suspend(ring);
        spin_unlock_irqrestore(&ring->lock, flags);
 }
 
@@ -1661,7 +1429,7 @@ static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring)
 
        spin_lock_irqsave(&ring->lock, flags);
        B43legacy_WARN_ON(!ring->tx);
-       ring->ops->tx_resume(ring);
+       op32_tx_resume(ring);
        spin_unlock_irqrestore(&ring->lock, flags);
 }
 
index 686941c242fc6aa8a1dfa00623435253d6352220..504a58767e95e293edad8acddf4c513148d54939 100644 (file)
@@ -82,90 +82,6 @@ struct b43legacy_dmadesc32 {
 #define B43legacy_DMA32_DCTL_FRAMESTART                0x80000000
 
 
-
-/*** 64-bit DMA Engine. ***/
-
-/* 64-bit DMA controller registers. */
-#define B43legacy_DMA64_TXCTL                          0x00
-#define                B43legacy_DMA64_TXENABLE                0x00000001
-#define                B43legacy_DMA64_TXSUSPEND               0x00000002
-#define                B43legacy_DMA64_TXLOOPBACK              0x00000004
-#define                B43legacy_DMA64_TXFLUSH                 0x00000010
-#define                B43legacy_DMA64_TXADDREXT_MASK          0x00030000
-#define                B43legacy_DMA64_TXADDREXT_SHIFT         16
-#define B43legacy_DMA64_TXINDEX                                0x04
-#define B43legacy_DMA64_TXRINGLO                       0x08
-#define B43legacy_DMA64_TXRINGHI                       0x0C
-#define B43legacy_DMA64_TXSTATUS                       0x10
-#define                B43legacy_DMA64_TXSTATDPTR              0x00001FFF
-#define                B43legacy_DMA64_TXSTAT                  0xF0000000
-#define                        B43legacy_DMA64_TXSTAT_DISABLED 0x00000000
-#define                        B43legacy_DMA64_TXSTAT_ACTIVE   0x10000000
-#define                        B43legacy_DMA64_TXSTAT_IDLEWAIT 0x20000000
-#define                        B43legacy_DMA64_TXSTAT_STOPPED  0x30000000
-#define                        B43legacy_DMA64_TXSTAT_SUSP     0x40000000
-#define B43legacy_DMA64_TXERROR                                0x14
-#define                B43legacy_DMA64_TXERRDPTR               0x0001FFFF
-#define                B43legacy_DMA64_TXERR                   0xF0000000
-#define                        B43legacy_DMA64_TXERR_NOERR     0x00000000
-#define                        B43legacy_DMA64_TXERR_PROT      0x10000000
-#define                        B43legacy_DMA64_TXERR_UNDERRUN  0x20000000
-#define                        B43legacy_DMA64_TXERR_TRANSFER  0x30000000
-#define                        B43legacy_DMA64_TXERR_DESCREAD  0x40000000
-#define                        B43legacy_DMA64_TXERR_CORE      0x50000000
-#define B43legacy_DMA64_RXCTL                          0x20
-#define                B43legacy_DMA64_RXENABLE                0x00000001
-#define                B43legacy_DMA64_RXFROFF_MASK            0x000000FE
-#define                B43legacy_DMA64_RXFROFF_SHIFT           1
-#define                B43legacy_DMA64_RXDIRECTFIFO            0x00000100
-#define                B43legacy_DMA64_RXADDREXT_MASK          0x00030000
-#define                B43legacy_DMA64_RXADDREXT_SHIFT         16
-#define B43legacy_DMA64_RXINDEX                                0x24
-#define B43legacy_DMA64_RXRINGLO                       0x28
-#define B43legacy_DMA64_RXRINGHI                       0x2C
-#define B43legacy_DMA64_RXSTATUS                       0x30
-#define                B43legacy_DMA64_RXSTATDPTR              0x00001FFF
-#define                B43legacy_DMA64_RXSTAT                  0xF0000000
-#define                        B43legacy_DMA64_RXSTAT_DISABLED 0x00000000
-#define                        B43legacy_DMA64_RXSTAT_ACTIVE   0x10000000
-#define                        B43legacy_DMA64_RXSTAT_IDLEWAIT 0x20000000
-#define                        B43legacy_DMA64_RXSTAT_STOPPED  0x30000000
-#define                        B43legacy_DMA64_RXSTAT_SUSP     0x40000000
-#define B43legacy_DMA64_RXERROR                                0x34
-#define                B43legacy_DMA64_RXERRDPTR               0x0001FFFF
-#define                B43legacy_DMA64_RXERR                   0xF0000000
-#define                        B43legacy_DMA64_RXERR_NOERR     0x00000000
-#define                        B43legacy_DMA64_RXERR_PROT      0x10000000
-#define                        B43legacy_DMA64_RXERR_UNDERRUN  0x20000000
-#define                        B43legacy_DMA64_RXERR_TRANSFER  0x30000000
-#define                        B43legacy_DMA64_RXERR_DESCREAD  0x40000000
-#define                        B43legacy_DMA64_RXERR_CORE      0x50000000
-
-/* 64-bit DMA descriptor. */
-struct b43legacy_dmadesc64 {
-       __le32 control0;
-       __le32 control1;
-       __le32 address_low;
-       __le32 address_high;
-} __packed;
-#define B43legacy_DMA64_DCTL0_DTABLEEND                0x10000000
-#define B43legacy_DMA64_DCTL0_IRQ              0x20000000
-#define B43legacy_DMA64_DCTL0_FRAMEEND         0x40000000
-#define B43legacy_DMA64_DCTL0_FRAMESTART       0x80000000
-#define B43legacy_DMA64_DCTL1_BYTECNT          0x00001FFF
-#define B43legacy_DMA64_DCTL1_ADDREXT_MASK     0x00030000
-#define B43legacy_DMA64_DCTL1_ADDREXT_SHIFT    16
-
-
-
-struct b43legacy_dmadesc_generic {
-       union {
-               struct b43legacy_dmadesc32 dma32;
-               struct b43legacy_dmadesc64 dma64;
-       } __packed;
-} __packed;
-
-
 /* Misc DMA constants */
 #define B43legacy_DMA_RINGMEMSIZE      PAGE_SIZE
 #define B43legacy_DMA0_RX_FRAMEOFFSET  30
@@ -197,35 +113,12 @@ struct b43legacy_dmadesc_meta {
        bool is_last_fragment;
 };
 
-struct b43legacy_dmaring;
-
-/* Lowlevel DMA operations that differ between 32bit and 64bit DMA. */
-struct b43legacy_dma_ops {
-       struct b43legacy_dmadesc_generic * (*idx2desc)
-                                          (struct b43legacy_dmaring *ring,
-                                          int slot,
-                                          struct b43legacy_dmadesc_meta
-                                          **meta);
-       void (*fill_descriptor)(struct b43legacy_dmaring *ring,
-                               struct b43legacy_dmadesc_generic *desc,
-                               dma_addr_t dmaaddr, u16 bufsize,
-                               int start, int end, int irq);
-       void (*poke_tx)(struct b43legacy_dmaring *ring, int slot);
-       void (*tx_suspend)(struct b43legacy_dmaring *ring);
-       void (*tx_resume)(struct b43legacy_dmaring *ring);
-       int (*get_current_rxslot)(struct b43legacy_dmaring *ring);
-       void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot);
-};
-
 enum b43legacy_dmatype {
        B43legacy_DMA_30BIT = 30,
        B43legacy_DMA_32BIT = 32,
-       B43legacy_DMA_64BIT = 64,
 };
 
 struct b43legacy_dmaring {
-       /* Lowlevel DMA ops. */
-       const struct b43legacy_dma_ops *ops;
        /* Kernel virtual base address of the ring memory. */
        void *descbase;
        /* Meta data about all descriptors. */
index 04c03b212a5ee3facede4cd7a164ebd5dde15c43..aae8dfcb852e54f54917409949124f9f5befb885 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
-#include <linux/wireless.h>
 #include <linux/workqueue.h>
 #include <linux/sched.h>
 #include <linux/skbuff.h>
@@ -3785,7 +3784,8 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
        INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);
 
        ssb_set_devtypedata(dev, wl);
-       b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+       b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n",
+                     dev->bus->chip_id, dev->id.revision);
        err = 0;
 out:
        return err;
index 89a116fba1de24f81d4fd3b25f7d5ad6e059c27a..bfa0d54221e8f48d4201f62b4a44ba777067f2fa 100644 (file)
@@ -816,7 +816,7 @@ static const struct net_device_ops hostap_netdev_ops = {
        .ndo_stop               = prism2_close,
        .ndo_do_ioctl           = hostap_ioctl,
        .ndo_set_mac_address    = prism2_set_mac_address,
-       .ndo_set_multicast_list = hostap_set_multicast_list,
+       .ndo_set_rx_mode        = hostap_set_multicast_list,
        .ndo_change_mtu         = prism2_change_mtu,
        .ndo_tx_timeout         = prism2_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
@@ -829,7 +829,7 @@ static const struct net_device_ops hostap_mgmt_netdev_ops = {
        .ndo_stop               = prism2_close,
        .ndo_do_ioctl           = hostap_ioctl,
        .ndo_set_mac_address    = prism2_set_mac_address,
-       .ndo_set_multicast_list = hostap_set_multicast_list,
+       .ndo_set_rx_mode        = hostap_set_multicast_list,
        .ndo_change_mtu         = prism2_change_mtu,
        .ndo_tx_timeout         = prism2_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
@@ -842,7 +842,7 @@ static const struct net_device_ops hostap_master_ops = {
        .ndo_stop               = prism2_close,
        .ndo_do_ioctl           = hostap_ioctl,
        .ndo_set_mac_address    = prism2_set_mac_address,
-       .ndo_set_multicast_list = hostap_set_multicast_list,
+       .ndo_set_rx_mode        = hostap_set_multicast_list,
        .ndo_change_mtu         = prism2_change_mtu,
        .ndo_tx_timeout         = prism2_tx_timeout,
        .ndo_validate_addr      = eth_validate_addr,
index 3774dd034746286815af04f0322e7d4e778d6f32..db35f99cac1422896dc94692351cc9b5e07eadc3 100644 (file)
@@ -161,7 +161,7 @@ that only one external action is invoked at a time.
 #include <linux/firmware.h>
 #include <linux/acpi.h>
 #include <linux/ctype.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 
 #include <net/lib80211.h>
 
@@ -174,7 +174,7 @@ that only one external action is invoked at a time.
 #define DRV_DESCRIPTION        "Intel(R) PRO/Wireless 2100 Network Driver"
 #define DRV_COPYRIGHT  "Copyright(c) 2003-2006 Intel Corporation"
 
-static struct pm_qos_request_list ipw2100_pm_qos_req;
+static struct pm_qos_request ipw2100_pm_qos_req;
 
 /* Debugging stuff */
 #ifdef CONFIG_IPW2100_DEBUG
index 87813c33bdc2a4f1632cc2007242ef8e2c067379..f303df43ed3ff8eb0d80f1280bf61b643d848d6e 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <net/cfg80211-wext.h>
 #include "ipw2200.h"
 
 
@@ -11701,7 +11702,7 @@ static const struct net_device_ops ipw_netdev_ops = {
        .ndo_init               = ipw_net_init,
        .ndo_open               = ipw_net_open,
        .ndo_stop               = ipw_net_stop,
-       .ndo_set_multicast_list = ipw_net_set_multicast_list,
+       .ndo_set_rx_mode        = ipw_net_set_multicast_list,
        .ndo_set_mac_address    = ipw_net_set_mac_address,
        .ndo_start_xmit         = libipw_xmit,
        .ndo_change_mtu         = libipw_change_mtu,
index abd923558d481519282ca7a69198596d41254d4f..7a7f0f38c8ab1c320c01aae1faba1bdb586e4280 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
index 977bd2477c6a91dd5cdad45a5b4ae3a3bbc79c64..0cc5177d738df9f9370cbf8ef325dddab7a8e556 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 
 #include <linux/netdevice.h>
index 73fe3cdf796b28555dcc8e044aaccedf936d7071..f7c0a7438476c6e62ed981d1692f7bff42aeb19c 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
index 26d324e3069237bc924ffa1aa4d3efcc5f873f8a..6862fdcaee6293f941b04d6e21218284b517f389 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
index 9b65153bdd018800a4d43a4d8184486bb7afbb3d..57ebe214e68ca621f218eaa69db0ed42cbed2b74 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 
 #include <linux/netdevice.h>
index ecdc6e557428ee4d777f955408fc8054fd1c82d5..86f4fce193e41ea9673bd9517faf491c387d8e3a 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
index bda0d61b2c0d1e5aefaea5b13fd4e25a84832ec1..dc568a474c5d089995fb66ed522cb8f6f4a5e27e 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
index 795826a014eda976eaa5a619dbe0a70b7a8a9b3f..015739d204f225bafecc4cf7222c4be6d3ee130d 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
index 14334668034e0b5f01bce281e896df9742cd59fe..6bc5575c8dff67dfe242b035b7a2ec11c005028f 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
index ad3bdba6beed1cf9c24479480e846175c1011c0e..1d7572f9887f189f3ac520c08c05996d68a27a9b 100644 (file)
@@ -111,20 +111,3 @@ config IWLWIFI_DEVICE_SVTOOL
          NL80211_TESTMODE. svtool is a software validation tool that runs in
          the user space and interacts with the device in the kernel space
          through the generic netlink message via NL80211_TESTMODE channel.
-
-config IWL_P2P
-       bool "iwlwifi experimental P2P support"
-       depends on IWLAGN
-       help
-         This option enables experimental P2P support for some devices
-         based on microcode support. Since P2P support is still under
-         development, this option may even enable it for some devices
-         now that turn out to not support it in the future due to
-         microcode restrictions.
-
-         To determine if your microcode supports the experimental P2P
-         offered by this option, check if the driver advertises AP
-         support when it is loaded.
-
-         Say Y only if you want to experiment with P2P.
-
index 01b49eb8c8ecca2f266eb1f92d045a338661f5b9..ccdbed567171983641cfa4301c49ade2e3b1245d 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL1000_UCODE_API_MAX 5
-#define IWL100_UCODE_API_MAX 5
+#define IWL1000_UCODE_API_MAX 6
+#define IWL100_UCODE_API_MAX 6
+
+/* Oldest version we won't warn about */
+#define IWL1000_UCODE_API_OK 5
+#define IWL100_UCODE_API_OK 5
 
 /* Lowest firmware API version supported */
 #define IWL1000_UCODE_API_MIN 1
@@ -135,8 +138,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
        priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
 
-       priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
-                                       BIT(IEEE80211_BAND_5GHZ);
+       priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
        priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
        if (priv->cfg->rx_with_siso_diversity)
@@ -201,12 +203,13 @@ static struct iwl_base_params iwl1000_base_params = {
 static struct iwl_ht_params iwl1000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
-       .smps_mode = IEEE80211_SMPS_STATIC,
+       .smps_mode = IEEE80211_SMPS_DYNAMIC,
 };
 
 #define IWL_DEVICE_1000                                                \
        .fw_name_pre = IWL1000_FW_PRE,                          \
        .ucode_api_max = IWL1000_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL1000_UCODE_API_OK,                   \
        .ucode_api_min = IWL1000_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
@@ -228,6 +231,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
 #define IWL_DEVICE_100                                         \
        .fw_name_pre = IWL100_FW_PRE,                           \
        .ucode_api_max = IWL100_UCODE_API_MAX,                  \
+       .ucode_api_ok = IWL100_UCODE_API_OK,                    \
        .ucode_api_min = IWL100_UCODE_API_MIN,                  \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
index 0e13f0bb2e178151789b5363006131ecd90b23d8..54d931d614fb15b4e3d2b3a36fa77c60dd4b6e27 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
 #include "iwl-6000-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL2030_UCODE_API_MAX 5
-#define IWL2000_UCODE_API_MAX 5
-#define IWL105_UCODE_API_MAX 5
-#define IWL135_UCODE_API_MAX 5
+#define IWL2030_UCODE_API_MAX 6
+#define IWL2000_UCODE_API_MAX 6
+#define IWL105_UCODE_API_MAX 6
+#define IWL135_UCODE_API_MAX 6
+
+/* Oldest version we won't warn about */
+#define IWL2030_UCODE_API_OK 5
+#define IWL2000_UCODE_API_OK 5
+#define IWL105_UCODE_API_OK 5
+#define IWL135_UCODE_API_OK 5
 
 /* Lowest firmware API version supported */
 #define IWL2030_UCODE_API_MIN 5
@@ -130,8 +135,7 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
        priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
 
-       priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
-                                       BIT(IEEE80211_BAND_5GHZ);
+       priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
        priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
        if (priv->cfg->rx_with_siso_diversity)
@@ -217,6 +221,7 @@ static struct iwl_base_params iwl2000_base_params = {
        .wd_timeout = IWL_DEF_WD_TIMEOUT,
        .max_event_log_size = 512,
        .shadow_reg_enable = true,
+       .hd_v2 = true,
 };
 
 
@@ -236,6 +241,7 @@ static struct iwl_base_params iwl2030_base_params = {
        .wd_timeout = IWL_LONG_WD_TIMEOUT,
        .max_event_log_size = 512,
        .shadow_reg_enable = true,
+       .hd_v2 = true,
 };
 
 static struct iwl_ht_params iwl2000_ht_params = {
@@ -256,6 +262,7 @@ static struct iwl_bt_params iwl2030_bt_params = {
 #define IWL_DEVICE_2000                                                \
        .fw_name_pre = IWL2000_FW_PRE,                          \
        .ucode_api_max = IWL2000_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL2000_UCODE_API_OK,                   \
        .ucode_api_min = IWL2000_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
@@ -280,6 +287,7 @@ struct iwl_cfg iwl2000_2bg_cfg = {
 #define IWL_DEVICE_2030                                                \
        .fw_name_pre = IWL2030_FW_PRE,                          \
        .ucode_api_max = IWL2030_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL2030_UCODE_API_OK,                   \
        .ucode_api_min = IWL2030_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
@@ -306,6 +314,7 @@ struct iwl_cfg iwl2030_2bg_cfg = {
 #define IWL_DEVICE_105                                         \
        .fw_name_pre = IWL105_FW_PRE,                           \
        .ucode_api_max = IWL105_UCODE_API_MAX,                  \
+       .ucode_api_ok = IWL105_UCODE_API_OK,                    \
        .ucode_api_min = IWL105_UCODE_API_MIN,                  \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
@@ -332,6 +341,7 @@ struct iwl_cfg iwl105_bgn_cfg = {
 #define IWL_DEVICE_135                                         \
        .fw_name_pre = IWL135_FW_PRE,                           \
        .ucode_api_max = IWL135_UCODE_API_MAX,                  \
+       .ucode_api_ok = IWL135_UCODE_API_OK,                    \
        .ucode_api_min = IWL135_UCODE_API_MIN,                  \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
index c95cefd529dc31d13819b037006495e7798e032f..a9adee5634d81c6d384a505b1d387e7a59917323 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
@@ -84,12 +83,12 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
 }
 
 static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
-       .min_nrg_cck = 95,
+       .min_nrg_cck = 100,
        .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
-       .auto_corr_min_ofdm_x1 = 120,
-       .auto_corr_min_ofdm_mrc_x1 = 240,
+       .auto_corr_min_ofdm_x1 = 105,
+       .auto_corr_min_ofdm_mrc_x1 = 220,
 
        .auto_corr_max_ofdm = 120,
        .auto_corr_max_ofdm_mrc = 210,
@@ -98,10 +97,10 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
 
        .auto_corr_min_cck = 125,
        .auto_corr_max_cck = 200,
-       .auto_corr_min_cck_mrc = 170,
+       .auto_corr_min_cck_mrc = 200,
        .auto_corr_max_cck_mrc = 400,
-       .nrg_th_cck = 95,
-       .nrg_th_ofdm = 95,
+       .nrg_th_cck = 100,
+       .nrg_th_ofdm = 100,
 
        .barker_corr_th_min = 190,
        .barker_corr_th_min_mrc = 390,
index 973d1972e8cc9eebb02e50a353b25d4f7d95507b..339de88d9ae2ce5ba12a6d281ddf0d2514901240 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
 /* Highest firmware API version supported */
 #define IWL6000_UCODE_API_MAX 4
 #define IWL6050_UCODE_API_MAX 5
-#define IWL6000G2_UCODE_API_MAX 5
+#define IWL6000G2_UCODE_API_MAX 6
+
+/* Oldest version we won't warn about */
+#define IWL6000G2_UCODE_API_OK 5
 
 /* Lowest firmware API version supported */
 #define IWL6000_UCODE_API_MIN 4
@@ -111,7 +113,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
 }
 
 static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
-       .min_nrg_cck = 97,
+       .min_nrg_cck = 110,
        .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 80,
        .auto_corr_min_ofdm_mrc = 128,
@@ -127,11 +129,11 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
        .auto_corr_max_cck = 175,
        .auto_corr_min_cck_mrc = 160,
        .auto_corr_max_cck_mrc = 310,
-       .nrg_th_cck = 97,
-       .nrg_th_ofdm = 100,
+       .nrg_th_cck = 110,
+       .nrg_th_ofdm = 110,
 
        .barker_corr_th_min = 190,
-       .barker_corr_th_min_mrc = 390,
+       .barker_corr_th_min_mrc = 336,
        .nrg_th_cca = 62,
 };
 
@@ -365,8 +367,9 @@ static struct iwl_bt_params iwl6000_bt_params = {
 };
 
 #define IWL_DEVICE_6005                                                \
-       .fw_name_pre = IWL6005_FW_PRE,                  \
+       .fw_name_pre = IWL6005_FW_PRE,                          \
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
+       .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
        .eeprom_ver = EEPROM_6005_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,       \
@@ -393,8 +396,9 @@ struct iwl_cfg iwl6005_2bg_cfg = {
 };
 
 #define IWL_DEVICE_6030                                                \
-       .fw_name_pre = IWL6030_FW_PRE,                  \
+       .fw_name_pre = IWL6030_FW_PRE,                          \
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
+       .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
        .eeprom_ver = EEPROM_6030_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,       \
index 72d6297602b833c2802abab20d6569b316a9a09d..1789e3af8101e27672f15b47cd4fe3e62a66a5c7 100644 (file)
@@ -505,28 +505,53 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
 
        iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
 
-       cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
-               HD_INA_NON_SQUARE_DET_OFDM_DATA;
-       cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
-               HD_INA_NON_SQUARE_DET_CCK_DATA;
-       cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
-               HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA;
-       cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
-               HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA;
-       cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
-               HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
-       cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
-               HD_OFDM_NON_SQUARE_DET_SLOPE_DATA;
-       cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
-               HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA;
-       cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
-               HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA;
-       cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
-               HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
-       cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
-               HD_CCK_NON_SQUARE_DET_SLOPE_DATA;
-       cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
-               HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA;
+       if (priv->cfg->base_params->hd_v2) {
+               cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
+                       HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
+               cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
+                       HD_INA_NON_SQUARE_DET_CCK_DATA_V2;
+               cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
+                       HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2;
+       } else {
+               cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
+                       HD_INA_NON_SQUARE_DET_OFDM_DATA_V1;
+               cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
+                       HD_INA_NON_SQUARE_DET_CCK_DATA_V1;
+               cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
+                       HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1;
+               cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
+                       HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1;
+               cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
+                       HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1;
+       }
 
        /* Update uCode's "work" table, and copy it to DSP */
        cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
index 0e5b842529c40ac7532f54a7f1174bff936d877b..47c43042ba4facf6d8be12df67492ca7db10d64b 100644 (file)
@@ -92,8 +92,8 @@
 
 #define IWLAGN_CMD_FIFO_NUM            7
 #define IWLAGN_NUM_QUEUES              20
-#define IWLAGN_NUM_AMPDU_QUEUES                10
-#define IWLAGN_FIRST_AMPDU_QUEUE       10
+#define IWLAGN_NUM_AMPDU_QUEUES                9
+#define IWLAGN_FIRST_AMPDU_QUEUE       11
 
 /* Fixed (non-configurable) rx data from phy */
 
index 3bee0f119bcd0167e8e368c35951bf132201f6d4..4edb6cfc5488d05f871048bb1f17a3b6d64b78ae 100644 (file)
@@ -753,18 +753,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
        return added;
 }
 
-static int iwl_fill_offch_tx(struct iwl_priv *priv, void *data, size_t maxlen)
-{
-       struct sk_buff *skb = priv->offchan_tx_skb;
-
-       if (skb->len < maxlen)
-               maxlen = skb->len;
-
-       memcpy(data, skb->data, maxlen);
-
-       return maxlen;
-}
-
 int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 {
        struct iwl_host_cmd cmd = {
@@ -807,7 +795,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
        scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 
-       if (priv->scan_type != IWL_SCAN_OFFCH_TX &&
+       if (priv->scan_type != IWL_SCAN_ROC &&
            iwl_is_any_associated(priv)) {
                u16 interval = 0;
                u32 extra;
@@ -816,7 +804,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 
                IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
                switch (priv->scan_type) {
-               case IWL_SCAN_OFFCH_TX:
+               case IWL_SCAN_ROC:
                        WARN_ON(1);
                        break;
                case IWL_SCAN_RADIO_RESET:
@@ -838,10 +826,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                scan->suspend_time = cpu_to_le32(scan_suspend_time);
                IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
                               scan_suspend_time, interval);
-       } else if (priv->scan_type == IWL_SCAN_OFFCH_TX) {
+       } else if (priv->scan_type == IWL_SCAN_ROC) {
                scan->suspend_time = 0;
-               scan->max_out_time =
-                       cpu_to_le32(1024 * priv->offchan_tx_timeout);
+               scan->max_out_time = 0;
+               scan->quiet_time = 0;
+               scan->quiet_plcp_th = 0;
        }
 
        switch (priv->scan_type) {
@@ -869,8 +858,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                } else
                        IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
                break;
-       case IWL_SCAN_OFFCH_TX:
-               IWL_DEBUG_SCAN(priv, "Start offchannel TX scan.\n");
+       case IWL_SCAN_ROC:
+               IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
                break;
        }
 
@@ -988,19 +977,13 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                                        IWL_MAX_SCAN_SIZE - sizeof(*scan));
                break;
        case IWL_SCAN_RADIO_RESET:
+       case IWL_SCAN_ROC:
                /* use bcast addr, will not be transmitted but must be valid */
                cmd_len = iwl_fill_probe_req(priv,
                                        (struct ieee80211_mgmt *)scan->data,
                                        iwl_bcast_addr, NULL, 0,
                                        IWL_MAX_SCAN_SIZE - sizeof(*scan));
                break;
-       case IWL_SCAN_OFFCH_TX:
-               cmd_len = iwl_fill_offch_tx(priv, scan->data,
-                                           IWL_MAX_SCAN_SIZE
-                                            - sizeof(*scan)
-                                            - sizeof(struct iwl_scan_channel));
-               scan->scan_flags |= IWL_SCAN_FLAGS_ACTION_FRAME_TX;
-               break;
        default:
                BUG();
        }
@@ -1021,18 +1004,18 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                                is_active, n_probes,
                                (void *)&scan->data[cmd_len]);
                break;
-       case IWL_SCAN_OFFCH_TX: {
+       case IWL_SCAN_ROC: {
                struct iwl_scan_channel *scan_ch;
 
                scan->channel_count = 1;
 
                scan_ch = (void *)&scan->data[cmd_len];
-               scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
+               scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
                scan_ch->channel =
-                       cpu_to_le16(priv->offchan_tx_chan->hw_value);
+                       cpu_to_le16(priv->hw_roc_channel->hw_value);
                scan_ch->active_dwell =
-                       cpu_to_le16(priv->offchan_tx_timeout);
-               scan_ch->passive_dwell = 0;
+               scan_ch->passive_dwell =
+                       cpu_to_le16(priv->hw_roc_duration);
 
                /* Set txpower levels to defaults */
                scan_ch->dsp_atten = 110;
@@ -1041,7 +1024,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                 * power level:
                 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
                 */
-               if (priv->offchan_tx_chan->band == IEEE80211_BAND_5GHZ)
+               if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
                        scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
                else
                        scan_ch->tx_gain = ((1 << 5) | (5 << 3));
index 3789ff4bf53beaa6dba5fe881d8c24f61f025a7f..1fa438e20f0adb01cd85fc1f897dcc8bb74580ed 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 
 #include <linux/netdevice.h>
index d42ef1763a711a06a994990b59ea858d8fec244b..d562e9359d97f7ae6fc85b0431e175189d97f1bd 100644 (file)
@@ -337,10 +337,10 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
        cmd.slots[0].type = 0; /* BSS */
        cmd.slots[1].type = 1; /* PAN */
 
-       if (priv->hw_roc_channel) {
+       if (priv->hw_roc_setup) {
                /* both contexts must be used for this to happen */
-               slot1 = priv->hw_roc_duration;
-               slot0 = IWL_MIN_SLOT_TIME;
+               slot1 = IWL_MIN_SLOT_TIME;
+               slot0 = 3000;
        } else if (ctx_bss->vif && ctx_pan->vif) {
                int bcnint = ctx_pan->beacon_int;
                int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
@@ -437,23 +437,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        /* always get timestamp with Rx frame */
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
-       if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->hw_roc_channel) {
-               struct ieee80211_channel *chan = priv->hw_roc_channel;
-
-               iwl_set_rxon_channel(priv, chan, ctx);
-               iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
-               ctx->staging.filter_flags |=
-                       RXON_FILTER_ASSOC_MSK |
-                       RXON_FILTER_PROMISC_MSK |
-                       RXON_FILTER_CTL2HOST_MSK;
-               ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
-               new_assoc = true;
-
-               if (memcmp(&ctx->staging, &ctx->active,
-                          sizeof(ctx->staging)) == 0)
-                       return 0;
-       }
-
        /*
         * force CTS-to-self frames protection if RTS-CTS is not preferred
         * one aggregation protection method
index 53bb59ee719da50b4a3aebd00dfdedaef16605a5..9bc26da62768cc97a0cdf3fa217fbb78561ae8c7 100644 (file)
@@ -128,11 +128,10 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
  * handle build REPLY_TX command notification.
  */
 static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
-                                       struct sk_buff *skb,
-                                       struct iwl_tx_cmd *tx_cmd,
-                                       struct ieee80211_tx_info *info,
-                                       struct ieee80211_hdr *hdr,
-                                       u8 std_id)
+                                     struct sk_buff *skb,
+                                     struct iwl_tx_cmd *tx_cmd,
+                                     struct ieee80211_tx_info *info,
+                                     struct ieee80211_hdr *hdr, u8 sta_id)
 {
        __le16 fc = hdr->frame_control;
        __le32 tx_flags = tx_cmd->tx_flags;
@@ -157,7 +156,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
                tx_flags |= TX_CMD_FLG_IGNORE_BT;
 
 
-       tx_cmd->sta_id = std_id;
+       tx_cmd->sta_id = sta_id;
        if (ieee80211_has_morefrags(fc))
                tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
 
@@ -189,9 +188,9 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
 #define RTS_DFAULT_RETRY_LIMIT         60
 
 static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
-                             struct iwl_tx_cmd *tx_cmd,
-                             struct ieee80211_tx_info *info,
-                             __le16 fc)
+                                    struct iwl_tx_cmd *tx_cmd,
+                                    struct ieee80211_tx_info *info,
+                                    __le16 fc)
 {
        u32 rate_flags;
        int rate_idx;
@@ -334,14 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        unsigned long flags;
        bool is_agg = false;
 
-       /*
-        * If the frame needs to go out off-channel, then
-        * we'll have put the PAN context to that channel,
-        * so make the frame go out there.
-        */
-       if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
-               ctx = &priv->contexts[IWL_RXON_CTX_PAN];
-       else if (info->control.vif)
+       if (info->control.vif)
                ctx = iwl_rxon_ctx_from_vif(info->control.vif);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -407,7 +399,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                 */
                hdr->frame_control |=
                        cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-       } else
+       } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
+               txq_id = IWL_AUX_QUEUE;
+       else
                txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
 
        /* irqs already disabled/saved above when locking priv->lock */
index b0ae4de7f0834f73401f80ef4d4e9063e4927036..33894dde1ae3dd454930d2b38cda3a8feec7e453 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
@@ -614,6 +613,87 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
        return 0;
 }
 
+static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
+{
+       static const u8 iwlagn_bss_ac_to_fifo[] = {
+               IWL_TX_FIFO_VO,
+               IWL_TX_FIFO_VI,
+               IWL_TX_FIFO_BE,
+               IWL_TX_FIFO_BK,
+       };
+       static const u8 iwlagn_bss_ac_to_queue[] = {
+               0, 1, 2, 3,
+       };
+       static const u8 iwlagn_pan_ac_to_fifo[] = {
+               IWL_TX_FIFO_VO_IPAN,
+               IWL_TX_FIFO_VI_IPAN,
+               IWL_TX_FIFO_BE_IPAN,
+               IWL_TX_FIFO_BK_IPAN,
+       };
+       static const u8 iwlagn_pan_ac_to_queue[] = {
+               7, 6, 5, 4,
+       };
+       int i;
+
+       /*
+        * The default context is always valid,
+        * the PAN context depends on uCode.
+        */
+       priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
+       if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
+               priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
+
+       for (i = 0; i < NUM_IWL_RXON_CTX; i++)
+               priv->contexts[i].ctxid = i;
+
+       priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
+       priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
+       priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
+       priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
+       priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
+       priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
+       priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
+       priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+       priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
+       priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
+       priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
+               BIT(NL80211_IFTYPE_ADHOC);
+       priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
+               BIT(NL80211_IFTYPE_STATION);
+       priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
+       priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
+       priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
+       priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
+
+       priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
+       priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
+               REPLY_WIPAN_RXON_TIMING;
+       priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
+               REPLY_WIPAN_RXON_ASSOC;
+       priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
+       priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
+       priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
+       priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
+       priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
+       priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
+       priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
+       priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
+       priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
+               BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
+
+       if (ucode_flags & IWL_UCODE_TLV_FLAGS_P2P)
+               priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
+                       BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                       BIT(NL80211_IFTYPE_P2P_GO);
+
+       priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
+       priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
+       priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
+
+       BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+}
+
+
 struct iwlagn_ucode_capabilities {
        u32 max_probe_length;
        u32 standard_phy_calibration_size;
@@ -952,6 +1032,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        int err;
        struct iwlagn_firmware_pieces pieces;
        const unsigned int api_max = priv->cfg->ucode_api_max;
+       unsigned int api_ok = priv->cfg->ucode_api_ok;
        const unsigned int api_min = priv->cfg->ucode_api_min;
        u32 api_ver;
        char buildstr[25];
@@ -962,10 +1043,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
                        IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
        };
 
+       if (!api_ok)
+               api_ok = api_max;
+
        memset(&pieces, 0, sizeof(pieces));
 
        if (!ucode_raw) {
-               if (priv->fw_index <= priv->cfg->ucode_api_max)
+               if (priv->fw_index <= api_ok)
                        IWL_ERR(priv,
                                "request for firmware file '%s' failed.\n",
                                priv->firmware_name);
@@ -1011,12 +1095,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
                        goto try_again;
                }
 
-               if (api_ver != api_max)
-                       IWL_ERR(priv,
-                               "Firmware has old API version. Expected v%u, "
-                               "got v%u. New firmware can be obtained "
-                               "from http://www.intellinuxwireless.org.\n",
-                               api_max, api_ver);
+               if (api_ver < api_ok) {
+                       if (api_ok != api_max)
+                               IWL_ERR(priv, "Firmware has old API version, "
+                                       "expected v%u through v%u, got v%u.\n",
+                                       api_ok, api_max, api_ver);
+                       else
+                               IWL_ERR(priv, "Firmware has old API version, "
+                                       "expected v%u, got v%u.\n",
+                                       api_max, api_ver);
+                       IWL_ERR(priv, "New firmware can be obtained from "
+                                     "http://www.intellinuxwireless.org/.\n");
+               }
        }
 
        if (build)
@@ -1143,17 +1233,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        priv->new_scan_threshold_behaviour =
                !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
 
-       if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) &&
-           (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) {
-               priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
-               priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
-       } else
-               priv->sta_key_max_num = STA_KEY_MAX_NUM;
+       if (!(priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
+               ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
 
-       if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+       /*
+        * if not PAN, then don't support P2P -- might be a uCode
+        * packaging bug or due to the eeprom check above
+        */
+       if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
+               ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
+
+       if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
+               priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
                priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
-       else
+       } else {
+               priv->sta_key_max_num = STA_KEY_MAX_NUM;
                priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
+       }
 
        /*
         * figure out the offset of chain noise reset and gain commands
@@ -1169,6 +1265,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        priv->phy_calib_chain_noise_gain_cmd =
                ucode_capa.standard_phy_calibration_size + 1;
 
+       /* initialize all valid contexts */
+       iwl_init_context(priv, ucode_capa.flags);
+
        /**************************************************
         * This is still part of probe() in a sense...
         *
@@ -1765,6 +1864,13 @@ static void __iwl_down(struct iwl_priv *priv)
 
        iwl_scan_cancel_timeout(priv, 200);
 
+       /*
+        * If active, scanning won't cancel it, so say it expired.
+        * No race since we hold the mutex here and a new one
+        * can't come in at this time.
+        */
+       ieee80211_remain_on_channel_expired(priv->hw);
+
        exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
@@ -1955,94 +2061,6 @@ static void iwl_bg_restart(struct work_struct *data)
        }
 }
 
-static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                                struct ieee80211_channel *chan,
-                                enum nl80211_channel_type channel_type,
-                                unsigned int wait)
-{
-       struct iwl_priv *priv = hw->priv;
-       int ret;
-
-       /* Not supported if we don't have PAN */
-       if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) {
-               ret = -EOPNOTSUPP;
-               goto free;
-       }
-
-       /* Not supported on pre-P2P firmware */
-       if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes &
-                                       BIT(NL80211_IFTYPE_P2P_CLIENT))) {
-               ret = -EOPNOTSUPP;
-               goto free;
-       }
-
-       mutex_lock(&priv->mutex);
-
-       if (!priv->contexts[IWL_RXON_CTX_PAN].is_active) {
-               /*
-                * If the PAN context is free, use the normal
-                * way of doing remain-on-channel offload + TX.
-                */
-               ret = 1;
-               goto out;
-       }
-
-       /* TODO: queue up if scanning? */
-       if (test_bit(STATUS_SCANNING, &priv->status) ||
-           priv->offchan_tx_skb) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       /*
-        * max_scan_ie_len doesn't include the blank SSID or the header,
-        * so need to add that again here.
-        */
-       if (skb->len > hw->wiphy->max_scan_ie_len + 24 + 2) {
-               ret = -ENOBUFS;
-               goto out;
-       }
-
-       priv->offchan_tx_skb = skb;
-       priv->offchan_tx_timeout = wait;
-       priv->offchan_tx_chan = chan;
-
-       ret = iwl_scan_initiate(priv, priv->contexts[IWL_RXON_CTX_PAN].vif,
-                               IWL_SCAN_OFFCH_TX, chan->band);
-       if (ret)
-               priv->offchan_tx_skb = NULL;
- out:
-       mutex_unlock(&priv->mutex);
- free:
-       if (ret < 0)
-               kfree_skb(skb);
-
-       return ret;
-}
-
-static int iwl_mac_offchannel_tx_cancel_wait(struct ieee80211_hw *hw)
-{
-       struct iwl_priv *priv = hw->priv;
-       int ret;
-
-       mutex_lock(&priv->mutex);
-
-       if (!priv->offchan_tx_skb) {
-               ret = -EINVAL;
-               goto unlock;
-       }
-
-       priv->offchan_tx_skb = NULL;
-
-       ret = iwl_scan_cancel_timeout(priv, 200);
-       if (ret)
-               ret = -EIO;
-unlock:
-       mutex_unlock(&priv->mutex);
-
-       return ret;
-}
-
 /*****************************************************************************
  *
  * mac80211 entry point functions
@@ -3198,35 +3216,34 @@ done:
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
-static void iwlagn_disable_roc(struct iwl_priv *priv)
+void iwlagn_disable_roc(struct iwl_priv *priv)
 {
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
-       struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel);
 
        lockdep_assert_held(&priv->mutex);
 
-       if (!ctx->is_active)
+       if (!priv->hw_roc_setup)
                return;
 
-       ctx->staging.dev_type = RXON_DEV_TYPE_2STA;
+       ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_set_rxon_channel(priv, chan, ctx);
-       iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
 
        priv->hw_roc_channel = NULL;
 
+       memset(ctx->staging.node_addr, 0, ETH_ALEN);
+
        iwlagn_commit_rxon(priv, ctx);
 
        ctx->is_active = false;
+       priv->hw_roc_setup = false;
 }
 
-static void iwlagn_bg_roc_done(struct work_struct *work)
+static void iwlagn_disable_roc_work(struct work_struct *work)
 {
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
-                                            hw_roc_work.work);
+                                            hw_roc_disable_work.work);
 
        mutex_lock(&priv->mutex);
-       ieee80211_remain_on_channel_expired(priv->hw);
        iwlagn_disable_roc(priv);
        mutex_unlock(&priv->mutex);
 }
@@ -3237,33 +3254,63 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
                                     int duration)
 {
        struct iwl_priv *priv = hw->priv;
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
        int err = 0;
 
        if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
                return -EOPNOTSUPP;
 
-       if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes &
-                                       BIT(NL80211_IFTYPE_P2P_CLIENT)))
+       if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)))
                return -EOPNOTSUPP;
 
        mutex_lock(&priv->mutex);
 
-       if (priv->contexts[IWL_RXON_CTX_PAN].is_active ||
-           test_bit(STATUS_SCAN_HW, &priv->status)) {
+       /*
+        * TODO: Remove this hack! Firmware needs to be updated
+        * to allow longer off-channel periods in scanning for
+        * this use case, based on a flag (and we'll need an API
+        * flag in the firmware when it has that).
+        */
+       if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80)
+               duration = 80;
+
+       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                err = -EBUSY;
                goto out;
        }
 
-       priv->contexts[IWL_RXON_CTX_PAN].is_active = true;
        priv->hw_roc_channel = channel;
        priv->hw_roc_chantype = channel_type;
-       priv->hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024);
-       iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
-       queue_delayed_work(priv->workqueue, &priv->hw_roc_work,
-                          msecs_to_jiffies(duration + 20));
+       priv->hw_roc_duration = duration;
+       cancel_delayed_work(&priv->hw_roc_disable_work);
+
+       if (!ctx->is_active) {
+               ctx->is_active = true;
+               ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
+               memcpy(ctx->staging.node_addr,
+                      priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
+                      ETH_ALEN);
+               memcpy(ctx->staging.bssid_addr,
+                      priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
+                      ETH_ALEN);
+               err = iwlagn_commit_rxon(priv, ctx);
+               if (err)
+                       goto out;
+               ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK |
+                                            RXON_FILTER_PROMISC_MSK |
+                                            RXON_FILTER_CTL2HOST_MSK;
+
+               err = iwlagn_commit_rxon(priv, ctx);
+               if (err) {
+                       iwlagn_disable_roc(priv);
+                       goto out;
+               }
+               priv->hw_roc_setup = true;
+       }
 
-       msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */
-       ieee80211_ready_on_channel(priv->hw);
+       err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band);
+       if (err)
+               iwlagn_disable_roc(priv);
 
  out:
        mutex_unlock(&priv->mutex);
@@ -3278,9 +3325,8 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
        if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
                return -EOPNOTSUPP;
 
-       cancel_delayed_work_sync(&priv->hw_roc_work);
-
        mutex_lock(&priv->mutex);
+       iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
        iwlagn_disable_roc(priv);
        mutex_unlock(&priv->mutex);
 
@@ -3305,7 +3351,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
        INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
        INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
-       INIT_DELAYED_WORK(&priv->hw_roc_work, iwlagn_bg_roc_done);
+       INIT_DELAYED_WORK(&priv->hw_roc_disable_work,
+                         iwlagn_disable_roc_work);
 
        iwl_setup_scan_deferred_work(priv);
 
@@ -3337,6 +3384,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 
        cancel_work_sync(&priv->bt_full_concurrency);
        cancel_work_sync(&priv->bt_runtime_config);
+       cancel_delayed_work_sync(&priv->hw_roc_disable_work);
 
        del_timer_sync(&priv->statistics_periodic);
        del_timer_sync(&priv->ucode_trace);
@@ -3489,8 +3537,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .tx_last_beacon = iwl_mac_tx_last_beacon,
        .remain_on_channel = iwl_mac_remain_on_channel,
        .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
-       .offchannel_tx = iwl_mac_offchannel_tx,
-       .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
        .rssi_callback = iwl_mac_rssi_callback,
        CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
        CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
@@ -3519,28 +3565,6 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
        return priv->cfg->lib->set_hw_params(priv);
 }
 
-static const u8 iwlagn_bss_ac_to_fifo[] = {
-       IWL_TX_FIFO_VO,
-       IWL_TX_FIFO_VI,
-       IWL_TX_FIFO_BE,
-       IWL_TX_FIFO_BK,
-};
-
-static const u8 iwlagn_bss_ac_to_queue[] = {
-       0, 1, 2, 3,
-};
-
-static const u8 iwlagn_pan_ac_to_fifo[] = {
-       IWL_TX_FIFO_VO_IPAN,
-       IWL_TX_FIFO_VI_IPAN,
-       IWL_TX_FIFO_BE_IPAN,
-       IWL_TX_FIFO_BK_IPAN,
-};
-
-static const u8 iwlagn_pan_ac_to_queue[] = {
-       7, 6, 5, 4,
-};
-
 /* This function both allocates and initializes hw and priv. */
 static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
 {
@@ -3563,65 +3587,6 @@ out:
        return hw;
 }
 
-static void iwl_init_context(struct iwl_priv *priv)
-{
-       int i;
-
-       /*
-        * The default context is always valid,
-        * more may be discovered when firmware
-        * is loaded.
-        */
-       priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
-
-       for (i = 0; i < NUM_IWL_RXON_CTX; i++)
-               priv->contexts[i].ctxid = i;
-
-       priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
-       priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
-       priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
-       priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
-       priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
-       priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
-       priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
-       priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
-       priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
-       priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
-       priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
-               BIT(NL80211_IFTYPE_ADHOC);
-       priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
-               BIT(NL80211_IFTYPE_STATION);
-       priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
-       priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
-       priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
-       priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
-
-       priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
-       priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
-               REPLY_WIPAN_RXON_TIMING;
-       priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
-               REPLY_WIPAN_RXON_ASSOC;
-       priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
-       priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
-       priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
-       priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
-       priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
-       priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
-       priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
-       priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
-       priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
-               BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
-#ifdef CONFIG_IWL_P2P
-       priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
-               BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
-#endif
-       priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
-       priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
-       priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
-
-       BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
-}
-
 int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
 {
        int err = 0;
@@ -3724,9 +3689,6 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
                priv->hw->wiphy->n_addresses++;
        }
 
-       /* initialize all valid contexts */
-       iwl_init_context(priv);
-
        /************************
         * 5. Setup HW constants
         ************************/
index d941c4c98e4b153f937460f417958a8612eba9a3..df2960ae92aa6dca28ea3bfd4914955d519dc3fa 100644 (file)
@@ -209,6 +209,7 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
 /* scan */
 int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
 void iwlagn_post_scan(struct iwl_priv *priv);
+void iwlagn_disable_roc(struct iwl_priv *priv);
 
 /* station mgmt */
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
index e9e9d1d1778dcc0dd86189bf25f7dfee9dd06ecd..0016c61b3000e84f52e1d4ceed2aa3406aedf24a 100644 (file)
@@ -3067,17 +3067,29 @@ struct iwl_missed_beacon_notif {
 /* number of additional entries for enhanced tbl */
 #define ENHANCE_HD_TABLE_ENTRIES  (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE)
 
-#define HD_INA_NON_SQUARE_DET_OFDM_DATA                        cpu_to_le16(0)
-#define HD_INA_NON_SQUARE_DET_CCK_DATA                 cpu_to_le16(0)
-#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA           cpu_to_le16(0)
-#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA          cpu_to_le16(668)
-#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA      cpu_to_le16(4)
-#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA              cpu_to_le16(486)
-#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA          cpu_to_le16(37)
-#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA           cpu_to_le16(853)
-#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA       cpu_to_le16(4)
-#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA               cpu_to_le16(476)
-#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA           cpu_to_le16(99)
+#define HD_INA_NON_SQUARE_DET_OFDM_DATA_V1             cpu_to_le16(0)
+#define HD_INA_NON_SQUARE_DET_CCK_DATA_V1              cpu_to_le16(0)
+#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1                cpu_to_le16(0)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1       cpu_to_le16(668)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1   cpu_to_le16(4)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1           cpu_to_le16(486)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1       cpu_to_le16(37)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1                cpu_to_le16(853)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1    cpu_to_le16(4)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1            cpu_to_le16(476)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1                cpu_to_le16(99)
+
+#define HD_INA_NON_SQUARE_DET_OFDM_DATA_V2             cpu_to_le16(1)
+#define HD_INA_NON_SQUARE_DET_CCK_DATA_V2              cpu_to_le16(1)
+#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2                cpu_to_le16(1)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2       cpu_to_le16(600)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2   cpu_to_le16(40)
+#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2           cpu_to_le16(486)
+#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2       cpu_to_le16(45)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2                cpu_to_le16(853)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2    cpu_to_le16(60)
+#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2            cpu_to_le16(476)
+#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2                cpu_to_le16(99)
 
 
 /* Control field in struct iwl_sensitivity_cmd */
index cf376f62b2f6b3d5dea8c7d13d61a4a313fd3957..e269987cd64c339acc8eb36c5b9fbcb08182dd3a 100644 (file)
@@ -40,6 +40,7 @@
 #include "iwl-io.h"
 #include "iwl-power.h"
 #include "iwl-sta.h"
+#include "iwl-agn.h"
 #include "iwl-helpers.h"
 #include "iwl-agn.h"
 #include "iwl-trans.h"
@@ -1273,8 +1274,12 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
                           viftype, vif->addr);
 
+       cancel_delayed_work_sync(&priv->hw_roc_disable_work);
+
        mutex_lock(&priv->mutex);
 
+       iwlagn_disable_roc(priv);
+
        if (!iwl_is_ready_rf(priv)) {
                IWL_WARN(priv, "Try to add interface when device not ready\n");
                err = -EINVAL;
index 02817a43855097e9c12bac9a4aa5a7de2caf9124..42bcb469d32cb4a8eae39338b7ccc297f263a4cc 100644 (file)
@@ -136,6 +136,7 @@ struct iwl_mod_params {
  * @max_event_log_size: size of event log buffer size for ucode event logging
  * @shadow_reg_enable: HW shadhow register bit
  * @no_idle_support: do not support idle mode
+ * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
  */
 struct iwl_base_params {
        int eeprom_size;
@@ -158,6 +159,7 @@ struct iwl_base_params {
        u32 max_event_log_size;
        const bool shadow_reg_enable;
        const bool no_idle_support;
+       const bool hd_v2;
 };
 /*
  * @advanced_bt_coexist: support advanced bt coexist
@@ -194,6 +196,8 @@ struct iwl_ht_params {
  *     (.ucode) will be added to filename before loading from disk. The
  *     filename is constructed as fw_name_pre<api>.ucode.
  * @ucode_api_max: Highest version of uCode API supported by driver.
+ * @ucode_api_ok: oldest version of the uCode API that is OK to load
+ *     without a warning, for use in transitions
  * @ucode_api_min: Lowest version of uCode API supported by driver.
  * @valid_tx_ant: valid transmit antenna
  * @valid_rx_ant: valid receive antenna
@@ -237,6 +241,7 @@ struct iwl_cfg {
        const char *name;
        const char *fw_name_pre;
        const unsigned int ucode_api_max;
+       const unsigned int ucode_api_ok;
        const unsigned int ucode_api_min;
        u8   valid_tx_ant;
        u8   valid_rx_ant;
index 6c9790cac8d0b284b5c8870318349fd4b6d5f609..dd34c7c502facfb6eadbcc0edecf5f756be3b8cb 100644 (file)
@@ -230,12 +230,23 @@ struct iwl_channel_info {
 #define IWL_TX_FIFO_BE_IPAN    4
 #define IWL_TX_FIFO_VI_IPAN    IWL_TX_FIFO_VI
 #define IWL_TX_FIFO_VO_IPAN    5
+/* re-uses the VO FIFO, uCode will properly flush/schedule */
+#define IWL_TX_FIFO_AUX                5
 #define IWL_TX_FIFO_UNUSED     -1
 
-/* Minimum number of queues. MAX_NUM is defined in hw specific files.
- * Set the minimum to accommodate the 4 standard TX queues, 1 command
- * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */
-#define IWL_MIN_NUM_QUEUES     10
+/* AUX (TX during scan dwell) queue */
+#define IWL_AUX_QUEUE          10
+
+/*
+ * Minimum number of queues. MAX_NUM is defined in hw specific files.
+ * Set the minimum to accommodate
+ *  - 4 standard TX queues
+ *  - the command queue
+ *  - 4 PAN TX queues
+ *  - the PAN multicast queue, and
+ *  - the AUX (TX during scan dwell) queue.
+ */
+#define IWL_MIN_NUM_QUEUES     11
 
 /*
  * Command queue depends on iPAN support.
@@ -564,11 +575,13 @@ enum iwl_ucode_tlv_type {
  * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
  *     treats good CRC threshold as a boolean
  * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
  */
 enum iwl_ucode_tlv_flag {
        IWL_UCODE_TLV_FLAGS_PAN         = BIT(0),
        IWL_UCODE_TLV_FLAGS_NEWSCAN     = BIT(1),
        IWL_UCODE_TLV_FLAGS_MFP         = BIT(2),
+       IWL_UCODE_TLV_FLAGS_P2P         = BIT(3),
 };
 
 struct iwl_ucode_tlv {
@@ -1168,7 +1181,7 @@ struct iwl_rxon_context {
 enum iwl_scan_type {
        IWL_SCAN_NORMAL,
        IWL_SCAN_RADIO_RESET,
-       IWL_SCAN_OFFCH_TX,
+       IWL_SCAN_ROC,
 };
 
 enum iwlagn_ucode_type {
@@ -1438,15 +1451,11 @@ struct iwl_priv {
 
        /* remain-on-channel offload support */
        struct ieee80211_channel *hw_roc_channel;
-       struct delayed_work hw_roc_work;
+       struct delayed_work hw_roc_disable_work;
        enum nl80211_channel_type hw_roc_chantype;
        int hw_roc_duration;
        bool hw_roc_setup;
 
-       struct sk_buff *offchan_tx_skb;
-       int offchan_tx_timeout;
-       struct ieee80211_channel *offchan_tx_chan;
-
        /* bt coex */
        u8 bt_enable_flag;
        u8 bt_status;
index a67ae56d5464bec1f6386c9c1ac056cae4e5109d..1a5252d8ca7359094681fd3fdeed8b70fc3fe193 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
index 69d4ec467dca70d8da0dbe0129677f42da2f2d30..2fdbffa079c1fdc4aa0529d5c2b0a885c8a18870 100644 (file)
@@ -478,27 +478,22 @@ out_no_pci:
        return err;
 }
 
-static void iwl_pci_down(struct iwl_bus *bus)
-{
-       struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus->bus_specific;
-
-       pci_disable_msi(pci_bus->pci_dev);
-       pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base);
-       pci_release_regions(pci_bus->pci_dev);
-       pci_disable_device(pci_bus->pci_dev);
-       pci_set_drvdata(pci_bus->pci_dev, NULL);
-
-       kfree(bus);
-}
-
 static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 {
        struct iwl_priv *priv = pci_get_drvdata(pdev);
-       void *bus_specific = priv->bus->bus_specific;
+       struct iwl_bus *bus = priv->bus;
+       struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus);
+       struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
 
        iwl_remove(priv);
 
-       iwl_pci_down(bus_specific);
+       pci_disable_msi(pci_dev);
+       pci_iounmap(pci_dev, pci_bus->hw_base);
+       pci_release_regions(pci_dev);
+       pci_disable_device(pci_dev);
+       pci_set_drvdata(pci_dev, NULL);
+
+       kfree(bus);
 }
 
 #ifdef CONFIG_PM
index dd6937e970553c942a05d72d07418a5f1c4a524a..28e59319f58112725dc99b083e853cf5d1d61df0 100644 (file)
@@ -103,6 +103,12 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
                ieee80211_scan_completed(priv->hw, aborted);
        }
 
+       if (priv->scan_type == IWL_SCAN_ROC) {
+               ieee80211_remain_on_channel_expired(priv->hw);
+               priv->hw_roc_channel = NULL;
+               schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
+       }
+
        priv->scan_type = IWL_SCAN_NORMAL;
        priv->scan_vif = NULL;
        priv->scan_request = NULL;
@@ -211,6 +217,9 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
                       le32_to_cpu(notif->tsf_high),
                       le32_to_cpu(notif->tsf_low),
                       notif->status, notif->beacon_timer);
+
+       if (priv->scan_type == IWL_SCAN_ROC)
+               ieee80211_ready_on_channel(priv->hw);
 }
 
 /* Service SCAN_RESULTS_NOTIFICATION (0x83) */
@@ -370,7 +379,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 
        IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
                        scan_type == IWL_SCAN_NORMAL ? "" :
-                       scan_type == IWL_SCAN_OFFCH_TX ? "offchan TX " :
+                       scan_type == IWL_SCAN_ROC ? "remain-on-channel " :
                        "internal short ");
 
        set_bit(STATUS_SCANNING, &priv->status);
@@ -565,10 +574,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
                goto out_settings;
        }
 
-       if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->offchan_tx_skb) {
-               ieee80211_tx_status_irqsafe(priv->hw,
-                                           priv->offchan_tx_skb);
-               priv->offchan_tx_skb = NULL;
+       if (priv->scan_type == IWL_SCAN_ROC) {
+               ieee80211_remain_on_channel_expired(priv->hw);
+               priv->hw_roc_channel = NULL;
+               schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ);
        }
 
        if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
index 41f0de9140087e4105354a9dcb2a03cacde4fccb..3001bfb46e25211843cc451b7a9856567db5c4e0 100644 (file)
@@ -750,6 +750,7 @@ static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
        { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
        { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
        { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
 };
 
 static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
@@ -763,6 +764,7 @@ static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
        { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
        { IWL_TX_FIFO_BE_IPAN, 2, },
        { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_AUX, IWL_AC_UNSET, },
 };
 static void iwl_trans_tx_start(struct iwl_priv *priv)
 {
@@ -848,10 +850,12 @@ static void iwl_trans_tx_start(struct iwl_priv *priv)
        /* reset to 0 to enable all the queue first */
        priv->txq_ctx_active_msk = 0;
 
-       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
-       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
+       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) !=
+                                               IWLAGN_FIRST_AMPDU_QUEUE);
+       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) !=
+                                               IWLAGN_FIRST_AMPDU_QUEUE);
 
-       for (i = 0; i < 10; i++) {
+       for (i = 0; i < IWLAGN_FIRST_AMPDU_QUEUE; i++) {
                int fifo = queue_to_fifo[i].fifo;
                int ac = queue_to_fifo[i].ac;
 
index b456a53b64b19b22aa3442b13ca1a2859ea622c6..85b3169c40d70148593a81e4f98f242d04e01d21 100644 (file)
@@ -19,6 +19,7 @@
 #include "decl.h"
 #include "cfg.h"
 #include "cmd.h"
+#include "mesh.h"
 
 
 #define CHAN2G(_channel, _freq, _flags) {        \
@@ -442,13 +443,16 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy,
        struct lbs_private *priv = wiphy_priv(wiphy);
        int ret = -ENOTSUPP;
 
-       lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
-                          channel->center_freq, channel_type);
+       lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d, type %d",
+                          netdev_name(netdev), channel->center_freq, channel_type);
 
        if (channel_type != NL80211_CHAN_NO_HT)
                goto out;
 
-       ret = lbs_set_channel(priv, channel->hw_value);
+       if (netdev == priv->mesh_dev)
+               ret = lbs_mesh_set_channel(priv, channel->hw_value);
+       else
+               ret = lbs_set_channel(priv, channel->hw_value);
 
  out:
        lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -708,7 +712,7 @@ static void lbs_scan_worker(struct work_struct *work)
 
        if (priv->scan_channel < priv->scan_req->n_channels) {
                cancel_delayed_work(&priv->scan_work);
-               if (!priv->stopping)
+               if (netif_running(priv->dev))
                        queue_delayed_work(priv->work_thread, &priv->scan_work,
                                msecs_to_jiffies(300));
        }
@@ -1292,6 +1296,9 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
        int ret = 0;
        u8 preamble = RADIO_PREAMBLE_SHORT;
 
+       if (dev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        if (!sme->bssid) {
@@ -1402,28 +1409,23 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
        return ret;
 }
 
-static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
-       u16 reason_code)
+int lbs_disconnect(struct lbs_private *priv, u16 reason)
 {
-       struct lbs_private *priv = wiphy_priv(wiphy);
        struct cmd_ds_802_11_deauthenticate cmd;
-
-       lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
-
-       /* store for lbs_cfg_ret_disconnect() */
-       priv->disassoc_reason = reason_code;
+       int ret;
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        /* Mildly ugly to use a locally store my own BSSID ... */
        memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
-       cmd.reasoncode = cpu_to_le16(reason_code);
+       cmd.reasoncode = cpu_to_le16(reason);
 
-       if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd))
-               return -EFAULT;
+       ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
+       if (ret)
+               return ret;
 
        cfg80211_disconnected(priv->dev,
-                       priv->disassoc_reason,
+                       reason,
                        NULL, 0,
                        GFP_KERNEL);
        priv->connect_status = LBS_DISCONNECTED;
@@ -1431,6 +1433,21 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
+static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
+       u16 reason_code)
+{
+       struct lbs_private *priv = wiphy_priv(wiphy);
+
+       if (dev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
+       lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
+
+       /* store for lbs_cfg_ret_disconnect() */
+       priv->disassoc_reason = reason_code;
+
+       return lbs_disconnect(priv, reason_code);
+}
 
 static int lbs_cfg_set_default_key(struct wiphy *wiphy,
                                   struct net_device *netdev,
@@ -1439,6 +1456,9 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy,
 {
        struct lbs_private *priv = wiphy_priv(wiphy);
 
+       if (netdev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        if (key_index != priv->wep_tx_key) {
@@ -1460,6 +1480,9 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
        u16 key_type;
        int ret = 0;
 
+       if (netdev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
@@ -1603,6 +1626,9 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
        s8 signal, noise;
        int ret;
 
+       if (dev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        if (idx != 0)
                ret = -ENOENT;
 
@@ -1636,6 +1662,9 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
        struct lbs_private *priv = wiphy_priv(wiphy);
        int ret = 0;
 
+       if (dev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        switch (type) {
@@ -1959,6 +1988,9 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        struct cfg80211_bss *bss;
        DECLARE_SSID_BUF(ssid_buf);
 
+       if (dev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        if (!params->channel) {
@@ -1995,6 +2027,9 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
        struct cmd_ds_802_11_ad_hoc_stop cmd;
        int ret = 0;
 
+       if (dev == priv->mesh_dev)
+               return -EOPNOTSUPP;
+
        lbs_deb_enter(LBS_DEB_CFG80211);
 
        memset(&cmd, 0, sizeof(cmd));
@@ -2117,6 +2152,8 @@ int lbs_cfg_register(struct lbs_private *priv)
                        BIT(NL80211_IFTYPE_ADHOC);
        if (lbs_rtap_supported(priv))
                wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+       if (lbs_mesh_activated(priv))
+               wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT);
 
        wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
 
index 4f46bb744bee8f4f8cb6432e09cf4a020180350d..a02ee151710e36a1f401912a7f1873ee09f9af37 100644 (file)
@@ -17,5 +17,6 @@ void lbs_send_disconnect_notification(struct lbs_private *priv);
 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
 
 void lbs_scan_deinit(struct lbs_private *priv);
+int lbs_disconnect(struct lbs_private *priv, u16 reason);
 
 #endif
index dbd24a4607ec362177d059d555ece8d73c31e98b..e08ab1de3d9d3bd126eb0a0c821bd46d82cee903 100644 (file)
@@ -1088,7 +1088,7 @@ void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
        if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
                __lbs_cleanup_and_insert_cmd(priv, cmd);
        priv->cur_cmd = NULL;
-       wake_up_interruptible(&priv->waitq);
+       wake_up(&priv->waitq);
 }
 
 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
@@ -1627,7 +1627,7 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
                lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
 
                /* Wake up main thread to execute next command */
-               wake_up_interruptible(&priv->waitq);
+               wake_up(&priv->waitq);
                cmdnode = ERR_PTR(-ENOBUFS);
                goto done;
        }
@@ -1647,7 +1647,7 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
 
        cmdnode->cmdwaitqwoken = 0;
        lbs_queue_cmd(priv, cmdnode);
-       wake_up_interruptible(&priv->waitq);
+       wake_up(&priv->waitq);
 
  done:
        lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
index da0b05bb89fe838d0b4591c3cb4529b4953fa46b..9304e6fc421f064eeacfd5ce5419f39302a64ce8 100644 (file)
@@ -43,10 +43,14 @@ int lbs_start_card(struct lbs_private *priv);
 void lbs_stop_card(struct lbs_private *priv);
 void lbs_host_to_card_done(struct lbs_private *priv);
 
+int lbs_start_iface(struct lbs_private *priv);
+int lbs_stop_iface(struct lbs_private *priv);
+
 int lbs_rtap_supported(struct lbs_private *priv);
 
 int lbs_set_mac_address(struct net_device *dev, void *addr);
 void lbs_set_multicast_list(struct net_device *dev);
+void lbs_update_mcast(struct lbs_private *priv);
 
 int lbs_suspend(struct lbs_private *priv);
 int lbs_resume(struct lbs_private *priv);
index adb3490e3cf52e427210d2c34eb1db2fd1ae247b..814838916b8271cfa390c3e7458dd09ec300bf1f 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef _LBS_DEV_H_
 #define _LBS_DEV_H_
 
-#include "mesh.h"
 #include "defs.h"
 #include "host.h"
 
@@ -22,6 +21,17 @@ struct sleep_params {
        uint16_t sp_reserved;
 };
 
+/* Mesh statistics */
+struct lbs_mesh_stats {
+       u32     fwd_bcast_cnt;          /* Fwd: Broadcast counter */
+       u32     fwd_unicast_cnt;        /* Fwd: Unicast counter */
+       u32     fwd_drop_ttl;           /* Fwd: TTL zero */
+       u32     fwd_drop_rbt;           /* Fwd: Recently Broadcasted */
+       u32     fwd_drop_noroute;       /* Fwd: No route to Destination */
+       u32     fwd_drop_nobuf;         /* Fwd: Run out of internal buffers */
+       u32     drop_blind;             /* Rx:  Dropped by blinding table */
+       u32     tx_failed_cnt;          /* Tx:  Failed transmissions */
+};
 
 /* Private structure for the MV device */
 struct lbs_private {
@@ -36,7 +46,6 @@ struct lbs_private {
        /* CFG80211 */
        struct wireless_dev *wdev;
        bool wiphy_registered;
-       bool stopping;
        struct cfg80211_scan_request *scan_req;
        u8 assoc_bss[ETH_ALEN];
        u8 disassoc_reason;
@@ -86,11 +95,14 @@ struct lbs_private {
 
        /* Hardware access */
        void *card;
+       bool iface_running;
        u8 fw_ready;
        u8 surpriseremoved;
        u8 setup_fw_on_resume;
        int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
        void (*reset_card) (struct lbs_private *priv);
+       int (*power_save) (struct lbs_private *priv);
+       int (*power_restore) (struct lbs_private *priv);
        int (*enter_deep_sleep) (struct lbs_private *priv);
        int (*exit_deep_sleep) (struct lbs_private *priv);
        int (*reset_deep_sleep_wakeup) (struct lbs_private *priv);
@@ -172,4 +184,16 @@ struct lbs_private {
 
 extern struct cmd_confirm_sleep confirm_sleep;
 
+/* Check if there is an interface active. */
+static inline int lbs_iface_active(struct lbs_private *priv)
+{
+       int r;
+
+       r = netif_running(priv->dev);
+       if (priv->mesh_dev);
+               r |= netif_running(priv->dev);
+
+       return r;
+}
+
 #endif
index 4dfb3bfd2cf3f923710939869cea359d503d3c1f..885ddc1c4fed70d8b6a2a47042cba18016069c00 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "decl.h"
 #include "cmd.h"
+#include "mesh.h"
 
 
 static void lbs_ethtool_get_drvinfo(struct net_device *dev,
index 387786e1b3947bd063c7a14d7125e973da20d6f3..c962e21762dc19012a0784f2bdd990921242b3d8 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/host.h>
+#include <linux/pm_runtime.h>
 
 #include "host.h"
 #include "decl.h"
@@ -47,6 +48,8 @@
 #include "cmd.h"
 #include "if_sdio.h"
 
+static void if_sdio_interrupt(struct sdio_func *func);
+
 /* The if_sdio_remove() callback function is called when
  * user removes this module from kernel space or ejects
  * the card from the slot. The driver handles these 2 cases
@@ -757,6 +760,136 @@ out:
        return ret;
 }
 
+/********************************************************************/
+/* Power management                                                 */
+/********************************************************************/
+
+static int if_sdio_power_on(struct if_sdio_card *card)
+{
+       struct sdio_func *func = card->func;
+       struct lbs_private *priv = card->priv;
+       struct mmc_host *host = func->card->host;
+       int ret;
+
+       sdio_claim_host(func);
+
+       ret = sdio_enable_func(func);
+       if (ret)
+               goto release;
+
+       /* For 1-bit transfers to the 8686 model, we need to enable the
+        * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
+        * bit to allow access to non-vendor registers. */
+       if ((card->model == MODEL_8686) &&
+           (host->caps & MMC_CAP_SDIO_IRQ) &&
+           (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
+               u8 reg;
+
+               func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+               reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
+               if (ret)
+                       goto disable;
+
+               reg |= SDIO_BUS_ECSI;
+               sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
+               if (ret)
+                       goto disable;
+       }
+
+       card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
+       if (ret)
+               goto disable;
+
+       card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
+       if (ret)
+               goto disable;
+
+       card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
+       if (ret)
+               goto disable;
+
+       sdio_release_host(func);
+       ret = if_sdio_prog_firmware(card);
+       sdio_claim_host(func);
+       if (ret)
+               goto disable;
+
+       /*
+        * Get rx_unit if the chip is SD8688 or newer.
+        * SD8385 & SD8686 do not have rx_unit.
+        */
+       if ((card->model != MODEL_8385)
+                       && (card->model != MODEL_8686))
+               card->rx_unit = if_sdio_read_rx_unit(card);
+       else
+               card->rx_unit = 0;
+
+       /*
+        * Set up the interrupt handler late.
+        *
+        * If we set it up earlier, the (buggy) hardware generates a spurious
+        * interrupt, even before the interrupt has been enabled, with
+        * CCCR_INTx = 0.
+        *
+        * We register the interrupt handler late so that we can handle any
+        * spurious interrupts, and also to avoid generation of that known
+        * spurious interrupt in the first place.
+        */
+       ret = sdio_claim_irq(func, if_sdio_interrupt);
+       if (ret)
+               goto disable;
+
+       /*
+        * Enable interrupts now that everything is set up
+        */
+       sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
+       if (ret)
+               goto release_irq;
+
+       sdio_release_host(func);
+
+       /*
+        * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
+        */
+       if (card->model == MODEL_8688) {
+               struct cmd_header cmd;
+
+               memset(&cmd, 0, sizeof(cmd));
+
+               lbs_deb_sdio("send function INIT command\n");
+               if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
+                               lbs_cmd_copyback, (unsigned long) &cmd))
+                       netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
+       }
+
+       priv->fw_ready = 1;
+
+       return 0;
+
+release_irq:
+       sdio_release_irq(func);
+disable:
+       sdio_disable_func(func);
+release:
+       sdio_release_host(func);
+       return ret;
+}
+
+static int if_sdio_power_off(struct if_sdio_card *card)
+{
+       struct sdio_func *func = card->func;
+       struct lbs_private *priv = card->priv;
+
+       priv->fw_ready = 0;
+
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+       sdio_disable_func(func);
+       sdio_release_host(func);
+       return 0;
+}
+
+
 /*******************************************************************/
 /* Libertas callbacks                                              */
 /*******************************************************************/
@@ -923,6 +1056,32 @@ static void if_sdio_reset_card(struct lbs_private *priv)
        schedule_work(&card_reset_work);
 }
 
+static int if_sdio_power_save(struct lbs_private *priv)
+{
+       struct if_sdio_card *card = priv->card;
+       int ret;
+
+       flush_workqueue(card->workqueue);
+
+       ret = if_sdio_power_off(card);
+
+       /* Let runtime PM know the card is powered off */
+       pm_runtime_put_sync(&card->func->dev);
+
+       return ret;
+}
+
+static int if_sdio_power_restore(struct lbs_private *priv)
+{
+       struct if_sdio_card *card = priv->card;
+
+       /* Make sure the card will not be powered off by runtime PM */
+       pm_runtime_get_sync(&card->func->dev);
+
+       return if_sdio_power_on(card);
+}
+
+
 /*******************************************************************/
 /* SDIO callbacks                                                  */
 /*******************************************************************/
@@ -976,7 +1135,6 @@ static int if_sdio_probe(struct sdio_func *func,
        int ret, i;
        unsigned int model;
        struct if_sdio_packet *packet;
-       struct mmc_host *host = func->card->host;
 
        lbs_deb_enter(LBS_DEB_SDIO);
 
@@ -1033,45 +1191,6 @@ static int if_sdio_probe(struct sdio_func *func,
                goto free;
        }
 
-       sdio_claim_host(func);
-
-       ret = sdio_enable_func(func);
-       if (ret)
-               goto release;
-
-       /* For 1-bit transfers to the 8686 model, we need to enable the
-        * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
-        * bit to allow access to non-vendor registers. */
-       if ((card->model == MODEL_8686) &&
-           (host->caps & MMC_CAP_SDIO_IRQ) &&
-           (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
-               u8 reg;
-
-               func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
-               reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
-               if (ret)
-                       goto release_int;
-
-               reg |= SDIO_BUS_ECSI;
-               sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
-               if (ret)
-                       goto release_int;
-       }
-
-       card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
-       if (ret)
-               goto release_int;
-
-       card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
-       if (ret)
-               goto release_int;
-
-       card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
-       if (ret)
-               goto release_int;
-
-       sdio_release_host(func);
-
        sdio_set_drvdata(func, card);
 
        lbs_deb_sdio("class = 0x%X, vendor = 0x%X, "
@@ -1079,14 +1198,11 @@ static int if_sdio_probe(struct sdio_func *func,
                        func->class, func->vendor, func->device,
                        model, (unsigned)card->ioport);
 
-       ret = if_sdio_prog_firmware(card);
-       if (ret)
-               goto reclaim;
 
        priv = lbs_add_card(card, &func->dev);
        if (!priv) {
                ret = -ENOMEM;
-               goto reclaim;
+               goto free;
        }
 
        card->priv = priv;
@@ -1097,62 +1213,21 @@ static int if_sdio_probe(struct sdio_func *func,
        priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
        priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
        priv->reset_card = if_sdio_reset_card;
+       priv->power_save = if_sdio_power_save;
+       priv->power_restore = if_sdio_power_restore;
 
-       sdio_claim_host(func);
-
-       /*
-        * Get rx_unit if the chip is SD8688 or newer.
-        * SD8385 & SD8686 do not have rx_unit.
-        */
-       if ((card->model != MODEL_8385)
-                       && (card->model != MODEL_8686))
-               card->rx_unit = if_sdio_read_rx_unit(card);
-       else
-               card->rx_unit = 0;
-
-       /*
-        * Set up the interrupt handler late.
-        *
-        * If we set it up earlier, the (buggy) hardware generates a spurious
-        * interrupt, even before the interrupt has been enabled, with
-        * CCCR_INTx = 0.
-        *
-        * We register the interrupt handler late so that we can handle any
-        * spurious interrupts, and also to avoid generation of that known
-        * spurious interrupt in the first place.
-        */
-       ret = sdio_claim_irq(func, if_sdio_interrupt);
-       if (ret)
-               goto disable;
-
-       /*
-        * Enable interrupts now that everything is set up
-        */
-       sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
-       sdio_release_host(func);
+       ret = if_sdio_power_on(card);
        if (ret)
-               goto reclaim;
-
-       priv->fw_ready = 1;
-
-       /*
-        * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
-        */
-       if (card->model == MODEL_8688) {
-               struct cmd_header cmd;
-
-               memset(&cmd, 0, sizeof(cmd));
-
-               lbs_deb_sdio("send function INIT command\n");
-               if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
-                               lbs_cmd_copyback, (unsigned long) &cmd))
-                       netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
-       }
+               goto err_activate_card;
 
        ret = lbs_start_card(priv);
+       if_sdio_power_off(card);
        if (ret)
                goto err_activate_card;
 
+       /* Tell PM core that we don't need the card to be powered now */
+       pm_runtime_put_noidle(&func->dev);
+
 out:
        lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
@@ -1161,14 +1236,6 @@ out:
 err_activate_card:
        flush_workqueue(card->workqueue);
        lbs_remove_card(priv);
-reclaim:
-       sdio_claim_host(func);
-release_int:
-       sdio_release_irq(func);
-disable:
-       sdio_disable_func(func);
-release:
-       sdio_release_host(func);
 free:
        destroy_workqueue(card->workqueue);
        while (card->packets) {
@@ -1195,6 +1262,9 @@ static void if_sdio_remove(struct sdio_func *func)
 
        card = sdio_get_drvdata(func);
 
+       /* Undo decrement done above in if_sdio_probe */
+       pm_runtime_get_noresume(&func->dev);
+
        if (user_rmmod && (card->model == MODEL_8688)) {
                /*
                 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
@@ -1219,11 +1289,6 @@ static void if_sdio_remove(struct sdio_func *func)
        flush_workqueue(card->workqueue);
        destroy_workqueue(card->workqueue);
 
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-       sdio_disable_func(func);
-       sdio_release_host(func);
-
        while (card->packets) {
                packet = card->packets;
                card->packets = card->packets->next;
index e0286cfbc91d1e3a9001ccf16dd68193ed729064..622ae6de0d8bfc31161ba687f0e4f35a0976b08d 100644 (file)
@@ -531,10 +531,6 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
                goto out;
        err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
                                IF_SPI_CIC_CMD_DOWNLOAD_OVER);
-               goto out;
-
-       lbs_deb_spi("waiting for helper to boot...\n");
-
 out:
        if (err)
                pr_err("failed to load helper firmware (err=%d)\n", err);
index b5acc393a65a02886631b2c91925dbf8f1375d78..0c846f5a646ab9859bb2451c7a1d4c9970c0aecd 100644 (file)
@@ -324,7 +324,7 @@ static int if_usb_probe(struct usb_interface *intf,
        }
        kparam_unblock_sysfs_write(fw_name);
 
-       if (!(priv = lbs_add_card(cardp, &udev->dev)))
+       if (!(priv = lbs_add_card(cardp, &intf->dev)))
                goto err_prog_firmware;
 
        cardp->priv = priv;
@@ -956,7 +956,7 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp,
        priv->dnld_sent = DNLD_RES_RECEIVED;
        spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-       wake_up_interruptible(&priv->waitq);
+       wake_up(&priv->waitq);
 
        return ret;
 }
@@ -1112,6 +1112,15 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
        if (priv->psstate != PS_STATE_FULL_POWER)
                return -1;
 
+#ifdef CONFIG_OLPC
+       if (machine_is_olpc()) {
+               if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
+                       olpc_ec_wakeup_clear(EC_SCI_SRC_WLAN);
+               else
+                       olpc_ec_wakeup_set(EC_SCI_SRC_WLAN);
+       }
+#endif
+
        ret = lbs_suspend(priv);
        if (ret)
                goto out;
index 94652c5a25de396ebe4fceeeb4ccd79663d4b862..d1c1d52931f1251ddd75fa5db38b8b853e42dc66 100644 (file)
@@ -23,6 +23,7 @@
 #include "cfg.h"
 #include "debugfs.h"
 #include "cmd.h"
+#include "mesh.h"
 
 #define DRIVER_RELEASE_VERSION "323.p0"
 const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
@@ -98,6 +99,37 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
        return 0;
 }
 
+int lbs_start_iface(struct lbs_private *priv)
+{
+       struct cmd_ds_802_11_mac_address cmd;
+       int ret;
+
+       if (priv->power_restore) {
+               ret = priv->power_restore(priv);
+               if (ret)
+                       return ret;
+       }
+
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(CMD_ACT_SET);
+       memcpy(cmd.macadd, priv->current_addr, ETH_ALEN);
+
+       ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
+       if (ret) {
+               lbs_deb_net("set MAC address failed\n");
+               goto err;
+       }
+
+       lbs_update_channel(priv);
+
+       priv->iface_running = true;
+       return 0;
+
+err:
+       if (priv->power_save)
+               priv->power_save(priv);
+       return ret;
+}
 
 /**
  *  lbs_dev_open - open the ethX interface
@@ -111,23 +143,64 @@ static int lbs_dev_open(struct net_device *dev)
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_NET);
+       if (!priv->iface_running) {
+               ret = lbs_start_iface(priv);
+               if (ret)
+                       goto out;
+       }
 
        spin_lock_irq(&priv->driver_lock);
-       priv->stopping = false;
 
-       if (priv->connect_status == LBS_CONNECTED)
-               netif_carrier_on(dev);
-       else
-               netif_carrier_off(dev);
+       netif_carrier_off(dev);
 
        if (!priv->tx_pending_len)
                netif_wake_queue(dev);
 
        spin_unlock_irq(&priv->driver_lock);
+
+out:
        lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
        return ret;
 }
 
+static bool lbs_command_queue_empty(struct lbs_private *priv)
+{
+       unsigned long flags;
+       bool ret;
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       ret = priv->cur_cmd == NULL && list_empty(&priv->cmdpendingq);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+       return ret;
+}
+
+int lbs_stop_iface(struct lbs_private *priv)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_MAIN);
+
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       priv->iface_running = false;
+       kfree_skb(priv->currenttxskb);
+       priv->currenttxskb = NULL;
+       priv->tx_pending_len = 0;
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+       cancel_work_sync(&priv->mcast_work);
+
+       /* Disable command processing, and wait for all commands to complete */
+       lbs_deb_main("waiting for commands to complete\n");
+       wait_event(priv->waitq, lbs_command_queue_empty(priv));
+       lbs_deb_main("all commands completed\n");
+
+       if (priv->power_save)
+               ret = priv->power_save(priv);
+
+       lbs_deb_leave(LBS_DEB_MAIN);
+       return ret;
+}
+
 /**
  *  lbs_eth_stop - close the ethX interface
  *
@@ -140,18 +213,25 @@ static int lbs_eth_stop(struct net_device *dev)
 
        lbs_deb_enter(LBS_DEB_NET);
 
+       if (priv->connect_status == LBS_CONNECTED)
+               lbs_disconnect(priv, WLAN_REASON_DEAUTH_LEAVING);
+
        spin_lock_irq(&priv->driver_lock);
-       priv->stopping = true;
        netif_stop_queue(dev);
        spin_unlock_irq(&priv->driver_lock);
 
-       schedule_work(&priv->mcast_work);
+       lbs_update_mcast(priv);
        cancel_delayed_work_sync(&priv->scan_work);
        if (priv->scan_req) {
                cfg80211_scan_done(priv->scan_req, false);
                priv->scan_req = NULL;
        }
 
+       netif_carrier_off(priv->dev);
+
+       if (!lbs_iface_active(priv))
+               lbs_stop_iface(priv);
+
        lbs_deb_leave(LBS_DEB_NET);
        return 0;
 }
@@ -169,7 +249,7 @@ void lbs_host_to_card_done(struct lbs_private *priv)
        /* Wake main thread if commands are pending */
        if (!priv->cur_cmd || priv->tx_pending_len > 0) {
                if (!priv->wakeup_dev_required)
-                       wake_up_interruptible(&priv->waitq);
+                       wake_up(&priv->waitq);
        }
 
        spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -182,29 +262,24 @@ int lbs_set_mac_address(struct net_device *dev, void *addr)
        int ret = 0;
        struct lbs_private *priv = dev->ml_priv;
        struct sockaddr *phwaddr = addr;
-       struct cmd_ds_802_11_mac_address cmd;
 
        lbs_deb_enter(LBS_DEB_NET);
 
+       /*
+        * Can only set MAC address when all interfaces are down, to be written
+        * to the hardware when one of them is brought up.
+        */
+       if (lbs_iface_active(priv))
+               return -EBUSY;
+
        /* In case it was called from the mesh device */
        dev = priv->dev;
 
-       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-       cmd.action = cpu_to_le16(CMD_ACT_SET);
-       memcpy(cmd.macadd, phwaddr->sa_data, ETH_ALEN);
-
-       ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
-       if (ret) {
-               lbs_deb_net("set MAC address failed\n");
-               goto done;
-       }
-
        memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
        memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
        if (priv->mesh_dev)
                memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
 
-done:
        lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
        return ret;
 }
@@ -258,18 +333,18 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
        return i;
 }
 
-static void lbs_set_mcast_worker(struct work_struct *work)
+void lbs_update_mcast(struct lbs_private *priv)
 {
-       struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
        struct cmd_ds_mac_multicast_adr mcast_cmd;
-       int dev_flags;
+       int dev_flags = 0;
        int nr_addrs;
        int old_mac_control = priv->mac_control;
 
        lbs_deb_enter(LBS_DEB_NET);
 
-       dev_flags = priv->dev->flags;
-       if (priv->mesh_dev)
+       if (netif_running(priv->dev))
+               dev_flags |= priv->dev->flags;
+       if (priv->mesh_dev && netif_running(priv->mesh_dev))
                dev_flags |= priv->mesh_dev->flags;
 
        if (dev_flags & IFF_PROMISC) {
@@ -315,6 +390,12 @@ static void lbs_set_mcast_worker(struct work_struct *work)
        lbs_deb_leave(LBS_DEB_NET);
 }
 
+static void lbs_set_mcast_worker(struct work_struct *work)
+{
+       struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
+       lbs_update_mcast(priv);
+}
+
 void lbs_set_multicast_list(struct net_device *dev)
 {
        struct lbs_private *priv = dev->ml_priv;
@@ -647,7 +728,7 @@ static void lbs_cmd_timeout_handler(unsigned long data)
        if (priv->dnld_sent == DNLD_CMD_SENT)
                priv->dnld_sent = DNLD_RES_RECEIVED;
 
-       wake_up_interruptible(&priv->waitq);
+       wake_up(&priv->waitq);
 out:
        spin_unlock_irqrestore(&priv->driver_lock, flags);
        lbs_deb_leave(LBS_DEB_CMD);
@@ -786,7 +867,7 @@ static const struct net_device_ops lbs_netdev_ops = {
        .ndo_stop               = lbs_eth_stop,
        .ndo_start_xmit         = lbs_hard_start_xmit,
        .ndo_set_mac_address    = lbs_set_mac_address,
-       .ndo_set_multicast_list = lbs_set_multicast_list,
+       .ndo_set_rx_mode        = lbs_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
 };
@@ -889,10 +970,6 @@ void lbs_remove_card(struct lbs_private *priv)
        lbs_remove_mesh(priv);
        lbs_scan_deinit(priv);
 
-       dev = priv->dev;
-
-       cancel_work_sync(&priv->mcast_work);
-
        /* worker thread destruction blocks on the in-flight command which
         * should have been cleared already in lbs_stop_card().
         */
@@ -950,17 +1027,18 @@ int lbs_start_card(struct lbs_private *priv)
        if (ret)
                goto done;
 
+       if (!lbs_disablemesh)
+               lbs_init_mesh(priv);
+       else
+               pr_info("%s: mesh disabled\n", dev->name);
+
        if (lbs_cfg_register(priv)) {
                pr_err("cannot register device\n");
                goto done;
        }
 
-       lbs_update_channel(priv);
-
-       if (!lbs_disablemesh)
-               lbs_init_mesh(priv);
-       else
-               pr_info("%s: mesh disabled\n", dev->name);
+       if (lbs_mesh_activated(priv))
+               lbs_start_mesh(priv);
 
        lbs_debugfs_init_one(priv, dev);
 
@@ -978,8 +1056,6 @@ EXPORT_SYMBOL_GPL(lbs_start_card);
 void lbs_stop_card(struct lbs_private *priv)
 {
        struct net_device *dev;
-       struct cmd_ctrl_node *cmdnode;
-       unsigned long flags;
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
@@ -992,30 +1068,6 @@ void lbs_stop_card(struct lbs_private *priv)
 
        lbs_debugfs_remove_one(priv);
        lbs_deinit_mesh(priv);
-
-       /* Delete the timeout of the currently processing command */
-       del_timer_sync(&priv->command_timer);
-       del_timer_sync(&priv->auto_deepsleep_timer);
-
-       /* Flush pending command nodes */
-       spin_lock_irqsave(&priv->driver_lock, flags);
-       lbs_deb_main("clearing pending commands\n");
-       list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
-               cmdnode->result = -ENOENT;
-               cmdnode->cmdwaitqwoken = 1;
-               wake_up(&cmdnode->cmdwait_q);
-       }
-
-       /* Flush the command the card is currently processing */
-       if (priv->cur_cmd) {
-               lbs_deb_main("clearing current command\n");
-               priv->cur_cmd->result = -ENOENT;
-               priv->cur_cmd->cmdwaitqwoken = 1;
-               wake_up(&priv->cur_cmd->cmdwait_q);
-       }
-       lbs_deb_main("done clearing commands\n");
-       spin_unlock_irqrestore(&priv->driver_lock, flags);
-
        unregister_netdev(dev);
 
 out:
@@ -1036,7 +1088,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event)
 
        kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
 
-       wake_up_interruptible(&priv->waitq);
+       wake_up(&priv->waitq);
 
        spin_unlock_irqrestore(&priv->driver_lock, flags);
        lbs_deb_leave(LBS_DEB_THREAD);
@@ -1054,7 +1106,7 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
        BUG_ON(resp_idx > 1);
        priv->resp_idx = resp_idx;
 
-       wake_up_interruptible(&priv->waitq);
+       wake_up(&priv->waitq);
 
        lbs_deb_leave(LBS_DEB_THREAD);
 }
index be72c08ea2a79acf457c4ef3e5e7b82ae927cbfc..e87c031b298fcd2c2a75f72a245944e752648763 100644 (file)
@@ -129,6 +129,19 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
        return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
 }
 
+int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel)
+{
+       return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel);
+}
+
+static uint16_t lbs_mesh_get_channel(struct lbs_private *priv)
+{
+       struct wireless_dev *mesh_wdev = priv->mesh_dev->ieee80211_ptr;
+       if (mesh_wdev->channel)
+               return mesh_wdev->channel->hw_value;
+       else
+               return 1;
+}
 
 /***************************************************************************
  * Mesh sysfs support
@@ -812,7 +825,6 @@ static void lbs_persist_config_remove(struct net_device *dev)
  */
 int lbs_init_mesh(struct lbs_private *priv)
 {
-       struct net_device *dev = priv->dev;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_MESH);
@@ -837,11 +849,9 @@ int lbs_init_mesh(struct lbs_private *priv)
                   useful */
 
                priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
-               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-                                   priv->channel)) {
+               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) {
                        priv->mesh_tlv = TLV_TYPE_MESH_ID;
-                       if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-                                           priv->channel))
+                       if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
                                priv->mesh_tlv = 0;
                }
        } else
@@ -851,23 +861,16 @@ int lbs_init_mesh(struct lbs_private *priv)
                 * 0x100+37; Do not invoke command with old TLV.
                 */
                priv->mesh_tlv = TLV_TYPE_MESH_ID;
-               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-                                   priv->channel))
+               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
                        priv->mesh_tlv = 0;
        }
 
        /* Stop meshing until interface is brought up */
-       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel);
+       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
 
        if (priv->mesh_tlv) {
                sprintf(priv->mesh_ssid, "mesh");
                priv->mesh_ssid_len = 4;
-
-               lbs_add_mesh(priv);
-
-               if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-                       netdev_err(dev, "cannot register lbs_mesh attribute\n");
-
                ret = 1;
        }
 
@@ -875,6 +878,13 @@ int lbs_init_mesh(struct lbs_private *priv)
        return ret;
 }
 
+void lbs_start_mesh(struct lbs_private *priv)
+{
+       lbs_add_mesh(priv);
+
+       if (device_create_file(&priv->dev->dev, &dev_attr_lbs_mesh))
+               netdev_err(priv->dev, "cannot register lbs_mesh attribute\n");
+}
 
 int lbs_deinit_mesh(struct lbs_private *priv)
 {
@@ -904,7 +914,8 @@ static int lbs_mesh_stop(struct net_device *dev)
        struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_MESH);
-       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel);
+       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
+               lbs_mesh_get_channel(priv));
 
        spin_lock_irq(&priv->driver_lock);
 
@@ -913,7 +924,9 @@ static int lbs_mesh_stop(struct net_device *dev)
 
        spin_unlock_irq(&priv->driver_lock);
 
-       schedule_work(&priv->mcast_work);
+       lbs_update_mcast(priv);
+       if (!lbs_iface_active(priv))
+               lbs_stop_iface(priv);
 
        lbs_deb_leave(LBS_DEB_MESH);
        return 0;
@@ -931,6 +944,11 @@ static int lbs_mesh_dev_open(struct net_device *dev)
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_NET);
+       if (!priv->iface_running) {
+               ret = lbs_start_iface(priv);
+               if (ret)
+                       goto out;
+       }
 
        spin_lock_irq(&priv->driver_lock);
 
@@ -947,7 +965,8 @@ static int lbs_mesh_dev_open(struct net_device *dev)
 
        spin_unlock_irq(&priv->driver_lock);
 
-       ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, priv->channel);
+       ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+               lbs_mesh_get_channel(priv));
 
 out:
        lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
@@ -959,7 +978,7 @@ static const struct net_device_ops mesh_netdev_ops = {
        .ndo_stop               = lbs_mesh_stop,
        .ndo_start_xmit         = lbs_hard_start_xmit,
        .ndo_set_mac_address    = lbs_set_mac_address,
-       .ndo_set_multicast_list = lbs_set_multicast_list,
+       .ndo_set_rx_mode        = lbs_set_multicast_list,
 };
 
 /**
@@ -971,18 +990,32 @@ static const struct net_device_ops mesh_netdev_ops = {
 static int lbs_add_mesh(struct lbs_private *priv)
 {
        struct net_device *mesh_dev = NULL;
+       struct wireless_dev *mesh_wdev;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_MESH);
 
        /* Allocate a virtual mesh device */
+       mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+       if (!mesh_wdev) {
+               lbs_deb_mesh("init mshX wireless device failed\n");
+               ret = -ENOMEM;
+               goto done;
+       }
+
        mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
        if (!mesh_dev) {
                lbs_deb_mesh("init mshX device failed\n");
                ret = -ENOMEM;
-               goto done;
+               goto err_free_wdev;
        }
+
+       mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT;
+       mesh_wdev->wiphy = priv->wdev->wiphy;
+       mesh_wdev->netdev = mesh_dev;
+
        mesh_dev->ml_priv = priv;
+       mesh_dev->ieee80211_ptr = mesh_wdev;
        priv->mesh_dev = mesh_dev;
 
        mesh_dev->netdev_ops = &mesh_netdev_ops;
@@ -996,7 +1029,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
        ret = register_netdev(mesh_dev);
        if (ret) {
                pr_err("cannot register mshX virtual interface\n");
-               goto err_free;
+               goto err_free_netdev;
        }
 
        ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
@@ -1012,9 +1045,12 @@ static int lbs_add_mesh(struct lbs_private *priv)
 err_unregister:
        unregister_netdev(mesh_dev);
 
-err_free:
+err_free_netdev:
        free_netdev(mesh_dev);
 
+err_free_wdev:
+       kfree(mesh_wdev);
+
 done:
        lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
        return ret;
@@ -1035,6 +1071,7 @@ void lbs_remove_mesh(struct lbs_private *priv)
        lbs_persist_config_remove(mesh_dev);
        unregister_netdev(mesh_dev);
        priv->mesh_dev = NULL;
+       kfree(mesh_dev->ieee80211_ptr);
        free_netdev(mesh_dev);
        lbs_deb_leave(LBS_DEB_MESH);
 }
index 50144913f2abefd8a86fe93f81e42ed7eeaedcde..6603f341c8746f0b6ed66078ac4d8d02b2ce4f53 100644 (file)
@@ -9,30 +9,25 @@
 #include <net/lib80211.h>
 
 #include "host.h"
+#include "dev.h"
 
 #ifdef CONFIG_LIBERTAS_MESH
 
-/* Mesh statistics */
-struct lbs_mesh_stats {
-       u32     fwd_bcast_cnt;          /* Fwd: Broadcast counter */
-       u32     fwd_unicast_cnt;        /* Fwd: Unicast counter */
-       u32     fwd_drop_ttl;           /* Fwd: TTL zero */
-       u32     fwd_drop_rbt;           /* Fwd: Recently Broadcasted */
-       u32     fwd_drop_noroute;       /* Fwd: No route to Destination */
-       u32     fwd_drop_nobuf;         /* Fwd: Run out of internal buffers */
-       u32     drop_blind;             /* Rx:  Dropped by blinding table */
-       u32     tx_failed_cnt;          /* Tx:  Failed transmissions */
-};
-
-
 struct net_device;
-struct lbs_private;
 
 int lbs_init_mesh(struct lbs_private *priv);
+void lbs_start_mesh(struct lbs_private *priv);
 int lbs_deinit_mesh(struct lbs_private *priv);
 
 void lbs_remove_mesh(struct lbs_private *priv);
 
+static inline bool lbs_mesh_activated(struct lbs_private *priv)
+{
+       /* Mesh SSID is only programmed after successful init */
+       return priv->mesh_ssid_len != 0;
+}
+
+int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel);
 
 /* Sending / Receiving */
 
@@ -67,11 +62,13 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
 
 #define lbs_init_mesh(priv)
 #define lbs_deinit_mesh(priv)
+#define lbs_start_mesh(priv)
 #define lbs_add_mesh(priv)
 #define lbs_remove_mesh(priv)
 #define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
 #define lbs_mesh_set_txpd(priv, dev, txpd)
-#define lbs_mesh_config(priv, enable, chan)
+#define lbs_mesh_set_channel(priv, channel) (0)
+#define lbs_mesh_activated(priv) (false)
 
 #endif
 
index bfb8898ae518908f8394ef94a6f158b74f1bb232..62e10eeadd7e11339ff4ee2b67cdf04d097a6bbf 100644 (file)
@@ -15,6 +15,7 @@
 #include "radiotap.h"
 #include "decl.h"
 #include "dev.h"
+#include "mesh.h"
 
 struct eth803hdr {
        u8 dest_addr[6];
index a6e85134cfe1c24e8bd0e3aa4f95e8178b2078ec..8f127520d7863f6ff5eb09b49272d7227b75c5ab 100644 (file)
@@ -12,6 +12,7 @@
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
+#include "mesh.h"
 
 /**
  * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
index 031cd89b17682825177499303b94a80f3a84e97a..34b79fc91e39995398f9074fdfcdf4950978a8d4 100644 (file)
@@ -612,6 +612,12 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
        rx_status.freq = data->channel->center_freq;
        rx_status.band = data->channel->band;
        rx_status.rate_idx = info->control.rates[0].idx;
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
+               rx_status.flag |= RX_FLAG_HT;
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               rx_status.flag |= RX_FLAG_40MHZ;
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
+               rx_status.flag |= RX_FLAG_SHORT_GI;
        /* TODO: simulate real signal strength (and optional packet loss) */
        rx_status.signal = data->power_level - 50;
 
index 352d2c5da1fcdacde3d08283305fd82e73c22600..6fd53e4e3fe646248036a082893cd6a8991ac51b 100644 (file)
@@ -547,7 +547,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
        sinfo->tx_bytes = priv->stats.tx_bytes;
        sinfo->rx_packets = priv->stats.rx_packets;
        sinfo->tx_packets = priv->stats.tx_packets;
-       sinfo->signal = priv->w_stats.qual.level;
+       sinfo->signal = priv->qual_level;
        sinfo->txrate.legacy = rate.rate;
 
        return ret;
@@ -792,139 +792,6 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
        return 0;
 }
 
-/*
- * This function informs the CFG802.11 subsystem of a new BSS connection.
- *
- * The following information are sent to the CFG802.11 subsystem
- * to register the new BSS connection. If we do not register the new BSS,
- * a kernel panic will result.
- *      - MAC address
- *      - Capabilities
- *      - Beacon period
- *      - RSSI value
- *      - Channel
- *      - Supported rates IE
- *      - Extended capabilities IE
- *      - DS parameter set IE
- *      - HT Capability IE
- *      - Vendor Specific IE (221)
- *      - WPA IE
- *      - RSN IE
- */
-static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
-                                              struct mwifiex_802_11_ssid *ssid)
-{
-       struct mwifiex_bssdescriptor *scan_table;
-       int i, j;
-       struct ieee80211_channel *chan;
-       u8 *ie, *ie_buf;
-       u32 ie_len;
-       u8 *beacon;
-       int beacon_size;
-       u8 element_id, element_len;
-
-#define MAX_IE_BUF     2048
-       ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
-       if (!ie_buf) {
-               dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n",
-                                               __func__);
-               return -ENOMEM;
-       }
-
-       scan_table = priv->adapter->scan_table;
-       for (i = 0; i < priv->adapter->num_in_scan_table; i++) {
-               if (ssid) {
-                       /* Inform specific BSS only */
-                       if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
-                                          ssid->ssid_len))
-                               continue;
-               }
-               memset(ie_buf, 0, MAX_IE_BUF);
-               ie_buf[0] = WLAN_EID_SSID;
-               ie_buf[1] = scan_table[i].ssid.ssid_len;
-               memcpy(&ie_buf[sizeof(struct ieee_types_header)],
-                      scan_table[i].ssid.ssid, ie_buf[1]);
-
-               ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header);
-               ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
-
-               ie[0] = WLAN_EID_SUPP_RATES;
-
-               for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
-                       if (!scan_table[i].supported_rates[j])
-                               break;
-                       else
-                               ie[j + sizeof(struct ieee_types_header)] =
-                                       scan_table[i].supported_rates[j];
-               }
-
-               ie[1] = j;
-               ie_len += ie[1] + sizeof(struct ieee_types_header);
-
-               beacon = scan_table[i].beacon_buf;
-               beacon_size = scan_table[i].beacon_buf_size;
-
-               /* Skip time stamp, beacon interval and capability */
-
-               if (beacon) {
-                       beacon += sizeof(scan_table[i].beacon_period)
-                               + sizeof(scan_table[i].time_stamp) +
-                               +sizeof(scan_table[i].cap_info_bitmap);
-
-                       beacon_size -= sizeof(scan_table[i].beacon_period)
-                               + sizeof(scan_table[i].time_stamp)
-                               + sizeof(scan_table[i].cap_info_bitmap);
-               }
-
-               while (beacon_size >= sizeof(struct ieee_types_header)) {
-                       ie = ie_buf + ie_len;
-                       element_id = *beacon;
-                       element_len = *(beacon + 1);
-                       if (beacon_size < (int) element_len +
-                           sizeof(struct ieee_types_header)) {
-                               dev_err(priv->adapter->dev, "%s: in processing"
-                                       " IE, bytes left < IE length\n",
-                                       __func__);
-                               break;
-                       }
-                       switch (element_id) {
-                       case WLAN_EID_EXT_CAPABILITY:
-                       case WLAN_EID_DS_PARAMS:
-                       case WLAN_EID_HT_CAPABILITY:
-                       case WLAN_EID_VENDOR_SPECIFIC:
-                       case WLAN_EID_RSN:
-                       case WLAN_EID_BSS_AC_ACCESS_DELAY:
-                               ie[0] = element_id;
-                               ie[1] = element_len;
-                               memcpy(&ie[sizeof(struct ieee_types_header)],
-                                      (u8 *) beacon
-                                      + sizeof(struct ieee_types_header),
-                                      element_len);
-                               ie_len += ie[1] +
-                                       sizeof(struct ieee_types_header);
-                               break;
-                       default:
-                               break;
-                       }
-                       beacon += element_len +
-                                       sizeof(struct ieee_types_header);
-                       beacon_size -= element_len +
-                                       sizeof(struct ieee_types_header);
-               }
-               chan = ieee80211_get_channel(priv->wdev->wiphy,
-                                               scan_table[i].freq);
-               cfg80211_inform_bss(priv->wdev->wiphy, chan,
-                                       scan_table[i].mac_address,
-                                       0, scan_table[i].cap_info_bitmap,
-                                       scan_table[i].beacon_period,
-                                       ie_buf, ie_len,
-                                       scan_table[i].rssi, GFP_KERNEL);
-       }
-
-       kfree(ie_buf);
-       return 0;
-}
-
 /*
  * This function connects with a BSS.
  *
@@ -937,8 +804,7 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
  * For Infra mode, the function returns failure if the specified SSID
  * is not found in scan table. However, for Ad-Hoc mode, it can create
  * the IBSS if it does not exist. On successful completion in either case,
- * the function notifies the CFG802.11 subsystem of the new BSS connection,
- * otherwise the kernel will panic.
+ * the function notifies the CFG802.11 subsystem of the new BSS connection.
  */
 static int
 mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
@@ -946,11 +812,11 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
                       struct cfg80211_connect_params *sme, bool privacy)
 {
        struct mwifiex_802_11_ssid req_ssid;
-       struct mwifiex_ssid_bssid ssid_bssid;
        int ret, auth_type = 0;
+       struct cfg80211_bss *bss = NULL;
+       u8 is_scanning_required = 0;
 
        memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
-       memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
 
        req_ssid.ssid_len = ssid_len;
        if (ssid_len > IEEE80211_MAX_SSID_LEN) {
@@ -1028,30 +894,48 @@ done:
                return -EFAULT;
        }
 
+       /*
+        * Scan entries are valid for some time (15 sec). So we can save one
+        * active scan time if we just try cfg80211_get_bss first. If it fails
+        * then request scan and cfg80211_get_bss() again for final output.
+        */
+       while (1) {
+               if (is_scanning_required) {
+                       /* Do specific SSID scanning */
+                       if (mwifiex_request_scan(priv, &req_ssid)) {
+                               dev_err(priv->adapter->dev, "scan error\n");
+                               return -EFAULT;
+                       }
+               }
 
-       memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
-
-       if (mode != NL80211_IFTYPE_ADHOC) {
-               if (mwifiex_find_best_bss(priv, &ssid_bssid))
-                       return -EFAULT;
-               /* Inform the BSS information to kernel, otherwise
-                * kernel will give a panic after successful assoc */
-               if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid))
-                       return -EFAULT;
+               /* Find the BSS we want using available scan results */
+               if (mode == NL80211_IFTYPE_ADHOC)
+                       bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
+                                              bssid, ssid, ssid_len,
+                                              WLAN_CAPABILITY_IBSS,
+                                              WLAN_CAPABILITY_IBSS);
+               else
+                       bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
+                                              bssid, ssid, ssid_len,
+                                              WLAN_CAPABILITY_ESS,
+                                              WLAN_CAPABILITY_ESS);
+
+               if (!bss) {
+                       if (is_scanning_required) {
+                               dev_warn(priv->adapter->dev, "assoc: requested "
+                                        "bss not found in scan results\n");
+                               break;
+                       }
+                       is_scanning_required = 1;
+               } else {
+                       dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
+                                       (char *) req_ssid.ssid, bss->bssid);
+                       memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
+                       break;
+               }
        }
 
-       dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
-              (char *) req_ssid.ssid, ssid_bssid.bssid);
-
-       memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6);
-
-       /* Connect to BSS by ESSID */
-       memset(&ssid_bssid.bssid, 0, ETH_ALEN);
-
-       if (!netif_queue_stopped(priv->netdev))
-               netif_stop_queue(priv->netdev);
-
-       if (mwifiex_bss_start(priv, &ssid_bssid))
+       if (mwifiex_bss_start(priv, bss, &req_ssid))
                return -EFAULT;
 
        if (mode == NL80211_IFTYPE_ADHOC) {
@@ -1416,13 +1300,8 @@ mwifiex_cfg80211_results(struct work_struct *work)
                                        MWIFIEX_SCAN_TYPE_ACTIVE;
                        scan_req->chan_list[i].scan_time = 0;
                }
-               if (mwifiex_set_user_scan_ioctl(priv, scan_req)) {
+               if (mwifiex_set_user_scan_ioctl(priv, scan_req))
                        ret = -EFAULT;
-                       goto done;
-               }
-               if (mwifiex_inform_bss_from_scan_result(priv, NULL))
-                       ret = -EFAULT;
-done:
                priv->scan_result_status = ret;
                dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
                                                        __func__);
index 4fee0993b186a9c44696617e16b7fcb50d0714d5..f23ec72ed4fe83b505d086248e0e602b9ec48d11 100644 (file)
@@ -821,6 +821,14 @@ struct host_cmd_ds_txpwr_cfg {
        __le32 mode;
 } __packed;
 
+struct mwifiex_bcn_param {
+       u8 bssid[ETH_ALEN];
+       u8 rssi;
+       __le32 timestamp[2];
+       __le16 beacon_period;
+       __le16 cap_info_bitmap;
+} __packed;
+
 #define MWIFIEX_USER_SCAN_CHAN_MAX             50
 
 #define MWIFIEX_MAX_SSID_LIST_LENGTH         10
@@ -861,13 +869,6 @@ struct mwifiex_user_scan_ssid {
 } __packed;
 
 struct mwifiex_user_scan_cfg {
-       /*
-        *  Flag set to keep the previous scan table intact
-        *
-        *  If set, the scan results will accumulate, replacing any previous
-        *   matched entries for a BSS with the new scan data
-        */
-       u8 keep_previous_scan;
        /*
         *  BSS mode to be sent in the firmware command
         */
index 3f1559e613201f615c28b06303d5deba0d33a092..26e685a31bc09a378524f3ca311dc5277423bb9b 100644 (file)
@@ -152,19 +152,6 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
 static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
 {
        int ret;
-       u32 buf_size;
-       struct mwifiex_bssdescriptor *temp_scan_table;
-
-       /* Allocate buffer to store the BSSID list */
-       buf_size = sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP;
-       temp_scan_table = kzalloc(buf_size, GFP_KERNEL);
-       if (!temp_scan_table) {
-               dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n",
-                      __func__);
-               return -ENOMEM;
-       }
-
-       adapter->scan_table = temp_scan_table;
 
        /* Allocate command buffer */
        ret = mwifiex_alloc_cmd_buffer(adapter);
@@ -222,14 +209,8 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
        adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
        adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
 
-       adapter->num_in_scan_table = 0;
-       memset(adapter->scan_table, 0,
-              (sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP));
        adapter->scan_probes = 1;
 
-       memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf));
-       adapter->bcn_buf_end = adapter->bcn_buf;
-
        adapter->multiple_dtim = 1;
 
        adapter->local_listen_interval = 0;     /* default value in firmware
@@ -326,8 +307,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
        del_timer(&adapter->cmd_timer);
 
        dev_dbg(adapter->dev, "info: free scan table\n");
-       kfree(adapter->scan_table);
-       adapter->scan_table = NULL;
 
        adapter->if_ops.cleanup_if(adapter);
 
index f6bcc868562f2bc1dbdfb99463104710bd2adeae..e0b68e7c8ca2344c18c7db200223636bc543b7df 100644 (file)
@@ -134,7 +134,6 @@ struct mwifiex_ver_ext {
 struct mwifiex_bss_info {
        u32 bss_mode;
        struct mwifiex_802_11_ssid ssid;
-       u32 scan_table_idx;
        u32 bss_chan;
        u32 region_code;
        u32 media_connected;
@@ -307,10 +306,12 @@ struct mwifiex_ds_read_eeprom {
        u8 value[MAX_EEPROM_DATA];
 };
 
+#define IEEE_MAX_IE_SIZE               256
+
 struct mwifiex_ds_misc_gen_ie {
        u32 type;
        u32 len;
-       u8 ie_data[IW_CUSTOM_MAX];
+       u8 ie_data[IEEE_MAX_IE_SIZE];
 };
 
 struct mwifiex_ds_misc_cmd {
index 644e2e405cb555511e4a12b9bab5b8bfd8a76cb2..5cdad92277fab0252d55d1bf873d4e30d3b1e4b3 100644 (file)
@@ -223,32 +223,6 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
        return 0;
 }
 
-/*
- * This function updates the scan entry TSF timestamps to reflect
- * a new association.
- */
-static void
-mwifiex_update_tsf_timestamps(struct mwifiex_private *priv,
-                             struct mwifiex_bssdescriptor *new_bss_desc)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       u32 table_idx;
-       long long new_tsf_base;
-       signed long long tsf_delta;
-
-       memcpy(&new_tsf_base, new_bss_desc->time_stamp, sizeof(new_tsf_base));
-
-       tsf_delta = new_tsf_base - new_bss_desc->network_tsf;
-
-       dev_dbg(adapter->dev, "info: TSF: update TSF timestamps, "
-               "0x%016llx -> 0x%016llx\n",
-              new_bss_desc->network_tsf, new_tsf_base);
-
-       for (table_idx = 0; table_idx < adapter->num_in_scan_table;
-            table_idx++)
-               adapter->scan_table[table_idx].network_tsf += tsf_delta;
-}
-
 /*
  * This function appends a WAPI IE.
  *
@@ -639,12 +613,6 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 
        priv->curr_bss_params.band = (u8) bss_desc->bss_band;
 
-       /*
-        * Adjust the timestamps in the scan table to be relative to the newly
-        * associated AP's TSF
-        */
-       mwifiex_update_tsf_timestamps(priv, bss_desc);
-
        if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
                priv->curr_bss_params.wmm_enabled = true;
        else
index e5fc53dc6887411152063c4692517aef2fe7e1e1..48b4d95219fb2e7ecc87183771c6f573140c5b70 100644 (file)
@@ -627,7 +627,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
        .ndo_set_mac_address = mwifiex_set_mac_address,
        .ndo_tx_timeout = mwifiex_tx_timeout,
        .ndo_get_stats = mwifiex_get_stats,
-       .ndo_set_multicast_list = mwifiex_set_multicast_list,
+       .ndo_set_rx_mode = mwifiex_set_multicast_list,
 };
 
 /*
@@ -849,6 +849,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
 {
        int i;
        struct mwifiex_adapter *adapter;
+       char fmt[64];
 
        if (down_interruptible(sem))
                goto exit_sem_err;
@@ -897,6 +898,9 @@ mwifiex_add_card(void *card, struct semaphore *sem,
 
        up(sem);
 
+       mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
+       dev_notice(adapter->dev, "driver_version = %s\n", fmt);
+
        return 0;
 
 err_add_intf:
index 2215c3c973544c68426ef1e5b7fb49f599d5e417..e6b6c0cfb63e32df41aee6ad2655bdde8e47dc58 100644 (file)
@@ -54,6 +54,8 @@ struct mwifiex_drv_mode {
 };
 
 
+#define MWIFIEX_MAX_AP                         64
+
 #define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT       (5 * HZ)
 
 #define MWIFIEX_TIMER_10S                      10000
@@ -227,27 +229,10 @@ struct ieee_types_header {
        u8 len;
 } __packed;
 
-struct ieee_obss_scan_param {
-       u16 obss_scan_passive_dwell;
-       u16 obss_scan_active_dwell;
-       u16 bss_chan_width_trigger_scan_int;
-       u16 obss_scan_passive_total;
-       u16 obss_scan_active_total;
-       u16 bss_width_chan_trans_delay;
-       u16 obss_scan_active_threshold;
-} __packed;
-
-struct ieee_types_obss_scan_param {
-       struct ieee_types_header ieee_hdr;
-       struct ieee_obss_scan_param obss_scan;
-} __packed;
-
 #define MWIFIEX_SUPPORTED_RATES                 14
 
 #define MWIFIEX_SUPPORTED_RATES_EXT             32
 
-#define IEEE_MAX_IE_SIZE                       256
-
 struct ieee_types_vendor_specific {
        struct ieee_types_vendor_header vend_hdr;
        u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
@@ -291,8 +276,6 @@ struct mwifiex_bssdescriptor {
        u16 bss_co_2040_offset;
        u8 *bcn_ext_cap;
        u16 ext_cap_offset;
-       struct ieee_types_obss_scan_param *bcn_obss_scan;
-       u16 overlap_bss_offset;
        struct ieee_types_vendor_specific *bcn_wpa_ie;
        u16 wpa_offset;
        struct ieee_types_generic *bcn_rsn_ie;
@@ -301,8 +284,6 @@ struct mwifiex_bssdescriptor {
        u16 wapi_offset;
        u8 *beacon_buf;
        u32 beacon_buf_size;
-       u32 beacon_buf_size_max;
-
 };
 
 struct mwifiex_current_bss_params {
@@ -468,7 +449,7 @@ struct mwifiex_private {
        struct dentry *dfs_dev_dir;
 #endif
        u8 nick_name[16];
-       struct iw_statistics w_stats;
+       u8 qual_level, qual_noise;
        u16 current_key_index;
        struct semaphore async_sem;
        u8 scan_pending_on_block;
@@ -624,15 +605,11 @@ struct mwifiex_adapter {
        u32 scan_processing;
        u16 region_code;
        struct mwifiex_802_11d_domain_reg domain_reg;
-       struct mwifiex_bssdescriptor *scan_table;
-       u32 num_in_scan_table;
        u16 scan_probes;
        u32 scan_mode;
        u16 specific_scan_time;
        u16 active_scan_time;
        u16 passive_scan_time;
-       u8 bcn_buf[MAX_SCAN_BEACON_BUFFER];
-       u8 *bcn_buf_end;
        u8 fw_bands;
        u8 adhoc_start_band;
        u8 config_bands;
@@ -765,13 +742,6 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
                            struct cmd_ctrl_node *cmd_node);
 int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                            struct host_cmd_ds_command *resp);
-s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
-                               struct mwifiex_802_11_ssid *ssid, u8 *bssid,
-                               u32 mode);
-s32 mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
-                                u32 mode);
-int mwifiex_find_best_network(struct mwifiex_private *priv,
-                             struct mwifiex_ssid_bssid *req_ssid_bssid);
 s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
                       struct mwifiex_802_11_ssid *ssid2);
 int mwifiex_associate(struct mwifiex_private *priv,
@@ -782,7 +752,6 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
                                 struct host_cmd_ds_command *resp);
 void mwifiex_reset_connect_state(struct mwifiex_private *priv);
-void mwifiex_2040_coex_event(struct mwifiex_private *priv);
 u8 mwifiex_band_to_radio_type(u8 band);
 int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
 int mwifiex_adhoc_start(struct mwifiex_private *priv,
@@ -922,8 +891,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
 int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
                            struct net_device *dev);
 int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
-int mwifiex_bss_start(struct mwifiex_private *priv,
-                     struct mwifiex_ssid_bssid *ssid_bssid);
+int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
+                     struct mwifiex_802_11_ssid *req_ssid);
 int mwifiex_set_hs_params(struct mwifiex_private *priv,
                              u16 action, int cmd_type,
                              struct mwifiex_ds_hs_cfg *hscfg);
@@ -934,8 +903,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
                            struct mwifiex_ds_get_signal *signal);
 int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
                              struct mwifiex_rate_cfg *rate);
-int mwifiex_find_best_bss(struct mwifiex_private *priv,
-                         struct mwifiex_ssid_bssid *ssid_bssid);
 int mwifiex_request_scan(struct mwifiex_private *priv,
                         struct mwifiex_802_11_ssid *req_ssid);
 int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
@@ -984,12 +951,20 @@ int mwifiex_main_process(struct mwifiex_adapter *);
 
 int mwifiex_bss_set_channel(struct mwifiex_private *,
                            struct mwifiex_chan_freq_power *cfp);
-int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *,
-                              struct mwifiex_ssid_bssid *);
 int mwifiex_set_radio_band_cfg(struct mwifiex_private *,
                         struct mwifiex_ds_band_cfg *);
 int mwifiex_get_bss_info(struct mwifiex_private *,
                         struct mwifiex_bss_info *);
+int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
+                             u8 *bssid, s32 rssi, u8 *ie_buf,
+                             size_t ie_len, u16 beacon_period,
+                             u16 cap_info_bitmap,
+                             struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
+                               struct mwifiex_bssdescriptor *bss_entry,
+                               u8 *ie_buf, u32 ie_len);
+int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
+                                       struct mwifiex_bssdescriptor *bss_desc);
 
 #ifdef CONFIG_DEBUG_FS
 void mwifiex_debugfs_init(void);
index 6f88c8ab5de5d6e07489f5ebd7cf1266c13d629d..b28241c6e737bbe824dc8b0ed558b8db23063269 100644 (file)
@@ -171,36 +171,6 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
        return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
 }
 
-/*
- * Sends IOCTL request to get the best BSS.
- *
- * This function allocates the IOCTL request buffer, fills it
- * with requisite parameters and calls the IOCTL handler.
- */
-int mwifiex_find_best_bss(struct mwifiex_private *priv,
-                         struct mwifiex_ssid_bssid *ssid_bssid)
-{
-       struct mwifiex_ssid_bssid tmp_ssid_bssid;
-       u8 *mac;
-
-       if (!ssid_bssid)
-               return -1;
-
-       memcpy(&tmp_ssid_bssid, ssid_bssid,
-              sizeof(struct mwifiex_ssid_bssid));
-
-       if (!mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid)) {
-               memcpy(ssid_bssid, &tmp_ssid_bssid,
-                      sizeof(struct mwifiex_ssid_bssid));
-               mac = (u8 *) &ssid_bssid->bssid;
-               dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s,"
-                               " %pM\n", ssid_bssid->ssid.ssid, mac);
-               return 0;
-       }
-
-       return -1;
-}
-
 /*
  * Sends IOCTL request to start a scan with user configurations.
  *
@@ -286,8 +256,7 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
  */
 static bool
 mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
-                                     struct mwifiex_bssdescriptor *bss_desc,
-                                     int index)
+                                     struct mwifiex_bssdescriptor *bss_desc)
 {
        if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
            && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
@@ -298,9 +267,9 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
            * LinkSys WRT54G && bss_desc->privacy
            */
         ) {
-               dev_dbg(priv->adapter->dev, "info: %s: WPA: index=%d"
+               dev_dbg(priv->adapter->dev, "info: %s: WPA:"
                        " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
-                       "EncMode=%#x privacy=%#x\n", __func__, index,
+                       "EncMode=%#x privacy=%#x\n", __func__,
                        (bss_desc->bcn_wpa_ie) ?
                        (*(bss_desc->bcn_wpa_ie)).
                        vend_hdr.element_id : 0,
@@ -324,8 +293,7 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
  */
 static bool
 mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc,
-                                      int index)
+                                      struct mwifiex_bssdescriptor *bss_desc)
 {
        if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
           && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled
@@ -336,9 +304,9 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
            * LinkSys WRT54G && bss_desc->privacy
            */
         ) {
-               dev_dbg(priv->adapter->dev, "info: %s: WPA2: index=%d"
+               dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
                        " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
-                       "EncMode=%#x privacy=%#x\n", __func__, index,
+                       "EncMode=%#x privacy=%#x\n", __func__,
                        (bss_desc->bcn_wpa_ie) ?
                        (*(bss_desc->bcn_wpa_ie)).
                        vend_hdr.element_id : 0,
@@ -383,8 +351,7 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
  */
 static bool
 mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc,
-                                      int index)
+                                      struct mwifiex_bssdescriptor *bss_desc)
 {
        if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
            && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
@@ -395,9 +362,9 @@ mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
            && priv->sec_info.encryption_mode
            && bss_desc->privacy) {
                dev_dbg(priv->adapter->dev, "info: %s: dynamic "
-                       "WEP: index=%d wpa_ie=%#x wpa2_ie=%#x "
+                       "WEP: wpa_ie=%#x wpa2_ie=%#x "
                        "EncMode=%#x privacy=%#x\n",
-                       __func__, index,
+                       __func__,
                        (bss_desc->bcn_wpa_ie) ?
                        (*(bss_desc->bcn_wpa_ie)).
                        vend_hdr.element_id : 0,
@@ -430,42 +397,41 @@ mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
  * Compatibility is not matched while roaming, except for mode.
  */
 static s32
-mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
+mwifiex_is_network_compatible(struct mwifiex_private *priv,
+                             struct mwifiex_bssdescriptor *bss_desc, u32 mode)
 {
        struct mwifiex_adapter *adapter = priv->adapter;
-       struct mwifiex_bssdescriptor *bss_desc;
 
-       bss_desc = &adapter->scan_table[index];
        bss_desc->disable_11n = false;
 
        /* Don't check for compatibility if roaming */
        if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
            && (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
-               return index;
+               return 0;
 
        if (priv->wps.session_enable) {
                dev_dbg(adapter->dev,
                        "info: return success directly in WPS period\n");
-               return index;
+               return 0;
        }
 
        if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
                dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
-               return index;
+               return 0;
        }
 
        if (bss_desc->bss_mode == mode) {
                if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
                        /* No security */
-                       return index;
+                       return 0;
                } else if (mwifiex_is_network_compatible_for_static_wep(priv,
                                                                bss_desc)) {
                        /* Static WEP enabled */
                        dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
                        bss_desc->disable_11n = true;
-                       return index;
-               } else if (mwifiex_is_network_compatible_for_wpa(priv, bss_desc,
-                                                                index)) {
+                       return 0;
+               } else if (mwifiex_is_network_compatible_for_wpa(priv,
+                                                                bss_desc)) {
                        /* WPA enabled */
                        if (((priv->adapter->config_bands & BAND_GN
                              || priv->adapter->config_bands & BAND_AN)
@@ -483,9 +449,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
                                        return -1;
                                }
                        }
-                       return index;
+                       return 0;
                } else if (mwifiex_is_network_compatible_for_wpa2(priv,
-                                                       bss_desc, index)) {
+                                                       bss_desc)) {
                        /* WPA2 enabled */
                        if (((priv->adapter->config_bands & BAND_GN
                              || priv->adapter->config_bands & BAND_AN)
@@ -503,22 +469,22 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
                                        return -1;
                                }
                        }
-                       return index;
+                       return 0;
                } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
                                                                bss_desc)) {
                        /* Ad-hoc AES enabled */
-                       return index;
+                       return 0;
                } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
-                                                       bss_desc, index)) {
+                                                       bss_desc)) {
                        /* Dynamic WEP enabled */
-                       return index;
+                       return 0;
                }
 
                /* Security doesn't match */
-               dev_dbg(adapter->dev, "info: %s: failed: index=%d "
+               dev_dbg(adapter->dev, "info: %s: failed: "
                       "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
                       "=%#x privacy=%#x\n",
-                      __func__, index,
+                      __func__,
                       (bss_desc->bcn_wpa_ie) ?
                       (*(bss_desc->bcn_wpa_ie)).vend_hdr.
                       element_id : 0,
@@ -537,52 +503,6 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
        return -1;
 }
 
-/*
- * This function finds the best SSID in the scan list.
- *
- * It searches the scan table for the best SSID that also matches the current
- * adapter network preference (mode, security etc.).
- */
-static s32
-mwifiex_find_best_network_in_list(struct mwifiex_private *priv)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       u32 mode = priv->bss_mode;
-       s32 best_net = -1;
-       s32 best_rssi = 0;
-       u32 i;
-
-       dev_dbg(adapter->dev, "info: num of BSSIDs = %d\n",
-                               adapter->num_in_scan_table);
-
-       for (i = 0; i < adapter->num_in_scan_table; i++) {
-               switch (mode) {
-               case NL80211_IFTYPE_STATION:
-               case NL80211_IFTYPE_ADHOC:
-                       if (mwifiex_is_network_compatible(priv, i, mode) >= 0) {
-                               if (SCAN_RSSI(adapter->scan_table[i].rssi) >
-                                   best_rssi) {
-                                       best_rssi = SCAN_RSSI(adapter->
-                                                         scan_table[i].rssi);
-                                       best_net = i;
-                               }
-                       }
-                       break;
-               case NL80211_IFTYPE_UNSPECIFIED:
-               default:
-                       if (SCAN_RSSI(adapter->scan_table[i].rssi) >
-                           best_rssi) {
-                               best_rssi = SCAN_RSSI(adapter->scan_table[i].
-                                                     rssi);
-                               best_net = i;
-                       }
-                       break;
-               }
-       }
-
-       return best_net;
-}
-
 /*
  * This function creates a channel list for the driver to scan, based
  * on region/band information.
@@ -1161,34 +1081,13 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
 }
 
 /*
- * This function interprets a BSS scan response returned from the firmware.
- *
- * The various fixed fields and IEs are parsed and passed back for a BSS
- * probe response or beacon from scan command. Information is recorded as
- * needed in the scan table for that entry.
- *
- * The following IE types are recognized and parsed -
- *      - SSID
- *      - Supported rates
- *      - FH parameters set
- *      - DS parameters set
- *      - CF parameters set
- *      - IBSS parameters set
- *      - ERP information
- *      - Extended supported rates
- *      - Vendor specific (221)
- *      - RSN IE
- *      - WAPI IE
- *      - HT capability
- *      - HT operation
- *      - BSS Coexistence 20/40
- *      - Extended capability
- *      - Overlapping BSS scan parameters
+ * This function parses provided beacon buffer and updates
+ * respective fields in bss descriptor structure.
  */
-static int
-mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
-                                  struct mwifiex_bssdescriptor *bss_entry,
-                                  u8 **beacon_info, u32 *bytes_left)
+int
+mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
+                               struct mwifiex_bssdescriptor *bss_entry,
+                               u8 *ie_buf, u32 ie_len)
 {
        int ret = 0;
        u8 element_id;
@@ -1196,135 +1095,43 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
        struct ieee_types_ds_param_set *ds_param_set;
        struct ieee_types_cf_param_set *cf_param_set;
        struct ieee_types_ibss_param_set *ibss_param_set;
-       __le16 beacon_interval;
-       __le16 capabilities;
        u8 *current_ptr;
        u8 *rate;
        u8 element_len;
        u16 total_ie_len;
        u8 bytes_to_copy;
        u8 rate_size;
-       u16 beacon_size;
        u8 found_data_rate_ie;
-       u32 bytes_left_for_current_beacon;
+       u32 bytes_left;
        struct ieee_types_vendor_specific *vendor_ie;
        const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
        const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
 
        found_data_rate_ie = false;
        rate_size = 0;
-       beacon_size = 0;
-
-       if (*bytes_left >= sizeof(beacon_size)) {
-               /* Extract & convert beacon size from the command buffer */
-               memcpy(&beacon_size, *beacon_info, sizeof(beacon_size));
-               *bytes_left -= sizeof(beacon_size);
-               *beacon_info += sizeof(beacon_size);
-       }
-
-       if (!beacon_size || beacon_size > *bytes_left) {
-               *beacon_info += *bytes_left;
-               *bytes_left = 0;
-               return -1;
-       }
-
-       /* Initialize the current working beacon pointer for this BSS
-          iteration */
-       current_ptr = *beacon_info;
-
-       /* Advance the return beacon pointer past the current beacon */
-       *beacon_info += beacon_size;
-       *bytes_left -= beacon_size;
-
-       bytes_left_for_current_beacon = beacon_size;
-
-       memcpy(bss_entry->mac_address, current_ptr, ETH_ALEN);
-       dev_dbg(adapter->dev, "info: InterpretIE: AP MAC Addr: %pM\n",
-                                               bss_entry->mac_address);
-
-       current_ptr += ETH_ALEN;
-       bytes_left_for_current_beacon -= ETH_ALEN;
-
-       if (bytes_left_for_current_beacon < 12) {
-               dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
-               return -1;
-       }
-
-       /*
-        * Next 4 fields are RSSI, time stamp, beacon interval,
-        *   and capability information
-        */
-
-       /* RSSI is 1 byte long */
-       bss_entry->rssi = (s32) (*current_ptr);
-       dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", *current_ptr);
-       current_ptr += 1;
-       bytes_left_for_current_beacon -= 1;
-
-       /*
-        *  The RSSI is not part of the beacon/probe response.  After we have
-        *    advanced current_ptr past the RSSI field, save the remaining
-        *    data for use at the application layer
-        */
-       bss_entry->beacon_buf = current_ptr;
-       bss_entry->beacon_buf_size = bytes_left_for_current_beacon;
-
-       /* Time stamp is 8 bytes long */
-       memcpy(bss_entry->time_stamp, current_ptr, 8);
-       current_ptr += 8;
-       bytes_left_for_current_beacon -= 8;
-
-       /* Beacon interval is 2 bytes long */
-       memcpy(&beacon_interval, current_ptr, 2);
-       bss_entry->beacon_period = le16_to_cpu(beacon_interval);
-       current_ptr += 2;
-       bytes_left_for_current_beacon -= 2;
-
-       /* Capability information is 2 bytes long */
-       memcpy(&capabilities, current_ptr, 2);
-       dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
-              capabilities);
-       bss_entry->cap_info_bitmap = le16_to_cpu(capabilities);
-       current_ptr += 2;
-       bytes_left_for_current_beacon -= 2;
-
-       /* Rest of the current buffer are IE's */
-       dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
-              bytes_left_for_current_beacon);
-
-       if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
-               dev_dbg(adapter->dev, "info: InterpretIE: AP WEP enabled\n");
-               bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
-       } else {
-               bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
-       }
-
-       if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
-               bss_entry->bss_mode = NL80211_IFTYPE_ADHOC;
-       else
-               bss_entry->bss_mode = NL80211_IFTYPE_STATION;
-
+       current_ptr = ie_buf;
+       bytes_left = ie_len;
+       bss_entry->beacon_buf = ie_buf;
+       bss_entry->beacon_buf_size = ie_len;
 
        /* Process variable IE */
-       while (bytes_left_for_current_beacon >= 2) {
+       while (bytes_left >= 2) {
                element_id = *current_ptr;
                element_len = *(current_ptr + 1);
                total_ie_len = element_len + sizeof(struct ieee_types_header);
 
-               if (bytes_left_for_current_beacon < total_ie_len) {
+               if (bytes_left < total_ie_len) {
                        dev_err(adapter->dev, "err: InterpretIE: in processing"
                                " IE, bytes left < IE length\n");
-                       bytes_left_for_current_beacon = 0;
-                       ret = -1;
-                       continue;
+                       return -1;
                }
                switch (element_id) {
                case WLAN_EID_SSID:
                        bss_entry->ssid.ssid_len = element_len;
                        memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
                               element_len);
-                       dev_dbg(adapter->dev, "info: InterpretIE: ssid: %-32s\n",
-                              bss_entry->ssid.ssid);
+                       dev_dbg(adapter->dev, "info: InterpretIE: ssid: "
+                                             "%-32s\n", bss_entry->ssid.ssid);
                        break;
 
                case WLAN_EID_SUPP_RATES:
@@ -1471,13 +1278,6 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
                                        sizeof(struct ieee_types_header) -
                                        bss_entry->beacon_buf);
                        break;
-               case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
-                       bss_entry->bcn_obss_scan =
-                               (struct ieee_types_obss_scan_param *)
-                               current_ptr;
-                       bss_entry->overlap_bss_offset = (u16) (current_ptr -
-                                                       bss_entry->beacon_buf);
-                       break;
                default:
                        break;
                }
@@ -1485,576 +1285,12 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
                current_ptr += element_len + 2;
 
                /* Need to account for IE ID and IE Len */
-               bytes_left_for_current_beacon -= (element_len + 2);
+               bytes_left -= (element_len + 2);
 
-       }       /* while (bytes_left_for_current_beacon > 2) */
+       }       /* while (bytes_left > 2) */
        return ret;
 }
 
-/*
- * This function adjusts the pointers used in beacon buffers to reflect
- * shifts.
- *
- * The memory allocated for beacon buffers is of fixed sizes where all the
- * saved beacons must be stored. New beacons are added in the free portion
- * of this memory, space permitting; while duplicate beacon buffers are
- * placed at the same start location. However, since duplicate beacon
- * buffers may not match the size of the old one, all the following buffers
- * in the memory must be shifted to either make space, or to fill up freed
- * up space.
- *
- * This function is used to update the beacon buffer pointers that are past
- * an existing beacon buffer that is updated with a new one of different
- * size. The pointers are shifted by a fixed amount, either forward or
- * backward.
- *
- * the following pointers in every affected beacon buffers are changed, if
- * present -
- *      - WPA IE pointer
- *      - RSN IE pointer
- *      - WAPI IE pointer
- *      - HT capability IE pointer
- *      - HT information IE pointer
- *      - BSS coexistence 20/40 IE pointer
- *      - Extended capability IE pointer
- *      - Overlapping BSS scan parameter IE pointer
- */
-static void
-mwifiex_adjust_beacon_buffer_ptrs(struct mwifiex_private *priv, u8 advance,
-                                 u8 *bcn_store, u32 rem_bcn_size,
-                                 u32 num_of_ent)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       u32 adj_idx;
-       for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
-               if (adapter->scan_table[adj_idx].beacon_buf > bcn_store) {
-
-                       if (advance)
-                               adapter->scan_table[adj_idx].beacon_buf +=
-                                       rem_bcn_size;
-                       else
-                               adapter->scan_table[adj_idx].beacon_buf -=
-                                       rem_bcn_size;
-
-                       if (adapter->scan_table[adj_idx].bcn_wpa_ie)
-                               adapter->scan_table[adj_idx].bcn_wpa_ie =
-                               (struct ieee_types_vendor_specific *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                                adapter->scan_table[adj_idx].wpa_offset);
-                       if (adapter->scan_table[adj_idx].bcn_rsn_ie)
-                               adapter->scan_table[adj_idx].bcn_rsn_ie =
-                               (struct ieee_types_generic *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                                adapter->scan_table[adj_idx].rsn_offset);
-                       if (adapter->scan_table[adj_idx].bcn_wapi_ie)
-                               adapter->scan_table[adj_idx].bcn_wapi_ie =
-                               (struct ieee_types_generic *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                                adapter->scan_table[adj_idx].wapi_offset);
-                       if (adapter->scan_table[adj_idx].bcn_ht_cap)
-                               adapter->scan_table[adj_idx].bcn_ht_cap =
-                               (struct ieee80211_ht_cap *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                                adapter->scan_table[adj_idx].ht_cap_offset);
-
-                       if (adapter->scan_table[adj_idx].bcn_ht_info)
-                               adapter->scan_table[adj_idx].bcn_ht_info =
-                               (struct ieee80211_ht_info *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                                adapter->scan_table[adj_idx].ht_info_offset);
-                       if (adapter->scan_table[adj_idx].bcn_bss_co_2040)
-                               adapter->scan_table[adj_idx].bcn_bss_co_2040 =
-                               (u8 *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                              adapter->scan_table[adj_idx].bss_co_2040_offset);
-                       if (adapter->scan_table[adj_idx].bcn_ext_cap)
-                               adapter->scan_table[adj_idx].bcn_ext_cap =
-                               (u8 *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                                adapter->scan_table[adj_idx].ext_cap_offset);
-                       if (adapter->scan_table[adj_idx].bcn_obss_scan)
-                               adapter->scan_table[adj_idx].bcn_obss_scan =
-                               (struct ieee_types_obss_scan_param *)
-                               (adapter->scan_table[adj_idx].beacon_buf +
-                              adapter->scan_table[adj_idx].overlap_bss_offset);
-               }
-       }
-}
-
-/*
- * This function updates the pointers used in beacon buffer for given bss
- * descriptor to reflect shifts
- *
- * Following pointers are updated
- *      - WPA IE pointer
- *      - RSN IE pointer
- *      - WAPI IE pointer
- *      - HT capability IE pointer
- *      - HT information IE pointer
- *      - BSS coexistence 20/40 IE pointer
- *      - Extended capability IE pointer
- *      - Overlapping BSS scan parameter IE pointer
- */
-static void
-mwifiex_update_beacon_buffer_ptrs(struct mwifiex_bssdescriptor *beacon)
-{
-       if (beacon->bcn_wpa_ie)
-               beacon->bcn_wpa_ie = (struct ieee_types_vendor_specific *)
-                       (beacon->beacon_buf + beacon->wpa_offset);
-       if (beacon->bcn_rsn_ie)
-               beacon->bcn_rsn_ie = (struct ieee_types_generic *)
-                       (beacon->beacon_buf + beacon->rsn_offset);
-       if (beacon->bcn_wapi_ie)
-               beacon->bcn_wapi_ie = (struct ieee_types_generic *)
-                       (beacon->beacon_buf + beacon->wapi_offset);
-       if (beacon->bcn_ht_cap)
-               beacon->bcn_ht_cap = (struct ieee80211_ht_cap *)
-                       (beacon->beacon_buf + beacon->ht_cap_offset);
-       if (beacon->bcn_ht_info)
-               beacon->bcn_ht_info = (struct ieee80211_ht_info *)
-                       (beacon->beacon_buf + beacon->ht_info_offset);
-       if (beacon->bcn_bss_co_2040)
-               beacon->bcn_bss_co_2040 = (u8 *) (beacon->beacon_buf +
-                       beacon->bss_co_2040_offset);
-       if (beacon->bcn_ext_cap)
-               beacon->bcn_ext_cap = (u8 *) (beacon->beacon_buf +
-                       beacon->ext_cap_offset);
-       if (beacon->bcn_obss_scan)
-               beacon->bcn_obss_scan = (struct ieee_types_obss_scan_param *)
-                       (beacon->beacon_buf + beacon->overlap_bss_offset);
-}
-
-/*
- * This function stores a beacon or probe response for a BSS returned
- * in the scan.
- *
- * This stores a new scan response or an update for a previous scan response.
- * New entries need to verify that they do not exceed the total amount of
- * memory allocated for the table.
- *
- * Replacement entries need to take into consideration the amount of space
- * currently allocated for the beacon/probe response and adjust the entry
- * as needed.
- *
- * A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved
- * for an entry in case it is a beacon since a probe response for the
- * network will by larger per the standard.  This helps to reduce the
- * amount of memory copying to fit a new probe response into an entry
- * already occupied by a network's previously stored beacon.
- */
-static void
-mwifiex_ret_802_11_scan_store_beacon(struct mwifiex_private *priv,
-                                    u32 beacon_idx, u32 num_of_ent,
-                                    struct mwifiex_bssdescriptor *new_beacon)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       u8 *bcn_store;
-       u32 new_bcn_size;
-       u32 old_bcn_size;
-       u32 bcn_space;
-
-       if (adapter->scan_table[beacon_idx].beacon_buf) {
-
-               new_bcn_size = new_beacon->beacon_buf_size;
-               old_bcn_size = adapter->scan_table[beacon_idx].beacon_buf_size;
-               bcn_space = adapter->scan_table[beacon_idx].beacon_buf_size_max;
-               bcn_store = adapter->scan_table[beacon_idx].beacon_buf;
-
-               /* Set the max to be the same as current entry unless changed
-                  below */
-               new_beacon->beacon_buf_size_max = bcn_space;
-               if (new_bcn_size == old_bcn_size) {
-                       /*
-                        * Beacon is the same size as the previous entry.
-                        *   Replace the previous contents with the scan result
-                        */
-                       memcpy(bcn_store, new_beacon->beacon_buf,
-                              new_beacon->beacon_buf_size);
-
-               } else if (new_bcn_size <= bcn_space) {
-                       /*
-                        * New beacon size will fit in the amount of space
-                        *   we have previously allocated for it
-                        */
-
-                       /* Copy the new beacon buffer entry over the old one */
-                       memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
-
-                       /*
-                        *  If the old beacon size was less than the maximum
-                        *  we had alloted for the entry, and the new entry
-                        *  is even smaller, reset the max size to the old
-                        *  beacon entry and compress the storage space
-                        *  (leaving a new pad space of (old_bcn_size -
-                        *  new_bcn_size).
-                        */
-                       if (old_bcn_size < bcn_space
-                           && new_bcn_size <= old_bcn_size) {
-                               /*
-                                * Old Beacon size is smaller than the alloted
-                                * storage size. Shrink the alloted storage
-                                * space.
-                                */
-                               dev_dbg(adapter->dev, "info: AppControl:"
-                                       " smaller duplicate beacon "
-                                      "(%d), old = %d, new = %d, space = %d,"
-                                      "left = %d\n",
-                                      beacon_idx, old_bcn_size, new_bcn_size,
-                                      bcn_space,
-                                      (int)(sizeof(adapter->bcn_buf) -
-                                       (adapter->bcn_buf_end -
-                                        adapter->bcn_buf)));
-
-                               /*
-                                *  memmove (since the memory overlaps) the
-                                *  data after the beacon we just stored to the
-                                *  end of the current beacon.  This cleans up
-                                *  any unused space the old larger beacon was
-                                *  using in the buffer
-                                */
-                               memmove(bcn_store + old_bcn_size,
-                                       bcn_store + bcn_space,
-                                       adapter->bcn_buf_end - (bcn_store +
-                                                                  bcn_space));
-
-                               /*
-                                * Decrement the end pointer by the difference
-                                * between the old larger size and the new
-                                * smaller size since we are using less space
-                                * due to the new beacon being smaller
-                                */
-                               adapter->bcn_buf_end -=
-                                       (bcn_space - old_bcn_size);
-
-                               /* Set the maximum storage size to the old
-                                  beacon size */
-                               new_beacon->beacon_buf_size_max = old_bcn_size;
-
-                               /* Adjust beacon buffer pointers that are past
-                                  the current */
-                               mwifiex_adjust_beacon_buffer_ptrs(priv, 0,
-                                       bcn_store, (bcn_space - old_bcn_size),
-                                       num_of_ent);
-                       }
-               } else if (adapter->bcn_buf_end + (new_bcn_size - bcn_space)
-                          < (adapter->bcn_buf + sizeof(adapter->bcn_buf))) {
-                       /*
-                        * Beacon is larger than space previously allocated
-                        * (bcn_space) and there is enough space left in the
-                        * beaconBuffer to store the additional data
-                        */
-                       dev_dbg(adapter->dev, "info: AppControl:"
-                               " larger duplicate beacon (%d), "
-                              "old = %d, new = %d, space = %d, left = %d\n",
-                              beacon_idx, old_bcn_size, new_bcn_size,
-                              bcn_space,
-                              (int)(sizeof(adapter->bcn_buf) -
-                               (adapter->bcn_buf_end -
-                                adapter->bcn_buf)));
-
-                       /*
-                        * memmove (since the memory overlaps) the data
-                        *  after the beacon we just stored to the end of
-                        *  the current beacon.  This moves the data for
-                        *  the beacons after this further in memory to
-                        *  make space for the new larger beacon we are
-                        *  about to copy in.
-                        */
-                       memmove(bcn_store + new_bcn_size,
-                               bcn_store + bcn_space,
-                               adapter->bcn_buf_end - (bcn_store + bcn_space));
-
-                       /* Copy the new beacon buffer entry over the old one */
-                       memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
-
-                       /* Move the beacon end pointer by the amount of new
-                          beacon data we are adding */
-                       adapter->bcn_buf_end += (new_bcn_size - bcn_space);
-
-                       /*
-                        * This entry is bigger than the alloted max space
-                        *  previously reserved.  Increase the max space to
-                        *  be equal to the new beacon size
-                        */
-                       new_beacon->beacon_buf_size_max = new_bcn_size;
-
-                       /* Adjust beacon buffer pointers that are past the
-                          current */
-                       mwifiex_adjust_beacon_buffer_ptrs(priv, 1, bcn_store,
-                                               (new_bcn_size - bcn_space),
-                                               num_of_ent);
-               } else {
-                       /*
-                        * Beacon is larger than the previously allocated space,
-                        * but there is not enough free space to store the
-                        * additional data.
-                        */
-                       dev_err(adapter->dev, "AppControl: larger duplicate "
-                               " beacon (%d), old = %d new = %d, space = %d,"
-                               " left = %d\n", beacon_idx, old_bcn_size,
-                               new_bcn_size, bcn_space,
-                               (int)(sizeof(adapter->bcn_buf) -
-                               (adapter->bcn_buf_end - adapter->bcn_buf)));
-
-                       /* Storage failure, keep old beacon intact */
-                       new_beacon->beacon_buf_size = old_bcn_size;
-                       if (new_beacon->bcn_wpa_ie)
-                               new_beacon->wpa_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       wpa_offset;
-                       if (new_beacon->bcn_rsn_ie)
-                               new_beacon->rsn_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       rsn_offset;
-                       if (new_beacon->bcn_wapi_ie)
-                               new_beacon->wapi_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       wapi_offset;
-                       if (new_beacon->bcn_ht_cap)
-                               new_beacon->ht_cap_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       ht_cap_offset;
-                       if (new_beacon->bcn_ht_info)
-                               new_beacon->ht_info_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       ht_info_offset;
-                       if (new_beacon->bcn_bss_co_2040)
-                               new_beacon->bss_co_2040_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       bss_co_2040_offset;
-                       if (new_beacon->bcn_ext_cap)
-                               new_beacon->ext_cap_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       ext_cap_offset;
-                       if (new_beacon->bcn_obss_scan)
-                               new_beacon->overlap_bss_offset =
-                                       adapter->scan_table[beacon_idx].
-                                       overlap_bss_offset;
-               }
-               /* Point the new entry to its permanent storage space */
-               new_beacon->beacon_buf = bcn_store;
-               mwifiex_update_beacon_buffer_ptrs(new_beacon);
-       } else {
-               /*
-                * No existing beacon data exists for this entry, check to see
-                *   if we can fit it in the remaining space
-                */
-               if (adapter->bcn_buf_end + new_beacon->beacon_buf_size +
-                   SCAN_BEACON_ENTRY_PAD < (adapter->bcn_buf +
-                                            sizeof(adapter->bcn_buf))) {
-
-                       /*
-                        * Copy the beacon buffer data from the local entry to
-                        * the adapter dev struct buffer space used to store
-                        * the raw beacon data for each entry in the scan table
-                        */
-                       memcpy(adapter->bcn_buf_end, new_beacon->beacon_buf,
-                              new_beacon->beacon_buf_size);
-
-                       /* Update the beacon ptr to point to the table save
-                          area */
-                       new_beacon->beacon_buf = adapter->bcn_buf_end;
-                       new_beacon->beacon_buf_size_max =
-                               (new_beacon->beacon_buf_size +
-                                SCAN_BEACON_ENTRY_PAD);
-
-                       mwifiex_update_beacon_buffer_ptrs(new_beacon);
-
-                       /* Increment the end pointer by the size reserved */
-                       adapter->bcn_buf_end += new_beacon->beacon_buf_size_max;
-
-                       dev_dbg(adapter->dev, "info: AppControl: beacon[%02d]"
-                               " sz=%03d, used = %04d, left = %04d\n",
-                              beacon_idx,
-                              new_beacon->beacon_buf_size,
-                              (int)(adapter->bcn_buf_end - adapter->bcn_buf),
-                              (int)(sizeof(adapter->bcn_buf) -
-                               (adapter->bcn_buf_end -
-                                adapter->bcn_buf)));
-               } else {
-                       /* No space for new beacon */
-                       dev_dbg(adapter->dev, "info: AppControl: no space for"
-                               " beacon (%d): %pM sz=%03d, left=%03d\n",
-                              beacon_idx, new_beacon->mac_address,
-                              new_beacon->beacon_buf_size,
-                              (int)(sizeof(adapter->bcn_buf) -
-                               (adapter->bcn_buf_end -
-                                adapter->bcn_buf)));
-
-                       /* Storage failure; clear storage records for this
-                          bcn */
-                       new_beacon->beacon_buf = NULL;
-                       new_beacon->beacon_buf_size = 0;
-                       new_beacon->beacon_buf_size_max = 0;
-                       new_beacon->bcn_wpa_ie = NULL;
-                       new_beacon->wpa_offset = 0;
-                       new_beacon->bcn_rsn_ie = NULL;
-                       new_beacon->rsn_offset = 0;
-                       new_beacon->bcn_wapi_ie = NULL;
-                       new_beacon->wapi_offset = 0;
-                       new_beacon->bcn_ht_cap = NULL;
-                       new_beacon->ht_cap_offset = 0;
-                       new_beacon->bcn_ht_info = NULL;
-                       new_beacon->ht_info_offset = 0;
-                       new_beacon->bcn_bss_co_2040 = NULL;
-                       new_beacon->bss_co_2040_offset = 0;
-                       new_beacon->bcn_ext_cap = NULL;
-                       new_beacon->ext_cap_offset = 0;
-                       new_beacon->bcn_obss_scan = NULL;
-                       new_beacon->overlap_bss_offset = 0;
-               }
-       }
-}
-
-/*
- * This function restores a beacon buffer of the current BSS descriptor.
- */
-static void mwifiex_restore_curr_bcn(struct mwifiex_private *priv)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       struct mwifiex_bssdescriptor *curr_bss =
-               &priv->curr_bss_params.bss_descriptor;
-       unsigned long flags;
-
-       if (priv->curr_bcn_buf &&
-           ((adapter->bcn_buf_end + priv->curr_bcn_size) <
-            (adapter->bcn_buf + sizeof(adapter->bcn_buf)))) {
-               spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
-
-               /* restore the current beacon buffer */
-               memcpy(adapter->bcn_buf_end, priv->curr_bcn_buf,
-                      priv->curr_bcn_size);
-               curr_bss->beacon_buf = adapter->bcn_buf_end;
-               curr_bss->beacon_buf_size = priv->curr_bcn_size;
-               adapter->bcn_buf_end += priv->curr_bcn_size;
-
-               /* adjust the pointers in the current BSS descriptor */
-               if (curr_bss->bcn_wpa_ie)
-                       curr_bss->bcn_wpa_ie =
-                               (struct ieee_types_vendor_specific *)
-                               (curr_bss->beacon_buf +
-                                curr_bss->wpa_offset);
-
-               if (curr_bss->bcn_rsn_ie)
-                       curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
-                               (curr_bss->beacon_buf +
-                                curr_bss->rsn_offset);
-
-               if (curr_bss->bcn_ht_cap)
-                       curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
-                               (curr_bss->beacon_buf +
-                                curr_bss->ht_cap_offset);
-
-               if (curr_bss->bcn_ht_info)
-                       curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
-                               (curr_bss->beacon_buf +
-                                curr_bss->ht_info_offset);
-
-               if (curr_bss->bcn_bss_co_2040)
-                       curr_bss->bcn_bss_co_2040 =
-                               (u8 *) (curr_bss->beacon_buf +
-                                curr_bss->bss_co_2040_offset);
-
-               if (curr_bss->bcn_ext_cap)
-                       curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
-                                curr_bss->ext_cap_offset);
-
-               if (curr_bss->bcn_obss_scan)
-                       curr_bss->bcn_obss_scan =
-                               (struct ieee_types_obss_scan_param *)
-                               (curr_bss->beacon_buf +
-                                curr_bss->overlap_bss_offset);
-
-               spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
-
-               dev_dbg(adapter->dev, "info: current beacon restored %d\n",
-                      priv->curr_bcn_size);
-       } else {
-               dev_warn(adapter->dev,
-                       "curr_bcn_buf not saved or bcn_buf has no space\n");
-       }
-}
-
-/*
- * This function post processes the scan table after a new scan command has
- * completed.
- *
- * It inspects each entry of the scan table and tries to find an entry that
- * matches with our current associated/joined network from the scan. If
- * one is found, the stored copy of the BSS descriptor of our current network
- * is updated.
- *
- * It also debug dumps the current scan table contents after processing is over.
- */
-static void
-mwifiex_process_scan_results(struct mwifiex_private *priv)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       s32 j;
-       u32 i;
-       unsigned long flags;
-
-       if (priv->media_connected) {
-
-               j = mwifiex_find_ssid_in_list(priv, &priv->curr_bss_params.
-                                             bss_descriptor.ssid,
-                                             priv->curr_bss_params.
-                                             bss_descriptor.mac_address,
-                                             priv->bss_mode);
-
-               if (j >= 0) {
-                       spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
-                       priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
-                       priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
-                       priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
-                       priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
-                       priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
-                       priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
-                       priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
-                       priv->curr_bss_params.bss_descriptor.ht_cap_offset =
-                               0;
-                       priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
-                       priv->curr_bss_params.bss_descriptor.ht_info_offset =
-                               0;
-                       priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
-                               NULL;
-                       priv->curr_bss_params.bss_descriptor.
-                               bss_co_2040_offset = 0;
-                       priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
-                       priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
-                       priv->curr_bss_params.bss_descriptor.
-                               bcn_obss_scan = NULL;
-                       priv->curr_bss_params.bss_descriptor.
-                               overlap_bss_offset = 0;
-                       priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
-                       priv->curr_bss_params.bss_descriptor.beacon_buf_size =
-                               0;
-                       priv->curr_bss_params.bss_descriptor.
-                               beacon_buf_size_max = 0;
-
-                       dev_dbg(adapter->dev, "info: Found current ssid/bssid"
-                               " in list @ index #%d\n", j);
-                       /* Make a copy of current BSSID descriptor */
-                       memcpy(&priv->curr_bss_params.bss_descriptor,
-                              &adapter->scan_table[j],
-                              sizeof(priv->curr_bss_params.bss_descriptor));
-
-                       mwifiex_save_curr_bcn(priv);
-                       spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
-
-               } else {
-                       mwifiex_restore_curr_bcn(priv);
-               }
-       }
-
-       for (i = 0; i < adapter->num_in_scan_table; i++)
-               dev_dbg(adapter->dev, "info: scan:(%02d) %pM "
-                      "RSSI[%03d], SSID[%s]\n",
-                      i, adapter->scan_table[i].mac_address,
-                      (s32) adapter->scan_table[i].rssi,
-                      adapter->scan_table[i].ssid.ssid);
-}
-
 /*
  * This function converts radio type scan parameter to a band configuration
  * to be used in join command.
@@ -2071,175 +1307,6 @@ mwifiex_radio_type_to_band(u8 radio_type)
        }
 }
 
-/*
- * This function deletes a specific indexed entry from the scan table.
- *
- * This also compacts the remaining entries and adjusts any buffering
- * of beacon/probe response data if needed.
- */
-static void
-mwifiex_scan_delete_table_entry(struct mwifiex_private *priv, s32 table_idx)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       u32 del_idx;
-       u32 beacon_buf_adj;
-       u8 *beacon_buf;
-
-       /*
-        * Shift the saved beacon buffer data for the scan table back over the
-        *   entry being removed.  Update the end of buffer pointer.  Save the
-        *   deleted buffer allocation size for pointer adjustments for entries
-        *   compacted after the deleted index.
-        */
-       beacon_buf_adj = adapter->scan_table[table_idx].beacon_buf_size_max;
-
-       dev_dbg(adapter->dev, "info: Scan: Delete Entry %d, beacon buffer "
-               "removal = %d bytes\n", table_idx, beacon_buf_adj);
-
-       /* Check if the table entry had storage allocated for its beacon */
-       if (beacon_buf_adj) {
-               beacon_buf = adapter->scan_table[table_idx].beacon_buf;
-
-               /*
-                * Remove the entry's buffer space, decrement the table end
-                * pointer by the amount we are removing
-                */
-               adapter->bcn_buf_end -= beacon_buf_adj;
-
-               dev_dbg(adapter->dev, "info: scan: delete entry %d,"
-                       " compact data: %p <- %p (sz = %d)\n",
-                      table_idx, beacon_buf,
-                      beacon_buf + beacon_buf_adj,
-                      (int)(adapter->bcn_buf_end - beacon_buf));
-
-               /*
-                * Compact data storage.  Copy all data after the deleted
-                * entry's end address (beacon_buf + beacon_buf_adj) back
-                * to the original start address (beacon_buf).
-                *
-                * Scan table entries affected by the move will have their
-                * entry pointer adjusted below.
-                *
-                * Use memmove since the dest/src memory regions overlap.
-                */
-               memmove(beacon_buf, beacon_buf + beacon_buf_adj,
-                       adapter->bcn_buf_end - beacon_buf);
-       }
-
-       dev_dbg(adapter->dev,
-               "info: Scan: Delete Entry %d, num_in_scan_table = %d\n",
-              table_idx, adapter->num_in_scan_table);
-
-       /* Shift all of the entries after the table_idx back by one, compacting
-          the table and removing the requested entry */
-       for (del_idx = table_idx; (del_idx + 1) < adapter->num_in_scan_table;
-            del_idx++) {
-               /* Copy the next entry over this one */
-               memcpy(adapter->scan_table + del_idx,
-                      adapter->scan_table + del_idx + 1,
-                      sizeof(struct mwifiex_bssdescriptor));
-
-               /*
-                * Adjust this entry's pointer to its beacon buffer based on
-                * the removed/compacted entry from the deleted index.  Don't
-                * decrement if the buffer pointer is NULL (no data stored for
-                * this entry).
-                */
-               if (adapter->scan_table[del_idx].beacon_buf) {
-                       adapter->scan_table[del_idx].beacon_buf -=
-                               beacon_buf_adj;
-                       if (adapter->scan_table[del_idx].bcn_wpa_ie)
-                               adapter->scan_table[del_idx].bcn_wpa_ie =
-                                       (struct ieee_types_vendor_specific *)
-                                       (adapter->scan_table[del_idx].
-                                        beacon_buf +
-                                        adapter->scan_table[del_idx].
-                                        wpa_offset);
-                       if (adapter->scan_table[del_idx].bcn_rsn_ie)
-                               adapter->scan_table[del_idx].bcn_rsn_ie =
-                                       (struct ieee_types_generic *)
-                                       (adapter->scan_table[del_idx].
-                                        beacon_buf +
-                                        adapter->scan_table[del_idx].
-                                        rsn_offset);
-                       if (adapter->scan_table[del_idx].bcn_wapi_ie)
-                               adapter->scan_table[del_idx].bcn_wapi_ie =
-                                       (struct ieee_types_generic *)
-                                       (adapter->scan_table[del_idx].beacon_buf
-                                        + adapter->scan_table[del_idx].
-                                        wapi_offset);
-                       if (adapter->scan_table[del_idx].bcn_ht_cap)
-                               adapter->scan_table[del_idx].bcn_ht_cap =
-                                       (struct ieee80211_ht_cap *)
-                                       (adapter->scan_table[del_idx].beacon_buf
-                                        + adapter->scan_table[del_idx].
-                                         ht_cap_offset);
-
-                       if (adapter->scan_table[del_idx].bcn_ht_info)
-                               adapter->scan_table[del_idx].bcn_ht_info =
-                                       (struct ieee80211_ht_info *)
-                                       (adapter->scan_table[del_idx].beacon_buf
-                                        + adapter->scan_table[del_idx].
-                                         ht_info_offset);
-                       if (adapter->scan_table[del_idx].bcn_bss_co_2040)
-                               adapter->scan_table[del_idx].bcn_bss_co_2040 =
-                                       (u8 *)
-                                       (adapter->scan_table[del_idx].beacon_buf
-                                        + adapter->scan_table[del_idx].
-                                          bss_co_2040_offset);
-                       if (adapter->scan_table[del_idx].bcn_ext_cap)
-                               adapter->scan_table[del_idx].bcn_ext_cap =
-                                       (u8 *)
-                                       (adapter->scan_table[del_idx].beacon_buf
-                                        + adapter->scan_table[del_idx].
-                                            ext_cap_offset);
-                       if (adapter->scan_table[del_idx].bcn_obss_scan)
-                               adapter->scan_table[del_idx].
-                                       bcn_obss_scan =
-                                       (struct ieee_types_obss_scan_param *)
-                                       (adapter->scan_table[del_idx].beacon_buf
-                                        + adapter->scan_table[del_idx].
-                                            overlap_bss_offset);
-               }
-       }
-
-       /* The last entry is invalid now that it has been deleted or moved
-          back */
-       memset(adapter->scan_table + adapter->num_in_scan_table - 1,
-              0x00, sizeof(struct mwifiex_bssdescriptor));
-
-       adapter->num_in_scan_table--;
-}
-
-/*
- * This function deletes all occurrences of a given SSID from the scan table.
- *
- * This iterates through the scan table and deletes all entries that match
- * the given SSID. It also compacts the remaining scan table entries.
- */
-static int
-mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv,
-                                    struct mwifiex_802_11_ssid *del_ssid)
-{
-       s32 table_idx = -1;
-
-       dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n",
-                       del_ssid->ssid);
-
-       /* If the requested SSID is found in the table, delete it.  Then keep
-          searching the table for multiple entires for the SSID until no
-          more are found */
-       while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL,
-                                       NL80211_IFTYPE_UNSPECIFIED)) >= 0) {
-               dev_dbg(priv->adapter->dev,
-                       "info: Scan: Delete SSID Entry: Found Idx = %d\n",
-                      table_idx);
-               mwifiex_scan_delete_table_entry(priv, table_idx);
-       }
-
-       return table_idx == -1 ? -1 : 0;
-}
-
 /*
  * This is an internal function used to start a scan based on an input
  * configuration.
@@ -2258,7 +1325,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
        struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
        u32 buf_size;
        struct mwifiex_chan_scan_param_set *scan_chan_list;
-       u8 keep_previous_scan;
        u8 filtered_scan;
        u8 scan_current_chan_only;
        u8 max_chan_per_scan;
@@ -2295,24 +1361,11 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
                return -ENOMEM;
        }
 
-       keep_previous_scan = false;
-
        mwifiex_scan_setup_scan_config(priv, user_scan_in,
                                       &scan_cfg_out->config, &chan_list_out,
                                       scan_chan_list, &max_chan_per_scan,
                                       &filtered_scan, &scan_current_chan_only);
 
-       if (user_scan_in)
-               keep_previous_scan = user_scan_in->keep_previous_scan;
-
-
-       if (!keep_previous_scan) {
-               memset(adapter->scan_table, 0x00,
-                      sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
-               adapter->num_in_scan_table = 0;
-               adapter->bcn_buf_end = adapter->bcn_buf;
-       }
-
        ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
                                        &scan_cfg_out->config, chan_list_out,
                                        scan_chan_list);
@@ -2378,6 +1431,107 @@ int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
        return 0;
 }
 
+/*
+ * This function checks compatibility of requested network with current
+ * driver settings.
+ */
+int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
+                                       struct mwifiex_bssdescriptor *bss_desc)
+{
+       int ret = -1;
+
+       if (!bss_desc)
+               return -1;
+
+       if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
+                       (u8) bss_desc->bss_band, (u16) bss_desc->channel))) {
+               switch (priv->bss_mode) {
+               case NL80211_IFTYPE_STATION:
+               case NL80211_IFTYPE_ADHOC:
+                       ret = mwifiex_is_network_compatible(priv, bss_desc,
+                                                           priv->bss_mode);
+                       if (ret)
+                               dev_err(priv->adapter->dev, "cannot find ssid "
+                                       "%s\n", bss_desc->ssid.ssid);
+                               break;
+               default:
+                               ret = 0;
+               }
+       }
+
+       return ret;
+}
+
+static int
+mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
+                       u8 *bssid, s32 rssi, const u8 *ie_buf,
+                       size_t ie_len, u16 beacon_period, u16 cap_info_bitmap)
+{
+       struct mwifiex_bssdescriptor *bss_desc = NULL;
+       int ret;
+       unsigned long flags;
+       u8 *beacon_ie;
+
+       /* Allocate and fill new bss descriptor */
+       bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
+                       GFP_KERNEL);
+       if (!bss_desc) {
+               dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
+               return -ENOMEM;
+       }
+       beacon_ie = kzalloc(ie_len, GFP_KERNEL);
+       if (!bss_desc) {
+               dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
+               return -ENOMEM;
+       }
+       memcpy(beacon_ie, ie_buf, ie_len);
+
+       ret = mwifiex_fill_new_bss_desc(priv, bssid, rssi, beacon_ie,
+                                       ie_len, beacon_period,
+                                       cap_info_bitmap, bss_desc);
+       if (ret)
+               goto done;
+
+       ret = mwifiex_check_network_compatibility(priv, bss_desc);
+       if (ret)
+               goto done;
+
+       /* Update current bss descriptor parameters */
+       spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
+       priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
+       priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
+       priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
+       priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
+       priv->curr_bss_params.bss_descriptor.ht_cap_offset =
+               0;
+       priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
+       priv->curr_bss_params.bss_descriptor.ht_info_offset =
+               0;
+       priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
+               NULL;
+       priv->curr_bss_params.bss_descriptor.
+               bss_co_2040_offset = 0;
+       priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
+       priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
+       priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
+       priv->curr_bss_params.bss_descriptor.beacon_buf_size =
+               0;
+
+       /* Make a copy of current BSSID descriptor */
+       memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
+               sizeof(priv->curr_bss_params.bss_descriptor));
+       mwifiex_save_curr_bcn(priv);
+       spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
+
+done:
+       kfree(bss_desc);
+       kfree(beacon_ie);
+       return 0;
+}
+
 /*
  * This function handles the command response of scan.
  *
@@ -2404,21 +1558,16 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
        struct mwifiex_adapter *adapter = priv->adapter;
        struct cmd_ctrl_node *cmd_node;
        struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
-       struct mwifiex_bssdescriptor *bss_new_entry = NULL;
        struct mwifiex_ie_types_data *tlv_data;
        struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
        u8 *bss_info;
        u32 scan_resp_size;
        u32 bytes_left;
-       u32 num_in_table;
-       u32 bss_idx;
        u32 idx;
        u32 tlv_buf_size;
-       long long tsf_val;
        struct mwifiex_chan_freq_power *cfp;
        struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
        struct chan_band_param_set *chan_band;
-       u8 band;
        u8 is_bgscan_resp;
        unsigned long flags;
 
@@ -2430,7 +1579,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                scan_rsp = &resp->params.scan_resp;
 
 
-       if (scan_rsp->number_of_sets > IW_MAX_AP) {
+       if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
                dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
                       scan_rsp->number_of_sets);
                ret = -1;
@@ -2447,7 +1596,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                "info: SCAN_RESP: returned %d APs before parsing\n",
               scan_rsp->number_of_sets);
 
-       num_in_table = adapter->num_in_scan_table;
        bss_info = scan_rsp->bss_desc_and_tlv_buffer;
 
        /*
@@ -2479,125 +1627,147 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                                             (struct mwifiex_ie_types_data **)
                                             &chan_band_tlv);
 
-       /*
-        *  Process each scan response returned (scan_rsp->number_of_sets).
-        *  Save the information in the bss_new_entry and then insert into the
-        *  driver scan table either as an update to an existing entry
-        *  or as an addition at the end of the table
-        */
-       bss_new_entry = kzalloc(sizeof(struct mwifiex_bssdescriptor),
-                               GFP_KERNEL);
-       if (!bss_new_entry) {
-               dev_err(adapter->dev, " failed to alloc bss_new_entry\n");
-               return -ENOMEM;
-       }
-
        for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
-               /* Zero out the bss_new_entry we are about to store info in */
-               memset(bss_new_entry, 0x00,
-                      sizeof(struct mwifiex_bssdescriptor));
-
-               if (mwifiex_interpret_bss_desc_with_ie(adapter, bss_new_entry,
-                                                       &bss_info,
-                                                       &bytes_left)) {
-                       /* Error parsing/interpreting scan response, skipped */
-                       dev_err(adapter->dev, "SCAN_RESP: "
-                              "mwifiex_interpret_bss_desc_with_ie "
-                              "returned ERROR\n");
-                       continue;
+               u8 bssid[ETH_ALEN];
+               s32 rssi;
+               const u8 *ie_buf;
+               size_t ie_len;
+               int channel = -1;
+               u64 network_tsf = 0;
+               u16 beacon_size = 0;
+               u32 curr_bcn_bytes;
+               u32 freq;
+               u16 beacon_period;
+               u16 cap_info_bitmap;
+               u8 *current_ptr;
+               struct mwifiex_bcn_param *bcn_param;
+
+               if (bytes_left >= sizeof(beacon_size)) {
+                       /* Extract & convert beacon size from command buffer */
+                       memcpy(&beacon_size, bss_info, sizeof(beacon_size));
+                       bytes_left -= sizeof(beacon_size);
+                       bss_info += sizeof(beacon_size);
                }
 
-               /* Process the data fields and IEs returned for this BSS */
-               dev_dbg(adapter->dev, "info: SCAN_RESP: BSSID = %pM\n",
-                      bss_new_entry->mac_address);
+               if (!beacon_size || beacon_size > bytes_left) {
+                       bss_info += bytes_left;
+                       bytes_left = 0;
+                       return -1;
+               }
 
-               /* Search the scan table for the same bssid */
-               for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) {
-                       if (memcmp(bss_new_entry->mac_address,
-                               adapter->scan_table[bss_idx].mac_address,
-                               sizeof(bss_new_entry->mac_address))) {
-                               continue;
+               /* Initialize the current working beacon pointer for this BSS
+                * iteration */
+               current_ptr = bss_info;
+
+               /* Advance the return beacon pointer past the current beacon */
+               bss_info += beacon_size;
+               bytes_left -= beacon_size;
+
+               curr_bcn_bytes = beacon_size;
+
+               /*
+                * First 5 fields are bssid, RSSI, time stamp, beacon interval,
+                *   and capability information
+                */
+               if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) {
+                       dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
+                       continue;
+               }
+               bcn_param = (struct mwifiex_bcn_param *)current_ptr;
+               current_ptr += sizeof(*bcn_param);
+               curr_bcn_bytes -= sizeof(*bcn_param);
+
+               memcpy(bssid, bcn_param->bssid, ETH_ALEN);
+
+               rssi = (s32) (bcn_param->rssi);
+               dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n",
+                                       rssi);
+
+               beacon_period = le16_to_cpu(bcn_param->beacon_period);
+
+               cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
+               dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
+                               cap_info_bitmap);
+
+               /* Rest of the current buffer are IE's */
+               ie_buf = current_ptr;
+               ie_len = curr_bcn_bytes;
+               dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP"
+                                     " = %d\n", curr_bcn_bytes);
+
+               while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
+                       u8 element_id, element_len;
+
+                       element_id = *current_ptr;
+                       element_len = *(current_ptr + 1);
+                       if (curr_bcn_bytes < element_len +
+                                       sizeof(struct ieee_types_header)) {
+                               dev_err(priv->adapter->dev, "%s: in processing"
+                                       " IE, bytes left < IE length\n",
+                                       __func__);
+                               goto done;
                        }
-                       /*
-                        * If the SSID matches as well, it is a
-                        * duplicate of this entry.  Keep the bss_idx
-                        * set to this entry so we replace the old
-                        * contents in the table
-                        */
-                       if ((bss_new_entry->ssid.ssid_len
-                               == adapter->scan_table[bss_idx]. ssid.ssid_len)
-                                       && (!memcmp(bss_new_entry->ssid.ssid,
-                                       adapter->scan_table[bss_idx].ssid.ssid,
-                                       bss_new_entry->ssid.ssid_len))) {
-                               dev_dbg(adapter->dev, "info: SCAN_RESP:"
-                                       " duplicate of index: %d\n", bss_idx);
+                       if (element_id == WLAN_EID_DS_PARAMS) {
+                               channel = *(u8 *) (current_ptr +
+                                       sizeof(struct ieee_types_header));
                                break;
                        }
-               }
-               /*
-                * If the bss_idx is equal to the number of entries in
-                * the table, the new entry was not a duplicate; append
-                * it to the scan table
-                */
-               if (bss_idx == num_in_table) {
-                       /* Range check the bss_idx, keep it limited to
-                          the last entry */
-                       if (bss_idx == IW_MAX_AP)
-                               bss_idx--;
-                       else
-                               num_in_table++;
+
+                       current_ptr += element_len +
+                                       sizeof(struct ieee_types_header);
+                       curr_bcn_bytes -= element_len +
+                                       sizeof(struct ieee_types_header);
                }
 
-               /*
-                * Save the beacon/probe response returned for later application
-                * retrieval.  Duplicate beacon/probe responses are updated if
-                * possible
-                */
-               mwifiex_ret_802_11_scan_store_beacon(priv, bss_idx,
-                                               num_in_table, bss_new_entry);
                /*
                 * If the TSF TLV was appended to the scan results, save this
                 * entry's TSF value in the networkTSF field.The networkTSF is
                 * the firmware's TSF value at the time the beacon or probe
                 * response was received.
                 */
-               if (tsf_tlv) {
-                       memcpy(&tsf_val, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE]
-                                       , sizeof(tsf_val));
-                       memcpy(&bss_new_entry->network_tsf, &tsf_val,
-                                       sizeof(bss_new_entry->network_tsf));
-               }
-               band = BAND_G;
-               if (chan_band_tlv) {
-                       chan_band = &chan_band_tlv->chan_band_param[idx];
-                       band = mwifiex_radio_type_to_band(chan_band->radio_type
-                                       & (BIT(0) | BIT(1)));
-               }
-
-               /* Save the band designation for this entry for use in join */
-               bss_new_entry->bss_band = band;
-               cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
-                                       (u8) bss_new_entry->bss_band,
-                                       (u16)bss_new_entry->channel);
+               if (tsf_tlv)
+                       memcpy(&network_tsf,
+                                       &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
+                                       sizeof(network_tsf));
+
+               if (channel != -1) {
+                       struct ieee80211_channel *chan;
+                       u8 band;
+
+                       band = BAND_G;
+                       if (chan_band_tlv) {
+                               chan_band =
+                                       &chan_band_tlv->chan_band_param[idx];
+                               band = mwifiex_radio_type_to_band(
+                                               chan_band->radio_type
+                                               & (BIT(0) | BIT(1)));
+                       }
 
-               if (cfp)
-                       bss_new_entry->freq = cfp->freq;
-               else
-                       bss_new_entry->freq = 0;
+                       cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
+                                               priv, (u8)band, (u16)channel);
 
-               /* Copy the locally created bss_new_entry to the scan table */
-               memcpy(&adapter->scan_table[bss_idx], bss_new_entry,
-                      sizeof(adapter->scan_table[bss_idx]));
+                       freq = cfp ? cfp->freq : 0;
 
-       }
+                       chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
 
-       dev_dbg(adapter->dev,
-               "info: SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
-              scan_rsp->number_of_sets,
-              num_in_table - adapter->num_in_scan_table, num_in_table);
+                       if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
+                               cfg80211_inform_bss(priv->wdev->wiphy, chan,
+                                       bssid, network_tsf, cap_info_bitmap,
+                                       beacon_period, ie_buf, ie_len, rssi,
+                                       GFP_KERNEL);
 
-       /* Update the total number of BSSIDs in the scan table */
-       adapter->num_in_scan_table = num_in_table;
+                               if (priv->media_connected && !memcmp(bssid,
+                                       priv->curr_bss_params.bss_descriptor
+                                                    .mac_address, ETH_ALEN))
+                                       mwifiex_update_curr_bss_params(priv,
+                                                       bssid, rssi, ie_buf,
+                                                       ie_len, beacon_period,
+                                                       cap_info_bitmap);
+                       }
+               } else {
+                       dev_dbg(adapter->dev, "missing BSS channel IE\n");
+               }
+       }
 
        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
        if (list_empty(&adapter->scan_pending_q)) {
@@ -2605,12 +1775,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
                adapter->scan_processing = false;
                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
-               /*
-                * Process the resulting scan table:
-                *   - Remove any bad ssids
-                *   - Update our current BSS information from scan data
-                */
-               mwifiex_process_scan_results(priv);
 
                /* Need to indicate IOCTL complete */
                if (adapter->curr_cmd->wait_q_enabled) {
@@ -2636,7 +1800,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
        }
 
 done:
-       kfree((u8 *) bss_new_entry);
        return ret;
 }
 
@@ -2662,141 +1825,6 @@ int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
        return 0;
 }
 
-/*
- * This function finds a SSID in the scan table.
- *
- * A BSSID may optionally be provided to qualify the SSID.
- * For non-Auto mode, further check is made to make sure the
- * BSS found in the scan table is compatible with the current
- * settings of the driver.
- */
-s32
-mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
-                         struct mwifiex_802_11_ssid *ssid, u8 *bssid,
-                         u32 mode)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       s32 net = -1, j;
-       u8 best_rssi = 0;
-       u32 i;
-
-       dev_dbg(adapter->dev, "info: num of entries in table = %d\n",
-              adapter->num_in_scan_table);
-
-       /*
-        * Loop through the table until the maximum is reached or until a match
-        *   is found based on the bssid field comparison
-        */
-       for (i = 0;
-            i < adapter->num_in_scan_table && (!bssid || (bssid && net < 0));
-            i++) {
-               if (!mwifiex_ssid_cmp(&adapter->scan_table[i].ssid, ssid) &&
-                   (!bssid
-                    || !memcmp(adapter->scan_table[i].mac_address, bssid,
-                               ETH_ALEN))
-                   &&
-                   (mwifiex_get_cfp_by_band_and_channel_from_cfg80211
-                    (priv, (u8) adapter->scan_table[i].bss_band,
-                     (u16) adapter->scan_table[i].channel))) {
-                       switch (mode) {
-                       case NL80211_IFTYPE_STATION:
-                       case NL80211_IFTYPE_ADHOC:
-                               j = mwifiex_is_network_compatible(priv, i,
-                                                                 mode);
-
-                               if (j >= 0) {
-                                       if (SCAN_RSSI
-                                           (adapter->scan_table[i].rssi) >
-                                           best_rssi) {
-                                               best_rssi = SCAN_RSSI(adapter->
-                                                                 scan_table
-                                                                 [i].rssi);
-                                               net = i;
-                                       }
-                               } else {
-                                       if (net == -1)
-                                               net = j;
-                               }
-                               break;
-                       case NL80211_IFTYPE_UNSPECIFIED:
-                       default:
-                               /*
-                                * Do not check compatibility if the mode
-                                * requested is Auto/Unknown.  Allows generic
-                                * find to work without verifying against the
-                                * Adapter security settings
-                                */
-                               if (SCAN_RSSI(adapter->scan_table[i].rssi) >
-                                   best_rssi) {
-                                       best_rssi = SCAN_RSSI(adapter->
-                                                         scan_table[i].rssi);
-                                       net = i;
-                               }
-                               break;
-                       }
-               }
-       }
-
-       return net;
-}
-
-/*
- * This function finds a specific compatible BSSID in the scan list.
- *
- * This function loops through the scan table looking for a compatible
- * match. If a BSSID matches, but the BSS is found to be not compatible
- * the function ignores it and continues to search through the rest of
- * the entries in case there is an AP with multiple SSIDs assigned to
- * the same BSSID.
- */
-s32
-mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
-                          u32 mode)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       s32 net = -1;
-       u32 i;
-
-       if (!bssid)
-               return -1;
-
-       dev_dbg(adapter->dev, "info: FindBSSID: Num of BSSIDs = %d\n",
-              adapter->num_in_scan_table);
-
-       /*
-        * Look through the scan table for a compatible match. The ret return
-        *   variable will be equal to the index in the scan table (greater
-        *   than zero) if the network is compatible.  The loop will continue
-        *   past a matched bssid that is not compatible in case there is an
-        *   AP with multiple SSIDs assigned to the same BSSID
-        */
-       for (i = 0; net < 0 && i < adapter->num_in_scan_table; i++) {
-               if (!memcmp
-                   (adapter->scan_table[i].mac_address, bssid, ETH_ALEN)
-                       && mwifiex_get_cfp_by_band_and_channel_from_cfg80211
-                                                               (priv,
-                                                           (u8) adapter->
-                                                           scan_table[i].
-                                                           bss_band,
-                                                           (u16) adapter->
-                                                           scan_table[i].
-                                                           channel)) {
-                       switch (mode) {
-                       case NL80211_IFTYPE_STATION:
-                       case NL80211_IFTYPE_ADHOC:
-                               net = mwifiex_is_network_compatible(priv, i,
-                                                                   mode);
-                               break;
-                       default:
-                               net = i;
-                               break;
-                       }
-               }
-       }
-
-       return net;
-}
-
 /*
  * This function inserts scan command node to the scan pending queue.
  */
@@ -2813,42 +1841,6 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
        spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
 }
 
-/*
- * This function finds an AP with specific ssid in the scan list.
- */
-int mwifiex_find_best_network(struct mwifiex_private *priv,
-                             struct mwifiex_ssid_bssid *req_ssid_bssid)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       struct mwifiex_bssdescriptor *req_bss;
-       s32 i;
-
-       memset(req_ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
-
-       i = mwifiex_find_best_network_in_list(priv);
-
-       if (i >= 0) {
-               req_bss = &adapter->scan_table[i];
-               memcpy(&req_ssid_bssid->ssid, &req_bss->ssid,
-                      sizeof(struct mwifiex_802_11_ssid));
-               memcpy((u8 *) &req_ssid_bssid->bssid,
-                      (u8 *) &req_bss->mac_address, ETH_ALEN);
-
-               /* Make sure we are in the right mode */
-               if (priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
-                       priv->bss_mode = req_bss->bss_mode;
-       }
-
-       if (!req_ssid_bssid->ssid.ssid_len)
-               return -1;
-
-       dev_dbg(adapter->dev, "info: Best network found = [%s], "
-              "[%pM]\n", req_ssid_bssid->ssid.ssid,
-              req_ssid_bssid->bssid);
-
-       return 0;
-}
-
 /*
  * This function sends a scan command for all available channels to the
  * firmware, filtered on a specific SSID.
@@ -2874,8 +1866,6 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
                return ret;
        }
 
-       mwifiex_scan_delete_ssid_table_entry(priv, req_ssid);
-
        scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
        if (!scan_cfg) {
                dev_err(adapter->dev, "failed to alloc scan_cfg\n");
@@ -2884,7 +1874,6 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
 
        memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
               req_ssid->ssid_len);
-       scan_cfg->keep_previous_scan = true;
 
        ret = mwifiex_scan_networks(priv, scan_cfg);
 
@@ -3010,6 +1999,39 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
                curr_bss->beacon_buf_size);
        dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
                priv->curr_bcn_size);
+
+       curr_bss->beacon_buf = priv->curr_bcn_buf;
+
+       /* adjust the pointers in the current BSS descriptor */
+       if (curr_bss->bcn_wpa_ie)
+               curr_bss->bcn_wpa_ie =
+                       (struct ieee_types_vendor_specific *)
+                       (curr_bss->beacon_buf +
+                        curr_bss->wpa_offset);
+
+       if (curr_bss->bcn_rsn_ie)
+               curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
+                       (curr_bss->beacon_buf +
+                        curr_bss->rsn_offset);
+
+       if (curr_bss->bcn_ht_cap)
+               curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
+                       (curr_bss->beacon_buf +
+                        curr_bss->ht_cap_offset);
+
+       if (curr_bss->bcn_ht_info)
+               curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
+                       (curr_bss->beacon_buf +
+                        curr_bss->ht_info_offset);
+
+       if (curr_bss->bcn_bss_co_2040)
+               curr_bss->bcn_bss_co_2040 =
+                       (u8 *) (curr_bss->beacon_buf +
+                                       curr_bss->bss_co_2040_offset);
+
+       if (curr_bss->bcn_ext_cap)
+               curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
+                               curr_bss->ext_cap_offset);
 }
 
 /*
index fc265cab09078685114fb1138add648c4108f310..f204810e83389bfa4085c6dd5dbc39daa26ee70f 100644 (file)
@@ -130,8 +130,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
        if (netif_carrier_ok(priv->netdev))
                netif_carrier_off(priv->netdev);
        /* Reset wireless stats signal info */
-       priv->w_stats.qual.level = 0;
-       priv->w_stats.qual.noise = 0;
+       priv->qual_level = 0;
+       priv->qual_noise = 0;
 }
 
 /*
@@ -299,11 +299,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
 
        case EVENT_BG_SCAN_REPORT:
                dev_dbg(adapter->dev, "event: BGS_REPORT\n");
-               /* Clear the previous scan result */
-               memset(adapter->scan_table, 0x00,
-                      sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
-               adapter->num_in_scan_table = 0;
-               adapter->bcn_buf_end = adapter->bcn_buf;
                ret = mwifiex_send_cmd_async(priv,
                                             HostCmd_CMD_802_11_BG_SCAN_QUERY,
                                             HostCmd_ACT_GEN_GET, 0, NULL);
index c34ff8c4f4f82adb471524df463b5d8c5e24fb5a..3fca219bcfb6deea19dcef14e324c2f5e9d8b1ea 100644 (file)
@@ -141,91 +141,143 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
        return ret;
 }
 
+/*
+ * This function fills bss descriptor structure using provided
+ * information.
+ */
+int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
+                             u8 *bssid, s32 rssi, u8 *ie_buf,
+                             size_t ie_len, u16 beacon_period,
+                             u16 cap_info_bitmap,
+                             struct mwifiex_bssdescriptor *bss_desc)
+{
+       int ret;
+
+       memcpy(bss_desc->mac_address, bssid, ETH_ALEN);
+       bss_desc->rssi = rssi;
+       bss_desc->beacon_buf = ie_buf;
+       bss_desc->beacon_buf_size = ie_len;
+       bss_desc->beacon_period = beacon_period;
+       bss_desc->cap_info_bitmap = cap_info_bitmap;
+       if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
+               dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
+               bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
+       } else {
+               bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
+       }
+       if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
+               bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
+       else
+               bss_desc->bss_mode = NL80211_IFTYPE_STATION;
+
+       ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc,
+                                             ie_buf, ie_len);
+
+       return ret;
+}
+
 /*
  * In Ad-Hoc mode, the IBSS is created if not found in scan list.
  * In both Ad-Hoc and infra mode, an deauthentication is performed
  * first.
  */
-int mwifiex_bss_start(struct mwifiex_private *priv,
-                     struct mwifiex_ssid_bssid *ssid_bssid)
+int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
+                     struct mwifiex_802_11_ssid *req_ssid)
 {
        int ret;
        struct mwifiex_adapter *adapter = priv->adapter;
-       s32 i = -1;
+       struct mwifiex_bssdescriptor *bss_desc = NULL;
+       u8 *beacon_ie = NULL;
 
        priv->scan_block = false;
-       if (!ssid_bssid)
-               return -1;
+
+       if (bss) {
+               /* Allocate and fill new bss descriptor */
+               bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
+                               GFP_KERNEL);
+               if (!bss_desc) {
+                       dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
+                       return -ENOMEM;
+               }
+               beacon_ie = kzalloc(bss->len_beacon_ies, GFP_KERNEL);
+               if (!beacon_ie) {
+                       dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
+                       return -ENOMEM;
+               }
+               memcpy(beacon_ie, bss->information_elements,
+                      bss->len_beacon_ies);
+               ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal,
+                                               beacon_ie, bss->len_beacon_ies,
+                                               bss->beacon_interval,
+                                               bss->capability, bss_desc);
+               if (ret)
+                       goto done;
+       }
 
        if (priv->bss_mode == NL80211_IFTYPE_STATION) {
                /* Infra mode */
                ret = mwifiex_deauthenticate(priv, NULL);
                if (ret)
-                       return ret;
+                       goto done;
 
-               /* Search for the requested SSID in the scan table */
-               if (ssid_bssid->ssid.ssid_len)
-                       i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid,
-                                               NULL, NL80211_IFTYPE_STATION);
-               else
-                       i = mwifiex_find_bssid_in_list(priv,
-                                               (u8 *) &ssid_bssid->bssid,
-                                               NL80211_IFTYPE_STATION);
-               if (i < 0)
-                       return -1;
+               ret = mwifiex_check_network_compatibility(priv, bss_desc);
+               if (ret)
+                       goto done;
+
+               dev_dbg(adapter->dev, "info: SSID found in scan list ... "
+                                     "associating...\n");
 
-               dev_dbg(adapter->dev,
-                       "info: SSID found in scan list ... associating...\n");
+               if (!netif_queue_stopped(priv->netdev))
+                       netif_stop_queue(priv->netdev);
 
                /* Clear any past association response stored for
                 * application retrieval */
                priv->assoc_rsp_size = 0;
-               ret = mwifiex_associate(priv, &adapter->scan_table[i]);
-               if (ret)
-                       return ret;
+               ret = mwifiex_associate(priv, bss_desc);
+               if (bss)
+                       cfg80211_put_bss(bss);
        } else {
                /* Adhoc mode */
                /* If the requested SSID matches current SSID, return */
-               if (ssid_bssid->ssid.ssid_len &&
+               if (bss_desc && bss_desc->ssid.ssid_len &&
                    (!mwifiex_ssid_cmp
                     (&priv->curr_bss_params.bss_descriptor.ssid,
-                     &ssid_bssid->ssid)))
+                     &bss_desc->ssid))) {
+                       kfree(bss_desc);
+                       kfree(beacon_ie);
                        return 0;
+               }
 
                /* Exit Adhoc mode first */
                dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
                ret = mwifiex_deauthenticate(priv, NULL);
                if (ret)
-                       return ret;
+                       goto done;
 
                priv->adhoc_is_link_sensed = false;
 
-               /* Search for the requested network in the scan table */
-               if (ssid_bssid->ssid.ssid_len)
-                       i = mwifiex_find_ssid_in_list(priv,
-                                                     &ssid_bssid->ssid, NULL,
-                                                     NL80211_IFTYPE_ADHOC);
-               else
-                       i = mwifiex_find_bssid_in_list(priv,
-                                                      (u8 *)&ssid_bssid->bssid,
-                                                      NL80211_IFTYPE_ADHOC);
-
-               if (i >= 0) {
+               ret = mwifiex_check_network_compatibility(priv, bss_desc);
+
+               if (!netif_queue_stopped(priv->netdev))
+                       netif_stop_queue(priv->netdev);
+
+               if (!ret) {
                        dev_dbg(adapter->dev, "info: network found in scan"
                                                        " list. Joining...\n");
-                       ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]);
-                       if (ret)
-                               return ret;
+                       ret = mwifiex_adhoc_join(priv, bss_desc);
+                       if (bss)
+                               cfg80211_put_bss(bss);
                } else {
                        dev_dbg(adapter->dev, "info: Network not found in "
                                "the list, creating adhoc with ssid = %s\n",
-                              ssid_bssid->ssid.ssid);
-                       ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid);
-                       if (ret)
-                               return ret;
+                               req_ssid->ssid);
+                       ret = mwifiex_adhoc_start(priv, req_ssid);
                }
        }
 
+done:
+       kfree(bss_desc);
+       kfree(beacon_ie);
        return ret;
 }
 
@@ -376,7 +428,6 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
 {
        struct mwifiex_adapter *adapter = priv->adapter;
        struct mwifiex_bssdescriptor *bss_desc;
-       s32 tbl_idx;
 
        if (!info)
                return -1;
@@ -394,17 +445,6 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
 
        info->region_code = adapter->region_code;
 
-       /* Scan table index if connected */
-       info->scan_table_idx = 0;
-       if (priv->media_connected) {
-               tbl_idx =
-                       mwifiex_find_ssid_in_list(priv, &bss_desc->ssid,
-                                                 bss_desc->mac_address,
-                                                 priv->bss_mode);
-               if (tbl_idx >= 0)
-                       info->scan_table_idx = tbl_idx;
-       }
-
        info->media_connected = priv->media_connected;
 
        info->max_power_level = priv->max_tx_power_level;
@@ -585,50 +625,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
                                    action, 0, channel);
 }
 
-/*
- * IOCTL request handler to find a particular BSS.
- *
- * The BSS can be searched with either a BSSID or a SSID. If none of
- * these are provided, just the best BSS (best RSSI) is returned.
- */
-int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
-                              struct mwifiex_ssid_bssid *ssid_bssid)
-{
-       struct mwifiex_adapter *adapter = priv->adapter;
-       struct mwifiex_bssdescriptor *bss_desc;
-       u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-       u8 mac[ETH_ALEN];
-       int i = 0;
-
-       if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) {
-               i = mwifiex_find_bssid_in_list(priv,
-                                              (u8 *) ssid_bssid->bssid,
-                                              priv->bss_mode);
-               if (i < 0) {
-                       memcpy(mac, ssid_bssid->bssid, sizeof(mac));
-                       dev_err(adapter->dev, "cannot find bssid %pM\n", mac);
-                       return -1;
-               }
-               bss_desc = &adapter->scan_table[i];
-               memcpy(&ssid_bssid->ssid, &bss_desc->ssid,
-                               sizeof(struct mwifiex_802_11_ssid));
-       } else if (ssid_bssid->ssid.ssid_len) {
-               i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL,
-                                             priv->bss_mode);
-               if (i < 0) {
-                       dev_err(adapter->dev, "cannot find ssid %s\n",
-                                       ssid_bssid->ssid.ssid);
-                       return -1;
-               }
-               bss_desc = &adapter->scan_table[i];
-               memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN);
-       } else {
-               return mwifiex_find_best_network(priv, ssid_bssid);
-       }
-
-       return 0;
-}
-
 /*
  * IOCTL request handler to change Ad-Hoc channel.
  *
@@ -653,6 +649,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
        struct mwifiex_bss_info bss_info;
        struct mwifiex_ssid_bssid ssid_bssid;
        u16 curr_chan = 0;
+       struct cfg80211_bss *bss = NULL;
+       struct ieee80211_channel *chan;
 
        memset(&bss_info, 0, sizeof(bss_info));
 
@@ -688,12 +686,20 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
                ret = -1;
                goto done;
        }
-       /* Start/Join Adhoc network */
-       memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
-       memcpy(&ssid_bssid.ssid, &bss_info.ssid,
-              sizeof(struct mwifiex_802_11_ssid));
 
-       ret = mwifiex_bss_start(priv, &ssid_bssid);
+       chan = __ieee80211_get_channel(priv->wdev->wiphy,
+                       ieee80211_channel_to_frequency(channel,
+                                               priv->curr_bss_params.band));
+
+       /* Find the BSS we want using available scan results */
+       bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid,
+                              bss_info.ssid.ssid, bss_info.ssid.ssid_len,
+                              WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+       if (!bss)
+               wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n",
+                         bss_info.bssid);
+
+       ret = mwifiex_bss_start(priv, bss, &bss_info.ssid);
 done:
        return ret;
 }
@@ -1280,9 +1286,9 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
 
        if (!status) {
                if (signal->selector & BCN_RSSI_AVG_MASK)
-                       priv->w_stats.qual.level = signal->bcn_rssi_avg;
+                       priv->qual_level = signal->bcn_rssi_avg;
                if (signal->selector & BCN_NF_AVG_MASK)
-                       priv->w_stats.qual.noise = signal->bcn_nf_avg;
+                       priv->qual_noise = signal->bcn_nf_avg;
        }
 
        return status;
@@ -1341,18 +1347,8 @@ int
 mwifiex_get_stats_info(struct mwifiex_private *priv,
                       struct mwifiex_ds_get_stats *log)
 {
-       int ret;
-
-       ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
+       return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
                                    HostCmd_ACT_GEN_GET, 0, log);
-
-       if (!ret) {
-               priv->w_stats.discard.fragment = log->fcs_error;
-               priv->w_stats.discard.retries = log->retry;
-               priv->w_stats.discard.misc = log->ack_failure;
-       }
-
-       return ret;
 }
 
 /*
@@ -1594,7 +1590,7 @@ mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
 {
        struct mwifiex_ds_misc_gen_ie gen_ie;
 
-       if (ie_len > IW_CUSTOM_MAX)
+       if (ie_len > IEEE_MAX_IE_SIZE)
                return -EFAULT;
 
        gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE;
index da36dbf8d87118e51b2c94946b2fddfea043baca..771280a47ea7c66da2f1d74fa2fb92e4c4a9fe46 100644 (file)
@@ -4097,9 +4097,6 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
 
                if (rc)
                        goto out;
-
-               mwl8k_vif->is_hw_crypto_enabled = false;
-
        }
 out:
        return rc;
index ef7efe839bb88fe1751635574de52c24a24e2c3a..b52acc4b408630967ac5a6469e6a9efe1f3d47dd 100644 (file)
@@ -2135,7 +2135,7 @@ static const struct net_device_ops orinoco_netdev_ops = {
        .ndo_open               = orinoco_open,
        .ndo_stop               = orinoco_stop,
        .ndo_start_xmit         = orinoco_xmit,
-       .ndo_set_multicast_list = orinoco_set_multicast_list,
+       .ndo_set_rx_mode        = orinoco_set_multicast_list,
        .ndo_change_mtu         = orinoco_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
index 811e87f8a349db7194a4ba8786c9de98a5618ebe..0793e4265b4334e69507e38f9ababa1e9e72d8db 100644 (file)
@@ -1562,7 +1562,7 @@ static const struct net_device_ops ezusb_netdev_ops = {
        .ndo_open               = orinoco_open,
        .ndo_stop               = orinoco_stop,
        .ndo_start_xmit         = ezusb_xmit,
-       .ndo_set_multicast_list = orinoco_set_multicast_list,
+       .ndo_set_rx_mode        = orinoco_set_multicast_list,
        .ndo_change_mtu         = orinoco_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
index bbb9beb206b1b9e8e590fa28c9d0e1dacca39670..33747e131a968e19f409de68e4edc92b6b2063e5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/ieee80211.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
+#include <net/cfg80211-wext.h>
 
 #include "hermes.h"
 #include "hermes_rid.h"
index 2a06ebcd67c5cd1f24beba30df18de1d79cc3c12..0021e49485128b08d95344b47ee047b706c76cdd 100644 (file)
@@ -273,7 +273,7 @@ static const struct net_device_ops ray_netdev_ops = {
        .ndo_start_xmit         = ray_dev_start_xmit,
        .ndo_set_config         = ray_dev_config,
        .ndo_get_stats          = ray_get_stats,
-       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_set_rx_mode        = set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
index 29f938930667d3696efd82f5d45fc9c98c15ac39..0c13840a7de57c0d675e026267a3ca3b95edc9fa 100644 (file)
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
-#include <linux/wireless.h>
 #include <linux/ieee80211.h>
 #include <linux/if_arp.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <net/iw_handler.h>
 #include <net/cfg80211.h>
 #include <linux/usb/usbnet.h>
 #include <linux/usb/rndis_host.h>
@@ -3392,7 +3390,7 @@ static const struct net_device_ops rndis_wlan_netdev_ops = {
        .ndo_tx_timeout         = usbnet_tx_timeout,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = rndis_wlan_set_multicast_list,
+       .ndo_set_rx_mode        = rndis_wlan_set_multicast_list,
 };
 
 static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
index 76bcc3547976703842747ae4369d47bf734da3f1..daa32fc9398bb7712886b4707fbd6f1096162680 100644 (file)
@@ -645,11 +645,6 @@ static void rt2400pci_start_queue(struct data_queue *queue)
                rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
                break;
        case QID_BEACON:
-               /*
-                * Allow the tbtt tasklet to be scheduled.
-                */
-               tasklet_enable(&rt2x00dev->tbtt_tasklet);
-
                rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
                rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
                rt2x00_set_field32(&reg, CSR14_TBCN, 1);
@@ -715,7 +710,7 @@ static void rt2400pci_stop_queue(struct data_queue *queue)
                /*
                 * Wait for possibly running tbtt tasklets.
                 */
-               tasklet_disable(&rt2x00dev->tbtt_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
                break;
        default:
                break;
@@ -982,12 +977,6 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_RADIO_IRQ_ON) {
                rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
                rt2x00pci_register_write(rt2x00dev, CSR7, reg);
-
-               /*
-                * Enable tasklets.
-                */
-               tasklet_enable(&rt2x00dev->txstatus_tasklet);
-               tasklet_enable(&rt2x00dev->rxdone_tasklet);
        }
 
        /*
@@ -1011,8 +1000,9 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
                 * Ensure that all tasklets are finished before
                 * disabling the interrupts.
                 */
-               tasklet_disable(&rt2x00dev->txstatus_tasklet);
-               tasklet_disable(&rt2x00dev->rxdone_tasklet);
+               tasklet_kill(&rt2x00dev->txstatus_tasklet);
+               tasklet_kill(&rt2x00dev->rxdone_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
        }
 }
 
@@ -1347,22 +1337,25 @@ static void rt2400pci_txstatus_tasklet(unsigned long data)
        /*
         * Enable all TXDONE interrupts again.
         */
-       spin_lock_irq(&rt2x00dev->irqmask_lock);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
+               spin_lock_irq(&rt2x00dev->irqmask_lock);
 
-       rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
-       rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
-       rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
-       rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
-       rt2x00pci_register_write(rt2x00dev, CSR8, reg);
+               rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
+               rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
+               rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
+               rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
+               rt2x00pci_register_write(rt2x00dev, CSR8, reg);
 
-       spin_unlock_irq(&rt2x00dev->irqmask_lock);
+               spin_unlock_irq(&rt2x00dev->irqmask_lock);
+       }
 }
 
 static void rt2400pci_tbtt_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt2x00lib_beacondone(rt2x00dev);
-       rt2400pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2400pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
 }
 
 static void rt2400pci_rxdone_tasklet(unsigned long data)
@@ -1370,7 +1363,7 @@ static void rt2400pci_rxdone_tasklet(unsigned long data)
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        if (rt2x00pci_rxdone(rt2x00dev))
                tasklet_schedule(&rt2x00dev->rxdone_tasklet);
-       else
+       else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
 }
 
index c288d951c03433f15196d7dd708f78d8c973d351..b46c3b8866fa99b29f582ba016a0cf6377065c51 100644 (file)
@@ -735,11 +735,6 @@ static void rt2500pci_start_queue(struct data_queue *queue)
                rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
                break;
        case QID_BEACON:
-               /*
-                * Allow the tbtt tasklet to be scheduled.
-                */
-               tasklet_enable(&rt2x00dev->tbtt_tasklet);
-
                rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
                rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
                rt2x00_set_field32(&reg, CSR14_TBCN, 1);
@@ -805,7 +800,7 @@ static void rt2500pci_stop_queue(struct data_queue *queue)
                /*
                 * Wait for possibly running tbtt tasklets.
                 */
-               tasklet_disable(&rt2x00dev->tbtt_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
                break;
        default:
                break;
@@ -1137,12 +1132,6 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_RADIO_IRQ_ON) {
                rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
                rt2x00pci_register_write(rt2x00dev, CSR7, reg);
-
-               /*
-                * Enable tasklets.
-                */
-               tasklet_enable(&rt2x00dev->txstatus_tasklet);
-               tasklet_enable(&rt2x00dev->rxdone_tasklet);
        }
 
        /*
@@ -1165,8 +1154,9 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
                /*
                 * Ensure that all tasklets are finished.
                 */
-               tasklet_disable(&rt2x00dev->txstatus_tasklet);
-               tasklet_disable(&rt2x00dev->rxdone_tasklet);
+               tasklet_kill(&rt2x00dev->txstatus_tasklet);
+               tasklet_kill(&rt2x00dev->rxdone_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
        }
 }
 
@@ -1479,22 +1469,25 @@ static void rt2500pci_txstatus_tasklet(unsigned long data)
        /*
         * Enable all TXDONE interrupts again.
         */
-       spin_lock_irq(&rt2x00dev->irqmask_lock);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
+               spin_lock_irq(&rt2x00dev->irqmask_lock);
 
-       rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
-       rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
-       rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
-       rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
-       rt2x00pci_register_write(rt2x00dev, CSR8, reg);
+               rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
+               rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
+               rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
+               rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
+               rt2x00pci_register_write(rt2x00dev, CSR8, reg);
 
-       spin_unlock_irq(&rt2x00dev->irqmask_lock);
+               spin_unlock_irq(&rt2x00dev->irqmask_lock);
+       }
 }
 
 static void rt2500pci_tbtt_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt2x00lib_beacondone(rt2x00dev);
-       rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
 }
 
 static void rt2500pci_rxdone_tasklet(unsigned long data)
@@ -1502,7 +1495,7 @@ static void rt2500pci_rxdone_tasklet(unsigned long data)
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        if (rt2x00pci_rxdone(rt2x00dev))
                tasklet_schedule(&rt2x00dev->rxdone_tasklet);
-       else
+       else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
 }
 
index ebc17ad61dec4612d0bbe872588c4f0e751d4fb4..cabf249aa55b7e4b957a206d8d14faee816c1fa2 100644 (file)
@@ -200,13 +200,6 @@ static void rt2800pci_start_queue(struct data_queue *queue)
                rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
                break;
        case QID_BEACON:
-               /*
-                * Allow beacon tasklets to be scheduled for periodic
-                * beacon updates.
-                */
-               tasklet_enable(&rt2x00dev->tbtt_tasklet);
-               tasklet_enable(&rt2x00dev->pretbtt_tasklet);
-
                rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
                rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
                rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
@@ -269,10 +262,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
                rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg);
 
                /*
-                * Wait for tbtt tasklets to finish.
+                * Wait for current invocation to finish. The tasklet
+                * won't be scheduled anymore afterwards since we disabled
+                * the TBTT and PRE TBTT timer.
                 */
-               tasklet_disable(&rt2x00dev->tbtt_tasklet);
-               tasklet_disable(&rt2x00dev->pretbtt_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
+               tasklet_kill(&rt2x00dev->pretbtt_tasklet);
+
                break;
        default:
                break;
@@ -437,14 +433,6 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_RADIO_IRQ_ON) {
                rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
                rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
-
-               /*
-                * Enable tasklets. The beacon related tasklets are
-                * enabled when the beacon queue is started.
-                */
-               tasklet_enable(&rt2x00dev->txstatus_tasklet);
-               tasklet_enable(&rt2x00dev->rxdone_tasklet);
-               tasklet_enable(&rt2x00dev->autowake_tasklet);
        }
 
        spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
@@ -472,12 +460,13 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
 
        if (state == STATE_RADIO_IRQ_OFF) {
                /*
-                * Ensure that all tasklets are finished before
-                * disabling the interrupts.
+                * Wait for possibly running tasklets to finish.
                 */
-               tasklet_disable(&rt2x00dev->txstatus_tasklet);
-               tasklet_disable(&rt2x00dev->rxdone_tasklet);
-               tasklet_disable(&rt2x00dev->autowake_tasklet);
+               tasklet_kill(&rt2x00dev->txstatus_tasklet);
+               tasklet_kill(&rt2x00dev->rxdone_tasklet);
+               tasklet_kill(&rt2x00dev->autowake_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
+               tasklet_kill(&rt2x00dev->pretbtt_tasklet);
        }
 }
 
@@ -813,14 +802,16 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt2x00lib_pretbtt(rt2x00dev);
-       rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT);
 }
 
 static void rt2800pci_tbtt_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt2x00lib_beacondone(rt2x00dev);
-       rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT);
 }
 
 static void rt2800pci_rxdone_tasklet(unsigned long data)
@@ -828,7 +819,7 @@ static void rt2800pci_rxdone_tasklet(unsigned long data)
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        if (rt2x00pci_rxdone(rt2x00dev))
                tasklet_schedule(&rt2x00dev->rxdone_tasklet);
-       else
+       else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
 }
 
@@ -836,7 +827,8 @@ static void rt2800pci_autowake_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt2800pci_wakeup(rt2x00dev);
-       rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_AUTO_WAKEUP);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_AUTO_WAKEUP);
 }
 
 static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
index 939563162fb3dce4a2ad731b3c4a48296a4774e3..dbf501ca317f51cac690b87a0edb7f8a84145353 100644 (file)
@@ -464,6 +464,15 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
        int wcid, ack, pid;
        int tx_wcid, tx_ack, tx_pid;
 
+       if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+           !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) {
+               WARNING(entry->queue->rt2x00dev,
+                       "Data pending for entry %u in queue %u\n",
+                       entry->entry_idx, entry->queue->qid);
+               cond_resched();
+               return false;
+       }
+
        wcid    = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
        ack     = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
        pid     = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
@@ -529,12 +538,11 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
                        entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
                        if (rt2800usb_txdone_entry_check(entry, reg))
                                break;
+                       entry = NULL;
                }
 
-               if (!entry || rt2x00queue_empty(queue))
-                       break;
-
-               rt2800_txdone_entry(entry, reg);
+               if (entry)
+                       rt2800_txdone_entry(entry, reg);
        }
 }
 
@@ -558,8 +566,10 @@ static void rt2800usb_work_txdone(struct work_struct *work)
                while (!rt2x00queue_empty(queue)) {
                        entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 
-                       if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+                       if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+                           !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
                                break;
+
                        if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
                                rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
                        else if (rt2x00queue_status_timeout(entry))
index 0955c941317fd7d7ff049b18ade0a3be8c3bd89f..92ff6a72a2bb422771c85788cda715ed797068c2 100644 (file)
@@ -946,7 +946,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
                tasklet_init(&rt2x00dev->taskletname, \
                             rt2x00dev->ops->lib->taskletname, \
                             (unsigned long)rt2x00dev); \
-               tasklet_disable(&rt2x00dev->taskletname); \
        }
 
        RT2X00_TASKLET_INIT(txstatus_tasklet);
index b6b4542c2460e6539de067048270385fba345d85..1e31050dafc9e9b2ea2a59073137de053e48074b 100644 (file)
@@ -262,23 +262,20 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
        struct queue_entry *entry = (struct queue_entry *)urb->context;
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 
-       if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+       if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
                return;
-
-       if (rt2x00dev->ops->lib->tx_dma_done)
-               rt2x00dev->ops->lib->tx_dma_done(entry);
-
-       /*
-        * Report the frame as DMA done
-        */
-       rt2x00lib_dmadone(entry);
-
        /*
         * Check if the frame was correctly uploaded
         */
        if (urb->status)
                set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
+       /*
+        * Report the frame as DMA done
+        */
+       rt2x00lib_dmadone(entry);
 
+       if (rt2x00dev->ops->lib->tx_dma_done)
+               rt2x00dev->ops->lib->tx_dma_done(entry);
        /*
         * Schedule the delayed work for reading the TX status
         * from the device.
@@ -874,18 +871,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
 {
        struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       int retval;
-
-       retval = rt2x00lib_suspend(rt2x00dev, state);
-       if (retval)
-               return retval;
 
-       /*
-        * Decrease usbdev refcount.
-        */
-       usb_put_dev(interface_to_usbdev(usb_intf));
-
-       return 0;
+       return rt2x00lib_suspend(rt2x00dev, state);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_suspend);
 
@@ -894,8 +881,6 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)
        struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
        struct rt2x00_dev *rt2x00dev = hw->priv;
 
-       usb_get_dev(interface_to_usbdev(usb_intf));
-
        return rt2x00lib_resume(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_resume);
index 53110b83bf6e47a2ff172b03c90db0cab81f5c4c..058ef4b19d1db54896567da65901c2a4ad91ab27 100644 (file)
@@ -1142,11 +1142,6 @@ static void rt61pci_start_queue(struct data_queue *queue)
                rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
                break;
        case QID_BEACON:
-               /*
-                * Allow the tbtt tasklet to be scheduled.
-                */
-               tasklet_enable(&rt2x00dev->tbtt_tasklet);
-
                rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
                rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
                rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
@@ -1230,7 +1225,7 @@ static void rt61pci_stop_queue(struct data_queue *queue)
                /*
                 * Wait for possibly running tbtt tasklets.
                 */
-               tasklet_disable(&rt2x00dev->tbtt_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
                break;
        default:
                break;
@@ -1731,13 +1726,6 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
 
                rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, &reg);
                rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg);
-
-               /*
-                * Enable tasklets.
-                */
-               tasklet_enable(&rt2x00dev->txstatus_tasklet);
-               tasklet_enable(&rt2x00dev->rxdone_tasklet);
-               tasklet_enable(&rt2x00dev->autowake_tasklet);
        }
 
        /*
@@ -1772,9 +1760,10 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
                /*
                 * Ensure that all tasklets are finished.
                 */
-               tasklet_disable(&rt2x00dev->txstatus_tasklet);
-               tasklet_disable(&rt2x00dev->rxdone_tasklet);
-               tasklet_disable(&rt2x00dev->autowake_tasklet);
+               tasklet_kill(&rt2x00dev->txstatus_tasklet);
+               tasklet_kill(&rt2x00dev->rxdone_tasklet);
+               tasklet_kill(&rt2x00dev->autowake_tasklet);
+               tasklet_kill(&rt2x00dev->tbtt_tasklet);
        }
 }
 
@@ -2300,22 +2289,24 @@ static void rt61pci_txstatus_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt61pci_txdone(rt2x00dev);
-       rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TXDONE);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TXDONE);
 }
 
 static void rt61pci_tbtt_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        rt2x00lib_beacondone(rt2x00dev);
-       rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_BEACON_DONE);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_BEACON_DONE);
 }
 
 static void rt61pci_rxdone_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
        if (rt2x00pci_rxdone(rt2x00dev))
-               rt2x00pci_rxdone(rt2x00dev);
-       else
+               tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+       else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
 }
 
@@ -2325,7 +2316,8 @@ static void rt61pci_autowake_tasklet(unsigned long data)
        rt61pci_wakeup(rt2x00dev);
        rt2x00pci_register_write(rt2x00dev,
                                 M2H_CMD_DONE_CSR, 0xffffffff);
-       rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP);
+       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP);
 }
 
 static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
index 5fa73852cb661b73274bd8e86e718a5ff92c80ba..b2f897acb23857836aee851f83b154e9e5a0e548 100644 (file)
 
 #include "wifi.h"
 
+static unsigned int debug = DBG_EMERG;
+module_param(debug, uint, 0);
+MODULE_PARM_DESC(debug, "Set global debug level for rtlwifi (0,2-5)");
+
 void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u8 i;
 
-       rtlpriv->dbg.global_debuglevel = DBG_EMERG;
+       rtlpriv->dbg.global_debuglevel = debug;
 
        rtlpriv->dbg.global_debugcomponents =
            COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
index 56f12358389d8614ba9167ad23239808cc489905..9983fa18065a679f3550031e8ee13d671fdbfcb1 100644 (file)
@@ -218,7 +218,6 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
-       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
        u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
        /*Retrieve original configuration settings. */
        u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
@@ -254,9 +253,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
        udelay(50);
 
        /*4 Disable Pci Bridge ASPM */
-       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-                                    pcicfg_addrport + (num4bytes << 2));
-       rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
+       pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
+                             pcibridge_linkctrlreg);
 
        udelay(50);
 }
@@ -277,7 +275,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
        u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum;
        u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum;
        u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
-       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
        u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
        u16 aspmlevel;
        u8 u_pcibridge_aspmsetting;
@@ -293,8 +290,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
        }
 
        /*4 Enable Pci Bridge ASPM */
-       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-                                    pcicfg_addrport + (num4bytes << 2));
 
        u_pcibridge_aspmsetting =
            pcipriv->ndis_adapter.pcibridge_linkctrlreg |
@@ -303,7 +298,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
        if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
                u_pcibridge_aspmsetting &= ~BIT(0);
 
-       rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting);
+       pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
+                             u_pcibridge_aspmsetting);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
                 ("PlatformEnableASPM():PciBridge busnumber[%x], "
@@ -335,25 +331,18 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
 
 static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
 {
-       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
-       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
        bool status = false;
        u8 offset_e0;
        unsigned offset_e4;
 
-       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-                       pcicfg_addrport + 0xE0);
-       rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, 0xA0);
+       pci_write_config_byte(rtlpci->pdev, 0xe0, 0xa0);
 
-       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-                       pcicfg_addrport + 0xE0);
-       rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &offset_e0);
+       pci_read_config_byte(rtlpci->pdev, 0xe0, &offset_e0);
 
        if (offset_e0 == 0xA0) {
-               rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-                                            pcicfg_addrport + 0xE4);
-               rtl_pci_raw_read_port_ulong(PCI_CONF_DATA, &offset_e4);
+               pci_read_config_dword(rtlpci->pdev, 0xe4, &offset_e4);
                if (offset_e4 & BIT(23))
                        status = true;
        }
@@ -364,17 +353,15 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
 static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
 {
        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
        u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
-       u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
        u8 linkctrl_reg;
        u8 num4bbytes;
 
        num4bbytes = (capabilityoffset + 0x10) / 4;
 
        /*Read  Link Control Register */
-       rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-                                    pcicfg_addrport + (num4bbytes << 2));
-       rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
+       pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg);
 
        pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
 }
@@ -1718,10 +1705,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
                    PCI_SLOT(bridge_pdev->devfn);
                pcipriv->ndis_adapter.pcibridge_funcnum =
                    PCI_FUNC(bridge_pdev->devfn);
-               pcipriv->ndis_adapter.pcicfg_addrport =
-                   (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
-                   (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
-                   (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
                pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
                    pci_pcie_cap(bridge_pdev);
                pcipriv->ndis_adapter.num4bytes =
index c53c620467479d70251d04ea98676d9329e2e34a..a24e505b202bb0f5a4fb61d6db622e9e7aa92ae8 100644 (file)
@@ -212,7 +212,6 @@ struct mp_adapter {
        u16 pcibridge_vendorid;
        u16 pcibridge_deviceid;
 
-       u32 pcicfg_addrport;
        u8 num4bytes;
 
        u8 pcibridge_pciehdr_offset;
@@ -273,29 +272,4 @@ static inline void pci_write32_async(struct rtl_priv *rtlpriv,
        writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
-static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
-{
-       outl(val, port);
-}
-
-static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
-{
-       outb(val, port);
-}
-
-static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval)
-{
-       *pval = inb(port);
-}
-
-static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval)
-{
-       *pval = inw(port);
-}
-
-static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval)
-{
-       *pval = inl(port);
-}
-
 #endif
index 79ca5273c9e9092ed1892064974cdde2549f781b..ee4f2b391822ac7b58da04e5c6fa6e52daef0813 100644 (file)
@@ -269,7 +269,7 @@ struct cmd_join {
        u8 bss_type;
        u8 channel;
        u8 ssid_len;
-       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 ctrl; /* JOIN_CMD_CTRL_* */
        u8 tx_mgt_frame_rate; /* OBSOLETE */
        u8 tx_mgt_frame_mod;  /* OBSOLETE */
index 1417b1445c3d0cbe3435583e082c644a276846db..04ed514957728540031024893a07bc2e3ecb3fb0 100644 (file)
@@ -76,7 +76,7 @@ struct wl12xx_ie_header {
 
 struct wl12xx_ie_ssid {
        struct wl12xx_ie_header header;
-       char ssid[IW_ESSID_MAX_SIZE];
+       char ssid[IEEE80211_MAX_SSID_LEN];
 } __packed;
 
 struct wl12xx_ie_rates {
index 7e33f1f4f3d47c7866baac5af76b656111139d2b..34f6ab53e51960b097f709b9546c0273aa9f47a5 100644 (file)
@@ -77,8 +77,6 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
        auth->sleep_auth = sleep_auth;
 
        ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
-       if (ret < 0)
-               return ret;
 
 out:
        kfree(auth);
@@ -624,10 +622,8 @@ int wl1271_acx_cca_threshold(struct wl1271 *wl)
 
        ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
                                   detection, sizeof(*detection));
-       if (ret < 0) {
+       if (ret < 0)
                wl1271_warning("failed to set cca threshold: %d", ret);
-               return ret;
-       }
 
 out:
        kfree(detection);
index 1f7037292c15785b50e033f75d2ede5cad77adb4..bba077ecd945f2bb0629752ec38364c162c6381c 100644 (file)
@@ -239,7 +239,7 @@ struct wl1271_cmd_join {
        u8 bss_type;
        u8 channel;
        u8 ssid_len;
-       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 ctrl; /* JOIN_CMD_CTRL_* */
        u8 reserved[3];
 } __packed;
@@ -528,7 +528,7 @@ struct wl1271_cmd_bss_start {
        /* wl1271_ssid_type */
        u8 ssid_type;
        u8 ssid_len;
-       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 padding_1[2];
 
        /* Basic rate set */
index e58c22d21e39af9d8683ff94e1ccee929258902c..2da42baef7d29f98fac17ec5399b5af3e2f3c3a2 100644 (file)
@@ -1997,7 +1997,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
        wl1271_power_off(wl);
 
        memset(wl->bssid, 0, ETH_ALEN);
-       memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
+       memset(wl->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
        wl->ssid_len = 0;
        wl->bss_type = MAX_BSS_TYPE;
        wl->set_bss_type = MAX_BSS_TYPE;
@@ -4283,6 +4283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
        wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
        wl->hw->wiphy->max_scan_ssids = 1;
+       wl->hw->wiphy->max_sched_scan_ssids = 1;
        /*
         * Maximum length of elements in scanning probe request templates
         * should be the maximum length possible for a template, without
index d882e4da71b705e87a0b47af18969239ac1f87f7..0b2a2987439d40afce9c4a69ba12c9d95e745184 100644 (file)
@@ -77,7 +77,7 @@ struct basic_scan_params {
        u8 ssid_len;
        /* in order to align */
        u8 padding1[2];
-       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
        /* Band to scan */
        u8 band;
        u8 use_ssid_list;
@@ -167,7 +167,7 @@ struct wl1271_cmd_sched_scan_config {
        u8 filter_type;
 
        u8 ssid_len;     /* For SCAN_SSID_FILTER_SPECIFIC */
-       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
 
        u8 n_probe_reqs; /* Number of probes requests per channel */
 
@@ -194,7 +194,7 @@ enum {
 struct wl1271_ssid {
        u8 type;
        u8 len;
-       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
        /* u8 padding[2]; */
 } __packed;
 
index 5cf18c2c23f09ee3fdd35a3aceafc322f3770580..fb1fd5af75ea562c47120067d88b8f9540e7b805 100644 (file)
@@ -164,7 +164,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl)
        /* If enabled, tell runtime PM not to power off the card */
        if (pm_runtime_enabled(&func->dev)) {
                ret = pm_runtime_get_sync(&func->dev);
-               if (ret)
+               if (ret < 0)
                        goto out;
        } else {
                /* Runtime PM is disabled: power up the card manually */
index 5d5e1ef87206a4e1722510084ba4cab2783cf0bd..4ae8effaee22828acf9565d47d9ad599f4ac9c00 100644 (file)
@@ -36,7 +36,6 @@ enum wl1271_tm_commands {
        WL1271_TM_CMD_TEST,
        WL1271_TM_CMD_INTERROGATE,
        WL1271_TM_CMD_CONFIGURE,
-       WL1271_TM_CMD_NVS_PUSH,
        WL1271_TM_CMD_SET_PLT_MODE,
        WL1271_TM_CMD_RECOVER,
 
@@ -139,12 +138,15 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
 
        if (ret < 0) {
                wl1271_warning("testmode cmd interrogate failed: %d", ret);
+               kfree(cmd);
                return ret;
        }
 
        skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd));
-       if (!skb)
+       if (!skb) {
+               kfree(cmd);
                return -ENOMEM;
+       }
 
        NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);
 
@@ -187,48 +189,6 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])
        return 0;
 }
 
-static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
-{
-       int ret = 0;
-       size_t len;
-       void *buf;
-
-       wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push");
-
-       if (!tb[WL1271_TM_ATTR_DATA])
-               return -EINVAL;
-
-       buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
-       len = nla_len(tb[WL1271_TM_ATTR_DATA]);
-
-       mutex_lock(&wl->mutex);
-
-       kfree(wl->nvs);
-
-       if ((wl->chip.id == CHIP_ID_1283_PG20) &&
-           (len != sizeof(struct wl128x_nvs_file)))
-               return -EINVAL;
-       else if (len != sizeof(struct wl1271_nvs_file))
-               return -EINVAL;
-
-       wl->nvs = kzalloc(len, GFP_KERNEL);
-       if (!wl->nvs) {
-               wl1271_error("could not allocate memory for the nvs file");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       memcpy(wl->nvs, buf, len);
-       wl->nvs_len = len;
-
-       wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
-
-out:
-       mutex_unlock(&wl->mutex);
-
-       return ret;
-}
-
 static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
 {
        u32 val;
@@ -285,8 +245,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
                return wl1271_tm_cmd_interrogate(wl, tb);
        case WL1271_TM_CMD_CONFIGURE:
                return wl1271_tm_cmd_configure(wl, tb);
-       case WL1271_TM_CMD_NVS_PUSH:
-               return wl1271_tm_cmd_nvs_push(wl, tb);
        case WL1271_TM_CMD_SET_PLT_MODE:
                return wl1271_tm_cmd_set_plt_mode(wl, tb);
        case WL1271_TM_CMD_RECOVER:
index 1a8751eb8140213d962e01ee467d2de900f1feb3..0bc29356ebe4a9651b7824d98c27100e97f4060a 100644 (file)
@@ -309,7 +309,7 @@ struct wl1271_scan {
        unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)];
        bool failed;
        u8 state;
-       u8 ssid[IW_ESSID_MAX_SIZE+1];
+       u8 ssid[IEEE80211_MAX_SSID_LEN+1];
        size_t ssid_len;
 };
 
@@ -415,7 +415,7 @@ struct wl1271 {
        u8 mac_addr[ETH_ALEN];
        u8 bss_type;
        u8 set_bss_type;
-       u8 ssid[IW_ESSID_MAX_SIZE + 1];
+       u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
        u8 ssid_len;
        int channel;
 
index 18fe542360f22e5945243d6f52bb95b8917ed2c7..f334ea0817229adc07f39a8bdd37990d2e669894 100644 (file)
@@ -77,7 +77,7 @@ struct wl12xx_ie_header {
 
 struct wl12xx_ie_ssid {
        struct wl12xx_ie_header header;
-       char ssid[IW_ESSID_MAX_SIZE];
+       char ssid[IEEE80211_MAX_SSID_LEN];
 } __packed;
 
 struct wl12xx_ie_rates {
index 415eec401e2e5aa55be1f4f688f90ef7f50785a2..8efa2f2d95797488f189de5a6d433ffe2e8fa3bc 100644 (file)
@@ -1722,7 +1722,7 @@ static const struct net_device_ops zd1201_netdev_ops = {
        .ndo_stop               = zd1201_net_stop,
        .ndo_start_xmit         = zd1201_hard_start_xmit,
        .ndo_tx_timeout         = zd1201_tx_timeout,
-       .ndo_set_multicast_list = zd1201_set_multicast,
+       .ndo_set_rx_mode        = zd1201_set_multicast,
        .ndo_set_mac_address    = zd1201_set_mac_address,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
index 6fa215a38615df05fa40549ce9354daaf7c0ce67..f78ef5bd7b76942189215d6f3dcf2158989c2ac5 100644 (file)
@@ -401,8 +401,8 @@ static int pcifront_claim_resource(struct pci_dev *dev, void *data)
                                pci_name(dev), i);
                        if (pci_claim_resource(dev, i)) {
                                dev_err(&pdev->xdev->dev, "Could not claim "
-                                       "resource %s/%d! Device offline. Try "
-                                       "giving less than 4GB to domain.\n",
+                                       "resource %s/%d! Device offline. Try"
+                                       "using e820_host=1 in the guest config.\n",
                                        pci_name(dev), i);
                        }
                }
index e956f659089a2c1b91716a7bccdf68f425837131..66ab92cf3105ca4db179f34868bd1416df9a8b04 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <asm/mach-types.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <mach/vpac270.h>
 
 #include "soc_common.h"
index 7bd829f247eb5ae98fa3b2c61914d16cf554a941..34f167edcc5567e39e871757791e85993eb34c1b 100644 (file)
@@ -2456,8 +2456,9 @@ static int hotkey_kthread(void *data)
        u32 poll_mask, event_mask;
        unsigned int si, so;
        unsigned long t;
-       unsigned int change_detector, must_reset;
+       unsigned int change_detector;
        unsigned int poll_freq;
+       bool was_frozen;
 
        mutex_lock(&hotkey_thread_mutex);
 
@@ -2488,14 +2489,14 @@ static int hotkey_kthread(void *data)
                                t = 100;        /* should never happen... */
                }
                t = msleep_interruptible(t);
-               if (unlikely(kthread_should_stop()))
+               if (unlikely(kthread_freezable_should_stop(&was_frozen)))
                        break;
-               must_reset = try_to_freeze();
-               if (t > 0 && !must_reset)
+
+               if (t > 0 && !was_frozen)
                        continue;
 
                mutex_lock(&hotkey_thread_data_mutex);
-               if (must_reset || hotkey_config_change != change_detector) {
+               if (was_frozen || hotkey_config_change != change_detector) {
                        /* forget old state on thaw or config change */
                        si = so;
                        t = 0;
@@ -2528,10 +2529,6 @@ exit:
 static void hotkey_poll_stop_sync(void)
 {
        if (tpacpi_hotkey_task) {
-               if (frozen(tpacpi_hotkey_task) ||
-                   freezing(tpacpi_hotkey_task))
-                       thaw_process(tpacpi_hotkey_task);
-
                kthread_stop(tpacpi_hotkey_task);
                tpacpi_hotkey_task = NULL;
                mutex_lock(&hotkey_thread_mutex);
index 1fefe82e12e3b94f59add3abb7af9db44047f1a8..ed25ef5887d47c381812c88bb51d16ae49c8e596 100644 (file)
@@ -832,7 +832,7 @@ static struct platform_driver ds2780_battery_driver = {
                .name = "ds2780-battery",
        },
        .probe    = ds2780_battery_probe,
-       .remove   = ds2780_battery_remove,
+       .remove   = __devexit_p(ds2780_battery_remove),
 };
 
 static int __init ds2780_battery_init(void)
index 98bfab35b8e99ab4c020e9dad91b8f6475b79ac2..a6dc9c7a95e2e7a099c0dfcbc9d68bbc8d0603c4 100644 (file)
@@ -111,12 +111,12 @@ static int max17042_get_property(struct power_supply *psy,
                val->intval *= 10000; /* Units of LSB = 10mV */
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-               val->intval = max17042_read_reg(chip->client,
-                               MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */
+               val->intval = max17042_read_reg(chip->client, MAX17042_VCELL)
+                           * 625 / 8;
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_AVG:
-               val->intval = max17042_read_reg(chip->client,
-                               MAX17042_AvgVCELL) * 83;
+               val->intval = max17042_read_reg(chip->client, MAX17042_AvgVCELL)
+                           * 625 / 8;
                break;
        case POWER_SUPPLY_PROP_CAPACITY:
                val->intval = max17042_read_reg(chip->client,
@@ -152,8 +152,7 @@ static int max17042_get_property(struct power_supply *psy,
                                val->intval++;
                                val->intval *= -1;
                        }
-                       val->intval >>= 4;
-                       val->intval *= 1000000 * 25 / chip->pdata->r_sns;
+                       val->intval *= 1562500 / chip->pdata->r_sns;
                } else {
                        return -EINVAL;
                }
@@ -209,6 +208,9 @@ static int __devinit max17042_probe(struct i2c_client *client,
        if (!chip->pdata->enable_current_sense)
                chip->battery.num_properties -= 2;
 
+       if (chip->pdata->r_sns == 0)
+               chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
+
        ret = power_supply_register(&client->dev, &chip->battery);
        if (ret) {
                dev_err(&client->dev, "failed: power supply register\n");
@@ -225,9 +227,6 @@ static int __devinit max17042_probe(struct i2c_client *client,
                max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
                max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
                max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
-       } else {
-               if (chip->pdata->r_sns == 0)
-                       chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
        }
 
        return 0;
index a9b0209a2f55042a572fc18b2d34b2cee979ad78..3c030c9052785875ec014262e185b0b300e401cf 100644 (file)
@@ -388,4 +388,4 @@ module_exit(max8903_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("MAX8903 Charger Driver");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
-MODULE_ALIAS("max8903-charger");
+MODULE_ALIAS("platform:max8903-charger");
index 7106b49b26e492dbea1bbdd888e46c95844ad0ed..e12b4a2a0be2a621899f7e23b970fb951a705544 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
@@ -177,6 +178,7 @@ static int __devexit max8997_battery_remove(struct platform_device *pdev)
 
 static const struct platform_device_id max8997_battery_id[] = {
        { "max8997-battery", 0 },
+       { }
 };
 
 static struct platform_driver max8997_battery_driver = {
index cc21fa2120be241e18f49de15805280fde97d077..6f5ffc3e2f03676828b0ce79ab9002e79e35da27 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
@@ -152,6 +153,7 @@ static __devinit int max8998_battery_probe(struct platform_device *pdev)
        case 0:
                dev_dbg(max8998->dev,
                        "Full Timeout not set: leave it unchanged.\n");
+               break;
        default:
                dev_err(max8998->dev, "Invalid Full Timeout value\n");
                ret = -EINVAL;
@@ -188,6 +190,7 @@ static int __devexit max8998_battery_remove(struct platform_device *pdev)
 
 static const struct platform_device_id max8998_battery_id[] = {
        { "max8998-battery", TYPE_MAX8998 },
+       { }
 };
 
 static struct platform_driver max8998_battery_driver = {
index 0b0ff3a936a61722be4fbb9a48d0a9de44626f1f..46a2f07edab10cf47ef40eee8438e66d9474ac0c 100644 (file)
@@ -519,9 +519,8 @@ static struct device_attribute olpc_bat_error = {
  *             Initialisation
  *********************************************************************/
 
-static struct platform_device *bat_pdev;
-
 static struct power_supply olpc_bat = {
+       .name = "olpc-battery",
        .get_property = olpc_bat_get_property,
        .use_for_apm = 1,
 };
@@ -534,13 +533,28 @@ void olpc_battery_trigger_uevent(unsigned long cause)
                kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE);
 }
 
-static int __init olpc_bat_init(void)
+static int olpc_battery_suspend(struct platform_device *pdev,
+                               pm_message_t state)
 {
-       int ret = 0;
-       uint8_t status;
+       if (device_may_wakeup(olpc_ac.dev))
+               olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR);
+       else
+               olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR);
+
+       if (device_may_wakeup(olpc_bat.dev))
+               olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
+                                  | EC_SCI_SRC_BATERR);
+       else
+               olpc_ec_wakeup_clear(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
+                                    | EC_SCI_SRC_BATERR);
 
-       if (!olpc_platform_info.ecver)
-               return -ENXIO;
+       return 0;
+}
+
+static int __devinit olpc_battery_probe(struct platform_device *pdev)
+{
+       int ret;
+       uint8_t status;
 
        /*
         * We've seen a number of EC protocol changes; this driver requires
@@ -558,15 +572,10 @@ static int __init olpc_bat_init(void)
 
        /* Ignore the status. It doesn't actually matter */
 
-       bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0);
-       if (IS_ERR(bat_pdev))
-               return PTR_ERR(bat_pdev);
-
-       ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
+       ret = power_supply_register(&pdev->dev, &olpc_ac);
        if (ret)
-               goto ac_failed;
+               return ret;
 
-       olpc_bat.name = bat_pdev->name;
        if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */
                olpc_bat.properties = olpc_xo15_bat_props;
                olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props);
@@ -575,7 +584,7 @@ static int __init olpc_bat_init(void)
                olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props);
        }
 
-       ret = power_supply_register(&bat_pdev->dev, &olpc_bat);
+       ret = power_supply_register(&pdev->dev, &olpc_bat);
        if (ret)
                goto battery_failed;
 
@@ -587,7 +596,12 @@ static int __init olpc_bat_init(void)
        if (ret)
                goto error_failed;
 
-       goto success;
+       if (olpc_ec_wakeup_available()) {
+               device_set_wakeup_capable(olpc_ac.dev, true);
+               device_set_wakeup_capable(olpc_bat.dev, true);
+       }
+
+       return 0;
 
 error_failed:
        device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
@@ -595,22 +609,45 @@ eeprom_failed:
        power_supply_unregister(&olpc_bat);
 battery_failed:
        power_supply_unregister(&olpc_ac);
-ac_failed:
-       platform_device_unregister(bat_pdev);
-success:
        return ret;
 }
 
-static void __exit olpc_bat_exit(void)
+static int __devexit olpc_battery_remove(struct platform_device *pdev)
 {
        device_remove_file(olpc_bat.dev, &olpc_bat_error);
        device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
        power_supply_unregister(&olpc_bat);
        power_supply_unregister(&olpc_ac);
-       platform_device_unregister(bat_pdev);
+       return 0;
 }
 
+static const struct of_device_id olpc_battery_ids[] __devinitconst = {
+       { .compatible = "olpc,xo1-battery" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, olpc_battery_ids);
+
+static struct platform_driver olpc_battery_drv = {
+       .driver = {
+               .name = "olpc-battery",
+               .owner = THIS_MODULE,
+               .of_match_table = olpc_battery_ids,
+       },
+       .probe = olpc_battery_probe,
+       .remove = __devexit_p(olpc_battery_remove),
+       .suspend = olpc_battery_suspend,
+};
+
+static int __init olpc_bat_init(void)
+{
+       return platform_driver_register(&olpc_battery_drv);
+}
 module_init(olpc_bat_init);
+
+static void __exit olpc_bat_exit(void)
+{
+       platform_driver_unregister(&olpc_battery_drv);
+}
 module_exit(olpc_bat_exit);
 
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
index 69f8aa3a6a4bda06b34ed6e7d147b09d723eaedc..87be6795605af9a5b82c8343c6b7dd007f4a4f01 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/notifier.h>
 #include <linux/power_supply.h>
 #include <linux/pda_power.h>
 #include <linux/regulator/consumer.h>
@@ -40,7 +41,9 @@ static int polling;
 
 #ifdef CONFIG_USB_OTG_UTILS
 static struct otg_transceiver *transceiver;
+static struct notifier_block otg_nb;
 #endif
+
 static struct regulator *ac_draw;
 
 enum {
@@ -222,7 +225,42 @@ static void polling_timer_func(unsigned long unused)
 #ifdef CONFIG_USB_OTG_UTILS
 static int otg_is_usb_online(void)
 {
-       return (transceiver->state == OTG_STATE_B_PERIPHERAL);
+       return (transceiver->last_event == USB_EVENT_VBUS ||
+               transceiver->last_event == USB_EVENT_ENUMERATED);
+}
+
+static int otg_is_ac_online(void)
+{
+       return (transceiver->last_event == USB_EVENT_CHARGER);
+}
+
+static int otg_handle_notification(struct notifier_block *nb,
+               unsigned long event, void *unused)
+{
+       switch (event) {
+       case USB_EVENT_CHARGER:
+               ac_status = PDA_PSY_TO_CHANGE;
+               break;
+       case USB_EVENT_VBUS:
+       case USB_EVENT_ENUMERATED:
+               usb_status = PDA_PSY_TO_CHANGE;
+               break;
+       case USB_EVENT_NONE:
+               ac_status = PDA_PSY_TO_CHANGE;
+               usb_status = PDA_PSY_TO_CHANGE;
+               break;
+       default:
+               return NOTIFY_OK;
+       }
+
+       /*
+        * Wait a bit before reading ac/usb line status and setting charger,
+        * because ac/usb status readings may lag from irq.
+        */
+       mod_timer(&charger_timer,
+                 jiffies + msecs_to_jiffies(pdata->wait_for_status));
+
+       return NOTIFY_OK;
 }
 #endif
 
@@ -282,6 +320,16 @@ static int pda_power_probe(struct platform_device *pdev)
                ret = PTR_ERR(ac_draw);
        }
 
+#ifdef CONFIG_USB_OTG_UTILS
+       transceiver = otg_get_transceiver();
+       if (transceiver && !pdata->is_usb_online) {
+               pdata->is_usb_online = otg_is_usb_online;
+       }
+       if (transceiver && !pdata->is_ac_online) {
+               pdata->is_ac_online = otg_is_ac_online;
+       }
+#endif
+
        if (pdata->is_ac_online) {
                ret = power_supply_register(&pdev->dev, &pda_psy_ac);
                if (ret) {
@@ -303,13 +351,6 @@ static int pda_power_probe(struct platform_device *pdev)
                }
        }
 
-#ifdef CONFIG_USB_OTG_UTILS
-       transceiver = otg_get_transceiver();
-       if (transceiver && !pdata->is_usb_online) {
-               pdata->is_usb_online = otg_is_usb_online;
-       }
-#endif
-
        if (pdata->is_usb_online) {
                ret = power_supply_register(&pdev->dev, &pda_psy_usb);
                if (ret) {
@@ -331,6 +372,18 @@ static int pda_power_probe(struct platform_device *pdev)
                }
        }
 
+#ifdef CONFIG_USB_OTG_UTILS
+       if (transceiver && pdata->use_otg_notifier) {
+               otg_nb.notifier_call = otg_handle_notification;
+               ret = otg_register_notifier(transceiver, &otg_nb);
+               if (ret) {
+                       dev_err(dev, "failure to register otg notifier\n");
+                       goto otg_reg_notifier_failed;
+               }
+               polling = 0;
+       }
+#endif
+
        if (polling) {
                dev_dbg(dev, "will poll for status\n");
                setup_timer(&polling_timer, polling_timer_func, 0);
@@ -343,6 +396,11 @@ static int pda_power_probe(struct platform_device *pdev)
 
        return 0;
 
+#ifdef CONFIG_USB_OTG_UTILS
+otg_reg_notifier_failed:
+       if (pdata->is_usb_online && usb_irq)
+               free_irq(usb_irq->start, &pda_psy_usb);
+#endif
 usb_irq_failed:
        if (pdata->is_usb_online)
                power_supply_unregister(&pda_psy_usb);
index 605514afc29f20029032ef2ab94cc1b006e8ffa3..58cc4906d216bbc82d82c0ffcb722234375941e1 100644 (file)
@@ -77,8 +77,8 @@ static ssize_t power_supply_show_property(struct device *dev,
                        dev_dbg(dev, "driver has no data for `%s' property\n",
                                attr->attr.name);
                else if (ret != -ENODEV)
-                       dev_err(dev, "driver failed to report `%s' property\n",
-                               attr->attr.name);
+                       dev_err(dev, "driver failed to report `%s' property: %zd\n",
+                               attr->attr.name, ret);
                return ret;
        }
 
index a675e31b4f132d507cd2c8c72ac09a5ada5cac0b..d32d0d70f9ba951c21204a6fccaf9a2d61951f67 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/s3c_adc_battery.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 #include <plat/adc.h>
 
index 6cc2ca6427f337460152ca9ab257d3575396e465..c32e6f83c7a85417c3d1ce6870da3ea204195a70 100644 (file)
@@ -27,6 +27,7 @@ struct wm831x_power {
        char wall_name[20];
        char usb_name[20];
        char battery_name[20];
+       bool have_battery;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -449,7 +450,8 @@ static irqreturn_t wm831x_bat_irq(int irq, void *data)
 
        /* The battery charger is autonomous so we don't need to do
         * anything except kick user space */
-       power_supply_changed(&wm831x_power->battery);
+       if (wm831x_power->have_battery)
+               power_supply_changed(&wm831x_power->battery);
 
        return IRQ_HANDLED;
 }
@@ -479,7 +481,8 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
        dev_dbg(wm831x->dev, "Power source changed\n");
 
        /* Just notify for everything - little harm in overnotifying. */
-       power_supply_changed(&wm831x_power->battery);
+       if (wm831x_power->have_battery)
+               power_supply_changed(&wm831x_power->battery);
        power_supply_changed(&wm831x_power->usb);
        power_supply_changed(&wm831x_power->wall);
 
@@ -537,15 +540,6 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
        if (ret)
                goto err_kmalloc;
 
-       battery->name = power->battery_name;
-       battery->properties = wm831x_bat_props;
-       battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
-       battery->get_property = wm831x_bat_get_prop;
-       battery->use_for_apm = 1;
-       ret = power_supply_register(&pdev->dev, battery);
-       if (ret)
-               goto err_wall;
-
        usb->name = power->usb_name,
        usb->type = POWER_SUPPLY_TYPE_USB;
        usb->properties = wm831x_usb_props;
@@ -553,7 +547,23 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
        usb->get_property = wm831x_usb_get_prop;
        ret = power_supply_register(&pdev->dev, usb);
        if (ret)
-               goto err_battery;
+               goto err_wall;
+
+       ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1);
+       if (ret < 0)
+               goto err_wall;
+       power->have_battery = ret & WM831X_CHG_ENA;
+
+       if (power->have_battery) {
+                   battery->name = power->battery_name;
+                   battery->properties = wm831x_bat_props;
+                   battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
+                   battery->get_property = wm831x_bat_get_prop;
+                   battery->use_for_apm = 1;
+                   ret = power_supply_register(&pdev->dev, battery);
+                   if (ret)
+                           goto err_usb;
+       }
 
        irq = platform_get_irq_byname(pdev, "SYSLO");
        ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
@@ -562,7 +572,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
        if (ret != 0) {
                dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
                        irq, ret);
-               goto err_usb;
+               goto err_battery;
        }
 
        irq = platform_get_irq_byname(pdev, "PWR SRC");
@@ -601,10 +611,11 @@ err_bat_irq:
 err_syslo:
        irq = platform_get_irq_byname(pdev, "SYSLO");
        free_irq(irq, power);
+err_battery:
+       if (power->have_battery)
+               power_supply_unregister(battery);
 err_usb:
        power_supply_unregister(usb);
-err_battery:
-       power_supply_unregister(battery);
 err_wall:
        power_supply_unregister(wall);
 err_kmalloc:
@@ -628,7 +639,8 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev)
        irq = platform_get_irq_byname(pdev, "SYSLO");
        free_irq(irq, wm831x_power);
 
-       power_supply_unregister(&wm831x_power->battery);
+       if (wm831x_power->have_battery)
+               power_supply_unregister(&wm831x_power->battery);
        power_supply_unregister(&wm831x_power->wall);
        power_supply_unregister(&wm831x_power->usb);
        kfree(wm831x_power);
index d119c38b3ff632ef158f66a971799c522202c6a3..ae38c44ccd4e00dac12c83bbd0e345d8aba1bb00 100644 (file)
@@ -313,7 +313,7 @@ static struct i2c_driver z2_batt_driver = {
                .pm     = Z2_BATTERY_PM_OPS
        },
        .probe          = z2_batt_probe,
-       .remove         = z2_batt_remove,
+       .remove         = __devexit_p(z2_batt_remove),
        .id_table       = z2_batt_id,
 };
 
index d63fddb0fbb0d5ead8cadb323bfbff49b2a3e00f..e821b2159b4b72a93ef0225d0db2a35b86bc4efa 100644 (file)
@@ -412,7 +412,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
                if (info->desc.id == res->start)
                        break;
        }
-       if ((i < 0) || (i > PM8607_ID_RG_MAX)) {
+       if (i == ARRAY_SIZE(pm8607_regulator_info)) {
                dev_err(&pdev->dev, "Failed to find regulator %llu\n",
                        (unsigned long long)res->start);
                return -EINVAL;
index cd4104542f0dc26ee0f7573556ad73c04dedc707..5abeb3ac3e8da43df3d58bf677c3ac0e3d17116e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
index 30eb9e54f7ec033a8ae7d889a5e42599c47a0a7c..1062cf9f02dc3303a7fae53a23203dd21a7707a8 100644 (file)
@@ -221,7 +221,7 @@ static int max8649_enable_time(struct regulator_dev *rdev)
        ret = (ret & MAX8649_RAMP_MASK) >> 5;
        rate = (32 * 1000) >> ret;      /* uV/uS */
 
-       return (voltage / rate);
+       return DIV_ROUND_UP(voltage, rate);
 }
 
 static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
index 486ed8141fcddc93dc13b7c5f91a58e8fd8baf10..3883d85c5b8864835c41b2b5b74b919696bd02d8 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/max8952.h>
-#include <linux/mutex.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -47,7 +46,6 @@ enum {
 struct max8952_data {
        struct i2c_client       *client;
        struct device           *dev;
-       struct mutex            mutex;
        struct max8952_platform_data *pdata;
        struct regulator_dev    *rdev;
 
@@ -208,7 +206,6 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
        max8952->client = client;
        max8952->dev = &client->dev;
        max8952->pdata = pdata;
-       mutex_init(&max8952->mutex);
 
        max8952->rdev = regulator_register(&regulator, max8952->dev,
                        &pdata->reg_data, max8952);
index 701a5900f83f64b6a645bf8d98ae16b0597ead08..a81abd4871bada15973e315519de8cb4eb6fa7e9 100644 (file)
 #define TPS65023_REG_CTRL_LDO2_EN      BIT(2)
 #define TPS65023_REG_CTRL_LDO1_EN      BIT(1)
 
+/* REG_CTRL2 bitfields */
+#define TPS65023_REG_CTRL2_GO          BIT(7)
+#define TPS65023_REG_CTRL2_CORE_ADJ    BIT(6)
+#define TPS65023_REG_CTRL2_DCDC2       BIT(2)
+#define TPS65023_REG_CTRL2_DCDC1       BIT(2)
+#define TPS65023_REG_CTRL2_DCDC3       BIT(0)
+
 /* LDO_CTRL bitfields */
 #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id)   ((ldo_id)*4)
 #define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id)    (0xF0 >> ((ldo_id)*4))
@@ -475,6 +482,10 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, tps);
 
+       /* Enable setting output voltage by I2C */
+       tps_65023_clear_bits(tps, TPS65023_REG_CON_CTRL2,
+                                               TPS65023_REG_CTRL2_CORE_ADJ);
+
        return 0;
 
  fail:
index bfffabc21edabdffe051466b9d11b9fd60890400..bdef70365f52b5c1c01ae30cd66d194d31c820ac 100644 (file)
@@ -90,12 +90,6 @@ static const u16 LDO2_VSEL_table[] = {
        3000, 3100, 3200, 3300,
 };
 
-static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDCx_VSEL_table),
-                               ARRAY_SIZE(VDCDCx_VSEL_table),
-                               ARRAY_SIZE(VDCDCx_VSEL_table),
-                               ARRAY_SIZE(LDO1_VSEL_table),
-                               ARRAY_SIZE(LDO2_VSEL_table)};
-
 struct tps_info {
        const char *name;
        unsigned min_uV;
@@ -598,7 +592,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
 
                tps->desc[i].name = info->name;
                tps->desc[i].id = i;
-               tps->desc[i].n_voltages = num_voltages[i];
+               tps->desc[i].n_voltages = info->table_len;
                tps->desc[i].ops = (i > TPS6507X_DCDC_3 ?
                &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
                tps->desc[i].type = REGULATOR_VOLTAGE;
index 3a9313e00fac796b3d8799c90004a13fd2587142..39d4a1749e71a78b3ad73907e407bb8d02435df3 100644 (file)
@@ -43,8 +43,6 @@
 #define TPS65912_REG_LDO9      12
 #define TPS65912_REG_LDO10     13
 
-#define TPS65912_MAX_REG_ID    TPS65912_REG_LDO_10
-
 /* Number of step-down converters available */
 #define TPS65912_NUM_DCDC      4
 
index 9a81f778d6b22216469b641d0dbe44c809667fd8..9677bbc433f9c68f0732ffaa96c8dd63024ee849 100644 (file)
@@ -362,14 +362,6 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
        int res;
        u8 rd_reg;
 
-#ifdef CONFIG_LOCKDEP
-       /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-        * we don't want and can't tolerate.  Although it might be
-        * friendlier not to borrow this thread context...
-        */
-       local_irq_enable();
-#endif
-
        res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
        if (res)
                goto out;
@@ -462,7 +454,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto out1;
 
-       ret = request_irq(irq, twl_rtc_interrupt,
+       ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
                                IRQF_TRIGGER_RISING,
                                dev_name(&rtc->dev), rtc);
        if (ret < 0) {
index eb4e034378cd0d4daba20ee6988343b571ac000f..f1a2016829fc5654335abaea3d7682eae4d33370 100644 (file)
@@ -249,6 +249,7 @@ static int dasd_ioctl_reset_profile(struct dasd_block *block)
 static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp)
 {
        struct dasd_profile_info_t *data;
+       int rc = 0;
 
        data = kmalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
@@ -279,11 +280,14 @@ static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp)
                spin_unlock_bh(&block->profile.lock);
        } else {
                spin_unlock_bh(&block->profile.lock);
-               return -EIO;
+               rc = -EIO;
+               goto out;
        }
        if (copy_to_user(argp, data, sizeof(*data)))
-               return -EFAULT;
-       return 0;
+               rc = -EFAULT;
+out:
+       kfree(data);
+       return rc;
 }
 #else
 static int dasd_ioctl_reset_profile(struct dasd_block *block)
index 3b94044027c2c0229df51a7c6e05f4519eb00df6..f4f1da213e2896617f63dfcfad20ce43a99beedb 100644 (file)
@@ -142,22 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
        return memcpy_hsa(dest, src, count, TO_KERNEL);
 }
 
-static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
-{
-       static char buf[4096];
-       int offs = 0, size;
-
-       while (offs < count) {
-               size = min(sizeof(buf), count - offs);
-               if (memcpy_real(buf, (void *) src + offs, size))
-                       return -EFAULT;
-               if (copy_to_user(dest + offs, buf, size))
-                       return -EFAULT;
-               offs += size;
-       }
-       return 0;
-}
-
 static int __init init_cpu_info(enum arch_id arch)
 {
        struct save_area *sa;
@@ -346,8 +330,8 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count,
 
        /* Copy from real mem */
        size = count - mem_offs - hdr_count;
-       rc = memcpy_real_user(buf + hdr_count + mem_offs, mem_start + mem_offs,
-                             size);
+       rc = copy_to_user_real(buf + hdr_count + mem_offs,
+                              (void *) mem_start + mem_offs, size);
        if (rc)
                goto fail;
 
index d15f8b4d78bd5f67476dafd0d6e320093a75d59c..5156264d0c745f6321ba00616bbb7ea1a8f853f3 100644 (file)
@@ -1,10 +1,13 @@
 /*
  *  Handling of internal CCW device requests.
  *
- *    Copyright IBM Corp. 2009
+ *    Copyright IBM Corp. 2009, 2011
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "cio"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/types.h>
 #include <linux/err.h>
 #include <asm/ccwdev.h>
@@ -323,7 +326,21 @@ void ccw_request_timeout(struct ccw_device *cdev)
 {
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
        struct ccw_request *req = &cdev->private->req;
-       int rc;
+       int rc = -ENODEV, chp;
+
+       if (cio_update_schib(sch))
+               goto err;
+
+       for (chp = 0; chp < 8; chp++) {
+               if ((0x80 >> chp) & sch->schib.pmcw.lpum)
+                       pr_warning("%s: No interrupt was received within %lus "
+                                  "(CS=%02x, DS=%02x, CHPID=%x.%02x)\n",
+                                  dev_name(&cdev->dev), req->timeout / HZ,
+                                  scsw_cstat(&sch->schib.scsw),
+                                  scsw_dstat(&sch->schib.scsw),
+                                  sch->schid.cssid,
+                                  sch->schib.pmcw.chpid[chp]);
+       }
 
        if (!ccwreq_next_path(cdev)) {
                /* set the final return code for this request */
@@ -342,7 +359,7 @@ err:
  * ccw_request_notoper - notoper handler for I/O request procedure
  * @cdev: ccw device
  *
- * Handle timeout during I/O request procedure.
+ * Handle notoper during I/O request procedure.
  */
 void ccw_request_notoper(struct ccw_device *cdev)
 {
index e5c966462c5ad2ae9001e6a4df863c8133feb46c..3dd86441da3d33ef7077a11e677d6ed600d34e73 100644 (file)
@@ -44,6 +44,7 @@ enum qdio_irq_states {
 #define SLSB_STATE_NOT_INIT    0x0
 #define SLSB_STATE_EMPTY       0x1
 #define SLSB_STATE_PRIMED      0x2
+#define SLSB_STATE_PENDING     0x3
 #define SLSB_STATE_HALTED      0xe
 #define SLSB_STATE_ERROR       0xf
 #define SLSB_TYPE_INPUT                0x0
@@ -67,6 +68,8 @@ enum qdio_irq_states {
        (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_NOT_INIT) /* 0xa0 */
 #define SLSB_P_OUTPUT_EMPTY    \
        (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_EMPTY)    /* 0xa1 */
+#define SLSB_P_OUTPUT_PENDING \
+       (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_PENDING)  /* 0xa3 */
 #define SLSB_CU_OUTPUT_PRIMED  \
        (SLSB_OWNER_CU | SLSB_TYPE_OUTPUT | SLSB_STATE_PRIMED)     /* 0x62 */
 #define SLSB_P_OUTPUT_HALTED   \
@@ -84,19 +87,11 @@ enum qdio_irq_states {
 #define CHSC_FLAG_QDIO_CAPABILITY      0x80
 #define CHSC_FLAG_VALIDITY             0x40
 
-/* qdio adapter-characteristics-1 flag */
-#define AC1_SIGA_INPUT_NEEDED          0x40    /* process input queues */
-#define AC1_SIGA_OUTPUT_NEEDED         0x20    /* process output queues */
-#define AC1_SIGA_SYNC_NEEDED           0x10    /* ask hypervisor to sync */
-#define AC1_AUTOMATIC_SYNC_ON_THININT  0x08    /* set by hypervisor */
-#define AC1_AUTOMATIC_SYNC_ON_OUT_PCI  0x04    /* set by hypervisor */
-#define AC1_SC_QEBSM_AVAILABLE         0x02    /* available for subchannel */
-#define AC1_SC_QEBSM_ENABLED           0x01    /* enabled for subchannel */
-
 /* SIGA flags */
 #define QDIO_SIGA_WRITE                0x00
 #define QDIO_SIGA_READ         0x01
 #define QDIO_SIGA_SYNC         0x02
+#define QDIO_SIGA_WRITEQ       0x04
 #define QDIO_SIGA_QEBSM_FLAG   0x80
 
 #ifdef CONFIG_64BIT
@@ -253,6 +248,12 @@ struct qdio_input_q {
 struct qdio_output_q {
        /* PCIs are enabled for the queue */
        int pci_out_enabled;
+       /* cq: use asynchronous output buffers */
+       int use_cq;
+       /* cq: aobs used for particual SBAL */
+       struct qaob **aobs;
+       /* cq: sbal state related to asynchronous operation */
+       struct qdio_outbuf_state *sbal_state;
        /* timer to check for more outbound work */
        struct timer_list timer;
        /* used SBALs before tasklet schedule */
@@ -432,9 +433,20 @@ struct indicator_t {
 
 extern struct indicator_t *q_indicators;
 
-static inline int shared_ind(u32 *dsci)
+static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq)
+{
+       return irq->nr_input_qs > 1;
+}
+
+static inline int references_shared_dsci(struct qdio_irq *irq)
 {
-       return dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+       return irq->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+}
+
+static inline int shared_ind(struct qdio_q *q)
+{
+       struct qdio_irq *i = q->irq_ptr;
+       return references_shared_dsci(i) || has_multiple_inq_on_dsci(i);
 }
 
 /* prototypes for thin interrupt */
@@ -449,6 +461,7 @@ void tiqdio_free_memory(void);
 int tiqdio_register_thinints(void);
 void tiqdio_unregister_thinints(void);
 
+
 /* prototypes for setup */
 void qdio_inbound_processing(unsigned long data);
 void qdio_outbound_processing(unsigned long data);
@@ -469,6 +482,9 @@ int qdio_setup_create_sysfs(struct ccw_device *cdev);
 void qdio_setup_destroy_sysfs(struct ccw_device *cdev);
 int qdio_setup_init(void);
 void qdio_setup_exit(void);
+int qdio_enable_async_operation(struct qdio_output_q *q);
+void qdio_disable_async_operation(struct qdio_output_q *q);
+struct qaob *qdio_allocate_aob(void);
 
 int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
                        unsigned char *state);
index 0e615cb912d0eb0a90a2d510b5814d3586b06297..aaf7f935bfd37e16c44e6ff70e84b38bde1c71c4 100644 (file)
@@ -76,6 +76,9 @@ static int qstat_show(struct seq_file *m, void *v)
                case SLSB_P_OUTPUT_NOT_INIT:
                        seq_printf(m, "N");
                        break;
+               case SLSB_P_OUTPUT_PENDING:
+                       seq_printf(m, "P");
+                       break;
                case SLSB_P_INPUT_PRIMED:
                case SLSB_CU_OUTPUT_PRIMED:
                        seq_printf(m, "+");
index 288c9140290e9a08b899b234c7e514c9bcc6838a..9a122280246c1783485af4140d9785cefadca976 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/gfp.h>
+#include <linux/io.h>
 #include <linux/kernel_stat.h>
 #include <linux/atomic.h>
 #include <asm/debug.h>
@@ -77,11 +78,13 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
  * Note: For IQDC unicast queues only the highest priority queue is processed.
  */
 static inline int do_siga_output(unsigned long schid, unsigned long mask,
-                                unsigned int *bb, unsigned int fc)
+                                unsigned int *bb, unsigned int fc,
+                                unsigned long aob)
 {
        register unsigned long __fc asm("0") = fc;
        register unsigned long __schid asm("1") = schid;
        register unsigned long __mask asm("2") = mask;
+       register unsigned long __aob asm("3") = aob;
        int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION;
 
        asm volatile(
@@ -90,7 +93,8 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask,
                "       srl     %0,28\n"
                "1:\n"
                EX_TABLE(0b, 1b)
-               : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask)
+               : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask),
+                 "+d" (__aob)
                : : "cc", "memory");
        *bb = ((unsigned int) __fc) >> 31;
        return cc;
@@ -212,7 +216,7 @@ again:
 /* returns number of examined buffers and their common state in *state */
 static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
                                 unsigned char *state, unsigned int count,
-                                int auto_ack)
+                                int auto_ack, int merge_pending)
 {
        unsigned char __state = 0;
        int i;
@@ -224,9 +228,14 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
                return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
 
        for (i = 0; i < count; i++) {
-               if (!__state)
+               if (!__state) {
                        __state = q->slsb.val[bufnr];
-               else if (q->slsb.val[bufnr] != __state)
+                       if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
+                               __state = SLSB_P_OUTPUT_EMPTY;
+               } else if (merge_pending) {
+                       if ((q->slsb.val[bufnr] & __state) != __state)
+                               break;
+               } else if (q->slsb.val[bufnr] != __state)
                        break;
                bufnr = next_buf(bufnr);
        }
@@ -237,7 +246,7 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
 static inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
                                unsigned char *state, int auto_ack)
 {
-       return get_buf_states(q, bufnr, state, 1, auto_ack);
+       return get_buf_states(q, bufnr, state, 1, auto_ack, 0);
 }
 
 /* wrap-around safe setting of slsb states, returns number of changed buffers */
@@ -308,19 +317,28 @@ static inline int qdio_siga_sync_q(struct qdio_q *q)
                return qdio_siga_sync(q, q->mask, 0);
 }
 
-static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit)
+static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
+       unsigned long aob)
 {
        unsigned long schid = *((u32 *) &q->irq_ptr->schid);
        unsigned int fc = QDIO_SIGA_WRITE;
        u64 start_time = 0;
        int retries = 0, cc;
+       unsigned long laob = 0;
+
+       if (q->u.out.use_cq && aob != 0) {
+               fc = QDIO_SIGA_WRITEQ;
+               laob = aob;
+       }
 
        if (is_qebsm(q)) {
                schid = q->irq_ptr->sch_token;
                fc |= QDIO_SIGA_QEBSM_FLAG;
        }
 again:
-       cc = do_siga_output(schid, q->mask, busy_bit, fc);
+       WARN_ON_ONCE((aob && queue_type(q) != QDIO_IQDIO_QFMT) ||
+               (aob && fc != QDIO_SIGA_WRITEQ));
+       cc = do_siga_output(schid, q->mask, busy_bit, fc, laob);
 
        /* hipersocket busy condition */
        if (unlikely(*busy_bit)) {
@@ -379,7 +397,7 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
 {
        if (need_siga_sync(q))
                qdio_siga_sync_q(q);
-       return get_buf_states(q, bufnr, state, 1, 0);
+       return get_buf_states(q, bufnr, state, 1, 0, 0);
 }
 
 static inline void qdio_stop_polling(struct qdio_q *q)
@@ -507,7 +525,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
         * No siga sync here, as a PCI or we after a thin interrupt
         * already sync'ed the queues.
         */
-       count = get_buf_states(q, q->first_to_check, &state, count, 1);
+       count = get_buf_states(q, q->first_to_check, &state, count, 1, 0);
        if (!count)
                goto out;
 
@@ -590,6 +608,107 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
                return 0;
 }
 
+static inline int contains_aobs(struct qdio_q *q)
+{
+       return !q->is_input_q && q->u.out.use_cq;
+}
+
+static inline void qdio_trace_aob(struct qdio_irq *irq, struct qdio_q *q,
+                               int i, struct qaob *aob)
+{
+       int tmp;
+
+       DBF_DEV_EVENT(DBF_INFO, irq, "AOB%d:%lx", i,
+                       (unsigned long) virt_to_phys(aob));
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES00:%lx",
+                       (unsigned long) aob->res0[0]);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES01:%lx",
+                       (unsigned long) aob->res0[1]);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES02:%lx",
+                       (unsigned long) aob->res0[2]);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES03:%lx",
+                       (unsigned long) aob->res0[3]);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES04:%lx",
+                       (unsigned long) aob->res0[4]);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES05:%lx",
+                       (unsigned long) aob->res0[5]);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES1:%x", aob->res1);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES2:%x", aob->res2);
+       DBF_DEV_EVENT(DBF_INFO, irq, "RES3:%x", aob->res3);
+       DBF_DEV_EVENT(DBF_INFO, irq, "AORC:%u", aob->aorc);
+       DBF_DEV_EVENT(DBF_INFO, irq, "FLAGS:%u", aob->flags);
+       DBF_DEV_EVENT(DBF_INFO, irq, "CBTBS:%u", aob->cbtbs);
+       DBF_DEV_EVENT(DBF_INFO, irq, "SBC:%u", aob->sb_count);
+       for (tmp = 0; tmp < QDIO_MAX_ELEMENTS_PER_BUFFER; ++tmp) {
+               DBF_DEV_EVENT(DBF_INFO, irq, "SBA%d:%lx", tmp,
+                               (unsigned long) aob->sba[tmp]);
+               DBF_DEV_EVENT(DBF_INFO, irq, "rSBA%d:%lx", tmp,
+                               (unsigned long) q->sbal[i]->element[tmp].addr);
+               DBF_DEV_EVENT(DBF_INFO, irq, "DC%d:%u", tmp, aob->dcount[tmp]);
+               DBF_DEV_EVENT(DBF_INFO, irq, "rDC%d:%u", tmp,
+                               q->sbal[i]->element[tmp].length);
+       }
+       DBF_DEV_EVENT(DBF_INFO, irq, "USER0:%lx", (unsigned long) aob->user0);
+       for (tmp = 0; tmp < 2; ++tmp) {
+               DBF_DEV_EVENT(DBF_INFO, irq, "RES4%d:%lx", tmp,
+                       (unsigned long) aob->res4[tmp]);
+       }
+       DBF_DEV_EVENT(DBF_INFO, irq, "USER1:%lx", (unsigned long) aob->user1);
+       DBF_DEV_EVENT(DBF_INFO, irq, "USER2:%lx", (unsigned long) aob->user2);
+}
+
+static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
+{
+       unsigned char state = 0;
+       int j, b = start;
+
+       if (!contains_aobs(q))
+               return;
+
+       for (j = 0; j < count; ++j) {
+               get_buf_state(q, b, &state, 0);
+               if (state == SLSB_P_OUTPUT_PENDING) {
+                       struct qaob *aob = q->u.out.aobs[b];
+                       if (aob == NULL)
+                               continue;
+
+                       BUG_ON(q->u.out.sbal_state == NULL);
+                       q->u.out.sbal_state[b].flags |=
+                               QDIO_OUTBUF_STATE_FLAG_PENDING;
+                       q->u.out.aobs[b] = NULL;
+               } else if (state == SLSB_P_OUTPUT_EMPTY) {
+                       BUG_ON(q->u.out.sbal_state == NULL);
+                       q->u.out.sbal_state[b].aob = NULL;
+               }
+               b = next_buf(b);
+       }
+}
+
+static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
+                                       int bufnr)
+{
+       unsigned long phys_aob = 0;
+
+       if (!q->use_cq)
+               goto out;
+
+       if (!q->aobs[bufnr]) {
+               struct qaob *aob = qdio_allocate_aob();
+               q->aobs[bufnr] = aob;
+       }
+       if (q->aobs[bufnr]) {
+               BUG_ON(q->sbal_state == NULL);
+               q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE;
+               q->sbal_state[bufnr].aob = q->aobs[bufnr];
+               q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
+               phys_aob = virt_to_phys(q->aobs[bufnr]);
+               BUG_ON(phys_aob & 0xFF);
+       }
+
+out:
+       return phys_aob;
+}
+
 static void qdio_kick_handler(struct qdio_q *q)
 {
        int start = q->first_to_kick;
@@ -610,6 +729,8 @@ static void qdio_kick_handler(struct qdio_q *q)
                              start, count);
        }
 
+       qdio_handle_aobs(q, start, count);
+
        q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
                   q->irq_ptr->int_parm);
 
@@ -672,23 +793,26 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
         */
        count = min(atomic_read(&q->nr_buf_used), QDIO_MAX_BUFFERS_MASK);
        stop = add_buf(q->first_to_check, count);
-
        if (q->first_to_check == stop)
-               return q->first_to_check;
+               goto out;
 
-       count = get_buf_states(q, q->first_to_check, &state, count, 0);
+       count = get_buf_states(q, q->first_to_check, &state, count, 0, 1);
        if (!count)
-               return q->first_to_check;
+               goto out;
 
        switch (state) {
+       case SLSB_P_OUTPUT_PENDING:
+               BUG();
        case SLSB_P_OUTPUT_EMPTY:
                /* the adapter got it */
-               DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out empty:%1d %02x", q->nr, count);
+               DBF_DEV_EVENT(DBF_INFO, q->irq_ptr,
+                       "out empty:%1d %02x", q->nr, count);
 
                atomic_sub(count, &q->nr_buf_used);
                q->first_to_check = add_buf(q->first_to_check, count);
                if (q->irq_ptr->perf_stat_enabled)
                        account_sbals(q, count);
+
                break;
        case SLSB_P_OUTPUT_ERROR:
                process_buffer_error(q, count);
@@ -701,7 +825,8 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
                /* the adapter has not fetched the output yet */
                if (q->irq_ptr->perf_stat_enabled)
                        q->q_stats.nr_sbal_nop++;
-               DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr);
+               DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d",
+                             q->nr);
                break;
        case SLSB_P_OUTPUT_NOT_INIT:
        case SLSB_P_OUTPUT_HALTED:
@@ -709,6 +834,8 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
        default:
                BUG();
        }
+
+out:
        return q->first_to_check;
 }
 
@@ -732,7 +859,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
                return 0;
 }
 
-static int qdio_kick_outbound_q(struct qdio_q *q)
+static int qdio_kick_outbound_q(struct qdio_q *q, unsigned long aob)
 {
        int retries = 0, cc;
        unsigned int busy_bit;
@@ -744,7 +871,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q)
 retry:
        qperf_inc(q, siga_write);
 
-       cc = qdio_siga_output(q, &busy_bit);
+       cc = qdio_siga_output(q, &busy_bit, aob);
        switch (cc) {
        case 0:
                break;
@@ -921,8 +1048,9 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
                        }
                        q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
                                                 q->irq_ptr->int_parm);
-               } else
+               } else {
                        tasklet_schedule(&q->tasklet);
+               }
        }
 
        if (!pci_out_supported(q))
@@ -1236,6 +1364,26 @@ out_err:
 }
 EXPORT_SYMBOL_GPL(qdio_allocate);
 
+static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
+{
+       struct qdio_q *q = irq_ptr->input_qs[0];
+       int i, use_cq = 0;
+
+       if (irq_ptr->nr_input_qs > 1 && queue_type(q) == QDIO_IQDIO_QFMT)
+               use_cq = 1;
+
+       for_each_output_queue(irq_ptr, q, i) {
+               if (use_cq) {
+                       if (qdio_enable_async_operation(&q->u.out) < 0) {
+                               use_cq = 0;
+                               continue;
+                       }
+               } else
+                       qdio_disable_async_operation(&q->u.out);
+       }
+       DBF_EVENT("use_cq:%d", use_cq);
+}
+
 /**
  * qdio_establish - establish queues on a qdio subchannel
  * @init_data: initialization data
@@ -1301,6 +1449,8 @@ int qdio_establish(struct qdio_initialize *init_data)
        qdio_setup_ssqd_info(irq_ptr);
        DBF_EVENT("qib ac:%4x", irq_ptr->qib.ac);
 
+       qdio_detect_hsicq(irq_ptr);
+
        /* qebsm is now setup if available, initialize buffer states */
        qdio_init_buf_states(irq_ptr);
 
@@ -1442,12 +1592,9 @@ set:
        used = atomic_add_return(count, &q->nr_buf_used) - count;
        BUG_ON(used + count > QDIO_MAX_BUFFERS_PER_Q);
 
-       /* no need to signal as long as the adapter had free buffers */
-       if (used)
-               return 0;
-
        if (need_siga_in(q))
                return qdio_siga_input(q);
+
        return 0;
 }
 
@@ -1480,17 +1627,21 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
                q->u.out.pci_out_enabled = 0;
 
        if (queue_type(q) == QDIO_IQDIO_QFMT) {
-               /* One SIGA-W per buffer required for unicast HiperSockets. */
+               unsigned long phys_aob = 0;
+
+               /* One SIGA-W per buffer required for unicast HSI */
                WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
 
-               rc = qdio_kick_outbound_q(q);
+               phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
+
+               rc = qdio_kick_outbound_q(q, phys_aob);
        } else if (need_siga_sync(q)) {
                rc = qdio_siga_sync_q(q);
        } else {
                /* try to fast requeue buffers */
                get_buf_state(q, prev_buf(bufnr), &state, 0);
                if (state != SLSB_CU_OUTPUT_PRIMED)
-                       rc = qdio_kick_outbound_q(q);
+                       rc = qdio_kick_outbound_q(q, 0);
                else
                        qperf_inc(q, fast_requeue);
        }
@@ -1518,6 +1669,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
 {
        struct qdio_irq *irq_ptr;
 
+
        if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q)
                return -EINVAL;
 
@@ -1562,7 +1714,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
 
        WARN_ON(queue_irqs_enabled(q));
 
-       if (!shared_ind(q->irq_ptr->dsci))
+       if (!shared_ind(q))
                xchg(q->irq_ptr->dsci, 0);
 
        qdio_stop_polling(q);
@@ -1572,7 +1724,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
         * We need to check again to not lose initiative after
         * resetting the ACK state.
         */
-       if (!shared_ind(q->irq_ptr->dsci) && *q->irq_ptr->dsci)
+       if (!shared_ind(q) && *q->irq_ptr->dsci)
                goto rescan;
        if (!qdio_inbound_q_done(q))
                goto rescan;
index 89107d0938c4542197b7227b547de3fa278cf2f6..dd8bd670a6b8fd290296060b50fbb305dbf2e508 100644 (file)
 #include "qdio_debug.h"
 
 static struct kmem_cache *qdio_q_cache;
+static struct kmem_cache *qdio_aob_cache;
+
+struct qaob *qdio_allocate_aob()
+{
+       struct qaob *aob;
+
+       aob = kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
+       return aob;
+}
+EXPORT_SYMBOL_GPL(qdio_allocate_aob);
+
+void qdio_release_aob(struct qaob *aob)
+{
+       kmem_cache_free(qdio_aob_cache, aob);
+}
+EXPORT_SYMBOL_GPL(qdio_release_aob);
 
 /*
  * qebsm is only available under 64bit but the adapter sets the feature
@@ -154,29 +170,36 @@ static void setup_queues(struct qdio_irq *irq_ptr,
        struct qdio_q *q;
        void **input_sbal_array = qdio_init->input_sbal_addr_array;
        void **output_sbal_array = qdio_init->output_sbal_addr_array;
+       struct qdio_outbuf_state *output_sbal_state_array =
+                                 qdio_init->output_sbal_state_array;
        int i;
 
        for_each_input_queue(irq_ptr, q, i) {
-               DBF_EVENT("in-q:%1d", i);
+               DBF_EVENT("inq:%1d", i);
                setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
 
                q->is_input_q = 1;
-               q->u.in.queue_start_poll = qdio_init->queue_start_poll;
+               q->u.in.queue_start_poll = qdio_init->queue_start_poll[i];
+
                setup_storage_lists(q, irq_ptr, input_sbal_array, i);
                input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
 
-               if (is_thinint_irq(irq_ptr))
+               if (is_thinint_irq(irq_ptr)) {
                        tasklet_init(&q->tasklet, tiqdio_inbound_processing,
                                     (unsigned long) q);
-               else
+               } else {
                        tasklet_init(&q->tasklet, qdio_inbound_processing,
                                     (unsigned long) q);
+               }
        }
 
        for_each_output_queue(irq_ptr, q, i) {
                DBF_EVENT("outq:%1d", i);
                setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
 
+               q->u.out.sbal_state = output_sbal_state_array;
+               output_sbal_state_array += QDIO_MAX_BUFFERS_PER_Q;
+
                q->is_input_q = 0;
                q->u.out.scan_threshold = qdio_init->scan_threshold;
                setup_storage_lists(q, irq_ptr, output_sbal_array, i);
@@ -311,6 +334,19 @@ void qdio_release_memory(struct qdio_irq *irq_ptr)
        for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) {
                q = irq_ptr->output_qs[i];
                if (q) {
+                       if (q->u.out.use_cq) {
+                               int n;
+
+                               for (n = 0; n < QDIO_MAX_BUFFERS_PER_Q; ++n) {
+                                       struct qaob *aob = q->u.out.aobs[n];
+                                       if (aob) {
+                                               qdio_release_aob(aob);
+                                               q->u.out.aobs[n] = NULL;
+                                       }
+                               }
+
+                               qdio_disable_async_operation(&q->u.out);
+                       }
                        free_page((unsigned long) q->slib);
                        kmem_cache_free(qdio_q_cache, q);
                }
@@ -465,23 +501,60 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
        printk(KERN_INFO "%s", s);
 }
 
+int qdio_enable_async_operation(struct qdio_output_q *outq)
+{
+       outq->aobs = kzalloc(sizeof(struct qaob *) * QDIO_MAX_BUFFERS_PER_Q,
+                            GFP_ATOMIC);
+       if (!outq->aobs) {
+               outq->use_cq = 0;
+               return -ENOMEM;
+       }
+       outq->use_cq = 1;
+       return 0;
+}
+
+void qdio_disable_async_operation(struct qdio_output_q *q)
+{
+       kfree(q->aobs);
+       q->aobs = NULL;
+       q->use_cq = 0;
+}
+
 int __init qdio_setup_init(void)
 {
+       int rc;
+
        qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q),
                                         256, 0, NULL);
        if (!qdio_q_cache)
                return -ENOMEM;
 
+       qdio_aob_cache = kmem_cache_create("qdio_aob",
+                                       sizeof(struct qaob),
+                                       sizeof(struct qaob),
+                                       0,
+                                       NULL);
+       if (!qdio_aob_cache) {
+               rc = -ENOMEM;
+               goto free_qdio_q_cache;
+       }
+
        /* Check for OSA/FCP thin interrupts (bit 67). */
        DBF_EVENT("thinint:%1d",
                  (css_general_characteristics.aif_osa) ? 1 : 0);
 
        /* Check for QEBSM support in general (bit 58). */
        DBF_EVENT("cssQEBSM:%1d", (qebsm_possible()) ? 1 : 0);
-       return 0;
+       rc = 0;
+out:
+       return rc;
+free_qdio_q_cache:
+       kmem_cache_destroy(qdio_q_cache);
+       goto out;
 }
 
 void qdio_setup_exit(void)
 {
+       kmem_cache_destroy(qdio_aob_cache);
        kmem_cache_destroy(qdio_q_cache);
 }
index 2a1d4dfaf859ac9e6899a5efb7c31422238b18d4..a3e3949d7b692d36c4aec1260b1aab74fd6b6e74 100644 (file)
@@ -67,12 +67,9 @@ static void put_indicator(u32 *addr)
 
 void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
 {
-       struct qdio_q *q;
-       int i;
-
        mutex_lock(&tiq_list_lock);
-       for_each_input_queue(irq_ptr, q, i)
-               list_add_rcu(&q->entry, &tiq_list);
+       BUG_ON(irq_ptr->nr_input_qs < 1);
+       list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list);
        mutex_unlock(&tiq_list_lock);
        xchg(irq_ptr->dsci, 1 << 7);
 }
@@ -80,19 +77,17 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
 void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
 {
        struct qdio_q *q;
-       int i;
 
-       for (i = 0; i < irq_ptr->nr_input_qs; i++) {
-               q = irq_ptr->input_qs[i];
-               /* if establish triggered an error */
-               if (!q || !q->entry.prev || !q->entry.next)
-                       continue;
+       BUG_ON(irq_ptr->nr_input_qs < 1);
+       q = irq_ptr->input_qs[0];
+       /* if establish triggered an error */
+       if (!q || !q->entry.prev || !q->entry.next)
+               return;
 
-               mutex_lock(&tiq_list_lock);
-               list_del_rcu(&q->entry);
-               mutex_unlock(&tiq_list_lock);
-               synchronize_rcu();
-       }
+       mutex_lock(&tiq_list_lock);
+       list_del_rcu(&q->entry);
+       mutex_unlock(&tiq_list_lock);
+       synchronize_rcu();
 }
 
 static inline u32 clear_shared_ind(void)
@@ -102,6 +97,40 @@ static inline u32 clear_shared_ind(void)
        return xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0);
 }
 
+static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
+{
+       struct qdio_q *q;
+       int i;
+
+       for_each_input_queue(irq, q, i) {
+               if (!references_shared_dsci(irq) &&
+                   has_multiple_inq_on_dsci(irq))
+                       xchg(q->irq_ptr->dsci, 0);
+
+               if (q->u.in.queue_start_poll) {
+                       /* skip if polling is enabled or already in work */
+                       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+                                            &q->u.in.queue_irq_state)) {
+                               qperf_inc(q, int_discarded);
+                               continue;
+                       }
+
+                       /* avoid dsci clear here, done after processing */
+                       q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
+                                                q->irq_ptr->int_parm);
+               } else {
+                       if (!shared_ind(q))
+                               xchg(q->irq_ptr->dsci, 0);
+
+                       /*
+                        * Call inbound processing but not directly
+                        * since that could starve other thinint queues.
+                        */
+                       tasklet_schedule(&q->tasklet);
+               }
+       }
+}
+
 /**
  * tiqdio_thinint_handler - thin interrupt handler for qdio
  * @alsi: pointer to adapter local summary indicator
@@ -120,35 +149,18 @@ static void tiqdio_thinint_handler(void *alsi, void *data)
 
        /* check for work on all inbound thinint queues */
        list_for_each_entry_rcu(q, &tiq_list, entry) {
+               struct qdio_irq *irq;
 
                /* only process queues from changed sets */
-               if (unlikely(shared_ind(q->irq_ptr->dsci))) {
+               irq = q->irq_ptr;
+               if (unlikely(references_shared_dsci(irq))) {
                        if (!si_used)
                                continue;
-               } else if (!*q->irq_ptr->dsci)
+               } else if (!*irq->dsci)
                        continue;
 
-               if (q->u.in.queue_start_poll) {
-                       /* skip if polling is enabled or already in work */
-                       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                                            &q->u.in.queue_irq_state)) {
-                               qperf_inc(q, int_discarded);
-                               continue;
-                       }
+               tiqdio_call_inq_handlers(irq);
 
-                       /* avoid dsci clear here, done after processing */
-                       q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
-                                                q->irq_ptr->int_parm);
-               } else {
-                       /* only clear it if the indicator is non-shared */
-                       if (!shared_ind(q->irq_ptr->dsci))
-                               xchg(q->irq_ptr->dsci, 0);
-                       /*
-                        * Call inbound processing but not directly
-                        * since that could starve other thinint queues.
-                        */
-                       tasklet_schedule(&q->tasklet);
-               }
                qperf_inc(q, adapter_int);
        }
        rcu_read_unlock();
index c3b8064a102dab48199d103953d5e2aa1b5f4386..fb246b944b16e7219957f41ca200dc4459484da8 100644 (file)
@@ -2122,7 +2122,7 @@ static const struct net_device_ops lcs_mc_netdev_ops = {
        .ndo_stop               = lcs_stop_device,
        .ndo_get_stats          = lcs_getstats,
        .ndo_start_xmit         = lcs_start_xmit,
-       .ndo_set_multicast_list = lcs_set_multicast_list,
+       .ndo_set_rx_mode        = lcs_set_multicast_list,
 };
 
 static int
index 26a4110eeb2d9e92519c814783f441bb8bcabcdb..b77c65ed13812f9d7e5462c0bcb5bcb9c1fa33f1 100644 (file)
@@ -110,6 +110,10 @@ struct qeth_perf_stats {
 
        unsigned int sc_dp_p;
        unsigned int sc_p_dp;
+       /* qdio_cq_handler: number of times called, time spent in */
+       __u64 cq_start_time;
+       unsigned int cq_cnt;
+       unsigned int cq_time;
        /* qdio_input_handler: number of times called, time spent in */
        __u64 inbound_start_time;
        unsigned int inbound_cnt;
@@ -213,6 +217,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
  */
 #define QETH_TX_TIMEOUT                100 * HZ
 #define QETH_RCD_TIMEOUT       60 * HZ
+#define QETH_RECLAIM_WORK_TIME HZ
 #define QETH_HEADER_SIZE       32
 #define QETH_MAX_PORTNO                15
 
@@ -231,7 +236,8 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
 #define QETH_IN_BUF_COUNT_MAX 128
 #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
 #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
-               ((card)->qdio.in_buf_pool.buf_count / 2)
+               ((card)->ssqd.qdioac1 & AC1_SIGA_INPUT_NEEDED ? 1 : \
+                ((card)->qdio.in_buf_pool.buf_count / 2))
 
 /* buffers we have to be behind before we get a PCI */
 #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
@@ -260,6 +266,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
 
 /* large receive scatter gather copy break */
 #define QETH_RX_SG_CB (PAGE_SIZE >> 1)
+#define QETH_RX_PULL_LEN 256
 
 struct qeth_hdr_layer3 {
        __u8  id;
@@ -375,6 +382,21 @@ enum qeth_qdio_buffer_states {
         * outbound: filled by driver; owned by hardware in order to be sent
         */
        QETH_QDIO_BUF_PRIMED,
+       /*
+        * inbound: not applicable
+        * outbound: identified to be pending in TPQ
+        */
+       QETH_QDIO_BUF_PENDING,
+       /*
+        * inbound: not applicable
+        * outbound: found in completion queue
+        */
+       QETH_QDIO_BUF_IN_CQ,
+       /*
+        * inbound: not applicable
+        * outbound: handled via transfer pending / completion queue
+        */
+       QETH_QDIO_BUF_HANDLED_DELAYED,
 };
 
 enum qeth_qdio_info_states {
@@ -399,6 +421,7 @@ struct qeth_qdio_buffer {
        struct qdio_buffer *buffer;
        /* the buffer pool entry currently associated to this buffer */
        struct qeth_buffer_pool_entry *pool_entry;
+       struct sk_buff *rx_skb;
 };
 
 struct qeth_qdio_q {
@@ -412,8 +435,11 @@ struct qeth_qdio_out_buffer {
        atomic_t state;
        int next_element_to_fill;
        struct sk_buff_head skb_list;
-       struct list_head ctx_list;
        int is_header[16];
+
+       struct qaob *aob;
+       struct qeth_qdio_out_q *q;
+       struct qeth_qdio_out_buffer *next_pending;
 };
 
 struct qeth_card;
@@ -426,7 +452,8 @@ enum qeth_out_q_states {
 
 struct qeth_qdio_out_q {
        struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
-       struct qeth_qdio_out_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
+       struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q];
+       struct qdio_outbuf_state *bufstates; /* convenience pointer */
        int queue_no;
        struct qeth_card *card;
        atomic_t state;
@@ -447,7 +474,9 @@ struct qeth_qdio_out_q {
 struct qeth_qdio_info {
        atomic_t state;
        /* input */
+       int no_in_queues;
        struct qeth_qdio_q *in_q;
+       struct qeth_qdio_q *c_q;
        struct qeth_qdio_buffer_pool in_buf_pool;
        struct qeth_qdio_buffer_pool init_pool;
        int in_buf_size;
@@ -455,6 +484,7 @@ struct qeth_qdio_info {
        /* output */
        int no_out_queues;
        struct qeth_qdio_out_q **out_qs;
+       struct qdio_outbuf_state *out_bufstates;
 
        /* priority queueing */
        int do_prio_queueing;
@@ -526,6 +556,12 @@ enum qeth_cmd_buffer_state {
        BUF_STATE_PROCESSED,
 };
 
+enum qeth_cq {
+       QETH_CQ_DISABLED = 0,
+       QETH_CQ_ENABLED = 1,
+       QETH_CQ_NOTAVAILABLE = 2,
+};
+
 struct qeth_ipato {
        int enabled;
        int invert4;
@@ -650,6 +686,8 @@ struct qeth_card_options {
        int rx_sg_cb;
        enum qeth_ipa_isolation_modes isolation;
        int sniffer;
+       enum qeth_cq cq;
+       char hsuid[9];
 };
 
 /*
@@ -747,6 +785,8 @@ struct qeth_card {
        struct mutex discipline_mutex;
        struct napi_struct napi;
        struct qeth_rx rx;
+       struct delayed_work buffer_reclaim_work;
+       int reclaim_index;
 };
 
 struct qeth_card_list_struct {
@@ -812,6 +852,7 @@ int qeth_core_create_device_attributes(struct device *);
 void qeth_core_remove_device_attributes(struct device *);
 int qeth_core_create_osn_attributes(struct device *);
 void qeth_core_remove_osn_attributes(struct device *);
+void qeth_buffer_reclaim_work(struct work_struct *);
 
 /* exports for qeth discipline device drivers */
 extern struct qeth_card_list_struct qeth_core_card_list;
@@ -840,7 +881,7 @@ int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
                unsigned int, const char *);
 void qeth_queue_input_buffer(struct qeth_card *, int);
 struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
-               struct qdio_buffer *, struct qdio_buffer_element **, int *,
+               struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *,
                struct qeth_hdr **);
 void qeth_schedule_recovery(struct qeth_card *);
 void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
@@ -887,6 +928,7 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
 int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
 int qeth_set_access_ctrl_online(struct qeth_card *card);
 int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
+int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
 int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
 int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
 
index 4550573c25e5161a57fede7f520e7aa23428a7fd..97172f8a15b7a8eccfb0baeb514d08193752b97a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mii.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
+#include <net/iucv/af_iucv.h>
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
@@ -44,6 +45,7 @@ struct qeth_card_list_struct qeth_core_card_list;
 EXPORT_SYMBOL_GPL(qeth_core_card_list);
 struct kmem_cache *qeth_core_header_cache;
 EXPORT_SYMBOL_GPL(qeth_core_header_cache);
+static struct kmem_cache *qeth_qdio_outbuf_cache;
 
 static struct device *qeth_core_root_dev;
 static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY;
@@ -56,6 +58,14 @@ static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *);
 static void qeth_setup_ccw(struct qeth_channel *, unsigned char *, __u32);
 static void qeth_free_buffer_pool(struct qeth_card *);
 static int qeth_qdio_establish(struct qeth_card *);
+static void qeth_free_qdio_buffers(struct qeth_card *);
+static void qeth_notify_skbs(struct qeth_qdio_out_q *queue,
+               struct qeth_qdio_out_buffer *buf,
+               enum iucv_tx_notify notification);
+static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf);
+static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+               struct qeth_qdio_out_buffer *buf,
+               enum qeth_qdio_buffer_states newbufstate);
 
 
 static inline const char *qeth_get_cardname(struct qeth_card *card)
@@ -199,7 +209,7 @@ static int qeth_alloc_buffer_pool(struct qeth_card *card)
 
        QETH_CARD_TEXT(card, 5, "alocpool");
        for (i = 0; i < card->qdio.init_pool.buf_count; ++i) {
-               pool_entry = kmalloc(sizeof(*pool_entry), GFP_KERNEL);
+               pool_entry = kzalloc(sizeof(*pool_entry), GFP_KERNEL);
                if (!pool_entry) {
                        qeth_free_buffer_pool(card);
                        return -ENOMEM;
@@ -239,6 +249,196 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
 }
 EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
 
+static inline int qeth_cq_init(struct qeth_card *card)
+{
+       int rc;
+
+       if (card->options.cq == QETH_CQ_ENABLED) {
+               QETH_DBF_TEXT(SETUP, 2, "cqinit");
+               memset(card->qdio.c_q->qdio_bufs, 0,
+                      QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
+               card->qdio.c_q->next_buf_to_init = 127;
+               rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT,
+                            card->qdio.no_in_queues - 1, 0,
+                            127);
+               if (rc) {
+                       QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
+                       goto out;
+               }
+       }
+       rc = 0;
+out:
+       return rc;
+}
+
+static inline int qeth_alloc_cq(struct qeth_card *card)
+{
+       int rc;
+
+       if (card->options.cq == QETH_CQ_ENABLED) {
+               int i;
+               struct qdio_outbuf_state *outbuf_states;
+
+               QETH_DBF_TEXT(SETUP, 2, "cqon");
+               card->qdio.c_q = kzalloc(sizeof(struct qeth_qdio_q),
+                                        GFP_KERNEL);
+               if (!card->qdio.c_q) {
+                       rc = -1;
+                       goto kmsg_out;
+               }
+               QETH_DBF_HEX(SETUP, 2, &card->qdio.c_q, sizeof(void *));
+
+               for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
+                       card->qdio.c_q->bufs[i].buffer =
+                               &card->qdio.c_q->qdio_bufs[i];
+               }
+
+               card->qdio.no_in_queues = 2;
+
+               card->qdio.out_bufstates = (struct qdio_outbuf_state *)
+                       kzalloc(card->qdio.no_out_queues *
+                               QDIO_MAX_BUFFERS_PER_Q *
+                               sizeof(struct qdio_outbuf_state), GFP_KERNEL);
+               outbuf_states = card->qdio.out_bufstates;
+               if (outbuf_states == NULL) {
+                       rc = -1;
+                       goto free_cq_out;
+               }
+               for (i = 0; i < card->qdio.no_out_queues; ++i) {
+                       card->qdio.out_qs[i]->bufstates = outbuf_states;
+                       outbuf_states += QDIO_MAX_BUFFERS_PER_Q;
+               }
+       } else {
+               QETH_DBF_TEXT(SETUP, 2, "nocq");
+               card->qdio.c_q = NULL;
+               card->qdio.no_in_queues = 1;
+       }
+       QETH_DBF_TEXT_(SETUP, 2, "iqc%d", card->qdio.no_in_queues);
+       rc = 0;
+out:
+       return rc;
+free_cq_out:
+       kfree(card->qdio.c_q);
+       card->qdio.c_q = NULL;
+kmsg_out:
+       dev_err(&card->gdev->dev, "Failed to create completion queue\n");
+       goto out;
+}
+
+static inline void qeth_free_cq(struct qeth_card *card)
+{
+       if (card->qdio.c_q) {
+               --card->qdio.no_in_queues;
+               kfree(card->qdio.c_q);
+               card->qdio.c_q = NULL;
+       }
+       kfree(card->qdio.out_bufstates);
+       card->qdio.out_bufstates = NULL;
+}
+
+static inline enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
+       int delayed) {
+       enum iucv_tx_notify n;
+
+       switch (sbalf15) {
+       case 0:
+               n = delayed ? TX_NOTIFY_DELAYED_OK : TX_NOTIFY_OK;
+               break;
+       case 4:
+       case 16:
+       case 17:
+       case 18:
+               n = delayed ? TX_NOTIFY_DELAYED_UNREACHABLE :
+                       TX_NOTIFY_UNREACHABLE;
+               break;
+       default:
+               n = delayed ? TX_NOTIFY_DELAYED_GENERALERROR :
+                       TX_NOTIFY_GENERALERROR;
+               break;
+       }
+
+       return n;
+}
+
+static inline void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q,
+       int bidx, int forced_cleanup)
+{
+       if (q->bufs[bidx]->next_pending != NULL) {
+               struct qeth_qdio_out_buffer *head = q->bufs[bidx];
+               struct qeth_qdio_out_buffer *c = q->bufs[bidx]->next_pending;
+
+               while (c) {
+                       if (forced_cleanup ||
+                           atomic_read(&c->state) ==
+                             QETH_QDIO_BUF_HANDLED_DELAYED) {
+                               struct qeth_qdio_out_buffer *f = c;
+                               QETH_CARD_TEXT(f->q->card, 5, "fp");
+                               QETH_CARD_TEXT_(f->q->card, 5, "%lx", (long) f);
+                               /* release here to avoid interleaving between
+                                  outbound tasklet and inbound tasklet
+                                  regarding notifications and lifecycle */
+                               qeth_release_skbs(c);
+
+                               c = f->next_pending;
+                               BUG_ON(head->next_pending != f);
+                               head->next_pending = c;
+                               kmem_cache_free(qeth_qdio_outbuf_cache, f);
+                       } else {
+                               head = c;
+                               c = c->next_pending;
+                       }
+
+               }
+       }
+}
+
+
+static inline void qeth_qdio_handle_aob(struct qeth_card *card,
+               unsigned long phys_aob_addr) {
+       struct qaob *aob;
+       struct qeth_qdio_out_buffer *buffer;
+       enum iucv_tx_notify notification;
+
+       aob = (struct qaob *) phys_to_virt(phys_aob_addr);
+       QETH_CARD_TEXT(card, 5, "haob");
+       QETH_CARD_TEXT_(card, 5, "%lx", phys_aob_addr);
+       buffer = (struct qeth_qdio_out_buffer *) aob->user1;
+       QETH_CARD_TEXT_(card, 5, "%lx", aob->user1);
+
+       BUG_ON(buffer == NULL);
+
+       if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED,
+                          QETH_QDIO_BUF_IN_CQ) == QETH_QDIO_BUF_PRIMED) {
+               notification = TX_NOTIFY_OK;
+       } else {
+               BUG_ON(atomic_read(&buffer->state) != QETH_QDIO_BUF_PENDING);
+
+               atomic_set(&buffer->state, QETH_QDIO_BUF_IN_CQ);
+               notification = TX_NOTIFY_DELAYED_OK;
+       }
+
+       if (aob->aorc != 0)  {
+               QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc);
+               notification = qeth_compute_cq_notification(aob->aorc, 1);
+       }
+       qeth_notify_skbs(buffer->q, buffer, notification);
+
+       buffer->aob = NULL;
+       qeth_clear_output_buffer(buffer->q, buffer,
+                               QETH_QDIO_BUF_HANDLED_DELAYED);
+       /* from here on: do not touch buffer anymore */
+       qdio_release_aob(aob);
+}
+
+static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue)
+{
+       return card->options.cq == QETH_CQ_ENABLED &&
+           card->qdio.c_q != NULL &&
+           queue != 0 &&
+           queue == card->qdio.no_in_queues - 1;
+}
+
+
 static int qeth_issue_next_read(struct qeth_card *card)
 {
        int rc;
@@ -589,7 +789,7 @@ static int qeth_setup_channel(struct qeth_channel *channel)
        QETH_DBF_TEXT(SETUP, 2, "setupch");
        for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) {
                channel->iob[cnt].data =
-                       kmalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL);
+                       kzalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL);
                if (channel->iob[cnt].data == NULL)
                        break;
                channel->iob[cnt].state = BUF_STATE_FREE;
@@ -681,6 +881,7 @@ EXPORT_SYMBOL_GPL(qeth_do_run_thread);
 void qeth_schedule_recovery(struct qeth_card *card)
 {
        QETH_CARD_TEXT(card, 2, "startrec");
+       WARN_ON(1);
        if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
                schedule_work(&card->kernel_thread_starter);
 }
@@ -883,22 +1084,60 @@ out:
        return;
 }
 
-static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
-               struct qeth_qdio_out_buffer *buf)
+static void qeth_notify_skbs(struct qeth_qdio_out_q *q,
+               struct qeth_qdio_out_buffer *buf,
+               enum iucv_tx_notify notification)
 {
-       int i;
        struct sk_buff *skb;
 
-       /* is PCI flag set on buffer? */
-       if (buf->buffer->element[0].sflags & SBAL_SFLAGS0_PCI_REQ)
-               atomic_dec(&queue->set_pci_flags_count);
+       if (skb_queue_empty(&buf->skb_list))
+               goto out;
+       skb = skb_peek(&buf->skb_list);
+       while (skb) {
+               QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification);
+               QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb);
+               if (skb->protocol == ETH_P_AF_IUCV) {
+                       if (skb->sk) {
+                               struct iucv_sock *iucv = iucv_sk(skb->sk);
+                               iucv->sk_txnotify(skb, notification);
+                       }
+               }
+               if (skb_queue_is_last(&buf->skb_list, skb))
+                       skb = NULL;
+               else
+                       skb = skb_queue_next(&buf->skb_list, skb);
+       }
+out:
+       return;
+}
+
+static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf)
+{
+       struct sk_buff *skb;
 
        skb = skb_dequeue(&buf->skb_list);
        while (skb) {
+               QETH_CARD_TEXT(buf->q->card, 5, "skbr");
+               QETH_CARD_TEXT_(buf->q->card, 5, "%lx", (long) skb);
                atomic_dec(&skb->users);
                dev_kfree_skb_any(skb);
                skb = skb_dequeue(&buf->skb_list);
        }
+}
+
+static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+               struct qeth_qdio_out_buffer *buf,
+               enum qeth_qdio_buffer_states newbufstate)
+{
+       int i;
+
+       /* is PCI flag set on buffer? */
+       if (buf->buffer->element[0].sflags & SBAL_SFLAGS0_PCI_REQ)
+               atomic_dec(&queue->set_pci_flags_count);
+
+       if (newbufstate == QETH_QDIO_BUF_EMPTY) {
+               qeth_release_skbs(buf);
+       }
        for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
                if (buf->buffer->element[i].addr && buf->is_header[i])
                        kmem_cache_free(qeth_core_header_cache,
@@ -912,21 +1151,36 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
        buf->buffer->element[15].eflags = 0;
        buf->buffer->element[15].sflags = 0;
        buf->next_element_to_fill = 0;
-       atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
+       atomic_set(&buf->state, newbufstate);
+}
+
+static void qeth_clear_outq_buffers(struct qeth_qdio_out_q *q, int free)
+{
+       int j;
+
+       for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
+               if (!q->bufs[j])
+                       continue;
+               qeth_cleanup_handled_pending(q, j, free);
+               qeth_clear_output_buffer(q, q->bufs[j], QETH_QDIO_BUF_EMPTY);
+               if (free) {
+                       kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]);
+                       q->bufs[j] = NULL;
+               }
+       }
 }
 
 void qeth_clear_qdio_buffers(struct qeth_card *card)
 {
-       int i, j;
+       int i;
 
        QETH_CARD_TEXT(card, 2, "clearqdbf");
        /* clear outbound buffers to free skbs */
-       for (i = 0; i < card->qdio.no_out_queues; ++i)
+       for (i = 0; i < card->qdio.no_out_queues; ++i) {
                if (card->qdio.out_qs[i]) {
-                       for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
-                               qeth_clear_output_buffer(card->qdio.out_qs[i],
-                                               &card->qdio.out_qs[i]->bufs[j]);
+                       qeth_clear_outq_buffers(card->qdio.out_qs[i], 0);
                }
+       }
 }
 EXPORT_SYMBOL_GPL(qeth_clear_qdio_buffers);
 
@@ -950,6 +1204,11 @@ static void qeth_free_qdio_buffers(struct qeth_card *card)
        if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
                QETH_QDIO_UNINITIALIZED)
                return;
+
+       qeth_free_cq(card);
+       cancel_delayed_work_sync(&card->buffer_reclaim_work);
+       for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
+               kfree_skb(card->qdio.in_q->bufs[j].rx_skb);
        kfree(card->qdio.in_q);
        card->qdio.in_q = NULL;
        /* inbound buffer pool */
@@ -957,9 +1216,7 @@ static void qeth_free_qdio_buffers(struct qeth_card *card)
        /* free outbound qdio_qs */
        if (card->qdio.out_qs) {
                for (i = 0; i < card->qdio.no_out_queues; ++i) {
-                       for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
-                               qeth_clear_output_buffer(card->qdio.out_qs[i],
-                                               &card->qdio.out_qs[i]->bufs[j]);
+                       qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
                        kfree(card->qdio.out_qs[i]);
                }
                kfree(card->qdio.out_qs);
@@ -995,27 +1252,29 @@ static void qeth_get_channel_path_desc(struct qeth_card *card)
        ccwdev = card->data.ccwdev;
        chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0);
        if (chp_dsc != NULL) {
-               /* CHPP field bit 6 == 1 -> single queue */
-               if ((chp_dsc->chpp & 0x02) == 0x02) {
-                       if ((atomic_read(&card->qdio.state) !=
-                               QETH_QDIO_UNINITIALIZED) &&
-                           (card->qdio.no_out_queues == 4))
-                               /* change from 4 to 1 outbound queues */
-                               qeth_free_qdio_buffers(card);
-                       card->qdio.no_out_queues = 1;
-                       if (card->qdio.default_out_queue != 0)
-                               dev_info(&card->gdev->dev,
+               if (card->info.type != QETH_CARD_TYPE_IQD) {
+                       /* CHPP field bit 6 == 1 -> single queue */
+                       if ((chp_dsc->chpp & 0x02) == 0x02) {
+                               if ((atomic_read(&card->qdio.state) !=
+                                       QETH_QDIO_UNINITIALIZED) &&
+                                   (card->qdio.no_out_queues == 4))
+                                       /* change from 4 to 1 outbound queues */
+                                       qeth_free_qdio_buffers(card);
+                               card->qdio.no_out_queues = 1;
+                               if (card->qdio.default_out_queue != 0)
+                                       dev_info(&card->gdev->dev,
                                        "Priority Queueing not supported\n");
-                       card->qdio.default_out_queue = 0;
-               } else {
-                       if ((atomic_read(&card->qdio.state) !=
-                               QETH_QDIO_UNINITIALIZED) &&
-                           (card->qdio.no_out_queues == 1)) {
-                               /* change from 1 to 4 outbound queues */
-                               qeth_free_qdio_buffers(card);
-                               card->qdio.default_out_queue = 2;
+                               card->qdio.default_out_queue = 0;
+                       } else {
+                               if ((atomic_read(&card->qdio.state) !=
+                                       QETH_QDIO_UNINITIALIZED) &&
+                                   (card->qdio.no_out_queues == 1)) {
+                                       /* change from 1 to 4 outbound queues */
+                                       qeth_free_qdio_buffers(card);
+                                       card->qdio.default_out_queue = 2;
+                               }
+                               card->qdio.no_out_queues = 4;
                        }
-                       card->qdio.no_out_queues = 4;
                }
                card->info.func_level = 0x4100 + chp_dsc->desc;
                kfree(chp_dsc);
@@ -1051,6 +1310,7 @@ static void qeth_set_intial_options(struct qeth_card *card)
        card->options.performance_stats = 0;
        card->options.rx_sg_cb = QETH_RX_SG_CB;
        card->options.isolation = ISOLATION_MODE_NONE;
+       card->options.cq = QETH_CQ_DISABLED;
 }
 
 static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
@@ -1119,6 +1379,7 @@ static int qeth_setup_card(struct qeth_card *card)
        card->ipato.invert6 = 0;
        /* init QDIO stuff */
        qeth_init_qdio_info(card);
+       INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);
        return 0;
 }
 
@@ -1140,7 +1401,7 @@ static struct qeth_card *qeth_alloc_card(void)
        if (!card)
                goto out;
        QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
-       card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
+       card->ip_tbd_list = kzalloc(sizeof(struct list_head), GFP_KERNEL);
        if (!card->ip_tbd_list) {
                QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
                goto out_card;
@@ -1180,6 +1441,7 @@ static int qeth_determine_card_type(struct qeth_card *card)
                        card->info.type = known_devices[i][QETH_DEV_MODEL_IND];
                        card->qdio.no_out_queues =
                                known_devices[i][QETH_QUEUE_NO_IND];
+                       card->qdio.no_in_queues = 1;
                        card->info.is_multicast_different =
                                known_devices[i][QETH_MULTICAST_IND];
                        qeth_get_channel_path_desc(card);
@@ -2027,6 +2289,37 @@ static int qeth_ulp_setup(struct qeth_card *card)
        return rc;
 }
 
+static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx)
+{
+       int rc;
+       struct qeth_qdio_out_buffer *newbuf;
+
+       rc = 0;
+       newbuf = kmem_cache_zalloc(qeth_qdio_outbuf_cache, GFP_ATOMIC);
+       if (!newbuf) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       newbuf->buffer = &q->qdio_bufs[bidx];
+       skb_queue_head_init(&newbuf->skb_list);
+       lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key);
+       newbuf->q = q;
+       newbuf->aob = NULL;
+       newbuf->next_pending = q->bufs[bidx];
+       atomic_set(&newbuf->state, QETH_QDIO_BUF_EMPTY);
+       q->bufs[bidx] = newbuf;
+       if (q->bufstates) {
+               q->bufstates[bidx].user = newbuf;
+               QETH_CARD_TEXT_(q->card, 2, "nbs%d", bidx);
+               QETH_CARD_TEXT_(q->card, 2, "%lx", (long) newbuf);
+               QETH_CARD_TEXT_(q->card, 2, "%lx",
+                               (long) newbuf->next_pending);
+       }
+out:
+       return rc;
+}
+
+
 static int qeth_alloc_qdio_buffers(struct qeth_card *card)
 {
        int i, j;
@@ -2037,52 +2330,63 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card)
                QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
                return 0;
 
-       card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
-                                 GFP_KERNEL);
+       card->qdio.in_q = kzalloc(sizeof(struct qeth_qdio_q),
+                                  GFP_KERNEL);
        if (!card->qdio.in_q)
                goto out_nomem;
        QETH_DBF_TEXT(SETUP, 2, "inq");
        QETH_DBF_HEX(SETUP, 2, &card->qdio.in_q, sizeof(void *));
        memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
        /* give inbound qeth_qdio_buffers their qdio_buffers */
-       for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
+       for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
                card->qdio.in_q->bufs[i].buffer =
                        &card->qdio.in_q->qdio_bufs[i];
+               card->qdio.in_q->bufs[i].rx_skb = NULL;
+       }
        /* inbound buffer pool */
        if (qeth_alloc_buffer_pool(card))
                goto out_freeinq;
+
        /* outbound */
        card->qdio.out_qs =
-               kmalloc(card->qdio.no_out_queues *
+               kzalloc(card->qdio.no_out_queues *
                        sizeof(struct qeth_qdio_out_q *), GFP_KERNEL);
        if (!card->qdio.out_qs)
                goto out_freepool;
        for (i = 0; i < card->qdio.no_out_queues; ++i) {
-               card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
+               card->qdio.out_qs[i] = kzalloc(sizeof(struct qeth_qdio_out_q),
                                               GFP_KERNEL);
                if (!card->qdio.out_qs[i])
                        goto out_freeoutq;
                QETH_DBF_TEXT_(SETUP, 2, "outq %i", i);
                QETH_DBF_HEX(SETUP, 2, &card->qdio.out_qs[i], sizeof(void *));
-               memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q));
                card->qdio.out_qs[i]->queue_no = i;
                /* give outbound qeth_qdio_buffers their qdio_buffers */
                for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
-                       card->qdio.out_qs[i]->bufs[j].buffer =
-                               &card->qdio.out_qs[i]->qdio_bufs[j];
-                       skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j].
-                                           skb_list);
-                       lockdep_set_class(
-                               &card->qdio.out_qs[i]->bufs[j].skb_list.lock,
-                               &qdio_out_skb_queue_key);
-                       INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list);
+                       BUG_ON(card->qdio.out_qs[i]->bufs[j] != NULL);
+                       if (qeth_init_qdio_out_buf(card->qdio.out_qs[i], j))
+                               goto out_freeoutqbufs;
                }
        }
+
+       /* completion */
+       if (qeth_alloc_cq(card))
+               goto out_freeoutq;
+
        return 0;
 
+out_freeoutqbufs:
+       while (j > 0) {
+               --j;
+               kmem_cache_free(qeth_qdio_outbuf_cache,
+                               card->qdio.out_qs[i]->bufs[j]);
+               card->qdio.out_qs[i]->bufs[j] = NULL;
+       }
 out_freeoutq:
-       while (i > 0)
+       while (i > 0) {
                kfree(card->qdio.out_qs[--i]);
+               qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
+       }
        kfree(card->qdio.out_qs);
        card->qdio.out_qs = NULL;
 out_freepool:
@@ -2353,6 +2657,12 @@ static int qeth_init_input_buffer(struct qeth_card *card,
        struct qeth_buffer_pool_entry *pool_entry;
        int i;
 
+       if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
+               buf->rx_skb = dev_alloc_skb(QETH_RX_PULL_LEN + ETH_HLEN);
+               if (!buf->rx_skb)
+                       return 1;
+       }
+
        pool_entry = qeth_find_free_buffer_pool_entry(card);
        if (!pool_entry)
                return 1;
@@ -2399,13 +2709,21 @@ int qeth_init_qdio_queues(struct qeth_card *card)
                QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
                return rc;
        }
+
+       /* completion */
+       rc = qeth_cq_init(card);
+       if (rc) {
+               return rc;
+       }
+
        /* outbound queue */
        for (i = 0; i < card->qdio.no_out_queues; ++i) {
                memset(card->qdio.out_qs[i]->qdio_bufs, 0,
                       QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
                for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
                        qeth_clear_output_buffer(card->qdio.out_qs[i],
-                                       &card->qdio.out_qs[i]->bufs[j]);
+                                       card->qdio.out_qs[i]->bufs[j],
+                                       QETH_QDIO_BUF_EMPTY);
                }
                card->qdio.out_qs[i]->card = card;
                card->qdio.out_qs[i]->next_buf_to_fill = 0;
@@ -2734,9 +3052,19 @@ int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
 }
 EXPORT_SYMBOL_GPL(qeth_check_qdio_errors);
 
+void qeth_buffer_reclaim_work(struct work_struct *work)
+{
+       struct qeth_card *card = container_of(work, struct qeth_card,
+               buffer_reclaim_work.work);
+
+       QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index);
+       qeth_queue_input_buffer(card, card->reclaim_index);
+}
+
 void qeth_queue_input_buffer(struct qeth_card *card, int index)
 {
        struct qeth_qdio_q *queue = card->qdio.in_q;
+       struct list_head *lh;
        int count;
        int i;
        int rc;
@@ -2768,6 +3096,20 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index)
                        atomic_add_unless(&card->force_alloc_skb, -1, 0);
                }
 
+               if (!count) {
+                       i = 0;
+                       list_for_each(lh, &card->qdio.in_buf_pool.entry_list)
+                               i++;
+                       if (i == card->qdio.in_buf_pool.buf_count) {
+                               QETH_CARD_TEXT(card, 2, "qsarbw");
+                               card->reclaim_index = index;
+                               schedule_delayed_work(
+                                       &card->buffer_reclaim_work,
+                                       QETH_RECLAIM_WORK_TIME);
+                       }
+                       return;
+               }
+
                /*
                 * according to old code it should be avoided to requeue all
                 * 128 buffers in order to benefit from PCI avoidance.
@@ -2787,8 +3129,6 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index)
                                qeth_get_micros() -
                                card->perf_stats.inbound_do_qdio_start_time;
                if (rc) {
-                       dev_warn(&card->gdev->dev,
-                               "QDIO reported an error, rc=%i\n", rc);
                        QETH_CARD_TEXT(card, 2, "qinberr");
                }
                queue->next_buf_to_init = (queue->next_buf_to_init + count) %
@@ -2862,12 +3202,12 @@ static int qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
                                queue->card->perf_stats.sc_p_dp++;
                        queue->do_pack = 0;
                        /* flush packing buffers */
-                       buffer = &queue->bufs[queue->next_buf_to_fill];
+                       buffer = queue->bufs[queue->next_buf_to_fill];
                        if ((atomic_read(&buffer->state) ==
                                                QETH_QDIO_BUF_EMPTY) &&
                            (buffer->next_element_to_fill > 0)) {
                                atomic_set(&buffer->state,
-                                               QETH_QDIO_BUF_PRIMED);
+                                          QETH_QDIO_BUF_PRIMED);
                                flush_count++;
                                queue->next_buf_to_fill =
                                        (queue->next_buf_to_fill + 1) %
@@ -2878,6 +3218,7 @@ static int qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
        return flush_count;
 }
 
+
 /*
  * Called to flush a packing buffer if no more pci flags are on the queue.
  * Checks if there is a packing buffer and prepares it to be flushed.
@@ -2887,7 +3228,7 @@ static int qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
 {
        struct qeth_qdio_out_buffer *buffer;
 
-       buffer = &queue->bufs[queue->next_buf_to_fill];
+       buffer = queue->bufs[queue->next_buf_to_fill];
        if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
           (buffer->next_element_to_fill > 0)) {
                /* it's a packing buffer */
@@ -2908,10 +3249,14 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
        unsigned int qdio_flags;
 
        for (i = index; i < index + count; ++i) {
-               buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
+               int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
+               buf = queue->bufs[bidx];
                buf->buffer->element[buf->next_element_to_fill - 1].eflags |=
                                SBAL_EFLAGS_LAST_ENTRY;
 
+               if (queue->bufstates)
+                       queue->bufstates[bidx].user = buf;
+
                if (queue->card->info.type == QETH_CARD_TYPE_IQD)
                        continue;
 
@@ -2963,6 +3308,9 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
                if (rc == QDIO_ERROR_SIGA_TARGET)
                        return;
                QETH_CARD_TEXT(queue->card, 2, "flushbuf");
+               QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no);
+               QETH_CARD_TEXT_(queue->card, 2, " idx%d", index);
+               QETH_CARD_TEXT_(queue->card, 2, " c%d", count);
                QETH_CARD_TEXT_(queue->card, 2, " err%d", rc);
 
                /* this must not happen under normal circumstances. if it
@@ -3024,14 +3372,120 @@ void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
 }
 EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
 
+int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
+{
+       int rc;
+
+       if (card->options.cq ==  QETH_CQ_NOTAVAILABLE) {
+               rc = -1;
+               goto out;
+       } else {
+               if (card->options.cq == cq) {
+                       rc = 0;
+                       goto out;
+               }
+
+               if (card->state != CARD_STATE_DOWN &&
+                   card->state != CARD_STATE_RECOVER) {
+                       rc = -1;
+                       goto out;
+               }
+
+               qeth_free_qdio_buffers(card);
+               card->options.cq = cq;
+               rc = 0;
+       }
+out:
+       return rc;
+
+}
+EXPORT_SYMBOL_GPL(qeth_configure_cq);
+
+
+static void qeth_qdio_cq_handler(struct qeth_card *card,
+               unsigned int qdio_err,
+               unsigned int queue, int first_element, int count) {
+       struct qeth_qdio_q *cq = card->qdio.c_q;
+       int i;
+       int rc;
+
+       if (!qeth_is_cq(card, queue))
+               goto out;
+
+       QETH_CARD_TEXT_(card, 5, "qcqhe%d", first_element);
+       QETH_CARD_TEXT_(card, 5, "qcqhc%d", count);
+       QETH_CARD_TEXT_(card, 5, "qcqherr%d", qdio_err);
+
+       if (qdio_err) {
+               netif_stop_queue(card->dev);
+               qeth_schedule_recovery(card);
+               goto out;
+       }
+
+       if (card->options.performance_stats) {
+               card->perf_stats.cq_cnt++;
+               card->perf_stats.cq_start_time = qeth_get_micros();
+       }
+
+       for (i = first_element; i < first_element + count; ++i) {
+               int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
+               struct qdio_buffer *buffer = &cq->qdio_bufs[bidx];
+               int e;
+
+               e = 0;
+               while (buffer->element[e].addr) {
+                       unsigned long phys_aob_addr;
+
+                       phys_aob_addr = (unsigned long) buffer->element[e].addr;
+                       qeth_qdio_handle_aob(card, phys_aob_addr);
+                       buffer->element[e].addr = NULL;
+                       buffer->element[e].eflags = 0;
+                       buffer->element[e].sflags = 0;
+                       buffer->element[e].length = 0;
+
+                       ++e;
+               }
+
+               buffer->element[15].eflags = 0;
+               buffer->element[15].sflags = 0;
+       }
+       rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue,
+                   card->qdio.c_q->next_buf_to_init,
+                   count);
+       if (rc) {
+               dev_warn(&card->gdev->dev,
+                       "QDIO reported an error, rc=%i\n", rc);
+               QETH_CARD_TEXT(card, 2, "qcqherr");
+       }
+       card->qdio.c_q->next_buf_to_init = (card->qdio.c_q->next_buf_to_init
+                                  + count) % QDIO_MAX_BUFFERS_PER_Q;
+
+       netif_wake_queue(card->dev);
+
+       if (card->options.performance_stats) {
+               int delta_t = qeth_get_micros();
+               delta_t -= card->perf_stats.cq_start_time;
+               card->perf_stats.cq_time += delta_t;
+       }
+out:
+       return;
+}
+
 void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
-               unsigned int queue, int first_element, int count,
+               unsigned int queue, int first_elem, int count,
                unsigned long card_ptr)
 {
        struct qeth_card *card = (struct qeth_card *)card_ptr;
 
-       if (qdio_err)
+       QETH_CARD_TEXT_(card, 2, "qihq%d", queue);
+       QETH_CARD_TEXT_(card, 2, "qiec%d", qdio_err);
+
+       if (qeth_is_cq(card, queue))
+               qeth_qdio_cq_handler(card, qdio_err, queue, first_elem, count);
+       else if (qdio_err)
                qeth_schedule_recovery(card);
+
+
 }
 EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);
 
@@ -3057,9 +3511,45 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
                        qeth_get_micros();
        }
        for (i = first_element; i < (first_element + count); ++i) {
-               buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
+               int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
+               buffer = queue->bufs[bidx];
                qeth_handle_send_error(card, buffer, qdio_error);
-               qeth_clear_output_buffer(queue, buffer);
+
+               if (queue->bufstates &&
+                   (queue->bufstates[bidx].flags &
+                    QDIO_OUTBUF_STATE_FLAG_PENDING) != 0) {
+                       BUG_ON(card->options.cq != QETH_CQ_ENABLED);
+
+                       if (atomic_cmpxchg(&buffer->state,
+                                          QETH_QDIO_BUF_PRIMED,
+                                          QETH_QDIO_BUF_PENDING) ==
+                               QETH_QDIO_BUF_PRIMED) {
+                               qeth_notify_skbs(queue, buffer,
+                                                TX_NOTIFY_PENDING);
+                       }
+                       buffer->aob = queue->bufstates[bidx].aob;
+                       QETH_CARD_TEXT_(queue->card, 5, "pel%d", bidx);
+                       QETH_CARD_TEXT(queue->card, 5, "aob");
+                       QETH_CARD_TEXT_(queue->card, 5, "%lx",
+                                       virt_to_phys(buffer->aob));
+                       BUG_ON(bidx < 0 || bidx >= QDIO_MAX_BUFFERS_PER_Q);
+                       if (qeth_init_qdio_out_buf(queue, bidx)) {
+                               QETH_CARD_TEXT(card, 2, "outofbuf");
+                               qeth_schedule_recovery(card);
+                       }
+               } else {
+                       if (card->options.cq == QETH_CQ_ENABLED) {
+                               enum iucv_tx_notify n;
+
+                               n = qeth_compute_cq_notification(
+                                       buffer->buffer->element[15].sflags, 0);
+                               qeth_notify_skbs(queue, buffer, n);
+                       }
+
+                       qeth_clear_output_buffer(queue, buffer,
+                                               QETH_QDIO_BUF_EMPTY);
+               }
+               qeth_cleanup_handled_pending(queue, bidx, 0);
        }
        atomic_sub(count, &queue->used_buffers);
        /* check if we need to do something on this outbound queue */
@@ -3291,7 +3781,7 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
                              QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
        /* ... now we've got the queue */
        index = queue->next_buf_to_fill;
-       buffer = &queue->bufs[queue->next_buf_to_fill];
+       buffer = queue->bufs[queue->next_buf_to_fill];
        /*
         * check if buffer is empty to make sure that we do not 'overtake'
         * ourselves and try to fill a buffer that is already primed
@@ -3325,7 +3815,7 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
        while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
                              QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
        start_index = queue->next_buf_to_fill;
-       buffer = &queue->bufs[queue->next_buf_to_fill];
+       buffer = queue->bufs[queue->next_buf_to_fill];
        /*
         * check if buffer is empty to make sure that we do not 'overtake'
         * ourselves and try to fill a buffer that is already primed
@@ -3347,7 +3837,7 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
                        queue->next_buf_to_fill =
                                (queue->next_buf_to_fill + 1) %
                                QDIO_MAX_BUFFERS_PER_Q;
-                       buffer = &queue->bufs[queue->next_buf_to_fill];
+                       buffer = queue->bufs[queue->next_buf_to_fill];
                        /* we did a step forward, so check buffer state
                         * again */
                        if (atomic_read(&buffer->state) !=
@@ -3925,6 +4415,20 @@ static void qeth_determine_capabilities(struct qeth_card *card)
        if (rc)
                QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
 
+       QETH_DBF_TEXT_(SETUP, 2, "qfmt%d", card->ssqd.qfmt);
+       QETH_DBF_TEXT_(SETUP, 2, "%d", card->ssqd.qdioac1);
+       QETH_DBF_TEXT_(SETUP, 2, "%d", card->ssqd.qdioac3);
+       QETH_DBF_TEXT_(SETUP, 2, "icnt%d", card->ssqd.icnt);
+       if (!((card->ssqd.qfmt != QDIO_IQDIO_QFMT) ||
+           ((card->ssqd.qdioac1 & CHSC_AC1_INITIATE_INPUTQ) == 0) ||
+           ((card->ssqd.qdioac3 & CHSC_AC3_FORMAT2_CQ_AVAILABLE) == 0))) {
+               dev_info(&card->gdev->dev,
+                       "Completion Queueing supported\n");
+       } else {
+               card->options.cq = QETH_CQ_NOTAVAILABLE;
+       }
+
+
 out_offline:
        if (ddev_offline == 1)
                ccw_device_set_offline(ddev);
@@ -3932,11 +4436,30 @@ out:
        return;
 }
 
+static inline void qeth_qdio_establish_cq(struct qeth_card *card,
+       struct qdio_buffer **in_sbal_ptrs,
+       void (**queue_start_poll) (struct ccw_device *, int, unsigned long)) {
+       int i;
+
+       if (card->options.cq == QETH_CQ_ENABLED) {
+               int offset = QDIO_MAX_BUFFERS_PER_Q *
+                            (card->qdio.no_in_queues - 1);
+               i = QDIO_MAX_BUFFERS_PER_Q * (card->qdio.no_in_queues - 1);
+               for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
+                       in_sbal_ptrs[offset + i] = (struct qdio_buffer *)
+                               virt_to_phys(card->qdio.c_q->bufs[i].buffer);
+               }
+
+               queue_start_poll[card->qdio.no_in_queues - 1] = NULL;
+       }
+}
+
 static int qeth_qdio_establish(struct qeth_card *card)
 {
        struct qdio_initialize init_data;
        char *qib_param_field;
        struct qdio_buffer **in_sbal_ptrs;
+       void (**queue_start_poll) (struct ccw_device *, int, unsigned long);
        struct qdio_buffer **out_sbal_ptrs;
        int i, j, k;
        int rc = 0;
@@ -3945,34 +4468,48 @@ static int qeth_qdio_establish(struct qeth_card *card)
 
        qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
                              GFP_KERNEL);
-       if (!qib_param_field)
-               return -ENOMEM;
+       if (!qib_param_field) {
+               rc =  -ENOMEM;
+               goto out_free_nothing;
+       }
 
        qeth_create_qib_param_field(card, qib_param_field);
        qeth_create_qib_param_field_blkt(card, qib_param_field);
 
-       in_sbal_ptrs = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(void *),
+       in_sbal_ptrs = kzalloc(card->qdio.no_in_queues *
+                              QDIO_MAX_BUFFERS_PER_Q * sizeof(void *),
                               GFP_KERNEL);
        if (!in_sbal_ptrs) {
-               kfree(qib_param_field);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto out_free_qib_param;
        }
-       for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
+       for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
                in_sbal_ptrs[i] = (struct qdio_buffer *)
                        virt_to_phys(card->qdio.in_q->bufs[i].buffer);
+       }
+
+       queue_start_poll = kzalloc(sizeof(void *) * card->qdio.no_in_queues,
+                                  GFP_KERNEL);
+       if (!queue_start_poll) {
+               rc = -ENOMEM;
+               goto out_free_in_sbals;
+       }
+       for (i = 0; i < card->qdio.no_in_queues; ++i)
+               queue_start_poll[i] = card->discipline.start_poll;
+
+       qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
 
        out_sbal_ptrs =
-               kmalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q *
+               kzalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q *
                        sizeof(void *), GFP_KERNEL);
        if (!out_sbal_ptrs) {
-               kfree(in_sbal_ptrs);
-               kfree(qib_param_field);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto out_free_queue_start_poll;
        }
        for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
                for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) {
                        out_sbal_ptrs[k] = (struct qdio_buffer *)virt_to_phys(
-                               card->qdio.out_qs[i]->bufs[j].buffer);
+                               card->qdio.out_qs[i]->bufs[j]->buffer);
                }
 
        memset(&init_data, 0, sizeof(struct qdio_initialize));
@@ -3980,14 +4517,15 @@ static int qeth_qdio_establish(struct qeth_card *card)
        init_data.q_format               = qeth_get_qdio_q_format(card);
        init_data.qib_param_field_format = 0;
        init_data.qib_param_field        = qib_param_field;
-       init_data.no_input_qs            = 1;
+       init_data.no_input_qs            = card->qdio.no_in_queues;
        init_data.no_output_qs           = card->qdio.no_out_queues;
        init_data.input_handler          = card->discipline.input_handler;
        init_data.output_handler         = card->discipline.output_handler;
-       init_data.queue_start_poll       = card->discipline.start_poll;
+       init_data.queue_start_poll       = queue_start_poll;
        init_data.int_parm               = (unsigned long) card;
        init_data.input_sbal_addr_array  = (void **) in_sbal_ptrs;
        init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
+       init_data.output_sbal_state_array = card->qdio.out_bufstates;
        init_data.scan_threshold =
                (card->info.type == QETH_CARD_TYPE_IQD) ? 8 : 32;
 
@@ -4004,10 +4542,26 @@ static int qeth_qdio_establish(struct qeth_card *card)
                        qdio_free(CARD_DDEV(card));
                }
        }
+
+       switch (card->options.cq) {
+       case QETH_CQ_ENABLED:
+               dev_info(&card->gdev->dev, "Completion Queue support enabled");
+               break;
+       case QETH_CQ_DISABLED:
+               dev_info(&card->gdev->dev, "Completion Queue support disabled");
+               break;
+       default:
+               break;
+       }
 out:
        kfree(out_sbal_ptrs);
+out_free_queue_start_poll:
+       kfree(queue_start_poll);
+out_free_in_sbals:
        kfree(in_sbal_ptrs);
+out_free_qib_param:
        kfree(qib_param_field);
+out_free_nothing:
        return rc;
 }
 
@@ -4144,29 +4698,36 @@ out:
 }
 EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);
 
-static inline int qeth_create_skb_frag(struct qdio_buffer_element *element,
+static inline int qeth_create_skb_frag(struct qeth_qdio_buffer *qethbuffer,
+               struct qdio_buffer_element *element,
                struct sk_buff **pskb, int offset, int *pfrag, int data_len)
 {
        struct page *page = virt_to_page(element->addr);
        if (*pskb == NULL) {
-               /* the upper protocol layers assume that there is data in the
-                * skb itself. Copy a small amount (64 bytes) to make them
-                * happy. */
-               *pskb = dev_alloc_skb(64 + ETH_HLEN);
-               if (!(*pskb))
-                       return -ENOMEM;
+               if (qethbuffer->rx_skb) {
+                       /* only if qeth_card.options.cq == QETH_CQ_ENABLED */
+                       *pskb = qethbuffer->rx_skb;
+                       qethbuffer->rx_skb = NULL;
+               } else {
+                       *pskb = dev_alloc_skb(QETH_RX_PULL_LEN + ETH_HLEN);
+                       if (!(*pskb))
+                               return -ENOMEM;
+               }
+
                skb_reserve(*pskb, ETH_HLEN);
-               if (data_len <= 64) {
+               if (data_len <= QETH_RX_PULL_LEN) {
                        memcpy(skb_put(*pskb, data_len), element->addr + offset,
                                data_len);
                } else {
                        get_page(page);
-                       memcpy(skb_put(*pskb, 64), element->addr + offset, 64);
-                       skb_fill_page_desc(*pskb, *pfrag, page, offset + 64,
-                               data_len - 64);
-                       (*pskb)->data_len += data_len - 64;
-                       (*pskb)->len      += data_len - 64;
-                       (*pskb)->truesize += data_len - 64;
+                       memcpy(skb_put(*pskb, QETH_RX_PULL_LEN),
+                              element->addr + offset, QETH_RX_PULL_LEN);
+                       skb_fill_page_desc(*pskb, *pfrag, page,
+                               offset + QETH_RX_PULL_LEN,
+                               data_len - QETH_RX_PULL_LEN);
+                       (*pskb)->data_len += data_len - QETH_RX_PULL_LEN;
+                       (*pskb)->len      += data_len - QETH_RX_PULL_LEN;
+                       (*pskb)->truesize += data_len - QETH_RX_PULL_LEN;
                        (*pfrag)++;
                }
        } else {
@@ -4177,15 +4738,18 @@ static inline int qeth_create_skb_frag(struct qdio_buffer_element *element,
                (*pskb)->truesize += data_len;
                (*pfrag)++;
        }
+
+
        return 0;
 }
 
 struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
-               struct qdio_buffer *buffer,
+               struct qeth_qdio_buffer *qethbuffer,
                struct qdio_buffer_element **__element, int *__offset,
                struct qeth_hdr **hdr)
 {
        struct qdio_buffer_element *element = *__element;
+       struct qdio_buffer *buffer = qethbuffer->buffer;
        int offset = *__offset;
        struct sk_buff *skb = NULL;
        int skb_len = 0;
@@ -4230,9 +4794,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
        if (!skb_len)
                return NULL;
 
-       if ((skb_len >= card->options.rx_sg_cb) &&
-           (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
-           (!atomic_read(&card->force_alloc_skb))) {
+       if (((skb_len >= card->options.rx_sg_cb) &&
+            (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
+            (!atomic_read(&card->force_alloc_skb))) ||
+           (card->options.cq == QETH_CQ_ENABLED)) {
                use_rx_sg = 1;
        } else {
                skb = dev_alloc_skb(skb_len + headroom);
@@ -4247,8 +4812,8 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
                data_len = min(skb_len, (int)(element->length - offset));
                if (data_len) {
                        if (use_rx_sg) {
-                               if (qeth_create_skb_frag(element, &skb, offset,
-                                   &frag, data_len))
+                               if (qeth_create_skb_frag(qethbuffer, element,
+                                   &skb, offset, &frag, data_len))
                                        goto no_mem;
                        } else {
                                memcpy(skb_put(skb, data_len), data_ptr,
@@ -4650,6 +5215,8 @@ static struct {
        {"tx do_QDIO count"},
        {"tx csum"},
        {"tx lin"},
+       {"cq handler count"},
+       {"cq handler time"}
 };
 
 int qeth_core_get_sset_count(struct net_device *dev, int stringset)
@@ -4708,6 +5275,8 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
        data[32] = card->perf_stats.outbound_do_qdio_cnt;
        data[33] = card->perf_stats.tx_csum;
        data[34] = card->perf_stats.tx_lin;
+       data[35] = card->perf_stats.cq_cnt;
+       data[36] = card->perf_stats.cq_time;
 }
 EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
 
@@ -4866,7 +5435,16 @@ static int __init qeth_core_init(void)
                goto slab_err;
        }
 
+       qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf",
+                       sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL);
+       if (!qeth_qdio_outbuf_cache) {
+               rc = -ENOMEM;
+               goto cqslab_err;
+       }
+
        return 0;
+cqslab_err:
+       kmem_cache_destroy(qeth_core_header_cache);
 slab_err:
        root_device_unregister(qeth_core_root_dev);
 register_err:
@@ -4891,6 +5469,7 @@ static void __exit qeth_core_exit(void)
                           &driver_attr_group);
        ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
        ccw_driver_unregister(&qeth_ccw_driver);
+       kmem_cache_destroy(qeth_qdio_outbuf_cache);
        kmem_cache_destroy(qeth_core_header_cache);
        qeth_unregister_dbf_views();
        pr_info("core functions removed\n");
index b70b47fbd6cd8ab8e6b3acc57b4bfe33e22cb571..a21ae3d549db1bce13b124aea664b14ac8bef525 100644 (file)
@@ -409,7 +409,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
        BUG_ON(!budget);
        while (budget) {
                skb = qeth_core_get_next_skb(card,
-                       card->qdio.in_q->bufs[card->rx.b_index].buffer,
+                       &card->qdio.in_q->bufs[card->rx.b_index],
                        &card->rx.b_element, &card->rx.e_offset, &hdr);
                if (!skb) {
                        *done = 1;
@@ -925,7 +925,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
        .ndo_get_stats          = qeth_get_stats,
        .ndo_start_xmit         = qeth_l2_hard_start_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = qeth_l2_set_multicast_list,
+       .ndo_set_rx_mode        = qeth_l2_set_multicast_list,
        .ndo_do_ioctl           = qeth_l2_do_ioctl,
        .ndo_set_mac_address    = qeth_l2_set_mac_address,
        .ndo_change_mtu         = qeth_change_mtu,
index 14a43aeb0c2af0c5a2df90d5dc634810e6e5c693..e367315a63f0e12890447eb0941d4c68aa6cd7d3 100644 (file)
@@ -63,5 +63,9 @@ int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
 void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
                        const u8 *);
 int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
+struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions);
+int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *);
+int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *);
+void qeth_l3_set_ip_addr_list(struct qeth_card *);
 
 #endif /* __QETH_L3_H__ */
index fafb8c299540e02218161711591ac049ec65dbb5..ce735204d317c75470b0920b48406a93007fa781 100644 (file)
@@ -29,6 +29,7 @@
 #include <net/ip.h>
 #include <net/arp.h>
 #include <net/ip6_checksum.h>
+#include <net/iucv/af_iucv.h>
 
 #include "qeth_l3.h"
 
@@ -267,7 +268,7 @@ static int __qeth_l3_insert_ip_todo(struct qeth_card *card,
        }
 }
 
-static int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
+int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
 {
        unsigned long flags;
        int rc = 0;
@@ -286,7 +287,7 @@ static int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
        return rc;
 }
 
-static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
+int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
 {
        unsigned long flags;
        int rc = 0;
@@ -305,7 +306,7 @@ static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
 }
 
 
-static struct qeth_ipaddr *qeth_l3_get_addr_buffer(
+struct qeth_ipaddr *qeth_l3_get_addr_buffer(
                                enum qeth_prot_versions prot)
 {
        struct qeth_ipaddr *addr;
@@ -421,7 +422,7 @@ again:
        list_splice(&fail_list, &card->ip_list);
 }
 
-static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
+void qeth_l3_set_ip_addr_list(struct qeth_card *card)
 {
        struct list_head *tbd_list;
        struct qeth_ipaddr *todo, *addr;
@@ -438,7 +439,7 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
 
        spin_lock_irqsave(&card->ip_lock, flags);
        tbd_list = card->ip_tbd_list;
-       card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
+       card->ip_tbd_list = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
        if (!card->ip_tbd_list) {
                QETH_CARD_TEXT(card, 0, "silnomem");
                card->ip_tbd_list = tbd_list;
@@ -1993,12 +1994,13 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
        __u16 vlan_tag = 0;
        int is_vlan;
        unsigned int len;
+       __u16 magic;
 
        *done = 0;
        BUG_ON(!budget);
        while (budget) {
                skb = qeth_core_get_next_skb(card,
-                       card->qdio.in_q->bufs[card->rx.b_index].buffer,
+                       &card->qdio.in_q->bufs[card->rx.b_index],
                        &card->rx.b_element, &card->rx.e_offset, &hdr);
                if (!skb) {
                        *done = 1;
@@ -2007,12 +2009,26 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
                skb->dev = card->dev;
                switch (hdr->hdr.l3.id) {
                case QETH_HEADER_TYPE_LAYER3:
-                       is_vlan = qeth_l3_rebuild_skb(card, skb, hdr,
+                       magic = *(__u16 *)skb->data;
+                       if ((card->info.type == QETH_CARD_TYPE_IQD) &&
+                           (magic == ETH_P_AF_IUCV)) {
+                               skb->protocol = ETH_P_AF_IUCV;
+                               skb->pkt_type = PACKET_HOST;
+                               skb->mac_header = NET_SKB_PAD;
+                               skb->dev = card->dev;
+                               len = skb->len;
+                               card->dev->header_ops->create(skb, card->dev, 0,
+                                       card->dev->dev_addr, "FAKELL",
+                                       card->dev->addr_len);
+                               netif_receive_skb(skb);
+                       } else {
+                               is_vlan = qeth_l3_rebuild_skb(card, skb, hdr,
                                                      &vlan_tag);
-                       len = skb->len;
-                       if (is_vlan && !card->options.sniffer)
-                               __vlan_hwaccel_put_tag(skb, vlan_tag);
-                       napi_gro_receive(&card->napi, skb);
+                               len = skb->len;
+                               if (is_vlan && !card->options.sniffer)
+                                       __vlan_hwaccel_put_tag(skb, vlan_tag);
+                               napi_gro_receive(&card->napi, skb);
+                       }
                        break;
                case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
                        skb->pkt_type = PACKET_HOST;
@@ -2784,6 +2800,30 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
        return cast_type;
 }
 
+static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,
+               struct qeth_hdr *hdr, struct sk_buff *skb)
+{
+       char daddr[16];
+       struct af_iucv_trans_hdr *iucv_hdr;
+
+       skb_pull(skb, 14);
+       card->dev->header_ops->create(skb, card->dev, 0,
+                                     card->dev->dev_addr, card->dev->dev_addr,
+                                     card->dev->addr_len);
+       skb_pull(skb, 14);
+       iucv_hdr = (struct af_iucv_trans_hdr *)skb->data;
+       memset(hdr, 0, sizeof(struct qeth_hdr));
+       hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
+       hdr->hdr.l3.ext_flags = 0;
+       hdr->hdr.l3.length = skb->len;
+       hdr->hdr.l3.flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
+       memset(daddr, 0, sizeof(daddr));
+       daddr[0] = 0xfe;
+       daddr[1] = 0x80;
+       memcpy(&daddr[8], iucv_hdr->destUserID, 8);
+       memcpy(hdr->hdr.l3.dest_addr, daddr, 16);
+}
+
 static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                struct sk_buff *skb, int ipv, int cast_type)
 {
@@ -2936,8 +2976,11 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        int data_offset = -1;
        int nr_frags;
 
-       if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) ||
-            card->options.sniffer)
+       if (((card->info.type == QETH_CARD_TYPE_IQD) &&
+            (((card->options.cq != QETH_CQ_ENABLED) && !ipv) ||
+             ((card->options.cq == QETH_CQ_ENABLED) &&
+              (skb->protocol != ETH_P_AF_IUCV)))) ||
+           card->options.sniffer)
                        goto tx_drop;
 
        if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@@ -2959,7 +3002,10 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
            (skb_shinfo(skb)->nr_frags == 0)) {
                new_skb = skb;
-               data_offset = ETH_HLEN;
+               if (new_skb->protocol == ETH_P_AF_IUCV)
+                       data_offset = 0;
+               else
+                       data_offset = ETH_HLEN;
                hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
                if (!hdr)
                        goto tx_drop;
@@ -2993,7 +3039,6 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        tag = (u16 *)(new_skb->data + 12);
                        *tag = __constant_htons(ETH_P_8021Q);
                        *(tag + 1) = htons(vlan_tx_tag_get(new_skb));
-                       new_skb->vlan_tci = 0;
                }
        }
 
@@ -3025,9 +3070,13 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        qeth_l3_fill_header(card, hdr, new_skb, ipv,
                                                cast_type);
                } else {
-                       qeth_l3_fill_header(card, hdr, new_skb, ipv,
-                                               cast_type);
-                       hdr->hdr.l3.length = new_skb->len - data_offset;
+                       if (new_skb->protocol == ETH_P_AF_IUCV)
+                               qeth_l3_fill_af_iucv_hdr(card, hdr, new_skb);
+                       else {
+                               qeth_l3_fill_header(card, hdr, new_skb, ipv,
+                                                       cast_type);
+                               hdr->hdr.l3.length = new_skb->len - data_offset;
+                       }
                }
 
                if (skb->ip_summed == CHECKSUM_PARTIAL)
@@ -3226,7 +3275,7 @@ static const struct net_device_ops qeth_l3_netdev_ops = {
        .ndo_get_stats          = qeth_get_stats,
        .ndo_start_xmit         = qeth_l3_hard_start_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = qeth_l3_set_multicast_list,
+       .ndo_set_rx_mode        = qeth_l3_set_multicast_list,
        .ndo_do_ioctl           = qeth_l3_do_ioctl,
        .ndo_change_mtu         = qeth_change_mtu,
        .ndo_fix_features       = qeth_l3_fix_features,
@@ -3242,7 +3291,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
        .ndo_get_stats          = qeth_get_stats,
        .ndo_start_xmit         = qeth_l3_hard_start_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = qeth_l3_set_multicast_list,
+       .ndo_set_rx_mode        = qeth_l3_set_multicast_list,
        .ndo_do_ioctl           = qeth_l3_do_ioctl,
        .ndo_change_mtu         = qeth_change_mtu,
        .ndo_fix_features       = qeth_l3_fix_features,
@@ -3290,6 +3339,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
                card->dev->flags |= IFF_NOARP;
                card->dev->netdev_ops = &qeth_l3_netdev_ops;
                qeth_l3_iqd_read_initial_mac(card);
+               if (card->options.hsuid[0])
+                       memcpy(card->dev->perm_addr, card->options.hsuid, 9);
        } else
                return -ENODEV;
 
@@ -3660,7 +3711,6 @@ static int qeth_l3_ip6_event(struct notifier_block *this,
        struct qeth_ipaddr *addr;
        struct qeth_card *card;
 
-
        card = qeth_l3_get_card_from_dev(dev);
        if (!card)
                return NOTIFY_DONE;
index cd99210296e2ae5d792d3c2b59a9f765827832b4..0ea2fbfe0e993a42932221d52f0040aaf52b96db 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/slab.h>
-
+#include <asm/ebcdic.h>
 #include "qeth_l3.h"
 
 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
@@ -308,6 +308,8 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
 
        if (card->info.type != QETH_CARD_TYPE_IQD)
                return -EPERM;
+       if (card->options.cq == QETH_CQ_ENABLED)
+               return -EPERM;
 
        mutex_lock(&card->conf_mutex);
        if ((card->state != CARD_STATE_DOWN) &&
@@ -347,6 +349,111 @@ out:
 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
                qeth_l3_dev_sniffer_store);
 
+
+static ssize_t qeth_l3_dev_hsuid_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct qeth_card *card = dev_get_drvdata(dev);
+       char tmp_hsuid[9];
+
+       if (!card)
+               return -EINVAL;
+
+       if (card->info.type != QETH_CARD_TYPE_IQD)
+               return -EPERM;
+
+       if (card->state == CARD_STATE_DOWN)
+               return -EPERM;
+
+       memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid));
+       EBCASC(tmp_hsuid, 8);
+       return sprintf(buf, "%s\n", tmp_hsuid);
+}
+
+static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct qeth_card *card = dev_get_drvdata(dev);
+       struct qeth_ipaddr *addr;
+       char *tmp;
+       int i;
+
+       if (!card)
+               return -EINVAL;
+
+       if (card->info.type != QETH_CARD_TYPE_IQD)
+               return -EPERM;
+       if (card->state != CARD_STATE_DOWN &&
+           card->state != CARD_STATE_RECOVER)
+               return -EPERM;
+       if (card->options.sniffer)
+               return -EPERM;
+       if (card->options.cq == QETH_CQ_NOTAVAILABLE)
+               return -EPERM;
+
+       tmp = strsep((char **)&buf, "\n");
+       if (strlen(tmp) > 8)
+               return -EINVAL;
+
+       if (card->options.hsuid[0]) {
+               /* delete old ip address */
+               addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
+               if (addr != NULL) {
+                       addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
+                       addr->u.a6.addr.s6_addr32[1] = 0x00000000;
+                       for (i = 8; i < 16; i++)
+                               addr->u.a6.addr.s6_addr[i] =
+                                       card->options.hsuid[i - 8];
+                       addr->u.a6.pfxlen = 0;
+                       addr->type = QETH_IP_TYPE_NORMAL;
+               } else
+                       return -ENOMEM;
+               if (!qeth_l3_delete_ip(card, addr))
+                       kfree(addr);
+               qeth_l3_set_ip_addr_list(card);
+       }
+
+       if (strlen(tmp) == 0) {
+               /* delete ip address only */
+               card->options.hsuid[0] = '\0';
+               if (card->dev)
+                       memcpy(card->dev->perm_addr, card->options.hsuid, 9);
+               qeth_configure_cq(card, QETH_CQ_DISABLED);
+               return count;
+       }
+
+       if (qeth_configure_cq(card, QETH_CQ_ENABLED))
+               return -EPERM;
+
+       for (i = 0; i < 8; i++)
+               card->options.hsuid[i] = ' ';
+       card->options.hsuid[8] = '\0';
+       strncpy(card->options.hsuid, tmp, strlen(tmp));
+       ASCEBC(card->options.hsuid, 8);
+       if (card->dev)
+               memcpy(card->dev->perm_addr, card->options.hsuid, 9);
+
+       addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
+       if (addr != NULL) {
+               addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
+               addr->u.a6.addr.s6_addr32[1] = 0x00000000;
+               for (i = 8; i < 16; i++)
+                       addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
+               addr->u.a6.pfxlen = 0;
+               addr->type = QETH_IP_TYPE_NORMAL;
+       } else
+               return -ENOMEM;
+       if (!qeth_l3_add_ip(card, addr))
+               kfree(addr);
+       qeth_l3_set_ip_addr_list(card);
+
+       return count;
+}
+
+static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show,
+                  qeth_l3_dev_hsuid_store);
+
+
 static struct attribute *qeth_l3_device_attrs[] = {
        &dev_attr_route4.attr,
        &dev_attr_route6.attr,
@@ -354,6 +461,7 @@ static struct attribute *qeth_l3_device_attrs[] = {
        &dev_attr_broadcast_mode.attr,
        &dev_attr_canonical_macaddr.attr,
        &dev_attr_sniffer.attr,
+       &dev_attr_hsuid.attr,
        NULL,
 };
 
index 6a38080e35edc0520a939d5a6f82f8aaf12c5645..cfcad8bde7cf3b1da88b8ceeeb7bac987a3726ac 100644 (file)
@@ -2,7 +2,8 @@ config SCSI_BNX2X_FCOE
        tristate "Broadcom NetXtreme II FCoE support"
        depends on PCI
        select NETDEVICES
-       select NETDEV_1000
+       select ETHERNET
+       select NET_VENDOR_BROADCOM
        select LIBFC
        select LIBFCOE
        select CNIC
index 42228ca5a9d223d42a6fbf897366620b47b96cc5..5613e8afffb0be4d891f00a5f9dd067e2365dd7f 100644 (file)
@@ -58,7 +58,7 @@
 
 #include "57xx_hsi_bnx2fc.h"
 #include "bnx2fc_debug.h"
-#include "../../net/cnic_if.h"
+#include "../../net/ethernet/broadcom/cnic_if.h"
 #include "bnx2fc_constants.h"
 
 #define BNX2FC_NAME            "bnx2fc"
index 45a6154ce9722347e709b4eed0885635392e4642..01cff1894b6d75bef7f28a310de3de5a0ad48135 100644 (file)
@@ -4,7 +4,8 @@ config SCSI_BNX2_ISCSI
        depends on PCI
        select SCSI_ISCSI_ATTRS
        select NETDEVICES
-       select NETDEV_1000
+       select ETHERNET
+       select NET_VENDOR_BROADCOM
        select CNIC
        ---help---
        This driver supports iSCSI offload for the Broadcom NetXtreme II
index dc5700765db40034988a36883699bac4dc54b104..0bd70e80efe46bee67fdd211ec00d2359db1f45b 100644 (file)
@@ -40,7 +40,7 @@
 #include <scsi/libiscsi.h>
 #include <scsi/scsi_transport_iscsi.h>
 
-#include "../../net/cnic_if.h"
+#include "../../net/ethernet/broadcom/cnic_if.h"
 #include "57xx_iscsi_hsi.h"
 #include "57xx_iscsi_constants.h"
 
index 09dbf9efc8eacee458d6073d61c478e4edfe4485..6f095e28a9747c0428e121df204d42d5edc66f60 100644 (file)
@@ -1,3 +1,3 @@
-EXTRA_CFLAGS += -I$(srctree)/drivers/net/cxgb3
+EXTRA_CFLAGS += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb3
 
 obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o
index 11dff23f7838479e33f90fd412154a66ceb77dbd..6bbc36fbd6ecc4d642de5705a2c95191d39161f6 100644 (file)
@@ -2,7 +2,8 @@ config SCSI_CXGB3_ISCSI
        tristate "Chelsio T3 iSCSI support"
        depends on PCI && INET
        select NETDEVICES
-       select NETDEV_10000
+       select ETHERNET
+       select NET_VENDOR_CHELSIO
        select CHELSIO_T3
        select SCSI_ISCSI_ATTRS
        ---help---
index b9f4af7454b754b87668452db90fc9e3f6788454..8290cdaa4652a156300b6ae04b7f23f12bc67576 100644 (file)
@@ -1,3 +1,3 @@
-EXTRA_CFLAGS += -I$(srctree)/drivers/net/cxgb4
+EXTRA_CFLAGS += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb4
 
 obj-$(CONFIG_SCSI_CXGB4_ISCSI) += cxgb4i.o
index d5302c27f37786d62302d29037a977a422b74827..16b2c7d26617db2ed9c3f2eb119fcb0bff446c2a 100644 (file)
@@ -2,7 +2,8 @@ config SCSI_CXGB4_ISCSI
        tristate "Chelsio T4 iSCSI support"
        depends on PCI && INET
        select NETDEVICES
-       select NETDEV_10000
+       select ETHERNET
+       select NET_VENDOR_CHELSIO
        select CHELSIO_T4
        select SCSI_ISCSI_ATTRS
        ---help---
index f33e2dd979348f4b78560d15b2f8e9f9d33ef09e..33b2ed451e095dde15bedd14ce04ded170e17fd4 100644 (file)
@@ -186,6 +186,9 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
     !defined(CONFIG_CPU_SUBTYPE_SH7709)
        [IRQ_TYPE_LEVEL_HIGH] = VALID(3),
 #endif
+#if defined(CONFIG_ARCH_SH7372)
+       [IRQ_TYPE_EDGE_BOTH] = VALID(4),
+#endif
 };
 
 static int intc_set_type(struct irq_data *data, unsigned int type)
index 82dee9a6c0de5a7761c95820697963938bbfb3fe..d3bff424286f109c6fcb1f0956096e604b0c0459 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <asm/io.h>
 #include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <mach/cpu.h>
 
 /* SPI register offsets */
index 06c9081d596d543339115539c4bb0c9f08bb773e..d497a93748a16cc40ac6efb0075cab5abecacb5b 100644 (file)
@@ -126,8 +126,6 @@ source "drivers/staging/quickstart/Kconfig"
 
 source "drivers/staging/sbe-2t3e3/Kconfig"
 
-source "drivers/staging/ath6kl/Kconfig"
-
 source "drivers/staging/keucr/Kconfig"
 
 source "drivers/staging/bcm/Kconfig"
index f3c5e33bb263b138ffcdb59b064db7b8a93e34e4..fe6c6114a66878ebf27916f7ab21767191d66b27 100644 (file)
@@ -54,7 +54,6 @@ obj-$(CONFIG_SOLO6X10)                += solo6x10/
 obj-$(CONFIG_TIDSPBRIDGE)      += tidspbridge/
 obj-$(CONFIG_ACPI_QUICKSTART)  += quickstart/
 obj-$(CONFIG_SBE_2T3E3)                += sbe-2t3e3/
-obj-$(CONFIG_ATH6K_LEGACY)     += ath6kl/
 obj-$(CONFIG_USB_ENESTORAGE)   += keucr/
 obj-$(CONFIG_BCM_WIMAX)                += bcm/
 obj-$(CONFIG_FT1000)           += ft1000/
diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig
deleted file mode 100644 (file)
index afd6cc1..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-config ATH6K_LEGACY
-       tristate "Atheros AR6003 support (non mac80211)"
-        depends on MMC && WLAN
-       depends on CFG80211
-        select WIRELESS_EXT
-        select WEXT_PRIV
-       help
-       This module adds support for wireless adapters based on Atheros AR6003 chipset running over SDIO. If you choose to build it as a module, it will be called ath6kl. Pls note that AR6002 and AR6001 are not supported by this driver.
-
-choice
-       prompt "AR6003 Board Data Configuration"
-       depends on ATH6K_LEGACY
-       default AR600x_SD31_XXX
-       help
-       Select the appropriate board data template from the list below that matches your AR6003 based reference design.
-
-config AR600x_SD31_XXX
-       bool "SD31-xxx"
-       help
-        Board Data file for a standard SD31 reference design (File: bdata.SD31.bin)
-
-config AR600x_WB31_XXX
-       bool "WB31-xxx"
-       help
-        Board Data file for a standard WB31 (BT/WiFi) reference design (File: bdata.WB31.bin)
-
-config AR600x_SD32_XXX
-       bool "SD32-xxx"
-       help
-        Board Data file for a standard SD32 (5GHz) reference design (File: bdata.SD32.bin)
-
-config AR600x_CUSTOM_XXX
-       bool "CUSTOM-xxx"
-       help
-        Board Data file for a custom reference design (File: should be named as bdata.CUSTOM.bin)
-endchoice
-
-config ATH6KL_ENABLE_COEXISTENCE
-       bool "BT Coexistence support"
-       depends on ATH6K_LEGACY
-       help
-       Enables WLAN/BT coexistence support. Select the apprpriate configuration from below.
-
-choice
-       prompt "Front-End Antenna Configuration"
-       depends on ATH6KL_ENABLE_COEXISTENCE
-       default AR600x_DUAL_ANTENNA
-       help
-       Indicates the number of antennas being used by BT and WLAN. Select the appropriate configuration from the list below that matches your AR6003 based reference design.
-
-config AR600x_DUAL_ANTENNA
-       bool "Dual Antenna"
-       help
-        Dual Antenna Design
-
-config AR600x_SINGLE_ANTENNA
-       bool "Single Antenna"
-       help
-        Single Antenna Design
-endchoice
-
-choice
-       prompt "Collocated Bluetooth Type"
-       depends on ATH6KL_ENABLE_COEXISTENCE
-       default AR600x_BT_AR3001
-       help
-       Select the appropriate configuration from the list below that matches your AR6003 based reference design.
-
-config AR600x_BT_QCOM
-       bool "Qualcomm BTS4020X"
-       help
-        Qualcomm BT (3 Wire PTA)
-
-config AR600x_BT_CSR
-       bool "CSR BC06"
-       help
-        CSR BT (3 Wire PTA)
-
-config AR600x_BT_AR3001
-       bool "Atheros AR3001"
-       help
-        Atheros BT (3 Wire PTA)
-endchoice
-
-config ATH6KL_HCI_BRIDGE
-       bool "HCI over SDIO support"
-       depends on ATH6K_LEGACY
-       help
-       Enables BT over SDIO. Applicable only for combo designs (eg: WB31)
-
-config ATH6KL_CONFIG_GPIO_BT_RESET
-       bool "Configure BT Reset GPIO"
-       depends on ATH6KL_HCI_BRIDGE
-       help
-       Configure a WLAN GPIO for use with BT.
-
-config AR600x_BT_RESET_PIN
-       int "GPIO"
-       depends on ATH6KL_CONFIG_GPIO_BT_RESET
-       default 22
-       help
-       WLAN GPIO to be used for resetting BT
-
-config ATH6KL_HTC_RAW_INTERFACE
-       bool "RAW HTC support"
-       depends on ATH6K_LEGACY
-       help
-       Enables raw HTC interface. Allows application to directly talk to the HTC interface via the ioctl interface
-
-config ATH6KL_VIRTUAL_SCATTER_GATHER
-       bool "Virtual Scatter-Gather support"
-       depends on ATH6K_LEGACY
-       help
-       Enables virtual scatter gather support for the hardware that does not support it natively.
-
-config ATH6KL_SKIP_ABI_VERSION_CHECK
-       bool "Skip ABI version check support"
-       depends on ATH6K_LEGACY
-       help
-       Forces the driver to disable ABI version check. Caution: Incompatilbity between the host driver and target firmware may lead to unknown side effects.
-
-config ATH6KL_BT_UART_FC_POLARITY
-       int "UART Flow Control Polarity"
-       depends on ATH6KL_LEGACY
-       default 0
-       help
-       Configures the polarity of UART Flow Control. A value of 0 implies active low and is the default setting. Set it to 1 for active high.
-
-config ATH6KL_DEBUG
-       bool "Debug support"
-       depends on ATH6K_LEGACY
-       help
-       Enables debug support
-
-config ATH6KL_ENABLE_HOST_DEBUG
-       bool "Host Debug support"
-       depends on ATH6KL_DEBUG
-       help
-       Enables debug support in the driver
-
-config ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
-       bool "Target Debug support - Enable UART prints"
-       depends on ATH6KL_DEBUG
-       help
-       Enables uart prints
-
-config AR600x_DEBUG_UART_TX_PIN
-       int "GPIO"
-       depends on ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
-       default 8
-       help
-       WLAN GPIO to be used for Debug UART (Tx)
-
-config ATH6KL_DISABLE_TARGET_DBGLOGS
-       bool "Target Debug support - Disable Debug logs"
-       depends on ATH6KL_DEBUG
-       help
-       Enables debug logs
diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile
deleted file mode 100644 (file)
index 1d3f239..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#------------------------------------------------------------------------------
-# Copyright (c) 2004-2010 Atheros Communications Inc.
-# All rights reserved.
-#
-# 
-#
-# 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.
-#
-#
-#
-# Author(s): ="Atheros"
-#------------------------------------------------------------------------------
-
-ccflags-y += -I$(obj)/include
-ccflags-y += -I$(obj)/include/common
-ccflags-y += -I$(obj)/wlan/include
-ccflags-y += -I$(obj)/os/linux/include
-ccflags-y += -I$(obj)/os
-ccflags-y += -I$(obj)/bmi/include
-ccflags-y += -I$(obj)/include/common/AR6002/hw4.0
-
-ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y)
-ccflags-y += -DAR600x_DUAL_ANTENNA
-endif
-
-ifeq ($(CONFIG_AR600x_SINGLE_ANTENNA),y)
-ccflags-y += -DAR600x_SINGLE_ANTENNA
-endif
-
-ifeq ($(CONFIG_AR600x_BT_QCOM),y)
-ccflags-y += -DAR600x_BT_QCOM
-endif
-
-ifeq ($(CONFIG_AR600x_BT_CSR),y)
-ccflags-y += -DAR600x_BT_CSR
-endif
-
-ifeq ($(CONFIG_AR600x_BT_AR3001),y)
-ccflags-y += -DAR600x_BT_AR3001
-endif
-
-ifeq ($(CONFIG_ATH6KL_HCI_BRIDGE),y)
-ccflags-y += -DATH_AR6K_ENABLE_GMBOX
-ccflags-y += -DHCI_TRANSPORT_SDIO
-ccflags-y += -DSETUPHCI_ENABLED
-ccflags-y += -DSETUPBTDEV_ENABLED
-ath6kl-y += htc2/AR6000/ar6k_gmbox.o
-ath6kl-y += htc2/AR6000/ar6k_gmbox_hciuart.o
-ath6kl-y += miscdrv/ar3kconfig.o
-ath6kl-y += miscdrv/ar3kps/ar3kpsconfig.o
-ath6kl-y += miscdrv/ar3kps/ar3kpsparser.o
-endif
-
-ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y)
-ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET
-endif
-
-ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y)
-ccflags-y += -DHTC_RAW_INTERFACE
-endif
-
-ifeq ($(CONFIG_ATH6KL_ENABLE_HOST_DEBUG),y)
-ccflags-y += -DDEBUG
-ccflags-y += -DATH_DEBUG_MODULE
-endif
-
-ifeq ($(CONFIG_ATH6KL_ENABLE_TARGET_DEBUG_PRINTS),y)
-ccflags-y += -DENABLEUARTPRINT_SET
-endif
-
-ifeq ($(CONFIG_ATH6KL_DISABLE_TARGET_DBGLOGS),y)
-ccflags-y += -DATH6KL_DISABLE_TARGET_DBGLOGS
-endif
-
-ifeq ($(CONFIG_ATH6KL_VIRTUAL_SCATTER_GATHER),y)
-ccflags-y += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
-endif
-
-ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y)
-ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK
-endif
-
-ccflags-y += -DWAPI_ENABLE
-ccflags-y += -DCHECKSUM_OFFLOAD
-
-obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o
-ath6kl-y += htc2/AR6000/ar6k.o
-ath6kl-y += htc2/AR6000/ar6k_events.o
-ath6kl-y += htc2/htc_send.o
-ath6kl-y += htc2/htc_recv.o
-ath6kl-y += htc2/htc_services.o
-ath6kl-y += htc2/htc.o
-ath6kl-y += bmi/src/bmi.o
-ath6kl-y += os/linux/cfg80211.o
-ath6kl-y += os/linux/ar6000_drv.o
-ath6kl-y += os/linux/ar6000_raw_if.o
-ath6kl-y += os/linux/ar6000_pm.o
-ath6kl-y += os/linux/netbuf.o
-ath6kl-y += os/linux/hci_bridge.o
-ath6kl-y += miscdrv/common_drv.o
-ath6kl-y += miscdrv/credit_dist.o
-ath6kl-y += wmi/wmi.o
-ath6kl-y += reorder/rcv_aggr.o
-ath6kl-y += wlan/src/wlan_node.o
-ath6kl-y += wlan/src/wlan_recv_beacon.o
-ath6kl-y += wlan/src/wlan_utils.o                       
-
-# ATH_HIF_TYPE := sdio
-ccflags-y += -I$(obj)/hif/sdio/linux_sdio/include
-ccflags-y += -DSDIO
-ath6kl-y += hif/sdio/linux_sdio/src/hif.o
-ath6kl-y += hif/sdio/linux_sdio/src/hif_scatter.o
diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO
deleted file mode 100644 (file)
index 7be4b46..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-TODO:
-
-We are working hard on cleaning up the driver. There's sooooooooo much todo
-so instead of editing this file please use the wiki:
-
-http://wireless.kernel.org/en/users/Drivers/ath6kl
-
-There's a respective TODO page there. Please also subscribe to the wiki page
-to get e-mail updates on changes.
-
-IRC:
-
-We *really* need to coordinate development for ath6kl as the cleanup
-patches will break pretty much any other patches. Please use IRC to
-help coordinate better:
-
-irc.freenode.net
-#ath6kl
-
-Send patches to:
-
-       - Greg Kroah-Hartman <greg@kroah.com>
-       - Luis R. Rodriguez <mcgrof@gmail.com>
-       - Joe Perches <joe@perches.com>
-       - Naveen Singh <nsingh@atheros.com>
diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h
deleted file mode 100644 (file)
index 8e25770..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef BMI_INTERNAL_H
-#define BMI_INTERNAL_H
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#define ATH_MODULE_NAME bmi
-#include "a_debug.h"
-#include "hw/mbox_host_reg.h"
-#include "bmi_msg.h"
-
-#define ATH_DEBUG_BMI  ATH_DEBUG_MAKE_MODULE_MASK(0)
-
-
-#define BMI_COMMUNICATION_TIMEOUT       100000
-
-/* ------ Global Variable Declarations ------- */
-static bool bmiDone;
-
-int
-bmiBufferSend(struct hif_device *device,
-              u8 *buffer,
-              u32 length);
-
-int
-bmiBufferReceive(struct hif_device *device,
-                 u8 *buffer,
-                 u32 length,
-                 bool want_timeout);
-
-#endif
diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c
deleted file mode 100644 (file)
index f1f085e..0000000
+++ /dev/null
@@ -1,1010 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="bmi.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-
-#ifdef THREAD_X
-#include <string.h>
-#endif
-
-#include "hif.h"
-#include "bmi.h"
-#include "htc_api.h"
-#include "bmi_internal.h"
-
-#ifdef ATH_DEBUG_MODULE
-static struct ath_debug_mask_description bmi_debug_desc[] = {
-    { ATH_DEBUG_BMI , "BMI Tracing"},
-};
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
-                                 "bmi",
-                                 "Boot Manager Interface",
-                                 ATH_DEBUG_MASK_DEFAULTS,
-                                 ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
-                                 bmi_debug_desc);
-                                 
-#endif
-
-/*
-Although we had envisioned BMI to run on top of HTC, this is not how the
-final implementation ended up. On the Target side, BMI is a part of the BSP
-and does not use the HTC protocol nor even DMA -- it is intentionally kept
-very simple.
-*/
-
-static bool pendingEventsFuncCheck = false;
-static u32 *pBMICmdCredits;
-static u8 *pBMICmdBuf;
-#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
-                       sizeof(u32) /* cmd */ + \
-                       sizeof(u32) /* addr */ + \
-                       sizeof(u32))/* length */
-#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
-    
-/* APIs visible to the driver */
-void
-BMIInit(void)
-{
-    bmiDone = false;
-    pendingEventsFuncCheck = false;
-
-    /*
-     * On some platforms, it's not possible to DMA to a static variable
-     * in a device driver (e.g. Linux loadable driver module).
-     * So we need to A_MALLOC space for "command credits" and for commands.
-     *
-     * Note: implicitly relies on A_MALLOC to provide a buffer that is
-     * suitable for DMA (or PIO).  This buffer will be passed down the
-     * bus stack.
-     */
-    if (!pBMICmdCredits) {
-        pBMICmdCredits = (u32 *)A_MALLOC_NOWAIT(4);
-        A_ASSERT(pBMICmdCredits);
-    }
-
-    if (!pBMICmdBuf) {
-        pBMICmdBuf = (u8 *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
-        A_ASSERT(pBMICmdBuf);
-    }
-    
-    A_REGISTER_MODULE_DEBUG_INFO(bmi);
-}
-
-void
-BMICleanup(void)
-{
-    if (pBMICmdCredits) {
-        kfree(pBMICmdCredits);
-        pBMICmdCredits = NULL;
-    }
-
-    if (pBMICmdBuf) {
-        kfree(pBMICmdBuf);
-        pBMICmdBuf = NULL;
-    }
-}
-
-int
-BMIDone(struct hif_device *device)
-{
-    int status;
-    u32 cid;
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
-        return 0;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
-    bmiDone = true;
-    cid = BMI_DONE;
-
-    status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid));
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    if (pBMICmdCredits) {
-        kfree(pBMICmdCredits);
-        pBMICmdCredits = NULL;
-    }
-
-    if (pBMICmdBuf) {
-        kfree(pBMICmdBuf);
-        pBMICmdBuf = NULL;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
-
-    return 0;
-}
-
-int
-BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info)
-{
-    int status;
-    u32 cid;
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
-    cid = BMI_GET_TARGET_INFO;
-
-    status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid));
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    status = bmiBufferReceive(device, (u8 *)&targ_info->target_ver,
-                                                sizeof(targ_info->target_ver), true);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
-        return A_ERROR;
-    }
-
-    if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
-        /* Determine how many bytes are in the Target's targ_info */
-        status = bmiBufferReceive(device, (u8 *)&targ_info->target_info_byte_count,
-                                            sizeof(targ_info->target_info_byte_count), true);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n"));
-            return A_ERROR;
-        }
-
-        /*
-         * The Target's targ_info doesn't match the Host's targ_info.
-         * We need to do some backwards compatibility work to make this OK.
-         */
-        A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
-
-        /* Read the remainder of the targ_info */
-        status = bmiBufferReceive(device,
-                        ((u8 *)targ_info)+sizeof(targ_info->target_info_byte_count),
-                        sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n",
-                                                               targ_info->target_info_byte_count));
-            return A_ERROR;
-        }
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
-                                                               targ_info->target_ver, targ_info->target_type));
-
-    return 0;
-}
-
-int
-BMIReadMemory(struct hif_device *device,
-              u32 address,
-              u8 *buffer,
-              u32 length)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-    u32 remaining, rxlen;
-
-    A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)));
-    memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-                               ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
-                               device, address, length));
-
-    cid = BMI_READ_MEMORY;
-
-    remaining = length;
-
-    while (remaining)
-    {
-        rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
-        offset = 0;
-        memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-        offset += sizeof(cid);
-        memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-        offset += sizeof(address);
-        memcpy(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
-        offset += sizeof(length);
-
-        status = bmiBufferSend(device, pBMICmdBuf, offset);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-            return A_ERROR;
-        }
-        status = bmiBufferReceive(device, pBMICmdBuf, rxlen, true);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
-            return A_ERROR;
-        }
-        memcpy(&buffer[length - remaining], pBMICmdBuf, rxlen);
-        remaining -= rxlen; address += rxlen;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
-    return 0;
-}
-
-int
-BMIWriteMemory(struct hif_device *device,
-               u32 address,
-               u8 *buffer,
-               u32 length)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-    u32 remaining, txlen;
-    const u32 header = sizeof(cid) + sizeof(address) + sizeof(length);
-    u8 alignedBuffer[BMI_DATASZ_MAX];
-    u8 *src;
-
-    A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
-    memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-         ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
-         device, address, length));
-
-    cid = BMI_WRITE_MEMORY;
-
-    remaining = length;
-    while (remaining)
-    {
-        src = &buffer[length - remaining];
-        if (remaining < (BMI_DATASZ_MAX - header)) {
-            if (remaining & 3) {
-                /* align it with 4 bytes */
-                remaining = remaining + (4 - (remaining & 3));
-                memcpy(alignedBuffer, src, remaining);
-                src = alignedBuffer;
-            } 
-            txlen = remaining;
-        } else {
-            txlen = (BMI_DATASZ_MAX - header);
-        }
-        offset = 0;
-        memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-        offset += sizeof(cid);
-        memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-        offset += sizeof(address);
-        memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
-        offset += sizeof(txlen);
-        memcpy(&(pBMICmdBuf[offset]), src, txlen);
-        offset += txlen;
-        status = bmiBufferSend(device, pBMICmdBuf, offset);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-            return A_ERROR;
-        }
-        remaining -= txlen; address += txlen;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
-
-    return 0;
-}
-
-int
-BMIExecute(struct hif_device *device,
-           u32 address,
-           u32 *param)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
-    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-       ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
-        device, address, *param));
-
-    cid = BMI_EXECUTE;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-    offset += sizeof(address);
-    memcpy(&(pBMICmdBuf[offset]), param, sizeof(*param));
-    offset += sizeof(*param);
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), false);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
-        return A_ERROR;
-    }
-
-    memcpy(param, pBMICmdBuf, sizeof(*param));
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
-    return 0;
-}
-
-int
-BMISetAppStart(struct hif_device *device,
-               u32 address)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
-    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-       ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
-        device, address));
-
-    cid = BMI_SET_APP_START;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-    offset += sizeof(address);
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
-    return 0;
-}
-
-int
-BMIReadSOCRegister(struct hif_device *device,
-                   u32 address,
-                   u32 *param)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
-    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-       ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
-       device, address));
-
-    cid = BMI_READ_SOC_REGISTER;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-    offset += sizeof(address);
-
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), true);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
-        return A_ERROR;
-    }
-    memcpy(param, pBMICmdBuf, sizeof(*param));
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
-    return 0;
-}
-
-int
-BMIWriteSOCRegister(struct hif_device *device,
-                    u32 address,
-                    u32 param)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
-    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-     ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
-     device, address, param));
-
-    cid = BMI_WRITE_SOC_REGISTER;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-    offset += sizeof(address);
-    memcpy(&(pBMICmdBuf[offset]), &param, sizeof(param));
-    offset += sizeof(param);
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
-    return 0;
-}
-
-int
-BMIrompatchInstall(struct hif_device *device,
-                   u32 ROM_addr,
-                   u32 RAM_addr,
-                   u32 nbytes,
-                   u32 do_activate,
-                   u32 *rompatch_id)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
-                               sizeof(nbytes) + sizeof(do_activate)));
-    memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
-                       sizeof(nbytes) + sizeof(do_activate));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-         ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n",
-         device, ROM_addr, RAM_addr, nbytes, do_activate));
-
-    cid = BMI_ROMPATCH_INSTALL;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
-    offset += sizeof(ROM_addr);
-    memcpy(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
-    offset += sizeof(RAM_addr);
-    memcpy(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
-    offset += sizeof(nbytes);
-    memcpy(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
-    offset += sizeof(do_activate);
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), true);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
-        return A_ERROR;
-    }
-    memcpy(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
-    return 0;
-}
-
-int
-BMIrompatchUninstall(struct hif_device *device,
-                     u32 rompatch_id)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id)));
-    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-         ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
-                                                                        device, rompatch_id));
-
-    cid = BMI_ROMPATCH_UNINSTALL;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
-    offset += sizeof(rompatch_id);
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id));
-    return 0;
-}
-
-static int
-_BMIrompatchChangeActivation(struct hif_device *device,
-                             u32 rompatch_count,
-                             u32 *rompatch_list,
-                             u32 do_activate)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-    u32 length;
-
-    A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)));
-    memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-         ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
-           device, rompatch_count));
-
-    cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
-
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
-    offset += sizeof(rompatch_count);
-    length = rompatch_count * sizeof(*rompatch_list);
-    memcpy(&(pBMICmdBuf[offset]), rompatch_list, length);
-    offset += length;
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
-
-    return 0;
-}
-
-int
-BMIrompatchActivate(struct hif_device *device,
-                    u32 rompatch_count,
-                    u32 *rompatch_list)
-{
-    return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
-}
-
-int
-BMIrompatchDeactivate(struct hif_device *device,
-                      u32 rompatch_count,
-                      u32 *rompatch_list)
-{
-    return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
-}
-
-int
-BMILZData(struct hif_device *device,
-          u8 *buffer,
-          u32 length)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-    u32 remaining, txlen;
-    const u32 header = sizeof(cid) + sizeof(length);
-
-    A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
-    memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-         ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n",
-         device, length));
-
-    cid = BMI_LZ_DATA;
-
-    remaining = length;
-    while (remaining)
-    {
-        txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
-                                       remaining : (BMI_DATASZ_MAX - header);
-        offset = 0;
-        memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-        offset += sizeof(cid);
-        memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
-        offset += sizeof(txlen);
-        memcpy(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
-        offset += txlen;
-        status = bmiBufferSend(device, pBMICmdBuf, offset);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
-            return A_ERROR;
-        }
-        remaining -= txlen;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));
-
-    return 0;
-}
-
-int
-BMILZStreamStart(struct hif_device *device,
-                 u32 address)
-{
-    u32 cid;
-    int status;
-    u32 offset;
-
-    A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
-    memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
-
-    if (bmiDone) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
-         ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n",
-         device, address));
-
-    cid = BMI_LZ_STREAM_START;
-    offset = 0;
-    memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
-    offset += sizeof(cid);
-    memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address));
-    offset += sizeof(address);
-    status = bmiBufferSend(device, pBMICmdBuf, offset);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n"));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));
-
-    return 0;
-}
-
-/* BMI Access routines */
-int
-bmiBufferSend(struct hif_device *device,
-              u8 *buffer,
-              u32 length)
-{
-    int status;
-    u32 timeout;
-    u32 address;
-    u32 mboxAddress[HTC_MAILBOX_NUM_MAX];
-
-    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
-                       &mboxAddress[0], sizeof(mboxAddress));
-
-    *pBMICmdCredits = 0;
-    timeout = BMI_COMMUNICATION_TIMEOUT;
-
-    while(timeout-- && !(*pBMICmdCredits)) {
-        /* Read the counter register to get the command credits */
-        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
-        /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
-         * a decrement, while the remaining 3 bytes has no effect.  The rationale behind this is to
-         * make all HIF accesses 4-byte aligned */
-        status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, 4,
-            HIF_RD_SYNC_BYTE_INC, NULL);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
-            return A_ERROR;
-        }
-        /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
-        (*pBMICmdCredits) &= 0xFF;
-    }
-
-    if (*pBMICmdCredits) {
-        address = mboxAddress[ENDPOINT1];
-        status = HIFReadWrite(device, address, buffer, length,
-            HIF_WR_SYNC_BYTE_INC, NULL);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
-            return A_ERROR;
-        }
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n"));
-        return A_ERROR;
-    }
-
-    return status;
-}
-
-int
-bmiBufferReceive(struct hif_device *device,
-                 u8 *buffer,
-                 u32 length,
-                 bool want_timeout)
-{
-    int status;
-    u32 address;
-    u32 mboxAddress[HTC_MAILBOX_NUM_MAX];
-    struct hif_pending_events_info     hifPendingEvents;
-    static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL;
-    
-    if (!pendingEventsFuncCheck) {
-            /* see if the HIF layer implements an alternative function to get pending events
-             * do this only once! */
-        HIFConfigureDevice(device,
-                           HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
-                           &getPendingEventsFunc,
-                           sizeof(getPendingEventsFunc));
-        pendingEventsFuncCheck = true;
-    }
-                       
-    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
-                       &mboxAddress[0], sizeof(mboxAddress));
-
-    /*
-     * During normal bootup, small reads may be required.
-     * Rather than issue an HIF Read and then wait as the Target
-     * adds successive bytes to the FIFO, we wait here until
-     * we know that response data is available.
-     *
-     * This allows us to cleanly timeout on an unexpected
-     * Target failure rather than risk problems at the HIF level.  In
-     * particular, this avoids SDIO timeouts and possibly garbage
-     * data on some host controllers.  And on an interconnect
-     * such as Compact Flash (as well as some SDIO masters) which
-     * does not provide any indication on data timeout, it avoids
-     * a potential hang or garbage response.
-     *
-     * Synchronization is more difficult for reads larger than the
-     * size of the MBOX FIFO (128B), because the Target is unable
-     * to push the 129th byte of data until AFTER the Host posts an
-     * HIF Read and removes some FIFO data.  So for large reads the
-     * Host proceeds to post an HIF Read BEFORE all the data is
-     * actually available to read.  Fortunately, large BMI reads do
-     * not occur in practice -- they're supported for debug/development.
-     *
-     * So Host/Target BMI synchronization is divided into these cases:
-     *  CASE 1: length < 4
-     *        Should not happen
-     *
-     *  CASE 2: 4 <= length <= 128
-     *        Wait for first 4 bytes to be in FIFO
-     *        If CONSERVATIVE_BMI_READ is enabled, also wait for
-     *        a BMI command credit, which indicates that the ENTIRE
-     *        response is available in the the FIFO
-     *
-     *  CASE 3: length > 128
-     *        Wait for the first 4 bytes to be in FIFO
-     *
-     * For most uses, a small timeout should be sufficient and we will
-     * usually see a response quickly; but there may be some unusual
-     * (debug) cases of BMI_EXECUTE where we want an larger timeout.
-     * For now, we use an unbounded busy loop while waiting for
-     * BMI_EXECUTE.
-     *
-     * If BMI_EXECUTE ever needs to support longer-latency execution,
-     * especially in production, this code needs to be enhanced to sleep
-     * and yield.  Also note that BMI_COMMUNICATION_TIMEOUT is currently
-     * a function of Host processor speed.
-     */
-    if (length >= 4) { /* NB: Currently, always true */
-        /*
-         * NB: word_available is declared static for esoteric reasons
-         * having to do with protection on some OSes.
-         */
-        static u32 word_available;
-        u32 timeout;
-
-        word_available = 0;
-        timeout = BMI_COMMUNICATION_TIMEOUT;
-        while((!want_timeout || timeout--) && !word_available) {
-            
-            if (getPendingEventsFunc != NULL) {
-                status = getPendingEventsFunc(device,
-                                              &hifPendingEvents,
-                                              NULL);
-                if (status) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n"));
-                    break;
-                }
-  
-                if (hifPendingEvents.AvailableRecvBytes >= sizeof(u32)) {
-                    word_available = 1;    
-                }
-                continue;    
-            }
-            
-            status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (u8 *)&word_available,
-                sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n"));
-                return A_ERROR;
-            }
-            /* We did a 4-byte read to the same register; all we really want is one bit */ 
-            word_available &= (1 << ENDPOINT1);
-        }
-
-        if (!word_available) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n"));
-            return A_ERROR;
-        }
-    }
-
-#define CONSERVATIVE_BMI_READ 0
-#if CONSERVATIVE_BMI_READ
-    /*
-     * This is an extra-conservative CREDIT check.  It guarantees
-     * that ALL data is available in the FIFO before we start to
-     * read from the interconnect.
-     *
-     * This credit check is useless when firmware chooses to
-     * allow multiple outstanding BMI Command Credits, since the next
-     * credit will already be present.  To restrict the Target to one
-     * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT.
-     *
-     * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set)
-     * we cannot wait for the next credit because the Target's FIFO
-     * will not hold the entire response.  So we need the Host to
-     * start to empty the FIFO sooner.  (And again, large reads are
-     * not used in practice; they are for debug/development only.)
-     *
-     * For a more conservative Host implementation (which would be
-     * safer for a Compact Flash interconnect):
-     *   Set CONSERVATIVE_BMI_READ (above) to 1
-     *   Set HI_OPTION_BMI_CRED_LIMIT and
-     *   reduce BMI_DATASZ_MAX to 32 or 64
-     */
-    if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */
-        u32 timeout;
-
-        *pBMICmdCredits = 0;
-        timeout = BMI_COMMUNICATION_TIMEOUT;
-        while((!want_timeout || timeout--) && !(*pBMICmdCredits) {
-            /* Read the counter register to get the command credits */
-            address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
-            /* read the counter using a 4-byte read.  Since the counter is NOT auto-decrementing,
-             * we can read this counter multiple times using a non-incrementing address mode.
-             * The rationale here is to make all HIF accesses a multiple of 4 bytes */
-            status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, sizeof(*pBMICmdCredits),
-                HIF_RD_SYNC_BYTE_FIX, NULL);
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n"));
-                return A_ERROR;
-            }
-                /* we did a 4-byte read to the same count register so mask off upper bytes */
-            (*pBMICmdCredits) &= 0xFF;
-        }
-
-        if (!(*pBMICmdCredits)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n"));
-            return A_ERROR;
-        }
-    }
-#endif
-
-    address = mboxAddress[ENDPOINT1];
-    status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
-        return A_ERROR;
-    }
-
-    return 0;
-}
-
-int
-BMIFastDownload(struct hif_device *device, u32 address, u8 *buffer, u32 length)
-{
-    int status = A_ERROR;
-    u32 lastWord = 0;
-    u32 lastWordOffset = length & ~0x3;
-    u32 unalignedBytes = length & 0x3;
-
-    status = BMILZStreamStart (device, address);
-    if (status) {
-            return A_ERROR;
-    }
-
-    if (unalignedBytes) {
-            /* copy the last word into a zero padded buffer */
-        memcpy(&lastWord, &buffer[lastWordOffset], unalignedBytes);
-    }
-
-    status = BMILZData(device, buffer, lastWordOffset);
-
-    if (status) {
-        return A_ERROR;
-    }
-
-    if (unalignedBytes) {
-        status = BMILZData(device, (u8 *)&lastWord, 4);
-    }
-
-    if (!status) {
-        //
-        // Close compressed stream and open a new (fake) one.  This serves mainly to flush Target caches.
-        //
-        status = BMILZStreamStart (device, 0x00);
-        if (status) {
-           return A_ERROR;
-        }
-    }
-       return status;
-}
-
-int
-BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length)
-{
-    return bmiBufferSend(device, buffer, length);
-}
-
-int
-BMIRawRead(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout)
-{
-    return bmiBufferReceive(device, buffer, length, want_timeout);
-}
diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
deleted file mode 100644 (file)
index 93a2adc..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// common header file for HIF modules designed for SDIO
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef HIF_SDIO_COMMON_H_
-#define HIF_SDIO_COMMON_H_
-
-    /* SDIO manufacturer ID and Codes */
-#define MANUFACTURER_ID_AR6002_BASE        0x200
-#define MANUFACTURER_ID_AR6003_BASE        0x300
-#define MANUFACTURER_ID_AR6K_BASE_MASK     0xFF00
-#define FUNCTION_CLASS                     0x0
-#define MANUFACTURER_CODE                  0x271    /* Atheros */
-
-    /* Mailbox address in SDIO address space */
-#define HIF_MBOX_BASE_ADDR                 0x800
-#define HIF_MBOX_WIDTH                     0x800
-#define HIF_MBOX_START_ADDR(mbox)               \
-   ( HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH)
-
-#define HIF_MBOX_END_ADDR(mbox)                 \
-    (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1)
-
-    /* extended MBOX address for larger MBOX writes to MBOX 0*/
-#define HIF_MBOX0_EXTENDED_BASE_ADDR       0x2800
-#define HIF_MBOX0_EXTENDED_WIDTH_AR6002    (6*1024)           
-#define HIF_MBOX0_EXTENDED_WIDTH_AR6003    (18*1024)   
-
-    /* version 1 of the chip has only a 12K extended mbox range */
-#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1  0x4000
-#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1      (12*1024)  
-
-    /* GMBOX addresses */
-#define HIF_GMBOX_BASE_ADDR                0x7000
-#define HIF_GMBOX_WIDTH                    0x4000
-
-    /* for SDIO we recommend a 128-byte block size */
-#define HIF_DEFAULT_IO_BLOCK_SIZE          128
-
-    /* set extended MBOX window information for SDIO interconnects */
-static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, struct hif_device_mbox_info *pInfo)
-{
-    switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) {                   
-        case MANUFACTURER_ID_AR6002_BASE :
-                /* MBOX 0 has an extended range */
-            pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR;             
-            pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002;
-            break;
-        case MANUFACTURER_ID_AR6003_BASE :
-                /* MBOX 0 has an extended range */
-            pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1;             
-            pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1;
-            pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR;
-            pInfo->GMboxSize = HIF_GMBOX_WIDTH;
-            break;
-        default:
-            A_ASSERT(false);
-            break;
-    }
-}
-             
-/* special CCCR (func 0) registers */
-
-#define CCCR_SDIO_IRQ_MODE_REG         0xF0        /* interrupt mode register */
-#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ   (1 << 0)    /* mode to enable special 4-bit interrupt assertion without clock*/ 
-                        
-#endif /*HIF_SDIO_COMMON_H_*/
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
deleted file mode 100644 (file)
index ed7ad47..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="hif_internal.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// internal header file for hif layer
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HIF_INTERNAL_H_
-#define _HIF_INTERNAL_H_
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#include "hif.h"
-#include "../../../common/hif_sdio_common.h"
-#include <linux/scatterlist.h>
-#define HIF_LINUX_MMC_SCATTER_SUPPORT
-
-#define BUS_REQUEST_MAX_NUM                64
-
-#define SDIO_CLOCK_FREQUENCY_DEFAULT       25000000
-#define SDWLAN_ENABLE_DISABLE_TIMEOUT      20
-#define FLAGS_CARD_ENAB                    0x02
-#define FLAGS_CARD_IRQ_UNMSK               0x04
-
-#define HIF_MBOX_BLOCK_SIZE                HIF_DEFAULT_IO_BLOCK_SIZE
-#define HIF_MBOX0_BLOCK_SIZE               1
-#define HIF_MBOX1_BLOCK_SIZE               HIF_MBOX_BLOCK_SIZE
-#define HIF_MBOX2_BLOCK_SIZE               HIF_MBOX_BLOCK_SIZE
-#define HIF_MBOX3_BLOCK_SIZE               HIF_MBOX_BLOCK_SIZE
-
-typedef struct bus_request {
-    struct bus_request *next;       /* link list of available requests */
-    struct bus_request *inusenext;  /* link list of in use requests */
-    struct semaphore sem_req;
-    u32 address;               /* request data */
-    u8 *buffer;
-    u32 length;
-    u32 request;
-    void *context;
-    int status;
-    struct hif_scatter_req_priv *pScatterReq;      /* this request is a scatter request */
-} BUS_REQUEST;
-
-struct hif_device {
-    struct sdio_func *func;
-    spinlock_t asynclock;
-    struct task_struct* async_task;             /* task to handle async commands */
-    struct semaphore sem_async;                 /* wake up for async task */
-    int    async_shutdown;                      /* stop the async task */
-    struct completion async_completion;          /* thread completion */
-    BUS_REQUEST   *asyncreq;                    /* request for async tasklet */
-    BUS_REQUEST *taskreq;                       /*  async tasklet data */
-    spinlock_t lock;
-    BUS_REQUEST *s_busRequestFreeQueue;         /* free list */
-    BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */
-    void     *claimedContext;
-    HTC_CALLBACKS htcCallbacks;
-    u8 *dma_buffer;
-    struct dl_list      ScatterReqHead;                /* scatter request list head */
-    bool       scatter_enabled;               /* scatter enabled flag */
-    bool   is_suspend;
-    bool   is_disabled;
-    atomic_t   irqHandling;
-    HIF_DEVICE_POWER_CHANGE_TYPE powerConfig;
-    const struct sdio_device_id *id;
-};
-
-#define HIF_DMA_BUFFER_SIZE (32 * 1024)
-#define CMD53_FIXED_ADDRESS 1
-#define CMD53_INCR_ADDRESS  2
-
-BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device);
-void hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest);
-void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest);
-
-#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
-
-#define MAX_SCATTER_REQUESTS             4
-#define MAX_SCATTER_ENTRIES_PER_REQ      16
-#define MAX_SCATTER_REQ_TRANSFER_SIZE    32*1024
-
-struct hif_scatter_req_priv {
-    struct hif_scatter_req     *pHifScatterReq;  /* HIF scatter request with allocated entries */   
-    struct hif_device          *device;          /* this device */
-    BUS_REQUEST         *busrequest;      /* request associated with request */
-        /* scatter list for linux */    
-    struct scatterlist  sgentries[MAX_SCATTER_ENTRIES_PER_REQ];   
-};
-
-#define ATH_DEBUG_SCATTER  ATH_DEBUG_MAKE_MODULE_MASK(0)
-
-int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo);
-void CleanupHIFScatterResources(struct hif_device *device);
-int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest);
-
-#else  // HIF_LINUX_MMC_SCATTER_SUPPORT
-
-static inline int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo)
-{
-    return A_ENOTSUP;
-}
-
-static inline int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest)
-{
-    return A_ENOTSUP;
-}
-
-#define CleanupHIFScatterResources(d) { }
-
-#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
-
-#endif // _HIF_INTERNAL_H_
-
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
deleted file mode 100644 (file)
index 5f5d677..0000000
+++ /dev/null
@@ -1,1273 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="hif.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// HIF layer reference implementation for Linux Native MMC stack
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#include <linux/mmc/card.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sd.h>
-#include <linux/kthread.h>
-
-/* by default setup a bounce buffer for the data packets, if the underlying host controller driver
-   does not use DMA you may be able to skip this step and save the memory allocation and transfer time */
-#define HIF_USE_DMA_BOUNCE_BUFFER 1
-#include "hif_internal.h"
-#define ATH_MODULE_NAME hif
-#include "a_debug.h"
-#include "hw/mbox_host_reg.h"
-
-#if HIF_USE_DMA_BOUNCE_BUFFER
-/* macro to check if DMA buffer is WORD-aligned and DMA-able.  Most host controllers assume the
- * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).  
- * virt_addr_valid check fails on stack memory.  
- */
-#define BUFFER_NEEDS_BOUNCE(buffer)  (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer)))
-#else
-#define BUFFER_NEEDS_BOUNCE(buffer)   (false)
-#endif
-
-/* ATHENV */
-#if defined(CONFIG_PM)
-#define dev_to_sdio_func(d)    container_of(d, struct sdio_func, dev)
-#define to_sdio_driver(d)      container_of(d, struct sdio_driver, drv)
-#endif /* CONFIG_PM */
-static void delHifDevice(struct hif_device * device);
-static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
-static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
-
-static int hifEnableFunc(struct hif_device *device, struct sdio_func *func);
-static int hifDisableFunc(struct hif_device *device, struct sdio_func *func);
-OSDRV_CALLBACKS osdrvCallbacks;
-
-int reset_sdio_on_unload = 0;
-module_param(reset_sdio_on_unload, int, 0644);
-
-extern u32 nohifscattersupport;
-
-static struct hif_device *ath6kl_alloc_hifdev(struct sdio_func *func)
-{
-       struct hif_device *hifdevice;
-
-       hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL);
-
-#if HIF_USE_DMA_BOUNCE_BUFFER
-       hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
-#endif
-       hifdevice->func = func;
-       hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
-       sdio_set_drvdata(func, hifdevice);
-
-       return hifdevice;
-}
-
-static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func)
-{
-       return (struct hif_device *) sdio_get_drvdata(func);
-}
-
-static const struct sdio_device_id ath6kl_hifdev_ids[] = {
-       { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) },
-       { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) },
-       { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) },
-       { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) },
-       { /* null */                                         },
-};
-
-MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids);
-
-static int ath6kl_hifdev_probe(struct sdio_func *func,
-                              const struct sdio_device_id *id)
-{
-       int ret;
-       struct hif_device *device;
-       int count;
-
-       AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
-                       ("ath6kl: Function: 0x%X, Vendor ID: 0x%X, "
-                        "Device ID: 0x%X, block size: 0x%X/0x%X\n",
-                       func->num, func->vendor, func->device,
-                       func->max_blksize, func->cur_blksize));
-
-       ath6kl_alloc_hifdev(func);
-       device = ath6kl_get_hifdev(func);
-
-       device->id = id;
-       device->is_disabled = true;
-
-       spin_lock_init(&device->lock);
-       spin_lock_init(&device->asynclock);
-
-       DL_LIST_INIT(&device->ScatterReqHead);
-
-       /* Try to allow scatter unless globally overridden */
-       if (!nohifscattersupport)
-               device->scatter_enabled = true;
-
-       A_MEMZERO(device->busRequest, sizeof(device->busRequest));
-
-       for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) {
-               sema_init(&device->busRequest[count].sem_req, 0);
-               hifFreeBusRequest(device, &device->busRequest[count]);
-       }
-
-       sema_init(&device->sem_async, 0);
-
-       ret = hifEnableFunc(device, func);
-
-       return ret;
-}
-
-static void ath6kl_hifdev_remove(struct sdio_func *func)
-{
-       int status = 0;
-       struct hif_device *device;
-
-       device = ath6kl_get_hifdev(func);
-       if (device->claimedContext != NULL)
-               status = osdrvCallbacks.
-                       deviceRemovedHandler(device->claimedContext, device);
-
-       if (device->is_disabled)
-               device->is_disabled = false;
-       else
-               status = hifDisableFunc(device, func);
-
-       CleanupHIFScatterResources(device);
-
-       delHifDevice(device);
-}
-
-#if defined(CONFIG_PM)
-static int ath6kl_hifdev_suspend(struct device *dev)
-{
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       int status = 0;
-       struct hif_device *device;
-
-       device = ath6kl_get_hifdev(func);
-
-       if (device && device->claimedContext &&
-           osdrvCallbacks.deviceSuspendHandler) {
-               /* set true first for PowerStateChangeNotify(..) */
-               device->is_suspend = true;
-               status = osdrvCallbacks.
-                       deviceSuspendHandler(device->claimedContext);
-               if (status)
-                       device->is_suspend = false;
-       }
-
-       CleanupHIFScatterResources(device);
-
-       switch (status) {
-       case 0:
-               return 0;
-       case A_EBUSY:
-               /* Hack for kernel in order to support deep sleep and wow */
-               return -EBUSY;
-       default:
-               return -1;
-       }
-}
-
-static int ath6kl_hifdev_resume(struct device *dev)
-{
-       struct sdio_func *func = dev_to_sdio_func(dev);
-       int status = 0;
-       struct hif_device *device;
-
-       device = ath6kl_get_hifdev(func);
-       if (device && device->claimedContext &&
-           osdrvCallbacks.deviceSuspendHandler) {
-               status = osdrvCallbacks.
-                       deviceResumeHandler(device->claimedContext);
-               if (status == 0)
-                       device->is_suspend = false;
-       }
-
-       return status;
-}
-
-static const struct dev_pm_ops ath6kl_hifdev_pmops = {
-       .suspend = ath6kl_hifdev_suspend,
-       .resume = ath6kl_hifdev_resume,
-};
-#endif /* CONFIG_PM */
-
-static struct sdio_driver ath6kl_hifdev_driver = {
-       .name = "ath6kl_hifdev",
-       .id_table = ath6kl_hifdev_ids,
-       .probe = ath6kl_hifdev_probe,
-       .remove = ath6kl_hifdev_remove,
-#if defined(CONFIG_PM)
-       .drv = {
-               .pm = &ath6kl_hifdev_pmops,
-       },
-#endif
-};
-
-/* make sure we only unregister when registered. */
-static int registered = 0;
-
-extern u32 onebitmode;
-extern u32 busspeedlow;
-extern u32 debughif;
-
-static void ResetAllCards(void);
-
-#ifdef DEBUG
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
-                                 "hif",
-                                 "(Linux MMC) Host Interconnect Framework",
-                                 ATH_DEBUG_MASK_DEFAULTS,
-                                 0,
-                                 NULL);
-                                 
-#endif
-
-
-/* ------ Functions ------ */
-int HIFInit(OSDRV_CALLBACKS *callbacks)
-{
-       int r;
-       AR_DEBUG_ASSERT(callbacks != NULL);
-
-       A_REGISTER_MODULE_DEBUG_INFO(hif);
-
-       /* store the callback handlers */
-       osdrvCallbacks = *callbacks;
-
-       /* Register with bus driver core */
-       registered = 1;
-
-       r = sdio_register_driver(&ath6kl_hifdev_driver);
-       if (r < 0)
-               return r;
-
-       return 0;
-}
-
-static int
-__HIFReadWrite(struct hif_device *device,
-             u32 address,
-             u8 *buffer,
-             u32 length,
-             u32 request,
-             void *context)
-{
-    u8 opcode;
-    int    status = 0;
-    int     ret;
-    u8 *tbuffer;
-    bool   bounced = false;
-
-    AR_DEBUG_ASSERT(device != NULL);
-    AR_DEBUG_ASSERT(device->func != NULL);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n", 
-                    device, buffer, address));
-
-    do {
-        if (request & HIF_EXTENDED_IO) {
-            //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n"));
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("AR6000: Invalid command type: 0x%08x\n", request));
-            status = A_EINVAL;
-            break;
-        }
-
-        if (request & HIF_BLOCK_BASIS) {
-            /* round to whole block length size */
-            length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE;
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
-                            ("AR6000: Block mode (BlockLen: %d)\n",
-                            length));
-        } else if (request & HIF_BYTE_BASIS) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
-                            ("AR6000: Byte mode (BlockLen: %d)\n",
-                            length));
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("AR6000: Invalid data mode: 0x%08x\n", request));
-            status = A_EINVAL;
-            break;
-        }
-
-#if 0
-        /* useful for checking register accesses */
-        if (length & 0x3) {
-            A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
-                                request & HIF_WRITE ? "write":"read", address, length);
-        }
-#endif
-
-        if (request & HIF_WRITE) {
-            if ((address >= HIF_MBOX_START_ADDR(0)) &&
-                (address <= HIF_MBOX_END_ADDR(3)))
-            {
-    
-                AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH);
-    
-                /*
-                 * Mailbox write. Adjust the address so that the last byte
-                 * falls on the EOM address.
-                 */
-                address += (HIF_MBOX_WIDTH - length);
-            }
-        }
-
-        if (request & HIF_FIXED_ADDRESS) {
-            opcode = CMD53_FIXED_ADDRESS;
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address));
-        } else if (request & HIF_INCREMENTAL_ADDRESS) {
-            opcode = CMD53_INCR_ADDRESS;
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address));
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("AR6000: Invalid address mode: 0x%08x\n", request));
-            status = A_EINVAL;
-            break;
-        }
-
-        if (request & HIF_WRITE) {
-#if HIF_USE_DMA_BOUNCE_BUFFER
-            if (BUFFER_NEEDS_BOUNCE(buffer)) {
-                AR_DEBUG_ASSERT(device->dma_buffer != NULL);
-                tbuffer = device->dma_buffer;
-                    /* copy the write data to the dma buffer */
-                AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
-                memcpy(tbuffer, buffer, length);
-                bounced = true;
-            } else {
-                tbuffer = buffer;    
-            }
-#else
-               tbuffer = buffer;
-#endif
-            if (opcode == CMD53_FIXED_ADDRESS) {
-                ret = sdio_writesb(device->func, address, tbuffer, length);
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n",
-                                                 ret, address, length, *(int *)tbuffer));
-            } else {
-                ret = sdio_memcpy_toio(device->func, address, tbuffer, length);
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
-                                                 ret, address, length, *(int *)tbuffer));
-            }
-        } else if (request & HIF_READ) {
-#if HIF_USE_DMA_BOUNCE_BUFFER
-            if (BUFFER_NEEDS_BOUNCE(buffer)) {
-                AR_DEBUG_ASSERT(device->dma_buffer != NULL);
-                AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
-                tbuffer = device->dma_buffer;
-                bounced = true;
-            } else {
-                tbuffer = buffer;    
-            }
-#else
-            tbuffer = buffer;
-#endif
-            if (opcode == CMD53_FIXED_ADDRESS) {
-                ret = sdio_readsb(device->func, tbuffer, address, length);
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n",
-                                                 ret, address, length, *(int *)tbuffer));
-            } else {
-                ret = sdio_memcpy_fromio(device->func, tbuffer, address, length);
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
-                                                 ret, address, length, *(int *)tbuffer));
-            }
-#if HIF_USE_DMA_BOUNCE_BUFFER
-            if (bounced) {
-                  /* copy the read data from the dma buffer */
-                memcpy(buffer, tbuffer, length);
-            }
-#endif
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("AR6000: Invalid direction: 0x%08x\n", request));
-            status = A_EINVAL;
-            break;
-        }
-
-        if (ret) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret));
-            status = A_ERROR;
-        }
-    } while (false);
-
-    return status;
-}
-
-void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest)
-{
-    unsigned long flags;
-    BUS_REQUEST *async;
-    BUS_REQUEST *active;
-    
-    spin_lock_irqsave(&device->asynclock, flags);
-    active = device->asyncreq;
-    if (active == NULL) {
-        device->asyncreq = busrequest;
-        device->asyncreq->inusenext = NULL;
-    } else {
-        for (async = device->asyncreq;
-             async != NULL;
-             async = async->inusenext) {
-             active =  async;
-        }
-        active->inusenext = busrequest;
-        busrequest->inusenext = NULL;
-    }
-    spin_unlock_irqrestore(&device->asynclock, flags);
-}
-
-
-/* queue a read/write request */
-int
-HIFReadWrite(struct hif_device *device,
-             u32 address,
-             u8 *buffer,
-             u32 length,
-             u32 request,
-             void *context)
-{
-    int    status = 0;
-    BUS_REQUEST *busrequest;
-
-
-    AR_DEBUG_ASSERT(device != NULL);
-    AR_DEBUG_ASSERT(device->func != NULL);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));
-
-    do {            
-        if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
-            /* serialize all requests through the async thread */
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n", 
-                        (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
-            busrequest = hifAllocateBusRequest(device);
-            if (busrequest == NULL) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
-                    ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n", 
-                        request & HIF_READ ? "READ":"WRITE", address, length));
-                return A_ERROR;
-            }
-            busrequest->address = address;
-            busrequest->buffer = buffer;
-            busrequest->length = length;
-            busrequest->request = request;
-            busrequest->context = context;
-            
-            AddToAsyncList(device, busrequest);
-            
-            if (request & HIF_SYNCHRONOUS) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest));
-
-                /* wait for completion */
-                up(&device->sem_async);
-                if (down_interruptible(&busrequest->sem_req) != 0) {
-                    /* interrupted, exit */
-                    return A_ERROR;
-                } else {
-                    int status = busrequest->status;
-                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n", 
-                                                     (unsigned long)busrequest, busrequest->status));
-                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
-                    hifFreeBusRequest(device, busrequest);
-                    return status;
-                }
-            } else {
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest));
-                up(&device->sem_async);
-                return A_PENDING;
-            }
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
-            status = A_EINVAL;
-            break;
-        }
-    } while(0);
-
-    return status;
-}
-/* thread to serialize all requests, both sync and async */
-static int async_task(void *param)
- {
-    struct hif_device *device;
-    BUS_REQUEST *request;
-    int status;
-    unsigned long flags;
-
-    device = (struct hif_device *)param;
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
-    set_current_state(TASK_INTERRUPTIBLE);
-    while(!device->async_shutdown) {
-        /* wait for work */
-        if (down_interruptible(&device->sem_async) != 0) {
-            /* interrupted, exit */
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
-            break;
-        }
-        if (device->async_shutdown) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
-            break;
-        }
-        /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
-        sdio_claim_host(device->func);
-        spin_lock_irqsave(&device->asynclock, flags);
-        /* pull the request to work on */
-        while (device->asyncreq != NULL) {
-            request = device->asyncreq;
-            if (request->inusenext != NULL) {
-                device->asyncreq = request->inusenext;
-            } else {
-                device->asyncreq = NULL;
-            }
-            spin_unlock_irqrestore(&device->asynclock, flags);
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request));
-            
-            if (request->pScatterReq != NULL) {
-                A_ASSERT(device->scatter_enabled);
-                    /* this is a queued scatter request, pass the request to scatter routine which
-                     * executes it synchronously, note, no need to free the request since scatter requests
-                     * are maintained on a separate list */
-                status = DoHifReadWriteScatter(device,request);
-            } else {                
-                    /* call HIFReadWrite in sync mode to do the work */
-                status = __HIFReadWrite(device, request->address, request->buffer,
-                                      request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
-                if (request->request & HIF_ASYNCHRONOUS) {
-                    void *context = request->context;
-                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request));
-                    hifFreeBusRequest(device, request);
-                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request));
-                    device->htcCallbacks.rwCompletionHandler(context, status);
-                } else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request));
-                    request->status = status;
-                    up(&request->sem_req);
-                }
-            }
-            spin_lock_irqsave(&device->asynclock, flags);
-        }
-        spin_unlock_irqrestore(&device->asynclock, flags);
-        sdio_release_host(device->func);
-    }
-
-    complete_and_exit(&device->async_completion, 0);
-    return 0;
-}
-
-static s32 IssueSDCommand(struct hif_device *device, u32 opcode, u32 arg, u32 flags, u32 *resp)
-{
-    struct mmc_command cmd;
-    s32 err;
-    struct mmc_host *host;
-    struct sdio_func *func;
-
-    func = device->func;
-    host = func->card->host;
-
-    memset(&cmd, 0, sizeof(struct mmc_command)); 
-    cmd.opcode = opcode;
-    cmd.arg = arg;
-    cmd.flags = flags;
-    err = mmc_wait_for_cmd(host, &cmd, 3);
-
-    if ((!err) && (resp)) {
-        *resp = cmd.resp[0];
-    }
-
-    return err;
-}
-
-int ReinitSDIO(struct hif_device *device)
-{
-    s32 err;
-    struct mmc_host *host;
-    struct mmc_card *card;
-       struct sdio_func *func;
-    u8 cmd52_resp;
-    u32 clock;
-
-    func = device->func;
-    card = func->card;
-    host = card->host;
-   
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
-    sdio_claim_host(func);
-
-    do {
-        if (!device->is_suspend) {
-            u32 resp;
-            u16 rca;
-            u32 i;
-            int bit = fls(host->ocr_avail) - 1;
-            /* emulate the mmc_power_up(...) */
-            host->ios.vdd = bit;
-            host->ios.chip_select = MMC_CS_DONTCARE;
-            host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-            host->ios.power_mode = MMC_POWER_UP;
-            host->ios.bus_width = MMC_BUS_WIDTH_1;
-            host->ios.timing = MMC_TIMING_LEGACY;
-            host->ops->set_ios(host, &host->ios);
-            /*
-             * This delay should be sufficient to allow the power supply
-             * to reach the minimum voltage.
-             */
-            msleep(2);
-
-            host->ios.clock = host->f_min;
-            host->ios.power_mode = MMC_POWER_ON;
-            host->ops->set_ios(host, &host->ios);
-
-            /*
-             * This delay must be at least 74 clock sizes, or 1 ms, or the
-             * time required to reach a stable voltage.
-             */
-            msleep(2);
-
-            /* Issue CMD0. Goto idle state */
-               host->ios.chip_select = MMC_CS_HIGH;
-            host->ops->set_ios(host, &host->ios);
-               msleep(1);
-            err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
-            host->ios.chip_select = MMC_CS_DONTCARE;
-            host->ops->set_ios(host, &host->ios);
-               msleep(1);
-            host->use_spi_crc = 0;
-
-            if (err) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));    
-                break;
-            }        
-
-            if (!host->ocr) {
-                /* Issue CMD5, arg = 0 */
-                err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
-                if (err) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));    
-                    break;
-                }
-                host->ocr = resp;
-            }
-
-            /* Issue CMD5, arg = ocr. Wait till card is ready  */
-            for (i=0;i<100;i++) {
-                err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
-                if (err) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));    
-                    break;
-                }
-                if (resp & MMC_CARD_BUSY) {
-                    break;
-                }
-                msleep(10);
-            }
-
-            if ((i == 100) || (err)) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));    
-                break;
-            }
-
-            /* Issue CMD3, get RCA */
-            err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
-            if (err) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));    
-                break;
-            }
-            rca = resp >> 16;
-            host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
-            host->ops->set_ios(host, &host->ios);
-
-            /* Issue CMD7, select card  */
-            err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
-            if (err) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));    
-                break;
-            }
-        }
-        
-        /* Enable high speed */
-        if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));    
-            err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
-            if (err) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed  : %d \n",err));    
-                card->state &= ~MMC_STATE_HIGHSPEED;
-                /* no need to break */
-            } else {
-                err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
-                if (err) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed  : %d \n",err));    
-                    break;
-                }
-                mmc_card_set_highspeed(card);
-                host->ios.timing = MMC_TIMING_SD_HS;
-                host->ops->set_ios(host, &host->ios);
-            }
-        }
-
-        /* Set clock */
-        if (mmc_card_highspeed(card)) {
-            clock = 50000000;
-        } else {
-            clock = card->cis.max_dtr;
-        }
-        
-        if (clock > host->f_max) {
-            clock = host->f_max;
-        }
-        host->ios.clock = clock;
-        host->ops->set_ios(host, &host->ios);
-        
-
-        if (card->host->caps & MMC_CAP_4_BIT_DATA) {
-            /* CMD52: Set bus width & disable card detect resistor */
-            err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
-            if (err) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));    
-                break;
-            }
-            host->ios.bus_width = MMC_BUS_WIDTH_4;
-            host->ops->set_ios(host, &host->ios);
-        }
-    } while (0);
-
-    sdio_release_host(func);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n"));
-
-    return (err) ? A_ERROR : 0;
-}
-
-int
-PowerStateChangeNotify(struct hif_device *device, HIF_DEVICE_POWER_CHANGE_TYPE config)
-{
-    int status = 0;
-#if defined(CONFIG_PM)
-       struct sdio_func *func = device->func;
-    int old_reset_val;
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config));
-    switch (config) {
-       case HIF_DEVICE_POWER_DOWN:
-       case HIF_DEVICE_POWER_CUT:
-            old_reset_val = reset_sdio_on_unload;
-            reset_sdio_on_unload = 1;
-            status = hifDisableFunc(device, func);
-            reset_sdio_on_unload = old_reset_val;
-            if (!device->is_suspend) {
-                struct mmc_host *host = func->card->host;
-                   host->ios.clock = 0;
-                   host->ios.vdd = 0;
-                host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-                host->ios.chip_select = MMC_CS_DONTCARE;
-                host->ios.power_mode = MMC_POWER_OFF;
-                host->ios.bus_width = MMC_BUS_WIDTH_1;
-                host->ios.timing = MMC_TIMING_LEGACY;
-                host->ops->set_ios(host, &host->ios);
-            }
-            break;
-       case HIF_DEVICE_POWER_UP:
-            if (device->powerConfig == HIF_DEVICE_POWER_CUT) {
-                status = ReinitSDIO(device);
-            }
-            if (status == 0) {
-                status = hifEnableFunc(device, func);
-            }
-            break;
-    } 
-    device->powerConfig = config;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n"));
-#endif
-    return status;
-}
-
-int
-HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
-                   void *config, u32 configLen)
-{
-    u32 count;
-    int status = 0;
-    
-    switch(opcode) {
-        case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
-            ((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
-            ((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
-            ((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
-            ((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
-            break;
-
-        case HIF_DEVICE_GET_MBOX_ADDR:
-            for (count = 0; count < 4; count ++) {
-                ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count);
-            }
-            
-            if (configLen >= sizeof(struct hif_device_mbox_info)) {    
-                SetExtendedMboxWindowInfo((u16)device->func->device,
-                                          (struct hif_device_mbox_info *)config);
-            }
-                        
-            break;
-        case HIF_DEVICE_GET_IRQ_PROC_MODE:
-            *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
-            break;
-       case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
-            if (!device->scatter_enabled) {
-                return A_ENOTSUP;    
-            }
-            status = SetupHIFScatterSupport(device, (struct hif_device_scatter_support_info *)config);
-            if (status) {
-                device->scatter_enabled = false;
-            }
-            break; 
-        case HIF_DEVICE_GET_OS_DEVICE:
-                /* pass back a pointer to the SDIO function's "dev" struct */
-            ((struct hif_device_os_device_info *)config)->pOSDevice = &device->func->dev;
-            break; 
-        case HIF_DEVICE_POWER_STATE_CHANGE:
-            status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
-            break;
-        default:
-            AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
-                            ("AR6000: Unsupported configuration opcode: %d\n", opcode));
-            status = A_ERROR;
-    }
-
-    return status;
-}
-
-void
-HIFShutDownDevice(struct hif_device *device)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
-    if (device != NULL) {
-        AR_DEBUG_ASSERT(device->func != NULL);
-    } else {
-            /* since we are unloading the driver anyways, reset all cards in case the SDIO card
-             * is externally powered and we are unloading the SDIO stack.  This avoids the problem when
-             * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
-             * enumerated */
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
-        ResetAllCards();
-
-        /* Unregister with bus driver core */
-        if (registered) {
-            registered = 0;
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
-                            ("AR6000: Unregistering with the bus driver\n"));
-            sdio_unregister_driver(&ath6kl_hifdev_driver);
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
-                            ("AR6000: Unregistered\n"));
-        }
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
-}
-
-static void
-hifIRQHandler(struct sdio_func *func)
-{
-    int status;
-    struct hif_device *device;
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
-
-    device = ath6kl_get_hifdev(func);
-    atomic_set(&device->irqHandling, 1);
-    /* release the host during ints so we can pick it back up when we process cmds */
-    sdio_release_host(device->func);
-    status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
-    sdio_claim_host(device->func);
-    atomic_set(&device->irqHandling, 0);
-    AR_DEBUG_ASSERT(status == 0 || status == A_ECANCELED);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n"));
-}
-
-/* handle HTC startup via thread*/
-static int startup_task(void *param)
-{
-    struct hif_device *device;
-
-    device = (struct hif_device *)param;
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
-        /* start  up inform DRV layer */
-    if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
-    }
-    return 0;
-}
-
-#if defined(CONFIG_PM)
-static int enable_task(void *param)
-{
-    struct hif_device *device;
-    device = (struct hif_device *)param;
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call  from resume_task\n"));
-
-        /* start  up inform DRV layer */
-    if (device && 
-        device->claimedContext && 
-        osdrvCallbacks.devicePowerChangeHandler &&
-        osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != 0)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
-    }
-
-    return 0;
-}
-#endif
-
-void
-HIFAckInterrupt(struct hif_device *device)
-{
-    AR_DEBUG_ASSERT(device != NULL);
-
-    /* Acknowledge our function IRQ */
-}
-
-void
-HIFUnMaskInterrupt(struct hif_device *device)
-{
-    int ret;
-
-    AR_DEBUG_ASSERT(device != NULL);
-    AR_DEBUG_ASSERT(device->func != NULL);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));
-
-    /* Register the IRQ Handler */
-    sdio_claim_host(device->func);
-    ret = sdio_claim_irq(device->func, hifIRQHandler);
-    sdio_release_host(device->func);
-    AR_DEBUG_ASSERT(ret == 0);
-}
-
-void HIFMaskInterrupt(struct hif_device *device)
-{
-    int ret;
-    AR_DEBUG_ASSERT(device != NULL);
-    AR_DEBUG_ASSERT(device->func != NULL);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));
-
-    /* Mask our function IRQ */
-    sdio_claim_host(device->func);
-    while (atomic_read(&device->irqHandling)) {        
-        sdio_release_host(device->func);
-        schedule_timeout(HZ/10);
-        sdio_claim_host(device->func);
-    }
-    ret = sdio_release_irq(device->func);
-    sdio_release_host(device->func);
-    AR_DEBUG_ASSERT(ret == 0);
-}
-
-BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device)
-{
-    BUS_REQUEST *busrequest;
-    unsigned long flag;
-
-    /* Acquire lock */
-    spin_lock_irqsave(&device->lock, flag);
-
-    /* Remove first in list */
-    if((busrequest = device->s_busRequestFreeQueue) != NULL)
-    {
-        device->s_busRequestFreeQueue = busrequest->next;
-    }
-    /* Release lock */
-    spin_unlock_irqrestore(&device->lock, flag);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest));
-    return busrequest;
-}
-
-void
-hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest)
-{
-    unsigned long flag;
-
-    AR_DEBUG_ASSERT(busrequest != NULL);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest));
-    /* Acquire lock */
-    spin_lock_irqsave(&device->lock, flag);
-
-
-    /* Insert first in list */
-    busrequest->next = device->s_busRequestFreeQueue;
-    busrequest->inusenext = NULL;
-    device->s_busRequestFreeQueue = busrequest;
-
-    /* Release lock */
-    spin_unlock_irqrestore(&device->lock, flag);
-}
-
-static int hifDisableFunc(struct hif_device *device, struct sdio_func *func)
-{
-    int ret;
-    int status = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
-    device = ath6kl_get_hifdev(func);
-    if (!IS_ERR(device->async_task)) {
-        init_completion(&device->async_completion);
-        device->async_shutdown = 1;
-        up(&device->sem_async);
-        wait_for_completion(&device->async_completion);
-        device->async_task = NULL;
-    }
-    /* Disable the card */
-    sdio_claim_host(device->func);
-    ret = sdio_disable_func(device->func);
-    if (ret) {
-        status = A_ERROR;
-    } 
-
-    if (reset_sdio_on_unload) {
-        /* reset the SDIO interface.  This is useful in automated testing where the card
-         * does not need to be removed at the end of the test.  It is expected that the user will 
-         * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n"));
-        
-        /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access
-         *        to undefined registers in the range of: 0xF0-0xFF */
-         
-        ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)); 
-        if (ret) {
-            status = A_ERROR;
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret));    
-        }
-    }
-
-    sdio_release_host(device->func);
-
-    if (status == 0) {
-        device->is_disabled = true;
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n"));
-
-    return status;
-}
-
-static int hifEnableFunc(struct hif_device *device, struct sdio_func *func)
-{
-    struct task_struct* pTask;
-    const char *taskName = NULL;
-    int (*taskFunc)(void *) = NULL;
-    int ret = 0;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
-    device = ath6kl_get_hifdev(func);
-
-    if (device->is_disabled) {
-       /* enable the SDIO function */
-        sdio_claim_host(func);
-
-        if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
-            /* enable 4-bit ASYNC interrupt on AR6003 or later devices */
-            ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
-            if (ret) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
-                sdio_release_host(func);
-                return ret;
-            }
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
-        }
-        /* give us some time to enable, in ms */
-        func->enable_timeout = 100;
-        ret = sdio_enable_func(func);
-        if (ret) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
-                                         __FUNCTION__, ret));
-            sdio_release_host(func);
-            return ret;
-        }
-        ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
-        sdio_release_host(func);
-        if (ret) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x  AR6K: 0x%X\n",
-                                         __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
-            return ret;
-        }
-        device->is_disabled = false;
-        /* create async I/O thread */
-        if (!device->async_task) {
-            device->async_shutdown = 0;
-            device->async_task = kthread_create(async_task,
-                                           (void *)device,
-                                           "AR6K Async");
-           if (IS_ERR(device->async_task)) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
-                return -ENOMEM;
-           }
-           AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
-           wake_up_process(device->async_task );    
-        }
-    }
-
-    if (!device->claimedContext) {
-        taskFunc = startup_task;
-        taskName = "AR6K startup";
-        ret = 0;
-#if defined(CONFIG_PM)
-    } else {
-        taskFunc = enable_task;
-        taskName = "AR6K enable";
-        ret = -ENOMEM;
-#endif /* CONFIG_PM */
-    }
-    /* create resume thread */
-    pTask = kthread_create(taskFunc, (void *)device, taskName);
-    if (IS_ERR(pTask)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
-        return -ENOMEM;
-    }
-    wake_up_process(pTask);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
-
-    /* task will call the enable func, indicate pending */
-    return ret;
-}
-
-/*
- * This should be moved to AR6K HTC layer.
- */
-int hifWaitForPendingRecv(struct hif_device *device)
-{
-    s32 cnt = 10;
-    u8 host_int_status;
-    int status = 0;
-
-    do {                           
-        while (atomic_read(&device->irqHandling)) {
-               /* wait until irq handler finished all the jobs */
-                       schedule_timeout(HZ/10);
-           }
-               /* check if there is any pending irq due to force done */
-               host_int_status = 0;
-           status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
-                                   (u8 *)&host_int_status, sizeof(host_int_status),
-                                    HIF_RD_SYNC_BYTE_INC, NULL);
-           host_int_status = !status ? (host_int_status & (1 << 0)) : 0;
-               if (host_int_status) {
-               schedule(); /* schedule for next dsrHandler */
-               }
-       } while (host_int_status && --cnt > 0);
-
-    if (host_int_status && cnt == 0) {
-         AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, 
-                            ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__));
-     }
-
-    return 0;
-}
-    
-static void
-delHifDevice(struct hif_device * device)
-{
-    AR_DEBUG_ASSERT(device!= NULL);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device));
-    kfree(device->dma_buffer);
-    kfree(device);
-}
-
-static void ResetAllCards(void)
-{
-}
-
-void HIFClaimDevice(struct hif_device  *device, void *context)
-{
-    device->claimedContext = context;
-}
-
-void HIFReleaseDevice(struct hif_device  *device)
-{
-    device->claimedContext = NULL;
-}
-
-int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks)
-{
-    if (device->htcCallbacks.context != NULL) {
-            /* already in use! */
-        return A_ERROR;
-    }
-    device->htcCallbacks = *callbacks;
-    return 0;
-}
-
-void HIFDetachHTC(struct hif_device *device)
-{
-    A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
-}
-
-#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
-    (arg) = (((rw) & 1) << 31)           | \
-            (((func) & 0x7) << 28)       | \
-            (((raw) & 1) << 27)          | \
-            (1 << 26)                    | \
-            (((address) & 0x1FFFF) << 9) | \
-            (1 << 8)                     | \
-            ((writedata) & 0xFF)
-            
-#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
-    SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00)
-#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
-    SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value)
-    
-static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte)
-{
-    struct mmc_command ioCmd;
-    unsigned long      arg;
-    
-    memset(&ioCmd,0,sizeof(ioCmd));
-    SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte);
-    ioCmd.opcode = SD_IO_RW_DIRECT;
-    ioCmd.arg = arg;
-    ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
-    
-    return mmc_wait_for_cmd(card->host, &ioCmd, 0);
-}
-
-static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte)
-{
-    struct mmc_command ioCmd;
-    unsigned long      arg;
-    s32 err;
-    
-    memset(&ioCmd,0,sizeof(ioCmd));
-    SDIO_SET_CMD52_READ_ARG(arg,0,address);
-    ioCmd.opcode = SD_IO_RW_DIRECT;
-    ioCmd.arg = arg;
-    ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
-
-    err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
-
-    if ((!err) && (byte)) {
-        *byte =  ioCmd.resp[0] & 0xFF;
-    }
-
-    return err;
-}
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
deleted file mode 100644 (file)
index 7516d91..0000000
+++ /dev/null
@@ -1,393 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// HIF scatter implementation
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/kthread.h>
-#include "hif_internal.h"
-#define ATH_MODULE_NAME hif
-#include "a_debug.h"
-
-#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
-
-#define _CMD53_ARG_READ          0
-#define _CMD53_ARG_WRITE         1
-#define _CMD53_ARG_BLOCK_BASIS   1 
-#define _CMD53_ARG_FIXED_ADDRESS 0
-#define _CMD53_ARG_INCR_ADDRESS  1
-
-#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \
-    (arg) = (((rw) & 1) << 31)                  | \
-            (((func) & 0x7) << 28)              | \
-            (((mode) & 1) << 27)                | \
-            (((opcode) & 1) << 26)              | \
-            (((address) & 0x1FFFF) << 9)        | \
-            ((bytes_blocks) & 0x1FF)
-            
-static void FreeScatterReq(struct hif_device *device, struct hif_scatter_req *pReq)
-{   
-    unsigned long flag;
-
-    spin_lock_irqsave(&device->lock, flag);
-
-    DL_ListInsertTail(&device->ScatterReqHead, &pReq->ListLink);
-    
-    spin_unlock_irqrestore(&device->lock, flag);
-        
-}
-
-static struct hif_scatter_req *AllocScatterReq(struct hif_device *device) 
-{
-    struct dl_list       *pItem; 
-    unsigned long flag;
-
-    spin_lock_irqsave(&device->lock, flag);
-    
-    pItem = DL_ListRemoveItemFromHead(&device->ScatterReqHead);
-    
-    spin_unlock_irqrestore(&device->lock, flag);
-    
-    if (pItem != NULL) {
-        return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink);
-    }
-    
-    return NULL;   
-}
-
-    /* called by async task to perform the operation synchronously using direct MMC APIs  */
-int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest)
-{
-    int                     i;
-    u8 rw;
-    u8 opcode;
-    struct mmc_request      mmcreq;
-    struct mmc_command      cmd;
-    struct mmc_data         data;
-    struct hif_scatter_req_priv   *pReqPriv;   
-    struct hif_scatter_req        *pReq;       
-    int                status = 0;
-    struct                  scatterlist *pSg;
-    
-    pReqPriv = busrequest->pScatterReq;
-    
-    A_ASSERT(pReqPriv != NULL);
-    
-    pReq = pReqPriv->pHifScatterReq;
-    
-    memset(&mmcreq, 0, sizeof(struct mmc_request));
-    memset(&cmd, 0, sizeof(struct mmc_command));
-    memset(&data, 0, sizeof(struct mmc_data));
-       
-    data.blksz = HIF_MBOX_BLOCK_SIZE;
-    data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
-                        
-    AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n",
-              (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks,
-              pReq->TotalLength,pReq->ValidScatterEntries));
-         
-    if (pReq->Request  & HIF_WRITE) {
-        rw = _CMD53_ARG_WRITE;
-        data.flags = MMC_DATA_WRITE;
-    } else {
-        rw = _CMD53_ARG_READ;
-        data.flags = MMC_DATA_READ;
-    }
-
-    if (pReq->Request & HIF_FIXED_ADDRESS) {
-        opcode = _CMD53_ARG_FIXED_ADDRESS;
-    } else {
-        opcode = _CMD53_ARG_INCR_ADDRESS;
-    }
-    
-        /* fill SG entries */
-    pSg = pReqPriv->sgentries;   
-    sg_init_table(pSg, pReq->ValidScatterEntries); 
-          
-        /* assemble SG list */   
-    for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) {
-            /* setup each sg entry */
-        if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) {
-                /* note some scatter engines can handle unaligned buffers, print this
-                 * as informational only */
-            AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER,
-                            ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n",
-                            pReq->Request & HIF_WRITE ? "WRITE":"READ",
-                            (unsigned long)pReq->ScatterList[i].pBuffer)); 
-        }
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("  %d:  Addr:0x%lX, Len:%d \n",
-            i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length));
-            
-        sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length);
-    }
-        /* set scatter-gather table for request */
-    data.sg = pReqPriv->sgentries;
-    data.sg_len = pReq->ValidScatterEntries;
-        /* set command argument */    
-    SDIO_SET_CMD53_ARG(cmd.arg, 
-                       rw, 
-                       device->func->num, 
-                       _CMD53_ARG_BLOCK_BASIS, 
-                       opcode,  
-                       pReq->Address,
-                       data.blocks);  
-                       
-    cmd.opcode = SD_IO_RW_EXTENDED;
-    cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
-    
-    mmcreq.cmd = &cmd;
-    mmcreq.data = &data;
-    
-    mmc_set_data_timeout(&data, device->func->card);    
-        /* synchronous call to process request */
-    mmc_wait_for_req(device->func->card->host, &mmcreq);
-    if (cmd.error) {
-        status = A_ERROR;   
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error));
-    }
-               
-    if (data.error) {
-        status = A_ERROR;
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error));   
-    }
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n",
-              (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks));        
-    }
-    
-        /* set completion status, fail or success */
-    pReq->CompletionStatus = status;
-    
-    if (pReq->Request & HIF_ASYNCHRONOUS) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status));
-            /* complete the request */
-        A_ASSERT(pReq->CompletionRoutine != NULL);
-        pReq->CompletionRoutine(pReq);
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status));
-            /* signal wait */
-        up(&busrequest->sem_req);
-    }
-                                                               
-    return status;   
-}
-
-    /* callback to issue a read-write scatter request */
-static int HifReadWriteScatter(struct hif_device *device, struct hif_scatter_req *pReq)
-{
-    int             status = A_EINVAL;
-    u32 request = pReq->Request;
-    struct hif_scatter_req_priv *pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0];
-    
-    do {
-        
-        A_ASSERT(pReqPriv != NULL);
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: total len: %d Scatter Entries: %d\n", 
-                            pReq->TotalLength, pReq->ValidScatterEntries));
-        
-        if (!(request & HIF_EXTENDED_IO)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("HIF-SCATTER: Invalid command type: 0x%08x\n", request));
-            break;
-        }
-        
-        if (!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("HIF-SCATTER: Invalid execution mode: 0x%08x\n", request));
-            break;
-        }
-        
-        if (!(request & HIF_BLOCK_BASIS)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("HIF-SCATTER: Invalid data mode: 0x%08x\n", request));
-            break;   
-        }
-        
-        if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
-                            ("HIF-SCATTER: Invalid length: %d \n", pReq->TotalLength));
-            break;          
-        }
-        
-        if (pReq->TotalLength == 0) {
-            A_ASSERT(false);
-            break;    
-        }
-        
-            /* add bus request to the async list for the async I/O thread to process */
-        AddToAsyncList(device, pReqPriv->busrequest);
-
-        if (request & HIF_SYNCHRONOUS) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued sync req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
-            /* signal thread and wait */
-            up(&device->sem_async);
-            if (down_interruptible(&pReqPriv->busrequest->sem_req) != 0) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("HIF-SCATTER: interrupted! \n"));
-                /* interrupted, exit */
-                status = A_ERROR;
-                break;
-            } else {
-                status = pReq->CompletionStatus;
-            }
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
-                /* wake thread, it will process and then take care of the async callback */
-            up(&device->sem_async);
-            status = 0;
-        }           
-       
-    } while (false);
-
-    if (status && (request & HIF_ASYNCHRONOUS)) {
-        pReq->CompletionStatus = status;
-        pReq->CompletionRoutine(pReq);
-        status = 0;
-    }
-        
-    return status;  
-}
-
-    /* setup of HIF scatter resources */
-int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo)
-{
-    int              status = A_ERROR;
-    int                   i;
-    struct hif_scatter_req_priv *pReqPriv;
-    BUS_REQUEST          *busrequest;
-        
-    do {
-        
-            /* check if host supports scatter requests and it meets our requirements */
-        if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
-                    device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ));
-            status = A_ENOTSUP;
-            break;    
-        }
-                    
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n",
-                MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); 
-        
-        for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {    
-                /* allocate the private request blob */
-            pReqPriv = (struct hif_scatter_req_priv *)A_MALLOC(sizeof(struct hif_scatter_req_priv));
-            if (NULL == pReqPriv) {
-                break;    
-            }
-            A_MEMZERO(pReqPriv, sizeof(struct hif_scatter_req_priv));
-                /* save the device instance*/
-            pReqPriv->device = device;      
-                /* allocate the scatter request */
-            pReqPriv->pHifScatterReq = (struct hif_scatter_req *)A_MALLOC(sizeof(struct hif_scatter_req) + 
-                                         (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item))); 
-           
-            if (NULL == pReqPriv->pHifScatterReq) {
-                kfree(pReqPriv);
-                break;      
-            }           
-                /* just zero the main part of the scatter request */
-            A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(struct hif_scatter_req));
-                /* back pointer to the private struct */
-            pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv;
-                /* allocate a bus request for this scatter request */
-            busrequest = hifAllocateBusRequest(device);
-            if (NULL == busrequest) {
-                kfree(pReqPriv->pHifScatterReq);
-                kfree(pReqPriv);
-                break;    
-            }
-                /* assign the scatter request to this bus request */
-            busrequest->pScatterReq = pReqPriv;
-                /* point back to the request */
-            pReqPriv->busrequest = busrequest;                           
-                /* add it to the scatter pool */
-            FreeScatterReq(device,pReqPriv->pHifScatterReq);
-        }
-        
-        if (i != MAX_SCATTER_REQUESTS) {
-            status = A_NO_MEMORY;
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n"));
-            break;    
-        }
-        
-            /* set scatter function pointers */
-        pInfo->pAllocateReqFunc = AllocScatterReq;
-        pInfo->pFreeReqFunc = FreeScatterReq;
-        pInfo->pReadWriteScatterFunc = HifReadWriteScatter;   
-        pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
-        pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE;
-     
-        status = 0;
-        
-    } while (false);
-    
-    if (status) {
-        CleanupHIFScatterResources(device);   
-    }
-    
-    return status;
-}
-
-    /* clean up scatter support */
-void CleanupHIFScatterResources(struct hif_device *device)
-{
-    struct hif_scatter_req_priv    *pReqPriv;
-    struct hif_scatter_req         *pReq;
-    
-        /* empty the free list */
-        
-    while (1) {
-        
-        pReq = AllocScatterReq(device);
-                
-        if (NULL == pReq) {
-            break;    
-        }   
-        
-        pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0];
-        A_ASSERT(pReqPriv != NULL);
-        
-        if (pReqPriv->busrequest != NULL) {
-            pReqPriv->busrequest->pScatterReq = NULL;
-                /* free bus request */
-            hifFreeBusRequest(device, pReqPriv->busrequest);
-            pReqPriv->busrequest = NULL;
-        }
-        
-        if (pReqPriv->pHifScatterReq != NULL) {
-            kfree(pReqPriv->pHifScatterReq);   
-            pReqPriv->pHifScatterReq = NULL; 
-        }
-                
-        kfree(pReqPriv);       
-    }
-}
-
-#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
deleted file mode 100644 (file)
index f8607bc..0000000
+++ /dev/null
@@ -1,1479 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6k.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// AR6K device layer that handles register level I/O
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "hw/mbox_host_reg.h"
-#include "a_osapi.h"
-#include "../htc_debug.h"
-#include "hif.h"
-#include "htc_packet.h"
-#include "ar6k.h"
-
-#define MAILBOX_FOR_BLOCK_SIZE          1
-
-int DevEnableInterrupts(struct ar6k_device *pDev);
-int DevDisableInterrupts(struct ar6k_device *pDev);
-
-static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev);
-
-void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket)
-{
-    LOCK_AR6K(pDev);
-    HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket);
-    UNLOCK_AR6K(pDev);
-}
-
-struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev)
-{
-    struct htc_packet *pPacket;
-
-    LOCK_AR6K(pDev);
-    pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList);
-    UNLOCK_AR6K(pDev);
-
-    return pPacket;
-}
-
-void DevCleanup(struct ar6k_device *pDev)
-{
-    DevCleanupGMbox(pDev);
-
-    if (pDev->HifAttached) {
-        HIFDetachHTC(pDev->HIFDevice);
-        pDev->HifAttached = false;
-    }
-
-    DevCleanupVirtualScatterSupport(pDev);
-
-    if (A_IS_MUTEX_VALID(&pDev->Lock)) {
-        A_MUTEX_DELETE(&pDev->Lock);
-    }
-}
-
-int DevSetup(struct ar6k_device *pDev)
-{
-    u32 blocksizes[AR6K_MAILBOXES];
-    int status = 0;
-    int      i;
-    HTC_CALLBACKS htcCallbacks;
-
-    do {
-
-        DL_LIST_INIT(&pDev->ScatterReqHead);
-           /* initialize our free list of IO packets */
-        INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
-        A_MUTEX_INIT(&pDev->Lock);
-
-        A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
-            /* the device layer handles these */
-        htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
-        htcCallbacks.dsrHandler = DevDsrHandler;
-        htcCallbacks.context = pDev;
-
-        status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);
-
-        if (status) {
-            break;
-        }
-
-        pDev->HifAttached = true;
-
-            /* get the addresses for all 4 mailboxes */
-        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
-                                    &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));
-
-        if (status) {
-            A_ASSERT(false);
-            break;
-        }
-
-            /* carve up register I/O packets (these are for ASYNC register I/O ) */
-        for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
-            struct htc_packet *pIOPacket;
-            pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
-            SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
-                                          pDev,
-                                          pDev->RegIOBuffers[i].Buffer,
-                                          AR6K_REG_IO_BUFFER_SIZE,
-                                          0); /* don't care */
-            AR6KFreeIOPacket(pDev,pIOPacket);
-        }
-
-            /* get the block sizes */
-        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
-                                    blocksizes, sizeof(blocksizes));
-
-        if (status) {
-            A_ASSERT(false);
-            break;
-        }
-
-            /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
-             * size on mailbox 0 is artificially set to 1.  So we use the block size that is set
-             * for the other 3 mailboxes */
-        pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
-            /* must be a power of 2 */
-        A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);
-
-            /* assemble mask, used for padding to a block */
-        pDev->BlockMask = pDev->BlockSize - 1;
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
-                    pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));
-
-        pDev->GetPendingEventsFunc = NULL;
-            /* see if the HIF layer implements the get pending events function  */
-        HIFConfigureDevice(pDev->HIFDevice,
-                           HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
-                           &pDev->GetPendingEventsFunc,
-                           sizeof(pDev->GetPendingEventsFunc));
-
-            /* assume we can process HIF interrupt events asynchronously */
-        pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;
-
-            /* see if the HIF layer overrides this assumption */
-        HIFConfigureDevice(pDev->HIFDevice,
-                           HIF_DEVICE_GET_IRQ_PROC_MODE,
-                           &pDev->HifIRQProcessingMode,
-                           sizeof(pDev->HifIRQProcessingMode));
-
-        switch (pDev->HifIRQProcessingMode) {
-            case HIF_DEVICE_IRQ_SYNC_ONLY:
-                AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
-                    /* see if HIF layer wants HTC to yield */
-                HIFConfigureDevice(pDev->HIFDevice,
-                                   HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
-                                   &pDev->HifIRQYieldParams,
-                                   sizeof(pDev->HifIRQYieldParams));
-
-                if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
-                        ("HIF requests that DSR yield per %d RECV packets \n",
-                        pDev->HifIRQYieldParams.RecvPacketYieldCount));
-                    pDev->DSRCanYield = true;
-                }
-                break;
-            case HIF_DEVICE_IRQ_ASYNC_SYNC:
-                AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
-                break;
-            default:
-                A_ASSERT(false);
-        }
-
-        pDev->HifMaskUmaskRecvEvent = NULL;
-
-            /* see if the HIF layer implements the mask/unmask recv events function  */
-        HIFConfigureDevice(pDev->HIFDevice,
-                           HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
-                           &pDev->HifMaskUmaskRecvEvent,
-                           sizeof(pDev->HifMaskUmaskRecvEvent));
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
-                 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));
-
-        status = DevDisableInterrupts(pDev);
-
-        if (status) {
-            break;
-        }
-
-        status = DevSetupGMbox(pDev);
-
-    } while (false);
-
-    if (status) {
-        if (pDev->HifAttached) {
-            HIFDetachHTC(pDev->HIFDevice);
-            pDev->HifAttached = false;
-        }
-    }
-
-    return status;
-
-}
-
-int DevEnableInterrupts(struct ar6k_device *pDev)
-{
-    int                  status;
-    struct ar6k_irq_enable_registers regs;
-
-    LOCK_AR6K(pDev);
-
-        /* Enable all the interrupts except for the internal AR6000 CPU interrupt */
-    pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
-                                      INT_STATUS_ENABLE_CPU_SET(0x01) |
-                                      INT_STATUS_ENABLE_COUNTER_SET(0x01);
-
-    if (NULL == pDev->GetPendingEventsFunc) {
-        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
-    } else {
-        /* The HIF layer provided us with a pending events function which means that
-         * the detection of pending mbox messages is handled in the HIF layer.
-         * This is the case for the SPI2 interface.
-         * In the normal case we enable MBOX interrupts, for the case
-         * with HIFs that offer this mechanism, we keep these interrupts
-         * masked */
-        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
-    }
-
-
-    /* Set up the CPU Interrupt Status Register */
-    pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);
-
-    /* Set up the Error Interrupt Status Register */
-    pDev->IrqEnableRegisters.error_status_enable =
-                                  ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
-                                  ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);
-
-    /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */
-    pDev->IrqEnableRegisters.counter_int_status_enable =
-        COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK);
-
-        /* copy into our temp area */
-    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
-
-    UNLOCK_AR6K(pDev);
-
-        /* always synchronous */
-    status = HIFReadWrite(pDev->HIFDevice,
-                          INT_STATUS_ENABLE_ADDRESS,
-                          &regs.int_status_enable,
-                          AR6K_IRQ_ENABLE_REGS_SIZE,
-                          HIF_WR_SYNC_BYTE_INC,
-                          NULL);
-
-    if (status) {
-        /* Can't write it for some reason */
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("Failed to update interrupt control registers err: %d\n", status));
-
-    }
-
-    return status;
-}
-
-int DevDisableInterrupts(struct ar6k_device *pDev)
-{
-    struct ar6k_irq_enable_registers regs;
-
-    LOCK_AR6K(pDev);
-        /* Disable all interrupts */
-    pDev->IrqEnableRegisters.int_status_enable = 0;
-    pDev->IrqEnableRegisters.cpu_int_status_enable = 0;
-    pDev->IrqEnableRegisters.error_status_enable = 0;
-    pDev->IrqEnableRegisters.counter_int_status_enable = 0;
-        /* copy into our temp area */
-    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
-
-    UNLOCK_AR6K(pDev);
-
-        /* always synchronous */
-    return HIFReadWrite(pDev->HIFDevice,
-                        INT_STATUS_ENABLE_ADDRESS,
-                        &regs.int_status_enable,
-                        AR6K_IRQ_ENABLE_REGS_SIZE,
-                        HIF_WR_SYNC_BYTE_INC,
-                        NULL);
-}
-
-/* enable device interrupts */
-int DevUnmaskInterrupts(struct ar6k_device *pDev)
-{
-    /* for good measure, make sure interrupt are disabled before unmasking at the HIF
-     * layer.
-     * The rationale here is that between device insertion (where we clear the interrupts the first time)
-     * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets.
-     * The AR6K interrupt enables reset back to an "enabled" state when this happens.
-     *  */
-    int IntStatus = 0;
-    DevDisableInterrupts(pDev);
-
-#ifdef THREAD_X
-    // Tobe verified...
-    IntStatus = DevEnableInterrupts(pDev);
-    /* Unmask the host controller interrupts */
-    HIFUnMaskInterrupt(pDev->HIFDevice);
-#else
-    /* Unmask the host controller interrupts */
-    HIFUnMaskInterrupt(pDev->HIFDevice);
-    IntStatus = DevEnableInterrupts(pDev);
-#endif
-
-    return IntStatus;
-}
-
-/* disable all device interrupts */
-int DevMaskInterrupts(struct ar6k_device *pDev)
-{
-        /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while
-         * we zero out our shadow registers in DevDisableInterrupts()*/
-    HIFMaskInterrupt(pDev->HIFDevice);
-
-    return DevDisableInterrupts(pDev);
-}
-
-/* callback when our fetch to enable/disable completes */
-static void DevDoEnableDisableRecvAsyncHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6k_device *pDev = (struct ar6k_device *)Context;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-    if (pPacket->Status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                (" Failed to disable receiver, status:%d \n", pPacket->Status));
-    }
-        /* free this IO packet */
-    AR6KFreeIOPacket(pDev,pPacket);
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n"));
-}
-
-/* disable packet reception (used in case the host runs out of buffers)
- * this is the "override" method when the HIF reports another methods to
- * disable recv events */
-static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
-{
-    int                  status = 0;
-    struct htc_packet                *pIOPacket = NULL;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
-            EnableRecv,AsyncMode));
-
-    do {
-
-        if (AsyncMode) {
-
-            pIOPacket = AR6KAllocIOPacket(pDev);
-
-            if (NULL == pIOPacket) {
-                status = A_NO_MEMORY;
-                A_ASSERT(false);
-                break;
-            }
-
-                /* stick in our completion routine when the I/O operation completes */
-            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
-            pIOPacket->pContext = pDev;
-
-                /* call the HIF layer override and do this asynchronously */
-            status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
-                                                 EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
-                                                 pIOPacket);
-            break;
-        }
-
-            /* if we get here we are doing it synchronously */
-        status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
-                                             EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
-                                             NULL);
-
-    } while (false);
-
-    if (status && (pIOPacket != NULL)) {
-        AR6KFreeIOPacket(pDev,pIOPacket);
-    }
-
-    return status;
-}
-
-/* disable packet reception (used in case the host runs out of buffers)
- * this is the "normal" method using the interrupt enable registers through
- * the host I/F */
-static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode)
-{
-    int                  status = 0;
-    struct htc_packet                *pIOPacket = NULL;
-    struct ar6k_irq_enable_registers regs;
-
-        /* take the lock to protect interrupt enable shadows */
-    LOCK_AR6K(pDev);
-
-    if (EnableRecv) {
-        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
-    } else {
-        pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
-    }
-
-        /* copy into our temp area */
-    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
-    UNLOCK_AR6K(pDev);
-
-    do {
-
-        if (AsyncMode) {
-
-            pIOPacket = AR6KAllocIOPacket(pDev);
-
-            if (NULL == pIOPacket) {
-                status = A_NO_MEMORY;
-                A_ASSERT(false);
-                break;
-            }
-
-                /* copy values to write to our async I/O buffer */
-            memcpy(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);
-
-                /* stick in our completion routine when the I/O operation completes */
-            pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
-            pIOPacket->pContext = pDev;
-
-                /* write it out asynchronously */
-            HIFReadWrite(pDev->HIFDevice,
-                         INT_STATUS_ENABLE_ADDRESS,
-                         pIOPacket->pBuffer,
-                         AR6K_IRQ_ENABLE_REGS_SIZE,
-                         HIF_WR_ASYNC_BYTE_INC,
-                         pIOPacket);
-            break;
-        }
-
-        /* if we get here we are doing it synchronously */
-
-        status = HIFReadWrite(pDev->HIFDevice,
-                              INT_STATUS_ENABLE_ADDRESS,
-                              &regs.int_status_enable,
-                              AR6K_IRQ_ENABLE_REGS_SIZE,
-                              HIF_WR_SYNC_BYTE_INC,
-                              NULL);
-
-    } while (false);
-
-    if (status && (pIOPacket != NULL)) {
-        AR6KFreeIOPacket(pDev,pIOPacket);
-    }
-
-    return status;
-}
-
-
-int DevStopRecv(struct ar6k_device *pDev, bool AsyncMode)
-{
-    if (NULL == pDev->HifMaskUmaskRecvEvent) {
-        return DevDoEnableDisableRecvNormal(pDev,false,AsyncMode);
-    } else {
-        return DevDoEnableDisableRecvOverride(pDev,false,AsyncMode);
-    }
-}
-
-int DevEnableRecv(struct ar6k_device *pDev, bool AsyncMode)
-{
-    if (NULL == pDev->HifMaskUmaskRecvEvent) {
-        return DevDoEnableDisableRecvNormal(pDev,true,AsyncMode);
-    } else {
-        return DevDoEnableDisableRecvOverride(pDev,true,AsyncMode);
-    }
-}
-
-int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending)
-{
-    int    status          = 0;
-    u8     host_int_status = 0x0;
-    u32 counter         = 0x0;
-
-    if(TimeoutInMs < 100)
-    {
-        TimeoutInMs = 100;
-    }
-
-    counter = TimeoutInMs / 100;
-
-    do
-    {
-        //Read the Host Interrupt Status Register
-        status = HIFReadWrite(pDev->HIFDevice,
-                              HOST_INT_STATUS_ADDRESS,
-                             &host_int_status,
-                              sizeof(u8),
-                              HIF_RD_SYNC_BYTE_INC,
-                              NULL);
-        if (status)
-        {
-            AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status));
-            break;
-        }
-
-        host_int_status = !status ? (host_int_status & (1 << 0)):0;
-        if(!host_int_status)
-        {
-            status          = 0;
-           *pbIsRecvPending = false;
-            break;
-        }
-        else
-        {
-            *pbIsRecvPending = true;
-        }
-
-        A_MDELAY(100);
-
-        counter--;
-
-    }while(counter);
-    return status;
-}
-
-void DevDumpRegisters(struct ar6k_device               *pDev,
-                      struct ar6k_irq_proc_registers   *pIrqProcRegs,
-                      struct ar6k_irq_enable_registers *pIrqEnableRegs)
-{
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n"));
-
-    if (pIrqProcRegs != NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Host Int Status:           0x%x\n",pIrqProcRegs->host_int_status));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("CPU Int Status:            0x%x\n",pIrqProcRegs->cpu_int_status));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Error Int Status:          0x%x\n",pIrqProcRegs->error_int_status));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Counter Int Status:        0x%x\n",pIrqProcRegs->counter_int_status));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Mbox Frame:                0x%x\n",pIrqProcRegs->mbox_frame));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Rx Lookahead Valid:        0x%x\n",pIrqProcRegs->rx_lookahead_valid));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Rx Lookahead 0:            0x%x\n",pIrqProcRegs->rx_lookahead[0]));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Rx Lookahead 1:            0x%x\n",pIrqProcRegs->rx_lookahead[1]));
-
-        if (pDev->MailBoxInfo.GMboxAddress != 0) {
-                /* if the target supports GMBOX hardware, dump some additional state */
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                ("GMBOX Host Int Status 2:   0x%x\n",pIrqProcRegs->host_int_status2));
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                ("GMBOX RX Avail:            0x%x\n",pIrqProcRegs->gmbox_rx_avail));
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                ("GMBOX lookahead alias 0:   0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[0]));
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                ("GMBOX lookahead alias 1:   0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[1]));
-        }
-
-    }
-
-    if (pIrqEnableRegs != NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Int Status Enable:         0x%x\n",pIrqEnableRegs->int_status_enable));
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable));
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n"));
-}
-
-
-#define DEV_GET_VIRT_DMA_INFO(p)  ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0]))
-
-static struct hif_scatter_req *DevAllocScatterReq(struct hif_device *Context)
-{
-    struct dl_list *pItem;
-    struct ar6k_device *pDev = (struct ar6k_device *)Context;
-    LOCK_AR6K(pDev);
-    pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead);
-    UNLOCK_AR6K(pDev);
-    if (pItem != NULL) {
-        return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink);
-    }
-    return NULL;
-}
-
-static void DevFreeScatterReq(struct hif_device *Context, struct hif_scatter_req *pReq)
-{
-    struct ar6k_device *pDev = (struct ar6k_device *)Context;
-    LOCK_AR6K(pDev);
-    DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink);
-    UNLOCK_AR6K(pDev);
-}
-
-int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA)
-{
-    u8 *pDMABuffer = NULL;
-    int             i, remaining;
-    u32 length;
-
-    pDMABuffer = pReq->pScatterBounceBuffer;
-
-    if (pDMABuffer == NULL) {
-        A_ASSERT(false);
-        return A_EINVAL;
-    }
-
-    remaining = (int)pReq->TotalLength;
-
-    for (i = 0; i < pReq->ValidScatterEntries; i++) {
-
-        length = min((int)pReq->ScatterList[i].Length, remaining);
-
-        if (length != (int)pReq->ScatterList[i].Length) {
-            A_ASSERT(false);
-                /* there is a problem with the scatter list */
-            return A_EINVAL;
-        }
-
-        if (FromDMA) {
-                /* from DMA buffer */
-            memcpy(pReq->ScatterList[i].pBuffer, pDMABuffer , length);
-        } else {
-                /* to DMA buffer */
-            memcpy(pDMABuffer, pReq->ScatterList[i].pBuffer, length);
-        }
-
-        pDMABuffer += length;
-        remaining -= length;
-    }
-
-    return 0;
-}
-
-static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6k_device     *pDev = (struct ar6k_device *)Context;
-    struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
-    
-    pReq->CompletionStatus = pPacket->Status;
-
-    AR6KFreeIOPacket(pDev,pPacket);
-
-    pReq->CompletionRoutine(pReq);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n"));
-}
-
-static int DevReadWriteScatter(struct hif_device *Context, struct hif_scatter_req *pReq)
-{
-    struct ar6k_device     *pDev = (struct ar6k_device *)Context;
-    int        status = 0;
-    struct htc_packet      *pIOPacket = NULL;
-    u32 request = pReq->Request;
-
-    do {
-
-        if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                            ("Invalid length: %d \n", pReq->TotalLength));
-            break;
-        }
-
-        if (pReq->TotalLength == 0) {
-            A_ASSERT(false);
-            break;
-        }
-
-        if (request & HIF_ASYNCHRONOUS) {
-                /* use an I/O packet to carry this request */
-            pIOPacket = AR6KAllocIOPacket(pDev);
-            if (NULL == pIOPacket) {
-                status = A_NO_MEMORY;
-                break;
-            }
-
-                /* save the request */
-            pIOPacket->pPktContext = pReq;
-                /* stick in our completion routine when the I/O operation completes */
-            pIOPacket->Completion = DevReadWriteScatterAsyncHandler;
-            pIOPacket->pContext = pDev;
-        }
-
-        if (request & HIF_WRITE) {
-            /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API
-             * this API will adjust the address automatically for the last byte to fall on the mailbox
-             * EOM. */
-
-            /* if the address is an extended address, we can adjust the address here since the extended
-             * address will bypass the normal checks in legacy HIF layers */
-            if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) {
-                pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength;
-            }
-        }
-
-            /* use legacy readwrite */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              pReq->Address,
-                              DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer,
-                              pReq->TotalLength,
-                              request,
-                              (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL);
-
-    } while (false);
-
-    if ((status != A_PENDING) && status && (request & HIF_ASYNCHRONOUS)) {
-        if (pIOPacket != NULL) {
-            AR6KFreeIOPacket(pDev,pIOPacket);
-        }
-        pReq->CompletionStatus = status;
-        pReq->CompletionRoutine(pReq);
-        status = 0;
-    }
-
-    return status;
-}
-
-
-static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev)
-{
-    struct hif_scatter_req *pReq;
-
-    while (1) {
-        pReq = DevAllocScatterReq((struct hif_device *)pDev);
-        if (NULL == pReq) {
-            break;
-        }
-        kfree(pReq);
-    }
-
-}
-
-    /* function to set up virtual scatter support if HIF layer has not implemented the interface */
-static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev)
-{
-    int                     status = 0;
-    int                          bufferSize, sgreqSize;
-    int                          i;
-    struct dev_scatter_dma_virtual_info *pVirtualInfo;
-    struct hif_scatter_req              *pReq;
-
-    bufferSize = sizeof(struct dev_scatter_dma_virtual_info) +
-                2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
-
-    sgreqSize = sizeof(struct hif_scatter_req) +
-                    (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item));
-
-    for (i = 0; i < AR6K_SCATTER_REQS; i++) {
-            /* allocate the scatter request, buffer info and the actual virtual buffer itself */
-        pReq = (struct hif_scatter_req *)A_MALLOC(sgreqSize + bufferSize);
-
-        if (NULL == pReq) {
-            status = A_NO_MEMORY;
-            break;
-        }
-
-        A_MEMZERO(pReq, sgreqSize);
-
-            /* the virtual DMA starts after the scatter request struct */
-        pVirtualInfo = (struct dev_scatter_dma_virtual_info *)((u8 *)pReq + sgreqSize);
-        A_MEMZERO(pVirtualInfo, sizeof(struct dev_scatter_dma_virtual_info));
-
-        pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0];
-            /* align buffer to cache line in case host controller can actually DMA this */
-        pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer);
-            /* store the structure in the private area */
-        pReq->HIFPrivate[0] = pVirtualInfo;
-            /* we emulate a DMA bounce interface */
-        pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE;
-        pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer;
-            /* free request to the list */
-        DevFreeScatterReq((struct hif_device *)pDev,pReq);
-    }
-
-    if (status) {
-        DevCleanupVirtualScatterSupport(pDev);
-    } else {
-        pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq;
-        pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq;
-        pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter;
-        if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n"));
-            pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ;
-            pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER;
-        } else {
-            pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ;
-            pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
-        }
-        pDev->ScatterIsVirtual = true;
-    }
-
-    return status;
-}
-
-int DevCleanupMsgBundling(struct ar6k_device *pDev)
-{
-    if(NULL != pDev)
-    {
-        DevCleanupVirtualScatterSupport(pDev);
-    }
-
-    return 0;
-}
-
-int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer)
-{
-    int status;
-
-    if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n"));
-        return A_ENOTSUP;
-    }
-
-    status = HIFConfigureDevice(pDev->HIFDevice,
-                                HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
-                                &pDev->HifScatterInfo,
-                                sizeof(pDev->HifScatterInfo));
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
-            ("AR6K: ** HIF layer does not support scatter requests (%d) \n",status));
-
-            /* we can try to use a virtual DMA scatter mechanism using legacy HIFReadWrite() */
-        status = DevSetupVirtualScatterSupport(pDev);
-
-        if (!status) {
-             AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                ("AR6K: virtual scatter transfers enabled (max scatter items:%d: maxlen:%d) \n",
-                    DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
-        }
-
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("AR6K: HIF layer supports scatter requests (max scatter items:%d: maxlen:%d) \n",
-                    DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
-    }
-
-    if (!status) {
-            /* for the recv path, the maximum number of bytes per recv bundle is just limited
-             * by the maximum transfer size at the HIF layer */
-        pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
-
-        if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K : SPI bus requires TX bundling disabled\n"));
-            pDev->MaxSendBundleSize = 0;
-        } else {
-                /* for the send path, the max transfer size is limited by the existence and size of
-                 * the extended mailbox address range */
-            if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) {
-                pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].ExtendedSize;
-            } else {
-                    /* legacy */
-                pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH;
-            }
-
-            if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePerScatterReq) {
-                    /* limit send bundle size to what the HIF can support for scatter requests */
-                pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
-            }
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-            ("AR6K: max recv: %d max send: %d \n",
-                    DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)));
-
-    }
-    return status;
-}
-
-int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async)
-{
-    int status;
-
-    if (Read) {
-            /* read operation */
-        pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BLOCK_FIX;
-        pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
-        A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev));
-    } else {
-        u32 mailboxWidth;
-
-            /* write operation */
-        pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BLOCK_INC;
-        A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev));
-        if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) {
-                /* for large writes use the extended address */
-            pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress;
-            mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize;
-        } else {
-            pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
-            mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH;
-        }
-
-        if (!pDev->ScatterIsVirtual) {
-            /* we are passing this scatter list down to the HIF layer' scatter request handler, fixup the address
-             * so that the last byte falls on the EOM, we do this for those HIFs that support the
-             * scatter API */
-            pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength);
-        }
-
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND,
-                ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x%X (mode: %s : %s)\n",
-                pScatterReq->ValidScatterEntries,
-                pScatterReq->TotalLength,
-                pScatterReq->Address,
-                Async ? "ASYNC" : "SYNC",
-                (Read) ? "RD" : "WR"));
-
-    status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq);
-
-    if (status) {
-        if (Async) {
-            pScatterReq->CompletionStatus = status;
-            pScatterReq->CompletionRoutine(pScatterReq);
-            return 0;
-        }
-        return status;
-    }
-
-    status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ? pDev : pDev->HIFDevice,
-                                                        pScatterReq);
-    if (!Async) {
-            /* in sync mode, we can touch the scatter request */
-        pScatterReq->CompletionStatus = status;
-        DEV_FINISH_SCATTER_OPERATION(pScatterReq);
-    } else {
-        if (status == A_PENDING) {
-            status = 0;
-        }
-    }
-
-    return status;
-}
-
-
-#ifdef MBOXHW_UNIT_TEST
-
-
-/* This is a mailbox hardware unit test that must be called in a schedulable context
- * This test is very simple, it will send a list of buffers with a counting pattern
- * and the target will invert the data and send the message back
- *
- * the unit test has the following constraints:
- *
- * The target has at least 8 buffers of 256 bytes each. The host will send
- * the following pattern of buffers in rapid succession :
- *
- * 1 buffer - 128 bytes
- * 1 buffer - 256 bytes
- * 1 buffer - 512 bytes
- * 1 buffer - 1024 bytes
- *
- * The host will send the buffers to one mailbox and wait for buffers to be reflected
- * back from the same mailbox. The target sends the buffers FIFO order.
- * Once the final buffer has been received for a mailbox, the next mailbox is tested.
- *
- *
- * Note:  To simplifythe test , we assume that the chosen buffer sizes
- *        will fall on a nice block pad
- *
- * It is expected that higher-order tests will be written to stress the mailboxes using
- * a message-based protocol (with some performance timming) that can create more
- * randomness in the packets sent over mailboxes.
- *
- * */
-
-#define A_ROUND_UP_PWR2(x, align)    (((int) (x) + ((align)-1)) & ~((align)-1))
-
-#define BUFFER_BLOCK_PAD 128
-
-#if 0
-#define BUFFER1 128
-#define BUFFER2 256
-#define BUFFER3 512
-#define BUFFER4 1024
-#endif
-
-#if 1
-#define BUFFER1 80
-#define BUFFER2 200
-#define BUFFER3 444
-#define BUFFER4 800
-#endif
-
-#define TOTAL_BYTES (A_ROUND_UP_PWR2(BUFFER1,BUFFER_BLOCK_PAD) + \
-                     A_ROUND_UP_PWR2(BUFFER2,BUFFER_BLOCK_PAD) + \
-                     A_ROUND_UP_PWR2(BUFFER3,BUFFER_BLOCK_PAD) + \
-                     A_ROUND_UP_PWR2(BUFFER4,BUFFER_BLOCK_PAD) )
-
-#define TEST_BYTES (BUFFER1 +  BUFFER2 + BUFFER3 + BUFFER4)
-
-#define TEST_CREDITS_RECV_TIMEOUT 100
-
-static u8 g_Buffer[TOTAL_BYTES];
-static u32 g_MailboxAddrs[AR6K_MAILBOXES];
-static u32 g_BlockSizes[AR6K_MAILBOXES];
-
-#define BUFFER_PROC_LIST_DEPTH 4
-
-struct buffer_proc_list {
-    u8 *pBuffer;
-    u32 length;
-};
-
-
-#define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \
-{                                                   \
-    (pList)->pBuffer = (pCurrpos);                  \
-    (pList)->length = (len);                        \
-    (pCurrpos) += (len);                            \
-    (pList)++;                                      \
-}
-
-/* a simple and crude way to send different "message" sizes */
-static void AssembleBufferList(struct buffer_proc_list *pList)
-{
-    u8 *pBuffer = g_Buffer;
-
-#if BUFFER_PROC_LIST_DEPTH < 4
-#error "Buffer processing list depth is not deep enough!!"
-#endif
-
-    PUSH_BUFF_PROC_ENTRY(pList,BUFFER1,pBuffer);
-    PUSH_BUFF_PROC_ENTRY(pList,BUFFER2,pBuffer);
-    PUSH_BUFF_PROC_ENTRY(pList,BUFFER3,pBuffer);
-    PUSH_BUFF_PROC_ENTRY(pList,BUFFER4,pBuffer);
-
-}
-
-#define FILL_ZERO     true
-#define FILL_COUNTING false
-static void InitBuffers(bool Zero)
-{
-    u16 *pBuffer16 = (u16 *)g_Buffer;
-    int      i;
-
-        /* fill buffer with 16 bit counting pattern or zeros */
-    for (i = 0; i <  (TOTAL_BYTES / 2) ; i++) {
-        if (!Zero) {
-            pBuffer16[i] = (u16)i;
-        } else {
-            pBuffer16[i] = 0;
-        }
-    }
-}
-
-
-static bool CheckOneBuffer(u16 *pBuffer16, int Length)
-{
-    int      i;
-    u16 startCount;
-    bool   success = true;
-
-        /* get the starting count */
-    startCount = pBuffer16[0];
-        /* invert it, this is the expected value */
-    startCount = ~startCount;
-        /* scan the buffer and verify */
-    for (i = 0; i < (Length / 2) ; i++,startCount++) {
-            /* target will invert all the data */
-        if ((u16)pBuffer16[i] != (u16)~startCount) {
-            success = false;
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n",
-                        pBuffer16[i], ((u16)~startCount), i, Length));
-             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n",
-                        pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3]));
-            break;
-        }
-    }
-
-    return success;
-}
-
-static bool CheckBuffers(void)
-{
-    int      i;
-    bool   success = true;
-    struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH];
-
-        /* assemble the list */
-    AssembleBufferList(checkList);
-
-        /* scan the buffers and verify */
-    for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) {
-        success = CheckOneBuffer((u16 *)checkList[i].pBuffer, checkList[i].length);
-        if (!success) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n",
-                        (u32)checkList[i].pBuffer, checkList[i].length));
-            break;
-        }
-    }
-
-    return success;
-}
-
-    /* find the end marker for the last buffer we will be sending */
-static u16 GetEndMarker(void)
-{
-    u8 *pBuffer;
-    struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH];
-
-        /* fill up buffers with the normal counting pattern */
-    InitBuffers(FILL_COUNTING);
-
-        /* assemble the list we will be sending down */
-    AssembleBufferList(checkList);
-        /* point to the last 2 bytes of the last buffer */
-    pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]);
-
-        /* the last count in the last buffer is the marker */
-    return (u16)pBuffer[0] | ((u16)pBuffer[1] << 8);
-}
-
-#define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR
-
-/* send the ordered buffers to the target */
-static int SendBuffers(struct ar6k_device *pDev, int mbox)
-{
-    int         status = 0;
-    u32 request = HIF_WR_SYNC_BLOCK_INC;
-    struct buffer_proc_list sendList[BUFFER_PROC_LIST_DEPTH];
-    int              i;
-    int              totalBytes = 0;
-    int              paddedLength;
-    int              totalwPadding = 0;
-
-    AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox));
-
-        /* fill buffer with counting pattern */
-    InitBuffers(FILL_COUNTING);
-
-        /* assemble the order in which we send */
-    AssembleBufferList(sendList);
-
-    for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) {
-
-            /* we are doing block transfers, so we need to pad everything to a block size */
-        paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) &
-                       (~(g_BlockSizes[mbox] - 1));
-
-            /* send each buffer synchronously */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              g_MailboxAddrs[mbox],
-                              sendList[i].pBuffer,
-                              paddedLength,
-                              request,
-                              NULL);
-        if (status) {
-            break;
-        }
-        totalBytes += sendList[i].length;
-        totalwPadding += paddedLength;
-    }
-
-    AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox));
-
-    return status;
-}
-
-/* poll the mailbox credit counter until we get a credit or timeout */
-static int GetCredits(struct ar6k_device *pDev, int mbox, int *pCredits)
-{
-    int status = 0;
-    int      timeout = TEST_CREDITS_RECV_TIMEOUT;
-    u8 credits = 0;
-    u32 address;
-
-    while (true) {
-
-            /* Read the counter register to get credits, this auto-decrements  */
-        address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4;
-        status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits),
-                              HIF_RD_SYNC_BYTE_FIX, NULL);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("Unable to decrement the command credit count register (mbox=%d)\n",mbox));
-            status = A_ERROR;
-            break;
-        }
-
-        if (credits) {
-            break;
-        }
-
-        timeout--;
-
-        if (timeout <= 0) {
-              AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address));
-            status = A_ERROR;
-            break;
-        }
-
-         /* delay a little, target may not be ready */
-         A_MDELAY(1000);
-
-    }
-
-    if (status == 0) {
-        *pCredits = credits;
-    }
-
-    return status;
-}
-
-
-/* wait for the buffers to come back */
-static int RecvBuffers(struct ar6k_device *pDev, int mbox)
-{
-    int         status = 0;
-    u32 request = HIF_RD_SYNC_BLOCK_INC;
-    struct buffer_proc_list recvList[BUFFER_PROC_LIST_DEPTH];
-    int              curBuffer;
-    int              credits;
-    int              i;
-    int              totalBytes = 0;
-    int              paddedLength;
-    int              totalwPadding = 0;
-
-    AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for buffers on mailbox : %d \n",mbox));
-
-        /* zero the buffers */
-    InitBuffers(FILL_ZERO);
-
-        /* assemble the order in which we should receive */
-    AssembleBufferList(recvList);
-
-    curBuffer = 0;
-
-    while (curBuffer < BUFFER_PROC_LIST_DEPTH) {
-
-            /* get number of buffers that have been completed, this blocks
-             * until we get at least 1 credit or it times out */
-        status = GetCredits(pDev, mbox, &credits);
-
-        if (status) {
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got %d messages on mailbox : %d \n",credits, mbox));
-
-            /* get all the buffers that are sitting on the queue */
-        for (i = 0; i < credits; i++) {
-            A_ASSERT(curBuffer < BUFFER_PROC_LIST_DEPTH);
-                /* recv the current buffer synchronously, the buffers should come back in
-                 * order... with padding applied by the target */
-            paddedLength = (recvList[curBuffer].length + (g_BlockSizes[mbox] - 1)) &
-                       (~(g_BlockSizes[mbox] - 1));
-
-            status = HIFReadWrite(pDev->HIFDevice,
-                                  g_MailboxAddrs[mbox],
-                                  recvList[curBuffer].pBuffer,
-                                  paddedLength,
-                                  request,
-                                  NULL);
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n",
-                        recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox]));
-                break;
-            }
-
-            totalwPadding += paddedLength;
-            totalBytes += recvList[curBuffer].length;
-            curBuffer++;
-        }
-
-        if (status) {
-            break;
-        }
-            /* go back and get some more */
-        credits = 0;
-    }
-
-    if (totalBytes != TEST_BYTES) {
-        A_ASSERT(false);
-    }  else {
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n",
-            mbox, totalBytes, totalwPadding));
-    }
-
-    return status;
-
-
-}
-
-static int DoOneMboxHWTest(struct ar6k_device *pDev, int mbox)
-{
-    int status;
-
-    do {
-            /* send out buffers */
-        status = SendBuffers(pDev,mbox);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox));
-            break;
-        }
-
-            /* go get them, this will block */
-        status =  RecvBuffers(pDev, mbox);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox));
-            break;
-        }
-
-            /* check the returned data patterns */
-        if (!CheckBuffers()) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer Verify Failed : mbox:%d\n",mbox));
-            status = A_ERROR;
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox));
-
-    }  while (false);
-
-    return status;
-}
-
-/* here is where the test starts */
-int DoMboxHWTest(struct ar6k_device *pDev)
-{
-    int      i;
-    int status;
-    int      credits = 0;
-    u8 params[4];
-    int      numBufs;
-    int      bufferSize;
-    u16 temp;
-
-
-    AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START -  \n"));
-
-    do {
-            /* get the addresses for all 4 mailboxes */
-        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
-                                    g_MailboxAddrs, sizeof(g_MailboxAddrs));
-
-        if (status) {
-            A_ASSERT(false);
-            break;
-        }
-
-            /* get the block sizes */
-        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
-                                    g_BlockSizes, sizeof(g_BlockSizes));
-
-        if (status) {
-            A_ASSERT(false);
-            break;
-        }
-
-            /* note, the HIF layer usually reports mbox 0 to have a block size of
-             * 1, but our test wants to run in block-mode for all mailboxes, so we treat all mailboxes
-             * the same. */
-        g_BlockSizes[0] = g_BlockSizes[1];
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Block Size to use: %d \n",g_BlockSizes[0]));
-
-        if (g_BlockSizes[1] > BUFFER_BLOCK_PAD) {
-            AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("%d Block size is too large for buffer pad %d\n",
-                g_BlockSizes[1], BUFFER_BLOCK_PAD));
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for target.... \n"));
-
-            /* the target lets us know it is ready by giving us 1 credit on
-             * mailbox 0 */
-        status = GetCredits(pDev, 0, &credits);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n"));
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target is ready ...\n"));
-
-            /* read the first 4 scratch registers */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              SCRATCH_ADDRESS,
-                              params,
-                              4,
-                              HIF_RD_SYNC_BYTE_INC,
-                              NULL);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n"));
-            break;
-        }
-
-        numBufs = params[0];
-        bufferSize = (int)(((u16)params[2] << 8) | (u16)params[1]);
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE,
-            ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n",
-            numBufs, bufferSize, (numBufs * bufferSize), TOTAL_BYTES));
-
-        if ((numBufs * bufferSize) < TOTAL_BYTES) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Not Enough buffer space to run test! need:%d, got:%d \n",
-                TOTAL_BYTES, (numBufs*bufferSize)));
-            status = A_ERROR;
-            break;
-        }
-
-        temp = GetEndMarker();
-
-        status = HIFReadWrite(pDev->HIFDevice,
-                              SCRATCH_ADDRESS + 4,
-                              (u8 *)&temp,
-                              2,
-                              HIF_WR_SYNC_BYTE_INC,
-                              NULL);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n"));
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp));
-
-        temp = (u16)g_BlockSizes[1];
-            /* convert to a mask */
-        temp = temp - 1;
-        status = HIFReadWrite(pDev->HIFDevice,
-                              SCRATCH_ADDRESS + 6,
-                              (u8 *)&temp,
-                              2,
-                              HIF_WR_SYNC_BYTE_INC,
-                              NULL);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n"));
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Set Block Mask: 0x%X \n",temp));
-
-            /* execute the test on each mailbox */
-        for (i = 0; i < AR6K_MAILBOXES; i++) {
-            status = DoOneMboxHWTest(pDev, i);
-            if (status) {
-                break;
-            }
-        }
-
-    } while (false);
-
-    if (status == 0) {
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! -  \n"));
-    } else {
-        AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! -  \n"));
-    }
-        /* don't let HTC_Start continue, the target is actually not running any HTC code */
-    return A_ERROR;
-}
-#endif
-
-
-
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
deleted file mode 100644 (file)
index e551dbe..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6k.h" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// AR6K device layer that handles register level I/O
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef AR6K_H_
-#define AR6K_H_
-
-#include "hci_transport_api.h"
-#include "../htc_debug.h"
-
-#define AR6K_MAILBOXES 4
-
-/* HTC runs over mailbox 0 */
-#define HTC_MAILBOX          0
-
-#define AR6K_TARGET_DEBUG_INTR_MASK     0x01
-
-#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK |   \
-                            INT_STATUS_ENABLE_CPU_MASK   |   \
-                            INT_STATUS_ENABLE_COUNTER_MASK)
-
-
-//#define MBOXHW_UNIT_TEST 1
-
-PREPACK struct ar6k_irq_proc_registers {
-    u8 host_int_status;
-    u8 cpu_int_status;
-    u8 error_int_status;
-    u8 counter_int_status;
-    u8 mbox_frame;
-    u8 rx_lookahead_valid;
-    u8 host_int_status2;
-    u8 gmbox_rx_avail;
-    u32 rx_lookahead[2];
-    u32 rx_gmbox_lookahead_alias[2];
-} POSTPACK;
-
-#define AR6K_IRQ_PROC_REGS_SIZE sizeof(struct ar6k_irq_proc_registers)
-
-PREPACK struct ar6k_irq_enable_registers {
-    u8 int_status_enable;
-    u8 cpu_int_status_enable;
-    u8 error_status_enable;
-    u8 counter_int_status_enable;
-} POSTPACK;
-
-PREPACK struct ar6k_gmbox_ctrl_registers {
-    u8 int_status_enable;
-} POSTPACK;
-
-#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers)
-
-#define AR6K_REG_IO_BUFFER_SIZE     32
-#define AR6K_MAX_REG_IO_BUFFERS     8
-#define FROM_DMA_BUFFER true
-#define TO_DMA_BUFFER   false
-#define AR6K_SCATTER_ENTRIES_PER_REQ            16
-#define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER      16*1024
-#define AR6K_SCATTER_REQS                       4
-#define AR6K_LEGACY_MAX_WRITE_LENGTH            2048
-
-#ifndef A_CACHE_LINE_PAD
-#define A_CACHE_LINE_PAD                        128
-#endif
-#define AR6K_MIN_SCATTER_ENTRIES_PER_REQ        2
-#define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER      4*1024
-
-/* buffers for ASYNC I/O */
-struct ar6k_async_reg_io_buffer {
-    struct htc_packet    HtcPacket;   /* we use an HTC packet as a wrapper for our async register-based I/O */
-    u8 _Pad1[A_CACHE_LINE_PAD];
-    u8 Buffer[AR6K_REG_IO_BUFFER_SIZE];  /* cache-line safe with pads around */
-    u8 _Pad2[A_CACHE_LINE_PAD];
-};
-
-struct ar6k_gmbox_info { 
-    void        *pProtocolContext;
-    int    (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes);
-    int    (*pCreditsPendingCallback)(void *pContext, int NumCredits,  bool CreditIRQEnabled);
-    void        (*pTargetFailureCallback)(void *pContext, int Status);
-    void        (*pStateDumpCallback)(void *pContext);
-    bool      CreditCountIRQEnabled;
-}; 
-
-struct ar6k_device {
-    A_MUTEX_T                   Lock;
-    u8 _Pad1[A_CACHE_LINE_PAD];
-    struct ar6k_irq_proc_registers     IrqProcRegisters;   /* cache-line safe with pads around */
-    u8 _Pad2[A_CACHE_LINE_PAD];
-    struct ar6k_irq_enable_registers   IrqEnableRegisters; /* cache-line safe with pads around */
-    u8 _Pad3[A_CACHE_LINE_PAD];
-    void                        *HIFDevice;
-    u32 BlockSize;
-    u32 BlockMask;
-    struct hif_device_mbox_info        MailBoxInfo;
-    HIF_PENDING_EVENTS_FUNC     GetPendingEventsFunc;
-    void                        *HTCContext;
-    struct htc_packet_queue            RegisterIOList;
-    struct ar6k_async_reg_io_buffer    RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
-    void                        (*TargetFailureCallback)(void *Context);
-    int                    (*MessagePendingCallback)(void *Context,
-                                                          u32 LookAheads[],
-                                                          int NumLookAheads, 
-                                                          bool *pAsyncProc,
-                                                          int *pNumPktsFetched);
-    HIF_DEVICE_IRQ_PROCESSING_MODE  HifIRQProcessingMode;
-    HIF_MASK_UNMASK_RECV_EVENT      HifMaskUmaskRecvEvent;
-    bool                          HifAttached;
-    struct hif_device_irq_yield_params     HifIRQYieldParams;
-    bool                          DSRCanYield;
-    int                             CurrentDSRRecvCount;
-    struct hif_device_scatter_support_info HifScatterInfo;
-    struct dl_list                         ScatterReqHead; 
-    bool                          ScatterIsVirtual;
-    int                             MaxRecvBundleSize;
-    int                             MaxSendBundleSize;
-    struct ar6k_gmbox_info                 GMboxInfo;
-    bool                          GMboxEnabled;
-    struct ar6k_gmbox_ctrl_registers       GMboxControlRegisters;
-    int                             RecheckIRQStatusCnt;
-};
-
-#define LOCK_AR6K(p)      A_MUTEX_LOCK(&(p)->Lock);
-#define UNLOCK_AR6K(p)    A_MUTEX_UNLOCK(&(p)->Lock);
-#define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1  /* note: no need to lock this, it only gets set */
-
-int DevSetup(struct ar6k_device *pDev);
-void     DevCleanup(struct ar6k_device *pDev);
-int DevUnmaskInterrupts(struct ar6k_device *pDev);
-int DevMaskInterrupts(struct ar6k_device *pDev);
-int DevPollMboxMsgRecv(struct ar6k_device *pDev,
-                            u32 *pLookAhead,
-                            int          TimeoutMS);
-int DevRWCompletionHandler(void *context, int status);
-int DevDsrHandler(void *context);
-int DevCheckPendingRecvMsgsAsync(void *context);
-void     DevAsyncIrqProcessComplete(struct ar6k_device *pDev);
-void     DevDumpRegisters(struct ar6k_device               *pDev,
-                          struct ar6k_irq_proc_registers   *pIrqProcRegs,
-                          struct ar6k_irq_enable_registers *pIrqEnableRegs);
-
-#define DEV_STOP_RECV_ASYNC true
-#define DEV_STOP_RECV_SYNC  false
-#define DEV_ENABLE_RECV_ASYNC true
-#define DEV_ENABLE_RECV_SYNC  false
-int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode);
-int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode);
-int DevEnableInterrupts(struct ar6k_device *pDev);
-int DevDisableInterrupts(struct ar6k_device *pDev);
-int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending);
-
-#define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask)))
-#define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length)
-#define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0)
-
-static INLINE int DevSendPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 SendLength) {
-    u32 paddedLength;
-    bool   sync = (pPacket->Completion == NULL) ? true : false;
-    int status;
-
-       /* adjust the length to be a multiple of block size if appropriate */
-    paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength);
-
-#if 0                    
-    if (paddedLength > pPacket->BufferLength) {
-        A_ASSERT(false);
-        if (pPacket->Completion != NULL) {
-            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
-            return 0;
-        }
-        return A_EINVAL;
-    }
-#endif
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
-                ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
-                paddedLength,
-                pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
-                sync ? "SYNC" : "ASYNC"));
-
-    status = HIFReadWrite(pDev->HIFDevice,
-                          pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
-                          pPacket->pBuffer,
-                          paddedLength,     /* the padded length */
-                          sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
-                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
-
-    if (sync) {
-        pPacket->Status = status;
-    } else {
-        if (status == A_PENDING) {
-            status = 0;
-        }    
-    }
-
-    return status;
-}
-                    
-static INLINE int DevRecvPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 RecvLength) {
-    u32 paddedLength;
-    int status;
-    bool   sync = (pPacket->Completion == NULL) ? true : false;
-
-        /* adjust the length to be a multiple of block size if appropriate */
-    paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);
-                    
-    if (paddedLength > pPacket->BufferLength) {
-        A_ASSERT(false);
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
-                    paddedLength,RecvLength,pPacket->BufferLength));
-        if (pPacket->Completion != NULL) {
-            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
-            return 0;
-        }
-        return A_EINVAL;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
-                (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
-                paddedLength,
-                pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
-                sync ? "SYNC" : "ASYNC"));
-
-    status = HIFReadWrite(pDev->HIFDevice,
-                          pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
-                          pPacket->pBuffer,
-                          paddedLength,
-                          sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
-                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
-
-    if (sync) {
-        pPacket->Status = status;
-    }
-
-    return status;
-}
-
-#define DEV_CHECK_RECV_YIELD(pDev) \
-            ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount)
-            
-#define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode)
-#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)
-
-/**************************************************/
-/****** Scatter Function and Definitions
- * 
- *  
- */
-  
-int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA);
-    
-    /* copy any READ data back into scatter list */        
-#define DEV_FINISH_SCATTER_OPERATION(pR)                               \
-do {                                                                   \
-       if (!((pR)->CompletionStatus) &&                                \
-           !((pR)->Request & HIF_WRITE) &&                             \
-           ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {          \
-               (pR)->CompletionStatus =                                \
-                       DevCopyScatterListToFromDMABuffer((pR),         \
-                                                         FROM_DMA_BUFFER); \
-       }                                                               \
-} while (0)
-    
-    /* copy any WRITE data to bounce buffer */
-static INLINE int DEV_PREPARE_SCATTER_OPERATION(struct hif_scatter_req *pReq)  {
-    if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
-        return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);    
-    } else {
-        return 0;
-    }
-}
-        
-    
-int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer);
-
-int DevCleanupMsgBundling(struct ar6k_device *pDev);
-                                  
-#define DEV_GET_MAX_MSG_PER_BUNDLE(pDev)        (pDev)->HifScatterInfo.MaxScatterEntries
-#define DEV_GET_MAX_BUNDLE_LENGTH(pDev)         (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq
-#define DEV_ALLOC_SCATTER_REQ(pDev)             \
-    (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice)
-    
-#define DEV_FREE_SCATTER_REQ(pDev,pR)           \
-    (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR))
-
-#define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev)   (pDev)->MaxRecvBundleSize
-#define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)   (pDev)->MaxSendBundleSize
-
-#define DEV_SCATTER_READ  true
-#define DEV_SCATTER_WRITE false
-#define DEV_SCATTER_ASYNC true
-#define DEV_SCATTER_SYNC  false
-int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async);
-
-#ifdef MBOXHW_UNIT_TEST
-int DoMboxHWTest(struct ar6k_device *pDev);
-#endif
-
-    /* completely virtual */
-struct dev_scatter_dma_virtual_info {
-    u8 *pVirtDmaBuffer;      /* dma-able buffer - CPU accessible address */
-    u8 DataArea[1];      /* start of data area */
-};
-
-
-
-void     DumpAR6KDevState(struct ar6k_device *pDev);
-
-/**************************************************/
-/****** GMBOX functions and definitions
- * 
- *  
- */
-
-#ifdef ATH_AR6K_ENABLE_GMBOX
-
-void     DevCleanupGMbox(struct ar6k_device *pDev);
-int DevSetupGMbox(struct ar6k_device *pDev);
-int DevCheckGMboxInterrupts(struct ar6k_device *pDev);
-void     DevNotifyGMboxTargetFailure(struct ar6k_device *pDev);
-
-#else
-
-    /* compiled out */
-#define DevCleanupGMbox(p)
-#define DevCheckGMboxInterrupts(p) 0
-#define DevNotifyGMboxTargetFailure(p)
-
-static INLINE int DevSetupGMbox(struct ar6k_device *pDev) {
-    pDev->GMboxEnabled = false;
-    return 0;
-}
-
-#endif
-
-#ifdef ATH_AR6K_ENABLE_GMBOX
-
-    /* GMBOX protocol modules must expose each of these internal APIs */
-HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo);
-int             GMboxProtocolInstall(struct ar6k_device *pDev);
-void                 GMboxProtocolUninstall(struct ar6k_device *pDev);
-
-    /* API used by GMBOX protocol modules */
-struct ar6k_device  *HTCGetAR6KDevice(void *HTCHandle);
-#define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \
-{                                                                  \
-    (pDev)->GMboxInfo.pProtocolContext = (context);                \
-    (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback);   \
-    (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \
-    (pDev)->GMboxInfo.pTargetFailureCallback = (failure);          \
-    (pDev)->GMboxInfo.pStateDumpCallback = (statedump);            \
-}
-
-#define DEV_GMBOX_GET_PROTOCOL(pDev)  (pDev)->GMboxInfo.pProtocolContext
-
-int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength);
-int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength);
-
-#define PROC_IO_ASYNC true
-#define PROC_IO_SYNC  false
-typedef enum GMBOX_IRQ_ACTION_TYPE {
-    GMBOX_ACTION_NONE = 0,
-    GMBOX_DISABLE_ALL,
-    GMBOX_ERRORS_IRQ_ENABLE,
-    GMBOX_RECV_IRQ_ENABLE,
-    GMBOX_RECV_IRQ_DISABLE,
-    GMBOX_CREDIT_IRQ_ENABLE,
-    GMBOX_CREDIT_IRQ_DISABLE,
-} GMBOX_IRQ_ACTION_TYPE;
-
-int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode);
-int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits);
-int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize);
-int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes);
-int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int SignalNumber, int AckTimeoutMS);
-
-#endif
-
-#endif /*AR6K_H_*/
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
deleted file mode 100644 (file)
index d7af68f..0000000
+++ /dev/null
@@ -1,783 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6k_events.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// AR6K Driver layer event handling (i.e. interrupts, message polling)
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "hw/mbox_host_reg.h"
-#include "a_osapi.h"
-#include "../htc_debug.h"
-#include "hif.h"
-#include "htc_packet.h"
-#include "ar6k.h"
-
-extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket);
-extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev);
-
-static int DevServiceDebugInterrupt(struct ar6k_device *pDev);
-
-#define DELAY_PER_INTERVAL_MS 10  /* 10 MS delay per polling interval */
-
-/* completion routine for ALL HIF layer async I/O */
-int DevRWCompletionHandler(void *context, int status)
-{
-    struct htc_packet *pPacket = (struct htc_packet *)context;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n",
-                (unsigned long)pPacket,
-                status));
-
-    COMPLETE_HTC_PACKET(pPacket,status);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("-DevRWCompletionHandler\n"));
-
-    return 0;
-}
-
-/* mailbox recv message polling */
-int DevPollMboxMsgRecv(struct ar6k_device *pDev,
-                            u32 *pLookAhead,
-                            int          TimeoutMS)
-{
-    int status = 0;
-    int      timeout = TimeoutMS/DELAY_PER_INTERVAL_MS;
-
-    A_ASSERT(timeout > 0);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n"));
-
-    while (true) {
-
-        if (pDev->GetPendingEventsFunc != NULL) {
-
-            struct hif_pending_events_info events;
-
-#ifdef THREAD_X
-                       events.Polling =1;
-#endif
-
-            /* the HIF layer uses a special mechanism to get events, do this
-             * synchronously */
-            status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
-                                            &events,
-                                            NULL);
-            if (status)
-            {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n"));
-                break;
-            }
-
-            if (events.Events & HIF_RECV_MSG_AVAIL)
-            {
-                    /*  there is a message available, the lookahead should be valid now */
-                *pLookAhead = events.LookAhead;
-
-                break;
-            }
-        } else {
-
-                /* this is the standard HIF way.... */
-                /* load the register table */
-            status = HIFReadWrite(pDev->HIFDevice,
-                                  HOST_INT_STATUS_ADDRESS,
-                                  (u8 *)&pDev->IrqProcRegisters,
-                                  AR6K_IRQ_PROC_REGS_SIZE,
-                                  HIF_RD_SYNC_BYTE_INC,
-                                  NULL);
-
-            if (status){
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n"));
-                break;
-            }
-
-                /* check for MBOX data and valid lookahead */
-            if (pDev->IrqProcRegisters.host_int_status & (1 << HTC_MAILBOX)) {
-                if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX))
-                {
-                    /* mailbox has a message and the look ahead is valid */
-                    *pLookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
-                    break;
-                }
-            }
-
-        }
-
-        timeout--;
-
-        if (timeout <= 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Timeout waiting for recv message \n"));
-            status = A_ERROR;
-
-                /* check if the target asserted */
-            if ( pDev->IrqProcRegisters.counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
-                    /* target signaled an assert, process this pending interrupt
-                     * this will call the target failure handler */
-                DevServiceDebugInterrupt(pDev);
-            }
-
-            break;
-        }
-
-            /* delay a little  */
-        A_MDELAY(DELAY_PER_INTERVAL_MS);
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("  Retry Mbox Poll : %d \n",timeout));
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevPollMboxMsgRecv \n"));
-
-    return status;
-}
-
-static int DevServiceCPUInterrupt(struct ar6k_device *pDev)
-{
-    int status;
-    u8 cpu_int_status;
-    u8 regBuffer[4];
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n"));
-    cpu_int_status = pDev->IrqProcRegisters.cpu_int_status &
-                     pDev->IrqEnableRegisters.cpu_int_status_enable;
-    A_ASSERT(cpu_int_status);
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                    ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
-                    cpu_int_status));
-
-        /* Clear the interrupt */
-    pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */
-
-        /* set up the register transfer buffer to hit the register 4 times , this is done
-         * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
-         * restrict bus transfer lengths to be a multiple of 4-bytes */
-
-        /* set W1C value to clear the interrupt, this hits the register first */
-    regBuffer[0] = cpu_int_status;
-        /* the remaining 4 values are set to zero which have no-effect  */
-    regBuffer[1] = 0;
-    regBuffer[2] = 0;
-    regBuffer[3] = 0;
-
-    status = HIFReadWrite(pDev->HIFDevice,
-                          CPU_INT_STATUS_ADDRESS,
-                          regBuffer,
-                          4,
-                          HIF_WR_SYNC_BYTE_FIX,
-                          NULL);
-
-    A_ASSERT(status == 0);
-    return status;
-}
-
-
-static int DevServiceErrorInterrupt(struct ar6k_device *pDev)
-{
-    int status;
-    u8 error_int_status;
-    u8 regBuffer[4];
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n"));
-    error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F;
-    A_ASSERT(error_int_status);
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                    ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
-                    error_int_status));
-
-    if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
-        /* Wakeup */
-        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n"));
-    }
-
-    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
-        /* Rx Underflow */
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n"));
-    }
-
-    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
-        /* Tx Overflow */
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n"));
-    }
-
-        /* Clear the interrupt */
-    pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */
-
-        /* set up the register transfer buffer to hit the register 4 times , this is done
-         * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
-         * restrict bus transfer lengths to be a multiple of 4-bytes */
-
-        /* set W1C value to clear the interrupt, this hits the register first */
-    regBuffer[0] = error_int_status;
-        /* the remaining 4 values are set to zero which have no-effect  */
-    regBuffer[1] = 0;
-    regBuffer[2] = 0;
-    regBuffer[3] = 0;
-
-    status = HIFReadWrite(pDev->HIFDevice,
-                          ERROR_INT_STATUS_ADDRESS,
-                          regBuffer,
-                          4,
-                          HIF_WR_SYNC_BYTE_FIX,
-                          NULL);
-
-    A_ASSERT(status == 0);
-    return status;
-}
-
-static int DevServiceDebugInterrupt(struct ar6k_device *pDev)
-{
-    u32 dummy;
-    int status;
-
-    /* Send a target failure event to the application */
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n"));
-
-    if (pDev->TargetFailureCallback != NULL) {
-        pDev->TargetFailureCallback(pDev->HTCContext);
-    }
-
-    if (pDev->GMboxEnabled) {
-        DevNotifyGMboxTargetFailure(pDev);
-    }
-
-    /* clear the interrupt , the debug error interrupt is
-     * counter 0 */
-        /* read counter to clear interrupt */
-    status = HIFReadWrite(pDev->HIFDevice,
-                          COUNT_DEC_ADDRESS,
-                          (u8 *)&dummy,
-                          4,
-                          HIF_RD_SYNC_BYTE_INC,
-                          NULL);
-
-    A_ASSERT(status == 0);
-    return status;
-}
-
-static int DevServiceCounterInterrupt(struct ar6k_device *pDev)
-{
-    u8 counter_int_status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n"));
-
-    counter_int_status = pDev->IrqProcRegisters.counter_int_status &
-                         pDev->IrqEnableRegisters.counter_int_status_enable;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                    ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
-                    counter_int_status));
-
-        /* Check if the debug interrupt is pending
-         * NOTE: other modules like GMBOX may use the counter interrupt for
-         * credit flow control on other counters, we only need to check for the debug assertion
-         * counter interrupt */
-    if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
-        return DevServiceDebugInterrupt(pDev);
-    }
-
-    return 0;
-}
-
-/* callback when our fetch to get interrupt status registers completes */
-static void DevGetEventAsyncHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6k_device *pDev = (struct ar6k_device *)Context;
-    u32 lookAhead = 0;
-    bool      otherInts = false;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-    do {
-
-        if (pPacket->Status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    (" GetEvents I/O request failed, status:%d \n", pPacket->Status));
-            /* bail out, don't unmask HIF interrupt */
-            break;
-        }
-
-        if (pDev->GetPendingEventsFunc != NULL) {
-                /* the HIF layer collected the information for us */
-            struct hif_pending_events_info *pEvents = (struct hif_pending_events_info *)pPacket->pBuffer;
-            if (pEvents->Events & HIF_RECV_MSG_AVAIL) {
-                lookAhead = pEvents->LookAhead;
-                if (0 == lookAhead) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n"));
-                }
-            }
-            if (pEvents->Events & HIF_OTHER_EVENTS) {
-                otherInts = true;
-            }
-        } else {
-                /* standard interrupt table handling.... */
-            struct ar6k_irq_proc_registers *pReg = (struct ar6k_irq_proc_registers *)pPacket->pBuffer;
-            u8 host_int_status;
-
-            host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable;
-
-            if (host_int_status & (1 << HTC_MAILBOX)) {
-                host_int_status &= ~(1 << HTC_MAILBOX);
-                if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) {
-                        /* mailbox has a message and the look ahead is valid */
-                    lookAhead = pReg->rx_lookahead[HTC_MAILBOX];
-                    if (0 == lookAhead) {
-                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n"));
-                    }
-                }
-            }
-
-            if (host_int_status) {
-                    /* there are other interrupts to handle */
-                otherInts = true;
-            }
-        }
-
-        if (otherInts || (lookAhead == 0)) {
-            /* if there are other interrupts to process, we cannot do this in the async handler so
-             * ack the interrupt which will cause our sync handler to run again
-             * if however there are no more messages, we can now ack the interrupt  */
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n",
-                otherInts, lookAhead));
-            HIFAckInterrupt(pDev->HIFDevice);
-        } else {
-            int      fetched = 0;
-            int status;
-
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                    (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n",
-                    lookAhead));
-                /* lookahead is non-zero and there are no other interrupts to service,
-                 * go get the next message */
-            status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched);
-
-            if (!status && !fetched) {
-                    /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
-                AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n"));
-                DevAsyncIrqProcessComplete(pDev);
-            }
-        }
-
-    } while (false);
-
-        /* free this IO packet */
-    AR6KFreeIOPacket(pDev,pPacket);
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n"));
-}
-
-/* called by the HTC layer when it wants us to check if the device has any more pending
- * recv messages, this starts off a series of async requests to read interrupt registers  */
-int DevCheckPendingRecvMsgsAsync(void *context)
-{
-    struct ar6k_device  *pDev = (struct ar6k_device *)context;
-    int      status = 0;
-    struct htc_packet   *pIOPacket;
-
-    /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can
-     * cause us to switch contexts */
-
-   AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-   do {
-
-        if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
-                /* break the async processing chain right here, no need to continue.
-                 * The DevDsrHandler() will handle things in a loop when things are driven
-                 * synchronously  */
-            break;
-        }
-
-            /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
-             * the target, if upper layers determine that we are in a low-throughput mode, we can
-             * rely on taking another interrupt rather than re-checking the status registers which can
-             * re-wake the target */
-        if (pDev->RecheckIRQStatusCnt == 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n"));
-                /* ack interrupt */
-            HIFAckInterrupt(pDev->HIFDevice);
-            break;
-        }
-
-            /* first allocate one of our HTC packets we created for async I/O
-             * we reuse HTC packet definitions so that we can use the completion mechanism
-             * in DevRWCompletionHandler() */
-        pIOPacket = AR6KAllocIOPacket(pDev);
-
-        if (NULL == pIOPacket) {
-                /* there should be only 1 asynchronous request out at a time to read these registers
-                 * so this should actually never happen */
-            status = A_NO_MEMORY;
-            A_ASSERT(false);
-            break;
-        }
-
-            /* stick in our completion routine when the I/O operation completes */
-        pIOPacket->Completion = DevGetEventAsyncHandler;
-        pIOPacket->pContext = pDev;
-
-        if (pDev->GetPendingEventsFunc) {
-                /* HIF layer has it's own mechanism, pass the IO to it.. */
-            status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
-                                                (struct hif_pending_events_info *)pIOPacket->pBuffer,
-                                                pIOPacket);
-
-        } else {
-                /* standard way, read the interrupt register table asynchronously again */
-            status = HIFReadWrite(pDev->HIFDevice,
-                                  HOST_INT_STATUS_ADDRESS,
-                                  pIOPacket->pBuffer,
-                                  AR6K_IRQ_PROC_REGS_SIZE,
-                                  HIF_RD_ASYNC_BYTE_INC,
-                                  pIOPacket);
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
-   } while (false);
-
-   AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));
-
-   return status;
-}
-
-void DevAsyncIrqProcessComplete(struct ar6k_device *pDev)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n"));
-    HIFAckInterrupt(pDev->HIFDevice);
-}
-
-/* process pending interrupts synchronously */
-static int ProcessPendingIRQs(struct ar6k_device *pDev, bool *pDone, bool *pASyncProcessing)
-{
-    int    status = 0;
-    u8 host_int_status = 0;
-    u32 lookAhead = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-    /*** NOTE: the HIF implementation guarantees that the context of this call allows
-     *         us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that
-     *         can block or switch thread/task ontexts.
-     *         This is a fully schedulable context.
-     * */
-    do {
-
-            if (pDev->IrqEnableRegisters.int_status_enable == 0) {
-                /* interrupt enables have been cleared, do not try to process any pending interrupts that
-                 * may result in more bus transactions.  The target may be unresponsive at this
-                 * point. */
-                 break;
-            }
-
-            if (pDev->GetPendingEventsFunc != NULL) {
-                struct hif_pending_events_info events;
-
-#ifdef THREAD_X
-            events.Polling= 0;
-#endif
-                /* the HIF layer uses a special mechanism to get events
-                 * get this synchronously  */
-            status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
-                                                &events,
-                                                NULL);
-
-            if (status) {
-                break;
-            }
-
-            if (events.Events & HIF_RECV_MSG_AVAIL) {
-                lookAhead = events.LookAhead;
-                if (0 == lookAhead) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs1 lookAhead is zero! \n"));
-                }
-            }
-
-            if (!(events.Events & HIF_OTHER_EVENTS) ||
-                !(pDev->IrqEnableRegisters.int_status_enable & OTHER_INTS_ENABLED)) {
-                    /* no need to read the register table, no other interesting interrupts.
-                     * Some interfaces (like SPI) can shadow interrupt sources without
-                     * requiring the host to do a full table read */
-                break;
-            }
-
-            /* otherwise fall through and read the register table */
-        }
-
-        /*
-         * Read the first 28 bytes of the HTC register table. This will yield us
-         * the value of different int status registers and the lookahead
-         * registers.
-         *    length = sizeof(int_status) + sizeof(cpu_int_status) +
-         *             sizeof(error_int_status) + sizeof(counter_int_status) +
-         *             sizeof(mbox_frame) + sizeof(rx_lookahead_valid) +
-         *             sizeof(hole) +  sizeof(rx_lookahead) +
-         *             sizeof(int_status_enable) + sizeof(cpu_int_status_enable) +
-         *             sizeof(error_status_enable) +
-         *             sizeof(counter_int_status_enable);
-         *
-        */
-#ifdef CONFIG_MMC_SDHCI_S3C
-            pDev->IrqProcRegisters.host_int_status = 0;
-            pDev->IrqProcRegisters.rx_lookahead_valid = 0;
-            pDev->IrqProcRegisters.host_int_status2 = 0;
-            pDev->IrqProcRegisters.rx_lookahead[0] = 0;
-            pDev->IrqProcRegisters.rx_lookahead[1] = 0xaaa5555;
-#endif /* CONFIG_MMC_SDHCI_S3C */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              HOST_INT_STATUS_ADDRESS,
-                              (u8 *)&pDev->IrqProcRegisters,
-                              AR6K_IRQ_PROC_REGS_SIZE,
-                              HIF_RD_SYNC_BYTE_INC,
-                              NULL);
-
-        if (status) {
-            break;
-        }
-
-#ifdef ATH_DEBUG_MODULE
-        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
-            DevDumpRegisters(pDev,
-                             &pDev->IrqProcRegisters,
-                             &pDev->IrqEnableRegisters);
-        }
-#endif
-
-            /* Update only those registers that are enabled */
-        host_int_status = pDev->IrqProcRegisters.host_int_status &
-                          pDev->IrqEnableRegisters.int_status_enable;
-
-        if (NULL == pDev->GetPendingEventsFunc) {
-                /* only look at mailbox status if the HIF layer did not provide this function,
-                 * on some HIF interfaces reading the RX lookahead is not valid to do */
-            if (host_int_status & (1 << HTC_MAILBOX)) {
-                    /* mask out pending mailbox value, we use "lookAhead" as the real flag for
-                     * mailbox processing below */
-                host_int_status &= ~(1 << HTC_MAILBOX);
-                if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) {
-                        /* mailbox has a message and the look ahead is valid */
-                    lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
-                    if (0 == lookAhead) {
-                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lookAhead is zero! \n"));
-                    }
-                }
-            }
-        } else {
-                /* not valid to check if the HIF has another mechanism for reading mailbox pending status*/
-            host_int_status &= ~(1 << HTC_MAILBOX);
-        }
-
-        if (pDev->GMboxEnabled) {
-                /*call GMBOX layer to process any interrupts of interest */
-            status = DevCheckGMboxInterrupts(pDev);
-        }
-
-    } while (false);
-
-
-    do {
-
-            /* did the interrupt status fetches succeed? */
-        if (status) {
-            break;
-        }
-
-        if ((0 == host_int_status) && (0 == lookAhead)) {
-                /* nothing to process, the caller can use this to break out of a loop */
-            *pDone = true;
-            break;
-        }
-
-        if (lookAhead != 0) {
-            int fetched = 0;
-
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead));
-                /* Mailbox Interrupt, the HTC layer may issue async requests to empty the
-                 * mailbox...
-                 * When emptying the recv mailbox we use the async handler above called from the
-                 * completion routine of the callers read request. This can improve performance
-                 * by reducing context switching when we rapidly pull packets */
-            status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, pASyncProcessing, &fetched);
-            if (status) {
-                break;
-            }
-
-            if (!fetched) {
-                    /* HTC could not pull any messages out due to lack of resources */
-                    /* force DSR handler to ack the interrupt */
-                *pASyncProcessing = false;
-                pDev->RecheckIRQStatusCnt = 0;
-            }
-        }
-
-            /* now handle the rest of them */
-        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                            (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n",
-                            host_int_status));
-
-        if (HOST_INT_STATUS_CPU_GET(host_int_status)) {
-                /* CPU Interrupt */
-            status = DevServiceCPUInterrupt(pDev);
-            if (status){
-                break;
-            }
-        }
-
-        if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
-                /* Error Interrupt */
-            status = DevServiceErrorInterrupt(pDev);
-            if (status){
-                break;
-            }
-        }
-
-        if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
-                /* Counter Interrupt */
-            status = DevServiceCounterInterrupt(pDev);
-            if (status){
-                break;
-            }
-        }
-
-    } while (false);
-
-        /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
-         * the target, if upper layers determine that we are in a low-throughput mode, we can
-         * rely on taking another interrupt rather than re-checking the status registers which can
-         * re-wake the target.
-         *
-         * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot
-         * be used due to possible side-effects.  For example, SPI requires the host to drain all
-         * messages from the mailbox before exiting the ISR routine. */
-    if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPendingEventsFunc == NULL)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n"));
-        *pDone = true;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n",
-                *pDone, *pASyncProcessing, status));
-
-    return status;
-}
-
-
-/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/
-int DevDsrHandler(void *context)
-{
-    struct ar6k_device *pDev = (struct ar6k_device *)context;
-    int    status = 0;
-    bool      done = false;
-    bool      asyncProc = false;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-        /* reset the recv counter that tracks when we need to yield from the DSR */
-    pDev->CurrentDSRRecvCount = 0;
-        /* reset counter used to flag a re-scan of IRQ status registers on the target */
-    pDev->RecheckIRQStatusCnt = 0;
-
-    while (!done) {
-        status = ProcessPendingIRQs(pDev, &done, &asyncProc);
-        if (status) {
-            break;
-        }
-
-        if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
-            /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */
-            asyncProc = false;
-            /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers.
-             * this has a nice side effect of blocking us until all async read requests are completed.
-             * This behavior is required on some HIF implementations that do not allow ASYNC
-             * processing in interrupt handlers (like Windows CE) */
-
-            if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) {
-                /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop
-                 * checking for more messages and return */
-                break;
-            }
-        }
-
-        if (asyncProc) {
-                /* the function performed some async I/O for performance, we
-                   need to exit the ISR immediately, the check below will prevent the interrupt from being
-                   Ack'd while we handle it asynchronously */
-            break;
-        }
-
-    }
-
-    if (!status && !asyncProc) {
-            /* Ack the interrupt only if :
-             *  1. we did not get any errors in processing interrupts
-             *  2. there are no outstanding async processing requests */
-        if (pDev->DSRCanYield) {
-                /* if the DSR can yield do not ACK the interrupt, there could be more pending messages.
-                 * The HIF layer must ACK the interrupt on behalf of HTC */
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount));
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n"));
-            HIFAckInterrupt(pDev->HIFDevice);
-        }
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n"));
-    return status;
-}
-
-#ifdef ATH_DEBUG_MODULE
-void DumpAR6KDevState(struct ar6k_device *pDev)
-{
-    int                    status;
-    struct ar6k_irq_enable_registers   regs;
-    struct ar6k_irq_proc_registers     procRegs;
-
-    LOCK_AR6K(pDev);
-        /* copy into our temp area */
-    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
-    UNLOCK_AR6K(pDev);
-
-        /* load the register table from the device */
-    status = HIFReadWrite(pDev->HIFDevice,
-                          HOST_INT_STATUS_ADDRESS,
-                          (u8 *)&procRegs,
-                          AR6K_IRQ_PROC_REGS_SIZE,
-                          HIF_RD_SYNC_BYTE_INC,
-                          NULL);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-            ("DumpAR6KDevState : Failed to read register table (%d) \n",status));
-        return;
-    }
-
-    DevDumpRegisters(pDev,&procRegs,&regs);
-
-    if (pDev->GMboxInfo.pStateDumpCallback != NULL) {
-        pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
-    }
-
-        /* dump any bus state at the HIF layer */
-    HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0);
-
-}
-#endif
-
-
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
deleted file mode 100644 (file)
index 725540f..0000000
+++ /dev/null
@@ -1,755 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6k_gmbox.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Generic MBOX API implementation
-// 
-// Author(s): ="Atheros"
-//==============================================================================
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#include "../htc_debug.h"
-#include "hif.h"
-#include "htc_packet.h"
-#include "ar6k.h"
-#include "hw/mbox_host_reg.h"
-#include "gmboxif.h"
-
-/* 
- * This file provides management functions and a toolbox for GMBOX protocol modules.  
- * Only one protocol module can be installed at a time. The determination of which protocol
- * module is installed is determined at compile time.  
- * 
- */
-#ifdef ATH_AR6K_ENABLE_GMBOX
-     /* GMBOX definitions */
-#define GMBOX_INT_STATUS_ENABLE_REG     0x488
-#define GMBOX_INT_STATUS_RX_DATA        (1 << 0)
-#define GMBOX_INT_STATUS_TX_OVERFLOW    (1 << 1)
-#define GMBOX_INT_STATUS_RX_OVERFLOW    (1 << 2)
-
-#define GMBOX_LOOKAHEAD_MUX_REG         0x498
-#define GMBOX_LA_MUX_OVERRIDE_2_3       (1 << 0)
-
-#define AR6K_GMBOX_CREDIT_DEC_ADDRESS   (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER)
-#define AR6K_GMBOX_CREDIT_SIZE_ADDRESS  (COUNT_ADDRESS     + AR6K_GMBOX_CREDIT_SIZE_COUNTER)
-
-
-    /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */ 
-extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket);
-extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev);
-
-
-/* callback when our fetch to enable/disable completes */
-static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6k_device *pDev = (struct ar6k_device *)Context;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-    if (pPacket->Status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status));
-    }
-        /* free this IO packet */
-    AR6KFreeIOPacket(pDev,pPacket);
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
-}
-
-static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
-{
-    int                  status = 0;
-    struct ar6k_irq_enable_registers regs;
-    struct htc_packet                *pIOPacket = NULL;  
-    
-    LOCK_AR6K(pDev);
-    
-    if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
-        pDev->GMboxInfo.CreditCountIRQEnabled = true;
-        pDev->IrqEnableRegisters.counter_int_status_enable |=
-            COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
-        pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01);
-    } else {
-        pDev->GMboxInfo.CreditCountIRQEnabled = false;
-        pDev->IrqEnableRegisters.counter_int_status_enable &=
-            ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER));    
-    }
-        /* copy into our temp area */
-    memcpy(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
-
-    UNLOCK_AR6K(pDev);
-
-    do {
-
-        if (AsyncMode) {
-
-            pIOPacket = AR6KAllocIOPacket(pDev);
-
-            if (NULL == pIOPacket) {
-                status = A_NO_MEMORY;
-                A_ASSERT(false);
-                break;
-            }
-
-                /* copy values to write to our async I/O buffer */
-            memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
-
-                /* stick in our completion routine when the I/O operation completes */
-            pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
-            pIOPacket->pContext = pDev;
-            pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
-                /* write it out asynchronously */
-            HIFReadWrite(pDev->HIFDevice,
-                         INT_STATUS_ENABLE_ADDRESS,
-                         pIOPacket->pBuffer,
-                         AR6K_IRQ_ENABLE_REGS_SIZE,
-                         HIF_WR_ASYNC_BYTE_INC,
-                         pIOPacket);
-                         
-            pIOPacket = NULL; 
-            break;
-        } 
-
-            /* if we get here we are doing it synchronously */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              INT_STATUS_ENABLE_ADDRESS,
-                              &regs.int_status_enable,
-                              AR6K_IRQ_ENABLE_REGS_SIZE,
-                              HIF_WR_SYNC_BYTE_INC,
-                              NULL);    
-    } while (false);
-    
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));    
-    } else {
-        if (!AsyncMode) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                    (" IRQAction Operation (%d) success \n", IrqAction)); 
-        }       
-    }
-    
-    if (pIOPacket != NULL) {
-        AR6KFreeIOPacket(pDev,pIOPacket);
-    }
-        
-    return status;
-}
-
-
-int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode)
-{
-    int      status = 0;
-    struct htc_packet    *pIOPacket = NULL;   
-    u8 GMboxIntControl[4];
-
-    if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
-        return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode);
-    } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
-        return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
-    }
-    
-    if (GMBOX_DISABLE_ALL == IrqAction) {
-            /* disable credit IRQ, those are on a different set of registers */
-        DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);    
-    }
-            
-        /* take the lock to protect interrupt enable shadows */
-    LOCK_AR6K(pDev);
-
-    switch (IrqAction) {
-        
-        case GMBOX_DISABLE_ALL:
-            pDev->GMboxControlRegisters.int_status_enable = 0;
-            break;
-        case GMBOX_ERRORS_IRQ_ENABLE:
-            pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW |
-                                                             GMBOX_INT_STATUS_RX_OVERFLOW;
-            break;
-        case GMBOX_RECV_IRQ_ENABLE:
-            pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA;
-            break;
-        case GMBOX_RECV_IRQ_DISABLE:
-            pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA;
-            break;
-        case GMBOX_ACTION_NONE:
-        default:
-            A_ASSERT(false);
-            break;
-    }
-    
-    GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
-    GMboxIntControl[1] = GMboxIntControl[0];
-    GMboxIntControl[2] = GMboxIntControl[0];
-    GMboxIntControl[3] = GMboxIntControl[0];
-    
-    UNLOCK_AR6K(pDev);
-
-    do {
-
-        if (AsyncMode) {
-
-            pIOPacket = AR6KAllocIOPacket(pDev);
-
-            if (NULL == pIOPacket) {
-                status = A_NO_MEMORY;
-                A_ASSERT(false);
-                break;
-            }
-
-                /* copy values to write to our async I/O buffer */
-            memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl));
-
-                /* stick in our completion routine when the I/O operation completes */
-            pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
-            pIOPacket->pContext = pDev;
-            pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
-                /* write it out asynchronously */
-            HIFReadWrite(pDev->HIFDevice,
-                         GMBOX_INT_STATUS_ENABLE_REG,
-                         pIOPacket->pBuffer,
-                         sizeof(GMboxIntControl),
-                         HIF_WR_ASYNC_BYTE_FIX,
-                         pIOPacket);
-            pIOPacket = NULL;
-            break;
-        }
-
-        /* if we get here we are doing it synchronously */
-
-        status = HIFReadWrite(pDev->HIFDevice,
-                              GMBOX_INT_STATUS_ENABLE_REG,
-                              GMboxIntControl,
-                              sizeof(GMboxIntControl),
-                              HIF_WR_SYNC_BYTE_FIX,
-                              NULL);
-
-    } while (false);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));    
-    } else {
-        if (!AsyncMode) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
-                    (" IRQAction Operation (%d) success \n", IrqAction)); 
-        }      
-    }
-    
-    if (pIOPacket != NULL) {
-        AR6KFreeIOPacket(pDev,pIOPacket);
-    }
-
-    return status;
-}
-
-void DevCleanupGMbox(struct ar6k_device *pDev)
-{
-    if (pDev->GMboxEnabled) {
-        pDev->GMboxEnabled = false;
-        GMboxProtocolUninstall(pDev);        
-    }
-}
-
-int DevSetupGMbox(struct ar6k_device *pDev)
-{
-    int    status = 0;
-    u8 muxControl[4];
-    
-    do {
-        
-        if (0 == pDev->MailBoxInfo.GMboxAddress) {
-            break;    
-        }
-    
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n",
-                    pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize));
-                    
-        status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
-        
-        if (status) {
-            break;    
-        }
-       
-            /* write to mailbox look ahead mux control register, we want the
-             * GMBOX lookaheads to appear on lookaheads 2 and 3 
-             * the register is 1-byte wide so we need to hit it 4 times to align the operation 
-             * to 4-bytes */            
-        muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3;
-        muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3;
-        muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3;
-        muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3;
-                
-        status = HIFReadWrite(pDev->HIFDevice,
-                              GMBOX_LOOKAHEAD_MUX_REG,
-                              muxControl,
-                              sizeof(muxControl),
-                              HIF_WR_SYNC_BYTE_FIX,  /* hit this register 4 times */
-                              NULL);
-        
-        if (status) {
-            break;    
-        }
-        
-        status = GMboxProtocolInstall(pDev);
-        
-        if (status) {
-            break;    
-        }
-        
-        pDev->GMboxEnabled = true;
-        
-    } while (false);
-    
-    return status;
-}
-
-int DevCheckGMboxInterrupts(struct ar6k_device *pDev)
-{
-    int status = 0;
-    u8 counter_int_status;
-    int      credits;
-    u8 host_int_status2;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n"));
-     
-    /* the caller guarantees that this is a context that allows for blocking I/O */
-    
-    do {
-        
-        host_int_status2 = pDev->IrqProcRegisters.host_int_status2 &
-                           pDev->GMboxControlRegisters.int_status_enable; 
-                
-        if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n"));  
-            status = A_ECOMM;   
-        }
-        
-        if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n"));  
-            status = A_ECOMM;    
-        }
-        
-        if (status) {
-            if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
-                pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status);        
-            }
-            break;
-        }
-    
-        if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) {
-            if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) {
-                A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL);
-                status = pDev->GMboxInfo.pMessagePendingCallBack(
-                                pDev->GMboxInfo.pProtocolContext,
-                                (u8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0],
-                                pDev->IrqProcRegisters.gmbox_rx_avail);
-            }
-        } 
-        
-        if (status) {
-           break;                
-        }
-        
-        counter_int_status = pDev->IrqProcRegisters.counter_int_status &
-                             pDev->IrqEnableRegisters.counter_int_status_enable;
-    
-            /* check if credit interrupt is pending */
-        if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER))) {
-            
-                /* do synchronous read */
-            status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits);
-            
-            if (status) {
-                break;    
-            }
-            
-            A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL);
-            status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
-                                                             credits,
-                                                             pDev->GMboxInfo.CreditCountIRQEnabled);
-        }
-        
-    } while (false);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status));
-    
-    return status;
-}
-
-
-int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength)
-{
-    u32 paddedLength;
-    bool   sync = (pPacket->Completion == NULL) ? true : false;
-    int status;
-    u32 address;
-    
-       /* adjust the length to be a multiple of block size if appropriate */
-    paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
-                ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
-                WriteLength,
-                pDev->MailBoxInfo.GMboxAddress,
-                sync ? "SYNC" : "ASYNC"));
-                
-        /* last byte of packet has to hit the EOM marker */
-    address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength;
-    
-    status = HIFReadWrite(pDev->HIFDevice,
-                          address,
-                          pPacket->pBuffer,
-                          paddedLength,     /* the padded length */
-                          sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
-                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
-
-    if (sync) {
-        pPacket->Status = status;
-    } else {
-        if (status == A_PENDING) {
-            status = 0;
-        }    
-    }
-
-    return status;
-}
-
-int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength)
-{
-    
-    u32 paddedLength;
-    int status;
-    bool   sync = (pPacket->Completion == NULL) ? true : false;
-
-        /* adjust the length to be a multiple of block size if appropriate */
-    paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
-                    
-    if (paddedLength > pPacket->BufferLength) {
-        A_ASSERT(false);
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
-                    paddedLength,ReadLength,pPacket->BufferLength));
-        if (pPacket->Completion != NULL) {
-            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
-            return 0;
-        }
-        return A_EINVAL;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
-                (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
-                paddedLength,
-                pDev->MailBoxInfo.GMboxAddress,
-                sync ? "SYNC" : "ASYNC"));
-
-    status = HIFReadWrite(pDev->HIFDevice,
-                          pDev->MailBoxInfo.GMboxAddress,
-                          pPacket->pBuffer,
-                          paddedLength,
-                          sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
-                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
-
-    if (sync) {
-        pPacket->Status = status;
-    }
-
-    return status;
-}
-
-
-static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length)
-{
-    int     credits = 0;
-    
-    /* theory of how this works:
-     * We read the credit decrement register multiple times on a byte-wide basis. 
-     * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a 
-     * reasonable chance to acquire "all" pending credits in a single I/O operation. 
-     * 
-     * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions.
-     * Each non-zero byte represents a single credit decrement (which is a credit given back to the host)
-     * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following
-     * pattern "could" appear:
-     * 
-     *    0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros
-     *    <--------->                     <----------------------------->
-     *         \_ credits aleady there              \_ target adding 4 more credits
-     * 
-     *    The total available credits would be 7, since there are 7 non-zero bytes in the buffer.
-     * 
-     * */
-    
-    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
-        DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer");
-    } 
-        
-    while (Length) {
-        if (*pBuffer != 0) {
-            credits++;    
-        }
-        Length--;
-        pBuffer++;   
-    }  
-    
-    return credits;
-}
-   
-
-/* callback when our fetch to enable/disable completes */
-static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6k_device *pDev = (struct ar6k_device *)Context;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
-
-    if (pPacket->Status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("Read Credit Operation failed! status:%d \n", pPacket->Status));
-    } else {
-        int credits = 0;
-        credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
-        pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
-                                                credits,
-                                                pDev->GMboxInfo.CreditCountIRQEnabled);
-        
-        
-    }
-        /* free this IO packet */
-    AR6KFreeIOPacket(pDev,pPacket);
-    AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
-}
-
-int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits)
-{
-    int    status = 0;
-    struct htc_packet  *pIOPacket = NULL;  
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
-                                            
-    do {
-        
-        pIOPacket = AR6KAllocIOPacket(pDev);
-
-        if (NULL == pIOPacket) {
-            status = A_NO_MEMORY;
-            A_ASSERT(false);
-            break;
-        }
-        
-        A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
-      
-        if (AsyncMode) {   
-                /* stick in our completion routine when the I/O operation completes */
-            pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
-            pIOPacket->pContext = pDev;
-                /* read registers asynchronously */
-            HIFReadWrite(pDev->HIFDevice,
-                         AR6K_GMBOX_CREDIT_DEC_ADDRESS,
-                         pIOPacket->pBuffer,
-                         AR6K_REG_IO_BUFFER_SIZE,  /* hit the register multiple times */
-                         HIF_RD_ASYNC_BYTE_FIX,
-                         pIOPacket);
-            pIOPacket = NULL;
-            break;
-        } 
-
-        pIOPacket->Completion = NULL;
-            /* if we get here we are doing it synchronously */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              AR6K_GMBOX_CREDIT_DEC_ADDRESS,
-                              pIOPacket->pBuffer,
-                              AR6K_REG_IO_BUFFER_SIZE,
-                              HIF_RD_SYNC_BYTE_FIX,
-                              NULL);    
-    } while (false);
-    
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                (" DevGMboxReadCreditCounter failed! status:%d \n", status));          
-    }
-    
-    if (pIOPacket != NULL) {
-        if (!status) {
-                /* sync mode processing */
-            *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);     
-        }
-        AR6KFreeIOPacket(pDev,pIOPacket);
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n", 
-            AsyncMode ? "ASYNC" : "SYNC", status));
-    
-    return status;
-}
-
-int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize)
-{
-    int    status;
-    u8 buffer[4];
-       
-    status = HIFReadWrite(pDev->HIFDevice,
-                          AR6K_GMBOX_CREDIT_SIZE_ADDRESS,
-                          buffer,
-                          sizeof(buffer),
-                          HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
-                          NULL);    
-    
-    if (!status) {
-        if (buffer[0] == 0) {
-            *pCreditSize = 256;    
-        } else {   
-            *pCreditSize = buffer[0];
-        } 
-           
-    } 
-    
-    return status;
-}
-
-void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev)
-{
-        /* Target ASSERTED!!! */
-    if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
-        pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE);        
-    }
-}
-
-int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes)
-{
-
-    int                    status = 0;
-    struct ar6k_irq_proc_registers     procRegs;
-    int                         maxCopy;
-  
-    do {
-            /* on entry the caller provides the length of the lookahead buffer */
-        if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) {
-            A_ASSERT(false);
-            status = A_EINVAL;
-            break;    
-        }
-        
-        maxCopy = *pLookAheadBytes;
-        *pLookAheadBytes = 0;
-            /* load the register table from the device */
-        status = HIFReadWrite(pDev->HIFDevice,
-                              HOST_INT_STATUS_ADDRESS,
-                              (u8 *)&procRegs,
-                              AR6K_IRQ_PROC_REGS_SIZE,
-                              HIF_RD_SYNC_BYTE_INC,
-                              NULL);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status));
-            break;
-        }
-        
-        if (procRegs.gmbox_rx_avail > 0) {
-            int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail;
-            memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes);
-            *pLookAheadBytes = bytes;
-        }
-        
-    } while (false);
-       
-    return status; 
-}
-
-int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS)
-{
-    int status = 0;
-    int      i;
-    u8 buffer[4];
-    
-    A_MEMZERO(buffer, sizeof(buffer));
-    
-    do {
-        
-        if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) {
-            status = A_EINVAL;
-            break;    
-        }
-        
-            /* set the last buffer to do the actual signal trigger */
-        buffer[3] = (1 << Signal);
-        
-        status = HIFReadWrite(pDev->HIFDevice,
-                              INT_WLAN_ADDRESS,
-                              buffer,
-                              sizeof(buffer),
-                              HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
-                              NULL);    
-                          
-        if (status) {
-            break;    
-        }
-        
-    } while (false);
-    
-    
-    if (!status) {
-            /* now read back the register to see if the bit cleared */
-        while (AckTimeoutMS) {        
-            status = HIFReadWrite(pDev->HIFDevice,
-                                  INT_WLAN_ADDRESS,
-                                  buffer,
-                                  sizeof(buffer),
-                                  HIF_RD_SYNC_BYTE_FIX,
-                                  NULL);    
-                          
-            if (status) {
-                break;    
-            }
-                            
-            for (i = 0; i < sizeof(buffer); i++) {
-                if (buffer[i] & (1 << Signal)) {
-                    /* bit is still set */
-                    break;    
-                }   
-            }
-            
-            if (i >= sizeof(buffer)) {
-                /* done */
-                break;    
-            }
-            
-            AckTimeoutMS--;
-            A_MDELAY(1);  
-        }
-        
-        if (0 == AckTimeoutMS) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal));
-            status = A_ERROR;    
-        }        
-    }
-    
-    return status;
-    
-}
-
-#endif  //ATH_AR6K_ENABLE_GMBOX
-
-
-
-
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
deleted file mode 100644 (file)
index 56a0d71..0000000
+++ /dev/null
@@ -1,1284 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6k_prot_hciUart.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Protocol module for use in bridging HCI-UART packets over the GMBOX interface
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#include "../htc_debug.h"
-#include "hif.h"
-#include "htc_packet.h"
-#include "ar6k.h"
-#include "hci_transport_api.h"
-#include "gmboxif.h"
-#include "ar6000_diag.h"
-#include "hw/apb_map.h"
-#include "hw/mbox_reg.h"
-
-#ifdef ATH_AR6K_ENABLE_GMBOX
-#define HCI_UART_COMMAND_PKT 0x01
-#define HCI_UART_ACL_PKT     0x02
-#define HCI_UART_SCO_PKT     0x03
-#define HCI_UART_EVENT_PKT   0x04
-
-#define HCI_RECV_WAIT_BUFFERS (1 << 0)
-
-#define HCI_SEND_WAIT_CREDITS (1 << 0)
-
-#define HCI_UART_BRIDGE_CREDIT_SIZE     128
-
-#define CREDIT_POLL_COUNT       256
-
-#define HCI_DELAY_PER_INTERVAL_MS 10 
-#define BTON_TIMEOUT_MS           500
-#define BTOFF_TIMEOUT_MS          500
-#define BAUD_TIMEOUT_MS           1
-#define BTPWRSAV_TIMEOUT_MS       1  
-
-struct gmbox_proto_hci_uart {
-    struct hci_transport_config_info   HCIConfig;
-    bool                      HCIAttached;
-    bool                      HCIStopped;
-    u32 RecvStateFlags;
-    u32 SendStateFlags;
-    HCI_TRANSPORT_PACKET_TYPE   WaitBufferType;
-    struct htc_packet_queue            SendQueue;         /* write queue holding HCI Command and ACL packets */
-    struct htc_packet_queue            HCIACLRecvBuffers;  /* recv queue holding buffers for incomming ACL packets */
-    struct htc_packet_queue            HCIEventBuffers;    /* recv queue holding buffers for incomming event packets */
-    struct ar6k_device                 *pDev;
-    A_MUTEX_T                   HCIRxLock;
-    A_MUTEX_T                   HCITxLock;
-    int                         CreditsMax;
-    int                         CreditsConsumed;
-    int                         CreditsAvailable;
-    int                         CreditSize;
-    int                         CreditsCurrentSeek;
-    int                         SendProcessCount;
-};
-
-#define LOCK_HCI_RX(t)   A_MUTEX_LOCK(&(t)->HCIRxLock);
-#define UNLOCK_HCI_RX(t) A_MUTEX_UNLOCK(&(t)->HCIRxLock);
-#define LOCK_HCI_TX(t)   A_MUTEX_LOCK(&(t)->HCITxLock);
-#define UNLOCK_HCI_TX(t) A_MUTEX_UNLOCK(&(t)->HCITxLock);
-
-#define DO_HCI_RECV_INDICATION(p, pt)                          \
-do {                                                           \
-       AR_DEBUG_PRINTF(ATH_DEBUG_RECV,                                 \
-                       ("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \
-                        (unsigned long)(pt),                           \
-                        (pt)->Status,                                  \
-                        !(pt)->Status ? (pt)->ActualLength : 0,        \
-                        HCI_GET_PACKET_TYPE(pt)));                     \
-       (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt));      \
-} while (0)
-
-#define DO_HCI_SEND_INDICATION(p,pt) \
-{   AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Indicate Send on packet:0x%lX status:%d type:%d \n",  \
-            (unsigned long)(pt),(pt)->Status,HCI_GET_PACKET_TYPE(pt)));                             \
-    (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt));                            \
-}
-    
-static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous);
-
-static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol)
-{
-    A_ASSERT(pProtocol != NULL);
-    
-    A_MUTEX_DELETE(&pProtocol->HCIRxLock);
-    A_MUTEX_DELETE(&pProtocol->HCITxLock);
-        
-    kfree(pProtocol);    
-}
-
-static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt)
-{
-    int    status;
-    int         credits;
-    int         creditPollCount = CREDIT_POLL_COUNT;
-    bool      gotCredits = false;
-
-    pProt->CreditsConsumed = 0;
-    
-    do {    
-        
-        if (pProt->CreditsMax != 0) {
-            /* we can only call this only once per target reset */
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI: InitTxCreditState - already called!  \n"));
-            A_ASSERT(false);
-            status = A_EINVAL;
-            break; 
-        }
-        
-        /* read the credit counter. At startup the target will set the credit counter
-         * to the max available, we read this in a loop because it may take
-         * multiple credit counter reads to get all credits  */
-                 
-        while (creditPollCount) {
-            
-            credits = 0;
-
-            status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
-    
-            if (status) {
-                break;    
-            }
-            
-            if (!gotCredits && (0 == credits)) {
-                creditPollCount--;
-                AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: credit is 0, retrying (%d)  \n",creditPollCount));
-                A_MDELAY(HCI_DELAY_PER_INTERVAL_MS);
-                continue;  
-            } else {
-                gotCredits = true;
-            }
-            
-            if (0 == credits) {
-                break;    
-            }
-            
-            pProt->CreditsMax += credits;
-        }
-        
-        if (status) {
-            break;    
-        }
-        
-        if (0 == creditPollCount) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("** HCI : Failed to get credits! GMBOX Target was not available \n"));        
-            status = A_ERROR;
-            break;
-        }
-        
-            /* now get the size */
-        status = DevGMboxReadCreditSize(pProt->pDev, &pProt->CreditSize);
-        
-        if (status) {
-            break;    
-        }
-               
-    } while (false);
-    
-    if (!status) {
-        pProt->CreditsAvailable = pProt->CreditsMax;
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI : InitTxCreditState - credits avail: %d, size: %d \n",
-            pProt->CreditsAvailable, pProt->CreditSize));    
-    }    
-    
-    return status;
-}
-
-static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQEnabled)
-{
-    struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext;    
-    bool               enableCreditIrq = false;
-    bool               disableCreditIrq = false;
-    bool               doPendingSends = false;
-    int             status = 0;
-    
-    /** this callback is called under 2 conditions:
-     *   1. The credit IRQ interrupt was enabled and signaled.
-     *   2. A credit counter read completed.
-     * 
-     *   The function must not assume that the calling context can block !
-     */
-     
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback (Credits:%d, IRQ:%s) \n",
-                Credits, CreditIRQEnabled ? "ON" : "OFF"));
-    
-    LOCK_HCI_TX(pProt);
-    
-    do {
-        
-        if (0 == Credits) {
-            if (!CreditIRQEnabled) {
-                    /* enable credit IRQ */
-                enableCreditIrq = true;
-            }
-            break;
-        }
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: current credit state, consumed:%d available:%d max:%d seek:%d\n",
-                         pProt->CreditsConsumed, 
-                         pProt->CreditsAvailable,  
-                         pProt->CreditsMax,
-                         pProt->CreditsCurrentSeek));
-                         
-        pProt->CreditsAvailable += Credits;
-        A_ASSERT(pProt->CreditsAvailable <= pProt->CreditsMax);
-        pProt->CreditsConsumed  -= Credits;
-        A_ASSERT(pProt->CreditsConsumed >= 0);
-            
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state, consumed:%d available:%d max:%d seek:%d\n",
-                         pProt->CreditsConsumed, 
-                         pProt->CreditsAvailable,  
-                         pProt->CreditsMax,
-                         pProt->CreditsCurrentSeek));
-        
-        if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
-                /* we have enough credits to fulfill at least 1 packet waiting in the queue */
-            pProt->CreditsCurrentSeek = 0;
-            pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS;  
-            doPendingSends = true;
-            if (CreditIRQEnabled) {
-                    /* credit IRQ was enabled, we shouldn't need it anymore */
-                disableCreditIrq = true;
-            }      
-        } else {
-                /* not enough credits yet, enable credit IRQ if we haven't already */
-            if (!CreditIRQEnabled) {               
-                enableCreditIrq = true;
-            }    
-        }
-                      
-    } while (false);
-    
-    UNLOCK_HCI_TX(pProt);
-
-    if (enableCreditIrq) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Enabling credit count IRQ...\n"));
-            /* must use async only */
-        status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_ENABLE, PROC_IO_ASYNC);    
-    } else if (disableCreditIrq) {
-            /* must use async only */
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Disabling credit count IRQ...\n"));
-        status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_DISABLE, PROC_IO_ASYNC); 
-    }
-       
-    if (doPendingSends) {
-        HCITrySend(pProt, NULL, false);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback \n"));
-    return status;
-}
-
-static INLINE void NotifyTransportFailure(struct gmbox_proto_hci_uart  *pProt, int status)
-{
-    if (pProt->HCIConfig.TransportFailure != NULL) {
-        pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status);
-    }
-}
-
-static void FailureCallback(void *pContext, int Status)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)pContext; 
-    
-        /* target assertion occurred */           
-    NotifyTransportFailure(pProt, Status);  
-}
-
-static void StateDumpCallback(void *pContext)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)pContext;
-   
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("============ HCIUart State ======================\n"));    
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("RecvStateFlags   :  0x%X \n",pProt->RecvStateFlags));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendStateFlags   :  0x%X \n",pProt->SendStateFlags));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("WaitBufferType   :  %d   \n",pProt->WaitBufferType));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendQueue Depth  :  %d   \n",HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsMax       :  %d   \n",pProt->CreditsMax));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsConsumed  :  %d   \n",pProt->CreditsConsumed));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsAvailable :  %d   \n",pProt->CreditsAvailable));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n"));
-}
-
-static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes)
-{
-    struct gmbox_proto_hci_uart        *pProt = (struct gmbox_proto_hci_uart *)pContext;
-    int                    status = 0;
-    int                         totalRecvLength = 0;
-    HCI_TRANSPORT_PACKET_TYPE   pktType = HCI_PACKET_INVALID;
-    bool                      recvRefillCalled = false;
-    bool                      blockRecv = false;
-    struct htc_packet                  *pPacket = NULL;
-    
-    /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCIUartMessagePending Lookahead Bytes:%d \n",ValidBytes));
-    
-    LOCK_HCI_RX(pProt);
-        
-    do {
-    
-        if (ValidBytes < 3) {
-                /* not enough for ACL or event header */
-            break;    
-        }    
-        
-        if ((LookAheadBytes[0] == HCI_UART_ACL_PKT) && (ValidBytes < 5)) {
-                /* not enough for ACL data header */
-            break;    
-        }
-                
-        switch (LookAheadBytes[0]) {       
-            case HCI_UART_EVENT_PKT:
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
-                        LookAheadBytes[1], LookAheadBytes[2]));
-                totalRecvLength = LookAheadBytes[2];
-                totalRecvLength += 3; /* add type + event code + length field */
-                pktType = HCI_EVENT_TYPE;      
-                break;
-            case HCI_UART_ACL_PKT:                
-                totalRecvLength = (LookAheadBytes[4] << 8) | LookAheadBytes[3];                
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI ACL: conn:0x%X length: %d \n",
-                        ((LookAheadBytes[2] & 0xF0) << 8) | LookAheadBytes[1], totalRecvLength));
-                totalRecvLength += 5; /* add type + connection handle + length field */
-                pktType = HCI_ACL_TYPE;           
-                break;        
-            default:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",LookAheadBytes[0]));
-                status = A_EPROTO;
-                break;
-        }
-        
-        if (status) {
-            break;    
-        }
-                
-        if (pProt->HCIConfig.pHCIPktRecvAlloc != NULL) {
-            UNLOCK_HCI_RX(pProt);
-                /* user is using a per-packet allocation callback */
-            pPacket = pProt->HCIConfig.pHCIPktRecvAlloc(pProt->HCIConfig.pContext,
-                                                        pktType,
-                                                        totalRecvLength);
-            LOCK_HCI_RX(pProt);
-    
-        } else {
-            struct htc_packet_queue *pQueue;
-                /* user is using a refill handler that can refill multiple HTC buffers */
-            
-                /* select buffer queue */
-            if (pktType == HCI_ACL_TYPE) {
-                pQueue = &pProt->HCIACLRecvBuffers;    
-            } else {
-                pQueue = &pProt->HCIEventBuffers;              
-            }    
-            
-            if (HTC_QUEUE_EMPTY(pQueue)) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                    ("** HCI pkt type: %d has no buffers available calling allocation handler \n", 
-                    pktType));
-                    /* check for refill handler */
-                if (pProt->HCIConfig.pHCIPktRecvRefill != NULL) {
-                    recvRefillCalled = true;
-                    UNLOCK_HCI_RX(pProt);
-                        /* call the re-fill handler */
-                    pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
-                                                       pktType,
-                                                       0);
-                    LOCK_HCI_RX(pProt);
-                        /* check if we have more buffers */
-                    pPacket = HTC_PACKET_DEQUEUE(pQueue);
-                        /* fall through */
-                }
-            } else {
-                pPacket = HTC_PACKET_DEQUEUE(pQueue);
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                    ("HCI pkt type: %d now has %d recv buffers left \n", 
-                            pktType, HTC_PACKET_QUEUE_DEPTH(pQueue)));    
-            }
-        }
-     
-        if (NULL == pPacket) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                    ("** HCI pkt type: %d has no buffers available stopping recv...\n", pktType));
-                /* this is not an error, we simply need to mark that we are waiting for buffers.*/
-            pProt->RecvStateFlags |= HCI_RECV_WAIT_BUFFERS;
-            pProt->WaitBufferType = pktType;
-            blockRecv = true;
-            break;
-        }
-        
-        if (totalRecvLength > (int)pPacket->BufferLength) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI-UART pkt: %d requires %d bytes (%d buffer bytes avail) ! \n",
-                LookAheadBytes[0], totalRecvLength, pPacket->BufferLength));
-            status = A_EINVAL;
-            break;
-        }
-        
-    } while (false);
-    
-    UNLOCK_HCI_RX(pProt);
-    
-        /* locks are released, we can go fetch the packet */
-        
-    do {
-        
-        if (status || (NULL == pPacket)) {
-            break;    
-        } 
-        
-            /* do this synchronously, we don't need to be fast here */
-        pPacket->Completion = NULL;
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI : getting recv packet len:%d hci-uart-type: %s \n",
-                totalRecvLength, (LookAheadBytes[0] == HCI_UART_EVENT_PKT) ? "EVENT" : "ACL"));
-                
-        status = DevGMboxRead(pProt->pDev, pPacket, totalRecvLength);     
-        
-        if (status) {
-            break;    
-        }
-        
-        if (pPacket->pBuffer[0] != LookAheadBytes[0]) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not contain expected packet type: %d ! \n",
-                        pPacket->pBuffer[0]));
-            status = A_EPROTO;
-            break;   
-        }
-        
-        if (pPacket->pBuffer[0] == HCI_UART_EVENT_PKT) {
-                /* validate event header fields */
-            if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
-                (pPacket->pBuffer[2] != LookAheadBytes[2])) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
-                DebugDumpBytes(LookAheadBytes, 3, "Expected HCI-UART Header");  
-                DebugDumpBytes(pPacket->pBuffer, 3, "** Bad HCI-UART Header");  
-                status = A_EPROTO;
-                break;       
-            }   
-        } else if (pPacket->pBuffer[0] == HCI_UART_ACL_PKT) {
-                /* validate acl header fields */
-            if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
-                (pPacket->pBuffer[2] != LookAheadBytes[2]) ||
-                (pPacket->pBuffer[3] != LookAheadBytes[3]) ||
-                (pPacket->pBuffer[4] != LookAheadBytes[4])) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
-                DebugDumpBytes(LookAheadBytes, 5, "Expected HCI-UART Header");  
-                DebugDumpBytes(pPacket->pBuffer, 5, "** Bad HCI-UART Header");  
-                status = A_EPROTO;
-                break;       
-            }   
-        }
-        
-            /* adjust buffer to move past packet ID */
-        pPacket->pBuffer++;
-        pPacket->ActualLength = totalRecvLength - 1;
-        pPacket->Status = 0;
-            /* indicate packet */
-        DO_HCI_RECV_INDICATION(pProt,pPacket);
-        pPacket = NULL;
-        
-            /* check if we need to refill recv buffers */        
-        if ((pProt->HCIConfig.pHCIPktRecvRefill != NULL) && !recvRefillCalled) {           
-            struct htc_packet_queue *pQueue;
-            int              watermark;
-
-            if (pktType == HCI_ACL_TYPE) {
-                watermark = pProt->HCIConfig.ACLRecvBufferWaterMark;
-                pQueue = &pProt->HCIACLRecvBuffers;    
-            } else {
-                watermark = pProt->HCIConfig.EventRecvBufferWaterMark;     
-                pQueue = &pProt->HCIEventBuffers;        
-            }    
-            
-            if (HTC_PACKET_QUEUE_DEPTH(pQueue) < watermark) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                    ("** HCI pkt type: %d watermark hit (%d) current:%d \n", 
-                    pktType, watermark, HTC_PACKET_QUEUE_DEPTH(pQueue)));
-                    /* call the re-fill handler */
-                pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
-                                                   pktType,
-                                                   HTC_PACKET_QUEUE_DEPTH(pQueue));
-            }
-        }   
-        
-    } while (false);
-        
-        /* check if we need to disable the receiver */
-    if (status || blockRecv) {
-        DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC); 
-    }
-    
-        /* see if we need to recycle the recv buffer */    
-    if (status && (pPacket != NULL)) {
-        struct htc_packet_queue queue;
-        
-        if (A_EPROTO == status) {
-            DebugDumpBytes(pPacket->pBuffer, totalRecvLength, "Bad HCI-UART Recv packet");    
-        }
-            /* recycle packet */
-        HTC_PACKET_RESET_RX(pPacket);
-        INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
-        HCI_TransportAddReceivePkts(pProt,&queue);
-        NotifyTransportFailure(pProt,status);    
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCIUartMessagePending \n"));
-    
-    return status;
-}
-
-static void HCISendPacketCompletion(void *Context, struct htc_packet *pPacket)
-{
-    struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)Context;
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket));
-    
-    if (pPacket->Status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Send Packet (0x%lX) failed: %d , len:%d \n",
-            (unsigned long)pPacket, pPacket->Status, pPacket->ActualLength));        
-    }
-    
-    DO_HCI_SEND_INDICATION(pProt,pPacket);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n"));
-}
-
-static int SeekCreditsSynch(struct gmbox_proto_hci_uart *pProt)
-{
-    int status = 0;
-    int      credits;
-    int      retry = 100;
-    
-    while (true) {
-        credits = 0;
-        status =  DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);   
-        if (status) {
-            break;    
-        }
-        LOCK_HCI_TX(pProt);
-        pProt->CreditsAvailable += credits;        
-        pProt->CreditsConsumed -= credits;        
-        if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
-            pProt->CreditsCurrentSeek = 0;
-            UNLOCK_HCI_TX(pProt);
-            break;    
-        }
-        UNLOCK_HCI_TX(pProt);
-        retry--;
-        if (0 == retry) {
-            status = A_EBUSY;
-            break;    
-        }
-        A_MDELAY(20);
-    }   
-    
-    return status;
-}
-
-static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous)
-{   
-    int    status = 0;
-    int         transferLength;
-    int         creditsRequired, remainder;
-    u8 hciUartType;
-    bool      synchSendComplete = false;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket,
-            Synchronous ? "SYNC" :"ASYNC"));
-    
-    LOCK_HCI_TX(pProt);
-     
-        /* increment write processing count on entry */    
-    pProt->SendProcessCount++;
-        
-    do {
-                                             
-        if (pProt->HCIStopped) {
-            status = A_ECANCELED;
-            break;     
-        }   
-         
-        if (pPacket != NULL) {  
-                /* packet was supplied */     
-            if (Synchronous) {
-                    /* in synchronous mode, the send queue can only hold 1 packet */
-                if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
-                    status = A_EBUSY;
-                    A_ASSERT(false);
-                    break;    
-                }             
-                
-                if (pProt->SendProcessCount > 1) {
-                        /* another thread or task is draining the TX queues  */
-                    status = A_EBUSY;
-                    A_ASSERT(false);
-                    break;
-                } 
-                  
-                HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
-                
-            } else {
-                    /* see if adding this packet hits the max depth (asynchronous mode only) */
-                if ((pProt->HCIConfig.MaxSendQueueDepth > 0) && 
-                    ((HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue) + 1) >= pProt->HCIConfig.MaxSendQueueDepth)) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("HCI Send queue is full, Depth:%d, Max:%d \n",
-                            HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue), 
-                            pProt->HCIConfig.MaxSendQueueDepth));
-                        /* queue will be full, invoke any callbacks to determine what action to take */
-                    if (pProt->HCIConfig.pHCISendFull != NULL) {
-                        AR_DEBUG_PRINTF(ATH_DEBUG_SEND, 
-                                    ("HCI : Calling driver's send full callback.... \n"));
-                        if (pProt->HCIConfig.pHCISendFull(pProt->HCIConfig.pContext,
-                                                          pPacket) == HCI_SEND_FULL_DROP) {
-                                /* drop it */
-                            status = A_NO_RESOURCE;      
-                            break;
-                        }
-                    }               
-                }
-          
-                HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
-            }
-
-        }
-               
-        if (pProt->SendStateFlags & HCI_SEND_WAIT_CREDITS) {
-            break;   
-        }
-
-        if (pProt->SendProcessCount > 1) {
-                /* another thread or task is draining the TX queues  */
-            break;
-        }
-    
-        /***** beyond this point only 1 thread may enter ******/
-           
-        /* now drain the send queue for transmission as long as we have enough
-         * credits */
-        while (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
-            
-            pPacket = HTC_PACKET_DEQUEUE(&pProt->SendQueue);
-
-            switch (HCI_GET_PACKET_TYPE(pPacket)) {            
-                case HCI_COMMAND_TYPE:
-                    hciUartType = HCI_UART_COMMAND_PKT;
-                    break;
-                case HCI_ACL_TYPE:
-                    hciUartType = HCI_UART_ACL_PKT;
-                    break;
-                default:
-                    status = A_EINVAL;
-                    A_ASSERT(false);
-                    break;
-            }
-                       
-            if (status) {
-                break;   
-            }
-            
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Got head packet:0x%lX , Type:%d  Length: %d Remaining Queue Depth: %d\n",
-                (unsigned long)pPacket, HCI_GET_PACKET_TYPE(pPacket), pPacket->ActualLength, 
-                HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
-        
-            transferLength = 1;  /* UART type header is 1 byte */
-            transferLength += pPacket->ActualLength;
-            transferLength = DEV_CALC_SEND_PADDED_LEN(pProt->pDev, transferLength);
-                   
-                /* figure out how many credits this message requires */
-            creditsRequired = transferLength / pProt->CreditSize;
-            remainder = transferLength % pProt->CreditSize;
-
-            if (remainder) {
-                creditsRequired++;
-            }
-
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Creds Required:%d   Got:%d\n",
-                            creditsRequired, pProt->CreditsAvailable));
-            
-            if (creditsRequired > pProt->CreditsAvailable) {
-                if (Synchronous) {
-                        /* in synchronous mode we need to seek credits in synchronously */
-                    pProt->CreditsCurrentSeek = creditsRequired;
-                    UNLOCK_HCI_TX(pProt);
-                    status = SeekCreditsSynch(pProt);
-                    LOCK_HCI_TX(pProt);
-                    if (status) {
-                        break;    
-                    }                    
-                    /* fall through and continue processing this send op */                    
-                } else {
-                        /* not enough credits, queue back to the head */
-                    HTC_PACKET_ENQUEUE_TO_HEAD(&pProt->SendQueue,pPacket);
-                        /* waiting for credits */
-                    pProt->SendStateFlags |= HCI_SEND_WAIT_CREDITS;
-                        /* provide a hint to reduce attempts to re-send if credits are dribbling back
-                         * this hint is the short fall of credits */
-                    pProt->CreditsCurrentSeek = creditsRequired;
-                    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: packet:0x%lX placed back in queue. head packet needs: %d credits \n",
-                                        (unsigned long)pPacket, pProt->CreditsCurrentSeek));
-                    pPacket = NULL;
-                    UNLOCK_HCI_TX(pProt);
-                    
-                        /* schedule a credit counter read, our CreditsAvailableCallback callback will be called
-                         * with the result */   
-                    DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_ASYNC, NULL);
-                             
-                    LOCK_HCI_TX(pProt);
-                    break;              
-                }          
-            }
-        
-                /* caller guarantees some head room */
-            pPacket->pBuffer--;
-            pPacket->pBuffer[0] = hciUartType;
-            
-            pProt->CreditsAvailable -= creditsRequired;
-            pProt->CreditsConsumed  += creditsRequired;
-            A_ASSERT(pProt->CreditsConsumed <= pProt->CreditsMax);
-            
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state: consumed:%d   available:%d max:%d\n",
-                             pProt->CreditsConsumed, pProt->CreditsAvailable,  pProt->CreditsMax));
-            
-            UNLOCK_HCI_TX(pProt);   
-            
-                /* write it out */   
-            if (Synchronous) {                            
-                pPacket->Completion = NULL;
-                pPacket->pContext = NULL;         
-            } else {                       
-                pPacket->Completion = HCISendPacketCompletion;
-                pPacket->pContext = pProt;    
-            }
-            
-            status = DevGMboxWrite(pProt->pDev,pPacket,transferLength);            
-            if (Synchronous) {            
-                synchSendComplete = true;
-            } else {
-                pPacket = NULL;    
-            }
-            
-            LOCK_HCI_TX(pProt);
-              
-        }
-        
-    } while (false);
-        
-    pProt->SendProcessCount--;
-    A_ASSERT(pProt->SendProcessCount >= 0);
-    UNLOCK_HCI_TX(pProt);
-    
-    if (Synchronous) {
-        A_ASSERT(pPacket != NULL);
-        if (!status && (!synchSendComplete)) {
-            status = A_EBUSY;
-            A_ASSERT(false);
-            LOCK_HCI_TX(pProt);
-            if (pPacket->ListLink.pNext != NULL) {
-                    /* remove from the queue */
-                HTC_PACKET_REMOVE(&pProt->SendQueue,pPacket);
-            }
-            UNLOCK_HCI_TX(pProt);
-        }
-    } else {   
-        if (status && (pPacket != NULL)) {
-            pPacket->Status = status;
-            DO_HCI_SEND_INDICATION(pProt,pPacket); 
-        }
-    }
-        
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HCITrySend:  \n"));
-    return status;    
-}
-
-static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt)
-{
-    struct htc_packet          *pPacket;
-    struct htc_packet_queue    discardQueue;
-    
-    INIT_HTC_PACKET_QUEUE(&discardQueue);
-    
-    LOCK_HCI_TX(pProt);
-    
-    if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
-        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->SendQueue);    
-    }
-    
-    UNLOCK_HCI_TX(pProt);
-    
-        /* discard packets */
-    while (!HTC_QUEUE_EMPTY(&discardQueue)) {
-        pPacket = HTC_PACKET_DEQUEUE(&discardQueue);   
-        pPacket->Status = A_ECANCELED;
-        DO_HCI_SEND_INDICATION(pProt,pPacket);
-    }
-    
-}
-
-static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt)
-{
-    struct htc_packet_queue discardQueue;
-    struct htc_packet *pPacket;
-    
-    INIT_HTC_PACKET_QUEUE(&discardQueue);
-    
-    LOCK_HCI_RX(pProt);
-        /*transfer list items from ACL and event buffer queues to the discard queue */       
-    if (!HTC_QUEUE_EMPTY(&pProt->HCIACLRecvBuffers)) {
-        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIACLRecvBuffers);    
-    }
-    if (!HTC_QUEUE_EMPTY(&pProt->HCIEventBuffers)) {
-        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIEventBuffers);    
-    }
-    UNLOCK_HCI_RX(pProt);
-    
-        /* now empty the discard queue */
-    while (!HTC_QUEUE_EMPTY(&discardQueue)) {
-        pPacket = HTC_PACKET_DEQUEUE(&discardQueue);      
-        pPacket->Status = A_ECANCELED;
-        DO_HCI_RECV_INDICATION(pProt,pPacket);
-    }
-    
-}
-
-/*** protocol module install entry point ***/
-
-int GMboxProtocolInstall(struct ar6k_device *pDev)
-{
-    int                status = 0;
-    struct gmbox_proto_hci_uart    *pProtocol = NULL;
-        
-    do {
-        
-        pProtocol = A_MALLOC(sizeof(struct gmbox_proto_hci_uart));
-        
-        if (NULL == pProtocol) {
-            status = A_NO_MEMORY;
-            break;    
-        }
-        
-        A_MEMZERO(pProtocol, sizeof(*pProtocol));
-        pProtocol->pDev = pDev;
-        INIT_HTC_PACKET_QUEUE(&pProtocol->SendQueue);
-        INIT_HTC_PACKET_QUEUE(&pProtocol->HCIACLRecvBuffers);
-        INIT_HTC_PACKET_QUEUE(&pProtocol->HCIEventBuffers);
-        A_MUTEX_INIT(&pProtocol->HCIRxLock);
-        A_MUTEX_INIT(&pProtocol->HCITxLock);
-     
-    } while (false);
-    
-    if (!status) {
-        LOCK_AR6K(pDev);
-        DEV_GMBOX_SET_PROTOCOL(pDev,
-                               HCIUartMessagePending,
-                               CreditsAvailableCallback,
-                               FailureCallback,
-                               StateDumpCallback,
-                               pProtocol);
-        UNLOCK_AR6K(pDev);
-    } else {
-        if (pProtocol != NULL) {
-            HCIUartCleanup(pProtocol);    
-        }    
-    }
-    
-    return status;    
-}
-
-/*** protocol module uninstall entry point ***/
-void GMboxProtocolUninstall(struct ar6k_device *pDev)
-{
-    struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev);
-    
-    if (pProtocol != NULL) {
-        
-            /* notify anyone attached */    
-        if (pProtocol->HCIAttached) {
-            A_ASSERT(pProtocol->HCIConfig.TransportRemoved != NULL);
-            pProtocol->HCIConfig.TransportRemoved(pProtocol->HCIConfig.pContext);
-            pProtocol->HCIAttached = false;
-        }
-        
-        HCIUartCleanup(pProtocol);
-        DEV_GMBOX_SET_PROTOCOL(pDev,NULL,NULL,NULL,NULL,NULL);       
-    }
-    
-}
-
-static int NotifyTransportReady(struct gmbox_proto_hci_uart  *pProt)
-{
-    struct hci_transport_properties props;
-    int                 status = 0;
-    
-    do {
-        
-        A_MEMZERO(&props,sizeof(props));
-        
-            /* HCI UART only needs one extra byte at the head to indicate the packet TYPE */
-        props.HeadRoom = 1;
-        props.TailRoom = 0;
-        props.IOBlockPad = pProt->pDev->BlockSize;
-        if (pProt->HCIAttached) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI: notifying attached client to transport... \n"));    
-            A_ASSERT(pProt->HCIConfig.TransportReady != NULL);
-            status = pProt->HCIConfig.TransportReady(pProt,
-                                                    &props,
-                                                    pProt->HCIConfig.pContext);
-        }
-        
-    } while (false);
-    
-    return status;
-}
-
-/***********  HCI UART protocol implementation ************************************************/
-
-HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo)
-{
-    struct gmbox_proto_hci_uart  *pProtocol = NULL; 
-    struct ar6k_device           *pDev;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n"));
-    
-    pDev = HTCGetAR6KDevice(HTCHandle);
-    
-    LOCK_AR6K(pDev);
-    
-    do {
-        
-        pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev);
-        
-        if (NULL == pProtocol) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not installed! \n"));
-            break;
-        }
-        
-        if (pProtocol->HCIAttached) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol already attached! \n"));
-            break;    
-        }
-        
-        memcpy(&pProtocol->HCIConfig, pInfo, sizeof(struct hci_transport_config_info));
-        
-        A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL);
-        A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL);
-        
-        pProtocol->HCIAttached = true;
-        
-    } while (false);
-    
-    UNLOCK_AR6K(pDev);
-    
-    if (pProtocol != NULL) {
-            /* TODO ... should we use a worker? */
-        NotifyTransportReady(pProtocol);
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach (0x%lX) \n",(unsigned long)pProtocol));
-    return (HCI_TRANSPORT_HANDLE)pProtocol;
-}
-
-void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans)
-{
-    struct gmbox_proto_hci_uart  *pProtocol = (struct gmbox_proto_hci_uart *)HciTrans; 
-    struct ar6k_device           *pDev = pProtocol->pDev;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n"));
-    
-    LOCK_AR6K(pDev);
-    if (!pProtocol->HCIAttached) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not attached! \n"));
-        UNLOCK_AR6K(pDev);
-        return;
-    }
-    pProtocol->HCIAttached = false;
-    UNLOCK_AR6K(pDev);
-    
-    HCI_TransportStop(HciTrans);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n"));
-}
-
-int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans; 
-    int              status = 0;
-    bool                unblockRecv = false;
-    struct htc_packet            *pPacket;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n"));
-    
-    LOCK_HCI_RX(pProt);
-   
-    do {
-         
-        if (pProt->HCIStopped) {
-            status = A_ECANCELED;
-            break;    
-        }
-        
-        pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
-        
-        if (NULL == pPacket) {
-            status = A_EINVAL;
-            break;    
-        }
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv packet added, type :%d, len:%d num:%d \n",
-                        HCI_GET_PACKET_TYPE(pPacket), pPacket->BufferLength, HTC_PACKET_QUEUE_DEPTH(pQueue)));
-                        
-        if (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) {
-            HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIEventBuffers, pQueue);
-        } else if (HCI_GET_PACKET_TYPE(pPacket) == HCI_ACL_TYPE) {
-            HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIACLRecvBuffers, pQueue);    
-        } else {
-            status = A_EINVAL;
-            break;    
-        }
-        
-        if (pProt->RecvStateFlags & HCI_RECV_WAIT_BUFFERS) {
-            if (pProt->WaitBufferType == HCI_GET_PACKET_TYPE(pPacket)) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv was blocked on packet type :%d, unblocking.. \n",
-                        pProt->WaitBufferType));
-                pProt->RecvStateFlags &= ~HCI_RECV_WAIT_BUFFERS;
-                pProt->WaitBufferType = HCI_PACKET_INVALID;
-                unblockRecv = true;
-            }
-        }
-        
-    } while (false);
-    
-    UNLOCK_HCI_RX(pProt);
-    
-    if (status) {
-        while (!HTC_QUEUE_EMPTY(pQueue)) {
-            pPacket = HTC_PACKET_DEQUEUE(pQueue);      
-            pPacket->Status = A_ECANCELED;
-            DO_HCI_RECV_INDICATION(pProt,pPacket);
-        }   
-    }
-    
-    if (unblockRecv) {
-        DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_ASYNC);
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCI_TransportAddReceivePkt \n"));
-    
-    return 0;
-}
-
-int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans;  
-    
-    return HCITrySend(pProt,pPacket,Synchronous);
-}
-
-void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans; 
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStop \n"));
-     
-    LOCK_AR6K(pProt->pDev);
-    if (pProt->HCIStopped) {
-        UNLOCK_AR6K(pProt->pDev);
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
-        return;    
-    }
-    pProt->HCIStopped = true;
-    UNLOCK_AR6K(pProt->pDev);
-     
-        /* disable interrupts */
-    DevGMboxIRQAction(pProt->pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
-    FlushSendQueue(pProt);
-    FlushRecvBuffers(pProt);
-    
-        /* signal bridge side to power down BT */
-    DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_OFF, BTOFF_TIMEOUT_MS);
-           
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
-}
-
-int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans)
-{
-    int              status;
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n"));
-    
-        /* set stopped in case we have a problem in starting */
-    pProt->HCIStopped = true;
-    
-    do {
-        
-        status = InitTxCreditState(pProt);   
-        
-        if (status) {
-            break;    
-        }     
-        
-        status = DevGMboxIRQAction(pProt->pDev, GMBOX_ERRORS_IRQ_ENABLE, PROC_IO_SYNC);   
-        
-        if (status) {
-            break;   
-        } 
-            /* enable recv */   
-        status = DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_SYNC);
-        
-        if (status) {
-            break;   
-        } 
-            /* signal bridge side to power up BT */
-        status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_ON, BTON_TIMEOUT_MS);
-        
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI_TransportStart : Failed to trigger BT ON \n"));
-            break;   
-        } 
-        
-            /* we made it */
-        pProt->HCIStopped = false;
-        
-    } while (false);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStart \n"));
-    
-    return status;
-}
-
-int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
-    return DevGMboxIRQAction(pProt->pDev, 
-                             Enable ? GMBOX_RECV_IRQ_ENABLE : GMBOX_RECV_IRQ_DISABLE, 
-                             PROC_IO_SYNC);
-                             
-}
-
-int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
-                                       struct htc_packet           *pPacket,
-                                       int                  MaxPollMS)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
-    int              status = 0;
-    u8 lookAhead[8];
-    int                   bytes;
-    int                   totalRecvLength;
-    
-    MaxPollMS = MaxPollMS / 16;
-    
-    if (MaxPollMS < 2) {
-        MaxPollMS = 2;    
-    }
-    
-    while (MaxPollMS) {
-        
-        bytes = sizeof(lookAhead);
-        status = DevGMboxRecvLookAheadPeek(pProt->pDev,lookAhead,&bytes);
-        if (status) {
-            break;    
-        }        
-                
-        if (bytes < 3) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI recv poll got bytes: %d, retry : %d \n",
-                        bytes, MaxPollMS));
-            A_MDELAY(16);
-            MaxPollMS--;        
-            continue;
-        }
-        
-        totalRecvLength = 0;
-        switch (lookAhead[0]) {       
-            case HCI_UART_EVENT_PKT:
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
-                        lookAhead[1], lookAhead[2]));
-                totalRecvLength = lookAhead[2];
-                totalRecvLength += 3; /* add type + event code + length field */
-                break;
-            default:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",lookAhead[0]));
-                status = A_EPROTO;
-                break;
-        }
-        
-        if (status) {
-            break;    
-        }
-        
-        pPacket->Completion = NULL;
-        status = DevGMboxRead(pProt->pDev,pPacket,totalRecvLength); 
-        if (status) {
-            break;    
-        }
-        
-        pPacket->pBuffer++;
-        pPacket->ActualLength = totalRecvLength - 1;
-        pPacket->Status = 0;
-        break; 
-    }
-    
-    if (MaxPollMS == 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI recv poll timeout! \n"));
-        status = A_ERROR;    
-    }
-    
-    return status;
-}
-
-#define LSB_SCRATCH_IDX     4
-#define MSB_SCRATCH_IDX     5
-int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud)
-{
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
-    struct hif_device *pHIFDevice = (struct hif_device *)(pProt->pDev->HIFDevice);
-    u32 scaledBaud, scratchAddr;
-    int status = 0;
-
-    /* Divide the desired baud rate by 100
-     * Store the LSB in the local scratch register 4 and the MSB in the local
-     * scratch register 5 for the target to read
-     */
-    scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * LSB_SCRATCH_IDX);
-    scaledBaud = (Baud / 100) & LOCAL_SCRATCH_VALUE_MASK;
-    status = ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);                     
-    scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * MSB_SCRATCH_IDX);
-    scaledBaud = ((Baud / 100) >> (LOCAL_SCRATCH_VALUE_MSB+1)) & LOCAL_SCRATCH_VALUE_MASK;
-    status |= ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);                     
-    if (0 != status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to set up baud rate in scratch register!"));            
-        return status;
-    }
-
-    /* Now interrupt the target to tell it about the baud rate */
-    status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BAUD_SET, BAUD_TIMEOUT_MS);
-    if (0 != status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to tell target to change baud rate!"));            
-    }
-    
-    return status;
-}
-
-int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable)
-{
-    int status;
-    struct gmbox_proto_hci_uart  *pProt = (struct gmbox_proto_hci_uart *)HciTrans;
-                             
-    if (Enable) {
-        status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON, BTPWRSAV_TIMEOUT_MS);
-    } else {
-        status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF, BTPWRSAV_TIMEOUT_MS);
-    }
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to enable/disable HCI power management!\n"));
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI power management enabled/disabled!\n"));
-    }
-
-    return status;
-}
-
-#endif  //ATH_AR6K_ENABLE_GMBOX
-
diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c
deleted file mode 100644 (file)
index ae54e64..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#include "htc_internal.h"
-
-#ifdef ATH_DEBUG_MODULE
-static struct ath_debug_mask_description g_HTCDebugDescription[] = {
-    { ATH_DEBUG_SEND , "Send"},
-    { ATH_DEBUG_RECV , "Recv"},
-    { ATH_DEBUG_SYNC , "Sync"},
-    { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"},
-    { ATH_DEBUG_IRQ  , "Interrupt Processing"}
-};
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
-                                 "htc",
-                                 "Host Target Communications",
-                                 ATH_DEBUG_MASK_DEFAULTS,
-                                 ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescription),
-                                 g_HTCDebugDescription);
-                                 
-#endif
-
-static void HTCReportFailure(void *Context);
-static void ResetEndpointStates(struct htc_target *target);
-
-void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList)
-{
-    LOCK_HTC(target);
-    HTC_PACKET_ENQUEUE(pList,pPacket);
-    UNLOCK_HTC(target);
-}
-
-struct htc_packet *HTCAllocControlBuffer(struct htc_target *target,  struct htc_packet_queue *pList)
-{
-    struct htc_packet *pPacket;
-
-    LOCK_HTC(target);
-    pPacket = HTC_PACKET_DEQUEUE(pList);
-    UNLOCK_HTC(target);
-
-    return pPacket;
-}
-
-/* cleanup the HTC instance */
-static void HTCCleanup(struct htc_target *target)
-{
-    s32 i;
-
-    DevCleanup(&target->Device);
-    
-    for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
-        if (target->HTCControlBuffers[i].Buffer) {
-            kfree(target->HTCControlBuffers[i].Buffer);
-        }
-    }
-    
-    if (A_IS_MUTEX_VALID(&target->HTCLock)) {
-        A_MUTEX_DELETE(&target->HTCLock);
-    }
-
-    if (A_IS_MUTEX_VALID(&target->HTCRxLock)) {
-        A_MUTEX_DELETE(&target->HTCRxLock);
-    }
-
-    if (A_IS_MUTEX_VALID(&target->HTCTxLock)) {
-        A_MUTEX_DELETE(&target->HTCTxLock);
-    }
-        /* free our instance */
-    kfree(target);
-}
-
-/* registered target arrival callback from the HIF layer */
-HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo)
-{
-    struct htc_target              *target = NULL;
-    int                 status = 0;
-    int                      i;
-    u32 ctrl_bufsz;
-    u32 blocksizes[HTC_MAILBOX_NUM_MAX];
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
-
-    A_REGISTER_MODULE_DEBUG_INFO(htc);
-    
-    do {
-
-            /* allocate target memory */
-        if ((target = (struct htc_target *)A_MALLOC(sizeof(struct htc_target))) == NULL) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
-            status = A_ERROR;
-            break;
-        }
-
-        A_MEMZERO(target, sizeof(struct htc_target));
-        A_MUTEX_INIT(&target->HTCLock);
-        A_MUTEX_INIT(&target->HTCRxLock);
-        A_MUTEX_INIT(&target->HTCTxLock);
-        INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
-        INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);
-        
-            /* give device layer the hif device handle */
-        target->Device.HIFDevice = hif_handle;
-            /* give the device layer our context (for event processing)
-             * the device layer will register it's own context with HIF
-             * so we need to set this so we can fetch it in the target remove handler */
-        target->Device.HTCContext = target;
-            /* set device layer target failure callback */
-        target->Device.TargetFailureCallback = HTCReportFailure;
-            /* set device layer recv message pending callback */
-        target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
-        target->EpWaitingForBuffers = ENDPOINT_MAX;
-
-        memcpy(&target->HTCInitInfo,pInfo,sizeof(struct htc_init_info));
-        
-        ResetEndpointStates(target);
-          
-            /* setup device layer */
-        status = DevSetup(&target->Device);
-
-        if (status) {
-            break;
-        }
-
-
-        /* get the block sizes */
-        status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
-                                    blocksizes, sizeof(blocksizes));
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n"));
-            break;
-        }
-
-        /* Set the control buffer size based on the block size */
-        if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) {
-            ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
-        } else {
-            ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
-        }
-        for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
-            target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);
-            if (target->HTCControlBuffers[i].Buffer == NULL) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
-                status = A_ERROR;
-                break;
-            }
-        }
-
-        if (status) {
-            break;
-        }
-
-            /* carve up buffers/packets for control messages */
-        for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
-            struct htc_packet *pControlPacket;
-            pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
-            SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
-                                          target,
-                                          target->HTCControlBuffers[i].Buffer,
-                                          ctrl_bufsz,
-                                          ENDPOINT_0);
-            HTC_FREE_CONTROL_RX(target,pControlPacket);
-        }
-
-        for (;i < NUM_CONTROL_BUFFERS;i++) {
-             struct htc_packet *pControlPacket;
-             pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
-             INIT_HTC_PACKET_INFO(pControlPacket,
-                                  target->HTCControlBuffers[i].Buffer,
-                                  ctrl_bufsz);
-             HTC_FREE_CONTROL_TX(target,pControlPacket);
-        }
-
-    } while (false);
-
-    if (status) {
-        if (target != NULL) {
-            HTCCleanup(target);
-            target = NULL;
-        }
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));
-
-    return target;
-}
-
-void  HTCDestroy(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy ..  Destroying :0x%lX \n",(unsigned long)target));
-    HTCCleanup(target);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n"));
-}
-
-/* get the low level HIF device for the caller , the caller may wish to do low level
- * HIF requests */
-void *HTCGetHifDevice(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    return target->Device.HIFDevice;
-}
-
-/* wait for the target to arrive (sends HTC Ready message)
- * this operation is fully synchronous and the message is polled for */
-int HTCWaitTarget(HTC_HANDLE HTCHandle)
-{
-    struct htc_target              *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    int                 status;
-    struct htc_packet              *pPacket = NULL;
-    HTC_READY_EX_MSG        *pRdyMsg;
-
-    struct htc_service_connect_req  connect;
-    struct htc_service_connect_resp resp;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target));
-
-    do {
-
-#ifdef MBOXHW_UNIT_TEST
-
-        status = DoMboxHWTest(&target->Device);
-
-        if (status) {
-            break;
-        }
-
-#endif
-
-            /* we should be getting 1 control message that the target is ready */
-        status = HTCWaitforControlMessage(target, &pPacket);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
-            break;
-        }
-
-            /* we controlled the buffer creation so it has to be properly aligned */
-        pRdyMsg = (HTC_READY_EX_MSG *)pPacket->pBuffer;
-
-        if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) ||
-            (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
-                /* this message is not valid */
-            AR_DEBUG_ASSERT(false);
-            status = A_EPROTO;
-            break;
-        }
-
-        
-        if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Info.CreditSize == 0) {
-              /* this message is not valid */
-            AR_DEBUG_ASSERT(false);
-            status = A_EPROTO;
-            break;
-        }
-
-        target->TargetCredits = pRdyMsg->Version2_0_Info.CreditCount;
-        target->TargetCreditSize = pRdyMsg->Version2_0_Info.CreditSize;
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, (" Target Ready: credits: %d credit size: %d\n",
-                target->TargetCredits, target->TargetCreditSize));
-        
-            /* check if this is an extended ready message */        
-        if (pPacket->ActualLength >= sizeof(HTC_READY_EX_MSG)) {
-                /* this is an extended message */    
-            target->HTCTargetVersion = pRdyMsg->HTCVersion;   
-            target->MaxMsgPerBundle = pRdyMsg->MaxMsgsPerHTCBundle;     
-        } else {
-                /* legacy */
-            target->HTCTargetVersion = HTC_VERSION_2P0;
-            target->MaxMsgPerBundle = 0;    
-        }
-        
-#ifdef HTC_FORCE_LEGACY_2P0   
-            /* for testing and comparison...*/     
-        target->HTCTargetVersion = HTC_VERSION_2P0;
-        target->MaxMsgPerBundle = 0;
-#endif
-           
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
-                    ("Using HTC Protocol Version : %s (%d)\n ", 
-                    (target->HTCTargetVersion == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
-                    target->HTCTargetVersion));
-                    
-        if (target->MaxMsgPerBundle > 0) {
-                /* limit what HTC can handle */
-            target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->MaxMsgPerBundle);          
-                /* target supports message bundling, setup device layer */
-            if (DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle)) {
-                    /* device layer can't handle bundling */
-                target->MaxMsgPerBundle = 0;        
-            } else {
-                    /* limit bundle what the device layer can handle */
-                target->MaxMsgPerBundle = min(DEV_GET_MAX_MSG_PER_BUNDLE(&target->Device),
-                                              target->MaxMsgPerBundle);     
-            }
-        }
-        
-        if (target->MaxMsgPerBundle > 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_TRC, 
-                    (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", target->MaxMsgPerBundle));    
-           
-            if (DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device) != 0) {           
-                target->SendBundlingEnabled = true;
-            }            
-            if (DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device) != 0) {    
-                target->RecvBundlingEnabled = true;
-            }
-                            
-            if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSize)) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("*** Credit size: %d is not block aligned! Disabling send bundling \n",
-                        target->TargetCreditSize));    
-                    /* disallow send bundling since the credit size is not aligned to a block size
-                     * the I/O block padding will spill into the next credit buffer which is fatal */
-                target->SendBundlingEnabled = false;
-            }
-        }
-           
-            /* setup our pseudo HTC control endpoint connection */
-        A_MEMZERO(&connect,sizeof(connect));
-        A_MEMZERO(&resp,sizeof(resp));
-        connect.EpCallbacks.pContext = target;
-        connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
-        connect.EpCallbacks.EpRecv = HTCControlRecv;
-        connect.EpCallbacks.EpRecvRefill = NULL;  /* not needed */
-        connect.EpCallbacks.EpSendFull = NULL;    /* not nedded */
-        connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
-        connect.ServiceID = HTC_CTRL_RSVD_SVC;
-
-            /* connect fake service */
-        status = HTCConnectService((HTC_HANDLE)target,
-                                   &connect,
-                                   &resp);
-
-        if (!status) {
-            break;
-        }
-
-    } while (false);
-
-    if (pPacket != NULL) {
-        HTC_FREE_CONTROL_RX(target,pPacket);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));
-
-    return status;
-}
-
-
-
-/* Start HTC, enable interrupts and let the target know host has finished setup */
-int HTCStart(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    struct htc_packet *pPacket;
-    int   status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
-
-        /* make sure interrupts are disabled at the chip level,
-         * this function can be called again from a reboot of the target without shutting down HTC */
-    DevDisableInterrupts(&target->Device);
-        /* make sure state is cleared again */
-    target->OpStateFlags = 0;
-    target->RecvStateFlags = 0;
-      
-        /* now that we are starting, push control receive buffers into the
-         * HTC control endpoint */
-
-    while (1) {
-        pPacket = HTC_ALLOC_CONTROL_RX(target);
-        if (NULL == pPacket) {
-            break;
-        }
-        HTCAddReceivePkt((HTC_HANDLE)target,pPacket);
-    }
-
-    do {
-
-        AR_DEBUG_ASSERT(target->InitCredits != NULL);
-        AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL);
-        AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL);
-
-            /* call init credits callback to do the distribution ,
-             * NOTE: the first entry in the distribution list is ENDPOINT_0, so
-             * we pass the start of the list after this one. */
-        target->InitCredits(target->pCredDistContext,
-                            target->EpCreditDistributionListHead->pNext,
-                            target->TargetCredits);
-
-#ifdef ATH_DEBUG_MODULE
-
-        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
-            DumpCreditDistStates(target);
-        }
-#endif
-
-            /* the caller is done connecting to services, so we can indicate to the
-            * target that the setup phase is complete */
-        status = HTCSendSetupComplete(target);
-
-        if (status) {
-            break;
-        }
-
-            /* unmask interrupts */
-        status = DevUnmaskInterrupts(&target->Device);
-
-        if (status) {
-            HTCStop(target);
-        }
-
-    } while (false);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
-    return status;
-}
-
-static void ResetEndpointStates(struct htc_target *target)
-{
-    struct htc_endpoint        *pEndpoint;
-    int                  i;
-
-    for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
-        pEndpoint = &target->EndPoint[i];
-        
-        A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist));
-        pEndpoint->ServiceID = 0;
-        pEndpoint->MaxMsgLength = 0;
-        pEndpoint->MaxTxQueueDepth = 0;
-        A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
-        INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
-        INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
-        INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue);
-        pEndpoint->target = target;
-    }
-        /* reset distribution list */
-    target->EpCreditDistributionListHead = NULL;
-}
-
-/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
-void HTCStop(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));
-
-    LOCK_HTC(target);
-        /* mark that we are shutting down .. */
-    target->OpStateFlags |= HTC_OP_STATE_STOPPING;
-    UNLOCK_HTC(target);
-    
-        /* Masking interrupts is a synchronous operation, when this function returns
-         * all pending HIF I/O has completed, we can safely flush the queues */
-    DevMaskInterrupts(&target->Device);
-
-#ifdef THREAD_X
-       //
-       //      Is this delay required
-       //
-    A_MDELAY(200); // wait for IRQ process done
-#endif
-        /* flush all send packets */
-    HTCFlushSendPkts(target);
-        /* flush all recv buffers */
-    HTCFlushRecvBuffers(target);
-
-    DevCleanupMsgBundling(&target->Device);
-
-    ResetEndpointStates(target);
-   
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
-}
-
-#ifdef ATH_DEBUG_MODULE
-void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-
-    LOCK_HTC_TX(target);
-
-    DumpCreditDistStates(target);
-
-    UNLOCK_HTC_TX(target);
-    
-    DumpAR6KDevState(&target->Device);
-}
-#endif
-/* report a target failure from the device, this is a callback from the device layer
- * which uses a mechanism to report errors from the target (i.e. special interrupts) */
-static void HTCReportFailure(void *Context)
-{
-    struct htc_target *target = (struct htc_target *)Context;
-
-    target->TargetFailure = true;
-
-    if (target->HTCInitInfo.TargetFailure != NULL) {
-            /* let upper layer know, it needs to call HTCStop() */
-        target->HTCInitInfo.TargetFailure(target->HTCInitInfo.pContext, A_ERROR);
-    }
-}
-
-bool HTCGetEndpointStatistics(HTC_HANDLE               HTCHandle,
-                                HTC_ENDPOINT_ID          Endpoint,
-                                HTC_ENDPOINT_STAT_ACTION Action,
-                                struct htc_endpoint_stats       *pStats)
-{
-
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    bool     clearStats = false;
-    bool     sample = false;
-
-    switch (Action) {
-        case HTC_EP_STAT_SAMPLE :
-            sample = true;
-            break;
-        case HTC_EP_STAT_SAMPLE_AND_CLEAR :
-            sample = true;
-            clearStats = true;
-            break;
-        case HTC_EP_STAT_CLEAR :
-            clearStats = true;
-            break;
-        default:
-            break;
-    }
-
-    A_ASSERT(Endpoint < ENDPOINT_MAX);
-
-        /* lock out TX and RX while we sample and/or clear */
-    LOCK_HTC_TX(target);
-    LOCK_HTC_RX(target);
-
-    if (sample) {
-        A_ASSERT(pStats != NULL);
-            /* return the stats to the caller */
-        memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats));
-    }
-
-    if (clearStats) {
-            /* reset stats */
-        A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats));
-    }
-
-    UNLOCK_HTC_RX(target);
-    UNLOCK_HTC_TX(target);
-
-    return true;
-}
-
-struct ar6k_device  *HTCGetAR6KDevice(void *HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    return &target->Device;
-}
-
diff --git a/drivers/staging/ath6kl/htc2/htc_debug.h b/drivers/staging/ath6kl/htc2/htc_debug.h
deleted file mode 100644 (file)
index 8455703..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_debug.h" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef HTC_DEBUG_H_
-#define HTC_DEBUG_H_
-
-#define ATH_MODULE_NAME htc
-#include "a_debug.h"
-
-/* ------- Debug related stuff ------- */
-
-#define  ATH_DEBUG_SEND ATH_DEBUG_MAKE_MODULE_MASK(0)
-#define  ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(1)
-#define  ATH_DEBUG_SYNC ATH_DEBUG_MAKE_MODULE_MASK(2)
-#define  ATH_DEBUG_DUMP ATH_DEBUG_MAKE_MODULE_MASK(3)
-#define  ATH_DEBUG_IRQ  ATH_DEBUG_MAKE_MODULE_MASK(4)
-
-
-#endif /*HTC_DEBUG_H_*/
diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h
deleted file mode 100644 (file)
index cac9735..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_internal.h" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HTC_INTERNAL_H_
-#define _HTC_INTERNAL_H_
-
-/* for debugging, uncomment this to capture the last frame header, on frame header
- * processing errors, the last frame header is dump for comparison */
-//#define HTC_CAPTURE_LAST_FRAME
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Header files */
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#include "htc_debug.h"
-#include "htc.h"
-#include "htc_api.h"
-#include "bmi_msg.h"
-#include "hif.h"
-#include "AR6000/ar6k.h"
-
-/* HTC operational parameters */
-#define HTC_TARGET_RESPONSE_TIMEOUT        2000 /* in ms */
-#define HTC_TARGET_DEBUG_INTR_MASK         0x01
-#define HTC_TARGET_CREDIT_INTR_MASK        0xF0
-
-#define HTC_HOST_MAX_MSG_PER_BUNDLE        8
-#define HTC_MIN_HTC_MSGS_TO_BUNDLE         2
-
-/* packet flags */
-
-#define HTC_RX_PKT_IGNORE_LOOKAHEAD      (1 << 0)
-#define HTC_RX_PKT_REFRESH_HDR           (1 << 1)
-#define HTC_RX_PKT_PART_OF_BUNDLE        (1 << 2)
-#define HTC_RX_PKT_NO_RECYCLE            (1 << 3)
-
-/* scatter request flags */
-
-#define HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE  (1 << 0)
-
-struct htc_endpoint {
-    HTC_ENDPOINT_ID             Id;
-    HTC_SERVICE_ID              ServiceID;      /* service ID this endpoint is bound to
-                                                   non-zero value means this endpoint is in use */
-    struct htc_packet_queue            TxQueue;        /* HTC frame buffer TX queue */
-    struct htc_packet_queue            RxBuffers;      /* HTC frame buffer RX list */
-    struct htc_endpoint_credit_dist    CreditDist;     /* credit distribution structure (exposed to driver layer) */
-    struct htc_ep_callbacks            EpCallBacks;    /* callbacks associated with this endpoint */
-    int                         MaxTxQueueDepth;   /* max depth of the TX queue before we need to
-                                                      call driver's full handler */
-    int                         MaxMsgLength;        /* max length of endpoint message */
-    int                         TxProcessCount;  /* reference count to continue tx processing */
-    struct htc_packet_queue            RecvIndicationQueue;    /* recv packets ready to be indicated */
-    int                         RxProcessCount;         /* reference count to allow single processing context */
-    struct htc_target           *target;                /* back pointer to target */
-    u8 SeqNo;                  /* TX seq no (helpful) for debugging */
-    u32 LocalConnectionFlags;   /* local connection flags */
-    struct htc_endpoint_stats          EndPointStats;          /* endpoint statistics */
-};
-
-#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count);
-#define HTC_SERVICE_TX_PACKET_TAG  HTC_TX_PACKET_TAG_INTERNAL
-
-#define NUM_CONTROL_BUFFERS     8
-#define NUM_CONTROL_TX_BUFFERS  2
-#define NUM_CONTROL_RX_BUFFERS  (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
-
-struct htc_control_buffer {
-    struct htc_packet    HtcPacket;
-    u8 *Buffer;
-};
-
-#define HTC_RECV_WAIT_BUFFERS        (1 << 0)
-#define HTC_OP_STATE_STOPPING        (1 << 0)
-
-/* our HTC target state */
-struct htc_target {
-    struct htc_endpoint                EndPoint[ENDPOINT_MAX];
-    struct htc_control_buffer          HTCControlBuffers[NUM_CONTROL_BUFFERS];
-    struct htc_endpoint_credit_dist   *EpCreditDistributionListHead;
-    struct htc_packet_queue            ControlBufferTXFreeList;
-    struct htc_packet_queue            ControlBufferRXFreeList;
-    HTC_CREDIT_DIST_CALLBACK    DistributeCredits;
-    HTC_CREDIT_INIT_CALLBACK    InitCredits;
-    void                       *pCredDistContext;
-    int                         TargetCredits;
-    unsigned int                TargetCreditSize;
-    A_MUTEX_T                   HTCLock;
-    A_MUTEX_T                   HTCRxLock;
-    A_MUTEX_T                   HTCTxLock;
-    struct ar6k_device                 Device;         /* AR6K - specific state */
-    u32 OpStateFlags;
-    u32 RecvStateFlags;
-    HTC_ENDPOINT_ID             EpWaitingForBuffers;
-    bool                      TargetFailure;
-#ifdef HTC_CAPTURE_LAST_FRAME
-    struct htc_frame_hdr               LastFrameHdr;  /* useful for debugging */
-    u8 LastTrailer[256];
-    u8 LastTrailerLength;
-#endif
-    struct htc_init_info               HTCInitInfo;
-    u8 HTCTargetVersion;
-    int                         MaxMsgPerBundle;       /* max messages per bundle for HTC */
-    bool                      SendBundlingEnabled;   /* run time enable for send bundling (dynamic) */
-    int                         RecvBundlingEnabled;   /* run time enable for recv bundling (dynamic) */
-};
-
-#define HTC_STOPPING(t) ((t)->OpStateFlags & HTC_OP_STATE_STOPPING)
-#define LOCK_HTC(t)      A_MUTEX_LOCK(&(t)->HTCLock);
-#define UNLOCK_HTC(t)    A_MUTEX_UNLOCK(&(t)->HTCLock);
-#define LOCK_HTC_RX(t)   A_MUTEX_LOCK(&(t)->HTCRxLock);
-#define UNLOCK_HTC_RX(t) A_MUTEX_UNLOCK(&(t)->HTCRxLock);
-#define LOCK_HTC_TX(t)   A_MUTEX_LOCK(&(t)->HTCTxLock);
-#define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock);
-
-#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((struct htc_target *)(hnd))
-#define HTC_RECYCLE_RX_PKT(target,p,e)                           \
-{                                                                \
-    if ((p)->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_NO_RECYCLE) {  \
-         HTC_PACKET_RESET_RX(pPacket);                           \
-         pPacket->Status = A_ECANCELED;                          \
-         (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext,      \
-                                 (p));                           \
-    } else {                                                     \
-        HTC_PACKET_RESET_RX(pPacket);                            \
-        HTCAddReceivePkt((HTC_HANDLE)(target),(p));              \
-    }                                                            \
-}
-
-/* internal HTC functions */
-void        HTCControlTxComplete(void *Context, struct htc_packet *pPacket);
-void        HTCControlRecv(void *Context, struct htc_packet *pPacket);
-int    HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket);
-struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList);
-void        HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList);
-int    HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket);
-void        HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket);
-int    HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched);
-void        HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
-int    HTCSendSetupComplete(struct htc_target *target);
-void        HTCFlushRecvBuffers(struct htc_target *target);
-void        HTCFlushSendPkts(struct htc_target *target);
-
-#ifdef ATH_DEBUG_MODULE
-void        DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist);
-void        DumpCreditDistStates(struct htc_target *target);
-void           DebugDumpBytes(u8 *buffer, u16 length, char *pDescription);
-#endif
-
-static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(struct htc_target *target) {
-    struct htc_packet *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList);
-    if (pPacket != NULL) {
-            /* set payload pointer area with some headroom */
-        pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH;
-    }
-    return pPacket;
-}
-
-#define HTC_FREE_CONTROL_TX(t,p) HTCFreeControlBuffer((t),(p),&(t)->ControlBufferTXFreeList)
-#define HTC_ALLOC_CONTROL_RX(t)  HTCAllocControlBuffer((t),&(t)->ControlBufferRXFreeList)
-#define HTC_FREE_CONTROL_RX(t,p) \
-{                                                                \
-    HTC_PACKET_RESET_RX(p);                                      \
-    HTCFreeControlBuffer((t),(p),&(t)->ControlBufferRXFreeList); \
-}
-
-#define HTC_PREPARE_SEND_PKT(pP,sendflags,ctrl0,ctrl1)       \
-{                                                   \
-    u8 *pHdrBuf;                               \
-    (pP)->pBuffer -= HTC_HDR_LENGTH;                \
-    pHdrBuf = (pP)->pBuffer;                        \
-    A_SET_UINT16_FIELD(pHdrBuf,struct htc_frame_hdr,PayloadLen,(u16)(pP)->ActualLength);  \
-    A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,Flags,(sendflags));                         \
-    A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,EndpointID, (u8)(pP)->Endpoint); \
-    A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[0], (u8)(ctrl0));   \
-    A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[1], (u8)(ctrl1));   \
-}
-
-#define HTC_UNPREPARE_SEND_PKT(pP)     \
-    (pP)->pBuffer += HTC_HDR_LENGTH;   \
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HTC_INTERNAL_H_ */
diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c
deleted file mode 100644 (file)
index 974cc8c..0000000
+++ /dev/null
@@ -1,1572 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_recv.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#include "htc_internal.h"
-
-#define HTCIssueRecv(t, p) \
-    DevRecvPacket(&(t)->Device,  \
-                  (p),          \
-                  (p)->ActualLength)
-
-#define DO_RCV_COMPLETION(e,q)  DoRecvCompletion(e,q)
-
-#define DUMP_RECV_PKT_INFO(pP) \
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC RECV packet 0x%lX (%d bytes) (hdr:0x%X) on ep : %d \n", \
-                        (unsigned long)(pP),                   \
-                        (pP)->ActualLength,                    \
-                        (pP)->PktInfo.AsRx.ExpectedHdr,        \
-                        (pP)->Endpoint))                         
-                        
-#define HTC_RX_STAT_PROFILE(t,ep,numLookAheads)        \
-{                                                      \
-    INC_HTC_EP_STAT((ep), RxReceived, 1);              \
-    if ((numLookAheads) == 1) {                        \
-        INC_HTC_EP_STAT((ep), RxLookAheads, 1);        \
-    } else if ((numLookAheads) > 1) {                  \
-        INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1);  \
-    }                                                  \
-}
-
-static void DoRecvCompletion(struct htc_endpoint     *pEndpoint,
-                             struct htc_packet_queue *pQueueToIndicate)
-{           
-    
-    do {
-        
-        if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
-                /* nothing to indicate */
-            break;    
-        }
-        if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) {    
-            AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n",
-                     pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
-                /* a recv multiple handler is being used, pass the queue to the handler */                             
-            pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext,
-                                                     pQueueToIndicate);
-            INIT_HTC_PACKET_QUEUE(pQueueToIndicate);        
-        } else {
-            struct htc_packet *pPacket;  
-            /* using legacy EpRecv */         
-            do {
-                pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet 0x%lX \n", \
-                        pEndpoint->Id, (unsigned long)(pPacket)));
-                pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);                                              
-            } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));                                              
-        }
-        
-    } while (false);
-
-}
-
-static INLINE int HTCProcessTrailer(struct htc_target *target,
-                                         u8 *pBuffer,
-                                         int         Length,
-                                         u32 *pNextLookAheads,
-                                         int        *pNumLookAheads,
-                                         HTC_ENDPOINT_ID FromEndpoint)
-{
-    HTC_RECORD_HDR          *pRecord;
-    u8 *pRecordBuf;
-    HTC_LOOKAHEAD_REPORT    *pLookAhead;
-    u8 *pOrigBuffer;
-    int                     origLength;
-    int                status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length));
-
-    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
-        AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer");
-    }
-
-    pOrigBuffer = pBuffer;
-    origLength = Length;
-    status = 0;
-    
-    while (Length > 0) {
-
-        if (Length < sizeof(HTC_RECORD_HDR)) {
-            status = A_EPROTO;
-            break;
-        }
-            /* these are byte aligned structs */
-        pRecord = (HTC_RECORD_HDR *)pBuffer;
-        Length -= sizeof(HTC_RECORD_HDR);
-        pBuffer += sizeof(HTC_RECORD_HDR);
-
-        if (pRecord->Length > Length) {
-                /* no room left in buffer for record */
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                (" invalid record length: %d (id:%d) buffer has: %d bytes left \n",
-                        pRecord->Length, pRecord->RecordID, Length));
-            status = A_EPROTO;
-            break;
-        }
-            /* start of record follows the header */
-        pRecordBuf = pBuffer;
-
-        switch (pRecord->RecordID) {
-            case HTC_RECORD_CREDITS:
-                AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_CREDIT_REPORT));
-                HTCProcessCreditRpt(target,
-                                    (HTC_CREDIT_REPORT *)pRecordBuf,
-                                    pRecord->Length / (sizeof(HTC_CREDIT_REPORT)),
-                                    FromEndpoint);
-                break;
-            case HTC_RECORD_LOOKAHEAD:
-                AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT));
-                pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf;
-                if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) &&
-                    (pNextLookAheads != NULL)) {
-
-                    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                                (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n",
-                                pLookAhead->PreValid,
-                                pLookAhead->PostValid));
-
-                        /* look ahead bytes are valid, copy them over */
-                    ((u8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0];
-                    ((u8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1];
-                    ((u8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2];
-                    ((u8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3];
-
-#ifdef ATH_DEBUG_MODULE
-                    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
-                        DebugDumpBytes((u8 *)pNextLookAheads,4,"Next Look Ahead");
-                    }
-#endif
-                        /* just one normal lookahead */
-                    *pNumLookAheads = 1;
-                }
-                break;
-            case HTC_RECORD_LOOKAHEAD_BUNDLE:
-                AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT));
-                if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) &&
-                    (pNextLookAheads != NULL)) {                   
-                    HTC_BUNDLED_LOOKAHEAD_REPORT    *pBundledLookAheadRpt;
-                    int                             i;
-                    
-                    pBundledLookAheadRpt = (HTC_BUNDLED_LOOKAHEAD_REPORT *)pRecordBuf;
-                    
-#ifdef ATH_DEBUG_MODULE
-                    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
-                        DebugDumpBytes(pRecordBuf,pRecord->Length,"Bundle LookAhead");
-                    }
-#endif
-                    
-                    if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) >
-                            HTC_HOST_MAX_MSG_PER_BUNDLE) {
-                            /* this should never happen, the target restricts the number
-                             * of messages per bundle configured by the host */        
-                        A_ASSERT(false);
-                        status = A_EPROTO;
-                        break;        
-                    }
-                                         
-                    for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
-                        ((u8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0];
-                        ((u8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1];
-                        ((u8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2];
-                        ((u8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3];
-                        pBundledLookAheadRpt++;
-                    }
-                    
-                    *pNumLookAheads = i;
-                }               
-                break;
-            default:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n",
-                        pRecord->RecordID, pRecord->Length));
-                break;
-        }
-
-        if (status) {
-            break;
-        }
-
-            /* advance buffer past this record for next time around */
-        pBuffer += pRecord->Length;
-        Length -= pRecord->Length;
-    }
-
-#ifdef ATH_DEBUG_MODULE
-    if (status) {
-        DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer");
-    }
-#endif
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n"));
-    return status;
-
-}
-
-/* process a received message (i.e. strip off header, process any trailer data)
- * note : locks must be released when this function is called */
-static int HTCProcessRecvHeader(struct htc_target *target,
-                                     struct htc_packet *pPacket, 
-                                     u32 *pNextLookAheads,
-                                     int        *pNumLookAheads)
-{
-    u8 temp;
-    u8 *pBuf;
-    int  status = 0;
-    u16 payloadLen;
-    u32 lookAhead;
-
-    pBuf = pPacket->pBuffer;
-    
-    if (pNumLookAheads != NULL) {
-        *pNumLookAheads = 0;
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n"));
-
-    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
-        AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT");
-    }
-
-    do {
-        /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to
-         * retrieve 16 bit fields */
-        payloadLen = A_GET_UINT16_FIELD(pBuf, struct htc_frame_hdr, PayloadLen);
-        
-        ((u8 *)&lookAhead)[0] = pBuf[0];
-        ((u8 *)&lookAhead)[1] = pBuf[1];
-        ((u8 *)&lookAhead)[2] = pBuf[2];
-        ((u8 *)&lookAhead)[3] = pBuf[3];
-
-        if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) {
-                /* refresh expected hdr, since this was unknown at the time we grabbed the packets
-                 * as part of a bundle */
-            pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
-                /* refresh actual length since we now have the real header */
-            pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH;
-            
-                /* validate the actual header that was refreshed  */ 
-            if (pPacket->ActualLength > pPacket->BufferLength) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n", 
-                    payloadLen, lookAhead));
-                    /* limit this to max buffer just to print out some of the buffer */    
-                pPacket->ActualLength = min(pPacket->ActualLength, pPacket->BufferLength);
-                status = A_EPROTO;
-                break;    
-            }
-            
-            if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID)) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n", 
-                    A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID), pPacket->Endpoint));
-                status = A_EPROTO;
-                break;      
-            }   
-        }
-                
-        if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) {
-            /* somehow the lookahead that gave us the full read length did not
-             * reflect the actual header in the pending message */
-             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("HTCProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X) \n", 
-                        (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags));
-#ifdef ATH_DEBUG_MODULE
-             DebugDumpBytes((u8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead");
-             DebugDumpBytes(pBuf,sizeof(struct htc_frame_hdr),"Current Frame Header");
-#ifdef HTC_CAPTURE_LAST_FRAME
-            DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(struct htc_frame_hdr),"Last Frame Header");
-            if (target->LastTrailerLength != 0) {
-                DebugDumpBytes(target->LastTrailer,
-                               target->LastTrailerLength,
-                               "Last trailer");
-            }
-#endif
-#endif
-            status = A_EPROTO;
-            break;
-        }
-
-            /* get flags */
-        temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, Flags);
-
-        if (temp & HTC_FLAGS_RECV_TRAILER) {
-            /* this packet has a trailer */
-
-                /* extract the trailer length in control byte 0 */
-            temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, ControlBytes[0]);
-
-            if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n",
-                        payloadLen, temp));
-                status = A_EPROTO;
-                break;
-            }
-
-            if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
-                    /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
-                     * not valid since the next packet may have already been fetched as part of the
-                     * bundle */
-                pNextLookAheads = NULL;   
-                pNumLookAheads = NULL;     
-            }
-            
-                /* process trailer data that follows HDR + application payload */
-            status = HTCProcessTrailer(target,
-                                       (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
-                                       temp,
-                                       pNextLookAheads,
-                                       pNumLookAheads,
-                                       pPacket->Endpoint);
-
-            if (status) {
-                break;
-            }
-
-#ifdef HTC_CAPTURE_LAST_FRAME
-            memcpy(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp);
-            target->LastTrailerLength = temp;
-#endif
-                /* trim length by trailer bytes */
-            pPacket->ActualLength -= temp;
-        }
-#ifdef HTC_CAPTURE_LAST_FRAME
-         else {
-            target->LastTrailerLength = 0;
-        }
-#endif
-
-            /* if we get to this point, the packet is good */
-            /* remove header and adjust length */
-        pPacket->pBuffer += HTC_HDR_LENGTH;
-        pPacket->ActualLength -= HTC_HDR_LENGTH;
-
-    } while (false);
-
-    if (status) {
-            /* dump the whole packet */
-#ifdef ATH_DEBUG_MODULE
-        DebugDumpBytes(pBuf,pPacket->ActualLength < 256 ? pPacket->ActualLength : 256 ,"BAD HTC Recv PKT");
-#endif
-    } else {
-#ifdef HTC_CAPTURE_LAST_FRAME
-        memcpy(&target->LastFrameHdr,pBuf,sizeof(struct htc_frame_hdr));
-#endif
-        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
-            if (pPacket->ActualLength > 0) {
-                AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg");
-            }
-        }
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessRecvHeader \n"));
-    return status;
-}
-
-static INLINE void HTCAsyncRecvCheckMorePackets(struct htc_target  *target, 
-                                                u32 NextLookAheads[],
-                                                int         NumLookAheads,
-                                                bool      CheckMoreMsgs)
-{
-        /* was there a lookahead for the next packet? */
-    if (NumLookAheads > 0) {
-        int nextStatus;
-        int      fetched = 0;
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                        ("HTCAsyncRecvCheckMorePackets - num lookaheads were non-zero : %d \n",
-                         NumLookAheads));
-            /* force status re-check */                    
-        REF_IRQ_STATUS_RECHECK(&target->Device);
-            /* we have more packets, get the next packet fetch started */
-        nextStatus = HTCRecvMessagePendingHandler(target, NextLookAheads, NumLookAheads, NULL, &fetched);
-        if (A_EPROTO == nextStatus) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("Next look ahead from recv header was INVALID\n"));
-#ifdef ATH_DEBUG_MODULE
-            DebugDumpBytes((u8 *)NextLookAheads,
-                            NumLookAheads * (sizeof(u32)),
-                            "BAD lookaheads from lookahead report");
-#endif
-        }
-        if (!nextStatus && !fetched) {
-                /* we could not fetch any more packets due to resources */
-            DevAsyncIrqProcessComplete(&target->Device);        
-        }
-    } else {
-        if (CheckMoreMsgs) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("HTCAsyncRecvCheckMorePackets - rechecking for more messages...\n"));
-            /* if we did not get anything on the look-ahead,
-             * call device layer to asynchronously re-check for messages. If we can keep the async
-             * processing going we get better performance.  If there is a pending message we will keep processing
-             * messages asynchronously which should pipeline things nicely */
-            DevCheckPendingRecvMsgsAsync(&target->Device);
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCAsyncRecvCheckMorePackets - no check \n"));    
-        }
-    }
-    
-     
-}      
-
-    /* unload the recv completion queue */
-static INLINE void DrainRecvIndicationQueue(struct htc_target *target, struct htc_endpoint *pEndpoint)
-{
-    struct htc_packet_queue     recvCompletions;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DrainRecvIndicationQueue \n"));
-                
-    INIT_HTC_PACKET_QUEUE(&recvCompletions);
-    
-    LOCK_HTC_RX(target);
-    
-            /* increment rx processing count on entry */    
-    pEndpoint->RxProcessCount++;
-    if (pEndpoint->RxProcessCount > 1) {
-         pEndpoint->RxProcessCount--;
-            /* another thread or task is draining the RX completion queue on this endpoint
-             * that thread will reset the rx processing count when the queue is drained */
-         UNLOCK_HTC_RX(target);
-         return;
-    }
-    
-    /******* at this point only 1 thread may enter ******/
-     
-    while (true) {
-                
-            /* transfer items from main recv queue to the local one so we can release the lock */ 
-        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&recvCompletions, &pEndpoint->RecvIndicationQueue);
-            
-        if (HTC_QUEUE_EMPTY(&recvCompletions)) {
-                /* all drained */
-            break;    
-        }
-        
-            /* release lock while we do the recv completions 
-             * other threads can now queue more recv completions */
-        UNLOCK_HTC_RX(target);
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV, 
-                ("DrainRecvIndicationQueue : completing %d RECV packets \n",
-                                        HTC_PACKET_QUEUE_DEPTH(&recvCompletions)));
-            /* do completion */
-        DO_RCV_COMPLETION(pEndpoint,&recvCompletions);     
-              
-            /* re-acquire lock to grab some more completions */
-        LOCK_HTC_RX(target);    
-    }
-    
-        /* reset count */
-    pEndpoint->RxProcessCount = 0;       
-    UNLOCK_HTC_RX(target);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-DrainRecvIndicationQueue \n"));
-  
-}
-
-    /* optimization for recv packets, we can indicate a "hint" that there are more
-     * single-packets to fetch on this endpoint */
-#define SET_MORE_RX_PACKET_INDICATION_FLAG(L,N,E,P) \
-    if ((N) > 0) { SetRxPacketIndicationFlags((L)[0],(E),(P)); }
-
-    /* for bundled frames, we can force the flag to indicate there are more packets */
-#define FORCE_MORE_RX_PACKET_INDICATION_FLAG(P) \
-    (P)->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS; 
-   
-   /* note: this function can be called with the RX lock held */     
-static INLINE void SetRxPacketIndicationFlags(u32 LookAhead,
-                                              struct htc_endpoint  *pEndpoint, 
-                                              struct htc_packet    *pPacket)
-{
-    struct htc_frame_hdr *pHdr = (struct htc_frame_hdr *)&LookAhead;
-        /* check to see if the "next" packet is from the same endpoint of the
-           completing packet */
-    if (pHdr->EndpointID == pPacket->Endpoint) {
-            /* check that there is a buffer available to actually fetch it */
-        if (!HTC_QUEUE_EMPTY(&pEndpoint->RxBuffers)) {                        
-                /* provide a hint that there are more RX packets to fetch */
-            FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);        
-        }             
-    }                  
-}
-
-     
-/* asynchronous completion handler for recv packet fetching, when the device layer
- * completes a read request, it will call this completion handler */
-void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct htc_target      *target = (struct htc_target *)Context;
-    struct htc_endpoint    *pEndpoint;
-    u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
-    int             numLookAheads = 0;
-    int        status;
-    bool          checkMorePkts = true;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n",
-                (unsigned long)pPacket, pPacket->Status, pPacket->Endpoint));
-
-    A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
-    AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
-    pEndpoint = &target->EndPoint[pPacket->Endpoint];
-    pPacket->Completion = NULL;
-
-        /* get completion status */
-    status = pPacket->Status;
-
-    do {
-        
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n",
-                pPacket->Status, pPacket->Endpoint));
-            break;
-        }
-            /* process the header for any trailer data */
-        status = HTCProcessRecvHeader(target,pPacket,nextLookAheads,&numLookAheads);
-
-        if (status) {
-            break;
-        }
-        
-        if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
-                /* this packet was part of a bundle that had to be broken up. 
-                 * It was fetched one message at a time.  There may be other asynchronous reads queued behind this one.
-                 * Do no issue another check for more packets since the last one in the series of requests
-                 * will handle it */
-            checkMorePkts = false;
-        }
-          
-        DUMP_RECV_PKT_INFO(pPacket);    
-        LOCK_HTC_RX(target);
-        SET_MORE_RX_PACKET_INDICATION_FLAG(nextLookAheads,numLookAheads,pEndpoint,pPacket);
-            /* we have a good packet, queue it to the completion queue */
-        HTC_PACKET_ENQUEUE(&pEndpoint->RecvIndicationQueue,pPacket);
-        HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
-        UNLOCK_HTC_RX(target);     
-       
-            /* check for more recv packets before indicating */
-        HTCAsyncRecvCheckMorePackets(target,nextLookAheads,numLookAheads,checkMorePkts);
-
-    } while (false);
-
-    if (status) {
-         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                         ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n",
-                         status));
-            /* recycle this packet */
-        HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
-    } else {
-            /* a good packet was queued, drain the queue */
-        DrainRecvIndicationQueue(target,pEndpoint);     
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvCompleteHandler\n"));
-}
-
-/* synchronously wait for a control message from the target,
- * This function is used at initialization time ONLY.  At init messages
- * on ENDPOINT 0 are expected. */
-int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket)
-{
-    int        status;
-    u32 lookAhead;
-    struct htc_packet      *pPacket = NULL;
-    struct htc_frame_hdr   *pHdr;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n"));
-
-    do  {
-
-        *ppControlPacket = NULL;
-
-            /* call the polling function to see if we have a message */
-        status = DevPollMboxMsgRecv(&target->Device,
-                                    &lookAhead,
-                                    HTC_TARGET_RESPONSE_TIMEOUT);
-
-        if (status) {
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead));
-
-            /* check the lookahead */
-        pHdr = (struct htc_frame_hdr *)&lookAhead;
-
-        if (pHdr->EndpointID != ENDPOINT_0) {
-                /* unexpected endpoint number, should be zero */
-            AR_DEBUG_ASSERT(false);
-            status = A_EPROTO;
-            break;
-        }
-
-        if (status) {
-                /* bad message */
-            AR_DEBUG_ASSERT(false);
-            status = A_EPROTO;
-            break;
-        }
-
-        pPacket = HTC_ALLOC_CONTROL_RX(target);
-
-        if (pPacket == NULL) {
-            AR_DEBUG_ASSERT(false);
-            status = A_NO_MEMORY;
-            break;
-        }
-        
-        pPacket->PktInfo.AsRx.HTCRxFlags = 0;
-        pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
-        pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
-
-        if (pPacket->ActualLength > pPacket->BufferLength) {
-            AR_DEBUG_ASSERT(false);
-            status = A_EPROTO;
-            break;
-        }
-
-            /* we want synchronous operation */
-        pPacket->Completion = NULL;
-
-            /* get the message from the device, this will block */
-        status = HTCIssueRecv(target, pPacket);
-
-        if (status) {
-            break;
-        }
-
-            /* process receive header */
-        status = HTCProcessRecvHeader(target,pPacket,NULL,NULL);
-
-        pPacket->Status = status;
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n",
-                     status));
-            break;
-        }
-
-            /* give the caller this control message packet, they are responsible to free */
-        *ppControlPacket = pPacket;
-
-    } while (false);
-
-    if (status) {
-        if (pPacket != NULL) {
-                /* cleanup buffer on error */
-            HTC_FREE_CONTROL_RX(target,pPacket);
-        }
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n"));
-
-    return status;
-}
-
-static int AllocAndPrepareRxPackets(struct htc_target       *target,
-                                         u32 LookAheads[],
-                                         int              Messages,                                        
-                                         struct htc_endpoint     *pEndpoint, 
-                                         struct htc_packet_queue *pQueue)
-{
-    int         status = 0;
-    struct htc_packet      *pPacket;
-    struct htc_frame_hdr   *pHdr;
-    int              i,j;
-    int              numMessages;
-    int              fullLength;
-    bool           noRecycle;
-            
-        /* lock RX while we assemble the packet buffers */
-    LOCK_HTC_RX(target);
-                        
-    for (i = 0; i < Messages; i++) {   
-         
-        pHdr = (struct htc_frame_hdr *)&LookAheads[i];
-
-        if (pHdr->EndpointID >= ENDPOINT_MAX) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID));
-                /* invalid endpoint */
-            status = A_EPROTO;
-            break;
-        }
-
-        if (pHdr->EndpointID != pEndpoint->Id) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d should be : %d (index:%d)\n",
-                pHdr->EndpointID, pEndpoint->Id, i));
-                /* invalid endpoint */
-            status = A_EPROTO;
-            break;    
-        }    
-       
-        if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n",
-                    pHdr->PayloadLen, (u32)HTC_MAX_PAYLOAD_LENGTH));
-            status = A_EPROTO;
-            break;
-        }
-
-        if (0 == pEndpoint->ServiceID) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID));
-                /* endpoint isn't even connected */
-            status = A_EPROTO;
-            break;
-        }
-
-        if ((pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) == 0) {
-                /* HTC header only indicates 1 message to fetch */
-            numMessages = 1;
-        } else {
-                /* HTC header indicates that every packet to follow has the same padded length so that it can
-                 * be optimally fetched as a full bundle */
-            numMessages = (pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) >> HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT;
-                /* the count doesn't include the starter frame, just a count of frames to follow */
-            numMessages++;
-            A_ASSERT(numMessages <= target->MaxMsgPerBundle);          
-            INC_HTC_EP_STAT(pEndpoint, RxBundleIndFromHdr, 1);
-            AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages));           
-        }
-     
-        fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(struct htc_frame_hdr));
-            
-            /* get packet buffers for each message, if there was a bundle detected in the header,
-             * use pHdr as a template to fetch all packets in the bundle */        
-        for (j = 0; j < numMessages; j++) {  
-            
-                /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup,
-                 * they must be explicitly returned */
-            noRecycle = false;
-                                                                                   
-            if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) {
-                UNLOCK_HTC_RX(target);
-                noRecycle = true;
-                    /* user is using a per-packet allocation callback */
-                pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext,
-                                                             pEndpoint->Id,
-                                                             fullLength);
-                LOCK_HTC_RX(target);
-    
-            } else if ((pEndpoint->EpCallBacks.EpRecvAllocThresh != NULL) &&
-                       (fullLength > pEndpoint->EpCallBacks.RecvAllocThreshold)) { 
-                INC_HTC_EP_STAT(pEndpoint,RxAllocThreshHit,1);
-                INC_HTC_EP_STAT(pEndpoint,RxAllocThreshBytes,pHdr->PayloadLen);                
-                    /* threshold was hit, call the special recv allocation callback */        
-                UNLOCK_HTC_RX(target);
-                noRecycle = true;
-                    /* user wants to allocate packets above a certain threshold */
-                pPacket = pEndpoint->EpCallBacks.EpRecvAllocThresh(pEndpoint->EpCallBacks.pContext,
-                                                                   pEndpoint->Id,
-                                                                   fullLength);
-                LOCK_HTC_RX(target);        
-                        
-            } else {
-                    /* user is using a refill handler that can refill multiple HTC buffers */
-                    
-                    /* get a packet from the endpoint recv queue */
-                pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
-    
-                if (NULL == pPacket) {
-                        /* check for refill handler */
-                    if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) {
-                        UNLOCK_HTC_RX(target);
-                            /* call the re-fill handler */
-                        pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
-                                                            pEndpoint->Id);
-                        LOCK_HTC_RX(target);
-                            /* check if we have more buffers */
-                        pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
-                            /* fall through */
-                    }
-                }
-            }
-    
-            if (NULL == pPacket) {
-                    /* this is not an error, we simply need to mark that we are waiting for buffers.*/
-                target->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS;
-                target->EpWaitingForBuffers = pEndpoint->Id;
-                status = A_NO_RESOURCE;
-                break;
-            }
-                             
-            AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id);
-                /* clear flags */
-            pPacket->PktInfo.AsRx.HTCRxFlags = 0;
-            pPacket->PktInfo.AsRx.IndicationFlags = 0;
-            pPacket->Status = 0;
-            
-            if (noRecycle) {
-                    /* flag that these packets cannot be recycled, they have to be returned to the 
-                     * user */
-                pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE; 
-            }
-                /* add packet to queue (also incase we need to cleanup down below)  */
-            HTC_PACKET_ENQUEUE(pQueue,pPacket);
-            
-            if (HTC_STOPPING(target)) {
-                status = A_ECANCELED;
-                break;
-            }
-    
-                /* make sure this message can fit in the endpoint buffer */
-            if ((u32)fullLength > pPacket->BufferLength) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n",
-                        pHdr->PayloadLen, fullLength, pPacket->BufferLength));
-                status = A_EPROTO;
-                break;
-            }
-            
-            if (j > 0) {
-                    /* for messages fetched in a bundle the expected lookahead is unknown since we
-                     * are only using the lookahead of the first packet as a template of what to
-                     * expect for lengths */
-                    /* flag that once we get the real HTC header we need to refesh the information */     
-                pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR;
-                    /* set it to something invalid */
-                pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF;    
-            } else {
-            
-                pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */
-            }
-                /* set the amount of data to fetch */
-            pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
-        }
-        
-        if (status) {
-            if (A_NO_RESOURCE == status) {
-                    /* this is actually okay */
-                status = 0;
-            }
-            break;    
-        }
-                
-    }
-    
-    UNLOCK_HTC_RX(target);
-    
-    if (status) {
-        while (!HTC_QUEUE_EMPTY(pQueue)) {
-            pPacket = HTC_PACKET_DEQUEUE(pQueue);
-                /* recycle all allocated packets */
-            HTC_RECYCLE_RX_PKT(target,pPacket,&target->EndPoint[pPacket->Endpoint]);
-        }        
-    }
-        
-    return status; 
-}
-
-static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq)
-{
-    int                 i;    
-    struct htc_packet          *pPacket;
-    struct htc_endpoint        *pEndpoint;
-    u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
-    int                 numLookAheads = 0;
-    struct htc_target          *target = (struct htc_target *)pScatterReq->Context;
-    int            status;
-    bool              partialBundle = false;
-    struct htc_packet_queue    localRecvQueue;
-    bool              procError = false;
-           
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion  TotLen: %d  Entries: %d\n",
-        pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
-    
-    A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
-           
-    if (pScatterReq->CompletionStatus) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Recv Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));            
-    }
-    
-    if (pScatterReq->CallerFlags & HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE) {
-        partialBundle = true;
-    }
-    
-    DEV_FINISH_SCATTER_OPERATION(pScatterReq);
-    
-    INIT_HTC_PACKET_QUEUE(&localRecvQueue);
-        
-    pPacket = (struct htc_packet *)pScatterReq->ScatterList[0].pCallerContexts[0];
-        /* note: all packets in a scatter req are for the same endpoint ! */
-    pEndpoint = &target->EndPoint[pPacket->Endpoint];
-         
-        /* walk through the scatter list and process */
-        /* **** NOTE: DO NOT HOLD ANY LOCKS here, HTCProcessRecvHeader can take the TX lock
-         * as it processes credit reports */
-    for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
-        pPacket = (struct htc_packet *)pScatterReq->ScatterList[i].pCallerContexts[0];
-        A_ASSERT(pPacket != NULL);       
-            /* reset count, we are only interested in the look ahead in the last packet when we
-             * break out of this loop */
-        numLookAheads = 0;
-        
-        if (!pScatterReq->CompletionStatus) {
-                /* process header for each of the recv packets */            
-            status = HTCProcessRecvHeader(target,pPacket,lookAheads,&numLookAheads);
-        } else {
-            status = A_ERROR;    
-        }
-        
-        if (!status) {
-            LOCK_HTC_RX(target);              
-            HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
-            INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
-            UNLOCK_HTC_RX(target);
-            if (i == (pScatterReq->ValidScatterEntries - 1)) {
-                    /* last packet's more packets flag is set based on the lookahead */
-                SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket);
-            } else {
-                    /* packets in a bundle automatically have this flag set */
-                FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
-            }
-             
-            DUMP_RECV_PKT_INFO(pPacket);            
-                /* since we can't hold a lock in this loop, we insert into our local recv queue for
-                 * storage until we can transfer them to the recv completion queue */
-            HTC_PACKET_ENQUEUE(&localRecvQueue,pPacket);
-            
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Recv packet scatter entry %d failed (out of %d) \n",
-                    i, pScatterReq->ValidScatterEntries));
-                /* recycle failed recv */
-            HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
-                /* set flag and continue processing the remaining scatter entries */
-            procError = true;
-        }   
-    
-    }
-  
-        /* free scatter request */
-    DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
-   
-    LOCK_HTC_RX(target);   
-        /* transfer the packets in the local recv queue to the recv completion queue */
-    HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RecvIndicationQueue, &localRecvQueue);  
-    
-    UNLOCK_HTC_RX(target);
-    
-    if (!procError) {  
-            /* pipeline the next check (asynchronously) for more packets */           
-        HTCAsyncRecvCheckMorePackets(target,
-                                     lookAheads,
-                                     numLookAheads,
-                                     partialBundle ? false : true);
-    }
-    
-        /* now drain the indication queue */
-    DrainRecvIndicationQueue(target,pEndpoint);
-          
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n"));
-}
-
-static int HTCIssueRecvPacketBundle(struct htc_target        *target,
-                                         struct htc_packet_queue  *pRecvPktQueue, 
-                                         struct htc_packet_queue  *pSyncCompletionQueue,
-                                         int               *pNumPacketsFetched,
-                                         bool             PartialBundle)
-{
-    int        status = 0;
-    struct hif_scatter_req *pScatterReq;
-    int             i, totalLength;
-    int             pktsToScatter;
-    struct htc_packet      *pPacket;
-    bool          asyncMode = (pSyncCompletionQueue == NULL) ? true : false;
-    int             scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device);
-        
-    pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue);
-    pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
-        
-    if ((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - pktsToScatter) > 0) {
-            /* we were forced to split this bundle receive operation
-             * all packets in this partial bundle must have their lookaheads ignored */
-        PartialBundle = true;
-            /* this would only happen if the target ignored our max bundle limit */
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
-                         ("HTCIssueRecvPacketBundle : partial bundle detected num:%d , %d \n",
-                         HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));       
-    }
-    
-    totalLength = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCIssueRecvPacketBundle (Numpackets: %d , actual : %d) \n", 
-        HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
-    
-    do {
-        
-        pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device); 
-        
-        if (pScatterReq == NULL) {
-                /* no scatter resources left, just let caller handle it the legacy way */
-            break;    
-        }        
-    
-        pScatterReq->CallerFlags = 0;
-             
-        if (PartialBundle) {
-                /* mark that this is a partial bundle, this has special ramifications to the
-                 * scatter completion routine */
-            pScatterReq->CallerFlags |= HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE;
-        }
-                   
-            /* convert HTC packets to scatter list */                   
-        for (i = 0; i < pktsToScatter; i++) {
-            int paddedLength;
-            
-            pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue);
-            A_ASSERT(pPacket != NULL);
-            
-            paddedLength = DEV_CALC_RECV_PADDED_LEN(&target->Device, pPacket->ActualLength);
-     
-            if ((scatterSpaceRemaining - paddedLength) < 0) {
-                    /* exceeds what we can transfer, put the packet back */  
-                HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue,pPacket);
-                break;    
-            }
-                        
-            scatterSpaceRemaining -= paddedLength;
-                       
-            if (PartialBundle || (i < (pktsToScatter - 1))) {
-                    /* packet 0..n-1 cannot be checked for look-aheads since we are fetching a bundle
-                     * the last packet however can have it's lookahead used */
-                pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
-            }
-            
-            /* note: 1 HTC packet per scatter entry */           
-                /* setup packet into */   
-            pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
-            pScatterReq->ScatterList[i].Length = paddedLength;
-            
-            pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE;
-            
-            if (asyncMode) {
-                    /* save HTC packet for async completion routine */
-                pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
-            } else {
-                    /* queue to caller's sync completion queue, caller will unload this when we return */
-                HTC_PACKET_ENQUEUE(pSyncCompletionQueue,pPacket);    
-            }             
-                   
-            A_ASSERT(pScatterReq->ScatterList[i].Length);
-            totalLength += pScatterReq->ScatterList[i].Length;
-        }            
-        
-        pScatterReq->TotalLength = totalLength;
-        pScatterReq->ValidScatterEntries = i;
-        
-        if (asyncMode) {
-            pScatterReq->CompletionRoutine = HTCAsyncRecvScatterCompletion;
-            pScatterReq->Context = target;
-        }
-        
-        status = DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_READ, asyncMode);
-        
-        if (!status) {
-            *pNumPacketsFetched = i;    
-        }
-        
-        if (!asyncMode) {
-                /* free scatter request */
-            DEV_FREE_SCATTER_REQ(&target->Device, pScatterReq);   
-        }
-        
-    } while (false);
-   
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCIssueRecvPacketBundle (status:%d) (fetched:%d) \n",
-            status,*pNumPacketsFetched));
-        
-    return status;
-}
-
-static INLINE void CheckRecvWaterMark(struct htc_endpoint    *pEndpoint)
-{  
-        /* see if endpoint is using a refill watermark 
-         * ** no need to use a lock here, since we are only inspecting...
-         * caller may must not hold locks when calling this function */
-    if (pEndpoint->EpCallBacks.RecvRefillWaterMark > 0) {
-        if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBuffers) < pEndpoint->EpCallBacks.RecvRefillWaterMark) {
-                /* call the re-fill handler before we continue */
-            pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
-                                                pEndpoint->Id);
-        }
-    }  
-}
-
-/* callback when device layer or lookahead report parsing detects a pending message */
-int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched)
-{
-    struct htc_target      *target = (struct htc_target *)Context;
-    int         status = 0;
-    struct htc_packet      *pPacket;
-    struct htc_endpoint    *pEndpoint;
-    bool          asyncProc = false;
-    u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
-    int             pktsFetched;
-    struct htc_packet_queue recvPktQueue, syncCompletedPktsQueue;
-    bool          partialBundle;
-    HTC_ENDPOINT_ID id;
-    int             totalFetched = 0;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler NumLookAheads: %d \n",NumLookAheads));
-    
-    if (pNumPktsFetched != NULL) {
-        *pNumPktsFetched = 0;    
-    }
-    
-    if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) {
-            /* We use async mode to get the packets if the device layer supports it.
-             * The device layer interfaces with HIF in which HIF may have restrictions on
-             * how interrupts are processed */
-        asyncProc = true;
-    }
-
-    if (pAsyncProc != NULL) {
-            /* indicate to caller how we decided to process this */
-        *pAsyncProc = asyncProc;
-    }
-    
-    if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
-        A_ASSERT(false);
-        return A_EPROTO; 
-    }
-        
-        /* on first entry copy the lookaheads into our temp array for processing */
-    memcpy(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads);
-            
-    while (true) {
-        
-            /* reset packets queues */
-        INIT_HTC_PACKET_QUEUE(&recvPktQueue);
-        INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue);
-        
-        if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
-            status = A_EPROTO;
-            A_ASSERT(false);
-            break;    
-        }
-   
-            /* first lookahead sets the expected endpoint IDs for all packets in a bundle */
-        id = ((struct htc_frame_hdr *)&lookAheads[0])->EndpointID;
-        pEndpoint = &target->EndPoint[id];
-        
-        if (id >= ENDPOINT_MAX) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MsgPend, Invalid Endpoint in look-ahead: %d \n",id));
-            status = A_EPROTO;
-            break;
-        }
-        
-            /* try to allocate as many HTC RX packets indicated by the lookaheads
-             * these packets are stored in the recvPkt queue */
-        status = AllocAndPrepareRxPackets(target, 
-                                          lookAheads, 
-                                          NumLookAheads,
-                                          pEndpoint, 
-                                          &recvPktQueue);        
-        if (status) {
-            break;    
-        }
-        if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) >= 2) {
-                /* a recv bundle was detected, force IRQ status re-check again */
-            REF_IRQ_STATUS_RECHECK(&target->Device);
-        }
-        
-        totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue);
-               
-            /* we've got packet buffers for all we can currently fetch, 
-             * this count is not valid anymore  */
-        NumLookAheads = 0;
-        partialBundle = false;
-       
-            /* now go fetch the list of HTC packets */
-        while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {   
-            
-            pktsFetched = 0;
-                       
-            if (target->RecvBundlingEnabled && (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) {             
-                    /* there are enough packets to attempt a bundle transfer and recv bundling is allowed  */
-                status = HTCIssueRecvPacketBundle(target,
-                                                  &recvPktQueue,
-                                                  asyncProc ? NULL : &syncCompletedPktsQueue,
-                                                  &pktsFetched,
-                                                  partialBundle);                                                   
-                if (status) {
-                    break;
-                }
-                
-                if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) {
-                        /* we couldn't fetch all packets at one time, this creates a broken
-                         * bundle  */
-                    partialBundle = true;
-                }                                                                     
-            }
-            
-                /* see if the previous operation fetched any packets using bundling */
-            if (0 == pktsFetched) {  
-                    /* dequeue one packet */
-                pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
-                A_ASSERT(pPacket != NULL);                 
-                                     
-                if (asyncProc) {
-                        /* we use async mode to get the packet if the device layer supports it
-                         * set our callback and context */
-                    pPacket->Completion = HTCRecvCompleteHandler;
-                    pPacket->pContext = target;
-                } else {
-                        /* fully synchronous */
-                    pPacket->Completion = NULL;
-                }
-                
-                if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) {
-                        /* lookaheads in all packets except the last one in the bundle must be ignored */
-                    pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
-                }
-                                    
-                    /* go fetch the packet */
-                status = HTCIssueRecv(target, pPacket);              
-                if (status) {
-                    break;
-                }  
-                               
-                if (!asyncProc) {               
-                        /* sent synchronously, queue this packet for synchronous completion */
-                    HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue,pPacket);
-                } 
-                               
-            }
-            
-        }
-
-        if (!status) {
-            CheckRecvWaterMark(pEndpoint);
-        }
-            
-        if (asyncProc) {
-                /* we did this asynchronously so we can get out of the loop, the asynch processing
-                 * creates a chain of requests to continue processing pending messages in the
-                 * context of callbacks  */
-            break;
-        }
-
-            /* synchronous handling */
-        if (target->Device.DSRCanYield) {
-                /* for the SYNC case, increment count that tracks when the DSR should yield */
-            target->Device.CurrentDSRRecvCount++;    
-        }
-            
-            /* in the sync case, all packet buffers are now filled, 
-             * we can process each packet, check lookaheads and then repeat */ 
-             
-             /* unload sync completion queue */      
-        while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
-            struct htc_packet_queue    container;
-           
-            pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
-            A_ASSERT(pPacket != NULL);
-            
-            pEndpoint = &target->EndPoint[pPacket->Endpoint];           
-                /* reset count on each iteration, we are only interested in the last packet's lookahead
-                 * information when we break out of this loop */
-            NumLookAheads = 0;
-                /* process header for each of the recv packets
-                 * note: the lookahead of the last packet is useful for us to continue in this loop */            
-            status = HTCProcessRecvHeader(target,pPacket,lookAheads,&NumLookAheads);
-            if (status) {
-                break;
-            }
-            
-            if (HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
-                    /* last packet's more packets flag is set based on the lookahead */
-                SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,NumLookAheads,pEndpoint,pPacket);
-            } else {
-                    /* packets in a bundle automatically have this flag set */
-                FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
-            }
-                /* good packet, indicate it */
-            HTC_RX_STAT_PROFILE(target,pEndpoint,NumLookAheads);
-            
-            if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_PART_OF_BUNDLE) {
-                INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
-            }
-            
-            INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
-            DO_RCV_COMPLETION(pEndpoint,&container);
-        }
-
-        if (status) {
-            break;
-        }
-            
-        if (NumLookAheads == 0) {
-                /* no more look aheads */
-            break;    
-        }
-
-            /* when we process recv synchronously we need to check if we should yield and stop
-             * fetching more packets indicated by the embedded lookaheads */
-        if (target->Device.DSRCanYield) {
-            if (DEV_CHECK_RECV_YIELD(&target->Device)) {
-                    /* break out, don't fetch any more packets */
-                break;  
-            }  
-        }
-            
-
-        /* check whether other OS contexts have queued any WMI command/data for WLAN. 
-         * This check is needed only if WLAN Tx and Rx happens in same thread context */
-        A_CHECK_DRV_TX();
-        
-            /* for SYNCH processing, if we get here, we are running through the loop again due to a detected lookahead.
-             * Set flag that we should re-check IRQ status registers again before leaving IRQ processing,
-             * this can net better performance in high throughput situations */
-        REF_IRQ_STATUS_RECHECK(&target->Device);
-    }
-    
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("Failed to get pending recv messages (%d) \n",status));
-            /* cleanup any packets we allocated but didn't use to actually fetch any packets */                        
-        while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {   
-            pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
-                /* clean up packets */
-            HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
-        }
-            /* cleanup any packets in sync completion queue */
-        while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {   
-            pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
-                /* clean up packets */
-            HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
-        }
-        if  (HTC_STOPPING(target)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
-                (" Host is going to stop. blocking receiver for HTCStop.. \n"));
-            DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
-        }
-    }
-        /* before leaving, check to see if host ran out of buffers and needs to stop the
-         * receiver */
-    if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
-                (" Host has no RX buffers, blocking receiver to prevent overrun.. \n"));
-            /* try to stop receive at the device layer */
-        DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
-    }
-    
-    if (pNumPktsFetched != NULL) {
-        *pNumPktsFetched = totalFetched;    
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n"));
-
-    return status;
-}
-
-int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue)
-{
-    struct htc_target      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    struct htc_endpoint    *pEndpoint;
-    bool          unblockRecv = false;
-    int        status = 0;
-    struct htc_packet      *pFirstPacket;
-
-    pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
-    
-    if (NULL == pFirstPacket) {
-        A_ASSERT(false);
-        return A_EINVAL;    
-    }
-    
-    AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
-                    ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n",
-                    pFirstPacket->Endpoint,
-                    HTC_PACKET_QUEUE_DEPTH(pPktQueue), 
-                    pFirstPacket->BufferLength));
-
-    do {
-
-        pEndpoint = &target->EndPoint[pFirstPacket->Endpoint];
-
-        LOCK_HTC_RX(target);
-
-        if (HTC_STOPPING(target)) {
-            struct htc_packet *pPacket;
-            
-            UNLOCK_HTC_RX(target);
-            
-                /* walk through queue and mark each one canceled */
-            HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
-                pPacket->Status = A_ECANCELED;    
-            } HTC_PACKET_QUEUE_ITERATE_END;
-            
-            DO_RCV_COMPLETION(pEndpoint,pPktQueue);
-            break;
-        }
-
-            /* store receive packets */
-        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBuffers, pPktQueue);
-
-            /* check if we are blocked waiting for a new buffer */
-        if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
-            if (target->EpWaitingForBuffers == pFirstPacket->Endpoint) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n",
-                    target->EpWaitingForBuffers));
-                target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
-                target->EpWaitingForBuffers = ENDPOINT_MAX;
-                unblockRecv = true;
-            }
-        }
-
-        UNLOCK_HTC_RX(target);
-
-        if (unblockRecv && !HTC_STOPPING(target)) {
-                /* TODO : implement a buffer threshold count? */
-            DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
-        }
-
-    } while (false);
-
-    return status;
-}
-
-/* Makes a buffer available to the HTC module */
-int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket)
-{
-    struct htc_packet_queue queue;
-    INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); 
-    return HTCAddReceivePktMultiple(HTCHandle, &queue);       
-}
-
-void HTCUnblockRecv(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    bool      unblockRecv = false;
-
-    LOCK_HTC_RX(target);
-
-        /* check if we are blocked waiting for a new buffer */
-    if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HTCUnblockRx : receiver was blocked on ep:%d, unblocking.. \n",
-            target->EpWaitingForBuffers));
-        target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
-        target->EpWaitingForBuffers = ENDPOINT_MAX;
-        unblockRecv = true;
-    }
-
-    UNLOCK_HTC_RX(target);
-
-    if (unblockRecv && !HTC_STOPPING(target)) {
-            /* re-enable */
-        DevEnableRecv(&target->Device,DEV_ENABLE_RECV_ASYNC);
-    }
-}
-
-static void HTCFlushRxQueue(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue)
-{
-    struct htc_packet  *pPacket;
-    struct htc_packet_queue container;
-    
-    LOCK_HTC_RX(target);
-
-    while (1) {
-        pPacket = HTC_PACKET_DEQUEUE(pQueue);
-        if (NULL == pPacket) {
-            break;
-        }
-        UNLOCK_HTC_RX(target);
-        pPacket->Status = A_ECANCELED;
-        pPacket->ActualLength = 0;
-        AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("  Flushing RX packet:0x%lX, length:%d, ep:%d \n",
-                (unsigned long)pPacket, pPacket->BufferLength, pPacket->Endpoint));
-        INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
-            /* give the packet back */
-        DO_RCV_COMPLETION(pEndpoint,&container);
-        LOCK_HTC_RX(target);
-    }
-    
-    UNLOCK_HTC_RX(target);
-}
-
-static void HTCFlushEndpointRX(struct htc_target *target, struct htc_endpoint *pEndpoint)
-{
-        /* flush any recv indications not already made */
-    HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue);
-        /* flush any rx buffers */
-    HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RxBuffers);
-}
-
-void HTCFlushRecvBuffers(struct htc_target *target)
-{
-    struct htc_endpoint    *pEndpoint;
-    int             i;
-
-    for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
-        pEndpoint = &target->EndPoint[i];
-        if (pEndpoint->ServiceID == 0) {
-                /* not in use.. */
-            continue;
-        }
-        HTCFlushEndpointRX(target,pEndpoint);
-    }
-}
-
-
-void HTCEnableRecv(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-
-    if (!HTC_STOPPING(target)) {
-            /* re-enable */
-        DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
-    }
-}
-
-void HTCDisableRecv(HTC_HANDLE HTCHandle)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-
-    if (!HTC_STOPPING(target)) {
-            /* disable */
-        DevStopRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
-    }
-}
-
-int HTCGetNumRecvBuffers(HTC_HANDLE      HTCHandle,
-                         HTC_ENDPOINT_ID Endpoint)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);    
-    return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers));
-}
-
-int HTCWaitForPendingRecv(HTC_HANDLE   HTCHandle,
-                               u32 TimeoutInMs,
-                               bool      *pbIsRecvPending)
-{
-    int    status  = 0;
-    struct htc_target *target  = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-
-    status = DevWaitForPendingRecv(&target->Device,
-                                    TimeoutInMs,
-                                    pbIsRecvPending);
-
-    return status;
-}
diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c
deleted file mode 100644 (file)
index 9310d4d..0000000
+++ /dev/null
@@ -1,1018 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_send.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#include "htc_internal.h"
-
-typedef enum _HTC_SEND_QUEUE_RESULT {
-    HTC_SEND_QUEUE_OK = 0,    /* packet was queued */
-    HTC_SEND_QUEUE_DROP = 1,  /* this packet should be dropped */
-} HTC_SEND_QUEUE_RESULT;
-
-#define DO_EP_TX_COMPLETION(ep,q)  DoSendCompletion(ep,q)
-
-/* call the distribute credits callback with the distribution */
-#define DO_DISTRIBUTION(t,reason,description,pList) \
-{                                             \
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,           \
-        ("  calling distribute function (%s) (dfn:0x%lX, ctxt:0x%lX, dist:0x%lX) \n", \
-                (description),                                           \
-                (unsigned long)(t)->DistributeCredits,                   \
-                (unsigned long)(t)->pCredDistContext,                    \
-                (unsigned long)pList));                                  \
-    (t)->DistributeCredits((t)->pCredDistContext,                        \
-                           (pList),                                      \
-                           (reason));                                    \
-}
-
-static void DoSendCompletion(struct htc_endpoint       *pEndpoint,
-                             struct htc_packet_queue   *pQueueToIndicate)
-{           
-    do {
-                
-        if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
-                /* nothing to indicate */
-            break;    
-        }
-        if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) {    
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n",
-                     pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
-                /* a multiple send complete handler is being used, pass the queue to the handler */                             
-            pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext,
-                                                        pQueueToIndicate);
-                /* all packets are now owned by the callback, reset queue to be safe */
-            INIT_HTC_PACKET_QUEUE(pQueueToIndicate);                                                      
-        } else {
-            struct htc_packet *pPacket;  
-            /* using legacy EpTxComplete */         
-            do {
-                pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
-                AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet 0x%lX \n", \
-                        pEndpoint->Id, (unsigned long)(pPacket)));
-                pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket);                                              
-            } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));                                              
-        }
-        
-    } while (false);
-
-}
-
-/* do final completion on sent packet */
-static INLINE void CompleteSentPacket(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket)
-{
-    pPacket->Completion = NULL;  
-    
-    if (pPacket->Status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-            ("CompleteSentPacket: request failed (status:%d, ep:%d, length:%d creds:%d) \n",
-                pPacket->Status, pPacket->Endpoint, pPacket->ActualLength, pPacket->PktInfo.AsTx.CreditsUsed));                
-            /* on failure to submit, reclaim credits for this packet */        
-        LOCK_HTC_TX(target);        
-        pEndpoint->CreditDist.TxCreditsToDist += pPacket->PktInfo.AsTx.CreditsUsed;
-        pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
-        DO_DISTRIBUTION(target,
-                        HTC_CREDIT_DIST_SEND_COMPLETE,
-                        "Send Complete",
-                        target->EpCreditDistributionListHead->pNext);
-        UNLOCK_HTC_TX(target);            
-    }
-        /* first, fixup the head room we allocated */
-    pPacket->pBuffer += HTC_HDR_LENGTH; 
-}
-
-/* our internal send packet completion handler when packets are submited to the AR6K device
- * layer */
-static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacket)
-{
-    struct htc_target      *target = (struct htc_target *)Context;
-    struct htc_endpoint    *pEndpoint = &target->EndPoint[pPacket->Endpoint];
-    struct htc_packet_queue container;
-    
-    CompleteSentPacket(target,pEndpoint,pPacket);
-    INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
-        /* do completion */
-    DO_EP_TX_COMPLETION(pEndpoint,&container);
-}
-
-int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket)
-{
-    int status;
-    bool   sync = false;
-
-    if (pPacket->Completion == NULL) {
-            /* mark that this request was synchronously issued */
-        sync = true;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
-                    ("+-HTCIssueSend: transmit length : %d (%s) \n",
-                    pPacket->ActualLength + (u32)HTC_HDR_LENGTH,
-                    sync ? "SYNC" : "ASYNC" ));
-
-        /* send message to device */
-    status = DevSendPacket(&target->Device,
-                           pPacket,
-                           pPacket->ActualLength + HTC_HDR_LENGTH);
-
-    if (sync) {
-            /* use local sync variable.  If this was issued asynchronously, pPacket is no longer
-             * safe to access. */
-        pPacket->pBuffer += HTC_HDR_LENGTH;
-    }
-    
-    /* if this request was asynchronous, the packet completion routine will be invoked by
-     * the device layer when the HIF layer completes the request */
-
-    return status;
-}
-
-    /* get HTC send packets from the TX queue on an endpoint */
-static INLINE void GetHTCSendPackets(struct htc_target        *target, 
-                                     struct htc_endpoint      *pEndpoint, 
-                                     struct htc_packet_queue  *pQueue)
-{
-    int          creditsRequired;
-    int          remainder;
-    u8 sendFlags;
-    struct htc_packet   *pPacket;
-    unsigned int transferLength;
-
-    /****** NOTE : the TX lock is held when this function is called *****************/
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets \n"));
-     
-        /* loop until we can grab as many packets out of the queue as we can */       
-    while (true) {
-        
-        sendFlags = 0;   
-            /* get packet at head, but don't remove it */
-        pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue);       
-        if (pPacket == NULL) {
-            break;    
-        }
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%lX , Queue Depth: %d\n",
-                (unsigned long)pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
-        
-        transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, pPacket->ActualLength + HTC_HDR_LENGTH);       
-       
-        if (transferLength <= target->TargetCreditSize) {
-            creditsRequired = 1;    
-        } else {
-                /* figure out how many credits this message requires */
-            creditsRequired = transferLength / target->TargetCreditSize;
-            remainder = transferLength % target->TargetCreditSize;
-            
-            if (remainder) {
-                creditsRequired++;
-            }
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d   Got:%d\n",
-                            creditsRequired, pEndpoint->CreditDist.TxCredits));
-
-        if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
-
-                /* not enough credits */
-            if (pPacket->Endpoint == ENDPOINT_0) {
-                    /* leave it in the queue */
-                break;
-            }
-                /* invoke the registered distribution function only if this is not
-                 * endpoint 0, we let the driver layer provide more credits if it can.
-                 * We pass the credit distribution list starting at the endpoint in question
-                 * */
-
-                /* set how many credits we need  */
-            pEndpoint->CreditDist.TxCreditsSeek =
-                                    creditsRequired - pEndpoint->CreditDist.TxCredits;
-            DO_DISTRIBUTION(target,
-                            HTC_CREDIT_DIST_SEEK_CREDITS,
-                            "Seek Credits",
-                            &pEndpoint->CreditDist);
-            pEndpoint->CreditDist.TxCreditsSeek = 0;
-
-            if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
-                    /* still not enough credits to send, leave packet in the queue */
-                AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
-                    (" Not enough credits for ep %d leaving packet in queue..\n",
-                    pPacket->Endpoint));
-                break;
-            }
-
-        }
-
-        pEndpoint->CreditDist.TxCredits -= creditsRequired;
-        INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired);
-
-            /* check if we need credits back from the target */
-        if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
-                /* we are getting low on credits, see if we can ask for more from the distribution function */
-            pEndpoint->CreditDist.TxCreditsSeek =
-                        pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits;
-
-            DO_DISTRIBUTION(target,
-                            HTC_CREDIT_DIST_SEEK_CREDITS,
-                            "Seek Credits",
-                            &pEndpoint->CreditDist);
-
-            pEndpoint->CreditDist.TxCreditsSeek = 0;
-                /* see if we were successful in getting more */
-            if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
-                    /* tell the target we need credits ASAP! */
-                sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
-                INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1);
-                AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits  \n"));
-            }
-        }
-                        
-            /* now we can fully dequeue */
-        pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); 
-            /* save the number of credits this packet consumed */
-        pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired;
-            /* all TX packets are handled asynchronously */
-        pPacket->Completion = HTCSendPktCompletionHandler;
-        pPacket->pContext = target;
-        INC_HTC_EP_STAT(pEndpoint, TxIssued, 1);
-            /* save send flags */
-        pPacket->PktInfo.AsTx.SendFlags = sendFlags;
-        pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;         
-        pEndpoint->SeqNo++;
-            /* queue this packet into the caller's queue */
-        HTC_PACKET_ENQUEUE(pQueue,pPacket);
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n"));
-     
-}
-
-static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq)
-{
-    int                 i;    
-    struct htc_packet          *pPacket;
-    struct htc_endpoint        *pEndpoint = (struct htc_endpoint *)pScatterReq->Context;
-    struct htc_target          *target = (struct htc_target *)pEndpoint->target;
-    int            status = 0;
-    struct htc_packet_queue    sendCompletes;
-    
-    INIT_HTC_PACKET_QUEUE(&sendCompletes);
-          
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCAsyncSendScatterCompletion  TotLen: %d  Entries: %d\n",
-        pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
-    
-    DEV_FINISH_SCATTER_OPERATION(pScatterReq);
-           
-    if (pScatterReq->CompletionStatus) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Send Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));            
-        status = A_ERROR;
-    }
-    
-        /* walk through the scatter list and process */
-    for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
-        pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
-        A_ASSERT(pPacket != NULL);
-        pPacket->Status = status;
-        CompleteSentPacket(target,pEndpoint,pPacket);
-            /* add it to the completion queue */
-        HTC_PACKET_ENQUEUE(&sendCompletes, pPacket);      
-    }
-    
-        /* free scatter request */
-    DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
-        /* complete all packets */
-    DO_EP_TX_COMPLETION(pEndpoint,&sendCompletes);
-               
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCAsyncSendScatterCompletion \n"));
-}
-
-    /* drain a queue and send as bundles 
-     * this function may return without fully draining the queue under the following conditions :
-     *    - scatter resources are exhausted
-     *    - a message that will consume a partial credit will stop the bundling process early 
-     *    - we drop below the minimum number of messages for a bundle 
-     * */
-static void HTCIssueSendBundle(struct htc_endpoint      *pEndpoint, 
-                               struct htc_packet_queue  *pQueue, 
-                               int               *pBundlesSent, 
-                               int               *pTotalBundlesPkts)
-{
-    int                 pktsToScatter;
-    unsigned int        scatterSpaceRemaining;
-    struct hif_scatter_req     *pScatterReq = NULL;
-    int                 i, packetsInScatterReq;
-    unsigned int        transferLength;
-    struct htc_packet          *pPacket;
-    bool              done = false;
-    int                 bundlesSent = 0;
-    int                 totalPktsInBundle = 0;
-    struct htc_target          *target = pEndpoint->target;
-    int                 creditRemainder = 0;
-    int                 creditPad;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCIssueSendBundle \n"));
-    
-    while (!done) {
-          
-        pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pQueue);
-        pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
-        
-        if (pktsToScatter < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
-                /* not enough to bundle */
-            break;    
-        }
-        
-        pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device); 
-        
-        if (pScatterReq == NULL) {
-                /* no scatter resources  */
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("   No more scatter resources \n"));
-            break;    
-        }       
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("   pkts to scatter: %d \n", pktsToScatter));
-        
-        pScatterReq->TotalLength = 0;
-        pScatterReq->ValidScatterEntries = 0;  
-        
-        packetsInScatterReq = 0;
-        scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device);
-        
-        for (i = 0; i < pktsToScatter; i++) {
-            
-            pScatterReq->ScatterList[i].pCallerContexts[0] = NULL;
-            
-            pPacket = HTC_GET_PKT_AT_HEAD(pQueue);        
-            if (pPacket == NULL) {
-                A_ASSERT(false);
-                break;    
-            }
-            
-            creditPad = 0;
-            transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, 
-                                                      pPacket->ActualLength + HTC_HDR_LENGTH);               
-                /* see if the padded transfer length falls on a credit boundary */         
-            creditRemainder = transferLength % target->TargetCreditSize;
-                                
-            if (creditRemainder != 0) {
-                    /* the transfer consumes a "partial" credit, this packet cannot be bundled unless
-                     * we add additional "dummy" padding (max 255 bytes) to consume the entire credit 
-                     *** NOTE: only allow the send padding if the endpoint is allowed to */
-                if (pEndpoint->LocalConnectionFlags & HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING) {
-                    if (transferLength < target->TargetCreditSize) {
-                            /* special case where the transfer is less than a credit */
-                        creditPad = target->TargetCreditSize - transferLength;                    
-                    } else {
-                        creditPad = creditRemainder;    
-                    }
-                                    
-                        /* now check to see if we can indicate padding in the HTC header */
-                    if ((creditPad > 0) && (creditPad <= 255)) {
-                            /* adjust the transferlength of this packet with the new credit padding */
-                        transferLength += creditPad;            
-                    } else {
-                            /* the amount to pad is too large, bail on this packet, we have to 
-                             * send it using the non-bundled method */
-                        pPacket = NULL;
-                    }
-                } else {
-                        /* bail on this packet, user does not want padding applied */
-                    pPacket = NULL;    
-                }
-            }                       
-                       
-            if (NULL == pPacket) {
-                    /* can't bundle */
-                done = true;
-                break;    
-            }         
-               
-            if (scatterSpaceRemaining < transferLength) {
-                    /* exceeds what we can transfer */
-                break;    
-            }
-            
-            scatterSpaceRemaining -= transferLength;
-                /* now remove it from the queue */ 
-            pPacket = HTC_PACKET_DEQUEUE(pQueue);           
-                /* save it in the scatter list */
-            pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;            
-                /* prepare packet and flag message as part of a send bundle */               
-            HTC_PREPARE_SEND_PKT(pPacket,
-                                 pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE, 
-                                 creditPad,                                 
-                                 pPacket->PktInfo.AsTx.SeqNo); 
-            pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
-            pScatterReq->ScatterList[i].Length = transferLength;
-            A_ASSERT(transferLength);
-            pScatterReq->TotalLength += transferLength;
-            pScatterReq->ValidScatterEntries++;
-            packetsInScatterReq++;             
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("  %d, Adding packet : 0x%lX, len:%d (remaining space:%d) \n", 
-                    i, (unsigned long)pPacket,transferLength,scatterSpaceRemaining));                                                      
-        }
-                    
-        if (packetsInScatterReq >= HTC_MIN_HTC_MSGS_TO_BUNDLE) {          
-                /* send path is always asynchronous */
-            pScatterReq->CompletionRoutine = HTCAsyncSendScatterCompletion;
-            pScatterReq->Context = pEndpoint;
-            bundlesSent++;
-            totalPktsInBundle += packetsInScatterReq;
-            packetsInScatterReq = 0;
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Send Scatter total bytes: %d , entries: %d\n",
-                                pScatterReq->TotalLength,pScatterReq->ValidScatterEntries));
-            DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_WRITE, DEV_SCATTER_ASYNC);
-                /* we don't own this anymore */
-            pScatterReq = NULL;
-                /* try to send some more */
-            continue;               
-        } 
-        
-            /* not enough packets to use the scatter request, cleanup */
-        if (pScatterReq != NULL) {
-            if (packetsInScatterReq > 0) {
-                    /* work backwards to requeue requests */
-                for (i = (packetsInScatterReq - 1); i >= 0; i--) {
-                    pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
-                    if (pPacket != NULL) {
-                            /* undo any prep */
-                        HTC_UNPREPARE_SEND_PKT(pPacket);
-                            /* queue back to the head */
-                        HTC_PACKET_ENQUEUE_TO_HEAD(pQueue,pPacket);   
-                    }  
-                }  
-            }               
-            DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);    
-        }  
-        
-        /* if we get here, we sent all that we could, get out */
-        break;  
-        
-    }
-    
-    *pBundlesSent = bundlesSent;
-    *pTotalBundlesPkts = totalPktsInBundle;
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCIssueSendBundle (sent:%d) \n",bundlesSent));  
-     
-    return; 
-}
-
-/*
- * if there are no credits, the packet(s) remains in the queue.
- * this function returns the result of the attempt to send a queue of HTC packets */
-static HTC_SEND_QUEUE_RESULT HTCTrySend(struct htc_target       *target,
-                                        struct htc_endpoint     *pEndpoint,
-                                        struct htc_packet_queue *pCallersSendQueue)
-{
-    struct htc_packet_queue      sendQueue; /* temp queue to hold packets at various stages */
-    struct htc_packet            *pPacket;
-    int                   bundlesSent;
-    int                   pktsInBundles;
-    int                   overflow;
-    HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:0x%lX Depth:%d)\n",
-            (unsigned long)pCallersSendQueue, 
-            (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue)));
-
-        /* init the local send queue */
-    INIT_HTC_PACKET_QUEUE(&sendQueue);
-    
-    do {
-        
-        if (NULL == pCallersSendQueue) {
-                /* caller didn't provide a queue, just wants us to check queues and send */
-            break;    
-        }
-        
-        if (HTC_QUEUE_EMPTY(pCallersSendQueue)) {
-                /* empty queue */
-            result = HTC_SEND_QUEUE_DROP;
-            break;    
-        }
-  
-        if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) {
-                    /* we've already overflowed */
-            overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);    
-        } else {
-                /* figure out how much we will overflow by */
-            overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
-            overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue); 
-                /* figure out how much we will overflow the TX queue by */
-            overflow -= pEndpoint->MaxTxQueueDepth;     
-        }
-                     
-            /* if overflow is negative or zero, we are okay */    
-        if (overflow > 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND, 
-                (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n",
-                pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth));      
-        }   
-        if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) {
-                /* all packets will fit or caller did not provide send full indication handler
-                 * --  just move all of them to the local sendQueue object */
-            HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue);           
-        } else {
-            int               i;
-            int               goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow;
-                        
-            A_ASSERT(goodPkts >= 0);
-                /* we have overflowed, and a callback is provided */        
-                /* dequeue all non-overflow packets into the sendqueue */
-            for (i = 0; i < goodPkts; i++) {
-                    /* pop off caller's queue*/
-                pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue);
-                A_ASSERT(pPacket != NULL);
-                    /* insert into local queue */
-                HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
-            }
-            
-                /* the caller's queue has all the packets that won't fit*/                
-                /* walk through the caller's queue and indicate each one to the send full handler */            
-            ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, struct htc_packet, ListLink) {            
-                
-                AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: 0x%lX \n", 
-                                            (unsigned long)pPacket));    
-                if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext,
-                                                      pPacket) == HTC_SEND_FULL_DROP) {
-                        /* callback wants the packet dropped */
-                    INC_HTC_EP_STAT(pEndpoint, TxDropped, 1);
-                        /* leave this one in the caller's queue for cleanup */
-                } else {
-                        /* callback wants to keep this packet, remove from caller's queue */
-                    HTC_PACKET_REMOVE(pCallersSendQueue, pPacket);
-                        /* put it in the send queue */
-                    HTC_PACKET_ENQUEUE(&sendQueue,pPacket);                                      
-                }
-                
-            } ITERATE_END;
-            
-            if (HTC_QUEUE_EMPTY(&sendQueue)) {
-                    /* no packets made it in, caller will cleanup */
-                result = HTC_SEND_QUEUE_DROP;
-                break;   
-            } 
-        }
-        
-    } while (false);
-    
-    if (result != HTC_SEND_QUEUE_OK) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend:  \n"));
-        return result;
-    }
-
-    LOCK_HTC_TX(target);
-    
-    if (!HTC_QUEUE_EMPTY(&sendQueue)) {
-            /* transfer packets */
-        HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue);
-        A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue));
-        INIT_HTC_PACKET_QUEUE(&sendQueue); 
-    }
-    
-        /* increment tx processing count on entry */    
-    pEndpoint->TxProcessCount++;
-    if (pEndpoint->TxProcessCount > 1) {
-            /* another thread or task is draining the TX queues on this endpoint
-             * that thread will reset the tx processing count when the queue is drained */
-        pEndpoint->TxProcessCount--;
-        UNLOCK_HTC_TX(target);
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n"));
-        return HTC_SEND_QUEUE_OK; 
-    }
-    
-    /***** beyond this point only 1 thread may enter ******/
-            
-        /* now drain the endpoint TX queue for transmission as long as we have enough
-         * credits */
-    while (true) {
-          
-        if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) {
-            break;
-        }
-                
-            /* get all the packets for this endpoint that we can for this pass */
-        GetHTCSendPackets(target, pEndpoint, &sendQueue);        
-     
-        if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) {
-                /* didn't get any packets due to a lack of credits */
-            break;    
-        }
-        
-        UNLOCK_HTC_TX(target);
-        
-            /* any packets to send are now in our local send queue */    
-         
-        bundlesSent = 0;
-        pktsInBundles = 0;
-     
-        while (true) {
-            
-                /* try to send a bundle on each pass */            
-            if ((target->SendBundlingEnabled) &&
-                    (HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
-                 int temp1,temp2;       
-                    /* bundling is enabled and there is at least a minimum number of packets in the send queue
-                     * send what we can in this pass */                       
-                 HTCIssueSendBundle(pEndpoint, &sendQueue, &temp1, &temp2);
-                 bundlesSent += temp1;
-                 pktsInBundles += temp2;
-            }
-        
-                /* if not bundling or there was a packet that could not be placed in a bundle, pull it out
-                 * and send it the normal way */
-            pPacket = HTC_PACKET_DEQUEUE(&sendQueue);
-            if (NULL == pPacket) {
-                    /* local queue is fully drained */
-                break;    
-            }
-            HTC_PREPARE_SEND_PKT(pPacket,
-                                 pPacket->PktInfo.AsTx.SendFlags,
-                                 0,
-                                 pPacket->PktInfo.AsTx.SeqNo);  
-            HTCIssueSend(target, pPacket);
-            
-                /* go back and see if we can bundle some more */
-        }
-        
-        LOCK_HTC_TX(target);
-        
-        INC_HTC_EP_STAT(pEndpoint, TxBundles, bundlesSent);
-        INC_HTC_EP_STAT(pEndpoint, TxPacketsBundled, pktsInBundles);
-        
-    }
-        
-        /* done with this endpoint, we can clear the count */
-    pEndpoint->TxProcessCount = 0;
-    UNLOCK_HTC_TX(target);
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend:  \n"));
-
-    return HTC_SEND_QUEUE_OK;
-}
-
-int  HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue)
-{
-    struct htc_target      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    struct htc_endpoint    *pEndpoint;
-    struct htc_packet      *pPacket;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n",
-                    (unsigned long)pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
-    
-        /* get packet at head to figure out which endpoint these packets will go into */
-    pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
-    if (NULL == pPacket) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
-        return A_EINVAL;   
-    }
-    
-    AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
-    pEndpoint = &target->EndPoint[pPacket->Endpoint];
-    
-    HTCTrySend(target, pEndpoint, pPktQueue);
-
-        /* do completion on any packets that couldn't get in */
-    if (!HTC_QUEUE_EMPTY(pPktQueue)) {        
-        
-        HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
-            if (HTC_STOPPING(target)) {
-                pPacket->Status = A_ECANCELED;
-            } else {
-                pPacket->Status = A_NO_RESOURCE;
-            } 
-        } HTC_PACKET_QUEUE_ITERATE_END;
-                   
-        DO_EP_TX_COMPLETION(pEndpoint,pPktQueue);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
-
-    return 0;
-}
-
-/* HTC API - HTCSendPkt */
-int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket)
-{
-    struct htc_packet_queue queue;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
-                    ("+-HTCSendPkt: Enter endPointId: %d, buffer: 0x%lX, length: %d \n",
-                    pPacket->Endpoint, (unsigned long)pPacket->pBuffer, pPacket->ActualLength));                   
-    INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); 
-    return HTCSendPktsMultiple(HTCHandle, &queue);
-}
-
-/* check TX queues to drain because of credit distribution update */
-static INLINE void HTCCheckEndpointTxQueues(struct htc_target *target)
-{
-    struct htc_endpoint                *pEndpoint;
-    struct htc_endpoint_credit_dist    *pDistItem;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n"));
-    pDistItem = target->EpCreditDistributionListHead;
-
-        /* run through the credit distribution list to see
-         * if there are packets queued
-         * NOTE: no locks need to be taken since the distribution list
-         * is not dynamic (cannot be re-ordered) and we are not modifying any state */
-    while (pDistItem != NULL) {
-        pEndpoint = (struct htc_endpoint *)pDistItem->pHTCReserved;
-
-        if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) > 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n",
-                    pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
-                /* try to start the stalled queue, this list is ordered by priority.
-                 * Highest priority queue get's processed first, if there are credits available the
-                 * highest priority queue will get a chance to reclaim credits from lower priority
-                 * ones */
-            HTCTrySend(target, pEndpoint, NULL);
-        }
-
-        pDistItem = pDistItem->pNext;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n"));
-}
-
-/* process credit reports and call distribution function */
-void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint)
-{
-    int             i;
-    struct htc_endpoint    *pEndpoint;
-    int             totalCredits = 0;
-    bool          doDist = false;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries));
-
-        /* lock out TX while we update credits */
-    LOCK_HTC_TX(target);
-
-    for (i = 0; i < NumEntries; i++, pRpt++) {
-        if (pRpt->EndpointID >= ENDPOINT_MAX) {
-            AR_DEBUG_ASSERT(false);
-            break;
-        }
-
-        pEndpoint = &target->EndPoint[pRpt->EndpointID];
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("  Endpoint %d got %d credits \n",
-                pRpt->EndpointID, pRpt->Credits));
-
-        INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1);
-        INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits);
-
-        if (FromEndpoint == pRpt->EndpointID) {
-                /* this credit report arrived on the same endpoint indicating it arrived in an RX
-                 * packet */
-            INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits);
-            INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1);
-        } else if (FromEndpoint == ENDPOINT_0) {
-                /* this credit arrived on endpoint 0 as a NULL message */
-            INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits);
-            INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1);
-        } else {
-                /* arrived on another endpoint */
-            INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits);
-            INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1);
-        }
-
-        if (ENDPOINT_0 == pRpt->EndpointID) {
-                /* always give endpoint 0 credits back */
-            pEndpoint->CreditDist.TxCredits += pRpt->Credits;
-        } else {
-                /* for all other endpoints, update credits to distribute, the distribution function
-                 * will handle giving out credits back to the endpoints */
-            pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits;
-                /* flag that we have to do the distribution */
-            doDist = true;
-        }
-        
-            /* refresh tx depth for distribution function that will recover these credits
-             * NOTE: this is only valid when there are credits to recover! */
-        pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
-        
-        totalCredits += pRpt->Credits;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("  Report indicated %d credits to distribute \n", totalCredits));
-
-    if (doDist) {
-            /* this was a credit return based on a completed send operations
-             * note, this is done with the lock held */
-        DO_DISTRIBUTION(target,
-                        HTC_CREDIT_DIST_SEND_COMPLETE,
-                        "Send Complete",
-                        target->EpCreditDistributionListHead->pNext);
-    }
-
-    UNLOCK_HTC_TX(target);
-
-    if (totalCredits) {
-        HTCCheckEndpointTxQueues(target);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n"));
-}
-
-/* flush endpoint TX queue */
-static void HTCFlushEndpointTX(struct htc_target *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag)
-{
-    struct htc_packet          *pPacket;
-    struct htc_packet_queue    discardQueue;
-    struct htc_packet_queue    container;
-
-        /* initialize the discard queue */
-    INIT_HTC_PACKET_QUEUE(&discardQueue);
-
-    LOCK_HTC_TX(target);
-
-        /* interate from the front of the TX queue and flush out packets */
-    ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, struct htc_packet, ListLink) {
-
-            /* check for removal */
-        if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) {
-                /* remove from queue */
-            HTC_PACKET_REMOVE(&pEndpoint->TxQueue, pPacket);
-                /* add it to the discard pile */
-            HTC_PACKET_ENQUEUE(&discardQueue, pPacket);
-        }
-
-    } ITERATE_END;
-
-    UNLOCK_HTC_TX(target);
-
-        /* empty the discard queue */
-    while (1) {
-        pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
-        if (NULL == pPacket) {
-            break;
-        }
-        pPacket->Status = A_ECANCELED;
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("  Flushing TX packet:0x%lX, length:%d, ep:%d tag:0x%X \n",
-                (unsigned long)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag));
-        INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
-        DO_EP_TX_COMPLETION(pEndpoint,&container);
-    }
-
-}
-
-void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d  ServiceID: 0x%X    --------------\n",
-                        pEPDist->Endpoint, pEPDist->ServiceID));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%lX next:0x%lX prev:0x%lX\n",
-                (unsigned long)pEPDist, (unsigned long)pEPDist->pNext, (unsigned long)pEPDist->pPrev));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags          : 0x%X \n", pEPDist->DistFlags));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm      : %d \n", pEPDist->TxCreditsNorm));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin       : %d \n", pEPDist->TxCreditsMin));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits          : %d \n", pEPDist->TxCredits));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned  : %d \n", pEPDist->TxCreditsAssigned));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek      : %d \n", pEPDist->TxCreditsSeek));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize       : %d \n", pEPDist->TxCreditSize));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist    : %d \n", pEPDist->TxCreditsToDist));
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth       : %d \n", 
-                    HTC_PACKET_QUEUE_DEPTH(&((struct htc_endpoint *)pEPDist->pHTCReserved)->TxQueue)));                                      
-    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n"));
-}
-
-void DumpCreditDistStates(struct htc_target *target)
-{
-    struct htc_endpoint_credit_dist *pEPList = target->EpCreditDistributionListHead;
-
-    while (pEPList != NULL) {
-        DumpCreditDist(pEPList);
-        pEPList = pEPList->pNext;
-    }
-
-    if (target->DistributeCredits != NULL) {
-        DO_DISTRIBUTION(target,
-                        HTC_DUMP_CREDIT_STATE,
-                        "Dump State",
-                        NULL);
-    }
-}
-
-/* flush all send packets from all endpoint queues */
-void HTCFlushSendPkts(struct htc_target *target)
-{
-    struct htc_endpoint    *pEndpoint;
-    int             i;
-
-    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
-        DumpCreditDistStates(target);
-    }
-
-    for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
-        pEndpoint = &target->EndPoint[i];
-        if (pEndpoint->ServiceID == 0) {
-                /* not in use.. */
-            continue;
-        }
-        HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL);
-    }
-
-
-}
-
-/* HTC API to flush an endpoint's TX queue*/
-void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag)
-{
-    struct htc_target      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    struct htc_endpoint    *pEndpoint = &target->EndPoint[Endpoint];
-
-    if (pEndpoint->ServiceID == 0) {
-        AR_DEBUG_ASSERT(false);
-        /* not in use.. */
-        return;
-    }
-
-    HTCFlushEndpointTX(target, pEndpoint, Tag);
-}
-
-/* HTC API to indicate activity to the credit distribution function */
-void HTCIndicateActivityChange(HTC_HANDLE      HTCHandle,
-                               HTC_ENDPOINT_ID Endpoint,
-                               bool          Active)
-{
-    struct htc_target      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    struct htc_endpoint    *pEndpoint = &target->EndPoint[Endpoint];
-    bool          doDist = false;
-
-    if (pEndpoint->ServiceID == 0) {
-        AR_DEBUG_ASSERT(false);
-        /* not in use.. */
-        return;
-    }
-
-    LOCK_HTC_TX(target);
-
-    if (Active) {
-        if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) {
-                /* mark active now */
-            pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE;
-            doDist = true;
-        }
-    } else {
-        if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
-                /* mark inactive now */
-            pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE;
-            doDist = true;
-        }
-    }
-
-    if (doDist) {
-            /* indicate current Tx Queue depth to the credit distribution function */
-        pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
-        /* do distribution again based on activity change
-         * note, this is done with the lock held */
-        DO_DISTRIBUTION(target,
-                        HTC_CREDIT_DIST_ACTIVITY_CHANGE,
-                        "Activity Change",
-                        target->EpCreditDistributionListHead->pNext);
-    }
-
-    UNLOCK_HTC_TX(target);
-
-    if (doDist && !Active) {
-        /* if a stream went inactive and this resulted in a credit distribution change,
-         * some credits may now be available for HTC packets that are stuck in
-         * HTC queues */
-        HTCCheckEndpointTxQueues(target);
-    }
-}
-
-bool HTCIsEndpointActive(HTC_HANDLE      HTCHandle,
-                           HTC_ENDPOINT_ID Endpoint)
-{
-    struct htc_target      *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    struct htc_endpoint    *pEndpoint = &target->EndPoint[Endpoint];
-
-    if (pEndpoint->ServiceID == 0) {
-        return false;
-    }
-    
-    if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
-        return true;
-    }
-    
-    return false;
-}
diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c
deleted file mode 100644 (file)
index c48070c..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_services.c" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#include "htc_internal.h"
-
-void HTCControlTxComplete(void *Context, struct htc_packet *pPacket)
-{
-        /* not implemented
-         * we do not send control TX frames during normal runtime, only during setup  */
-    AR_DEBUG_ASSERT(false);
-}
-
-    /* callback when a control message arrives on this endpoint */
-void HTCControlRecv(void *Context, struct htc_packet *pPacket)
-{
-    AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0);
-
-    if (pPacket->Status == A_ECANCELED) {
-        /* this is a flush operation, return the control packet back to the pool */
-        HTC_FREE_CONTROL_RX((struct htc_target*)Context,pPacket);    
-        return;
-    }  
-    
-        /* the only control messages we are expecting are NULL messages (credit resports) */   
-    if (pPacket->ActualLength > 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("HTCControlRecv, got message with length:%d \n",
-                        pPacket->ActualLength + (u32)HTC_HDR_LENGTH));
-
-#ifdef ATH_DEBUG_MODULE
-            /* dump header and message */
-        DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
-                       pPacket->ActualLength + HTC_HDR_LENGTH,
-                       "Unexpected ENDPOINT 0 Message");
-#endif
-    }
-
-    HTC_RECYCLE_RX_PKT((struct htc_target*)Context,pPacket,&((struct htc_target*)Context)->EndPoint[0]);
-}
-
-int HTCSendSetupComplete(struct htc_target *target)
-{
-    struct htc_packet             *pSendPacket = NULL;
-    int                status;
-
-    do {
-           /* allocate a packet to send to the target */
-        pSendPacket = HTC_ALLOC_CONTROL_TX(target);
-
-        if (NULL == pSendPacket) {
-            status = A_NO_MEMORY;
-            break;
-        }
-
-        if (target->HTCTargetVersion >= HTC_VERSION_2P1) {
-            HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx;
-            u32 setupFlags = 0;
-                   
-            pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer;
-            A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
-            pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID;   
-            if (target->MaxMsgPerBundle > 0) {
-                    /* host can do HTC bundling, indicate this to the target */
-                setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV; 
-                pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle;
-            }    
-            memcpy(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags));            
-            SET_HTC_PACKET_INFO_TX(pSendPacket,
-                                   NULL,
-                                   (u8 *)pSetupCompleteEx,
-                                   sizeof(HTC_SETUP_COMPLETE_EX_MSG),
-                                   ENDPOINT_0,
-                                   HTC_SERVICE_TX_PACKET_TAG);
-      
-        }  else {            
-            HTC_SETUP_COMPLETE_MSG *pSetupComplete;
-                /* assemble setup complete message */
-            pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer;
-            A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG));
-            pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID;   
-            SET_HTC_PACKET_INFO_TX(pSendPacket,
-                                   NULL,
-                                   (u8 *)pSetupComplete,
-                                   sizeof(HTC_SETUP_COMPLETE_MSG),
-                                   ENDPOINT_0,
-                                   HTC_SERVICE_TX_PACKET_TAG);
-        }
-
-            /* we want synchronous operation */
-        pSendPacket->Completion = NULL;
-        HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
-            /* send the message */
-        status = HTCIssueSend(target,pSendPacket);
-
-    } while (false);
-
-    if (pSendPacket != NULL) {
-        HTC_FREE_CONTROL_TX(target,pSendPacket);
-    }
-
-    return status;
-}
-
-
-int HTCConnectService(HTC_HANDLE               HTCHandle,
-                           struct htc_service_connect_req  *pConnectReq,
-                           struct htc_service_connect_resp *pConnectResp)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    int                            status = 0;
-    struct htc_packet                          *pRecvPacket = NULL;
-    struct htc_packet                          *pSendPacket = NULL;
-    HTC_CONNECT_SERVICE_RESPONSE_MSG    *pResponseMsg;
-    HTC_CONNECT_SERVICE_MSG             *pConnectMsg;
-    HTC_ENDPOINT_ID                     assignedEndpoint = ENDPOINT_MAX;
-    struct htc_endpoint                        *pEndpoint;
-    unsigned int                        maxMsgSize = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%lX SvcID:0x%X \n",
-               (unsigned long)target, pConnectReq->ServiceID));
-
-    do {
-
-        AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);
-
-        if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
-                /* special case for pseudo control service */
-            assignedEndpoint = ENDPOINT_0;
-            maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
-        } else {
-                /* allocate a packet to send to the target */
-            pSendPacket = HTC_ALLOC_CONTROL_TX(target);
-
-            if (NULL == pSendPacket) {
-                AR_DEBUG_ASSERT(false);
-                status = A_NO_MEMORY;
-                break;
-            }
-                /* assemble connect service message */
-            pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
-            AR_DEBUG_ASSERT(pConnectMsg != NULL);
-            A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
-            pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
-            pConnectMsg->ServiceID = pConnectReq->ServiceID;
-            pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
-                /* check caller if it wants to transfer meta data */
-            if ((pConnectReq->pMetaData != NULL) &&
-                (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
-                    /* copy meta data into message buffer (after header ) */
-                memcpy((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
-                         pConnectReq->pMetaData,
-                         pConnectReq->MetaDataLength);
-                pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
-            }
-
-            SET_HTC_PACKET_INFO_TX(pSendPacket,
-                                   NULL,
-                                   (u8 *)pConnectMsg,
-                                   sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength,
-                                   ENDPOINT_0,
-                                   HTC_SERVICE_TX_PACKET_TAG);
-
-                /* we want synchronous operation */
-            pSendPacket->Completion = NULL;
-            HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
-            status = HTCIssueSend(target,pSendPacket);
-
-            if (status) {
-                break;
-            }
-
-                /* wait for response */
-            status = HTCWaitforControlMessage(target, &pRecvPacket);
-
-            if (status) {
-                break;
-            }
-                /* we controlled the buffer creation so it has to be properly aligned */
-            pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer;
-
-            if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
-                (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) {
-                    /* this message is not valid */
-                AR_DEBUG_ASSERT(false);
-                status = A_EPROTO;
-                break;
-            }
-
-            pConnectResp->ConnectRespCode = pResponseMsg->Status;
-                /* check response status */
-            if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    (" Target failed service 0x%X connect request (status:%d)\n",
-                                pResponseMsg->ServiceID, pResponseMsg->Status));
-                status = A_EPROTO;
-                break;
-            }
-
-            assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
-            maxMsgSize = pResponseMsg->MaxMsgSize;
-
-            if ((pConnectResp->pMetaData != NULL) &&
-                (pResponseMsg->ServiceMetaLength > 0) &&
-                (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
-                    /* caller supplied a buffer and the target responded with data */
-                int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength);
-                    /* copy the meta data */
-                memcpy(pConnectResp->pMetaData,
-                         ((u8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG),
-                         copyLength);
-                pConnectResp->ActualLength = copyLength;
-            }
-
-        }
-
-            /* the rest of these are parameter checks so set the error status */
-        status = A_EPROTO;
-
-        if (assignedEndpoint >= ENDPOINT_MAX) {
-            AR_DEBUG_ASSERT(false);
-            break;
-        }
-
-        if (0 == maxMsgSize) {
-            AR_DEBUG_ASSERT(false);
-            break;
-        }
-
-        pEndpoint = &target->EndPoint[assignedEndpoint];
-        pEndpoint->Id = assignedEndpoint;
-        if (pEndpoint->ServiceID != 0) {
-            /* endpoint already in use! */
-            AR_DEBUG_ASSERT(false);
-            break;
-        }
-
-            /* return assigned endpoint to caller */
-        pConnectResp->Endpoint = assignedEndpoint;
-        pConnectResp->MaxMsgLength = maxMsgSize;
-
-            /* setup the endpoint */
-        pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */
-        pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
-        pEndpoint->MaxMsgLength = maxMsgSize;
-            /* copy all the callbacks */
-        pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
-            /* set the credit distribution info for this endpoint, this information is
-             * passed back to the credit distribution callback function */
-        pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
-        pEndpoint->CreditDist.pHTCReserved = pEndpoint;
-        pEndpoint->CreditDist.Endpoint = assignedEndpoint;
-        pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
-        
-        if (pConnectReq->MaxSendMsgSize != 0) {
-                /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications
-                 * since the host will actually issue smaller messages in the Send path */
-            if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
-                    /* can't be larger than the maximum the target can support */
-                AR_DEBUG_ASSERT(false);
-                break;       
-            }
-            pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize;
-        } else {
-            pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;
-        }
-        
-        if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
-            pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
-        }
-        
-            /* save local connection flags */
-        pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
-        
-        status = 0;
-
-    } while (false);
-
-    if (pSendPacket != NULL) {
-        HTC_FREE_CONTROL_TX(target,pSendPacket);
-    }
-
-    if (pRecvPacket != NULL) {
-        HTC_FREE_CONTROL_RX(target,pRecvPacket);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));
-
-    return status;
-}
-
-static void AddToEndpointDistList(struct htc_target *target, struct htc_endpoint_credit_dist *pEpDist)
-{
-    struct htc_endpoint_credit_dist *pCurEntry,*pLastEntry;
-
-    if (NULL == target->EpCreditDistributionListHead) {
-        target->EpCreditDistributionListHead = pEpDist;
-        pEpDist->pNext = NULL;
-        pEpDist->pPrev = NULL;
-        return;
-    }
-
-        /* queue to the end of the list, this does not have to be very
-         * fast since this list is built at startup time */
-    pCurEntry = target->EpCreditDistributionListHead;
-
-    while (pCurEntry) {
-        pLastEntry = pCurEntry;
-        pCurEntry = pCurEntry->pNext;
-    }
-
-    pLastEntry->pNext = pEpDist;
-    pEpDist->pPrev = pLastEntry;
-    pEpDist->pNext = NULL;
-}
-
-
-
-/* default credit init callback */
-static void HTCDefaultCreditInit(void                     *Context,
-                                 struct htc_endpoint_credit_dist *pEPList,
-                                 int                      TotalCredits)
-{
-    struct htc_endpoint_credit_dist *pCurEpDist;
-    int                      totalEps = 0;
-    int                      creditsPerEndpoint;
-
-    pCurEpDist = pEPList;
-        /* first run through the list and figure out how many endpoints we are dealing with */
-    while (pCurEpDist != NULL) {
-        pCurEpDist = pCurEpDist->pNext;
-        totalEps++;
-    }
-
-        /* even distribution */
-    creditsPerEndpoint = TotalCredits/totalEps;
-
-    pCurEpDist = pEPList;
-        /* run through the list and set minimum and normal credits and
-         * provide the endpoint with some credits to start */
-    while (pCurEpDist != NULL) {
-
-        if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) {
-                /* too many endpoints and not enough credits */
-            AR_DEBUG_ASSERT(false);
-            break;
-        }
-            /* our minimum is set for at least 1 max message */
-        pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
-            /* this value is ignored by our credit alg, since we do
-             * not dynamically adjust credits, this is the policy of
-             * the "default" credit distribution, something simple and easy */
-        pCurEpDist->TxCreditsNorm = 0xFFFF;
-            /* give the endpoint minimum credits */
-        pCurEpDist->TxCredits = creditsPerEndpoint;
-        pCurEpDist->TxCreditsAssigned = creditsPerEndpoint;
-        pCurEpDist = pCurEpDist->pNext;
-    }
-
-}
-
-/* default credit distribution callback, NOTE, this callback holds the TX lock */
-void HTCDefaultCreditDist(void                     *Context,
-                          struct htc_endpoint_credit_dist *pEPDistList,
-                          HTC_CREDIT_DIST_REASON   Reason)
-{
-    struct htc_endpoint_credit_dist *pCurEpDist;
-
-    if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) {
-        pCurEpDist = pEPDistList;
-            /* simple distribution */
-        while (pCurEpDist != NULL) {
-            if (pCurEpDist->TxCreditsToDist > 0) {
-                    /* just give the endpoint back the credits */
-                pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
-                pCurEpDist->TxCreditsToDist = 0;
-            }
-            pCurEpDist = pCurEpDist->pNext;
-        }
-    }
-
-    /* note we do not need to handle the other reason codes as this is a very
-     * simple distribution scheme, no need to seek for more credits or handle inactivity */
-}
-
-void HTCSetCreditDistribution(HTC_HANDLE               HTCHandle,
-                              void                     *pCreditDistContext,
-                              HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
-                              HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
-                              HTC_SERVICE_ID           ServicePriorityOrder[],
-                              int                      ListLength)
-{
-    struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
-    int i;
-    int ep;
-
-    if (CreditInitFunc != NULL) {
-            /* caller has supplied their own distribution functions */
-        target->InitCredits = CreditInitFunc;
-        AR_DEBUG_ASSERT(CreditDistFunc != NULL);
-        target->DistributeCredits = CreditDistFunc;
-        target->pCredDistContext = pCreditDistContext;
-    } else {
-        /* caller wants HTC to do distribution */
-        /* if caller wants service to handle distributions then
-         * it must set both of these to NULL! */
-        AR_DEBUG_ASSERT(CreditDistFunc == NULL);
-        target->InitCredits = HTCDefaultCreditInit;
-        target->DistributeCredits = HTCDefaultCreditDist;
-        target->pCredDistContext = target;
-    }
-
-        /* always add HTC control endpoint first, we only expose the list after the
-         * first one, this is added for TX queue checking */
-    AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);
-
-        /* build the list of credit distribution structures in priority order
-         * supplied by the caller, these will follow endpoint 0 */
-    for (i = 0; i < ListLength; i++) {
-            /* match services with endpoints and add the endpoints to the distribution list
-             * in FIFO order */
-        for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
-            if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
-                    /* queue this one to the list */
-                AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
-                break;
-            }
-        }
-        AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
-    }
-
-}
diff --git a/drivers/staging/ath6kl/include/a_config.h b/drivers/staging/ath6kl/include/a_config.h
deleted file mode 100644 (file)
index f7c0931..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="a_config.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 software configuration options that enables
-// specific software "features"
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _A_CONFIG_H_
-#define _A_CONFIG_H_
-
-#include "../os/linux/include/config_linux.h"
-
-#endif
diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h
deleted file mode 100644 (file)
index 5154fcb..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="a_debug.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _A_DEBUG_H_
-#define _A_DEBUG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include <a_osapi.h>
-
-    /* standard debug print masks bits 0..7 */
-#define ATH_DEBUG_ERR   (1 << 0)   /* errors */
-#define ATH_DEBUG_WARN  (1 << 1)   /* warnings */
-#define ATH_DEBUG_INFO  (1 << 2)   /* informational (module startup info) */
-#define ATH_DEBUG_TRC   (1 << 3)   /* generic function call tracing */
-#define ATH_DEBUG_RSVD1 (1 << 4)
-#define ATH_DEBUG_RSVD2 (1 << 5)
-#define ATH_DEBUG_RSVD3 (1 << 6)
-#define ATH_DEBUG_RSVD4 (1 << 7)
-
-#define ATH_DEBUG_MASK_DEFAULTS  (ATH_DEBUG_ERR | ATH_DEBUG_WARN)
-#define ATH_DEBUG_ANY  0xFFFF
-
-    /* other aliases used throughout */
-#define ATH_DEBUG_ERROR   ATH_DEBUG_ERR
-#define ATH_LOG_ERR       ATH_DEBUG_ERR
-#define ATH_LOG_INF       ATH_DEBUG_INFO
-#define ATH_LOG_TRC       ATH_DEBUG_TRC
-#define ATH_DEBUG_TRACE   ATH_DEBUG_TRC
-#define ATH_DEBUG_INIT    ATH_DEBUG_INFO
-
-    /* bits 8..31 are module-specific masks */
-#define ATH_DEBUG_MODULE_MASK_SHIFT   8
-
-    /* macro to make a module-specific masks */
-#define ATH_DEBUG_MAKE_MODULE_MASK(index)  (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
-
-void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription);
-
-/* Debug support on a per-module basis
- *
- * Usage:
- *
- *   Each module can utilize it's own debug mask variable.  A set of commonly used
- *   masks are provided (ERRORS, WARNINGS, TRACE etc..).  It is up to each module
- *   to define module-specific masks using the macros above.
- *
- *   Each module defines a single debug mask variable debug_XXX where the "name" of the module is
- *   common to all C-files within that module.  This requires every C-file that includes a_debug.h
- *   to define the module name in that file.
- *
- *   Example:
- *
- *   #define ATH_MODULE_NAME htc
- *   #include "a_debug.h"
- *
- *   This will define a debug mask structure called debug_htc and all debug macros will reference this
- *   variable.
- *
- *   A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro:
- *
- *      #define ATH_DEBUG_MY_MASK1  ATH_DEBUG_MAKE_MODULE_MASK(0)
- *      #define ATH_DEBUG_MY_MASK2  ATH_DEBUG_MAKE_MODULE_MASK(1)
- *
- *   The instantiation of the debug structure should be made by the module.  When a module is
- *   instantiated, the module can set a description string, a default mask and an array of description
- *   entries containing information on each module-defined debug mask.
- *   NOTE: The instantiation is statically allocated, only one instance can exist per module.
- *
- *   Example:
- *
- *
- *   #define ATH_DEBUG_BMI  ATH_DEBUG_MAKE_MODULE_MASK(0)
- *
- *   #ifdef DEBUG
- *   static struct ath_debug_mask_description bmi_debug_desc[] = {
- *       { ATH_DEBUG_BMI , "BMI Tracing"},   <== description of the module specific mask
- *   };
- *
- *   ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
- *                                    "bmi"  <== module name
- *                                    "Boot Manager Interface",  <== description of module
- *                                    ATH_DEBUG_MASK_DEFAULTS,          <== defaults
- *                                    ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
- *                                    bmi_debug_desc);
- *
- *   #endif
- *
- *  A module can optionally register it's debug module information in order for other tools to change the
- *  bit mask at runtime.  A module can call  A_REGISTER_MODULE_DEBUG_INFO() in it's module
- *  init code.  This macro can be called multiple times without consequence.  The debug info maintains
- *  state to indicate whether the information was previously registered.
- *
- * */
-
-#define ATH_DEBUG_MAX_MASK_DESC_LENGTH   32
-#define ATH_DEBUG_MAX_MOD_DESC_LENGTH    64
-
-struct ath_debug_mask_description {
-    u32 Mask;
-    char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH];
-};
-
-#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0)
-
-typedef struct  _ATH_DEBUG_MODULE_DBG_INFO{
-    struct _ATH_DEBUG_MODULE_DBG_INFO *pNext;
-    char ModuleName[16];
-    char ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH];
-    u32 Flags;
-    u32 CurrentMask;
-    int                         MaxDescriptions;
-    struct ath_debug_mask_description  *pMaskDescriptions; /* pointer to array of descriptions */
-} ATH_DEBUG_MODULE_DBG_INFO;
-
-#define ATH_DEBUG_DESCRIPTION_COUNT(d)  (int)((sizeof((d))) / (sizeof(struct ath_debug_mask_description)))
-
-#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s)
-#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask
-#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s
-
-#ifdef ATH_DEBUG_MODULE
-
-    /* for source files that will instantiate the debug variables */
-#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) \
-ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \
-            {NULL,(name),(moddesc),0,(initmask),count,(descriptions)}
-
-#ifdef ATH_MODULE_NAME
-extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME);
-#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl))
-#endif /* ATH_MODULE_NAME */
-
-#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl)
-
-#define ATH_DEBUG_DECLARE_EXTERN(s) \
-    extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s)
-
-#define AR_DEBUG_PRINTBUF(buffer, length, desc) DebugDumpBytes(buffer,length,desc)
-
-
-#define AR_DEBUG_ASSERT A_ASSERT
-
-void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
-void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
-#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
-#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
-
-#else /* !ATH_DEBUG_MODULE */
-    /* NON ATH_DEBUG_MODULE */
-#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions)
-#define AR_DEBUG_LVL_CHECK(lvl) 0
-#define AR_DEBUG_PRINTBUF(buffer, length, desc)
-#define AR_DEBUG_ASSERT(test)
-#define ATH_DEBUG_DECLARE_EXTERN(s)
-#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl)
-#define A_DUMP_MODULE_DEBUG_INFO(s)
-#define A_REGISTER_MODULE_DEBUG_INFO(s)
-
-#endif
-
-int a_get_module_mask(char *module_name, u32 *pMask);
-int a_set_module_mask(char *module_name, u32 Mask);
-void a_dump_module_debug_info_by_name(char *module_name);
-void a_module_debug_support_init(void);
-void a_module_debug_support_cleanup(void);
-
-#include "../os/linux/include/debug_linux.h"
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/drivers/staging/ath6kl/include/a_drv.h b/drivers/staging/ath6kl/include/a_drv.h
deleted file mode 100644 (file)
index 1548604..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="a_drv.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 basic atheros data types.
-// It is used to map the data types in atheros files to a platform specific
-// type.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _A_DRV_H_
-#define _A_DRV_H_
-
-#include "../os/linux/include/athdrv_linux.h"
-
-#endif /* _ADRV_H_ */
diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h
deleted file mode 100644 (file)
index a40d97a..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="a_drv_api.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _A_DRV_API_H_
-#define _A_DRV_API_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/****************************************************************************/
-/****************************************************************************/
-/**                                                                        **/
-/** WMI related hooks                                                      **/
-/**                                                                        **/
-/****************************************************************************/
-/****************************************************************************/
-
-#include <ar6000_api.h>
-
-#define A_WMI_CHANNELLIST_RX(devt, numChan, chanList)   \
-    ar6000_channelList_rx((devt), (numChan), (chanList))
-
-#define A_WMI_SET_NUMDATAENDPTS(devt, num)  \
-    ar6000_set_numdataendpts((devt), (num))
-
-#define A_WMI_CONTROL_TX(devt, osbuf, streamID) \
-    ar6000_control_tx((devt), (osbuf), (streamID))
-
-#define A_WMI_TARGETSTATS_EVENT(devt, pStats, len)  \
-    ar6000_targetStats_event((devt), (pStats), (len))
-
-#define A_WMI_SCANCOMPLETE_EVENT(devt, status)  \
-    ar6000_scanComplete_event((devt), (status))
-
-#ifdef CONFIG_HOST_DSET_SUPPORT
-
-#define A_WMI_DSET_DATA_REQ(devt, access_cookie, offset, length, targ_buf, targ_reply_fn, targ_reply_arg)   \
-    ar6000_dset_data_req((devt), (access_cookie), (offset), (length), (targ_buf), (targ_reply_fn), (targ_reply_arg))
-
-#define A_WMI_DSET_CLOSE(devt, access_cookie)   \
-    ar6000_dset_close((devt), (access_cookie))
-
-#endif
-
-#define A_WMI_DSET_OPEN_REQ(devt, id, targ_handle, targ_reply_fn, targ_reply_arg) \
-    ar6000_dset_open_req((devt), (id), (targ_handle), (targ_reply_fn), (targ_reply_arg))
-
-#define A_WMI_CONNECT_EVENT(devt, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo) \
-    ar6000_connect_event((devt), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo))
-
-#define A_WMI_PSPOLL_EVENT(devt, aid)\
-    ar6000_pspoll_event((devt),(aid))
-
-#define A_WMI_DTIMEXPIRY_EVENT(devt)\
-    ar6000_dtimexpiry_event((devt))
-
-#ifdef WAPI_ENABLE
-#define A_WMI_WAPI_REKEY_EVENT(devt, type, mac)\
-    ap_wapi_rekey_event((devt),(type),(mac))
-#endif
-
-#define A_WMI_REGDOMAIN_EVENT(devt, regCode)    \
-    ar6000_regDomain_event((devt), (regCode))
-
-#define A_WMI_NEIGHBORREPORT_EVENT(devt, numAps, info)  \
-    ar6000_neighborReport_event((devt), (numAps), (info))
-
-#define A_WMI_DISCONNECT_EVENT(devt, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus)  \
-    ar6000_disconnect_event((devt), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus))
-
-#define A_WMI_TKIP_MICERR_EVENT(devt, keyid, ismcast)   \
-    ar6000_tkip_micerr_event((devt), (keyid), (ismcast))
-
-#define A_WMI_BITRATE_RX(devt, rateKbps)    \
-    ar6000_bitrate_rx((devt), (rateKbps))
-
-#define A_WMI_TXPWR_RX(devt, txPwr) \
-    ar6000_txPwr_rx((devt), (txPwr))
-
-#define A_WMI_READY_EVENT(devt, datap, phyCap, sw_ver, abi_ver) \
-    ar6000_ready_event((devt), (datap), (phyCap), (sw_ver), (abi_ver))
-
-#define A_WMI_DBGLOG_INIT_DONE(ar) \
-    ar6000_dbglog_init_done(ar);
-
-#define A_WMI_RSSI_THRESHOLD_EVENT(devt, newThreshold, rssi)    \
-    ar6000_rssiThreshold_event((devt), (newThreshold), (rssi))
-
-#define A_WMI_REPORT_ERROR_EVENT(devt, errorVal)    \
-    ar6000_reportError_event((devt), (errorVal))
-
-#define A_WMI_ROAM_TABLE_EVENT(devt, pTbl) \
-    ar6000_roam_tbl_event((devt), (pTbl))
-
-#define A_WMI_ROAM_DATA_EVENT(devt, p) \
-    ar6000_roam_data_event((devt), (p))
-
-#define A_WMI_WOW_LIST_EVENT(devt, num_filters, wow_filters)    \
-    ar6000_wow_list_event((devt), (num_filters), (wow_filters))
-
-#define A_WMI_CAC_EVENT(devt, ac, cac_indication, statusCode, tspecSuggestion)  \
-    ar6000_cac_event((devt), (ac), (cac_indication), (statusCode), (tspecSuggestion))
-
-#define A_WMI_CHANNEL_CHANGE_EVENT(devt, oldChannel, newChannel)  \
-    ar6000_channel_change_event((devt), (oldChannel), (newChannel))
-
-#define A_WMI_PMKID_LIST_EVENT(devt, num_pmkid, pmkid_list, bssid_list) \
-    ar6000_pmkid_list_event((devt), (num_pmkid), (pmkid_list), (bssid_list))
-
-#define A_WMI_PEER_EVENT(devt, eventCode, bssid)    \
-    ar6000_peer_event ((devt), (eventCode), (bssid))
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \
-    ar6000_tcmd_rx_report_event((devt), (results), (len))
-#endif
-
-#define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source)    \
-    ar6000_hbChallengeResp_event((devt), (cookie), (source))
-
-#define A_WMI_TX_RETRY_ERR_EVENT(devt) \
-    ar6000_tx_retry_err_event((devt))
-
-#define A_WMI_SNR_THRESHOLD_EVENT_RX(devt, newThreshold, snr) \
-    ar6000_snrThresholdEvent_rx((devt), (newThreshold), (snr))
-
-#define A_WMI_LQ_THRESHOLD_EVENT_RX(devt, range, lqVal) \
-    ar6000_lqThresholdEvent_rx((devt), (range), (lqVal))
-
-#define A_WMI_RATEMASK_RX(devt, ratemask) \
-    ar6000_ratemask_rx((devt), (ratemask))
-
-#define A_WMI_KEEPALIVE_RX(devt, configured)    \
-    ar6000_keepalive_rx((devt), (configured))
-
-#define A_WMI_BSSINFO_EVENT_RX(ar, datp, len)   \
-    ar6000_bssInfo_event_rx((ar), (datap), (len))
-
-#define A_WMI_DBGLOG_EVENT(ar, dropped, buffer, length) \
-    ar6000_dbglog_event((ar), (dropped), (buffer), (length));
-
-#define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \
-    ar6000_indicate_tx_activity((devt),(trafficClass), true)
-
-#define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \
-    ar6000_indicate_tx_activity((devt),(trafficClass), false)
-#define A_WMI_Ac2EndpointID(devht, ac)\
-    ar6000_ac2_endpoint_id((devht), (ac))
-
-#define A_WMI_AGGR_RECV_ADDBA_REQ_EVT(devt, cmd)\
-    ar6000_aggr_rcv_addba_req_evt((devt), (cmd))
-#define A_WMI_AGGR_RECV_ADDBA_RESP_EVT(devt, cmd)\
-    ar6000_aggr_rcv_addba_resp_evt((devt), (cmd))
-#define A_WMI_AGGR_RECV_DELBA_REQ_EVT(devt, cmd)\
-    ar6000_aggr_rcv_delba_req_evt((devt), (cmd))
-#define A_WMI_HCI_EVENT_EVT(devt, cmd)\
-    ar6000_hci_event_rcv_evt((devt), (cmd))
-
-#define A_WMI_Endpoint2Ac(devt, ep) \
-    ar6000_endpoint_id2_ac((devt), (ep))
-
-#define A_WMI_BTCOEX_CONFIG_EVENT(devt, evt, len)\
-       ar6000_btcoex_config_event((devt), (evt), (len))
-
-#define A_WMI_BTCOEX_STATS_EVENT(devt, datap, len)\
-       ar6000_btcoex_stats_event((devt), (datap), (len))
-
-/****************************************************************************/
-/****************************************************************************/
-/**                                                                        **/
-/** HTC related hooks                                                      **/
-/**                                                                        **/
-/****************************************************************************/
-/****************************************************************************/
-
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-#define A_WMI_PROF_COUNT_RX(addr, count) prof_count_rx((addr), (count))
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/staging/ath6kl/include/a_osapi.h b/drivers/staging/ath6kl/include/a_osapi.h
deleted file mode 100644 (file)
index fd7ae0d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="a_osapi.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 basic atheros data types.
-// It is used to map the data types in atheros files to a platform specific
-// type.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _A_OSAPI_H_
-#define _A_OSAPI_H_
-
-#include "../os/linux/include/osapi_linux.h"
-
-#endif /* _OSAPI_H_ */
diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h
deleted file mode 100644 (file)
index 5ead58d..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * 
-//
-// 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 __AGGR_RECV_API_H__
-#define __AGGR_RECV_API_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (* RX_CALLBACK)(void * dev, void *osbuf);
-
-typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, u16 num);
-
-/*
- * aggr_init:
- * Initialises the data structures, allocates data queues and 
- * os buffers. Netbuf allocator is the input param, used by the
- * aggr module for allocation of NETBUFs from driver context.
- * These NETBUFs are used for AMSDU processing.
- * Returns the context for the aggr module.
- */
-void *
-aggr_init(ALLOC_NETBUFS netbuf_allocator);
-
-
-/*
- * aggr_register_rx_dispatcher:
- * Registers OS call back function to deliver the
- * frames to OS. This is generally the topmost layer of
- * the driver context, after which the frames go to
- * IP stack via the call back function.
- * This dispatcher is active only when aggregation is ON.
- */
-void
-aggr_register_rx_dispatcher(void *cntxt, void * dev,  RX_CALLBACK fn);
-
-
-/*
- * aggr_process_bar:
- * When target receives BAR, it communicates to host driver
- * for modifying window parameters. Target indicates this via the 
- * event: WMI_ADDBA_REQ_EVENTID. Host will dequeue all frames
- * up to the indicated sequence number.
- */
-void
-aggr_process_bar(void *cntxt, u8 tid, u16 seq_no);
-
-
-/*
- * aggr_recv_addba_req_evt:
- * This event is to initiate/modify the receive side window.
- * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup 
- * recv re-ordering queues. Target will negotiate ADDBA with peer, 
- * and indicate via this event after successfully completing the 
- * negotiation. This happens in two situations:
- *  1. Initial setup of aggregation
- *  2. Renegotiation of current recv window.
- * Window size for re-ordering is limited by target buffer
- * space, which is reflected in win_sz.
- * (Re)Start the periodic timer to deliver long standing frames,
- * in hold_q to OS.
- */
-void
-aggr_recv_addba_req_evt(void * cntxt, u8 tid, u16 seq_no, u8 win_sz);
-
-
-/*
- * aggr_recv_delba_req_evt:
- * Target indicates deletion of a BA window for a tid via the
- * WMI_DELBA_EVENTID. Host would deliver all the frames in the 
- * hold_q, reset tid config and disable the periodic timer, if 
- * aggr is not enabled on any tid.
- */
-void
-aggr_recv_delba_req_evt(void * cntxt, u8 tid);
-
-
-
-/*
- * aggr_process_recv_frm:
- * Called only for data frames. When aggr is ON for a tid, the buffer 
- * is always consumed, and osbuf would be NULL. For a non-aggr case,
- * osbuf is not modified.
- * AMSDU frames are consumed and are later freed. They are sliced and 
- * diced to individual frames and dispatched to stack.
- * After consuming a osbuf(when aggr is ON), a previously registered
- * callback may be called to deliver frames in order.
- */
-void
-aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf);
-
-
-/*
- * aggr_module_destroy:
- * Frees up all the queues and frames in them. Releases the cntxt to OS.
- */
-void
-aggr_module_destroy(void *cntxt);
-
-/*
- * Dumps the aggregation stats 
- */
-void
-aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf);
-
-/* 
- * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
- *  hold Q state.  Examples include when a Connect event or disconnect event is 
- *  received. 
- */
-void
-aggr_reset_state(void *cntxt);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*__AGGR_RECV_API_H__ */
diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h
deleted file mode 100644 (file)
index 91bc4ee..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-/* AR3K module configuration APIs for HCI-bridge operation */
-
-#ifndef AR3KCONFIG_H_
-#define AR3KCONFIG_H_
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT         (1 << 0)
-#define AR3K_CONFIG_FLAG_SET_AR3K_BAUD              (1 << 1)
-#define AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY     (1 << 2)
-#define AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP        (1 << 3)
-
-
-struct ar3k_config_info {
-    u32 Flags;           /* config flags */
-    void                     *pHCIDev;        /* HCI bridge device     */
-    struct hci_transport_properties *pHCIProps;      /* HCI bridge props      */
-    struct hif_device               *pHIFDevice;     /* HIF layer device      */
-    
-    u32 AR3KBaudRate;    /* AR3K operational baud rate */
-    u16 AR6KScale;       /* AR6K UART scale value */
-    u16 AR6KStep;        /* AR6K UART step value  */
-    struct hci_dev           *pBtStackHCIDev; /* BT Stack HCI dev */
-    u32 PwrMgmtEnabled;  /* TLPM enabled? */
-    u16 IdleTimeout;     /* TLPM idle timeout */
-    u16 WakeupTimeout;   /* TLPM wakeup timeout */
-    u8 bdaddr[6];       /* Bluetooth device address */
-};
-                                                                                        
-int AR3KConfigure(struct ar3k_config_info *pConfigInfo);
-
-int AR3KConfigureExit(void *config);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*AR3KCONFIG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6000_api.h b/drivers/staging/ath6kl/include/ar6000_api.h
deleted file mode 100644 (file)
index e946080..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6000_api.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 API to access the OS dependent atheros host driver
-// by the WMI or WLAN generic modules.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _AR6000_API_H_
-#define _AR6000_API_H_
-
-#include "../os/linux/include/ar6xapi_linux.h"
-
-#endif /* _AR6000_API_H */
-
diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h
deleted file mode 100644 (file)
index 739c01c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ar6000_diag.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef AR6000_DIAG_H_
-#define AR6000_DIAG_H_
-
-
-int
-ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
-
-int
-ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
-
-int
-ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
-                    u8 *data, u32 length);
-
-int
-ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
-                     u8 *data, u32 length);
-
-int
-ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval);
-
-void
-ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs);
-
-#endif /*AR6000_DIAG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6kap_common.h b/drivers/staging/ath6kl/include/ar6kap_common.h
deleted file mode 100644 (file)
index 532d8eb..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-//------------------------------------------------------------------------------
-
-// <copyright file="ar6kap_common.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 common AP mode data structures.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef _AR6KAP_COMMON_H_
-#define _AR6KAP_COMMON_H_
-/*
- * Used with AR6000_XIOCTL_AP_GET_STA_LIST
- */
-typedef struct {
-    u8 mac[ATH_MAC_LEN];
-    u8 aid;
-    u8 keymgmt;
-    u8 ucipher;
-    u8 auth;
-} station_t;
-typedef struct {
-    station_t sta[AP_MAX_NUM_STA];
-} ap_get_sta_t;
-#endif /* _AR6KAP_COMMON_H_ */
diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h
deleted file mode 100644 (file)
index 81456ee..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="athbtfilter.h" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Public Bluetooth filter APIs
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef ATHBTFILTER_H_
-#define ATHBTFILTER_H_
-
-#define ATH_DEBUG_INFO  (1 << 2)
-#define ATH_DEBUG_INF    ATH_DEBUG_INFO
-
-typedef enum _ATHBT_HCI_CTRL_TYPE {
-    ATHBT_HCI_COMMAND     = 0,
-    ATHBT_HCI_EVENT       = 1,
-} ATHBT_HCI_CTRL_TYPE;
-
-typedef enum _ATHBT_STATE_INDICATION {
-    ATH_BT_NOOP        = 0,
-    ATH_BT_INQUIRY     = 1,
-    ATH_BT_CONNECT     = 2,
-    ATH_BT_SCO         = 3,
-    ATH_BT_ACL         = 4,
-    ATH_BT_A2DP        = 5,
-    ATH_BT_ESCO        = 6,
-    /* new states go here.. */
-
-    ATH_BT_MAX_STATE_INDICATION
-} ATHBT_STATE_INDICATION;
-
-    /* filter function for OUTGOING commands and INCOMMING events */
-typedef void   (*ATHBT_FILTER_CMD_EVENTS_FN)(void *pContext, ATHBT_HCI_CTRL_TYPE Type, unsigned char *pBuffer, int Length);
-
-    /* filter function for OUTGOING data HCI packets */
-typedef void   (*ATHBT_FILTER_DATA_FN)(void *pContext, unsigned char *pBuffer, int Length);
-
-typedef enum _ATHBT_STATE {
-    STATE_OFF  = 0,
-    STATE_ON   = 1,
-    STATE_MAX
-} ATHBT_STATE;
-
-    /* BT state indication (when filter functions are not used) */
-
-typedef void   (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion);
-
-struct athbt_filter_instance {
-#ifdef UNDER_CE
-    WCHAR                       *pWlanAdapterName;  /* filled in by user */
-#else
-    char *pWlanAdapterName;  /* filled in by user */
-#endif /* UNDER_CE */
-    int                         FilterEnabled;      /* filtering is enabled */
-    int                         Attached;           /* filter library is attached */
-    void                        *pContext;          /* private context for filter library */
-    ATHBT_FILTER_CMD_EVENTS_FN  pFilterCmdEvents;   /* function ptr to filter a command or event */
-    ATHBT_FILTER_DATA_FN        pFilterAclDataOut;  /* function ptr to filter ACL data out (to radio) */
-    ATHBT_FILTER_DATA_FN        pFilterAclDataIn;   /* function ptr to filter ACL data in (from radio) */
-    ATHBT_INDICATE_STATE_FN     pIndicateState;     /* function ptr to indicate a state */
-}; /* XXX: unused ? */
-
-
-/* API MACROS */
-
-#define AthBtFilterHciCommand(instance,packet,length)          \
-    if ((instance)->FilterEnabled) {                           \
-        (instance)->pFilterCmdEvents((instance)->pContext,     \
-                                   ATHBT_HCI_COMMAND,          \
-                                   (unsigned char *)(packet),  \
-                                   (length));                  \
-    }
-
-#define AthBtFilterHciEvent(instance,packet,length)            \
-    if ((instance)->FilterEnabled) {                           \
-        (instance)->pFilterCmdEvents((instance)->pContext,     \
-                                   ATHBT_HCI_EVENT,            \
-                                   (unsigned char *)(packet),  \
-                                   (length));                  \
-    }
-
-#define AthBtFilterHciAclDataOut(instance,packet,length)     \
-    if ((instance)->FilterEnabled) {                         \
-        (instance)->pFilterAclDataOut((instance)->pContext,  \
-                                 (unsigned char *)(packet),  \
-                                 (length));                  \
-    }
-
-#define AthBtFilterHciAclDataIn(instance,packet,length)      \
-    if ((instance)->FilterEnabled) {                         \
-        (instance)->pFilterAclDataIn((instance)->pContext,   \
-                                 (unsigned char *)(packet),  \
-                                 (length));                  \
-    }
-        
-/* if filtering is not desired, the application can indicate the state directly using this
- * macro:
- */
-#define AthBtIndicateState(instance,indication,state)           \
-    if ((instance)->FilterEnabled) {                            \
-        (instance)->pIndicateState((instance)->pContext,        \
-                                   (indication),                \
-                                   (state),                     \
-                                   0);                          \
-    }
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* API prototypes */
-int     AthBtFilter_Attach(ATH_BT_FILTER_INSTANCE *pInstance, unsigned int flags);
-void    AthBtFilter_Detach(ATH_BT_FILTER_INSTANCE *pInstance);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*ATHBTFILTER_H_*/
diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h
deleted file mode 100644 (file)
index d3227f7..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="bmi.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// BMI declarations and prototypes
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _BMI_H_
-#define _BMI_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Header files */
-#include "a_config.h"
-#include "athdefs.h"
-#include "hif.h"
-#include "a_osapi.h"
-#include "bmi_msg.h"
-
-void
-BMIInit(void);
-
-void
-BMICleanup(void);
-
-int
-BMIDone(struct hif_device *device);
-
-int
-BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info);
-
-int
-BMIReadMemory(struct hif_device *device,
-              u32 address,
-              u8 *buffer,
-              u32 length);
-
-int
-BMIWriteMemory(struct hif_device *device,
-               u32 address,
-               u8 *buffer,
-               u32 length);
-
-int
-BMIExecute(struct hif_device *device,
-           u32 address,
-           u32 *param);
-
-int
-BMISetAppStart(struct hif_device *device,
-               u32 address);
-
-int
-BMIReadSOCRegister(struct hif_device *device,
-                   u32 address,
-                   u32 *param);
-
-int
-BMIWriteSOCRegister(struct hif_device *device,
-                    u32 address,
-                    u32 param);
-
-int
-BMIrompatchInstall(struct hif_device *device,
-                   u32 ROM_addr,
-                   u32 RAM_addr,
-                   u32 nbytes,
-                   u32 do_activate,
-                   u32 *patch_id);
-
-int
-BMIrompatchUninstall(struct hif_device *device,
-                     u32 rompatch_id);
-
-int
-BMIrompatchActivate(struct hif_device *device,
-                    u32 rompatch_count,
-                    u32 *rompatch_list);
-
-int
-BMIrompatchDeactivate(struct hif_device *device,
-                      u32 rompatch_count,
-                      u32 *rompatch_list);
-
-int
-BMILZStreamStart(struct hif_device *device,
-                 u32 address);
-
-int
-BMILZData(struct hif_device *device,
-          u8 *buffer,
-          u32 length);
-
-int
-BMIFastDownload(struct hif_device *device,
-                u32 address,
-                u8 *buffer,
-                u32 length);
-
-int
-BMIRawWrite(struct hif_device *device,
-            u8 *buffer,
-            u32 length);
-
-int
-BMIRawRead(struct hif_device *device, 
-           u8 *buffer, 
-           u32 length,
-           bool want_timeout);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
deleted file mode 100644 (file)
index 5407e05..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="AR6K_version.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#define __VER_MAJOR_ 3
-#define __VER_MINOR_ 0 
-#define __VER_PATCH_ 0
-
-/* The makear6ksdk script (used for release builds) modifies the following line. */
-#define __BUILD_NUMBER_ 233
-
-
-/* Format of the version number. */
-#define VER_MAJOR_BIT_OFFSET        28
-#define VER_MINOR_BIT_OFFSET        24
-#define VER_PATCH_BIT_OFFSET        16
-#define VER_BUILD_NUM_BIT_OFFSET    0
-
-
-/*
- * The version has the following format:
- * Bits 28-31: Major version
- * Bits 24-27: Minor version
- * Bits 16-23: Patch version
- * Bits 0-15:  Build number (automatically generated during build process )
- * E.g. Build 1.1.3.7 would be represented as 0x11030007.
- *
- * DO NOT split the following macro into multiple lines as this may confuse the build scripts.
- */
-#define AR6K_SW_VERSION     ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) )
-
-/* ABI Version. Reflects the version of binary interface exposed by AR6K target firmware. Needs to be incremented by 1 for any change in the firmware that requires upgrade of the driver on the host side for the change to work correctly */
-#define AR6K_ABI_VERSION        1
diff --git a/drivers/staging/ath6kl/include/common/AR6002/addrs.h b/drivers/staging/ath6kl/include/common/AR6002/addrs.h
deleted file mode 100644 (file)
index bbf8d42..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-//
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef __ADDRS_H__
-#define __ADDRS_H__
-
-/*
- * Special AR6002 Addresses that may be needed by special
- * applications (e.g. ART) on the Host as well as Target.
- */
-
-#if defined(AR6002_REV2)
-#define AR6K_RAM_START 0x00500000
-#define TARG_RAM_OFFSET(vaddr) ((u32)(vaddr) & 0xfffff)
-#define TARG_RAM_SZ (184*1024)
-#define TARG_ROM_SZ (80*1024)
-#endif
-#if defined(AR6002_REV4) || defined(AR6003)
-#define AR6K_RAM_START 0x00540000
-#define TARG_RAM_OFFSET(vaddr) (((u32)(vaddr) & 0xfffff) - 0x40000)
-#define TARG_RAM_SZ (256*1024)
-#define TARG_ROM_SZ (256*1024)
-#endif
-
-#define AR6002_BOARD_DATA_SZ 768
-#define AR6002_BOARD_EXT_DATA_SZ 0
-#define AR6003_BOARD_DATA_SZ 1024
-#define AR6003_BOARD_EXT_DATA_SZ 768
-
-#define AR6K_RAM_ADDR(byte_offset) (AR6K_RAM_START+(byte_offset))
-#define TARG_RAM_ADDRS(byte_offset) AR6K_RAM_ADDR(byte_offset)
-
-#define AR6K_ROM_START 0x004e0000
-#define TARG_ROM_OFFSET(vaddr) (((u32)(vaddr) & 0x1fffff) - 0xe0000)
-#define AR6K_ROM_ADDR(byte_offset) (AR6K_ROM_START+(byte_offset))
-#define TARG_ROM_ADDRS(byte_offset) AR6K_ROM_ADDR(byte_offset)
-
-/*
- * At this ROM address is a pointer to the start of the ROM DataSet Index.
- * If there are no ROM DataSets, there's a 0 at this address.
- */
-#define ROM_DATASET_INDEX_ADDR          (TARG_ROM_ADDRS(TARG_ROM_SZ)-8)
-#define ROM_MBIST_CKSUM_ADDR            (TARG_ROM_ADDRS(TARG_ROM_SZ)-4)
-
-/*
- * The API A_BOARD_DATA_ADDR() is the proper way to get a read pointer to
- * board data.
- */
-
-/* Size of Board Data, in bytes */
-#if defined(AR6002_REV4) || defined(AR6003)
-#define BOARD_DATA_SZ AR6003_BOARD_DATA_SZ
-#else
-#define BOARD_DATA_SZ AR6002_BOARD_DATA_SZ
-#endif
-
-
-/*
- * Constants used by ASM code to access fields of host_interest_s,
- * which is at a fixed location in RAM.
- */
-#if defined(AR6002_REV4) || defined(AR6003)
-#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR  (AR6K_RAM_START + 0x60c)
-#else
-#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR  (AR6K_RAM_START + 0x40c)
-#endif
-#define FLASH_IS_PRESENT_TARGADDR       HOST_INTEREST_FLASH_IS_PRESENT_ADDR
-
-#endif /* __ADDRS_H__ */
-
-
-
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
deleted file mode 100644 (file)
index 609eb98..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _APB_ATHR_WLAN_MAP_H_
-#define _APB_ATHR_WLAN_MAP_H_
-
-#define WLAN_RTC_BASE_ADDRESS                    0x00004000
-#define WLAN_VMC_BASE_ADDRESS                    0x00008000
-#define WLAN_UART_BASE_ADDRESS                   0x0000c000
-#define WLAN_DBG_UART_BASE_ADDRESS               0x0000d000
-#define WLAN_UMBOX_BASE_ADDRESS                  0x0000e000
-#define WLAN_SI_BASE_ADDRESS                     0x00010000
-#define WLAN_GPIO_BASE_ADDRESS                   0x00014000
-#define WLAN_MBOX_BASE_ADDRESS                   0x00018000
-#define WLAN_ANALOG_INTF_BASE_ADDRESS            0x0001c000
-#define WLAN_MAC_BASE_ADDRESS                    0x00020000
-#define WLAN_RDMA_BASE_ADDRESS                   0x00030100
-#define EFUSE_BASE_ADDRESS                       0x00031000
-
-#endif /* _APB_ATHR_WLAN_MAP_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
deleted file mode 100644 (file)
index 0068ca3..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#include "apb_athr_wlan_map.h"
-
-#ifndef BT_HEADERS
-
-#define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS
-#define VMC_BASE_ADDRESS WLAN_VMC_BASE_ADDRESS
-#define UART_BASE_ADDRESS WLAN_UART_BASE_ADDRESS
-#define DBG_UART_BASE_ADDRESS WLAN_DBG_UART_BASE_ADDRESS
-#define UMBOX_BASE_ADDRESS WLAN_UMBOX_BASE_ADDRESS
-#define SI_BASE_ADDRESS WLAN_SI_BASE_ADDRESS
-#define GPIO_BASE_ADDRESS WLAN_GPIO_BASE_ADDRESS
-#define MBOX_BASE_ADDRESS WLAN_MBOX_BASE_ADDRESS
-#define ANALOG_INTF_BASE_ADDRESS WLAN_ANALOG_INTF_BASE_ADDRESS
-#define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS
-#define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS
-
-#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
deleted file mode 100644 (file)
index 109f24e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#include "mbox_wlan_host_reg.h"
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
deleted file mode 100644 (file)
index 72fa483..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#include "mbox_wlan_reg.h"
-
-#ifndef BT_HEADERS
-
-#define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS
-#define MBOX_FIFO_OFFSET WLAN_MBOX_FIFO_OFFSET
-#define MBOX_FIFO_DATA_MSB WLAN_MBOX_FIFO_DATA_MSB
-#define MBOX_FIFO_DATA_LSB WLAN_MBOX_FIFO_DATA_LSB
-#define MBOX_FIFO_DATA_MASK WLAN_MBOX_FIFO_DATA_MASK
-#define MBOX_FIFO_DATA_GET(x) WLAN_MBOX_FIFO_DATA_GET(x)
-#define MBOX_FIFO_DATA_SET(x) WLAN_MBOX_FIFO_DATA_SET(x)
-#define MBOX_FIFO_STATUS_ADDRESS WLAN_MBOX_FIFO_STATUS_ADDRESS
-#define MBOX_FIFO_STATUS_OFFSET WLAN_MBOX_FIFO_STATUS_OFFSET
-#define MBOX_FIFO_STATUS_EMPTY_MSB WLAN_MBOX_FIFO_STATUS_EMPTY_MSB
-#define MBOX_FIFO_STATUS_EMPTY_LSB WLAN_MBOX_FIFO_STATUS_EMPTY_LSB
-#define MBOX_FIFO_STATUS_EMPTY_MASK WLAN_MBOX_FIFO_STATUS_EMPTY_MASK
-#define MBOX_FIFO_STATUS_EMPTY_GET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x)
-#define MBOX_FIFO_STATUS_EMPTY_SET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x)
-#define MBOX_FIFO_STATUS_FULL_MSB WLAN_MBOX_FIFO_STATUS_FULL_MSB
-#define MBOX_FIFO_STATUS_FULL_LSB WLAN_MBOX_FIFO_STATUS_FULL_LSB
-#define MBOX_FIFO_STATUS_FULL_MASK WLAN_MBOX_FIFO_STATUS_FULL_MASK
-#define MBOX_FIFO_STATUS_FULL_GET(x) WLAN_MBOX_FIFO_STATUS_FULL_GET(x)
-#define MBOX_FIFO_STATUS_FULL_SET(x) WLAN_MBOX_FIFO_STATUS_FULL_SET(x)
-#define MBOX_DMA_POLICY_ADDRESS WLAN_MBOX_DMA_POLICY_ADDRESS
-#define MBOX_DMA_POLICY_OFFSET WLAN_MBOX_DMA_POLICY_OFFSET
-#define MBOX_DMA_POLICY_TX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB
-#define MBOX_DMA_POLICY_TX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB
-#define MBOX_DMA_POLICY_TX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK
-#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x)
-#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x)
-#define MBOX_DMA_POLICY_TX_ORDER_MSB WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB
-#define MBOX_DMA_POLICY_TX_ORDER_LSB WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB
-#define MBOX_DMA_POLICY_TX_ORDER_MASK WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK
-#define MBOX_DMA_POLICY_TX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x)
-#define MBOX_DMA_POLICY_TX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x)
-#define MBOX_DMA_POLICY_RX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB
-#define MBOX_DMA_POLICY_RX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB
-#define MBOX_DMA_POLICY_RX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK
-#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x)
-#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x)
-#define MBOX_DMA_POLICY_RX_ORDER_MSB WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB
-#define MBOX_DMA_POLICY_RX_ORDER_LSB WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB
-#define MBOX_DMA_POLICY_RX_ORDER_MASK WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK
-#define MBOX_DMA_POLICY_RX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x)
-#define MBOX_DMA_POLICY_RX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x)
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX0_DMA_RX_CONTROL_ADDRESS WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS
-#define MBOX0_DMA_RX_CONTROL_OFFSET WLAN_MBOX0_DMA_RX_CONTROL_OFFSET
-#define MBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB
-#define MBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB
-#define MBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK
-#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x)
-#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x)
-#define MBOX0_DMA_RX_CONTROL_START_MSB WLAN_MBOX0_DMA_RX_CONTROL_START_MSB
-#define MBOX0_DMA_RX_CONTROL_START_LSB WLAN_MBOX0_DMA_RX_CONTROL_START_LSB
-#define MBOX0_DMA_RX_CONTROL_START_MASK WLAN_MBOX0_DMA_RX_CONTROL_START_MASK
-#define MBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x)
-#define MBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x)
-#define MBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB
-#define MBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB
-#define MBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK
-#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x)
-#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x)
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX0_DMA_TX_CONTROL_ADDRESS WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS
-#define MBOX0_DMA_TX_CONTROL_OFFSET WLAN_MBOX0_DMA_TX_CONTROL_OFFSET
-#define MBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB
-#define MBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB
-#define MBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK
-#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x)
-#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x)
-#define MBOX0_DMA_TX_CONTROL_START_MSB WLAN_MBOX0_DMA_TX_CONTROL_START_MSB
-#define MBOX0_DMA_TX_CONTROL_START_LSB WLAN_MBOX0_DMA_TX_CONTROL_START_LSB
-#define MBOX0_DMA_TX_CONTROL_START_MASK WLAN_MBOX0_DMA_TX_CONTROL_START_MASK
-#define MBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x)
-#define MBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x)
-#define MBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB
-#define MBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB
-#define MBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK
-#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x)
-#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x)
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX1_DMA_RX_CONTROL_ADDRESS WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS
-#define MBOX1_DMA_RX_CONTROL_OFFSET WLAN_MBOX1_DMA_RX_CONTROL_OFFSET
-#define MBOX1_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB
-#define MBOX1_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB
-#define MBOX1_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK
-#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x)
-#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x)
-#define MBOX1_DMA_RX_CONTROL_START_MSB WLAN_MBOX1_DMA_RX_CONTROL_START_MSB
-#define MBOX1_DMA_RX_CONTROL_START_LSB WLAN_MBOX1_DMA_RX_CONTROL_START_LSB
-#define MBOX1_DMA_RX_CONTROL_START_MASK WLAN_MBOX1_DMA_RX_CONTROL_START_MASK
-#define MBOX1_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x)
-#define MBOX1_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x)
-#define MBOX1_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB
-#define MBOX1_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB
-#define MBOX1_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK
-#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x)
-#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x)
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX1_DMA_TX_CONTROL_ADDRESS WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS
-#define MBOX1_DMA_TX_CONTROL_OFFSET WLAN_MBOX1_DMA_TX_CONTROL_OFFSET
-#define MBOX1_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB
-#define MBOX1_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB
-#define MBOX1_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK
-#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x)
-#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x)
-#define MBOX1_DMA_TX_CONTROL_START_MSB WLAN_MBOX1_DMA_TX_CONTROL_START_MSB
-#define MBOX1_DMA_TX_CONTROL_START_LSB WLAN_MBOX1_DMA_TX_CONTROL_START_LSB
-#define MBOX1_DMA_TX_CONTROL_START_MASK WLAN_MBOX1_DMA_TX_CONTROL_START_MASK
-#define MBOX1_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x)
-#define MBOX1_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x)
-#define MBOX1_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB
-#define MBOX1_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB
-#define MBOX1_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK
-#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x)
-#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x)
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX2_DMA_RX_CONTROL_ADDRESS WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS
-#define MBOX2_DMA_RX_CONTROL_OFFSET WLAN_MBOX2_DMA_RX_CONTROL_OFFSET
-#define MBOX2_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB
-#define MBOX2_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB
-#define MBOX2_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK
-#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x)
-#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x)
-#define MBOX2_DMA_RX_CONTROL_START_MSB WLAN_MBOX2_DMA_RX_CONTROL_START_MSB
-#define MBOX2_DMA_RX_CONTROL_START_LSB WLAN_MBOX2_DMA_RX_CONTROL_START_LSB
-#define MBOX2_DMA_RX_CONTROL_START_MASK WLAN_MBOX2_DMA_RX_CONTROL_START_MASK
-#define MBOX2_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x)
-#define MBOX2_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x)
-#define MBOX2_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB
-#define MBOX2_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB
-#define MBOX2_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK
-#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x)
-#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x)
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX2_DMA_TX_CONTROL_ADDRESS WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS
-#define MBOX2_DMA_TX_CONTROL_OFFSET WLAN_MBOX2_DMA_TX_CONTROL_OFFSET
-#define MBOX2_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB
-#define MBOX2_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB
-#define MBOX2_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK
-#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x)
-#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x)
-#define MBOX2_DMA_TX_CONTROL_START_MSB WLAN_MBOX2_DMA_TX_CONTROL_START_MSB
-#define MBOX2_DMA_TX_CONTROL_START_LSB WLAN_MBOX2_DMA_TX_CONTROL_START_LSB
-#define MBOX2_DMA_TX_CONTROL_START_MASK WLAN_MBOX2_DMA_TX_CONTROL_START_MASK
-#define MBOX2_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x)
-#define MBOX2_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x)
-#define MBOX2_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB
-#define MBOX2_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB
-#define MBOX2_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK
-#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x)
-#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x)
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX3_DMA_RX_CONTROL_ADDRESS WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS
-#define MBOX3_DMA_RX_CONTROL_OFFSET WLAN_MBOX3_DMA_RX_CONTROL_OFFSET
-#define MBOX3_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB
-#define MBOX3_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB
-#define MBOX3_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK
-#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x)
-#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x)
-#define MBOX3_DMA_RX_CONTROL_START_MSB WLAN_MBOX3_DMA_RX_CONTROL_START_MSB
-#define MBOX3_DMA_RX_CONTROL_START_LSB WLAN_MBOX3_DMA_RX_CONTROL_START_LSB
-#define MBOX3_DMA_RX_CONTROL_START_MASK WLAN_MBOX3_DMA_RX_CONTROL_START_MASK
-#define MBOX3_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x)
-#define MBOX3_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x)
-#define MBOX3_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB
-#define MBOX3_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB
-#define MBOX3_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK
-#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x)
-#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x)
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define MBOX3_DMA_TX_CONTROL_ADDRESS WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS
-#define MBOX3_DMA_TX_CONTROL_OFFSET WLAN_MBOX3_DMA_TX_CONTROL_OFFSET
-#define MBOX3_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB
-#define MBOX3_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB
-#define MBOX3_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK
-#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x)
-#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x)
-#define MBOX3_DMA_TX_CONTROL_START_MSB WLAN_MBOX3_DMA_TX_CONTROL_START_MSB
-#define MBOX3_DMA_TX_CONTROL_START_LSB WLAN_MBOX3_DMA_TX_CONTROL_START_LSB
-#define MBOX3_DMA_TX_CONTROL_START_MASK WLAN_MBOX3_DMA_TX_CONTROL_START_MASK
-#define MBOX3_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x)
-#define MBOX3_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x)
-#define MBOX3_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB
-#define MBOX3_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB
-#define MBOX3_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK
-#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x)
-#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x)
-#define MBOX_INT_STATUS_ADDRESS WLAN_MBOX_INT_STATUS_ADDRESS
-#define MBOX_INT_STATUS_OFFSET WLAN_MBOX_INT_STATUS_OFFSET
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
-#define MBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB
-#define MBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB
-#define MBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK
-#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x)
-#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x)
-#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB
-#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB
-#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK
-#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
-#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
-#define MBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB
-#define MBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB
-#define MBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK
-#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x)
-#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x)
-#define MBOX_INT_STATUS_HOST_MSB WLAN_MBOX_INT_STATUS_HOST_MSB
-#define MBOX_INT_STATUS_HOST_LSB WLAN_MBOX_INT_STATUS_HOST_LSB
-#define MBOX_INT_STATUS_HOST_MASK WLAN_MBOX_INT_STATUS_HOST_MASK
-#define MBOX_INT_STATUS_HOST_GET(x) WLAN_MBOX_INT_STATUS_HOST_GET(x)
-#define MBOX_INT_STATUS_HOST_SET(x) WLAN_MBOX_INT_STATUS_HOST_SET(x)
-#define MBOX_INT_ENABLE_ADDRESS WLAN_MBOX_INT_ENABLE_ADDRESS
-#define MBOX_INT_ENABLE_OFFSET WLAN_MBOX_INT_ENABLE_OFFSET
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
-#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB
-#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB
-#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK
-#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
-#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
-#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB
-#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB
-#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK
-#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
-#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
-#define MBOX_INT_ENABLE_HOST_MSB WLAN_MBOX_INT_ENABLE_HOST_MSB
-#define MBOX_INT_ENABLE_HOST_LSB WLAN_MBOX_INT_ENABLE_HOST_LSB
-#define MBOX_INT_ENABLE_HOST_MASK WLAN_MBOX_INT_ENABLE_HOST_MASK
-#define MBOX_INT_ENABLE_HOST_GET(x) WLAN_MBOX_INT_ENABLE_HOST_GET(x)
-#define MBOX_INT_ENABLE_HOST_SET(x) WLAN_MBOX_INT_ENABLE_HOST_SET(x)
-#define INT_HOST_ADDRESS WLAN_INT_HOST_ADDRESS
-#define INT_HOST_OFFSET WLAN_INT_HOST_OFFSET
-#define INT_HOST_VECTOR_MSB WLAN_INT_HOST_VECTOR_MSB
-#define INT_HOST_VECTOR_LSB WLAN_INT_HOST_VECTOR_LSB
-#define INT_HOST_VECTOR_MASK WLAN_INT_HOST_VECTOR_MASK
-#define INT_HOST_VECTOR_GET(x) WLAN_INT_HOST_VECTOR_GET(x)
-#define INT_HOST_VECTOR_SET(x) WLAN_INT_HOST_VECTOR_SET(x)
-#define LOCAL_COUNT_ADDRESS WLAN_LOCAL_COUNT_ADDRESS
-#define LOCAL_COUNT_OFFSET WLAN_LOCAL_COUNT_OFFSET
-#define LOCAL_COUNT_VALUE_MSB WLAN_LOCAL_COUNT_VALUE_MSB
-#define LOCAL_COUNT_VALUE_LSB WLAN_LOCAL_COUNT_VALUE_LSB
-#define LOCAL_COUNT_VALUE_MASK WLAN_LOCAL_COUNT_VALUE_MASK
-#define LOCAL_COUNT_VALUE_GET(x) WLAN_LOCAL_COUNT_VALUE_GET(x)
-#define LOCAL_COUNT_VALUE_SET(x) WLAN_LOCAL_COUNT_VALUE_SET(x)
-#define COUNT_INC_ADDRESS WLAN_COUNT_INC_ADDRESS
-#define COUNT_INC_OFFSET WLAN_COUNT_INC_OFFSET
-#define COUNT_INC_VALUE_MSB WLAN_COUNT_INC_VALUE_MSB
-#define COUNT_INC_VALUE_LSB WLAN_COUNT_INC_VALUE_LSB
-#define COUNT_INC_VALUE_MASK WLAN_COUNT_INC_VALUE_MASK
-#define COUNT_INC_VALUE_GET(x) WLAN_COUNT_INC_VALUE_GET(x)
-#define COUNT_INC_VALUE_SET(x) WLAN_COUNT_INC_VALUE_SET(x)
-#define LOCAL_SCRATCH_ADDRESS WLAN_LOCAL_SCRATCH_ADDRESS
-#define LOCAL_SCRATCH_OFFSET WLAN_LOCAL_SCRATCH_OFFSET
-#define LOCAL_SCRATCH_VALUE_MSB WLAN_LOCAL_SCRATCH_VALUE_MSB
-#define LOCAL_SCRATCH_VALUE_LSB WLAN_LOCAL_SCRATCH_VALUE_LSB
-#define LOCAL_SCRATCH_VALUE_MASK WLAN_LOCAL_SCRATCH_VALUE_MASK
-#define LOCAL_SCRATCH_VALUE_GET(x) WLAN_LOCAL_SCRATCH_VALUE_GET(x)
-#define LOCAL_SCRATCH_VALUE_SET(x) WLAN_LOCAL_SCRATCH_VALUE_SET(x)
-#define USE_LOCAL_BUS_ADDRESS WLAN_USE_LOCAL_BUS_ADDRESS
-#define USE_LOCAL_BUS_OFFSET WLAN_USE_LOCAL_BUS_OFFSET
-#define USE_LOCAL_BUS_PIN_INIT_MSB WLAN_USE_LOCAL_BUS_PIN_INIT_MSB
-#define USE_LOCAL_BUS_PIN_INIT_LSB WLAN_USE_LOCAL_BUS_PIN_INIT_LSB
-#define USE_LOCAL_BUS_PIN_INIT_MASK WLAN_USE_LOCAL_BUS_PIN_INIT_MASK
-#define USE_LOCAL_BUS_PIN_INIT_GET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x)
-#define USE_LOCAL_BUS_PIN_INIT_SET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x)
-#define SDIO_CONFIG_ADDRESS WLAN_SDIO_CONFIG_ADDRESS
-#define SDIO_CONFIG_OFFSET WLAN_SDIO_CONFIG_OFFSET
-#define SDIO_CONFIG_CCCR_IOR1_MSB WLAN_SDIO_CONFIG_CCCR_IOR1_MSB
-#define SDIO_CONFIG_CCCR_IOR1_LSB WLAN_SDIO_CONFIG_CCCR_IOR1_LSB
-#define SDIO_CONFIG_CCCR_IOR1_MASK WLAN_SDIO_CONFIG_CCCR_IOR1_MASK
-#define SDIO_CONFIG_CCCR_IOR1_GET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x)
-#define SDIO_CONFIG_CCCR_IOR1_SET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x)
-#define MBOX_DEBUG_ADDRESS WLAN_MBOX_DEBUG_ADDRESS
-#define MBOX_DEBUG_OFFSET WLAN_MBOX_DEBUG_OFFSET
-#define MBOX_DEBUG_SEL_MSB WLAN_MBOX_DEBUG_SEL_MSB
-#define MBOX_DEBUG_SEL_LSB WLAN_MBOX_DEBUG_SEL_LSB
-#define MBOX_DEBUG_SEL_MASK WLAN_MBOX_DEBUG_SEL_MASK
-#define MBOX_DEBUG_SEL_GET(x) WLAN_MBOX_DEBUG_SEL_GET(x)
-#define MBOX_DEBUG_SEL_SET(x) WLAN_MBOX_DEBUG_SEL_SET(x)
-#define MBOX_FIFO_RESET_ADDRESS WLAN_MBOX_FIFO_RESET_ADDRESS
-#define MBOX_FIFO_RESET_OFFSET WLAN_MBOX_FIFO_RESET_OFFSET
-#define MBOX_FIFO_RESET_INIT_MSB WLAN_MBOX_FIFO_RESET_INIT_MSB
-#define MBOX_FIFO_RESET_INIT_LSB WLAN_MBOX_FIFO_RESET_INIT_LSB
-#define MBOX_FIFO_RESET_INIT_MASK WLAN_MBOX_FIFO_RESET_INIT_MASK
-#define MBOX_FIFO_RESET_INIT_GET(x) WLAN_MBOX_FIFO_RESET_INIT_GET(x)
-#define MBOX_FIFO_RESET_INIT_SET(x) WLAN_MBOX_FIFO_RESET_INIT_SET(x)
-#define MBOX_TXFIFO_POP_ADDRESS WLAN_MBOX_TXFIFO_POP_ADDRESS
-#define MBOX_TXFIFO_POP_OFFSET WLAN_MBOX_TXFIFO_POP_OFFSET
-#define MBOX_TXFIFO_POP_DATA_MSB WLAN_MBOX_TXFIFO_POP_DATA_MSB
-#define MBOX_TXFIFO_POP_DATA_LSB WLAN_MBOX_TXFIFO_POP_DATA_LSB
-#define MBOX_TXFIFO_POP_DATA_MASK WLAN_MBOX_TXFIFO_POP_DATA_MASK
-#define MBOX_TXFIFO_POP_DATA_GET(x) WLAN_MBOX_TXFIFO_POP_DATA_GET(x)
-#define MBOX_TXFIFO_POP_DATA_SET(x) WLAN_MBOX_TXFIFO_POP_DATA_SET(x)
-#define MBOX_RXFIFO_POP_ADDRESS WLAN_MBOX_RXFIFO_POP_ADDRESS
-#define MBOX_RXFIFO_POP_OFFSET WLAN_MBOX_RXFIFO_POP_OFFSET
-#define MBOX_RXFIFO_POP_DATA_MSB WLAN_MBOX_RXFIFO_POP_DATA_MSB
-#define MBOX_RXFIFO_POP_DATA_LSB WLAN_MBOX_RXFIFO_POP_DATA_LSB
-#define MBOX_RXFIFO_POP_DATA_MASK WLAN_MBOX_RXFIFO_POP_DATA_MASK
-#define MBOX_RXFIFO_POP_DATA_GET(x) WLAN_MBOX_RXFIFO_POP_DATA_GET(x)
-#define MBOX_RXFIFO_POP_DATA_SET(x) WLAN_MBOX_RXFIFO_POP_DATA_SET(x)
-#define SDIO_DEBUG_ADDRESS WLAN_SDIO_DEBUG_ADDRESS
-#define SDIO_DEBUG_OFFSET WLAN_SDIO_DEBUG_OFFSET
-#define SDIO_DEBUG_SEL_MSB WLAN_SDIO_DEBUG_SEL_MSB
-#define SDIO_DEBUG_SEL_LSB WLAN_SDIO_DEBUG_SEL_LSB
-#define SDIO_DEBUG_SEL_MASK WLAN_SDIO_DEBUG_SEL_MASK
-#define SDIO_DEBUG_SEL_GET(x) WLAN_SDIO_DEBUG_SEL_GET(x)
-#define SDIO_DEBUG_SEL_SET(x) WLAN_SDIO_DEBUG_SEL_SET(x)
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define GMBOX0_DMA_RX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS
-#define GMBOX0_DMA_RX_CONTROL_OFFSET WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET
-#define GMBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB
-#define GMBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB
-#define GMBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK
-#define GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x)
-#define GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x)
-#define GMBOX0_DMA_RX_CONTROL_START_MSB WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB
-#define GMBOX0_DMA_RX_CONTROL_START_LSB WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB
-#define GMBOX0_DMA_RX_CONTROL_START_MASK WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK
-#define GMBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x)
-#define GMBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x)
-#define GMBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB
-#define GMBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB
-#define GMBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK
-#define GMBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x)
-#define GMBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x)
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
-#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
-#define GMBOX0_DMA_TX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS
-#define GMBOX0_DMA_TX_CONTROL_OFFSET WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET
-#define GMBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB
-#define GMBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB
-#define GMBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK
-#define GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x)
-#define GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x)
-#define GMBOX0_DMA_TX_CONTROL_START_MSB WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB
-#define GMBOX0_DMA_TX_CONTROL_START_LSB WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB
-#define GMBOX0_DMA_TX_CONTROL_START_MASK WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK
-#define GMBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x)
-#define GMBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x)
-#define GMBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB
-#define GMBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB
-#define GMBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK
-#define GMBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x)
-#define GMBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x)
-#define GMBOX_INT_STATUS_ADDRESS WLAN_GMBOX_INT_STATUS_ADDRESS
-#define GMBOX_INT_STATUS_OFFSET WLAN_GMBOX_INT_STATUS_OFFSET
-#define GMBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB
-#define GMBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB
-#define GMBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK
-#define GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x)
-#define GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x)
-#define GMBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB
-#define GMBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB
-#define GMBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK
-#define GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
-#define GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
-#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
-#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
-#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
-#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
-#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
-#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
-#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
-#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
-#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
-#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
-#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
-#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
-#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
-#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
-#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
-#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB
-#define GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB
-#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK
-#define GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
-#define GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
-#define GMBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB
-#define GMBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB
-#define GMBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK
-#define GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x)
-#define GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x)
-#define GMBOX_INT_ENABLE_ADDRESS WLAN_GMBOX_INT_ENABLE_ADDRESS
-#define GMBOX_INT_ENABLE_OFFSET WLAN_GMBOX_INT_ENABLE_OFFSET
-#define GMBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB
-#define GMBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB
-#define GMBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK
-#define GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
-#define GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
-#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB
-#define GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB
-#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK
-#define GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
-#define GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
-#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
-#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
-#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
-#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
-#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
-#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
-#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
-#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
-#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
-#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
-#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
-#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
-#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
-#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
-#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
-#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
-#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
-#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
-#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
-#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
-#define GMBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB
-#define GMBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB
-#define GMBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK
-#define GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
-#define GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
-#define HOST_IF_WINDOW_ADDRESS WLAN_HOST_IF_WINDOW_ADDRESS
-#define HOST_IF_WINDOW_OFFSET WLAN_HOST_IF_WINDOW_OFFSET
-#define HOST_IF_WINDOW_DATA_MSB WLAN_HOST_IF_WINDOW_DATA_MSB
-#define HOST_IF_WINDOW_DATA_LSB WLAN_HOST_IF_WINDOW_DATA_LSB
-#define HOST_IF_WINDOW_DATA_MASK WLAN_HOST_IF_WINDOW_DATA_MASK
-#define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x)
-#define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x)
-
-#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
deleted file mode 100644 (file)
index 038d0d0..0000000
+++ /dev/null
@@ -1,471 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _MBOX_WLAN_HOST_REG_REG_H_
-#define _MBOX_WLAN_HOST_REG_REG_H_
-
-#define HOST_INT_STATUS_ADDRESS                  0x00000400
-#define HOST_INT_STATUS_OFFSET                   0x00000400
-#define HOST_INT_STATUS_ERROR_MSB                7
-#define HOST_INT_STATUS_ERROR_LSB                7
-#define HOST_INT_STATUS_ERROR_MASK               0x00000080
-#define HOST_INT_STATUS_ERROR_GET(x)             (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
-#define HOST_INT_STATUS_ERROR_SET(x)             (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
-#define HOST_INT_STATUS_CPU_MSB                  6
-#define HOST_INT_STATUS_CPU_LSB                  6
-#define HOST_INT_STATUS_CPU_MASK                 0x00000040
-#define HOST_INT_STATUS_CPU_GET(x)               (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
-#define HOST_INT_STATUS_CPU_SET(x)               (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
-#define HOST_INT_STATUS_INT_MSB                  5
-#define HOST_INT_STATUS_INT_LSB                  5
-#define HOST_INT_STATUS_INT_MASK                 0x00000020
-#define HOST_INT_STATUS_INT_GET(x)               (((x) & HOST_INT_STATUS_INT_MASK) >> HOST_INT_STATUS_INT_LSB)
-#define HOST_INT_STATUS_INT_SET(x)               (((x) << HOST_INT_STATUS_INT_LSB) & HOST_INT_STATUS_INT_MASK)
-#define HOST_INT_STATUS_COUNTER_MSB              4
-#define HOST_INT_STATUS_COUNTER_LSB              4
-#define HOST_INT_STATUS_COUNTER_MASK             0x00000010
-#define HOST_INT_STATUS_COUNTER_GET(x)           (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
-#define HOST_INT_STATUS_COUNTER_SET(x)           (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
-#define HOST_INT_STATUS_MBOX_DATA_MSB            3
-#define HOST_INT_STATUS_MBOX_DATA_LSB            0
-#define HOST_INT_STATUS_MBOX_DATA_MASK           0x0000000f
-#define HOST_INT_STATUS_MBOX_DATA_GET(x)         (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
-#define HOST_INT_STATUS_MBOX_DATA_SET(x)         (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
-
-#define CPU_INT_STATUS_ADDRESS                   0x00000401
-#define CPU_INT_STATUS_OFFSET                    0x00000401
-#define CPU_INT_STATUS_BIT_MSB                   7
-#define CPU_INT_STATUS_BIT_LSB                   0
-#define CPU_INT_STATUS_BIT_MASK                  0x000000ff
-#define CPU_INT_STATUS_BIT_GET(x)                (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
-#define CPU_INT_STATUS_BIT_SET(x)                (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
-
-#define ERROR_INT_STATUS_ADDRESS                 0x00000402
-#define ERROR_INT_STATUS_OFFSET                  0x00000402
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB)
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK)
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MSB 5
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB 5
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB)
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK)
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MSB 4
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB 4
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB)
-#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK)
-#define ERROR_INT_STATUS_SPI_MSB                 3
-#define ERROR_INT_STATUS_SPI_LSB                 3
-#define ERROR_INT_STATUS_SPI_MASK                0x00000008
-#define ERROR_INT_STATUS_SPI_GET(x)              (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
-#define ERROR_INT_STATUS_SPI_SET(x)              (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
-#define ERROR_INT_STATUS_WAKEUP_MSB              2
-#define ERROR_INT_STATUS_WAKEUP_LSB              2
-#define ERROR_INT_STATUS_WAKEUP_MASK             0x00000004
-#define ERROR_INT_STATUS_WAKEUP_GET(x)           (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
-#define ERROR_INT_STATUS_WAKEUP_SET(x)           (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
-#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB        1
-#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB        1
-#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK       0x00000002
-#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x)     (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
-#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x)     (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
-#define ERROR_INT_STATUS_TX_OVERFLOW_MSB         0
-#define ERROR_INT_STATUS_TX_OVERFLOW_LSB         0
-#define ERROR_INT_STATUS_TX_OVERFLOW_MASK        0x00000001
-#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x)      (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
-#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x)      (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
-
-#define COUNTER_INT_STATUS_ADDRESS               0x00000403
-#define COUNTER_INT_STATUS_OFFSET                0x00000403
-#define COUNTER_INT_STATUS_COUNTER_MSB           7
-#define COUNTER_INT_STATUS_COUNTER_LSB           0
-#define COUNTER_INT_STATUS_COUNTER_MASK          0x000000ff
-#define COUNTER_INT_STATUS_COUNTER_GET(x)        (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
-#define COUNTER_INT_STATUS_COUNTER_SET(x)        (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
-
-#define MBOX_FRAME_ADDRESS                       0x00000404
-#define MBOX_FRAME_OFFSET                        0x00000404
-#define MBOX_FRAME_RX_EOM_MSB                    7
-#define MBOX_FRAME_RX_EOM_LSB                    4
-#define MBOX_FRAME_RX_EOM_MASK                   0x000000f0
-#define MBOX_FRAME_RX_EOM_GET(x)                 (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
-#define MBOX_FRAME_RX_EOM_SET(x)                 (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
-#define MBOX_FRAME_RX_SOM_MSB                    3
-#define MBOX_FRAME_RX_SOM_LSB                    0
-#define MBOX_FRAME_RX_SOM_MASK                   0x0000000f
-#define MBOX_FRAME_RX_SOM_GET(x)                 (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
-#define MBOX_FRAME_RX_SOM_SET(x)                 (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
-
-#define RX_LOOKAHEAD_VALID_ADDRESS               0x00000405
-#define RX_LOOKAHEAD_VALID_OFFSET                0x00000405
-#define RX_LOOKAHEAD_VALID_MBOX_MSB              3
-#define RX_LOOKAHEAD_VALID_MBOX_LSB              0
-#define RX_LOOKAHEAD_VALID_MBOX_MASK             0x0000000f
-#define RX_LOOKAHEAD_VALID_MBOX_GET(x)           (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
-#define RX_LOOKAHEAD_VALID_MBOX_SET(x)           (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
-
-#define HOST_INT_STATUS2_ADDRESS                 0x00000406
-#define HOST_INT_STATUS2_OFFSET                  0x00000406
-#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MSB  2
-#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB  2
-#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK 0x00000004
-#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB)
-#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK)
-#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MSB   1
-#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB   1
-#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK  0x00000002
-#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB)
-#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK)
-#define HOST_INT_STATUS2_GMBOX_DATA_MSB          0
-#define HOST_INT_STATUS2_GMBOX_DATA_LSB          0
-#define HOST_INT_STATUS2_GMBOX_DATA_MASK         0x00000001
-#define HOST_INT_STATUS2_GMBOX_DATA_GET(x)       (((x) & HOST_INT_STATUS2_GMBOX_DATA_MASK) >> HOST_INT_STATUS2_GMBOX_DATA_LSB)
-#define HOST_INT_STATUS2_GMBOX_DATA_SET(x)       (((x) << HOST_INT_STATUS2_GMBOX_DATA_LSB) & HOST_INT_STATUS2_GMBOX_DATA_MASK)
-
-#define GMBOX_RX_AVAIL_ADDRESS                   0x00000407
-#define GMBOX_RX_AVAIL_OFFSET                    0x00000407
-#define GMBOX_RX_AVAIL_BYTE_MSB                  6
-#define GMBOX_RX_AVAIL_BYTE_LSB                  0
-#define GMBOX_RX_AVAIL_BYTE_MASK                 0x0000007f
-#define GMBOX_RX_AVAIL_BYTE_GET(x)               (((x) & GMBOX_RX_AVAIL_BYTE_MASK) >> GMBOX_RX_AVAIL_BYTE_LSB)
-#define GMBOX_RX_AVAIL_BYTE_SET(x)               (((x) << GMBOX_RX_AVAIL_BYTE_LSB) & GMBOX_RX_AVAIL_BYTE_MASK)
-
-#define RX_LOOKAHEAD0_ADDRESS                    0x00000408
-#define RX_LOOKAHEAD0_OFFSET                     0x00000408
-#define RX_LOOKAHEAD0_DATA_MSB                   7
-#define RX_LOOKAHEAD0_DATA_LSB                   0
-#define RX_LOOKAHEAD0_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD0_DATA_GET(x)                (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
-#define RX_LOOKAHEAD0_DATA_SET(x)                (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
-
-#define RX_LOOKAHEAD1_ADDRESS                    0x0000040c
-#define RX_LOOKAHEAD1_OFFSET                     0x0000040c
-#define RX_LOOKAHEAD1_DATA_MSB                   7
-#define RX_LOOKAHEAD1_DATA_LSB                   0
-#define RX_LOOKAHEAD1_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD1_DATA_GET(x)                (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
-#define RX_LOOKAHEAD1_DATA_SET(x)                (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
-
-#define RX_LOOKAHEAD2_ADDRESS                    0x00000410
-#define RX_LOOKAHEAD2_OFFSET                     0x00000410
-#define RX_LOOKAHEAD2_DATA_MSB                   7
-#define RX_LOOKAHEAD2_DATA_LSB                   0
-#define RX_LOOKAHEAD2_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD2_DATA_GET(x)                (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
-#define RX_LOOKAHEAD2_DATA_SET(x)                (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
-
-#define RX_LOOKAHEAD3_ADDRESS                    0x00000414
-#define RX_LOOKAHEAD3_OFFSET                     0x00000414
-#define RX_LOOKAHEAD3_DATA_MSB                   7
-#define RX_LOOKAHEAD3_DATA_LSB                   0
-#define RX_LOOKAHEAD3_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD3_DATA_GET(x)                (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
-#define RX_LOOKAHEAD3_DATA_SET(x)                (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
-
-#define INT_STATUS_ENABLE_ADDRESS                0x00000418
-#define INT_STATUS_ENABLE_OFFSET                 0x00000418
-#define INT_STATUS_ENABLE_ERROR_MSB              7
-#define INT_STATUS_ENABLE_ERROR_LSB              7
-#define INT_STATUS_ENABLE_ERROR_MASK             0x00000080
-#define INT_STATUS_ENABLE_ERROR_GET(x)           (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
-#define INT_STATUS_ENABLE_ERROR_SET(x)           (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
-#define INT_STATUS_ENABLE_CPU_MSB                6
-#define INT_STATUS_ENABLE_CPU_LSB                6
-#define INT_STATUS_ENABLE_CPU_MASK               0x00000040
-#define INT_STATUS_ENABLE_CPU_GET(x)             (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
-#define INT_STATUS_ENABLE_CPU_SET(x)             (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
-#define INT_STATUS_ENABLE_INT_MSB                5
-#define INT_STATUS_ENABLE_INT_LSB                5
-#define INT_STATUS_ENABLE_INT_MASK               0x00000020
-#define INT_STATUS_ENABLE_INT_GET(x)             (((x) & INT_STATUS_ENABLE_INT_MASK) >> INT_STATUS_ENABLE_INT_LSB)
-#define INT_STATUS_ENABLE_INT_SET(x)             (((x) << INT_STATUS_ENABLE_INT_LSB) & INT_STATUS_ENABLE_INT_MASK)
-#define INT_STATUS_ENABLE_COUNTER_MSB            4
-#define INT_STATUS_ENABLE_COUNTER_LSB            4
-#define INT_STATUS_ENABLE_COUNTER_MASK           0x00000010
-#define INT_STATUS_ENABLE_COUNTER_GET(x)         (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
-#define INT_STATUS_ENABLE_COUNTER_SET(x)         (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
-#define INT_STATUS_ENABLE_MBOX_DATA_MSB          3
-#define INT_STATUS_ENABLE_MBOX_DATA_LSB          0
-#define INT_STATUS_ENABLE_MBOX_DATA_MASK         0x0000000f
-#define INT_STATUS_ENABLE_MBOX_DATA_GET(x)       (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
-#define INT_STATUS_ENABLE_MBOX_DATA_SET(x)       (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
-
-#define CPU_INT_STATUS_ENABLE_ADDRESS            0x00000419
-#define CPU_INT_STATUS_ENABLE_OFFSET             0x00000419
-#define CPU_INT_STATUS_ENABLE_BIT_MSB            7
-#define CPU_INT_STATUS_ENABLE_BIT_LSB            0
-#define CPU_INT_STATUS_ENABLE_BIT_MASK           0x000000ff
-#define CPU_INT_STATUS_ENABLE_BIT_GET(x)         (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
-#define CPU_INT_STATUS_ENABLE_BIT_SET(x)         (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
-
-#define ERROR_STATUS_ENABLE_ADDRESS              0x0000041a
-#define ERROR_STATUS_ENABLE_OFFSET               0x0000041a
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB)
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK)
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MSB 5
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB 5
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB)
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK)
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MSB 4
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB 4
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB)
-#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK)
-#define ERROR_STATUS_ENABLE_WAKEUP_MSB           2
-#define ERROR_STATUS_ENABLE_WAKEUP_LSB           2
-#define ERROR_STATUS_ENABLE_WAKEUP_MASK          0x00000004
-#define ERROR_STATUS_ENABLE_WAKEUP_GET(x)        (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
-#define ERROR_STATUS_ENABLE_WAKEUP_SET(x)        (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB     1
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB     1
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK    0x00000002
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x)  (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x)  (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB      0
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB      0
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK     0x00000001
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x)   (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x)   (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
-
-#define COUNTER_INT_STATUS_ENABLE_ADDRESS        0x0000041b
-#define COUNTER_INT_STATUS_ENABLE_OFFSET         0x0000041b
-#define COUNTER_INT_STATUS_ENABLE_BIT_MSB        7
-#define COUNTER_INT_STATUS_ENABLE_BIT_LSB        0
-#define COUNTER_INT_STATUS_ENABLE_BIT_MASK       0x000000ff
-#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x)     (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
-#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x)     (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
-
-#define COUNT_ADDRESS                            0x00000420
-#define COUNT_OFFSET                             0x00000420
-#define COUNT_VALUE_MSB                          7
-#define COUNT_VALUE_LSB                          0
-#define COUNT_VALUE_MASK                         0x000000ff
-#define COUNT_VALUE_GET(x)                       (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
-#define COUNT_VALUE_SET(x)                       (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
-
-#define COUNT_DEC_ADDRESS                        0x00000440
-#define COUNT_DEC_OFFSET                         0x00000440
-#define COUNT_DEC_VALUE_MSB                      7
-#define COUNT_DEC_VALUE_LSB                      0
-#define COUNT_DEC_VALUE_MASK                     0x000000ff
-#define COUNT_DEC_VALUE_GET(x)                   (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
-#define COUNT_DEC_VALUE_SET(x)                   (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
-
-#define SCRATCH_ADDRESS                          0x00000460
-#define SCRATCH_OFFSET                           0x00000460
-#define SCRATCH_VALUE_MSB                        7
-#define SCRATCH_VALUE_LSB                        0
-#define SCRATCH_VALUE_MASK                       0x000000ff
-#define SCRATCH_VALUE_GET(x)                     (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
-#define SCRATCH_VALUE_SET(x)                     (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
-
-#define FIFO_TIMEOUT_ADDRESS                     0x00000468
-#define FIFO_TIMEOUT_OFFSET                      0x00000468
-#define FIFO_TIMEOUT_VALUE_MSB                   7
-#define FIFO_TIMEOUT_VALUE_LSB                   0
-#define FIFO_TIMEOUT_VALUE_MASK                  0x000000ff
-#define FIFO_TIMEOUT_VALUE_GET(x)                (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
-#define FIFO_TIMEOUT_VALUE_SET(x)                (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
-
-#define FIFO_TIMEOUT_ENABLE_ADDRESS              0x00000469
-#define FIFO_TIMEOUT_ENABLE_OFFSET               0x00000469
-#define FIFO_TIMEOUT_ENABLE_SET_MSB              0
-#define FIFO_TIMEOUT_ENABLE_SET_LSB              0
-#define FIFO_TIMEOUT_ENABLE_SET_MASK             0x00000001
-#define FIFO_TIMEOUT_ENABLE_SET_GET(x)           (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
-#define FIFO_TIMEOUT_ENABLE_SET_SET(x)           (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
-
-#define DISABLE_SLEEP_ADDRESS                    0x0000046a
-#define DISABLE_SLEEP_OFFSET                     0x0000046a
-#define DISABLE_SLEEP_FOR_INT_MSB                1
-#define DISABLE_SLEEP_FOR_INT_LSB                1
-#define DISABLE_SLEEP_FOR_INT_MASK               0x00000002
-#define DISABLE_SLEEP_FOR_INT_GET(x)             (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
-#define DISABLE_SLEEP_FOR_INT_SET(x)             (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
-#define DISABLE_SLEEP_ON_MSB                     0
-#define DISABLE_SLEEP_ON_LSB                     0
-#define DISABLE_SLEEP_ON_MASK                    0x00000001
-#define DISABLE_SLEEP_ON_GET(x)                  (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
-#define DISABLE_SLEEP_ON_SET(x)                  (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
-
-#define LOCAL_BUS_ADDRESS                        0x00000470
-#define LOCAL_BUS_OFFSET                         0x00000470
-#define LOCAL_BUS_STATE_MSB                      1
-#define LOCAL_BUS_STATE_LSB                      0
-#define LOCAL_BUS_STATE_MASK                     0x00000003
-#define LOCAL_BUS_STATE_GET(x)                   (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
-#define LOCAL_BUS_STATE_SET(x)                   (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
-
-#define INT_WLAN_ADDRESS                         0x00000472
-#define INT_WLAN_OFFSET                          0x00000472
-#define INT_WLAN_VECTOR_MSB                      7
-#define INT_WLAN_VECTOR_LSB                      0
-#define INT_WLAN_VECTOR_MASK                     0x000000ff
-#define INT_WLAN_VECTOR_GET(x)                   (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
-#define INT_WLAN_VECTOR_SET(x)                   (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
-
-#define WINDOW_DATA_ADDRESS                      0x00000474
-#define WINDOW_DATA_OFFSET                       0x00000474
-#define WINDOW_DATA_DATA_MSB                     7
-#define WINDOW_DATA_DATA_LSB                     0
-#define WINDOW_DATA_DATA_MASK                    0x000000ff
-#define WINDOW_DATA_DATA_GET(x)                  (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
-#define WINDOW_DATA_DATA_SET(x)                  (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
-
-#define WINDOW_WRITE_ADDR_ADDRESS                0x00000478
-#define WINDOW_WRITE_ADDR_OFFSET                 0x00000478
-#define WINDOW_WRITE_ADDR_ADDR_MSB               7
-#define WINDOW_WRITE_ADDR_ADDR_LSB               0
-#define WINDOW_WRITE_ADDR_ADDR_MASK              0x000000ff
-#define WINDOW_WRITE_ADDR_ADDR_GET(x)            (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
-#define WINDOW_WRITE_ADDR_ADDR_SET(x)            (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
-
-#define WINDOW_READ_ADDR_ADDRESS                 0x0000047c
-#define WINDOW_READ_ADDR_OFFSET                  0x0000047c
-#define WINDOW_READ_ADDR_ADDR_MSB                7
-#define WINDOW_READ_ADDR_ADDR_LSB                0
-#define WINDOW_READ_ADDR_ADDR_MASK               0x000000ff
-#define WINDOW_READ_ADDR_ADDR_GET(x)             (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
-#define WINDOW_READ_ADDR_ADDR_SET(x)             (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
-
-#define HOST_CTRL_SPI_CONFIG_ADDRESS             0x00000480
-#define HOST_CTRL_SPI_CONFIG_OFFSET              0x00000480
-#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MSB       4
-#define HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB       4
-#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK      0x00000010
-#define HOST_CTRL_SPI_CONFIG_SPI_RESET_GET(x)    (((x) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK) >> HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB)
-#define HOST_CTRL_SPI_CONFIG_SPI_RESET_SET(x)    (((x) << HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK)
-#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MSB 3
-#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB 3
-#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008
-#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB)
-#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK)
-#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MSB       2
-#define HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB       2
-#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK      0x00000004
-#define HOST_CTRL_SPI_CONFIG_TEST_MODE_GET(x)    (((x) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK) >> HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB)
-#define HOST_CTRL_SPI_CONFIG_TEST_MODE_SET(x)    (((x) << HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK)
-#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MSB       1
-#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB       0
-#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK      0x00000003
-#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_GET(x)    (((x) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK) >> HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB)
-#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_SET(x)    (((x) << HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK)
-
-#define HOST_CTRL_SPI_STATUS_ADDRESS             0x00000481
-#define HOST_CTRL_SPI_STATUS_OFFSET              0x00000481
-#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MSB        3
-#define HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB        3
-#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK       0x00000008
-#define HOST_CTRL_SPI_STATUS_ADDR_ERR_GET(x)     (((x) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB)
-#define HOST_CTRL_SPI_STATUS_ADDR_ERR_SET(x)     (((x) << HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK)
-#define HOST_CTRL_SPI_STATUS_RD_ERR_MSB          2
-#define HOST_CTRL_SPI_STATUS_RD_ERR_LSB          2
-#define HOST_CTRL_SPI_STATUS_RD_ERR_MASK         0x00000004
-#define HOST_CTRL_SPI_STATUS_RD_ERR_GET(x)       (((x) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK) >> HOST_CTRL_SPI_STATUS_RD_ERR_LSB)
-#define HOST_CTRL_SPI_STATUS_RD_ERR_SET(x)       (((x) << HOST_CTRL_SPI_STATUS_RD_ERR_LSB) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK)
-#define HOST_CTRL_SPI_STATUS_WR_ERR_MSB          1
-#define HOST_CTRL_SPI_STATUS_WR_ERR_LSB          1
-#define HOST_CTRL_SPI_STATUS_WR_ERR_MASK         0x00000002
-#define HOST_CTRL_SPI_STATUS_WR_ERR_GET(x)       (((x) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_WR_ERR_LSB)
-#define HOST_CTRL_SPI_STATUS_WR_ERR_SET(x)       (((x) << HOST_CTRL_SPI_STATUS_WR_ERR_LSB) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK)
-#define HOST_CTRL_SPI_STATUS_READY_MSB           0
-#define HOST_CTRL_SPI_STATUS_READY_LSB           0
-#define HOST_CTRL_SPI_STATUS_READY_MASK          0x00000001
-#define HOST_CTRL_SPI_STATUS_READY_GET(x)        (((x) & HOST_CTRL_SPI_STATUS_READY_MASK) >> HOST_CTRL_SPI_STATUS_READY_LSB)
-#define HOST_CTRL_SPI_STATUS_READY_SET(x)        (((x) << HOST_CTRL_SPI_STATUS_READY_LSB) & HOST_CTRL_SPI_STATUS_READY_MASK)
-
-#define NON_ASSOC_SLEEP_EN_ADDRESS               0x00000482
-#define NON_ASSOC_SLEEP_EN_OFFSET                0x00000482
-#define NON_ASSOC_SLEEP_EN_BIT_MSB               0
-#define NON_ASSOC_SLEEP_EN_BIT_LSB               0
-#define NON_ASSOC_SLEEP_EN_BIT_MASK              0x00000001
-#define NON_ASSOC_SLEEP_EN_BIT_GET(x)            (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB)
-#define NON_ASSOC_SLEEP_EN_BIT_SET(x)            (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK)
-
-#define CPU_DBG_SEL_ADDRESS                      0x00000483
-#define CPU_DBG_SEL_OFFSET                       0x00000483
-#define CPU_DBG_SEL_BIT_MSB                      5
-#define CPU_DBG_SEL_BIT_LSB                      0
-#define CPU_DBG_SEL_BIT_MASK                     0x0000003f
-#define CPU_DBG_SEL_BIT_GET(x)                   (((x) & CPU_DBG_SEL_BIT_MASK) >> CPU_DBG_SEL_BIT_LSB)
-#define CPU_DBG_SEL_BIT_SET(x)                   (((x) << CPU_DBG_SEL_BIT_LSB) & CPU_DBG_SEL_BIT_MASK)
-
-#define CPU_DBG_ADDRESS                          0x00000484
-#define CPU_DBG_OFFSET                           0x00000484
-#define CPU_DBG_DATA_MSB                         7
-#define CPU_DBG_DATA_LSB                         0
-#define CPU_DBG_DATA_MASK                        0x000000ff
-#define CPU_DBG_DATA_GET(x)                      (((x) & CPU_DBG_DATA_MASK) >> CPU_DBG_DATA_LSB)
-#define CPU_DBG_DATA_SET(x)                      (((x) << CPU_DBG_DATA_LSB) & CPU_DBG_DATA_MASK)
-
-#define INT_STATUS2_ENABLE_ADDRESS               0x00000488
-#define INT_STATUS2_ENABLE_OFFSET                0x00000488
-#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MSB 2
-#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB 2
-#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK 0x00000004
-#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB)
-#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK)
-#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MSB 1
-#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB 1
-#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK 0x00000002
-#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB)
-#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK)
-#define INT_STATUS2_ENABLE_GMBOX_DATA_MSB        0
-#define INT_STATUS2_ENABLE_GMBOX_DATA_LSB        0
-#define INT_STATUS2_ENABLE_GMBOX_DATA_MASK       0x00000001
-#define INT_STATUS2_ENABLE_GMBOX_DATA_GET(x)     (((x) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK) >> INT_STATUS2_ENABLE_GMBOX_DATA_LSB)
-#define INT_STATUS2_ENABLE_GMBOX_DATA_SET(x)     (((x) << INT_STATUS2_ENABLE_GMBOX_DATA_LSB) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK)
-
-#define GMBOX_RX_LOOKAHEAD_ADDRESS               0x00000490
-#define GMBOX_RX_LOOKAHEAD_OFFSET                0x00000490
-#define GMBOX_RX_LOOKAHEAD_DATA_MSB              7
-#define GMBOX_RX_LOOKAHEAD_DATA_LSB              0
-#define GMBOX_RX_LOOKAHEAD_DATA_MASK             0x000000ff
-#define GMBOX_RX_LOOKAHEAD_DATA_GET(x)           (((x) & GMBOX_RX_LOOKAHEAD_DATA_MASK) >> GMBOX_RX_LOOKAHEAD_DATA_LSB)
-#define GMBOX_RX_LOOKAHEAD_DATA_SET(x)           (((x) << GMBOX_RX_LOOKAHEAD_DATA_LSB) & GMBOX_RX_LOOKAHEAD_DATA_MASK)
-
-#define GMBOX_RX_LOOKAHEAD_MUX_ADDRESS           0x00000498
-#define GMBOX_RX_LOOKAHEAD_MUX_OFFSET            0x00000498
-#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MSB           0
-#define GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB           0
-#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK          0x00000001
-#define GMBOX_RX_LOOKAHEAD_MUX_SEL_GET(x)        (((x) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK) >> GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB)
-#define GMBOX_RX_LOOKAHEAD_MUX_SEL_SET(x)        (((x) << GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK)
-
-#define CIS_WINDOW_ADDRESS                       0x00000600
-#define CIS_WINDOW_OFFSET                        0x00000600
-#define CIS_WINDOW_DATA_MSB                      7
-#define CIS_WINDOW_DATA_LSB                      0
-#define CIS_WINDOW_DATA_MASK                     0x000000ff
-#define CIS_WINDOW_DATA_GET(x)                   (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
-#define CIS_WINDOW_DATA_SET(x)                   (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
-
-
-#endif /* _MBOX_WLAN_HOST_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
deleted file mode 100644 (file)
index f5167b9..0000000
+++ /dev/null
@@ -1,589 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _MBOX_WLAN_REG_REG_H_
-#define _MBOX_WLAN_REG_REG_H_
-
-#define WLAN_MBOX_FIFO_ADDRESS                   0x00000000
-#define WLAN_MBOX_FIFO_OFFSET                    0x00000000
-#define WLAN_MBOX_FIFO_DATA_MSB                  19
-#define WLAN_MBOX_FIFO_DATA_LSB                  0
-#define WLAN_MBOX_FIFO_DATA_MASK                 0x000fffff
-#define WLAN_MBOX_FIFO_DATA_GET(x)               (((x) & WLAN_MBOX_FIFO_DATA_MASK) >> WLAN_MBOX_FIFO_DATA_LSB)
-#define WLAN_MBOX_FIFO_DATA_SET(x)               (((x) << WLAN_MBOX_FIFO_DATA_LSB) & WLAN_MBOX_FIFO_DATA_MASK)
-
-#define WLAN_MBOX_FIFO_STATUS_ADDRESS            0x00000010
-#define WLAN_MBOX_FIFO_STATUS_OFFSET             0x00000010
-#define WLAN_MBOX_FIFO_STATUS_EMPTY_MSB          19
-#define WLAN_MBOX_FIFO_STATUS_EMPTY_LSB          16
-#define WLAN_MBOX_FIFO_STATUS_EMPTY_MASK         0x000f0000
-#define WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x)       (((x) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK) >> WLAN_MBOX_FIFO_STATUS_EMPTY_LSB)
-#define WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x)       (((x) << WLAN_MBOX_FIFO_STATUS_EMPTY_LSB) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK)
-#define WLAN_MBOX_FIFO_STATUS_FULL_MSB           15
-#define WLAN_MBOX_FIFO_STATUS_FULL_LSB           12
-#define WLAN_MBOX_FIFO_STATUS_FULL_MASK          0x0000f000
-#define WLAN_MBOX_FIFO_STATUS_FULL_GET(x)        (((x) & WLAN_MBOX_FIFO_STATUS_FULL_MASK) >> WLAN_MBOX_FIFO_STATUS_FULL_LSB)
-#define WLAN_MBOX_FIFO_STATUS_FULL_SET(x)        (((x) << WLAN_MBOX_FIFO_STATUS_FULL_LSB) & WLAN_MBOX_FIFO_STATUS_FULL_MASK)
-
-#define WLAN_MBOX_DMA_POLICY_ADDRESS             0x00000014
-#define WLAN_MBOX_DMA_POLICY_OFFSET              0x00000014
-#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB      3
-#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB      3
-#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK     0x00000008
-#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x)   (((x) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB)
-#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x)   (((x) << WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK)
-#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB        2
-#define WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB        2
-#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK       0x00000004
-#define WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x)     (((x) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB)
-#define WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x)     (((x) << WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK)
-#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB      1
-#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB      1
-#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK     0x00000002
-#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x)   (((x) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB)
-#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x)   (((x) << WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK)
-#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB        0
-#define WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB        0
-#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK       0x00000001
-#define WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x)     (((x) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB)
-#define WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x)     (((x) << WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK)
-
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS        0x0000001c
-#define WLAN_MBOX0_DMA_RX_CONTROL_OFFSET         0x0000001c
-#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX0_DMA_RX_CONTROL_START_MSB      1
-#define WLAN_MBOX0_DMA_RX_CONTROL_START_LSB      1
-#define WLAN_MBOX0_DMA_RX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_START_LSB)
-#define WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK)
-#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB)
-#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS        0x00000024
-#define WLAN_MBOX0_DMA_TX_CONTROL_OFFSET         0x00000024
-#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX0_DMA_TX_CONTROL_START_MSB      1
-#define WLAN_MBOX0_DMA_TX_CONTROL_START_LSB      1
-#define WLAN_MBOX0_DMA_TX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_START_LSB)
-#define WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK)
-#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB)
-#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS        0x0000002c
-#define WLAN_MBOX1_DMA_RX_CONTROL_OFFSET         0x0000002c
-#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX1_DMA_RX_CONTROL_START_MSB      1
-#define WLAN_MBOX1_DMA_RX_CONTROL_START_LSB      1
-#define WLAN_MBOX1_DMA_RX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_START_LSB)
-#define WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX1_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK)
-#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB)
-#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS        0x00000034
-#define WLAN_MBOX1_DMA_TX_CONTROL_OFFSET         0x00000034
-#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX1_DMA_TX_CONTROL_START_MSB      1
-#define WLAN_MBOX1_DMA_TX_CONTROL_START_LSB      1
-#define WLAN_MBOX1_DMA_TX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_START_LSB)
-#define WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX1_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK)
-#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB)
-#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS        0x0000003c
-#define WLAN_MBOX2_DMA_RX_CONTROL_OFFSET         0x0000003c
-#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX2_DMA_RX_CONTROL_START_MSB      1
-#define WLAN_MBOX2_DMA_RX_CONTROL_START_LSB      1
-#define WLAN_MBOX2_DMA_RX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_START_LSB)
-#define WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX2_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK)
-#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB)
-#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS        0x00000044
-#define WLAN_MBOX2_DMA_TX_CONTROL_OFFSET         0x00000044
-#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX2_DMA_TX_CONTROL_START_MSB      1
-#define WLAN_MBOX2_DMA_TX_CONTROL_START_LSB      1
-#define WLAN_MBOX2_DMA_TX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_START_LSB)
-#define WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX2_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK)
-#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB)
-#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS        0x0000004c
-#define WLAN_MBOX3_DMA_RX_CONTROL_OFFSET         0x0000004c
-#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX3_DMA_RX_CONTROL_START_MSB      1
-#define WLAN_MBOX3_DMA_RX_CONTROL_START_LSB      1
-#define WLAN_MBOX3_DMA_RX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_START_LSB)
-#define WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX3_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK)
-#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB)
-#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS        0x00000054
-#define WLAN_MBOX3_DMA_TX_CONTROL_OFFSET         0x00000054
-#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB     2
-#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB     2
-#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK    0x00000004
-#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x)  (((x) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB)
-#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x)  (((x) << WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK)
-#define WLAN_MBOX3_DMA_TX_CONTROL_START_MSB      1
-#define WLAN_MBOX3_DMA_TX_CONTROL_START_LSB      1
-#define WLAN_MBOX3_DMA_TX_CONTROL_START_MASK     0x00000002
-#define WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x)   (((x) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_START_LSB)
-#define WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x)   (((x) << WLAN_MBOX3_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK)
-#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB       0
-#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB       0
-#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK      0x00000001
-#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x)    (((x) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB)
-#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x)    (((x) << WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK)
-
-#define WLAN_MBOX_INT_STATUS_ADDRESS             0x00000058
-#define WLAN_MBOX_INT_STATUS_OFFSET              0x00000058
-#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31
-#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28
-#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000
-#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
-#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
-#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27
-#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24
-#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
-#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
-#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
-#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23
-#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20
-#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000
-#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
-#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
-#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB     17
-#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB     17
-#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK    0x00020000
-#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x)  (((x) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB)
-#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x)  (((x) << WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK)
-#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB    16
-#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB    16
-#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK   0x00010000
-#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
-#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
-#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB    15
-#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB    12
-#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK   0x0000f000
-#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
-#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
-#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB     11
-#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB     8
-#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK    0x00000f00
-#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x)  (((x) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB)
-#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x)  (((x) << WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK)
-#define WLAN_MBOX_INT_STATUS_HOST_MSB            7
-#define WLAN_MBOX_INT_STATUS_HOST_LSB            0
-#define WLAN_MBOX_INT_STATUS_HOST_MASK           0x000000ff
-#define WLAN_MBOX_INT_STATUS_HOST_GET(x)         (((x) & WLAN_MBOX_INT_STATUS_HOST_MASK) >> WLAN_MBOX_INT_STATUS_HOST_LSB)
-#define WLAN_MBOX_INT_STATUS_HOST_SET(x)         (((x) << WLAN_MBOX_INT_STATUS_HOST_LSB) & WLAN_MBOX_INT_STATUS_HOST_MASK)
-
-#define WLAN_MBOX_INT_ENABLE_ADDRESS             0x0000005c
-#define WLAN_MBOX_INT_ENABLE_OFFSET              0x0000005c
-#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31
-#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28
-#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000
-#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
-#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
-#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
-#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB     17
-#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB     17
-#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK    0x00020000
-#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)  (((x) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
-#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)  (((x) << WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
-#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB    16
-#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB    16
-#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK   0x00010000
-#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
-#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
-#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB    15
-#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB    12
-#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK   0x0000f000
-#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
-#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
-#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB     11
-#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB     8
-#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK    0x00000f00
-#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)  (((x) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
-#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)  (((x) << WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
-#define WLAN_MBOX_INT_ENABLE_HOST_MSB            7
-#define WLAN_MBOX_INT_ENABLE_HOST_LSB            0
-#define WLAN_MBOX_INT_ENABLE_HOST_MASK           0x000000ff
-#define WLAN_MBOX_INT_ENABLE_HOST_GET(x)         (((x) & WLAN_MBOX_INT_ENABLE_HOST_MASK) >> WLAN_MBOX_INT_ENABLE_HOST_LSB)
-#define WLAN_MBOX_INT_ENABLE_HOST_SET(x)         (((x) << WLAN_MBOX_INT_ENABLE_HOST_LSB) & WLAN_MBOX_INT_ENABLE_HOST_MASK)
-
-#define WLAN_INT_HOST_ADDRESS                    0x00000060
-#define WLAN_INT_HOST_OFFSET                     0x00000060
-#define WLAN_INT_HOST_VECTOR_MSB                 7
-#define WLAN_INT_HOST_VECTOR_LSB                 0
-#define WLAN_INT_HOST_VECTOR_MASK                0x000000ff
-#define WLAN_INT_HOST_VECTOR_GET(x)              (((x) & WLAN_INT_HOST_VECTOR_MASK) >> WLAN_INT_HOST_VECTOR_LSB)
-#define WLAN_INT_HOST_VECTOR_SET(x)              (((x) << WLAN_INT_HOST_VECTOR_LSB) & WLAN_INT_HOST_VECTOR_MASK)
-
-#define WLAN_LOCAL_COUNT_ADDRESS                 0x00000080
-#define WLAN_LOCAL_COUNT_OFFSET                  0x00000080
-#define WLAN_LOCAL_COUNT_VALUE_MSB               7
-#define WLAN_LOCAL_COUNT_VALUE_LSB               0
-#define WLAN_LOCAL_COUNT_VALUE_MASK              0x000000ff
-#define WLAN_LOCAL_COUNT_VALUE_GET(x)            (((x) & WLAN_LOCAL_COUNT_VALUE_MASK) >> WLAN_LOCAL_COUNT_VALUE_LSB)
-#define WLAN_LOCAL_COUNT_VALUE_SET(x)            (((x) << WLAN_LOCAL_COUNT_VALUE_LSB) & WLAN_LOCAL_COUNT_VALUE_MASK)
-
-#define WLAN_COUNT_INC_ADDRESS                   0x000000a0
-#define WLAN_COUNT_INC_OFFSET                    0x000000a0
-#define WLAN_COUNT_INC_VALUE_MSB                 7
-#define WLAN_COUNT_INC_VALUE_LSB                 0
-#define WLAN_COUNT_INC_VALUE_MASK                0x000000ff
-#define WLAN_COUNT_INC_VALUE_GET(x)              (((x) & WLAN_COUNT_INC_VALUE_MASK) >> WLAN_COUNT_INC_VALUE_LSB)
-#define WLAN_COUNT_INC_VALUE_SET(x)              (((x) << WLAN_COUNT_INC_VALUE_LSB) & WLAN_COUNT_INC_VALUE_MASK)
-
-#define WLAN_LOCAL_SCRATCH_ADDRESS               0x000000c0
-#define WLAN_LOCAL_SCRATCH_OFFSET                0x000000c0
-#define WLAN_LOCAL_SCRATCH_VALUE_MSB             7
-#define WLAN_LOCAL_SCRATCH_VALUE_LSB             0
-#define WLAN_LOCAL_SCRATCH_VALUE_MASK            0x000000ff
-#define WLAN_LOCAL_SCRATCH_VALUE_GET(x)          (((x) & WLAN_LOCAL_SCRATCH_VALUE_MASK) >> WLAN_LOCAL_SCRATCH_VALUE_LSB)
-#define WLAN_LOCAL_SCRATCH_VALUE_SET(x)          (((x) << WLAN_LOCAL_SCRATCH_VALUE_LSB) & WLAN_LOCAL_SCRATCH_VALUE_MASK)
-
-#define WLAN_USE_LOCAL_BUS_ADDRESS               0x000000e0
-#define WLAN_USE_LOCAL_BUS_OFFSET                0x000000e0
-#define WLAN_USE_LOCAL_BUS_PIN_INIT_MSB          0
-#define WLAN_USE_LOCAL_BUS_PIN_INIT_LSB          0
-#define WLAN_USE_LOCAL_BUS_PIN_INIT_MASK         0x00000001
-#define WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x)       (((x) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK) >> WLAN_USE_LOCAL_BUS_PIN_INIT_LSB)
-#define WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x)       (((x) << WLAN_USE_LOCAL_BUS_PIN_INIT_LSB) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK)
-
-#define WLAN_SDIO_CONFIG_ADDRESS                 0x000000e4
-#define WLAN_SDIO_CONFIG_OFFSET                  0x000000e4
-#define WLAN_SDIO_CONFIG_CCCR_IOR1_MSB           0
-#define WLAN_SDIO_CONFIG_CCCR_IOR1_LSB           0
-#define WLAN_SDIO_CONFIG_CCCR_IOR1_MASK          0x00000001
-#define WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x)        (((x) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK) >> WLAN_SDIO_CONFIG_CCCR_IOR1_LSB)
-#define WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x)        (((x) << WLAN_SDIO_CONFIG_CCCR_IOR1_LSB) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK)
-
-#define WLAN_MBOX_DEBUG_ADDRESS                  0x000000e8
-#define WLAN_MBOX_DEBUG_OFFSET                   0x000000e8
-#define WLAN_MBOX_DEBUG_SEL_MSB                  2
-#define WLAN_MBOX_DEBUG_SEL_LSB                  0
-#define WLAN_MBOX_DEBUG_SEL_MASK                 0x00000007
-#define WLAN_MBOX_DEBUG_SEL_GET(x)               (((x) & WLAN_MBOX_DEBUG_SEL_MASK) >> WLAN_MBOX_DEBUG_SEL_LSB)
-#define WLAN_MBOX_DEBUG_SEL_SET(x)               (((x) << WLAN_MBOX_DEBUG_SEL_LSB) & WLAN_MBOX_DEBUG_SEL_MASK)
-
-#define WLAN_MBOX_FIFO_RESET_ADDRESS             0x000000ec
-#define WLAN_MBOX_FIFO_RESET_OFFSET              0x000000ec
-#define WLAN_MBOX_FIFO_RESET_INIT_MSB            0
-#define WLAN_MBOX_FIFO_RESET_INIT_LSB            0
-#define WLAN_MBOX_FIFO_RESET_INIT_MASK           0x00000001
-#define WLAN_MBOX_FIFO_RESET_INIT_GET(x)         (((x) & WLAN_MBOX_FIFO_RESET_INIT_MASK) >> WLAN_MBOX_FIFO_RESET_INIT_LSB)
-#define WLAN_MBOX_FIFO_RESET_INIT_SET(x)         (((x) << WLAN_MBOX_FIFO_RESET_INIT_LSB) & WLAN_MBOX_FIFO_RESET_INIT_MASK)
-
-#define WLAN_MBOX_TXFIFO_POP_ADDRESS             0x000000f0
-#define WLAN_MBOX_TXFIFO_POP_OFFSET              0x000000f0
-#define WLAN_MBOX_TXFIFO_POP_DATA_MSB            0
-#define WLAN_MBOX_TXFIFO_POP_DATA_LSB            0
-#define WLAN_MBOX_TXFIFO_POP_DATA_MASK           0x00000001
-#define WLAN_MBOX_TXFIFO_POP_DATA_GET(x)         (((x) & WLAN_MBOX_TXFIFO_POP_DATA_MASK) >> WLAN_MBOX_TXFIFO_POP_DATA_LSB)
-#define WLAN_MBOX_TXFIFO_POP_DATA_SET(x)         (((x) << WLAN_MBOX_TXFIFO_POP_DATA_LSB) & WLAN_MBOX_TXFIFO_POP_DATA_MASK)
-
-#define WLAN_MBOX_RXFIFO_POP_ADDRESS             0x00000100
-#define WLAN_MBOX_RXFIFO_POP_OFFSET              0x00000100
-#define WLAN_MBOX_RXFIFO_POP_DATA_MSB            0
-#define WLAN_MBOX_RXFIFO_POP_DATA_LSB            0
-#define WLAN_MBOX_RXFIFO_POP_DATA_MASK           0x00000001
-#define WLAN_MBOX_RXFIFO_POP_DATA_GET(x)         (((x) & WLAN_MBOX_RXFIFO_POP_DATA_MASK) >> WLAN_MBOX_RXFIFO_POP_DATA_LSB)
-#define WLAN_MBOX_RXFIFO_POP_DATA_SET(x)         (((x) << WLAN_MBOX_RXFIFO_POP_DATA_LSB) & WLAN_MBOX_RXFIFO_POP_DATA_MASK)
-
-#define WLAN_SDIO_DEBUG_ADDRESS                  0x00000110
-#define WLAN_SDIO_DEBUG_OFFSET                   0x00000110
-#define WLAN_SDIO_DEBUG_SEL_MSB                  3
-#define WLAN_SDIO_DEBUG_SEL_LSB                  0
-#define WLAN_SDIO_DEBUG_SEL_MASK                 0x0000000f
-#define WLAN_SDIO_DEBUG_SEL_GET(x)               (((x) & WLAN_SDIO_DEBUG_SEL_MASK) >> WLAN_SDIO_DEBUG_SEL_LSB)
-#define WLAN_SDIO_DEBUG_SEL_SET(x)               (((x) << WLAN_SDIO_DEBUG_SEL_LSB) & WLAN_SDIO_DEBUG_SEL_MASK)
-
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000114
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000114
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS       0x00000118
-#define WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET        0x00000118
-#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB    2
-#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB    2
-#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK   0x00000004
-#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB)
-#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK)
-#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB     1
-#define WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB     1
-#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK    0x00000002
-#define WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x)  (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB)
-#define WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x)  (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK)
-#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB      0
-#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB      0
-#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK     0x00000001
-#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x)   (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB)
-#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x)   (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK)
-
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x0000011c
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x0000011c
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS       0x00000120
-#define WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET        0x00000120
-#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB    2
-#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB    2
-#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK   0x00000004
-#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB)
-#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK)
-#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB     1
-#define WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB     1
-#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK    0x00000002
-#define WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x)  (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB)
-#define WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x)  (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK)
-#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB      0
-#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB      0
-#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK     0x00000001
-#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x)   (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB)
-#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x)   (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK)
-
-#define WLAN_GMBOX_INT_STATUS_ADDRESS            0x00000124
-#define WLAN_GMBOX_INT_STATUS_OFFSET             0x00000124
-#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB    6
-#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB    6
-#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK   0x00000040
-#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB)
-#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK)
-#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB   5
-#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB   5
-#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK  0x00000020
-#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB)
-#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK)
-#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 4
-#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 4
-#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0x00000010
-#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
-#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 3
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 3
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000008
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 2
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 2
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00000004
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
-#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
-#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB   1
-#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB   1
-#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK  0x00000002
-#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
-#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
-#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB    0
-#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB    0
-#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK   0x00000001
-#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB)
-#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK)
-
-#define WLAN_GMBOX_INT_ENABLE_ADDRESS            0x00000128
-#define WLAN_GMBOX_INT_ENABLE_OFFSET             0x00000128
-#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB    6
-#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB    6
-#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK   0x00000040
-#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB)
-#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK)
-#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB   5
-#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB   5
-#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK  0x00000020
-#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
-#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
-#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 4
-#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 4
-#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0x00000010
-#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
-#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 3
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 3
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000008
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 2
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 2
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00000004
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
-#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
-#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB   1
-#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB   1
-#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK  0x00000002
-#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
-#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
-#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB    0
-#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB    0
-#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK   0x00000001
-#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB)
-#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK)
-
-#define WLAN_HOST_IF_WINDOW_ADDRESS              0x00002000
-#define WLAN_HOST_IF_WINDOW_OFFSET               0x00002000
-#define WLAN_HOST_IF_WINDOW_DATA_MSB             7
-#define WLAN_HOST_IF_WINDOW_DATA_LSB             0
-#define WLAN_HOST_IF_WINDOW_DATA_MASK            0x000000ff
-#define WLAN_HOST_IF_WINDOW_DATA_GET(x)          (((x) & WLAN_HOST_IF_WINDOW_DATA_MASK) >> WLAN_HOST_IF_WINDOW_DATA_LSB)
-#define WLAN_HOST_IF_WINDOW_DATA_SET(x)          (((x) << WLAN_HOST_IF_WINDOW_DATA_LSB) & WLAN_HOST_IF_WINDOW_DATA_MASK)
-
-#endif /* _MBOX_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
deleted file mode 100644 (file)
index fcafec8..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#include "rtc_wlan_reg.h"
-
-#ifndef BT_HEADERS
-
-#define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS
-#define RESET_CONTROL_OFFSET WLAN_RESET_CONTROL_OFFSET
-#define RESET_CONTROL_DEBUG_UART_RST_MSB WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB
-#define RESET_CONTROL_DEBUG_UART_RST_LSB WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB
-#define RESET_CONTROL_DEBUG_UART_RST_MASK WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK
-#define RESET_CONTROL_DEBUG_UART_RST_GET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x)
-#define RESET_CONTROL_DEBUG_UART_RST_SET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x)
-#define RESET_CONTROL_BB_COLD_RST_MSB WLAN_RESET_CONTROL_BB_COLD_RST_MSB
-#define RESET_CONTROL_BB_COLD_RST_LSB WLAN_RESET_CONTROL_BB_COLD_RST_LSB
-#define RESET_CONTROL_BB_COLD_RST_MASK WLAN_RESET_CONTROL_BB_COLD_RST_MASK
-#define RESET_CONTROL_BB_COLD_RST_GET(x) WLAN_RESET_CONTROL_BB_COLD_RST_GET(x)
-#define RESET_CONTROL_BB_COLD_RST_SET(x) WLAN_RESET_CONTROL_BB_COLD_RST_SET(x)
-#define RESET_CONTROL_BB_WARM_RST_MSB WLAN_RESET_CONTROL_BB_WARM_RST_MSB
-#define RESET_CONTROL_BB_WARM_RST_LSB WLAN_RESET_CONTROL_BB_WARM_RST_LSB
-#define RESET_CONTROL_BB_WARM_RST_MASK WLAN_RESET_CONTROL_BB_WARM_RST_MASK
-#define RESET_CONTROL_BB_WARM_RST_GET(x) WLAN_RESET_CONTROL_BB_WARM_RST_GET(x)
-#define RESET_CONTROL_BB_WARM_RST_SET(x) WLAN_RESET_CONTROL_BB_WARM_RST_SET(x)
-#define RESET_CONTROL_CPU_INIT_RESET_MSB WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB
-#define RESET_CONTROL_CPU_INIT_RESET_LSB WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB
-#define RESET_CONTROL_CPU_INIT_RESET_MASK WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK
-#define RESET_CONTROL_CPU_INIT_RESET_GET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x)
-#define RESET_CONTROL_CPU_INIT_RESET_SET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x)
-#define RESET_CONTROL_VMC_REMAP_RESET_MSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB
-#define RESET_CONTROL_VMC_REMAP_RESET_LSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB
-#define RESET_CONTROL_VMC_REMAP_RESET_MASK WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK
-#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x)
-#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x)
-#define RESET_CONTROL_RST_OUT_MSB WLAN_RESET_CONTROL_RST_OUT_MSB
-#define RESET_CONTROL_RST_OUT_LSB WLAN_RESET_CONTROL_RST_OUT_LSB
-#define RESET_CONTROL_RST_OUT_MASK WLAN_RESET_CONTROL_RST_OUT_MASK
-#define RESET_CONTROL_RST_OUT_GET(x) WLAN_RESET_CONTROL_RST_OUT_GET(x)
-#define RESET_CONTROL_RST_OUT_SET(x) WLAN_RESET_CONTROL_RST_OUT_SET(x)
-#define RESET_CONTROL_COLD_RST_MSB WLAN_RESET_CONTROL_COLD_RST_MSB
-#define RESET_CONTROL_COLD_RST_LSB WLAN_RESET_CONTROL_COLD_RST_LSB
-#define RESET_CONTROL_COLD_RST_MASK WLAN_RESET_CONTROL_COLD_RST_MASK
-#define RESET_CONTROL_COLD_RST_GET(x) WLAN_RESET_CONTROL_COLD_RST_GET(x)
-#define RESET_CONTROL_COLD_RST_SET(x) WLAN_RESET_CONTROL_COLD_RST_SET(x)
-#define RESET_CONTROL_WARM_RST_MSB WLAN_RESET_CONTROL_WARM_RST_MSB
-#define RESET_CONTROL_WARM_RST_LSB WLAN_RESET_CONTROL_WARM_RST_LSB
-#define RESET_CONTROL_WARM_RST_MASK WLAN_RESET_CONTROL_WARM_RST_MASK
-#define RESET_CONTROL_WARM_RST_GET(x) WLAN_RESET_CONTROL_WARM_RST_GET(x)
-#define RESET_CONTROL_WARM_RST_SET(x) WLAN_RESET_CONTROL_WARM_RST_SET(x)
-#define RESET_CONTROL_CPU_WARM_RST_MSB WLAN_RESET_CONTROL_CPU_WARM_RST_MSB
-#define RESET_CONTROL_CPU_WARM_RST_LSB WLAN_RESET_CONTROL_CPU_WARM_RST_LSB
-#define RESET_CONTROL_CPU_WARM_RST_MASK WLAN_RESET_CONTROL_CPU_WARM_RST_MASK
-#define RESET_CONTROL_CPU_WARM_RST_GET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x)
-#define RESET_CONTROL_CPU_WARM_RST_SET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x)
-#define RESET_CONTROL_MAC_COLD_RST_MSB WLAN_RESET_CONTROL_MAC_COLD_RST_MSB
-#define RESET_CONTROL_MAC_COLD_RST_LSB WLAN_RESET_CONTROL_MAC_COLD_RST_LSB
-#define RESET_CONTROL_MAC_COLD_RST_MASK WLAN_RESET_CONTROL_MAC_COLD_RST_MASK
-#define RESET_CONTROL_MAC_COLD_RST_GET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x)
-#define RESET_CONTROL_MAC_COLD_RST_SET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x)
-#define RESET_CONTROL_MAC_WARM_RST_MSB WLAN_RESET_CONTROL_MAC_WARM_RST_MSB
-#define RESET_CONTROL_MAC_WARM_RST_LSB WLAN_RESET_CONTROL_MAC_WARM_RST_LSB
-#define RESET_CONTROL_MAC_WARM_RST_MASK WLAN_RESET_CONTROL_MAC_WARM_RST_MASK
-#define RESET_CONTROL_MAC_WARM_RST_GET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x)
-#define RESET_CONTROL_MAC_WARM_RST_SET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x)
-#define RESET_CONTROL_MBOX_RST_MSB WLAN_RESET_CONTROL_MBOX_RST_MSB
-#define RESET_CONTROL_MBOX_RST_LSB WLAN_RESET_CONTROL_MBOX_RST_LSB
-#define RESET_CONTROL_MBOX_RST_MASK WLAN_RESET_CONTROL_MBOX_RST_MASK
-#define RESET_CONTROL_MBOX_RST_GET(x) WLAN_RESET_CONTROL_MBOX_RST_GET(x)
-#define RESET_CONTROL_MBOX_RST_SET(x) WLAN_RESET_CONTROL_MBOX_RST_SET(x)
-#define RESET_CONTROL_UART_RST_MSB WLAN_RESET_CONTROL_UART_RST_MSB
-#define RESET_CONTROL_UART_RST_LSB WLAN_RESET_CONTROL_UART_RST_LSB
-#define RESET_CONTROL_UART_RST_MASK WLAN_RESET_CONTROL_UART_RST_MASK
-#define RESET_CONTROL_UART_RST_GET(x) WLAN_RESET_CONTROL_UART_RST_GET(x)
-#define RESET_CONTROL_UART_RST_SET(x) WLAN_RESET_CONTROL_UART_RST_SET(x)
-#define RESET_CONTROL_SI0_RST_MSB WLAN_RESET_CONTROL_SI0_RST_MSB
-#define RESET_CONTROL_SI0_RST_LSB WLAN_RESET_CONTROL_SI0_RST_LSB
-#define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK
-#define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x)
-#define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x)
-#define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS
-#define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET
-#define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB
-#define CPU_CLOCK_STANDARD_LSB WLAN_CPU_CLOCK_STANDARD_LSB
-#define CPU_CLOCK_STANDARD_MASK WLAN_CPU_CLOCK_STANDARD_MASK
-#define CPU_CLOCK_STANDARD_GET(x) WLAN_CPU_CLOCK_STANDARD_GET(x)
-#define CPU_CLOCK_STANDARD_SET(x) WLAN_CPU_CLOCK_STANDARD_SET(x)
-#define CLOCK_OUT_ADDRESS WLAN_CLOCK_OUT_ADDRESS
-#define CLOCK_OUT_OFFSET WLAN_CLOCK_OUT_OFFSET
-#define CLOCK_OUT_SELECT_MSB WLAN_CLOCK_OUT_SELECT_MSB
-#define CLOCK_OUT_SELECT_LSB WLAN_CLOCK_OUT_SELECT_LSB
-#define CLOCK_OUT_SELECT_MASK WLAN_CLOCK_OUT_SELECT_MASK
-#define CLOCK_OUT_SELECT_GET(x) WLAN_CLOCK_OUT_SELECT_GET(x)
-#define CLOCK_OUT_SELECT_SET(x) WLAN_CLOCK_OUT_SELECT_SET(x)
-#define CLOCK_CONTROL_ADDRESS WLAN_CLOCK_CONTROL_ADDRESS
-#define CLOCK_CONTROL_OFFSET WLAN_CLOCK_CONTROL_OFFSET
-#define CLOCK_CONTROL_LF_CLK32_MSB WLAN_CLOCK_CONTROL_LF_CLK32_MSB
-#define CLOCK_CONTROL_LF_CLK32_LSB WLAN_CLOCK_CONTROL_LF_CLK32_LSB
-#define CLOCK_CONTROL_LF_CLK32_MASK WLAN_CLOCK_CONTROL_LF_CLK32_MASK
-#define CLOCK_CONTROL_LF_CLK32_GET(x) WLAN_CLOCK_CONTROL_LF_CLK32_GET(x)
-#define CLOCK_CONTROL_LF_CLK32_SET(x) WLAN_CLOCK_CONTROL_LF_CLK32_SET(x)
-#define CLOCK_CONTROL_SI0_CLK_MSB WLAN_CLOCK_CONTROL_SI0_CLK_MSB
-#define CLOCK_CONTROL_SI0_CLK_LSB WLAN_CLOCK_CONTROL_SI0_CLK_LSB
-#define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK
-#define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)
-#define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)
-#define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS
-#define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET
-#define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB
-#define RESET_CAUSE_LAST_LSB WLAN_RESET_CAUSE_LAST_LSB
-#define RESET_CAUSE_LAST_MASK WLAN_RESET_CAUSE_LAST_MASK
-#define RESET_CAUSE_LAST_GET(x) WLAN_RESET_CAUSE_LAST_GET(x)
-#define RESET_CAUSE_LAST_SET(x) WLAN_RESET_CAUSE_LAST_SET(x)
-#define SYSTEM_SLEEP_ADDRESS WLAN_SYSTEM_SLEEP_ADDRESS
-#define SYSTEM_SLEEP_OFFSET WLAN_SYSTEM_SLEEP_OFFSET
-#define SYSTEM_SLEEP_HOST_IF_MSB WLAN_SYSTEM_SLEEP_HOST_IF_MSB
-#define SYSTEM_SLEEP_HOST_IF_LSB WLAN_SYSTEM_SLEEP_HOST_IF_LSB
-#define SYSTEM_SLEEP_HOST_IF_MASK WLAN_SYSTEM_SLEEP_HOST_IF_MASK
-#define SYSTEM_SLEEP_HOST_IF_GET(x) WLAN_SYSTEM_SLEEP_HOST_IF_GET(x)
-#define SYSTEM_SLEEP_HOST_IF_SET(x) WLAN_SYSTEM_SLEEP_HOST_IF_SET(x)
-#define SYSTEM_SLEEP_MBOX_MSB WLAN_SYSTEM_SLEEP_MBOX_MSB
-#define SYSTEM_SLEEP_MBOX_LSB WLAN_SYSTEM_SLEEP_MBOX_LSB
-#define SYSTEM_SLEEP_MBOX_MASK WLAN_SYSTEM_SLEEP_MBOX_MASK
-#define SYSTEM_SLEEP_MBOX_GET(x) WLAN_SYSTEM_SLEEP_MBOX_GET(x)
-#define SYSTEM_SLEEP_MBOX_SET(x) WLAN_SYSTEM_SLEEP_MBOX_SET(x)
-#define SYSTEM_SLEEP_MAC_IF_MSB WLAN_SYSTEM_SLEEP_MAC_IF_MSB
-#define SYSTEM_SLEEP_MAC_IF_LSB WLAN_SYSTEM_SLEEP_MAC_IF_LSB
-#define SYSTEM_SLEEP_MAC_IF_MASK WLAN_SYSTEM_SLEEP_MAC_IF_MASK
-#define SYSTEM_SLEEP_MAC_IF_GET(x) WLAN_SYSTEM_SLEEP_MAC_IF_GET(x)
-#define SYSTEM_SLEEP_MAC_IF_SET(x) WLAN_SYSTEM_SLEEP_MAC_IF_SET(x)
-#define SYSTEM_SLEEP_LIGHT_MSB WLAN_SYSTEM_SLEEP_LIGHT_MSB
-#define SYSTEM_SLEEP_LIGHT_LSB WLAN_SYSTEM_SLEEP_LIGHT_LSB
-#define SYSTEM_SLEEP_LIGHT_MASK WLAN_SYSTEM_SLEEP_LIGHT_MASK
-#define SYSTEM_SLEEP_LIGHT_GET(x) WLAN_SYSTEM_SLEEP_LIGHT_GET(x)
-#define SYSTEM_SLEEP_LIGHT_SET(x) WLAN_SYSTEM_SLEEP_LIGHT_SET(x)
-#define SYSTEM_SLEEP_DISABLE_MSB WLAN_SYSTEM_SLEEP_DISABLE_MSB
-#define SYSTEM_SLEEP_DISABLE_LSB WLAN_SYSTEM_SLEEP_DISABLE_LSB
-#define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK
-#define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x)
-#define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x)
-#define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS
-#define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET
-#define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB
-#define LPO_INIT_DIVIDEND_INT_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB
-#define LPO_INIT_DIVIDEND_INT_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK
-#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x)
-#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x)
-#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS
-#define LPO_INIT_DIVIDEND_FRACTION_OFFSET WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x)
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x)
-#define LPO_CAL_ADDRESS WLAN_LPO_CAL_ADDRESS
-#define LPO_CAL_OFFSET WLAN_LPO_CAL_OFFSET
-#define LPO_CAL_ENABLE_MSB WLAN_LPO_CAL_ENABLE_MSB
-#define LPO_CAL_ENABLE_LSB WLAN_LPO_CAL_ENABLE_LSB
-#define LPO_CAL_ENABLE_MASK WLAN_LPO_CAL_ENABLE_MASK
-#define LPO_CAL_ENABLE_GET(x) WLAN_LPO_CAL_ENABLE_GET(x)
-#define LPO_CAL_ENABLE_SET(x) WLAN_LPO_CAL_ENABLE_SET(x)
-#define LPO_CAL_COUNT_MSB WLAN_LPO_CAL_COUNT_MSB
-#define LPO_CAL_COUNT_LSB WLAN_LPO_CAL_COUNT_LSB
-#define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK
-#define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x)
-#define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x)
-
-#endif
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
deleted file mode 100644 (file)
index 5c048ff..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _RTC_WLAN_REG_REG_H_
-#define _RTC_WLAN_REG_REG_H_
-
-#define WLAN_RESET_CONTROL_ADDRESS               0x00000000
-#define WLAN_RESET_CONTROL_OFFSET                0x00000000
-#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB    14
-#define WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB    14
-#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK   0x00004000
-#define WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) >> WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB)
-#define WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK)
-#define WLAN_RESET_CONTROL_BB_COLD_RST_MSB       13
-#define WLAN_RESET_CONTROL_BB_COLD_RST_LSB       13
-#define WLAN_RESET_CONTROL_BB_COLD_RST_MASK      0x00002000
-#define WLAN_RESET_CONTROL_BB_COLD_RST_GET(x)    (((x) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) >> WLAN_RESET_CONTROL_BB_COLD_RST_LSB)
-#define WLAN_RESET_CONTROL_BB_COLD_RST_SET(x)    (((x) << WLAN_RESET_CONTROL_BB_COLD_RST_LSB) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK)
-#define WLAN_RESET_CONTROL_BB_WARM_RST_MSB       12
-#define WLAN_RESET_CONTROL_BB_WARM_RST_LSB       12
-#define WLAN_RESET_CONTROL_BB_WARM_RST_MASK      0x00001000
-#define WLAN_RESET_CONTROL_BB_WARM_RST_GET(x)    (((x) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) >> WLAN_RESET_CONTROL_BB_WARM_RST_LSB)
-#define WLAN_RESET_CONTROL_BB_WARM_RST_SET(x)    (((x) << WLAN_RESET_CONTROL_BB_WARM_RST_LSB) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK)
-#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB    11
-#define WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB    11
-#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK   0x00000800
-#define WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) >> WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB)
-#define WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK)
-#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB   10
-#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB   10
-#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK  0x00000400
-#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) >> WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB)
-#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK)
-#define WLAN_RESET_CONTROL_RST_OUT_MSB           9
-#define WLAN_RESET_CONTROL_RST_OUT_LSB           9
-#define WLAN_RESET_CONTROL_RST_OUT_MASK          0x00000200
-#define WLAN_RESET_CONTROL_RST_OUT_GET(x)        (((x) & WLAN_RESET_CONTROL_RST_OUT_MASK) >> WLAN_RESET_CONTROL_RST_OUT_LSB)
-#define WLAN_RESET_CONTROL_RST_OUT_SET(x)        (((x) << WLAN_RESET_CONTROL_RST_OUT_LSB) & WLAN_RESET_CONTROL_RST_OUT_MASK)
-#define WLAN_RESET_CONTROL_COLD_RST_MSB          8
-#define WLAN_RESET_CONTROL_COLD_RST_LSB          8
-#define WLAN_RESET_CONTROL_COLD_RST_MASK         0x00000100
-#define WLAN_RESET_CONTROL_COLD_RST_GET(x)       (((x) & WLAN_RESET_CONTROL_COLD_RST_MASK) >> WLAN_RESET_CONTROL_COLD_RST_LSB)
-#define WLAN_RESET_CONTROL_COLD_RST_SET(x)       (((x) << WLAN_RESET_CONTROL_COLD_RST_LSB) & WLAN_RESET_CONTROL_COLD_RST_MASK)
-#define WLAN_RESET_CONTROL_WARM_RST_MSB          7
-#define WLAN_RESET_CONTROL_WARM_RST_LSB          7
-#define WLAN_RESET_CONTROL_WARM_RST_MASK         0x00000080
-#define WLAN_RESET_CONTROL_WARM_RST_GET(x)       (((x) & WLAN_RESET_CONTROL_WARM_RST_MASK) >> WLAN_RESET_CONTROL_WARM_RST_LSB)
-#define WLAN_RESET_CONTROL_WARM_RST_SET(x)       (((x) << WLAN_RESET_CONTROL_WARM_RST_LSB) & WLAN_RESET_CONTROL_WARM_RST_MASK)
-#define WLAN_RESET_CONTROL_CPU_WARM_RST_MSB      6
-#define WLAN_RESET_CONTROL_CPU_WARM_RST_LSB      6
-#define WLAN_RESET_CONTROL_CPU_WARM_RST_MASK     0x00000040
-#define WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x)   (((x) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) >> WLAN_RESET_CONTROL_CPU_WARM_RST_LSB)
-#define WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x)   (((x) << WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK)
-#define WLAN_RESET_CONTROL_MAC_COLD_RST_MSB      5
-#define WLAN_RESET_CONTROL_MAC_COLD_RST_LSB      5
-#define WLAN_RESET_CONTROL_MAC_COLD_RST_MASK     0x00000020
-#define WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x)   (((x) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) >> WLAN_RESET_CONTROL_MAC_COLD_RST_LSB)
-#define WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x)   (((x) << WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK)
-#define WLAN_RESET_CONTROL_MAC_WARM_RST_MSB      4
-#define WLAN_RESET_CONTROL_MAC_WARM_RST_LSB      4
-#define WLAN_RESET_CONTROL_MAC_WARM_RST_MASK     0x00000010
-#define WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x)   (((x) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) >> WLAN_RESET_CONTROL_MAC_WARM_RST_LSB)
-#define WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x)   (((x) << WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK)
-#define WLAN_RESET_CONTROL_MBOX_RST_MSB          2
-#define WLAN_RESET_CONTROL_MBOX_RST_LSB          2
-#define WLAN_RESET_CONTROL_MBOX_RST_MASK         0x00000004
-#define WLAN_RESET_CONTROL_MBOX_RST_GET(x)       (((x) & WLAN_RESET_CONTROL_MBOX_RST_MASK) >> WLAN_RESET_CONTROL_MBOX_RST_LSB)
-#define WLAN_RESET_CONTROL_MBOX_RST_SET(x)       (((x) << WLAN_RESET_CONTROL_MBOX_RST_LSB) & WLAN_RESET_CONTROL_MBOX_RST_MASK)
-#define WLAN_RESET_CONTROL_UART_RST_MSB          1
-#define WLAN_RESET_CONTROL_UART_RST_LSB          1
-#define WLAN_RESET_CONTROL_UART_RST_MASK         0x00000002
-#define WLAN_RESET_CONTROL_UART_RST_GET(x)       (((x) & WLAN_RESET_CONTROL_UART_RST_MASK) >> WLAN_RESET_CONTROL_UART_RST_LSB)
-#define WLAN_RESET_CONTROL_UART_RST_SET(x)       (((x) << WLAN_RESET_CONTROL_UART_RST_LSB) & WLAN_RESET_CONTROL_UART_RST_MASK)
-#define WLAN_RESET_CONTROL_SI0_RST_MSB           0
-#define WLAN_RESET_CONTROL_SI0_RST_LSB           0
-#define WLAN_RESET_CONTROL_SI0_RST_MASK          0x00000001
-#define WLAN_RESET_CONTROL_SI0_RST_GET(x)        (((x) & WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB)
-#define WLAN_RESET_CONTROL_SI0_RST_SET(x)        (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK)
-
-#define WLAN_CPU_CLOCK_ADDRESS                   0x00000020
-#define WLAN_CPU_CLOCK_OFFSET                    0x00000020
-#define WLAN_CPU_CLOCK_STANDARD_MSB              1
-#define WLAN_CPU_CLOCK_STANDARD_LSB              0
-#define WLAN_CPU_CLOCK_STANDARD_MASK             0x00000003
-#define WLAN_CPU_CLOCK_STANDARD_GET(x)           (((x) & WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB)
-#define WLAN_CPU_CLOCK_STANDARD_SET(x)           (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK)
-
-#define WLAN_CLOCK_CONTROL_ADDRESS               0x00000028
-#define WLAN_CLOCK_CONTROL_OFFSET                0x00000028
-#define WLAN_CLOCK_CONTROL_LF_CLK32_MSB          2
-#define WLAN_CLOCK_CONTROL_LF_CLK32_LSB          2
-#define WLAN_CLOCK_CONTROL_LF_CLK32_MASK         0x00000004
-#define WLAN_CLOCK_CONTROL_LF_CLK32_GET(x)       (((x) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) >> WLAN_CLOCK_CONTROL_LF_CLK32_LSB)
-#define WLAN_CLOCK_CONTROL_LF_CLK32_SET(x)       (((x) << WLAN_CLOCK_CONTROL_LF_CLK32_LSB) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK)
-#define WLAN_CLOCK_CONTROL_SI0_CLK_MSB           0
-#define WLAN_CLOCK_CONTROL_SI0_CLK_LSB           0
-#define WLAN_CLOCK_CONTROL_SI0_CLK_MASK          0x00000001
-#define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)        (((x) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB)
-#define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)        (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK)
-
-#define WLAN_SYSTEM_SLEEP_ADDRESS                0x000000c4
-#define WLAN_SYSTEM_SLEEP_OFFSET                 0x000000c4
-#define WLAN_SYSTEM_SLEEP_HOST_IF_MSB            4
-#define WLAN_SYSTEM_SLEEP_HOST_IF_LSB            4
-#define WLAN_SYSTEM_SLEEP_HOST_IF_MASK           0x00000010
-#define WLAN_SYSTEM_SLEEP_HOST_IF_GET(x)         (((x) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) >> WLAN_SYSTEM_SLEEP_HOST_IF_LSB)
-#define WLAN_SYSTEM_SLEEP_HOST_IF_SET(x)         (((x) << WLAN_SYSTEM_SLEEP_HOST_IF_LSB) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK)
-#define WLAN_SYSTEM_SLEEP_MBOX_MSB               3
-#define WLAN_SYSTEM_SLEEP_MBOX_LSB               3
-#define WLAN_SYSTEM_SLEEP_MBOX_MASK              0x00000008
-#define WLAN_SYSTEM_SLEEP_MBOX_GET(x)            (((x) & WLAN_SYSTEM_SLEEP_MBOX_MASK) >> WLAN_SYSTEM_SLEEP_MBOX_LSB)
-#define WLAN_SYSTEM_SLEEP_MBOX_SET(x)            (((x) << WLAN_SYSTEM_SLEEP_MBOX_LSB) & WLAN_SYSTEM_SLEEP_MBOX_MASK)
-#define WLAN_SYSTEM_SLEEP_MAC_IF_MSB             2
-#define WLAN_SYSTEM_SLEEP_MAC_IF_LSB             2
-#define WLAN_SYSTEM_SLEEP_MAC_IF_MASK            0x00000004
-#define WLAN_SYSTEM_SLEEP_MAC_IF_GET(x)          (((x) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) >> WLAN_SYSTEM_SLEEP_MAC_IF_LSB)
-#define WLAN_SYSTEM_SLEEP_MAC_IF_SET(x)          (((x) << WLAN_SYSTEM_SLEEP_MAC_IF_LSB) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK)
-#define WLAN_SYSTEM_SLEEP_LIGHT_MSB              1
-#define WLAN_SYSTEM_SLEEP_LIGHT_LSB              1
-#define WLAN_SYSTEM_SLEEP_LIGHT_MASK             0x00000002
-#define WLAN_SYSTEM_SLEEP_LIGHT_GET(x)           (((x) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) >> WLAN_SYSTEM_SLEEP_LIGHT_LSB)
-#define WLAN_SYSTEM_SLEEP_LIGHT_SET(x)           (((x) << WLAN_SYSTEM_SLEEP_LIGHT_LSB) & WLAN_SYSTEM_SLEEP_LIGHT_MASK)
-#define WLAN_SYSTEM_SLEEP_DISABLE_MSB            0
-#define WLAN_SYSTEM_SLEEP_DISABLE_LSB            0
-#define WLAN_SYSTEM_SLEEP_DISABLE_MASK           0x00000001
-#define WLAN_SYSTEM_SLEEP_DISABLE_GET(x)         (((x) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB)
-#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x)         (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK)
-
-#define WLAN_LPO_CAL_ADDRESS                     0x000000e0
-#define WLAN_LPO_CAL_OFFSET                      0x000000e0
-#define WLAN_LPO_CAL_ENABLE_MSB                  20
-#define WLAN_LPO_CAL_ENABLE_LSB                  20
-#define WLAN_LPO_CAL_ENABLE_MASK                 0x00100000
-#define WLAN_LPO_CAL_ENABLE_GET(x)               (((x) & WLAN_LPO_CAL_ENABLE_MASK) >> WLAN_LPO_CAL_ENABLE_LSB)
-#define WLAN_LPO_CAL_ENABLE_SET(x)               (((x) << WLAN_LPO_CAL_ENABLE_LSB) & WLAN_LPO_CAL_ENABLE_MASK)
-#define WLAN_LPO_CAL_COUNT_MSB                   19
-#define WLAN_LPO_CAL_COUNT_LSB                   0
-#define WLAN_LPO_CAL_COUNT_MASK                  0x000fffff
-#define WLAN_LPO_CAL_COUNT_GET(x)                (((x) & WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB)
-#define WLAN_LPO_CAL_COUNT_SET(x)                (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK)
-
-#endif /* _RTC_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
deleted file mode 100644 (file)
index 302b20b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _UART_REG_REG_H_
-#define _UART_REG_REG_H_
-
-#define UART_CLKDIV_ADDRESS                      0x00000008
-#define UART_CLKDIV_OFFSET                       0x00000008
-#define UART_CLKDIV_CLK_SCALE_MSB                23
-#define UART_CLKDIV_CLK_SCALE_LSB                16
-#define UART_CLKDIV_CLK_SCALE_MASK               0x00ff0000
-#define UART_CLKDIV_CLK_SCALE_GET(x)             (((x) & UART_CLKDIV_CLK_SCALE_MASK) >> UART_CLKDIV_CLK_SCALE_LSB)
-#define UART_CLKDIV_CLK_SCALE_SET(x)             (((x) << UART_CLKDIV_CLK_SCALE_LSB) & UART_CLKDIV_CLK_SCALE_MASK)
-#define UART_CLKDIV_CLK_STEP_MSB                 15
-#define UART_CLKDIV_CLK_STEP_LSB                 0
-#define UART_CLKDIV_CLK_STEP_MASK                0x0000ffff
-#define UART_CLKDIV_CLK_STEP_GET(x)              (((x) & UART_CLKDIV_CLK_STEP_MASK) >> UART_CLKDIV_CLK_STEP_LSB)
-#define UART_CLKDIV_CLK_STEP_SET(x)              (((x) << UART_CLKDIV_CLK_STEP_LSB) & UART_CLKDIV_CLK_STEP_MASK)
-
-#endif /* _UART_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h
deleted file mode 100644 (file)
index 7492248..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="athdefs.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef __ATHDEFS_H__
-#define __ATHDEFS_H__
-
-/*
- * This file contains definitions that may be used across both
- * Host and Target software.  Nothing here is module-dependent
- * or platform-dependent.
- */
-
-/*
- * Generic error codes that can be used by hw, sta, ap, sim, dk
- * and any other environments.
- * Feel free to add any more non-zero codes that you need.
- */
-
-#define A_ERROR                        (-1)    /* Generic error return */
-#define A_DEVICE_NOT_FOUND     1       /* not able to find PCI device */
-#define A_NO_MEMORY            2       /* not able to allocate memory,
-                                        * not avail#defineable */
-#define A_MEMORY_NOT_AVAIL     3       /* memory region is not free for
-                                        * mapping */
-#define A_NO_FREE_DESC         4       /* no free descriptors available */
-#define A_BAD_ADDRESS          5       /* address does not match descriptor */
-#define A_WIN_DRIVER_ERROR     6       /* used in NT_HW version,
-                                        * if problem at init */
-#define A_REGS_NOT_MAPPED      7       /* registers not correctly mapped */
-#define A_EPERM                        8       /* Not superuser */
-#define A_EACCES               0       /* Access denied */
-#define A_ENOENT               10      /* No such entry, search failed, etc. */
-#define A_EEXIST               11      /* The object already exists
-                                        * (can't create) */
-#define A_EFAULT               12      /* Bad address fault */
-#define A_EBUSY                        13      /* Object is busy */
-#define A_EINVAL               14      /* Invalid parameter */
-#define A_EMSGSIZE             15      /* Bad message buffer length */
-#define A_ECANCELED            16      /* Operation canceled */
-#define A_ENOTSUP              17      /* Operation not supported */
-#define A_ECOMM                        18      /* Communication error on send */
-#define A_EPROTO               19      /* Protocol error */
-#define A_ENODEV               20      /* No such device */
-#define A_EDEVNOTUP            21      /* device is not UP */
-#define A_NO_RESOURCE          22      /* No resources for
-                                        * requested operation */
-#define A_HARDWARE             23      /* Hardware failure */
-#define A_PENDING              24      /* Asynchronous routine; will send up
-                                        * results later
-                                        * (typically in callback) */
-#define A_EBADCHANNEL          25      /* The channel cannot be used */
-#define A_DECRYPT_ERROR                26      /* Decryption error */
-#define A_PHY_ERROR            27      /* RX PHY error */
-#define A_CONSUMED             28      /* Object was consumed */
-
-#endif /* __ATHDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h
deleted file mode 100644 (file)
index 84e8db5..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-//
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef __BMI_MSG_H__
-#define __BMI_MSG_H__
-
-/*
- * Bootloader Messaging Interface (BMI)
- *
- * BMI is a very simple messaging interface used during initialization
- * to read memory, write memory, execute code, and to define an
- * application entry PC.
- *
- * It is used to download an application to AR6K, to provide
- * patches to code that is already resident on AR6K, and generally
- * to examine and modify state.  The Host has an opportunity to use
- * BMI only once during bootup.  Once the Host issues a BMI_DONE
- * command, this opportunity ends.
- *
- * The Host writes BMI requests to mailbox0, and reads BMI responses
- * from mailbox0.   BMI requests all begin with a command
- * (see below for specific commands), and are followed by
- * command-specific data.
- *
- * Flow control:
- * The Host can only issue a command once the Target gives it a
- * "BMI Command Credit", using AR6K Counter #4.  As soon as the
- * Target has completed a command, it issues another BMI Command
- * Credit (so the Host can issue the next command).
- *
- * BMI handles all required Target-side cache flushing.
- */
-
-
-/* Maximum data size used for BMI transfers */
-#define BMI_DATASZ_MAX                      256
-
-/* BMI Commands */
-
-#define BMI_NO_COMMAND                      0
-
-#define BMI_DONE                            1
-        /*
-         * Semantics: Host is done using BMI
-         * Request format:
-         *    u32 command (BMI_DONE)
-         * Response format: none
-         */
-
-#define BMI_READ_MEMORY                     2
-        /*
-         * Semantics: Host reads AR6K memory
-         * Request format:
-         *    u32 command (BMI_READ_MEMORY)
-         *    u32 address
-         *    u32 length, at most BMI_DATASZ_MAX
-         * Response format:
-         *    u8 data[length]
-         */
-
-#define BMI_WRITE_MEMORY                    3
-        /*
-         * Semantics: Host writes AR6K memory
-         * Request format:
-         *    u32 command (BMI_WRITE_MEMORY)
-         *    u32 address
-         *    u32 length, at most BMI_DATASZ_MAX
-         *    u8 data[length]
-         * Response format: none
-         */
-
-#define BMI_EXECUTE                         4
-        /*
-         * Semantics: Causes AR6K to execute code
-         * Request format:
-         *    u32 command (BMI_EXECUTE)
-         *    u32 address
-         *    u32 parameter
-         * Response format:
-         *    u32 return value
-         */
-
-#define BMI_SET_APP_START                   5
-        /*
-         * Semantics: Set Target application starting address
-         * Request format:
-         *    u32 command (BMI_SET_APP_START)
-         *    u32 address
-         * Response format: none
-         */
-
-#define BMI_READ_SOC_REGISTER               6
-        /*
-         * Semantics: Read a 32-bit Target SOC register.
-         * Request format:
-         *    u32 command (BMI_READ_REGISTER)
-         *    u32 address
-         * Response format: 
-         *    u32 value
-         */
-
-#define BMI_WRITE_SOC_REGISTER              7
-        /*
-         * Semantics: Write a 32-bit Target SOC register.
-         * Request format:
-         *    u32 command (BMI_WRITE_REGISTER)
-         *    u32 address
-         *    u32 value
-         *
-         * Response format: none
-         */
-
-#define BMI_GET_TARGET_ID                  8
-#define BMI_GET_TARGET_INFO                8
-        /*
-         * Semantics: Fetch the 4-byte Target information
-         * Request format:
-         *    u32 command (BMI_GET_TARGET_ID/INFO)
-         * Response format1 (old firmware):
-         *    u32 TargetVersionID
-         * Response format2 (newer firmware):
-         *    u32 TARGET_VERSION_SENTINAL
-         *    struct bmi_target_info;
-         */
-
-PREPACK struct bmi_target_info {
-    u32 target_info_byte_count; /* size of this structure */
-    u32 target_ver;             /* Target Version ID */
-    u32 target_type;            /* Target type */
-} POSTPACK;
-#define TARGET_VERSION_SENTINAL 0xffffffff
-#define TARGET_TYPE_AR6001 1
-#define TARGET_TYPE_AR6002 2
-#define TARGET_TYPE_AR6003 3
-
-
-#define BMI_ROMPATCH_INSTALL               9
-        /*
-         * Semantics: Install a ROM Patch.
-         * Request format:
-         *    u32 command (BMI_ROMPATCH_INSTALL)
-         *    u32 Target ROM Address
-         *    u32 Target RAM Address or Value (depending on Target Type)
-         *    u32 Size, in bytes
-         *    u32 Activate? 1-->activate;
-         *                            0-->install but do not activate
-         * Response format:
-         *    u32 PatchID
-         */
-
-#define BMI_ROMPATCH_UNINSTALL             10
-        /*
-         * Semantics: Uninstall a previously-installed ROM Patch,
-         * automatically deactivating, if necessary.
-         * Request format:
-         *    u32 command (BMI_ROMPATCH_UNINSTALL)
-         *    u32 PatchID
-         *
-         * Response format: none
-         */
-
-#define BMI_ROMPATCH_ACTIVATE              11
-        /*
-         * Semantics: Activate a list of previously-installed ROM Patches.
-         * Request format:
-         *    u32 command (BMI_ROMPATCH_ACTIVATE)
-         *    u32 rompatch_count
-         *    u32 PatchID[rompatch_count]
-         *
-         * Response format: none
-         */
-
-#define BMI_ROMPATCH_DEACTIVATE            12
-        /*
-         * Semantics: Deactivate a list of active ROM Patches.
-         * Request format:
-         *    u32 command (BMI_ROMPATCH_DEACTIVATE)
-         *    u32 rompatch_count
-         *    u32 PatchID[rompatch_count]
-         *
-         * Response format: none
-         */
-
-
-#define BMI_LZ_STREAM_START                13
-        /*
-         * Semantics: Begin an LZ-compressed stream of input
-         * which is to be uncompressed by the Target to an
-         * output buffer at address.  The output buffer must
-         * be sufficiently large to hold the uncompressed
-         * output from the compressed input stream.  This BMI
-         * command should be followed by a series of 1 or more
-         * BMI_LZ_DATA commands.
-         *    u32 command (BMI_LZ_STREAM_START)
-         *    u32 address
-         * Note: Not supported on all versions of ROM firmware.
-         */
-
-#define BMI_LZ_DATA                        14
-        /*
-         * Semantics: Host writes AR6K memory with LZ-compressed
-         * data which is uncompressed by the Target.  This command
-         * must be preceded by a BMI_LZ_STREAM_START command. A series
-         * of BMI_LZ_DATA commands are considered part of a single
-         * input stream until another BMI_LZ_STREAM_START is issued.
-         * Request format:
-         *    u32 command (BMI_LZ_DATA)
-         *    u32 length (of compressed data),
-         *                  at most BMI_DATASZ_MAX
-         *    u8 CompressedData[length]
-         * Response format: none
-         * Note: Not supported on all versions of ROM firmware.
-         */
-
-#endif /* __BMI_MSG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/cnxmgmt.h b/drivers/staging/ath6kl/include/common/cnxmgmt.h
deleted file mode 100644 (file)
index 7a902cb..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="cnxmgmt.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef _CNXMGMT_H_
-#define _CNXMGMT_H_
-
-typedef enum {
-    CM_CONNECT_WITHOUT_SCAN             = 0x0001,
-    CM_CONNECT_ASSOC_POLICY_USER        = 0x0002,
-    CM_CONNECT_SEND_REASSOC             = 0x0004,
-    CM_CONNECT_WITHOUT_ROAMTABLE_UPDATE = 0x0008,
-    CM_CONNECT_DO_WPA_OFFLOAD           = 0x0010,
-    CM_CONNECT_DO_NOT_DEAUTH            = 0x0020,
-} CM_CONNECT_TYPE;
-
-#endif  /* _CNXMGMT_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h
deleted file mode 100644 (file)
index 5566e56..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dbglog.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef _DBGLOG_H_
-#define _DBGLOG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define DBGLOG_TIMESTAMP_OFFSET          0
-#define DBGLOG_TIMESTAMP_MASK            0x0000FFFF /* Bit 0-15. Contains bit
-                                                       8-23 of the LF0 timer */
-#define DBGLOG_DBGID_OFFSET              16
-#define DBGLOG_DBGID_MASK                0x03FF0000 /* Bit 16-25 */
-#define DBGLOG_DBGID_NUM_MAX             256 /* Upper limit is width of mask */
-
-#define DBGLOG_MODULEID_OFFSET           26
-#define DBGLOG_MODULEID_MASK             0x3C000000 /* Bit 26-29 */
-#define DBGLOG_MODULEID_NUM_MAX          16 /* Upper limit is width of mask */
-
-/*
- * Please ensure that the definition of any new module introduced is captured
- * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The 
- * structure is required for the parser to correctly pick up the values for
- * different modules.
- */
-#define DBGLOG_MODULEID_START
-#define DBGLOG_MODULEID_INF                   0
-#define DBGLOG_MODULEID_WMI                   1
-#define DBGLOG_MODULEID_MISC                  2
-#define DBGLOG_MODULEID_PM                    3
-#define DBGLOG_MODULEID_TXRX_MGMTBUF          4
-#define DBGLOG_MODULEID_TXRX_TXBUF            5
-#define DBGLOG_MODULEID_TXRX_RXBUF            6
-#define DBGLOG_MODULEID_WOW                   7
-#define DBGLOG_MODULEID_WHAL                  8
-#define DBGLOG_MODULEID_DC                    9
-#define DBGLOG_MODULEID_CO                    10
-#define DBGLOG_MODULEID_RO                    11
-#define DBGLOG_MODULEID_CM                    12
-#define DBGLOG_MODULEID_MGMT                  13
-#define DBGLOG_MODULEID_TMR                   14
-#define DBGLOG_MODULEID_BTCOEX                15
-#define DBGLOG_MODULEID_END
-
-#define DBGLOG_NUM_ARGS_OFFSET             30
-#define DBGLOG_NUM_ARGS_MASK               0xC0000000 /* Bit 30-31 */
-#define DBGLOG_NUM_ARGS_MAX                2 /* Upper limit is width of mask */
-
-#define DBGLOG_MODULE_LOG_ENABLE_OFFSET    0
-#define DBGLOG_MODULE_LOG_ENABLE_MASK      0x0000FFFF
-
-#define DBGLOG_REPORTING_ENABLED_OFFSET    16
-#define DBGLOG_REPORTING_ENABLED_MASK      0x00010000
-
-#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17
-#define DBGLOG_TIMESTAMP_RESOLUTION_MASK   0x000E0000
-
-#define DBGLOG_REPORT_SIZE_OFFSET          20
-#define DBGLOG_REPORT_SIZE_MASK            0x3FF00000
-
-#define DBGLOG_LOG_BUFFER_SIZE             1500
-#define DBGLOG_DBGID_DEFINITION_LEN_MAX    90
-
-PREPACK struct dbglog_buf_s {
-    struct dbglog_buf_s *next;
-    u8 *buffer;
-    u32 bufsize;
-    u32 length;
-    u32 count;
-    u32 free;
-} POSTPACK;
-
-PREPACK struct dbglog_hdr_s {
-    struct dbglog_buf_s *dbuf;
-    u32 dropped;
-} POSTPACK;
-
-PREPACK struct dbglog_config_s {
-    u32 cfgvalid; /* Mask with valid config bits */
-    union {
-        /* TODO: Take care of endianness */
-        struct {
-            u32 mmask:16; /* Mask of modules with logging on */
-            u32 rep:1; /* Reporting enabled or not */
-            u32 tsr:3; /* Time stamp resolution. Def: 1 ms */
-            u32 size:10; /* Report size in number of messages */
-            u32 reserved:2;
-        } dbglog_config;
-
-        u32 value;
-    } u;
-} POSTPACK;
-
-#define cfgmmask                   u.dbglog_config.mmask
-#define cfgrep                     u.dbglog_config.rep
-#define cfgtsr                     u.dbglog_config.tsr
-#define cfgsize                    u.dbglog_config.size
-#define cfgvalue                   u.value
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DBGLOG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog_id.h b/drivers/staging/ath6kl/include/common/dbglog_id.h
deleted file mode 100644 (file)
index 15ef829..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dbglog_id.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef _DBGLOG_ID_H_
-#define _DBGLOG_ID_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 
- * The nomenclature for the debug identifiers is MODULE_DESCRIPTION.
- * Please ensure that the definition of any new debugid introduced is captured
- * between the <MODULE>_DBGID_DEFINITION_START and 
- * <MODULE>_DBGID_DEFINITION_END defines. The structure is required for the 
- * parser to correctly pick up the values for different debug identifiers.
- */
-
-/* INF debug identifier definitions */
-#define INF_DBGID_DEFINITION_START
-#define INF_ASSERTION_FAILED                          1
-#define INF_TARGET_ID                                 2
-#define INF_DBGID_DEFINITION_END
-
-/* WMI debug identifier definitions */
-#define WMI_DBGID_DEFINITION_START
-#define WMI_CMD_RX_XTND_PKT_TOO_SHORT                 1
-#define WMI_EXTENDED_CMD_NOT_HANDLED                  2
-#define WMI_CMD_RX_PKT_TOO_SHORT                      3
-#define WMI_CALLING_WMI_EXTENSION_FN                  4
-#define WMI_CMD_NOT_HANDLED                           5
-#define WMI_IN_SYNC                                   6
-#define WMI_TARGET_WMI_SYNC_CMD                       7
-#define WMI_SET_SNR_THRESHOLD_PARAMS                  8
-#define WMI_SET_RSSI_THRESHOLD_PARAMS                 9
-#define WMI_SET_LQ_TRESHOLD_PARAMS                   10
-#define WMI_TARGET_CREATE_PSTREAM_CMD                11
-#define WMI_WI_DTM_INUSE                             12
-#define WMI_TARGET_DELETE_PSTREAM_CMD                13
-#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD       14
-#define WMI_TARGET_GET_BIT_RATE_CMD                  15
-#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS       16
-#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD        17
-#define WMI_TARGET_GET_TX_PWR_CMD                    18
-#define WMI_FREE_EVBUF_WMIBUF                        19
-#define WMI_FREE_EVBUF_DATABUF                       20
-#define WMI_FREE_EVBUF_BADFLAG                       21
-#define WMI_HTC_RX_ERROR_DATA_PACKET                 22
-#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX             23
-#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT      24
-#define WMI_SENDING_READY_EVENT                      25
-#define WMI_SETPOWER_MDOE_TO_MAXPERF                 26
-#define WMI_SETPOWER_MDOE_TO_REC                     27
-#define WMI_BSSINFO_EVENT_FROM                       28
-#define WMI_TARGET_GET_STATS_CMD                     29
-#define WMI_SENDING_SCAN_COMPLETE_EVENT              30
-#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT        31
-#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT       32
-#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT     33
-#define WMI_SENDING_ERROR_REPORT_EVENT               34
-#define WMI_SENDING_CAC_EVENT                        35
-#define WMI_TARGET_GET_ROAM_TABLE_CMD                36
-#define WMI_TARGET_GET_ROAM_DATA_CMD                 37
-#define WMI_SENDING_GPIO_INTR_EVENT                  38
-#define WMI_SENDING_GPIO_ACK_EVENT                   39
-#define WMI_SENDING_GPIO_DATA_EVENT                  40
-#define WMI_CMD_RX                                   41
-#define WMI_CMD_RX_XTND                              42
-#define WMI_EVENT_SEND                               43
-#define WMI_EVENT_SEND_XTND                          44
-#define WMI_CMD_PARAMS_DUMP_START                    45
-#define WMI_CMD_PARAMS_DUMP_END                      46
-#define WMI_CMD_PARAMS                               47
-#define WMI_DBGID_DEFINITION_END
-
-/* MISC debug identifier definitions */
-#define MISC_DBGID_DEFINITION_START
-#define MISC_WLAN_SCHEDULER_EVENT_REGISTER_ERROR     1
-#define TLPM_INIT                                    2
-#define TLPM_FILTER_POWER_STATE                      3
-#define TLPM_NOTIFY_NOT_IDLE                         4
-#define TLPM_TIMEOUT_IDLE_HANDLER                    5
-#define TLPM_TIMEOUT_WAKEUP_HANDLER                  6
-#define TLPM_WAKEUP_SIGNAL_HANDLER                   7
-#define TLPM_UNEXPECTED_GPIO_INTR_ERROR              8
-#define TLPM_BREAK_ON_NOT_RECEIVED_ERROR             9
-#define TLPM_BREAK_OFF_NOT_RECIVED_ERROR             10
-#define TLPM_ACK_GPIO_INTR                           11
-#define TLPM_ON                                      12
-#define TLPM_OFF                                     13
-#define TLPM_WAKEUP_FROM_HOST                        14
-#define TLPM_WAKEUP_FROM_BT                          15 
-#define TLPM_TX_BREAK_RECIVED                        16
-#define TLPM_IDLE_TIMER_NOT_RUNNING                  17
-#define MISC_DBGID_DEFINITION_END
-    
-/* TXRX debug identifier definitions */
-#define TXRX_TXBUF_DBGID_DEFINITION_START
-#define TXRX_TXBUF_ALLOCATE_BUF                      1
-#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX                 2
-#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ                  3
-#define TXRX_TXBUF_TXQ_DEPTH                         4   
-#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ                 5
-#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ         6
-#define TXRX_TXBUF_INITIALIZE_TIMER                  7
-#define TXRX_TXBUF_ARM_TIMER                         8
-#define TXRX_TXBUF_DISARM_TIMER                      9
-#define TXRX_TXBUF_UNINITIALIZE_TIMER                10
-#define TXRX_TXBUF_DBGID_DEFINITION_END
-#define TXRX_RXBUF_DBGID_DEFINITION_START    
-#define TXRX_RXBUF_ALLOCATE_BUF                      1
-#define TXRX_RXBUF_QUEUE_TO_HOST                     2
-#define TXRX_RXBUF_QUEUE_TO_WLAN                     3
-#define TXRX_RXBUF_ZERO_LEN_BUF                      4
-#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN  5
-#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF        6
-#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN         7
-#define TXRX_RXBUF_SEND_TO_RECV_MGMT                 8
-#define TXRX_RXBUF_SEND_TO_IEEE_LAYER                9
-#define TXRX_RXBUF_REQUEUE_ERROR                     10
-#define TXRX_RXBUF_DBGID_DEFINITION_END
-
-#define TXRX_MGMTBUF_DBGID_DEFINITION_START 
-#define TXRX_MGMTBUF_ALLOCATE_BUF                    1
-#define TXRX_MGMTBUF_ALLOCATE_SM_BUF                 2    
-#define TXRX_MGMTBUF_ALLOCATE_RMBUF                  3
-#define TXRX_MGMTBUF_GET_BUF                         4
-#define TXRX_MGMTBUF_GET_SM_BUF                      5
-#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ                6
-#define TXRX_MGMTBUF_REAPED_BUF                      7
-#define TXRX_MGMTBUF_REAPED_SM_BUF                   8
-#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN              9
-#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN          10
-#define TXRX_MGMTBUF_ENQUEUE_INTO_DATA_SFQ           11
-#define TXRX_MGMTBUF_DEQUEUE_FROM_DATA_SFQ           12
-#define TXRX_MGMTBUF_PAUSE_DATA_TXQ                  13
-#define TXRX_MGMTBUF_RESUME_DATA_TXQ                 14
-#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT       15
-#define TXRX_MGMTBUF_DRAINQ                          16
-#define TXRX_MGMTBUF_INDICATE_Q_DRAINED              17
-#define TXRX_MGMTBUF_ENQUEUE_INTO_HW_SFQ             18
-#define TXRX_MGMTBUF_DEQUEUE_FROM_HW_SFQ             19
-#define TXRX_MGMTBUF_PAUSE_HW_TXQ                    20
-#define TXRX_MGMTBUF_RESUME_HW_TXQ                   21
-#define TXRX_MGMTBUF_TEAR_DOWN_BA                    22
-#define TXRX_MGMTBUF_PROCESS_ADDBA_REQ               23
-#define TXRX_MGMTBUF_PROCESS_DELBA                   24
-#define TXRX_MGMTBUF_PERFORM_BA                      25
-#define TXRX_MGMTBUF_WLAN_RESET_ON_ERROR             26 
-#define TXRX_MGMTBUF_DBGID_DEFINITION_END
-
-/* PM (Power Module) debug identifier definitions */
-#define PM_DBGID_DEFINITION_START
-#define PM_INIT                                      1
-#define PM_ENABLE                                    2
-#define PM_SET_STATE                                 3
-#define PM_SET_POWERMODE                             4
-#define PM_CONN_NOTIFY                               5
-#define PM_REF_COUNT_NEGATIVE                        6
-#define PM_INFRA_STA_APSD_ENABLE                     7
-#define PM_INFRA_STA_UPDATE_APSD_STATE               8
-#define PM_CHAN_OP_REQ                               9
-#define PM_SET_MY_BEACON_POLICY                      10
-#define PM_SET_ALL_BEACON_POLICY                     11
-#define PM_INFRA_STA_SET_PM_PARAMS1                  12
-#define PM_INFRA_STA_SET_PM_PARAMS2                  13
-#define PM_ADHOC_SET_PM_CAPS_FAIL                    14
-#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID              15
-#define PM_ADHOC_SET_PM_PARAMS                       16
-#define PM_ADHOC_STATE1                              18
-#define PM_ADHOC_STATE2                              19
-#define PM_ADHOC_CONN_MAP                            20 
-#define PM_FAKE_SLEEP                                21
-#define PM_AP_STATE1                                 22
-#define PM_AP_SET_PM_PARAMS                          23
-#define PM_DBGID_DEFINITION_END
-
-/* Wake on Wireless debug identifier definitions */
-#define WOW_DBGID_DEFINITION_START
-#define WOW_INIT                                        1
-#define WOW_GET_CONFIG_DSET                             2   
-#define WOW_NO_CONFIG_DSET                              3
-#define WOW_INVALID_CONFIG_DSET                         4
-#define WOW_USE_DEFAULT_CONFIG                          5
-#define WOW_SETUP_GPIO                                  6
-#define WOW_INIT_DONE                                   7
-#define WOW_SET_GPIO_PIN                                8
-#define WOW_CLEAR_GPIO_PIN                              9
-#define WOW_SET_WOW_MODE_CMD                            10
-#define WOW_SET_HOST_MODE_CMD                           11  
-#define WOW_ADD_WOW_PATTERN_CMD                         12    
-#define WOW_NEW_WOW_PATTERN_AT_INDEX                    13    
-#define WOW_DEL_WOW_PATTERN_CMD                         14    
-#define WOW_LIST_CONTAINS_PATTERNS                      15    
-#define WOW_GET_WOW_LIST_CMD                            16 
-#define WOW_INVALID_FILTER_ID                           17
-#define WOW_INVALID_FILTER_LISTID                       18
-#define WOW_NO_VALID_FILTER_AT_ID                       19
-#define WOW_NO_VALID_LIST_AT_ID                         20
-#define WOW_NUM_PATTERNS_EXCEEDED                       21
-#define WOW_NUM_LISTS_EXCEEDED                          22
-#define WOW_GET_WOW_STATS                               23
-#define WOW_CLEAR_WOW_STATS                             24
-#define WOW_WAKEUP_HOST                                 25
-#define WOW_EVENT_WAKEUP_HOST                           26
-#define WOW_EVENT_DISCARD                               27
-#define WOW_PATTERN_MATCH                               28
-#define WOW_PATTERN_NOT_MATCH                           29
-#define WOW_PATTERN_NOT_MATCH_OFFSET                    30
-#define WOW_DISABLED_HOST_ASLEEP                        31
-#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS             32
-#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND          33
-#define WOW_DBGID_DEFINITION_END
-
-/* WHAL debug identifier definitions */
-#define WHAL_DBGID_DEFINITION_START
-#define WHAL_ERROR_ANI_CONTROL                      1
-#define WHAL_ERROR_CHIP_TEST1                       2
-#define WHAL_ERROR_CHIP_TEST2                       3
-#define WHAL_ERROR_EEPROM_CHECKSUM                  4
-#define WHAL_ERROR_EEPROM_MACADDR                   5
-#define WHAL_ERROR_INTERRUPT_HIU                    6
-#define WHAL_ERROR_KEYCACHE_RESET                   7
-#define WHAL_ERROR_KEYCACHE_SET                     8 
-#define WHAL_ERROR_KEYCACHE_TYPE                    9
-#define WHAL_ERROR_KEYCACHE_TKIPENTRY              10
-#define WHAL_ERROR_KEYCACHE_WEPLENGTH              11
-#define WHAL_ERROR_PHY_INVALID_CHANNEL             12
-#define WHAL_ERROR_POWER_AWAKE                     13
-#define WHAL_ERROR_POWER_SET                       14
-#define WHAL_ERROR_RECV_STOPDMA                    15
-#define WHAL_ERROR_RECV_STOPPCU                    16
-#define WHAL_ERROR_RESET_CHANNF1                   17
-#define WHAL_ERROR_RESET_CHANNF2                   18
-#define WHAL_ERROR_RESET_PM                        19
-#define WHAL_ERROR_RESET_OFFSETCAL                 20
-#define WHAL_ERROR_RESET_RFGRANT                   21
-#define WHAL_ERROR_RESET_RXFRAME                   22
-#define WHAL_ERROR_RESET_STOPDMA                   23
-#define WHAL_ERROR_RESET_RECOVER                   24
-#define WHAL_ERROR_XMIT_COMPUTE                    25
-#define WHAL_ERROR_XMIT_NOQUEUE                    26
-#define WHAL_ERROR_XMIT_ACTIVEQUEUE                27
-#define WHAL_ERROR_XMIT_BADTYPE                    28
-#define WHAL_ERROR_XMIT_STOPDMA                    29
-#define WHAL_ERROR_INTERRUPT_BB_PANIC              30 
-#define WHAL_ERROR_RESET_TXIQCAL                   31 
-#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW      32 
-#define WHAL_DBGID_DEFINITION_END
-
-/* DC debug identifier definitions */
-#define DC_DBGID_DEFINITION_START
-#define DC_SCAN_CHAN_START                          1
-#define DC_SCAN_CHAN_FINISH                         2
-#define DC_BEACON_RECEIVE7                          3
-#define DC_SSID_PROBE_CB                            4
-#define DC_SEND_NEXT_SSID_PROBE                     5
-#define DC_START_SEARCH                             6
-#define DC_CANCEL_SEARCH_CB                         7
-#define DC_STOP_SEARCH                              8
-#define DC_END_SEARCH                               9
-#define DC_MIN_CHDWELL_TIMEOUT                     10
-#define DC_START_SEARCH_CANCELED                   11
-#define DC_SET_POWER_MODE                          12
-#define DC_INIT                                    13
-#define DC_SEARCH_OPPORTUNITY                      14
-#define DC_RECEIVED_ANY_BEACON                     15
-#define DC_RECEIVED_MY_BEACON                      16
-#define DC_PROFILE_IS_ADHOC_BUT_BSS_IS_INFRA       17
-#define DC_PS_ENABLED_BUT_ATHEROS_IE_ABSENT        18
-#define DC_BSS_ADHOC_CHANNEL_NOT_ALLOWED           19
-#define DC_SET_BEACON_UPDATE                       20
-#define DC_BEACON_UPDATE_COMPLETE                  21
-#define DC_END_SEARCH_BEACON_UPDATE_COMP_CB        22
-#define DC_BSSINFO_EVENT_DROPPED                   23
-#define DC_IEEEPS_ENABLED_BUT_ATIM_ABSENT          24 
-#define DC_DBGID_DEFINITION_END
-
-/* CO debug identifier definitions */
-#define CO_DBGID_DEFINITION_START
-#define CO_INIT                                     1
-#define CO_ACQUIRE_LOCK                             2
-#define CO_START_OP1                                3
-#define CO_START_OP2                                4
-#define CO_DRAIN_TX_COMPLETE_CB                     5
-#define CO_CHANGE_CHANNEL_CB                        6
-#define CO_RETURN_TO_HOME_CHANNEL                   7
-#define CO_FINISH_OP_TIMEOUT                        8
-#define CO_OP_END                                   9
-#define CO_CANCEL_OP                               10
-#define CO_CHANGE_CHANNEL                          11
-#define CO_RELEASE_LOCK                            12
-#define CO_CHANGE_STATE                            13
-#define CO_DBGID_DEFINITION_END
-
-/* RO debug identifier definitions */
-#define RO_DBGID_DEFINITION_START
-#define RO_REFRESH_ROAM_TABLE                       1
-#define RO_UPDATE_ROAM_CANDIDATE                    2
-#define RO_UPDATE_ROAM_CANDIDATE_CB                 3
-#define RO_UPDATE_ROAM_CANDIDATE_FINISH             4
-#define RO_REFRESH_ROAM_TABLE_DONE                  5
-#define RO_PERIODIC_SEARCH_CB                       6
-#define RO_PERIODIC_SEARCH_TIMEOUT                  7
-#define RO_INIT                                     8
-#define RO_BMISS_STATE1                             9
-#define RO_BMISS_STATE2                            10
-#define RO_SET_PERIODIC_SEARCH_ENABLE              11
-#define RO_SET_PERIODIC_SEARCH_DISABLE             12
-#define RO_ENABLE_SQ_THRESHOLD                     13
-#define RO_DISABLE_SQ_THRESHOLD                    14
-#define RO_ADD_BSS_TO_ROAM_TABLE                   15
-#define RO_SET_PERIODIC_SEARCH_MODE                16
-#define RO_CONFIGURE_SQ_THRESHOLD1                 17
-#define RO_CONFIGURE_SQ_THRESHOLD2                 18
-#define RO_CONFIGURE_SQ_PARAMS                     19
-#define RO_LOW_SIGNAL_QUALITY_EVENT                20
-#define RO_HIGH_SIGNAL_QUALITY_EVENT               21
-#define RO_REMOVE_BSS_FROM_ROAM_TABLE              22
-#define RO_UPDATE_CONNECTION_STATE_METRIC          23
-#define RO_DBGID_DEFINITION_END
-
-/* CM debug identifier definitions */
-#define CM_DBGID_DEFINITION_START
-#define CM_INITIATE_HANDOFF                         1
-#define CM_INITIATE_HANDOFF_CB                      2
-#define CM_CONNECT_EVENT                            3
-#define CM_DISCONNECT_EVENT                         4
-#define CM_INIT                                     5
-#define CM_HANDOFF_SOURCE                           6
-#define CM_SET_HANDOFF_TRIGGERS                     7
-#define CM_CONNECT_REQUEST                          8
-#define CM_CONNECT_REQUEST_CB                       9
-#define CM_CONTINUE_SCAN_CB                         10 
-#define CM_DBGID_DEFINITION_END
-
-
-/* mgmt debug identifier definitions */
-#define MGMT_DBGID_DEFINITION_START
-#define KEYMGMT_CONNECTION_INIT                     1
-#define KEYMGMT_CONNECTION_COMPLETE                 2
-#define KEYMGMT_CONNECTION_CLOSE                    3
-#define KEYMGMT_ADD_KEY                             4
-#define MLME_NEW_STATE                              5
-#define MLME_CONN_INIT                              6
-#define MLME_CONN_COMPLETE                          7
-#define MLME_CONN_CLOSE                             8 
-#define MGMT_DBGID_DEFINITION_END
-
-/* TMR debug identifier definitions */
-#define TMR_DBGID_DEFINITION_START
-#define TMR_HANG_DETECTED                           1
-#define TMR_WDT_TRIGGERED                           2
-#define TMR_WDT_RESET                               3
-#define TMR_HANDLER_ENTRY                           4
-#define TMR_HANDLER_EXIT                            5
-#define TMR_SAVED_START                             6
-#define TMR_SAVED_END                               7
-#define TMR_DBGID_DEFINITION_END
-
-/* BTCOEX debug identifier definitions */
-#define BTCOEX_DBGID_DEFINITION_START
-#define BTCOEX_STATUS_CMD                           1
-#define BTCOEX_PARAMS_CMD                           2
-#define BTCOEX_ANT_CONFIG                           3
-#define BTCOEX_COLOCATED_BT_DEVICE                  4
-#define BTCOEX_CLOSE_RANGE_SCO_ON                   5
-#define BTCOEX_CLOSE_RANGE_SCO_OFF                  6
-#define BTCOEX_CLOSE_RANGE_A2DP_ON                  7
-#define BTCOEX_CLOSE_RANGE_A2DP_OFF                 8
-#define BTCOEX_A2DP_PROTECT_ON                      9
-#define BTCOEX_A2DP_PROTECT_OFF                     10
-#define BTCOEX_SCO_PROTECT_ON                       11
-#define BTCOEX_SCO_PROTECT_OFF                      12
-#define BTCOEX_CLOSE_RANGE_DETECTOR_START           13
-#define BTCOEX_CLOSE_RANGE_DETECTOR_STOP            14
-#define BTCOEX_CLOSE_RANGE_TOGGLE                   15
-#define BTCOEX_CLOSE_RANGE_TOGGLE_RSSI_LRCNT        16
-#define BTCOEX_CLOSE_RANGE_RSSI_THRESH              17
-#define BTCOEX_CLOSE_RANGE_LOW_RATE_THRESH          18
-#define BTCOEX_PTA_PRI_INTR_HANDLER                    19
-#define BTCOEX_PSPOLL_QUEUED                                           20
-#define BTCOEX_PSPOLL_COMPLETE                                         21
-#define BTCOEX_DBG_PM_AWAKE                                                    22
-#define BTCOEX_DBG_PM_SLEEP                                                    23
-#define BTCOEX_DBG_SCO_COEX_ON                                         24
-#define BTCOEX_SCO_DATARECEIVE                                         25
-#define BTCOEX_INTR_INIT                                                       26
-#define BTCOEX_PTA_PRI_DIFF                                                    27
-#define BTCOEX_TIM_NOTIFICATION                                                28
-#define BTCOEX_SCO_WAKEUP_ON_DATA                                      29
-#define BTCOEX_SCO_SLEEP                                                       30
-#define BTCOEX_SET_WEIGHTS                                                     31
-#define BTCOEX_SCO_DATARECEIVE_LATENCY_VAL                     32
-#define BTCOEX_SCO_MEASURE_TIME_DIFF                           33
-#define BTCOEX_SET_EOL_VAL                                                     34
-#define BTCOEX_OPT_DETECT_HANDLER                                      35
-#define BTCOEX_SCO_TOGGLE_STATE                                                36
-#define BTCOEX_SCO_STOMP                                                       37
-#define BTCOEX_NULL_COMP_CALLBACK                                      38
-#define BTCOEX_RX_INCOMING                                                     39
-#define BTCOEX_RX_INCOMING_CTL                                         40
-#define BTCOEX_RX_INCOMING_MGMT                                                41
-#define BTCOEX_RX_INCOMING_DATA                                                42
-#define BTCOEX_RTS_RECEPTION                                           43
-#define BTCOEX_FRAME_PRI_LOW_RATE_THRES                                44
-#define BTCOEX_PM_FAKE_SLEEP                                           45
-#define BTCOEX_ACL_COEX_STATUS                                         46
-#define BTCOEX_ACL_COEX_DETECTION                                      47
-#define BTCOEX_A2DP_COEX_STATUS                                                48
-#define BTCOEX_SCO_STATUS                                                      49
-#define BTCOEX_WAKEUP_ON_DATA                                          50
-#define BTCOEX_DATARECEIVE                                                     51
-#define BTCOEX_GET_MAX_AGGR_SIZE                                       53
-#define BTCOEX_MAX_AGGR_AVAIL_TIME                                     54
-#define BTCOEX_DBG_WBTIMER_INTR                                                55
-#define BTCOEX_DBG_SCO_SYNC                         57
-#define BTCOEX_UPLINK_QUEUED_RATE                                      59
-#define BTCOEX_DBG_UPLINK_ENABLE_EOL                           60
-#define BTCOEX_UPLINK_FRAME_DURATION                           61
-#define BTCOEX_UPLINK_SET_EOL                                          62
-#define BTCOEX_DBG_EOL_EXPIRED                                         63
-#define BTCOEX_DBG_DATA_COMPLETE                                       64
-#define BTCOEX_UPLINK_QUEUED_TIMESTAMP                         65
-#define BTCOEX_DBG_DATA_COMPLETE_TIME                          66
-#define BTCOEX_DBG_A2DP_ROLE_IS_SLAVE               67
-#define BTCOEX_DBG_A2DP_ROLE_IS_MASTER              68
-#define BTCOEX_DBG_UPLINK_SEQ_NUM                                      69
-#define BTCOEX_UPLINK_AGGR_SEQ                                         70
-#define BTCOEX_DBG_TX_COMP_SEQ_NO                                      71
-#define BTCOEX_DBG_MAX_AGGR_PAUSE_STATE                                72
-#define BTCOEX_DBG_ACL_TRAFFIC                      73
-#define BTCOEX_CURR_AGGR_PROP                                          74
-#define BTCOEX_DBG_SCO_GET_PER_TIME_DIFF                       75
-#define BTCOEX_PSPOLL_PROCESS                                          76
-#define BTCOEX_RETURN_FROM_MAC                                         77
-#define BTCOEX_FREED_REQUEUED_CNT                                      78
-#define BTCOEX_DBG_TOGGLE_LOW_RATES                                    79
-#define BTCOEX_MAC_GOES_TO_SLEEP                               80
-#define BTCOEX_DBG_A2DP_NO_SYNC                     81
-#define BTCOEX_RETURN_FROM_MAC_HOLD_Q_INFO                     82
-#define BTCOEX_RETURN_FROM_MAC_AC                                      83
-#define BTCOEX_DBG_DTIM_RECV                        84
-#define BTCOEX_IS_PRE_UPDATE                                           86
-#define BTCOEX_ENQUEUED_BIT_MAP                                                87
-#define BTCOEX_TX_COMPLETE_FIRST_DESC_STATS                    88
-#define BTCOEX_UPLINK_DESC                                                     89
-#define BTCOEX_SCO_GET_PER_FIRST_FRM_TIMESTAMP         90
-#define BTCOEX_DBG_RECV_ACK                                                    94
-#define BTCOEX_DBG_ADDBA_INDICATION                 95
-#define BTCOEX_TX_COMPLETE_EOL_FAILED                          96
-#define BTCOEX_DBG_A2DP_USAGE_COMPLETE                         97
-#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_HANDLER          98
-#define BTCOEX_DBG_A2DP_SYNC_INTR                   99
-#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_RECEPTION           100
-#define BTCOEX_FORM_AGGR_CURR_AGGR                                101
-#define BTCOEX_DBG_TOGGLE_A2DP_BURST_CNT           102
-#define BTCOEX_DBG_BT_TRAFFIC                                     103
-#define BTCOEX_DBG_STOMP_BT_TRAFFIC                       104
-#define BTCOEX_RECV_NULL                           105
-#define BTCOEX_DBG_A2DP_MASTER_BT_END                     106
-#define BTCOEX_DBG_A2DP_BT_START                                  107
-#define BTCOEX_DBG_A2DP_SLAVE_BT_END                      108
-#define BTCOEX_DBG_A2DP_STOMP_BT                                  109
-#define BTCOEX_DBG_GO_TO_SLEEP                                    110
-#define BTCOEX_DBG_A2DP_PKT                                               111
-#define BTCOEX_DBG_A2DP_PSPOLL_DATA_RECV                  112
-#define BTCOEX_DBG_A2DP_NULL                                      113
-#define BTCOEX_DBG_UPLINK_DATA                                    114
-#define BTCOEX_DBG_A2DP_STOMP_LOW_PRIO_NULL               115
-#define BTCOEX_DBG_ADD_BA_RESP_TIMEOUT                    116
-#define BTCOEX_DBG_TXQ_STATE                                      117
-#define BTCOEX_DBG_ALLOW_SCAN                                     118
-#define BTCOEX_DBG_SCAN_REQUEST                                           119
-#define BTCOEX_A2DP_SLEEP                                                 127
-#define BTCOEX_DBG_DATA_ACTIV_TIMEOUT                     128
-#define BTCOEX_DBG_SWITCH_TO_PSPOLL_ON_MODE               129
-#define BTCOEX_DBG_SWITCH_TO_PSPOLL_OFF_MODE      130
-#define BTCOEX_DATARECEIVE_AGGR                                           131
-#define BTCOEX_DBG_DATA_RECV_SLEEPING_PENDING     132
-#define BTCOEX_DBG_DATARESP_TIMEOUT                               133
-#define BTCOEX_BDG_BMISS                                                  134
-#define BTCOEX_DBG_DATA_RECV_WAKEUP_TIM                           135
-#define BTCOEX_DBG_SECOND_BMISS                                           136
-#define BTCOEX_DBG_SET_WLAN_STATE                                 138
-#define BTCOEX_BDG_FIRST_BMISS                                    139
-#define BTCOEX_DBG_A2DP_CHAN_OP                                           140
-#define BTCOEX_DBG_A2DP_INTR                                      141
-#define BTCOEX_DBG_BT_INQUIRY                                     142
-#define BTCOEX_DBG_BT_INQUIRY_DATA_FETCH                  143
-#define BTCOEX_DBG_POST_INQUIRY_FINISH                    144
-#define BTCOEX_DBG_SCO_OPT_MODE_TIMER_HANDLER     145
-#define BTCOEX_DBG_NULL_FRAME_SLEEP                               146
-#define BTCOEX_DBG_NULL_FRAME_AWAKE                               147
-#define BTCOEX_DBG_SET_AGGR_SIZE                                  152
-#define BTCOEX_DBG_TEAR_BA_TIMEOUT                                153
-#define BTCOEX_DBG_MGMT_FRAME_SEQ_NO                      154
-#define BTCOEX_DBG_SCO_STOMP_HIGH_PRI                     155
-#define BTCOEX_DBG_COLOCATED_BT_DEV                               156
-#define BTCOEX_DBG_FE_ANT_TYPE                                157
-#define BTCOEX_DBG_BT_INQUIRY_CMD                                 158
-#define BTCOEX_DBG_SCO_CONFIG                                     159
-#define BTCOEX_DBG_SCO_PSPOLL_CONFIG                      160
-#define BTCOEX_DBG_SCO_OPTMODE_CONFIG                 161
-#define BTCOEX_DBG_A2DP_CONFIG                                162
-#define BTCOEX_DBG_A2DP_PSPOLL_CONFIG                 163
-#define BTCOEX_DBG_A2DP_OPTMODE_CONFIG                164
-#define BTCOEX_DBG_ACLCOEX_CONFIG                             165
-#define BTCOEX_DBG_ACLCOEX_PSPOLL_CONFIG                  166
-#define BTCOEX_DBG_ACLCOEX_OPTMODE_CONFIG             167
-#define BTCOEX_DBG_DEBUG_CMD                                      168
-#define BTCOEX_DBG_SET_BT_OPERATING_STATUS                169
-#define BTCOEX_DBG_GET_CONFIG                                     170
-#define BTCOEX_DBG_GET_STATS                                      171
-#define BTCOEX_DBG_BT_OPERATING_STATUS                    172
-#define BTCOEX_DBG_PERFORM_RECONNECT               173
-#define BTCOEX_DBG_ACL_WLAN_MED                    175
-#define BTCOEX_DBG_ACL_BT_MED                      176
-#define BTCOEX_DBG_WLAN_CONNECT                    177
-#define BTCOEX_DBG_A2DP_DUAL_START                 178
-#define BTCOEX_DBG_PMAWAKE_NOTIFY                  179
-#define BTCOEX_DBG_BEACON_SCAN_ENABLE              180
-#define BTCOEX_DBG_BEACON_SCAN_DISABLE             181
-#define BTCOEX_DBG_RX_NOTIFY                       182
-#define BTCOEX_SCO_GET_PER_SECOND_FRM_TIMESTAMP    183
-#define BTCOEX_DBG_TXQ_DETAILS                     184
-#define BTCOEX_DBG_SCO_STOMP_LOW_PRI               185
-#define BTCOEX_DBG_A2DP_FORCE_SCAN                 186
-#define BTCOEX_DBG_DTIM_STOMP_COMP                 187
-#define BTCOEX_ACL_PRESENCE_TIMER                  188
-#define BTCOEX_DBGID_DEFINITION_END
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DBGLOG_ID_H_ */
diff --git a/drivers/staging/ath6kl/include/common/discovery.h b/drivers/staging/ath6kl/include/common/discovery.h
deleted file mode 100644 (file)
index da1b332..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="discovery.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef _DISCOVERY_H_
-#define _DISCOVERY_H_
-
-/*
- * DC_SCAN_PRIORITY is an 8-bit bitmap of the scan priority of a channel
- */
-typedef enum {
-    DEFAULT_SCPRI = 0x01,
-    POPULAR_SCPRI = 0x02,
-    SSIDS_SCPRI   = 0x04,
-    PROF_SCPRI    = 0x08,
-} DC_SCAN_PRIORITY;
-
-/* The following search type construct can be used to manipulate the behavior of the search module based on different bits set */
-typedef enum {
-    SCAN_RESET                     = 0,
-    SCAN_ALL                       = (DEFAULT_SCPRI | POPULAR_SCPRI |  \
-                                      SSIDS_SCPRI | PROF_SCPRI),
-
-    SCAN_POPULAR                   = (POPULAR_SCPRI | SSIDS_SCPRI | PROF_SCPRI),
-    SCAN_SSIDS                     = (SSIDS_SCPRI | PROF_SCPRI),
-    SCAN_PROF_MASK                 = (PROF_SCPRI),
-    SCAN_MULTI_CHANNEL             = 0x000100,
-    SCAN_DETERMINISTIC             = 0x000200,
-    SCAN_PROFILE_MATCH_TERMINATED  = 0x000400,
-    SCAN_HOME_CHANNEL_SKIP         = 0x000800,
-    SCAN_CHANNEL_LIST_CONTINUE     = 0x001000,
-    SCAN_CURRENT_SSID_SKIP         = 0x002000,
-    SCAN_ACTIVE_PROBE_DISABLE      = 0x004000,
-    SCAN_CHANNEL_HINT_ONLY         = 0x008000,
-    SCAN_ACTIVE_CHANNELS_ONLY      = 0x010000,
-    SCAN_UNUSED1                   = 0x020000, /* unused */
-    SCAN_PERIODIC                  = 0x040000,
-    SCAN_FIXED_DURATION            = 0x080000,
-    SCAN_AP_ASSISTED               = 0x100000,
-} DC_SCAN_TYPE;
-
-typedef enum {
-    BSS_REPORTING_DEFAULT = 0x0,
-    EXCLUDE_NON_SCAN_RESULTS = 0x1, /* Exclude results outside of scan */
-} DC_BSS_REPORTING_POLICY;
-
-typedef enum {
-    DC_IGNORE_WPAx_GROUP_CIPHER = 0x01,
-    DC_PROFILE_MATCH_DONE = 0x02,
-    DC_IGNORE_AAC_BEACON = 0x04, 
-    DC_CSA_FOLLOW_BSS = 0x08,
-} DC_PROFILE_FILTER;
-
-#define DEFAULT_DC_PROFILE_FILTER   (DC_CSA_FOLLOW_BSS)
-
-#endif  /* _DISCOVERY_H_ */
diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h
deleted file mode 100644 (file)
index 9eb5fdf..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//
-
-/* This file contains shared definitions for the host/target endpoint ping test */
-
-#ifndef EPPING_TEST_H_
-#define EPPING_TEST_H_
-
-    /* alignment to 4-bytes */
-#define EPPING_ALIGNMENT_PAD  (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr))
-
-#ifndef A_OFFSETOF
-#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field))
-#endif
-
-#define EPPING_RSVD_FILL                  0xCC
-
-#define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET  7 
-  
-typedef PREPACK struct {    
-    u8 _HCIRsvd[8];           /* reserved for HCI packet header (GMBOX) testing */
-    u8 StreamEcho_h;          /* stream no. to echo this packet on (filled by host) */
-    u8 StreamEchoSent_t;      /* stream no. packet was echoed to (filled by target)
-                                          When echoed: StreamEchoSent_t == StreamEcho_h */
-    u8 StreamRecv_t;          /* stream no. that target received this packet on (filled by target) */
-    u8 StreamNo_h;            /* stream number to send on (filled by host) */
-    u8 Magic_h[4];            /* magic number to filter for this packet on the host*/
-    u8 _rsvd[6];              /* reserved fields that must be set to a "reserved" value
-                                          since this packet maps to a 14-byte ethernet frame we want 
-                                          to make sure ethertype field is set to something unknown */
-                                          
-    u8 _pad[2];               /* padding for alignment */
-    u8 TimeStamp[8];          /* timestamp of packet (host or target) */
-    u32 HostContext_h;         /* 4 byte host context, target echos this back */
-    u32 SeqNo;                 /* sequence number (set by host or target) */
-    u16 Cmd_h;                 /* ping command (filled by host) */
-    u16 CmdFlags_h;            /* optional flags */
-    u8 CmdBuffer_h[8];        /* buffer for command (host -> target) */
-    u8 CmdBuffer_t[8];        /* buffer for command (target -> host) */
-    u16 DataLength;            /* length of data */
-    u16 DataCRC;               /* 16 bit CRC of data */
-    u16 HeaderCRC;             /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */
-} POSTPACK EPPING_HEADER;
-
-#define EPPING_PING_MAGIC_0               0xAA
-#define EPPING_PING_MAGIC_1               0x55
-#define EPPING_PING_MAGIC_2               0xCE
-#define EPPING_PING_MAGIC_3               0xEC
-
-
-
-#define IS_EPPING_PACKET(pPkt)   (((pPkt)->Magic_h[0] == EPPING_PING_MAGIC_0) && \
-                                  ((pPkt)->Magic_h[1] == EPPING_PING_MAGIC_1) && \
-                                  ((pPkt)->Magic_h[2] == EPPING_PING_MAGIC_2) && \
-                                  ((pPkt)->Magic_h[3] == EPPING_PING_MAGIC_3))
-
-#define SET_EPPING_PACKET_MAGIC(pPkt) { (pPkt)->Magic_h[0] = EPPING_PING_MAGIC_0; \
-                                        (pPkt)->Magic_h[1] = EPPING_PING_MAGIC_1; \
-                                        (pPkt)->Magic_h[2] = EPPING_PING_MAGIC_2; \
-                                        (pPkt)->Magic_h[3] = EPPING_PING_MAGIC_3;}
-                                                                            
-#define CMD_FLAGS_DATA_CRC            (1 << 0)  /* DataCRC field is valid */
-#define CMD_FLAGS_DELAY_ECHO          (1 << 1)  /* delay the echo of the packet */
-#define CMD_FLAGS_NO_DROP             (1 << 2)  /* do not drop at HTC layer no matter what the stream is */
-
-#define IS_EPING_PACKET_NO_DROP(pPkt)  ((pPkt)->CmdFlags_h & CMD_FLAGS_NO_DROP)
-
-#define EPPING_CMD_ECHO_PACKET          1   /* echo packet test */
-#define EPPING_CMD_RESET_RECV_CNT       2   /* reset recv count */
-#define EPPING_CMD_CAPTURE_RECV_CNT     3   /* fetch recv count, 4-byte count returned in CmdBuffer_t */
-#define EPPING_CMD_NO_ECHO              4   /* non-echo packet test (tx-only) */
-#define EPPING_CMD_CONT_RX_START        5   /* continuous RX packets, parameters are in CmdBuffer_h */
-#define EPPING_CMD_CONT_RX_STOP         6   /* stop continuous RX packet transmission */
-
-    /* test command parameters may be no more than 8 bytes */
-typedef PREPACK struct {    
-    u16 BurstCnt;       /* number of packets to burst together (for HTC 2.1 testing) */
-    u16 PacketLength;   /* length of packet to generate including header */
-    u16 Flags;          /* flags */
-
-#define EPPING_CONT_RX_DATA_CRC     (1 << 0)  /* Add CRC to all data */
-#define EPPING_CONT_RX_RANDOM_DATA  (1 << 1)  /* randomize the data pattern */
-#define EPPING_CONT_RX_RANDOM_LEN   (1 << 2)  /* randomize the packet lengths */          
-} POSTPACK EPPING_CONT_RX_PARAMS;
-
-#define EPPING_HDR_CRC_OFFSET    A_OFFSETOF(EPPING_HEADER,StreamNo_h)
-#define EPPING_HDR_BYTES_CRC     (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(u16)))
-
-#define HCI_TRANSPORT_STREAM_NUM  16  /* this number is higher than the define WMM AC classes so we
-                                         can use this to distinguish packets */
-
-#endif /*EPPING_TEST_H_*/
diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h
deleted file mode 100644 (file)
index ea11c14..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __GMBOXIF_H__
-#define __GMBOXIF_H__
-
-/* GMBOX interface definitions */
-    
-#define AR6K_GMBOX_CREDIT_COUNTER       1   /* we use credit counter 1 to track credits */
-#define AR6K_GMBOX_CREDIT_SIZE_COUNTER  2   /* credit counter 2 is used to pass the size of each credit */
-
-
-    /* HCI UART transport definitions when used over GMBOX interface */
-#define HCI_UART_COMMAND_PKT 0x01
-#define HCI_UART_ACL_PKT     0x02
-#define HCI_UART_SCO_PKT     0x03
-#define HCI_UART_EVENT_PKT   0x04
-
-    /* definitions for BT HCI packets */
-typedef PREPACK struct {
-    u16 Flags_ConnHandle;
-    u16 Length;
-} POSTPACK BT_HCI_ACL_HEADER;
-
-typedef PREPACK struct {
-    u16 Flags_ConnHandle;
-    u8 Length;
-} POSTPACK BT_HCI_SCO_HEADER;
-
-typedef PREPACK struct {
-    u16 OpCode;
-    u8 ParamLength;
-} POSTPACK BT_HCI_COMMAND_HEADER;
-
-typedef PREPACK struct {
-    u8 EventCode;
-    u8 ParamLength;
-} POSTPACK BT_HCI_EVENT_HEADER;
-
-/* MBOX host interrupt signal assignments */
-
-#define MBOX_SIG_HCI_BRIDGE_MAX      8
-#define MBOX_SIG_HCI_BRIDGE_BT_ON    0
-#define MBOX_SIG_HCI_BRIDGE_BT_OFF   1
-#define MBOX_SIG_HCI_BRIDGE_BAUD_SET 2
-#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON    3
-#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF   4
-
-
-#endif /* __GMBOXIF_H__ */
-
diff --git a/drivers/staging/ath6kl/include/common/gpio_reg.h b/drivers/staging/ath6kl/include/common/gpio_reg.h
deleted file mode 100644 (file)
index f9d425d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _GPIO_REG_REG_H_
-#define _GPIO_REG_REG_H_
-
-#define GPIO_PIN10_ADDRESS                       0x00000050
-#define GPIO_PIN11_ADDRESS                       0x00000054
-#define GPIO_PIN12_ADDRESS                       0x00000058
-#define GPIO_PIN13_ADDRESS                       0x0000005c
-
-#endif /* _GPIO_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h
deleted file mode 100644 (file)
index 85cbfa8..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __HTC_H__
-#define __HTC_H__
-
-#define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field))
-
-#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \
-        (((u16)(((u8 *)(p))[(highbyte)])) << 8 | (u16)(((u8 *)(p))[(lowbyte)]))
-        
-/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a 
- * structure using only the type and field name.
- * Use these macros if there is the potential for unaligned buffer accesses. */
-#define A_GET_UINT16_FIELD(p,type,field) \
-    ASSEMBLE_UNALIGNED_UINT16(p,\
-                              A_OFFSETOF(type,field) + 1, \
-                              A_OFFSETOF(type,field))
-
-#define A_SET_UINT16_FIELD(p,type,field,value) \
-{                                              \
-    ((u8 *)(p))[A_OFFSETOF(type,field)] = (u8)(value);        \
-    ((u8 *)(p))[A_OFFSETOF(type,field) + 1] = (u8)((value) >> 8); \
-}
-  
-#define A_GET_UINT8_FIELD(p,type,field) \
-            ((u8 *)(p))[A_OFFSETOF(type,field)]
-            
-#define A_SET_UINT8_FIELD(p,type,field,value) \
-    ((u8 *)(p))[A_OFFSETOF(type,field)] = (value)
-
-/****** DANGER DANGER ***************
- * 
- *   The frame header length and message formats defined herein were
- *   selected to accommodate optimal alignment for target processing.  This reduces code
- *   size and improves performance.
- * 
- *   Any changes to the header length may alter the alignment and cause exceptions
- *   on the target. When adding to the message structures insure that fields are
- *   properly aligned.
- * 
- */
-
-/* HTC frame header */
-PREPACK struct htc_frame_hdr {
-        /* do not remove or re-arrange these fields, these are minimally required
-         * to take advantage of 4-byte lookaheads in some hardware implementations */
-    u8 EndpointID;
-    u8 Flags;
-    u16 PayloadLen;       /* length of data (including trailer) that follows the header */
-    
-    /***** end of 4-byte lookahead ****/
-    
-    u8 ControlBytes[2];
-    
-    /* message payload starts after the header */
-    
-} POSTPACK;
-
-/* frame header flags */
-
-    /* send direction */
-#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
-#define HTC_FLAGS_SEND_BUNDLE        (1 << 1)  /* start or part of bundle */
-    /* receive direction */
-#define HTC_FLAGS_RECV_UNUSED_0      (1 << 0)  /* bit 0 unused */    
-#define HTC_FLAGS_RECV_TRAILER       (1 << 1)  /* bit 1 trailer data present */
-#define HTC_FLAGS_RECV_UNUSED_2      (1 << 0)  /* bit 2 unused */
-#define HTC_FLAGS_RECV_UNUSED_3      (1 << 0)  /* bit 3 unused */
-#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0)  /* bits 7..4  */
-#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4
-
-#define HTC_HDR_LENGTH  (sizeof(struct htc_frame_hdr))
-#define HTC_MAX_TRAILER_LENGTH   255
-#define HTC_MAX_PAYLOAD_LENGTH   (4096 - sizeof(struct htc_frame_hdr))
-
-/* HTC control message IDs */
-
-#define HTC_MSG_READY_ID                    1
-#define HTC_MSG_CONNECT_SERVICE_ID          2
-#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3   
-#define HTC_MSG_SETUP_COMPLETE_ID           4
-#define HTC_MSG_SETUP_COMPLETE_EX_ID        5
-
-#define HTC_MAX_CONTROL_MESSAGE_LENGTH  256
-         
-/* base message ID header */
-typedef PREPACK struct {
-    u16 MessageID;
-} POSTPACK HTC_UNKNOWN_MSG;
-                                                     
-/* HTC ready message
- * direction : target-to-host  */
-typedef PREPACK struct {
-    u16 MessageID;    /* ID */
-    u16 CreditCount;  /* number of credits the target can offer */
-    u16 CreditSize;   /* size of each credit */
-    u8 MaxEndpoints; /* maximum number of endpoints the target has resources for */
-    u8 _Pad1;
-} POSTPACK HTC_READY_MSG;
-
-    /* extended HTC ready message */
-typedef PREPACK struct {
-    HTC_READY_MSG   Version2_0_Info;   /* legacy version 2.0 information at the front... */
-    /* extended information */
-    u8 HTCVersion;
-    u8 MaxMsgsPerHTCBundle;
-} POSTPACK HTC_READY_EX_MSG;
-
-#define HTC_VERSION_2P0  0x00  
-#define HTC_VERSION_2P1  0x01  /* HTC 2.1 */
-
-#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
-
-/* connect service
- * direction : host-to-target */
-typedef PREPACK struct {
-    u16 MessageID;
-    u16 ServiceID;           /* service ID of the service to connect to */
-    u16 ConnectionFlags;     /* connection flags */
-
-#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2)  /* reduce credit dribbling when 
-                                                             the host needs credits */  
-#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK             (0x3)  
-#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH        0x0
-#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF          0x1
-#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS     0x2
-#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY             0x3
-                                                             
-    u8 ServiceMetaLength;   /* length of meta data that follows */
-    u8 _Pad1;
-    
-    /* service-specific meta data starts after the header */
-    
-} POSTPACK HTC_CONNECT_SERVICE_MSG;
-
-/* connect response
- * direction : target-to-host */
-typedef PREPACK struct {
-    u16 MessageID;
-    u16 ServiceID;            /* service ID that the connection request was made */
-    u8 Status;               /* service connection status */
-    u8 EndpointID;           /* assigned endpoint ID */
-    u16 MaxMsgSize;           /* maximum expected message size on this endpoint */
-    u8 ServiceMetaLength;    /* length of meta data that follows */
-    u8 _Pad1;
-    
-    /* service-specific meta data starts after the header */
-    
-} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG;
-
-typedef PREPACK struct {
-    u16 MessageID;
-    /* currently, no other fields */
-} POSTPACK HTC_SETUP_COMPLETE_MSG;
-
-    /* extended setup completion message */
-typedef PREPACK struct {
-    u16 MessageID;
-    u32 SetupFlags;
-    u8 MaxMsgsPerBundledRecv;
-    u8 Rsvd[3];
-} POSTPACK HTC_SETUP_COMPLETE_EX_MSG;
-
-#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV     (1 << 0)
-
-/* connect response status codes */
-#define HTC_SERVICE_SUCCESS      0  /* success */
-#define HTC_SERVICE_NOT_FOUND    1  /* service could not be found */
-#define HTC_SERVICE_FAILED       2  /* specific service failed the connect */
-#define HTC_SERVICE_NO_RESOURCES 3  /* no resources (i.e. no more endpoints) */  
-#define HTC_SERVICE_NO_MORE_EP   4  /* specific service is not allowing any more 
-                                       endpoints */
-
-/* report record IDs */
-
-#define HTC_RECORD_NULL             0
-#define HTC_RECORD_CREDITS          1
-#define HTC_RECORD_LOOKAHEAD        2
-#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
-
-typedef PREPACK struct {
-    u8 RecordID;     /* Record ID */
-    u8 Length;       /* Length of record */
-} POSTPACK HTC_RECORD_HDR;
-
-typedef PREPACK struct {
-    u8 EndpointID;     /* Endpoint that owns these credits */
-    u8 Credits;        /* credits to report since last report */
-} POSTPACK HTC_CREDIT_REPORT;
-
-typedef PREPACK struct {    
-    u8 PreValid;         /* pre valid guard */
-    u8 LookAhead[4];     /* 4 byte lookahead */
-    u8 PostValid;        /* post valid guard */
-    
-   /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes.
-    * The PreValid bytes must equal the inverse of the PostValid byte */
-    
-} POSTPACK HTC_LOOKAHEAD_REPORT;
-
-typedef PREPACK struct {    
-    u8 LookAhead[4];     /* 4 byte lookahead */
-} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT;
-
-#endif /* __HTC_H__ */
-
diff --git a/drivers/staging/ath6kl/include/common/htc_services.h b/drivers/staging/ath6kl/include/common/htc_services.h
deleted file mode 100644 (file)
index fb22268..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_services.h" company="Atheros">
-//    Copyright (c) 2007 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __HTC_SERVICES_H__
-#define __HTC_SERVICES_H__
-
-/* Current service IDs */
-
-typedef enum {
-    RSVD_SERVICE_GROUP  = 0,
-    WMI_SERVICE_GROUP   = 1, 
-    
-    HTC_TEST_GROUP = 254,
-    HTC_SERVICE_GROUP_LAST = 255
-}HTC_SERVICE_GROUP_IDS;
-
-#define MAKE_SERVICE_ID(group,index) \
-            (int)(((int)group << 8) | (int)(index))
-
-/* NOTE: service ID of 0x0000 is reserved and should never be used */
-#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1)
-#define WMI_CONTROL_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0)
-#define WMI_DATA_BE_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1)
-#define WMI_DATA_BK_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2)
-#define WMI_DATA_VI_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3)
-#define WMI_DATA_VO_SVC   MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4)
-#define WMI_MAX_SERVICES  5
-
-/* raw stream service (i.e. flash, tcmd, calibration apps) */
-#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0)
-
-#endif /*HTC_SERVICES_H_*/
diff --git a/drivers/staging/ath6kl/include/common/pkt_log.h b/drivers/staging/ath6kl/include/common/pkt_log.h
deleted file mode 100644 (file)
index a3719ad..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2005-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __PKT_LOG_H__
-#define __PKT_LOG_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Pkt log info */
-typedef PREPACK struct pkt_log_t {
-    struct info_t {
-        u16 st;
-        u16 end;
-        u16 cur;
-    }info[4096];
-    u16 last_idx;
-}POSTPACK PACKET_LOG;
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif  /* __PKT_LOG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/roaming.h b/drivers/staging/ath6kl/include/common/roaming.h
deleted file mode 100644 (file)
index 8019850..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="roaming.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef _ROAMING_H_
-#define _ROAMING_H_
-
-/* 
- * The signal quality could be in terms of either snr or rssi. We should 
- * have an enum for both of them. For the time being, we are going to move 
- * it to wmi.h that is shared by both host and the target, since we are 
- * repartitioning the code to the host 
- */
-#define SIGNAL_QUALITY_NOISE_FLOOR        -96
-#define SIGNAL_QUALITY_METRICS_NUM_MAX    2
-typedef enum {
-    SIGNAL_QUALITY_METRICS_SNR = 0,
-    SIGNAL_QUALITY_METRICS_RSSI,
-    SIGNAL_QUALITY_METRICS_ALL,
-} SIGNAL_QUALITY_METRICS_TYPE;
-
-#endif  /* _ROAMING_H_ */
diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h
deleted file mode 100644 (file)
index c866cef..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2010 Atheros Corporation.  All rights reserved.
-//
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef __TARGADDRS_H__
-#define __TARGADDRS_H__
-
-#if defined(AR6002)
-#include "AR6002/addrs.h"
-#endif
-
-/*
- * AR6K option bits, to enable/disable various features.
- * By default, all option bits are 0.
- * These bits can be set in LOCAL_SCRATCH register 0.
- */
-#define AR6K_OPTION_BMI_DISABLE      0x01 /* Disable BMI comm with Host */
-#define AR6K_OPTION_SERIAL_ENABLE    0x02 /* Enable serial port msgs */
-#define AR6K_OPTION_WDT_DISABLE      0x04 /* WatchDog Timer override */
-#define AR6K_OPTION_SLEEP_DISABLE    0x08 /* Disable system sleep */
-#define AR6K_OPTION_STOP_BOOT        0x10 /* Stop boot processes (for ATE) */
-#define AR6K_OPTION_ENABLE_NOANI     0x20 /* Operate without ANI */
-#define AR6K_OPTION_DSET_DISABLE     0x40 /* Ignore DataSets */
-#define AR6K_OPTION_IGNORE_FLASH     0x80 /* Ignore flash during bootup */
-
-/*
- * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
- * host_interest structure.  It must match the address of the _host_interest
- * symbol (see linker script).
- *
- * Host Interest is shared between Host and Target in order to coordinate
- * between the two, and is intended to remain constant (with additions only
- * at the end) across software releases.
- *
- * All addresses are available here so that it's possible to
- * write a single binary that works with all Target Types.
- * May be used in assembler code as well as C.
- */
-#define AR6002_HOST_INTEREST_ADDRESS    0x00500400
-#define AR6003_HOST_INTEREST_ADDRESS    0x00540600
-
-
-#define HOST_INTEREST_MAX_SIZE          0x100
-
-#if !defined(__ASSEMBLER__)
-struct register_dump_s;
-struct dbglog_hdr_s;
-
-/*
- * These are items that the Host may need to access
- * via BMI or via the Diagnostic Window. The position
- * of items in this structure must remain constant
- * across firmware revisions!
- *
- * Types for each item must be fixed size across
- * target and host platforms.
- *
- * More items may be added at the end.
- */
-PREPACK struct host_interest_s {
-    /*
-     * Pointer to application-defined area, if any.
-     * Set by Target application during startup.
-     */
-    u32 hi_app_host_interest;                      /* 0x00 */
-
-    /* Pointer to register dump area, valid after Target crash. */
-    u32 hi_failure_state;                          /* 0x04 */
-
-    /* Pointer to debug logging header */
-    u32 hi_dbglog_hdr;                             /* 0x08 */
-
-    u32 hi_unused1;                       /* 0x0c */
-
-    /*
-     * General-purpose flag bits, similar to AR6000_OPTION_* flags.
-     * Can be used by application rather than by OS.
-     */
-    u32 hi_option_flag;                            /* 0x10 */
-
-    /*
-     * Boolean that determines whether or not to
-     * display messages on the serial port.
-     */
-    u32 hi_serial_enable;                          /* 0x14 */
-
-    /* Start address of DataSet index, if any */
-    u32 hi_dset_list_head;                         /* 0x18 */
-
-    /* Override Target application start address */
-    u32 hi_app_start;                              /* 0x1c */
-
-    /* Clock and voltage tuning */
-    u32 hi_skip_clock_init;                        /* 0x20 */
-    u32 hi_core_clock_setting;                     /* 0x24 */
-    u32 hi_cpu_clock_setting;                      /* 0x28 */
-    u32 hi_system_sleep_setting;                   /* 0x2c */
-    u32 hi_xtal_control_setting;                   /* 0x30 */
-    u32 hi_pll_ctrl_setting_24ghz;                 /* 0x34 */
-    u32 hi_pll_ctrl_setting_5ghz;                  /* 0x38 */
-    u32 hi_ref_voltage_trim_setting;               /* 0x3c */
-    u32 hi_clock_info;                             /* 0x40 */
-
-    /*
-     * Flash configuration overrides, used only
-     * when firmware is not executing from flash.
-     * (When using flash, modify the global variables
-     * with equivalent names.)
-     */
-    u32 hi_bank0_addr_value;                       /* 0x44 */
-    u32 hi_bank0_read_value;                       /* 0x48 */
-    u32 hi_bank0_write_value;                      /* 0x4c */
-    u32 hi_bank0_config_value;                     /* 0x50 */
-
-    /* Pointer to Board Data  */
-    u32 hi_board_data;                             /* 0x54 */
-    u32 hi_board_data_initialized;                 /* 0x58 */
-
-    u32 hi_dset_RAM_index_table;                   /* 0x5c */
-
-    u32 hi_desired_baud_rate;                      /* 0x60 */
-    u32 hi_dbglog_config;                          /* 0x64 */
-    u32 hi_end_RAM_reserve_sz;                     /* 0x68 */
-    u32 hi_mbox_io_block_sz;                       /* 0x6c */
-
-    u32 hi_num_bpatch_streams;                     /* 0x70 -- unused */
-    u32 hi_mbox_isr_yield_limit;                   /* 0x74 */
-
-    u32 hi_refclk_hz;                              /* 0x78 */
-    u32 hi_ext_clk_detected;                       /* 0x7c */
-    u32 hi_dbg_uart_txpin;                         /* 0x80 */
-    u32 hi_dbg_uart_rxpin;                         /* 0x84 */
-    u32 hi_hci_uart_baud;                          /* 0x88 */
-    u32 hi_hci_uart_pin_assignments;               /* 0x8C */
-        /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */
-    u32 hi_hci_uart_baud_scale_val;                /* 0x90 */
-    u32 hi_hci_uart_baud_step_val;                 /* 0x94 */
-
-    u32 hi_allocram_start;                         /* 0x98 */
-    u32 hi_allocram_sz;                            /* 0x9c */
-    u32 hi_hci_bridge_flags;                       /* 0xa0 */
-    u32 hi_hci_uart_support_pins;                  /* 0xa4 */
-        /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */
-    u32 hi_hci_uart_pwr_mgmt_params;               /* 0xa8 */
-       /*
-        * 0xa8   - [1]: 0 = UART FC active low, 1 = UART FC active high
-        *      [31:16]: wakeup timeout in ms
-        */
-
-       /* Pointer to extended board data */
-       u32 hi_board_ext_data;                /* 0xac */
-       u32 hi_board_ext_data_config;         /* 0xb0 */
-
-       /*
-         * Bit [0]  :   valid
-         * Bit[31:16:   size
-       */
-       /*
-        * hi_reset_flag is used to do some stuff when target reset.
-        * such as restore app_start after warm reset or
-        * preserve host Interest area, or preserve ROM data, literals etc.
-        */
-       u32 hi_reset_flag;                            /* 0xb4 */
-       /* indicate hi_reset_flag is valid */
-       u32 hi_reset_flag_valid;                      /* 0xb8 */
-       u32 hi_hci_uart_pwr_mgmt_params_ext;           /* 0xbc */
-       /*
-        * 0xbc - [31:0]: idle timeout in ms
-        */
-       /* ACS flags */
-       u32 hi_acs_flags;                              /* 0xc0 */
-       u32 hi_console_flags;                          /* 0xc4 */
-       u32 hi_nvram_state;                            /* 0xc8 */
-       u32 hi_option_flag2;                           /* 0xcc */
-
-       /* If non-zero, override values sent to Host in WMI_READY event. */
-       u32 hi_sw_version_override;                    /* 0xd0 */
-       u32 hi_abi_version_override;                   /* 0xd4 */
-
-       /*
-        * Percentage of high priority RX traffic to total expected RX traffic -
-        * applicable only to ar6004
-        */
-       u32 hi_hp_rx_traffic_ratio;                    /* 0xd8 */
-
-       /* test applications flags */
-       u32 hi_test_apps_related    ;                  /* 0xdc */
-       /* location of test script */
-       u32 hi_ota_testscript;                         /* 0xe0 */
-       /* location of CAL data */
-       u32 hi_cal_data;                               /* 0xe4 */
-       /* Number of packet log buffers */
-        u32 hi_pktlog_num_buffers;                     /* 0xe8 */
-
-} POSTPACK;
-
-/* Bits defined in hi_option_flag */
-#define HI_OPTION_TIMER_WAR       0x01 /* Enable timer workaround */
-#define HI_OPTION_BMI_CRED_LIMIT  0x02 /* Limit BMI command credits */
-#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */
-/* MAC addr method 0-locally administred 1-globally unique addrs */
-#define HI_OPTION_MAC_ADDR_METHOD   0x08
-#define HI_OPTION_FW_BRIDGE         0x10 /* Firmware Bridging */
-#define HI_OPTION_ENABLE_PROFILE    0x20 /* Enable CPU profiling */
-#define HI_OPTION_DISABLE_DBGLOG    0x40 /* Disable debug logging */
-#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */
-#define HI_OPTION_PAPRD_DISABLE     0x100 /* Disable PAPRD (debug) */
-#define HI_OPTION_NUM_DEV_LSB       0x200
-#define HI_OPTION_NUM_DEV_MSB       0x800
-#define HI_OPTION_DEV_MODE_LSB      0x1000
-#define HI_OPTION_DEV_MODE_MSB      0x8000000
-/* Disable LowFreq Timer Stabilization */
-#define HI_OPTION_NO_LFT_STBL       0x10000000
-#define HI_OPTION_SKIP_REG_SCAN     0x20000000 /* Skip regulatory scan */
-/* Do regulatory scan during init beforesending WMI ready event to host */
-#define HI_OPTION_INIT_REG_SCAN     0x40000000
-#define HI_OPTION_SKIP_MEMMAP       0x80000000 /* REV6: Do not adjust memory
-                                                map */
-
-/* hi_option_flag2 options */
-#define HI_OPTION_OFFLOAD_AMSDU     0x01
-#define HI_OPTION_DFS_SUPPORT       0x02 /* Enable DFS support */
-
-#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
-
-/* 2 bits of hi_option_flag are used to represent 3 modes */
-#define HI_OPTION_FW_MODE_IBSS    0x0 /* IBSS Mode */
-#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */
-#define HI_OPTION_FW_MODE_AP      0x2 /* AP Mode */
-
-/* 2 bits of hi_option flag are usedto represent 4 submodes */
-#define HI_OPTION_FW_SUBMODE_NONE    0x0  /* Normal mode */
-#define HI_OPTION_FW_SUBMODE_P2PDEV  0x1  /* p2p device mode */
-#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */
-#define HI_OPTION_FW_SUBMODE_P2PGO   0x3 /* p2p go mode */
-
-/* Num dev Mask */
-#define HI_OPTION_NUM_DEV_MASK    0x7
-#define HI_OPTION_NUM_DEV_SHIFT   0x9
-
-/* firmware bridging */
-#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
-
-/* Fw Mode/SubMode Mask
-|------------------------------------------------------------------------------|
-|   SUB   |   SUB   |   SUB   |  SUB    |         |         |         |
-| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
-|   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)
-|------------------------------------------------------------------------------|
-*/
-#define HI_OPTION_FW_MODE_BITS         0x2
-#define HI_OPTION_FW_MODE_MASK         0x3
-#define HI_OPTION_FW_MODE_SHIFT        0xC
-#define HI_OPTION_ALL_FW_MODE_MASK     0xFF
-
-#define HI_OPTION_FW_SUBMODE_BITS      0x2
-#define HI_OPTION_FW_SUBMODE_MASK      0x3
-#define HI_OPTION_FW_SUBMODE_SHIFT     0x14
-#define HI_OPTION_ALL_FW_SUBMODE_MASK  0xFF00
-#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8
-
-/* hi_reset_flag */
-
-/* preserve App Start address */
-#define HI_RESET_FLAG_PRESERVE_APP_START         0x01
-/* preserve host interest */
-#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST     0x02
-#define HI_RESET_FLAG_PRESERVE_ROMDATA           0x04  /* preserve ROM data */
-#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE       0x08
-#define HI_RESET_FLAG_PRESERVE_BOOT_INFO         0x10
-
-#define HI_RESET_FLAG_IS_VALID  0x12345678 /* indicate the reset flag is
-valid */
-
-#define ON_RESET_FLAGS_VALID() \
-       (HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID)
-
-#define RESET_FLAGS_VALIDATE()  \
-       (HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID)
-
-#define RESET_FLAGS_INVALIDATE() \
-       (HOST_INTEREST->hi_reset_flag_valid = 0)
-
-#define ON_RESET_PRESERVE_APP_START() \
-        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START)
-
-#define ON_RESET_PRESERVE_NVRAM_STATE() \
-        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE)
-
-#define ON_RESET_PRESERVE_HOST_INTEREST() \
-        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST)
-
-#define ON_RESET_PRESERVE_ROMDATA() \
-        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA)
-
-#define ON_RESET_PRESERVE_BOOT_INFO() \
-        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO)
-
-#define HI_ACS_FLAGS_ENABLED        (1 << 0)    /* ACS is enabled */
-#define HI_ACS_FLAGS_USE_WWAN       (1 << 1)    /* Use physical WWAN device */
-#define HI_ACS_FLAGS_TEST_VAP       (1 << 2)    /* Use test VAP */
-
-/* CONSOLE FLAGS
- *
- * Bit Range  Meaning
- * ---------  --------------------------------
- *   2..0     UART ID (0 = Default)
- *    3       Baud Select (0 = 9600, 1 = 115200)
- *   30..4    Reserved
- *    31      Enable Console
- *
- */
-
-#define HI_CONSOLE_FLAGS_ENABLE       (1 << 31)
-#define HI_CONSOLE_FLAGS_UART_MASK    (0x7)
-#define HI_CONSOLE_FLAGS_UART_SHIFT   0
-#define HI_CONSOLE_FLAGS_BAUD_SELECT  (1 << 3)
-
-/*
- * Intended for use by Host software, this macro returns the Target RAM
- * address of any item in the host_interest structure.
- * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data);
- */
-#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \
-    (u32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item)))
-
-#define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \
-    (u32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item)))
-
-#define AR6004_HOST_INTEREST_ITEM_ADDRESS(item) \
-        ((u32)&((((struct host_interest_s *)(AR6004_HOST_INTEREST_ADDRESS))->item)))
-
-
-#define HOST_INTEREST_DBGLOG_IS_ENABLED() \
-        (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG))
-
-#define HOST_INTEREST_PKTLOG_IS_ENABLED() \
-        ((HOST_INTEREST->hi_pktlog_num_buffers))
-
-
-#define HOST_INTEREST_PROFILE_IS_ENABLED() \
-        (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE)
-
-#define LF_TIMER_STABILIZATION_IS_ENABLED() \
-        (!(HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL))
-
-#define IS_AMSDU_OFFLAOD_ENABLED() \
-        ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU))
-
-#define HOST_INTEREST_DFS_IS_ENABLED() \
-        ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT))
-
-/* Convert a Target virtual address into a Target physical address */
-#define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff)
-#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
-#define TARG_VTOP(TargetType, vaddr) \
-        (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : AR6003_VTOP(vaddr))
-
-#define AR6003_REV2_APP_START_OVERRIDE          0x944C00
-#define AR6003_REV2_APP_LOAD_ADDRESS            0x543180
-#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS      0x57E500
-#define AR6003_REV2_DATASET_PATCH_ADDRESS       0x57e884
-#define AR6003_REV2_RAM_RESERVE_SIZE            6912
-
-#define AR6003_REV3_APP_START_OVERRIDE          0x945d00
-#define AR6003_REV3_APP_LOAD_ADDRESS            0x545000
-#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS      0x542330
-#define AR6003_REV3_DATASET_PATCH_ADDRESS       0x57FF74
-#define AR6003_REV3_RAM_RESERVE_SIZE            512
-
-#define AR6003_BOARD_EXT_DATA_ADDRESS           0x57E600
-
-/* # of u32 entries in targregs, used by DIAG_FETCH_TARG_REGS */
-#define AR6003_FETCH_TARG_REGS_COUNT 64
-
-#endif /* !__ASSEMBLER__ */
-
-#endif /* __TARGADDRS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h
deleted file mode 100644 (file)
index 7d94aee..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="testcmd.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef  TESTCMD_H_
-#define  TESTCMD_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef AR6002_REV2
-#define TCMD_MAX_RATES 12
-#else
-#define TCMD_MAX_RATES 28
-#endif
-
-typedef enum {
-    ZEROES_PATTERN = 0,
-    ONES_PATTERN,
-    REPEATING_10,
-    PN7_PATTERN,
-    PN9_PATTERN,
-    PN15_PATTERN
-}TX_DATA_PATTERN;
-
-/* Continuous tx
-   mode : TCMD_CONT_TX_OFF - Disabling continuous tx
-          TCMD_CONT_TX_SINE - Enable continuous unmodulated tx
-          TCMD_CONT_TX_FRAME- Enable continuous modulated tx
-   freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g)
-dataRate: 0 - 1 Mbps
-          1 - 2 Mbps
-          2 - 5.5 Mbps
-          3 - 11 Mbps
-          4 - 6 Mbps
-          5 - 9 Mbps
-          6 - 12 Mbps
-          7 - 18 Mbps
-          8 - 24 Mbps
-          9 - 36 Mbps
-         10 - 28 Mbps
-         11 - 54 Mbps
-  txPwr: Tx power in dBm[5 -11] for unmod Tx, [5-14] for mod Tx
-antenna:  1 - one antenna
-          2 - two antenna
-Note : Enable/disable continuous tx test cmd works only when target is awake.
-*/
-
-typedef enum {
-    TCMD_CONT_TX_OFF = 0,
-    TCMD_CONT_TX_SINE,
-    TCMD_CONT_TX_FRAME,
-    TCMD_CONT_TX_TX99,
-    TCMD_CONT_TX_TX100
-} TCMD_CONT_TX_MODE;
-
-typedef enum {
-    TCMD_WLAN_MODE_NOHT = 0,
-    TCMD_WLAN_MODE_HT20 = 1,
-    TCMD_WLAN_MODE_HT40PLUS = 2,
-    TCMD_WLAN_MODE_HT40MINUS = 3,
-} TCMD_WLAN_MODE;
-
-typedef PREPACK struct {
-    u32 testCmdId;
-    u32 mode;
-    u32 freq;
-    u32 dataRate;
-    s32 txPwr;
-    u32 antenna;
-    u32 enANI;
-    u32 scramblerOff;
-    u32 aifsn;
-    u16 pktSz;
-    u16 txPattern;
-    u32 shortGuard;
-    u32 numPackets;
-    u32 wlanMode;
-} POSTPACK TCMD_CONT_TX;
-
-#define TCMD_TXPATTERN_ZERONE                 0x1
-#define TCMD_TXPATTERN_ZERONE_DIS_SCRAMBLE    0x2
-
-/* Continuous Rx
- act: TCMD_CONT_RX_PROMIS - promiscuous mode (accept all incoming frames)
-      TCMD_CONT_RX_FILTER - filter mode (accept only frames with dest
-                                             address equal specified
-                                             mac address (set via act =3)
-      TCMD_CONT_RX_REPORT  off mode  (disable cont rx mode and get the
-                                          report from the last cont
-                                          Rx test)
-
-     TCMD_CONT_RX_SETMAC - set MacAddr mode (sets the MAC address for the
-                                                 target. This Overrides
-                                                 the default MAC address.)
-
-*/
-typedef enum {
-    TCMD_CONT_RX_PROMIS =0,
-    TCMD_CONT_RX_FILTER,
-    TCMD_CONT_RX_REPORT,
-    TCMD_CONT_RX_SETMAC,
-    TCMD_CONT_RX_SET_ANT_SWITCH_TABLE
-} TCMD_CONT_RX_ACT;
-
-typedef PREPACK struct {
-    u32 testCmdId;
-    u32 act;
-    u32 enANI;
-    PREPACK union {
-        struct PREPACK TCMD_CONT_RX_PARA {
-            u32 freq;
-            u32 antenna;
-            u32 wlanMode;
-        } POSTPACK para;
-        struct PREPACK TCMD_CONT_RX_REPORT {
-            u32 totalPkt;
-            s32 rssiInDBm;
-            u32 crcErrPkt;
-            u32 secErrPkt;
-            u16 rateCnt[TCMD_MAX_RATES];
-            u16 rateCntShortGuard[TCMD_MAX_RATES];
-        } POSTPACK report;
-        struct PREPACK TCMD_CONT_RX_MAC {
-            u8    addr[ATH_MAC_LEN];
-        } POSTPACK mac;
-        struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE {
-            u32 antswitch1;
-            u32 antswitch2;
-        }POSTPACK antswitchtable;
-    } POSTPACK u;
-} POSTPACK TCMD_CONT_RX;
-
-/* Force sleep/wake  test cmd
- mode: TCMD_PM_WAKEUP - Wakeup the target
-       TCMD_PM_SLEEP - Force the target to sleep.
- */
-typedef enum {
-    TCMD_PM_WAKEUP = 1, /* be consistent with target */
-    TCMD_PM_SLEEP,
-    TCMD_PM_DEEPSLEEP
-} TCMD_PM_MODE;
-
-typedef PREPACK struct {
-    u32 testCmdId;
-    u32 mode;
-} POSTPACK TCMD_PM;
-
-typedef enum {
-    TCMD_CONT_TX_ID,
-    TCMD_CONT_RX_ID,
-    TCMD_PM_ID
-} TCMD_ID;
-
-typedef PREPACK union {
-          TCMD_CONT_TX contTx;
-          TCMD_CONT_RX contRx;
-          TCMD_PM pm;
-} POSTPACK TEST_CMD;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TESTCMD_H_ */
diff --git a/drivers/staging/ath6kl/include/common/tlpm.h b/drivers/staging/ath6kl/include/common/tlpm.h
deleted file mode 100644 (file)
index 659b1c0..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __TLPM_H__
-#define __TLPM_H__
-
-/* idle timeout in 16-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
-#define TLPM_DEFAULT_IDLE_TIMEOUT_MS         1000
-/* hex in LSB and MSB for HCI command */
-#define TLPM_DEFAULT_IDLE_TIMEOUT_LSB        0xE8
-#define TLPM_DEFAULT_IDLE_TIMEOUT_MSB        0x3
-
-/* wakeup timeout in 8-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
-#define TLPM_DEFAULT_WAKEUP_TIMEOUT_MS       10
-
-/* default UART FC polarity is low */
-#define TLPM_DEFAULT_UART_FC_POLARITY        0
-
-#endif
diff --git a/drivers/staging/ath6kl/include/common/wlan_defs.h b/drivers/staging/ath6kl/include/common/wlan_defs.h
deleted file mode 100644 (file)
index 03e4d23..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wlan_defs.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef __WLAN_DEFS_H__
-#define __WLAN_DEFS_H__
-
-/*
- * This file contains WLAN definitions that may be used across both
- * Host and Target software.  
- */
-
-typedef enum {
-    MODE_11A        = 0,   /* 11a Mode */
-    MODE_11G        = 1,   /* 11b/g Mode */
-    MODE_11B        = 2,   /* 11b Mode */
-    MODE_11GONLY    = 3,   /* 11g only Mode */
-#ifdef SUPPORT_11N
-    MODE_11NA_HT20   = 4,  /* 11a HT20 mode */
-    MODE_11NG_HT20   = 5,  /* 11g HT20 mode */
-    MODE_11NA_HT40   = 6,  /* 11a HT40 mode */
-    MODE_11NG_HT40   = 7,  /* 11g HT40 mode */
-    MODE_UNKNOWN    = 8,
-    MODE_MAX        = 8
-#else
-    MODE_UNKNOWN    = 4,
-    MODE_MAX        = 4
-#endif
-} WLAN_PHY_MODE;
-
-typedef enum {
-    WLAN_11A_CAPABILITY   = 1,
-    WLAN_11G_CAPABILITY   = 2,
-    WLAN_11AG_CAPABILITY  = 3,
-}WLAN_CAPABILITY;
-
-#ifdef SUPPORT_11N
-typedef unsigned long A_RATEMASK;
-#else
-typedef unsigned short A_RATEMASK;
-#endif
-
-#ifdef SUPPORT_11N
-#define IS_MODE_11A(mode)       (((mode) == MODE_11A) || \
-                                 ((mode) == MODE_11NA_HT20) || \
-                                 ((mode) == MODE_11NA_HT40))
-#define IS_MODE_11B(mode)       ((mode) == MODE_11B)
-#define IS_MODE_11G(mode)       (((mode) == MODE_11G) || \
-                                 ((mode) == MODE_11GONLY) || \
-                                 ((mode) == MODE_11NG_HT20) || \
-                                 ((mode) == MODE_11NG_HT40))
-#define IS_MODE_11GONLY(mode)   ((mode) == MODE_11GONLY)
-#else
-#define IS_MODE_11A(mode)       ((mode) == MODE_11A)
-#define IS_MODE_11B(mode)       ((mode) == MODE_11B)
-#define IS_MODE_11G(mode)       (((mode) == MODE_11G) || \
-                                 ((mode) == MODE_11GONLY))
-#define IS_MODE_11GONLY(mode)   ((mode) == MODE_11GONLY)
-#endif /* SUPPORT_11N */
-
-#endif /* __WLANDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h
deleted file mode 100644 (file)
index d968744..0000000
+++ /dev/null
@@ -1,3220 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-//
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-/*
- * This file contains the definitions of the WMI protocol specified in the
- * Wireless Module Interface (WMI).  It includes definitions of all the
- * commands and events. Commands are messages from the host to the WM.
- * Events and Replies are messages from the WM to the host.
- *
- * Ownership of correctness in regards to commands
- * belongs to the host driver and the WMI is not required to validate
- * parameters for value, proper range, or any other checking.
- *
- */
-
-#ifndef _WMI_H_
-#define _WMI_H_
-
-#include "wmix.h"
-#include "wlan_defs.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define HTC_PROTOCOL_VERSION    0x0002
-#define HTC_PROTOCOL_REVISION   0x0000
-
-#define WMI_PROTOCOL_VERSION    0x0002
-#define WMI_PROTOCOL_REVISION   0x0000
-
-#define ATH_MAC_LEN             6               /* length of mac in bytes */
-#define WMI_CMD_MAX_LEN         100
-#define WMI_CONTROL_MSG_MAX_LEN     256
-#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536
-#define IS_ETHERTYPE(_typeOrLen)        ((_typeOrLen) >= 0x0600)
-#define RFC1042OUI      {0x00, 0x00, 0x00}
-
-#define IP_ETHERTYPE 0x0800
-
-#define WMI_IMPLICIT_PSTREAM 0xFF
-#define WMI_MAX_THINSTREAM 15
-
-#ifdef AR6002_REV2
-#define IBSS_MAX_NUM_STA          4
-#else
-#define IBSS_MAX_NUM_STA          8
-#endif
-
-PREPACK struct host_app_area_s {
-    u32 wmi_protocol_ver;
-} POSTPACK;
-
-/*
- * Data Path
- */
-typedef PREPACK struct {
-    u8 dstMac[ATH_MAC_LEN];
-    u8 srcMac[ATH_MAC_LEN];
-    u16 typeOrLen;
-} POSTPACK ATH_MAC_HDR;
-
-typedef PREPACK struct {
-    u8 dsap;
-    u8 ssap;
-    u8 cntl;
-    u8 orgCode[3];
-    u16 etherType;
-} POSTPACK ATH_LLC_SNAP_HDR;
-
-typedef enum {
-    DATA_MSGTYPE = 0x0,
-    CNTL_MSGTYPE,
-    SYNC_MSGTYPE,
-    OPT_MSGTYPE,
-} WMI_MSG_TYPE;
-
-
-/*
- * Macros for operating on WMI_DATA_HDR (info) field
- */
-
-#define WMI_DATA_HDR_MSG_TYPE_MASK  0x03
-#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
-#define WMI_DATA_HDR_UP_MASK        0x07
-#define WMI_DATA_HDR_UP_SHIFT       2
-/* In AP mode, the same bit (b5) is used to indicate Power save state in
- * the Rx dir and More data bit state in the tx direction.
- */
-#define WMI_DATA_HDR_PS_MASK        0x1
-#define WMI_DATA_HDR_PS_SHIFT       5
-
-#define WMI_DATA_HDR_MORE_MASK      0x1
-#define WMI_DATA_HDR_MORE_SHIFT     5
-
-typedef enum {
-    WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
-    WMI_DATA_HDR_DATA_TYPE_802_11,
-    WMI_DATA_HDR_DATA_TYPE_ACL, /* used to be used for the PAL */
-} WMI_DATA_HDR_DATA_TYPE;
-
-#define WMI_DATA_HDR_DATA_TYPE_MASK     0x3
-#define WMI_DATA_HDR_DATA_TYPE_SHIFT    6
-
-#define WMI_DATA_HDR_SET_MORE_BIT(h) ((h)->info |= (WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT))
-
-#define WMI_DATA_HDR_IS_MSG_TYPE(h, t)  (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t))
-#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) (h)->info = (((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | (t << WMI_DATA_HDR_MSG_TYPE_SHIFT))
-#define WMI_DATA_HDR_GET_UP(h)    (((h)->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK)
-#define WMI_DATA_HDR_SET_UP(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT))
-
-#define WMI_DATA_HDR_GET_DATA_TYPE(h)   (((h)->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) & WMI_DATA_HDR_DATA_TYPE_MASK)
-#define WMI_DATA_HDR_SET_DATA_TYPE(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_DATA_TYPE_MASK << WMI_DATA_HDR_DATA_TYPE_SHIFT)) | ((p) << WMI_DATA_HDR_DATA_TYPE_SHIFT))
-
-#define WMI_DATA_HDR_GET_DOT11(h)   (WMI_DATA_HDR_GET_DATA_TYPE((h)) == WMI_DATA_HDR_DATA_TYPE_802_11)
-#define WMI_DATA_HDR_SET_DOT11(h, p) WMI_DATA_HDR_SET_DATA_TYPE((h), (p))
-
-/* Macros for operating on WMI_DATA_HDR (info2) field */
-#define WMI_DATA_HDR_SEQNO_MASK     0xFFF
-#define WMI_DATA_HDR_SEQNO_SHIFT    0
-
-#define WMI_DATA_HDR_AMSDU_MASK     0x1
-#define WMI_DATA_HDR_AMSDU_SHIFT    12
-
-#define WMI_DATA_HDR_META_MASK      0x7
-#define WMI_DATA_HDR_META_SHIFT     13
-
-#define GET_SEQ_NO(_v)                  ((_v) & WMI_DATA_HDR_SEQNO_MASK)
-#define GET_ISMSDU(_v)                  ((_v) & WMI_DATA_HDR_AMSDU_MASK)
-
-#define WMI_DATA_HDR_GET_SEQNO(h)        GET_SEQ_NO((h)->info2 >> WMI_DATA_HDR_SEQNO_SHIFT)
-#define WMI_DATA_HDR_SET_SEQNO(h, _v)   ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_SEQNO_MASK << WMI_DATA_HDR_SEQNO_SHIFT)) | (GET_SEQ_NO(_v) << WMI_DATA_HDR_SEQNO_SHIFT))
-
-#define WMI_DATA_HDR_IS_AMSDU(h)        GET_ISMSDU((h)->info2 >> WMI_DATA_HDR_AMSDU_SHIFT)
-#define WMI_DATA_HDR_SET_AMSDU(h, _v)   ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_AMSDU_MASK << WMI_DATA_HDR_AMSDU_SHIFT)) | (GET_ISMSDU(_v) << WMI_DATA_HDR_AMSDU_SHIFT))
-
-#define WMI_DATA_HDR_GET_META(h)        (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK)
-#define WMI_DATA_HDR_SET_META(h, _v)    ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT))
-
-/* Macros for operating on WMI_DATA_HDR (info3) field */
-#define WMI_DATA_HDR_DEVID_MASK      0xF
-#define WMI_DATA_HDR_DEVID_SHIFT     0
-#define GET_DEVID(_v)                ((_v) & WMI_DATA_HDR_DEVID_MASK)
-
-#define WMI_DATA_HDR_GET_DEVID(h) \
-       (((h)->info3 >> WMI_DATA_HDR_DEVID_SHIFT) & WMI_DATA_HDR_DEVID_MASK)
-#define WMI_DATA_HDR_SET_DEVID(h, _v) \
-       ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_DEVID_MASK << WMI_DATA_HDR_DEVID_SHIFT)) | (GET_DEVID(_v) << WMI_DATA_HDR_DEVID_SHIFT))
-
-typedef PREPACK struct {
-    s8 rssi;
-    u8 info;               /* usage of 'info' field(8-bit):
-                                     *  b1:b0       - WMI_MSG_TYPE
-                                     *  b4:b3:b2    - UP(tid)
-                                     *  b5          - Used in AP mode. More-data in tx dir, PS in rx.
-                                     *  b7:b6       -  Dot3 header(0),
-                                     *                 Dot11 Header(1),
-                                     *                 ACL data(2)
-                                     */
-
-    u16 info2;              /* usage of 'info2' field(16-bit):
-                                     * b11:b0       - seq_no
-                                     * b12          - A-MSDU?
-                                     * b15:b13      - META_DATA_VERSION 0 - 7
-                                     */
-    u16 info3;
-} POSTPACK WMI_DATA_HDR;
-
-/*
- *  TX META VERSION DEFINITIONS
- */
-#define WMI_MAX_TX_META_SZ  (12)
-#define WMI_MAX_TX_META_VERSION (7)
-#define WMI_META_VERSION_1 (0x01)
-#define WMI_META_VERSION_2 (0X02)
-
-#define WMI_ACL_TO_DOT11_HEADROOM   36
-
-#if 0 /* removed to prevent compile errors for WM.. */
-typedef PREPACK struct {
-/* intentionally empty. Default version is no meta data. */
-} POSTPACK WMI_TX_META_V0;
-#endif
-
-typedef PREPACK struct {
-    u8 pktID;           /* The packet ID to identify the tx request */
-    u8 ratePolicyID;    /* The rate policy to be used for the tx of this frame */
-} POSTPACK WMI_TX_META_V1;
-
-
-#define WMI_CSUM_DIR_TX (0x1)
-#define TX_CSUM_CALC_FILL (0x1)
-typedef PREPACK struct {
-    u8 csumStart;       /*Offset from start of the WMI header for csum calculation to begin */
-    u8 csumDest;        /*Offset from start of WMI header where final csum goes*/
-    u8 csumFlags;    /*number of bytes over which csum is calculated*/
-} POSTPACK WMI_TX_META_V2;
-
-
-/*
- *  RX META VERSION DEFINITIONS
- */
-/* if RX meta data is present at all then the meta data field
- *  will consume WMI_MAX_RX_META_SZ bytes of space between the
- *  WMI_DATA_HDR and the payload. How much of the available
- *  Meta data is actually used depends on which meta data
- *  version is active. */
-#define WMI_MAX_RX_META_SZ  (12)
-#define WMI_MAX_RX_META_VERSION (7)
-
-#define WMI_RX_STATUS_OK            0 /* success */
-#define WMI_RX_STATUS_DECRYPT_ERR   1 /* decrypt error */
-#define WMI_RX_STATUS_MIC_ERR       2 /* tkip MIC error */
-#define WMI_RX_STATUS_ERR           3 /* undefined error */
-
-#define WMI_RX_FLAGS_AGGR           0x0001 /* part of AGGR */
-#define WMI_RX_FlAGS_STBC           0x0002 /* used STBC */
-#define WMI_RX_FLAGS_SGI            0x0004 /* used SGI */
-#define WMI_RX_FLAGS_HT             0x0008 /* is HT packet */
-/* the flags field is also used to store the CRYPTO_TYPE of the frame
- * that value is shifted by WMI_RX_FLAGS_CRYPTO_SHIFT */
-#define WMI_RX_FLAGS_CRYPTO_SHIFT   4
-#define WMI_RX_FLAGS_CRYPTO_MASK    0x1f
-#define WMI_RX_META_GET_CRYPTO(flags) (((flags) >> WMI_RX_FLAGS_CRYPTO_SHIFT) & WMI_RX_FLAGS_CRYPTO_MASK)
-
-#if 0 /* removed to prevent compile errors for WM.. */
-typedef PREPACK struct {
-/* intentionally empty. Default version is no meta data. */
-} POSTPACK WMI_RX_META_VERSION_0;
-#endif
-
-typedef PREPACK struct {
-    u8 status; /* one of WMI_RX_STATUS_... */
-    u8 rix;    /* rate index mapped to rate at which this packet was received. */
-    u8 rssi;   /* rssi of packet */
-    u8 channel;/* rf channel during packet reception */
-    u16 flags;  /* a combination of WMI_RX_FLAGS_... */
-} POSTPACK WMI_RX_META_V1;
-
-#define RX_CSUM_VALID_FLAG (0x1)
-typedef PREPACK struct {
-    u16 csum;
-    u8 csumFlags;/* bit 0 set -partial csum valid
-                             bit 1 set -test mode */
-} POSTPACK WMI_RX_META_V2;
-
-
-
-#define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF)
-/* Macros for operating on WMI_CMD_HDR (info1) field */
-#define WMI_CMD_HDR_DEVID_MASK      0xF
-#define WMI_CMD_HDR_DEVID_SHIFT     0
-#define GET_CMD_DEVID(_v)           ((_v) & WMI_CMD_HDR_DEVID_MASK)
-
-#define WMI_CMD_HDR_GET_DEVID(h) \
-       (((h)->info1 >> WMI_CMD_HDR_DEVID_SHIFT) & WMI_CMD_HDR_DEVID_MASK)
-#define WMI_CMD_HDR_SET_DEVID(h, _v) \
-       ((h)->info1 = ((h)->info1 & \
-               ~(WMI_CMD_HDR_DEVID_MASK << WMI_CMD_HDR_DEVID_SHIFT)) | \
-                (GET_CMD_DEVID(_v) << WMI_CMD_HDR_DEVID_SHIFT))
-
-/*
- * Control Path
- */
-typedef PREPACK struct {
-    u16 commandId;
-/*
- * info1 - 16 bits
- * b03:b00 - id
- * b15:b04 - unused
- */
-    u16 info1;
-
-    u16 reserved;      /* For alignment */
-} POSTPACK WMI_CMD_HDR;        /* used for commands and events */
-
-/*
- * List of Commnands
- */
-typedef enum {
-    WMI_CONNECT_CMDID           = 0x0001,
-    WMI_RECONNECT_CMDID,
-    WMI_DISCONNECT_CMDID,
-    WMI_SYNCHRONIZE_CMDID,
-    WMI_CREATE_PSTREAM_CMDID,
-    WMI_DELETE_PSTREAM_CMDID,
-    WMI_START_SCAN_CMDID,
-    WMI_SET_SCAN_PARAMS_CMDID,
-    WMI_SET_BSS_FILTER_CMDID,
-    WMI_SET_PROBED_SSID_CMDID,               /* 10 */
-    WMI_SET_LISTEN_INT_CMDID,
-    WMI_SET_BMISS_TIME_CMDID,
-    WMI_SET_DISC_TIMEOUT_CMDID,
-    WMI_GET_CHANNEL_LIST_CMDID,
-    WMI_SET_BEACON_INT_CMDID,
-    WMI_GET_STATISTICS_CMDID,
-    WMI_SET_CHANNEL_PARAMS_CMDID,
-    WMI_SET_POWER_MODE_CMDID,
-    WMI_SET_IBSS_PM_CAPS_CMDID,
-    WMI_SET_POWER_PARAMS_CMDID,              /* 20 */
-    WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
-    WMI_ADD_CIPHER_KEY_CMDID,
-    WMI_DELETE_CIPHER_KEY_CMDID,
-    WMI_ADD_KRK_CMDID,
-    WMI_DELETE_KRK_CMDID,
-    WMI_SET_PMKID_CMDID,
-    WMI_SET_TX_PWR_CMDID,
-    WMI_GET_TX_PWR_CMDID,
-    WMI_SET_ASSOC_INFO_CMDID,
-    WMI_ADD_BAD_AP_CMDID,                    /* 30 */
-    WMI_DELETE_BAD_AP_CMDID,
-    WMI_SET_TKIP_COUNTERMEASURES_CMDID,
-    WMI_RSSI_THRESHOLD_PARAMS_CMDID,
-    WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
-    WMI_SET_ACCESS_PARAMS_CMDID,
-    WMI_SET_RETRY_LIMITS_CMDID,
-    WMI_SET_OPT_MODE_CMDID,
-    WMI_OPT_TX_FRAME_CMDID,
-    WMI_SET_VOICE_PKT_SIZE_CMDID,
-    WMI_SET_MAX_SP_LEN_CMDID,                /* 40 */
-    WMI_SET_ROAM_CTRL_CMDID,
-    WMI_GET_ROAM_TBL_CMDID,
-    WMI_GET_ROAM_DATA_CMDID,
-    WMI_ENABLE_RM_CMDID,
-    WMI_SET_MAX_OFFHOME_DURATION_CMDID,
-    WMI_EXTENSION_CMDID,                        /* Non-wireless extensions */
-    WMI_SNR_THRESHOLD_PARAMS_CMDID,
-    WMI_LQ_THRESHOLD_PARAMS_CMDID,
-    WMI_SET_LPREAMBLE_CMDID,
-    WMI_SET_RTS_CMDID,                       /* 50 */
-    WMI_CLR_RSSI_SNR_CMDID,
-    WMI_SET_FIXRATES_CMDID,
-    WMI_GET_FIXRATES_CMDID,
-    WMI_SET_AUTH_MODE_CMDID,
-    WMI_SET_REASSOC_MODE_CMDID,
-    WMI_SET_WMM_CMDID,
-    WMI_SET_WMM_TXOP_CMDID,
-    WMI_TEST_CMDID,
-    /* COEX AR6002 only*/
-    WMI_SET_BT_STATUS_CMDID,                
-    WMI_SET_BT_PARAMS_CMDID,                /* 60 */
-
-    WMI_SET_KEEPALIVE_CMDID,
-    WMI_GET_KEEPALIVE_CMDID,
-    WMI_SET_APPIE_CMDID,
-    WMI_GET_APPIE_CMDID,
-    WMI_SET_WSC_STATUS_CMDID,
-
-    /* Wake on Wireless */
-    WMI_SET_HOST_SLEEP_MODE_CMDID,
-    WMI_SET_WOW_MODE_CMDID,
-    WMI_GET_WOW_LIST_CMDID,
-    WMI_ADD_WOW_PATTERN_CMDID,
-    WMI_DEL_WOW_PATTERN_CMDID,               /* 70 */
-
-    WMI_SET_FRAMERATES_CMDID,
-    WMI_SET_AP_PS_CMDID,
-    WMI_SET_QOS_SUPP_CMDID,
-    /* WMI_THIN_RESERVED_... mark the start and end
-     * values for WMI_THIN_RESERVED command IDs. These
-     * command IDs can be found in wmi_thin.h */
-    WMI_THIN_RESERVED_START = 0x8000,
-    WMI_THIN_RESERVED_END = 0x8fff,
-    /*
-     * Developer commands starts at 0xF000
-     */
-    WMI_SET_BITRATE_CMDID = 0xF000,
-    WMI_GET_BITRATE_CMDID,
-    WMI_SET_WHALPARAM_CMDID,
-
-
-    /*Should add the new command to the tail for compatible with
-     * etna.
-     */
-    WMI_SET_MAC_ADDRESS_CMDID,
-    WMI_SET_AKMP_PARAMS_CMDID,
-    WMI_SET_PMKID_LIST_CMDID,
-    WMI_GET_PMKID_LIST_CMDID,
-    WMI_ABORT_SCAN_CMDID,
-    WMI_SET_TARGET_EVENT_REPORT_CMDID,
-
-    // Unused
-    WMI_UNUSED1,
-    WMI_UNUSED2,
-
-    /*
-     * AP mode commands
-     */
-    WMI_AP_HIDDEN_SSID_CMDID,
-    WMI_AP_SET_NUM_STA_CMDID,
-    WMI_AP_ACL_POLICY_CMDID,
-    WMI_AP_ACL_MAC_LIST_CMDID,
-    WMI_AP_CONFIG_COMMIT_CMDID,
-    WMI_AP_SET_MLME_CMDID,
-    WMI_AP_SET_PVB_CMDID,
-    WMI_AP_CONN_INACT_CMDID,
-    WMI_AP_PROT_SCAN_TIME_CMDID,
-    WMI_AP_SET_COUNTRY_CMDID,
-    WMI_AP_SET_DTIM_CMDID,
-    WMI_AP_MODE_STAT_CMDID,
-
-    WMI_SET_IP_CMDID,
-    WMI_SET_PARAMS_CMDID,
-    WMI_SET_MCAST_FILTER_CMDID,
-    WMI_DEL_MCAST_FILTER_CMDID,
-
-    WMI_ALLOW_AGGR_CMDID,
-    WMI_ADDBA_REQ_CMDID,
-    WMI_DELBA_REQ_CMDID,
-    WMI_SET_HT_CAP_CMDID,
-    WMI_SET_HT_OP_CMDID,
-    WMI_SET_TX_SELECT_RATES_CMDID,
-    WMI_SET_TX_SGI_PARAM_CMDID,
-    WMI_SET_RATE_POLICY_CMDID,
-
-    WMI_HCI_CMD_CMDID,
-    WMI_RX_FRAME_FORMAT_CMDID,
-    WMI_SET_THIN_MODE_CMDID,
-    WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
-
-    WMI_AP_SET_11BG_RATESET_CMDID,
-    WMI_SET_PMK_CMDID,
-    WMI_MCAST_FILTER_CMDID,
-    /* COEX CMDID AR6003*/
-    WMI_SET_BTCOEX_FE_ANT_CMDID,
-    WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
-    WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
-    WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
-    WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
-    WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
-    WMI_SET_BTCOEX_DEBUG_CMDID,
-    WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
-    WMI_GET_BTCOEX_STATS_CMDID,
-    WMI_GET_BTCOEX_CONFIG_CMDID,
-
-       WMI_SET_DFS_ENABLE_CMDID,   /* F034 */
-       WMI_SET_DFS_MINRSSITHRESH_CMDID,
-       WMI_SET_DFS_MAXPULSEDUR_CMDID,
-       WMI_DFS_RADAR_DETECTED_CMDID,
-
-       /* P2P CMDS */
-       WMI_P2P_SET_CONFIG_CMDID,    /* F038 */
-       WMI_WPS_SET_CONFIG_CMDID,
-       WMI_SET_REQ_DEV_ATTR_CMDID,
-       WMI_P2P_FIND_CMDID,
-       WMI_P2P_STOP_FIND_CMDID,
-       WMI_P2P_GO_NEG_START_CMDID,
-       WMI_P2P_LISTEN_CMDID,
-
-       WMI_CONFIG_TX_MAC_RULES_CMDID,    /* F040 */
-       WMI_SET_PROMISCUOUS_MODE_CMDID,
-       WMI_RX_FRAME_FILTER_CMDID,
-       WMI_SET_CHANNEL_CMDID,
-
-       /* WAC commands */
-       WMI_ENABLE_WAC_CMDID,
-       WMI_WAC_SCAN_REPLY_CMDID,
-       WMI_WAC_CTRL_REQ_CMDID,
-       WMI_SET_DIV_PARAMS_CMDID,
-
-       WMI_GET_PMK_CMDID,
-       WMI_SET_PASSPHRASE_CMDID,
-       WMI_SEND_ASSOC_RES_CMDID,
-       WMI_SET_ASSOC_REQ_RELAY_CMDID,
-       WMI_GET_RFKILL_MODE_CMDID,
-
-       /* ACS command, consists of sub-commands */
-       WMI_ACS_CTRL_CMDID,
-
-       /* Ultra low power store / recall commands */
-       WMI_STORERECALL_CONFIGURE_CMDID,
-       WMI_STORERECALL_RECALL_CMDID,
-       WMI_STORERECALL_HOST_READY_CMDID,
-       WMI_FORCE_TARGET_ASSERT_CMDID,
-       WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
-} WMI_COMMAND_ID;
-
-/*
- * Frame Types
- */
-typedef enum {
-    WMI_FRAME_BEACON        =   0,
-    WMI_FRAME_PROBE_REQ,
-    WMI_FRAME_PROBE_RESP,
-    WMI_FRAME_ASSOC_REQ,
-    WMI_FRAME_ASSOC_RESP,
-    WMI_NUM_MGMT_FRAME
-} WMI_MGMT_FRAME_TYPE;
-
-/*
- * Connect Command
- */
-typedef enum {
-    INFRA_NETWORK       = 0x01,
-    ADHOC_NETWORK       = 0x02,
-    ADHOC_CREATOR       = 0x04,
-    AP_NETWORK          = 0x10,
-} NETWORK_TYPE;
-
-typedef enum {
-    OPEN_AUTH           = 0x01,
-    SHARED_AUTH         = 0x02,
-    LEAP_AUTH           = 0x04,  /* different from IEEE_AUTH_MODE definitions */
-} DOT11_AUTH_MODE;
-
-enum {
-       AUTH_IDLE,
-       AUTH_OPEN_IN_PROGRESS,
-};
-
-typedef enum {
-    NONE_AUTH           = 0x01,
-    WPA_AUTH            = 0x02,
-    WPA2_AUTH           = 0x04,
-    WPA_PSK_AUTH        = 0x08,
-    WPA2_PSK_AUTH       = 0x10,
-    WPA_AUTH_CCKM       = 0x20,
-    WPA2_AUTH_CCKM      = 0x40,
-} AUTH_MODE;
-
-typedef enum {
-    NONE_CRYPT          = 0x01,
-    WEP_CRYPT           = 0x02,
-    TKIP_CRYPT          = 0x04,
-    AES_CRYPT           = 0x08,
-#ifdef WAPI_ENABLE
-    WAPI_CRYPT          = 0x10,
-#endif /*WAPI_ENABLE*/
-} CRYPTO_TYPE;
-
-#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
-#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
-
-#ifdef WAPI_ENABLE
-#undef WMI_MAX_CRYPTO_TYPE
-#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1)
-#endif /* WAPI_ENABLE */
-
-#ifdef WAPI_ENABLE
-#define IW_ENCODE_ALG_SM4       0x20
-#define IW_AUTH_WAPI_ENABLED    0x20
-#endif
-
-#define WMI_MIN_KEY_INDEX   0
-#define WMI_MAX_KEY_INDEX   3
-
-#ifdef WAPI_ENABLE
-#undef WMI_MAX_KEY_INDEX
-#define WMI_MAX_KEY_INDEX   7 /* wapi grpKey 0-3, prwKey 4-7 */
-#endif /* WAPI_ENABLE */
-
-#define WMI_MAX_KEY_LEN     32
-
-#define WMI_MAX_SSID_LEN    32
-
-typedef enum {
-    CONNECT_ASSOC_POLICY_USER           = 0x0001,
-    CONNECT_SEND_REASSOC                = 0x0002,
-    CONNECT_IGNORE_WPAx_GROUP_CIPHER    = 0x0004,
-    CONNECT_PROFILE_MATCH_DONE          = 0x0008,
-    CONNECT_IGNORE_AAC_BEACON           = 0x0010,
-    CONNECT_CSA_FOLLOW_BSS              = 0x0020,
-    CONNECT_DO_WPA_OFFLOAD              = 0x0040,
-    CONNECT_DO_NOT_DEAUTH               = 0x0080,
-} WMI_CONNECT_CTRL_FLAGS_BITS;
-
-#define DEFAULT_CONNECT_CTRL_FLAGS    (CONNECT_CSA_FOLLOW_BSS)
-
-typedef PREPACK struct {
-    u8 networkType;
-    u8 dot11AuthMode;
-    u8 authMode;
-    u8 pairwiseCryptoType;
-    u8 pairwiseCryptoLen;
-    u8 groupCryptoType;
-    u8 groupCryptoLen;
-    u8 ssidLength;
-    u8     ssid[WMI_MAX_SSID_LEN];
-    u16 channel;
-    u8 bssid[ATH_MAC_LEN];
-    u32 ctrl_flags;
-} POSTPACK WMI_CONNECT_CMD;
-
-/*
- * WMI_RECONNECT_CMDID
- */
-typedef PREPACK struct {
-    u16 channel;                    /* hint */
-    u8 bssid[ATH_MAC_LEN];         /* mandatory if set */
-} POSTPACK WMI_RECONNECT_CMD;
-
-#define WMI_PMK_LEN     32
-typedef PREPACK struct {
-    u8 pmk[WMI_PMK_LEN];
-} POSTPACK WMI_SET_PMK_CMD;
-
-/*
- * WMI_SET_EXCESS_TX_RETRY_THRES_CMDID
- */
-typedef PREPACK struct {
-    u32 threshold;
-} POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD;
-
-/*
- * WMI_ADD_CIPHER_KEY_CMDID
- */
-typedef enum {
-    PAIRWISE_USAGE      = 0x00,
-    GROUP_USAGE         = 0x01,
-    TX_USAGE            = 0x02,     /* default Tx Key - Static WEP only */
-} KEY_USAGE;
-
-/*
- * Bit Flag
- * Bit 0 - Initialise TSC - default is Initialize
- */
-#define KEY_OP_INIT_TSC       0x01
-#define KEY_OP_INIT_RSC       0x02
-#ifdef WAPI_ENABLE
-#define KEY_OP_INIT_WAPIPN    0x10
-#endif /* WAPI_ENABLE */
-
-#define KEY_OP_INIT_VAL     0x03     /* Default Initialise the TSC & RSC */
-#define KEY_OP_VALID_MASK   0x03
-
-typedef PREPACK struct {
-    u8 keyIndex;
-    u8 keyType;
-    u8 keyUsage;           /* KEY_USAGE */
-    u8 keyLength;
-    u8 keyRSC[8];          /* key replay sequence counter */
-    u8 key[WMI_MAX_KEY_LEN];
-    u8 key_op_ctrl;       /* Additional Key Control information */
-    u8 key_macaddr[ATH_MAC_LEN];
-} POSTPACK WMI_ADD_CIPHER_KEY_CMD;
-
-/*
- * WMI_DELETE_CIPHER_KEY_CMDID
- */
-typedef PREPACK struct {
-    u8 keyIndex;
-} POSTPACK WMI_DELETE_CIPHER_KEY_CMD;
-
-#define WMI_KRK_LEN     16
-/*
- * WMI_ADD_KRK_CMDID
- */
-typedef PREPACK struct {
-    u8 krk[WMI_KRK_LEN];
-} POSTPACK WMI_ADD_KRK_CMD;
-
-/*
- * WMI_SET_TKIP_COUNTERMEASURES_CMDID
- */
-typedef enum {
-    WMI_TKIP_CM_DISABLE = 0x0,
-    WMI_TKIP_CM_ENABLE  = 0x1,
-} WMI_TKIP_CM_CONTROL;
-
-typedef PREPACK struct {
-    u8 cm_en;                     /* WMI_TKIP_CM_CONTROL */
-} POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD;
-
-/*
- * WMI_SET_PMKID_CMDID
- */
-
-#define WMI_PMKID_LEN 16
-
-typedef enum {
-   PMKID_DISABLE = 0,
-   PMKID_ENABLE  = 1,
-} PMKID_ENABLE_FLG;
-
-typedef PREPACK struct {
-    u8 bssid[ATH_MAC_LEN];
-    u8 enable;                 /* PMKID_ENABLE_FLG */
-    u8 pmkid[WMI_PMKID_LEN];
-} POSTPACK WMI_SET_PMKID_CMD;
-
-/*
- * WMI_START_SCAN_CMD
- */
-typedef enum {
-    WMI_LONG_SCAN  = 0,
-    WMI_SHORT_SCAN = 1,
-} WMI_SCAN_TYPE;
-
-typedef PREPACK struct {
-    u32   forceFgScan;
-    u32   isLegacy;        /* For Legacy Cisco AP compatibility */
-    u32 homeDwellTime;   /* Maximum duration in the home channel(milliseconds) */
-    u32 forceScanInterval;    /* Time interval between scans (milliseconds)*/
-    u8 scanType;           /* WMI_SCAN_TYPE */
-    u8 numChannels;            /* how many channels follow */
-    u16 channelList[1];         /* channels in Mhz */
-} POSTPACK WMI_START_SCAN_CMD;
-
-/*
- * WMI_SET_SCAN_PARAMS_CMDID
- */
-#define WMI_SHORTSCANRATIO_DEFAULT      3
-/* 
- *  Warning: ScanCtrlFlag value of 0xFF is used to disable all flags in WMI_SCAN_PARAMS_CMD 
- *  Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS
- */
-typedef enum {
-    CONNECT_SCAN_CTRL_FLAGS = 0x01,    /* set if can scan in the Connect cmd */
-    SCAN_CONNECTED_CTRL_FLAGS = 0x02,  /* set if scan for the SSID it is */
-                                       /* already connected to */
-    ACTIVE_SCAN_CTRL_FLAGS = 0x04,     /* set if enable active scan */
-    ROAM_SCAN_CTRL_FLAGS = 0x08,       /* set if enable roam scan when bmiss and lowrssi */
-    REPORT_BSSINFO_CTRL_FLAGS = 0x10,   /* set if follows customer BSSINFO reporting rule */
-    ENABLE_AUTO_CTRL_FLAGS = 0x20,      /* if disabled, target doesn't
-                                          scan after a disconnect event  */
-    ENABLE_SCAN_ABORT_EVENT = 0x40      /* Scan complete event with canceled status will be generated when a scan is prempted before it gets completed */
-} WMI_SCAN_CTRL_FLAGS_BITS;
-
-#define CAN_SCAN_IN_CONNECT(flags)      (flags & CONNECT_SCAN_CTRL_FLAGS)
-#define CAN_SCAN_CONNECTED(flags)       (flags & SCAN_CONNECTED_CTRL_FLAGS)
-#define ENABLE_ACTIVE_SCAN(flags)       (flags & ACTIVE_SCAN_CTRL_FLAGS)
-#define ENABLE_ROAM_SCAN(flags)         (flags & ROAM_SCAN_CTRL_FLAGS)
-#define CONFIG_REPORT_BSSINFO(flags)     (flags & REPORT_BSSINFO_CTRL_FLAGS)
-#define IS_AUTO_SCAN_ENABLED(flags)      (flags & ENABLE_AUTO_CTRL_FLAGS)
-#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT)
-
-#define DEFAULT_SCAN_CTRL_FLAGS         (CONNECT_SCAN_CTRL_FLAGS| SCAN_CONNECTED_CTRL_FLAGS| ACTIVE_SCAN_CTRL_FLAGS| ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS)
-
-
-typedef PREPACK struct {
-    u16 fg_start_period;        /* seconds */
-    u16 fg_end_period;          /* seconds */
-    u16 bg_period;              /* seconds */
-    u16 maxact_chdwell_time;    /* msec */
-    u16 pas_chdwell_time;       /* msec */
-    u8 shortScanRatio;         /* how many shorts scan for one long */
-    u8 scanCtrlFlags;
-    u16 minact_chdwell_time;    /* msec */
-    u16 maxact_scan_per_ssid;   /* max active scans per ssid */
-    u32 max_dfsch_act_time;  /* msecs */
-} POSTPACK WMI_SCAN_PARAMS_CMD;
-
-/*
- * WMI_SET_BSS_FILTER_CMDID
- */
-typedef enum {
-    NONE_BSS_FILTER = 0x0,              /* no beacons forwarded */
-    ALL_BSS_FILTER,                     /* all beacons forwarded */
-    PROFILE_FILTER,                     /* only beacons matching profile */
-    ALL_BUT_PROFILE_FILTER,             /* all but beacons matching profile */
-    CURRENT_BSS_FILTER,                 /* only beacons matching current BSS */
-    ALL_BUT_BSS_FILTER,                 /* all but beacons matching BSS */
-    PROBED_SSID_FILTER,                 /* beacons matching probed ssid */
-    LAST_BSS_FILTER,                    /* marker only */
-} WMI_BSS_FILTER;
-
-typedef PREPACK struct {
-    u8 bssFilter;                      /* see WMI_BSS_FILTER */
-    u8 reserved1;                      /* For alignment */
-    u16 reserved2;                      /* For alignment */
-    u32 ieMask;
-} POSTPACK WMI_BSS_FILTER_CMD;
-
-/*
- * WMI_SET_PROBED_SSID_CMDID
- */
-#define MAX_PROBED_SSID_INDEX   9
-
-typedef enum {
-    DISABLE_SSID_FLAG  = 0,                  /* disables entry */
-    SPECIFIC_SSID_FLAG = 0x01,               /* probes specified ssid */
-    ANY_SSID_FLAG      = 0x02,               /* probes for any ssid */
-} WMI_SSID_FLAG;
-
-typedef PREPACK struct {
-    u8 entryIndex;                     /* 0 to MAX_PROBED_SSID_INDEX */
-    u8 flag;                           /* WMI_SSID_FLG */
-    u8 ssidLength;
-    u8 ssid[32];
-} POSTPACK WMI_PROBED_SSID_CMD;
-
-/*
- * WMI_SET_LISTEN_INT_CMDID
- * The Listen interval is between 15 and 3000 TUs
- */
-#define MIN_LISTEN_INTERVAL 15
-#define MAX_LISTEN_INTERVAL 5000
-#define MIN_LISTEN_BEACONS 1
-#define MAX_LISTEN_BEACONS 50
-
-typedef PREPACK struct {
-    u16 listenInterval;
-    u16 numBeacons;
-} POSTPACK WMI_LISTEN_INT_CMD;
-
-/*
- * WMI_SET_BEACON_INT_CMDID
- */
-typedef PREPACK struct {
-    u16 beaconInterval;
-} POSTPACK WMI_BEACON_INT_CMD;
-
-/*
- * WMI_SET_BMISS_TIME_CMDID
- * valid values are between 1000 and 5000 TUs
- */
-
-#define MIN_BMISS_TIME     1000
-#define MAX_BMISS_TIME     5000
-#define MIN_BMISS_BEACONS  1
-#define MAX_BMISS_BEACONS  50
-
-typedef PREPACK struct {
-    u16 bmissTime;
-    u16 numBeacons;
-} POSTPACK WMI_BMISS_TIME_CMD;
-
-/*
- * WMI_SET_POWER_MODE_CMDID
- */
-typedef enum {
-    REC_POWER = 0x01,
-    MAX_PERF_POWER,
-} WMI_POWER_MODE;
-
-typedef PREPACK struct {
-    u8 powerMode;      /* WMI_POWER_MODE */
-} POSTPACK WMI_POWER_MODE_CMD;
-
-typedef PREPACK struct {
-    s8 status;      /* WMI_SET_PARAMS_REPLY */
-} POSTPACK WMI_SET_PARAMS_REPLY;
-
-typedef PREPACK struct {
-    u32 opcode;
-    u32 length;
-    char buffer[1];      /* WMI_SET_PARAMS */
-} POSTPACK WMI_SET_PARAMS_CMD;
-
-typedef PREPACK struct {
-    u8 multicast_mac[ATH_MAC_LEN];      /* WMI_SET_MCAST_FILTER */
-} POSTPACK WMI_SET_MCAST_FILTER_CMD;
-
-typedef PREPACK struct {
-    u8 enable;      /* WMI_MCAST_FILTER */
-} POSTPACK WMI_MCAST_FILTER_CMD;
-
-/*
- * WMI_SET_POWER_PARAMS_CMDID
- */
-typedef enum {
-    IGNORE_DTIM = 0x01,
-    NORMAL_DTIM = 0x02,
-    STICK_DTIM  = 0x03,
-    AUTO_DTIM   = 0x04,
-} WMI_DTIM_POLICY;
-
-/* Policy to determnine whether TX should wakeup WLAN if sleeping */
-typedef enum {
-    TX_WAKEUP_UPON_SLEEP = 1,
-    TX_DONT_WAKEUP_UPON_SLEEP = 2
-} WMI_TX_WAKEUP_POLICY_UPON_SLEEP;
-
-/*
- * Policy to determnine whether power save failure event should be sent to
- * host during scanning
- */
-typedef enum {
-    SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
-    IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
-} POWER_SAVE_FAIL_EVENT_POLICY;
-
-typedef PREPACK struct {
-    u16 idle_period;             /* msec */
-    u16 pspoll_number;
-    u16 dtim_policy;
-    u16 tx_wakeup_policy;
-    u16 num_tx_to_wakeup;
-    u16 ps_fail_event_policy;
-} POSTPACK WMI_POWER_PARAMS_CMD;
-
-/* Adhoc power save types */
-typedef enum {
-    ADHOC_PS_DISABLE=1,
-    ADHOC_PS_ATH=2,
-    ADHOC_PS_IEEE=3,
-    ADHOC_PS_OTHER=4,
-} WMI_ADHOC_PS_TYPE;
-
-typedef PREPACK struct {
-    u8 power_saving;
-    u8 ttl; /* number of beacon periods */
-    u16 atim_windows;          /* msec */
-    u16 timeout_value;         /* msec */
-} POSTPACK WMI_IBSS_PM_CAPS_CMD;
-
-/* AP power save types */
-typedef enum {
-    AP_PS_DISABLE=1,
-    AP_PS_ATH=2,
-} WMI_AP_PS_TYPE;
-
-typedef PREPACK struct {
-    u32 idle_time;   /* in msec */
-    u32 ps_period;   /* in usec */
-    u8 sleep_period; /* in ps periods */
-    u8 psType;
-} POSTPACK WMI_AP_PS_CMD;
-
-/*
- * WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID
- */
-typedef enum {
-    IGNORE_TIM_ALL_QUEUES_APSD = 0,
-    PROCESS_TIM_ALL_QUEUES_APSD = 1,
-    IGNORE_TIM_SIMULATED_APSD = 2,
-    PROCESS_TIM_SIMULATED_APSD = 3,
-} APSD_TIM_POLICY;
-
-typedef PREPACK struct {
-    u16 psPollTimeout;          /* msec */
-    u16 triggerTimeout;         /* msec */
-    u32 apsdTimPolicy;      /* TIM behavior with  ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */
-    u32 simulatedAPSDTimPolicy;      /* TIM behavior with  simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */
-} POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD;
-
-/*
- * WMI_SET_VOICE_PKT_SIZE_CMDID
- */
-typedef PREPACK struct {
-    u16 voicePktSize;
-} POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD;
-
-/*
- * WMI_SET_MAX_SP_LEN_CMDID
- */
-typedef enum {
-    DELIVER_ALL_PKT = 0x0,
-    DELIVER_2_PKT = 0x1,
-    DELIVER_4_PKT = 0x2,
-    DELIVER_6_PKT = 0x3,
-} APSD_SP_LEN_TYPE;
-
-typedef PREPACK struct {
-    u8 maxSPLen;
-} POSTPACK WMI_SET_MAX_SP_LEN_CMD;
-
-/*
- * WMI_SET_DISC_TIMEOUT_CMDID
- */
-typedef PREPACK struct {
-    u8 disconnectTimeout;          /* seconds */
-} POSTPACK WMI_DISC_TIMEOUT_CMD;
-
-typedef enum {
-    UPLINK_TRAFFIC = 0,
-    DNLINK_TRAFFIC = 1,
-    BIDIR_TRAFFIC = 2,
-} DIR_TYPE;
-
-typedef enum {
-    DISABLE_FOR_THIS_AC = 0,
-    ENABLE_FOR_THIS_AC  = 1,
-    ENABLE_FOR_ALL_AC   = 2,
-} VOICEPS_CAP_TYPE;
-
-typedef enum {
-    TRAFFIC_TYPE_APERIODIC = 0,
-    TRAFFIC_TYPE_PERIODIC = 1,
-}TRAFFIC_TYPE;
-
-/*
- * WMI_SYNCHRONIZE_CMDID
- */
-typedef PREPACK struct {
-    u8 dataSyncMap;
-} POSTPACK WMI_SYNC_CMD;
-
-/*
- * WMI_CREATE_PSTREAM_CMDID
- */
-typedef PREPACK struct {
-    u32 minServiceInt;           /* in milli-sec */
-    u32 maxServiceInt;           /* in milli-sec */
-    u32 inactivityInt;           /* in milli-sec */
-    u32 suspensionInt;           /* in milli-sec */
-    u32 serviceStartTime;
-    u32 minDataRate;             /* in bps */
-    u32 meanDataRate;            /* in bps */
-    u32 peakDataRate;            /* in bps */
-    u32 maxBurstSize;
-    u32 delayBound;
-    u32 minPhyRate;              /* in bps */
-    u32 sba;
-    u32 mediumTime;
-    u16 nominalMSDU;             /* in octects */
-    u16 maxMSDU;                 /* in octects */
-    u8 trafficClass;
-    u8 trafficDirection;        /* DIR_TYPE */
-    u8 rxQueueNum;
-    u8 trafficType;             /* TRAFFIC_TYPE */
-    u8 voicePSCapability;       /* VOICEPS_CAP_TYPE */
-    u8 tsid;
-    u8 userPriority;            /* 802.1D user priority */
-    u8 nominalPHY;              /* nominal phy rate */
-} POSTPACK WMI_CREATE_PSTREAM_CMD;
-
-/*
- * WMI_DELETE_PSTREAM_CMDID
- */
-typedef PREPACK struct {
-    u8 txQueueNumber;
-    u8 rxQueueNumber;
-    u8 trafficDirection;
-    u8 trafficClass;
-    u8 tsid;
-} POSTPACK WMI_DELETE_PSTREAM_CMD;
-
-/*
- * WMI_SET_CHANNEL_PARAMS_CMDID
- */
-typedef enum {
-    WMI_11A_MODE  = 0x1,
-    WMI_11G_MODE  = 0x2,
-    WMI_11AG_MODE = 0x3,
-    WMI_11B_MODE  = 0x4,
-    WMI_11GONLY_MODE = 0x5,    
-} WMI_PHY_MODE;
-
-#define WMI_MAX_CHANNELS        32
-
-typedef PREPACK struct {
-    u8 reserved1;
-    u8 scanParam;              /* set if enable scan */
-    u8 phyMode;                /* see WMI_PHY_MODE */
-    u8 numChannels;            /* how many channels follow */
-    u16 channelList[1];         /* channels in Mhz */
-} POSTPACK WMI_CHANNEL_PARAMS_CMD;
-
-
-/*
- *  WMI_RSSI_THRESHOLD_PARAMS_CMDID
- *  Setting the polltime to 0 would disable polling.
- *  Threshold values are in the ascending order, and should agree to:
- *  (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
- *      < highThreshold_upperVal)
- */
-
-typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{
-    u32 pollTime;               /* Polling time as a factor of LI */
-    s16 thresholdAbove1_Val;          /* lowest of upper */
-    s16 thresholdAbove2_Val;
-    s16 thresholdAbove3_Val;
-    s16 thresholdAbove4_Val;
-    s16 thresholdAbove5_Val;
-    s16 thresholdAbove6_Val;          /* highest of upper */
-    s16 thresholdBelow1_Val;         /* lowest of bellow */
-    s16 thresholdBelow2_Val;
-    s16 thresholdBelow3_Val;
-    s16 thresholdBelow4_Val;
-    s16 thresholdBelow5_Val;
-    s16 thresholdBelow6_Val;         /* highest of bellow */
-    u8 weight;                  /* "alpha" */
-    u8 reserved[3];
-} POSTPACK  WMI_RSSI_THRESHOLD_PARAMS_CMD;
-
-/*
- *  WMI_SNR_THRESHOLD_PARAMS_CMDID
- *  Setting the polltime to 0 would disable polling.
- */
-
-typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{
-    u32 pollTime;               /* Polling time as a factor of LI */
-    u8 weight;                  /* "alpha" */
-    u8 thresholdAbove1_Val;      /* lowest of uppper*/
-    u8 thresholdAbove2_Val;
-    u8 thresholdAbove3_Val;
-    u8 thresholdAbove4_Val;      /* highest of upper */
-    u8 thresholdBelow1_Val;     /* lowest of bellow */
-    u8 thresholdBelow2_Val;
-    u8 thresholdBelow3_Val;
-    u8 thresholdBelow4_Val;     /* highest of bellow */
-    u8 reserved[3];
-} POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD;
-
-/*
- *  WMI_LQ_THRESHOLD_PARAMS_CMDID
- */
-typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS {
-    u8 enable;
-    u8 thresholdAbove1_Val;
-    u8 thresholdAbove2_Val;
-    u8 thresholdAbove3_Val;
-    u8 thresholdAbove4_Val;
-    u8 thresholdBelow1_Val;
-    u8 thresholdBelow2_Val;
-    u8 thresholdBelow3_Val;
-    u8 thresholdBelow4_Val;
-    u8 reserved[3];
-} POSTPACK  WMI_LQ_THRESHOLD_PARAMS_CMD;
-
-typedef enum {
-    WMI_LPREAMBLE_DISABLED = 0,
-    WMI_LPREAMBLE_ENABLED
-} WMI_LPREAMBLE_STATUS;
-
-typedef enum {
-    WMI_IGNORE_BARKER_IN_ERP = 0,
-    WMI_DONOT_IGNORE_BARKER_IN_ERP
-} WMI_PREAMBLE_POLICY;
-
-typedef PREPACK struct {
-    u8 status;
-    u8 preamblePolicy;
-}POSTPACK WMI_SET_LPREAMBLE_CMD;
-
-typedef PREPACK struct {
-    u16 threshold;
-}POSTPACK WMI_SET_RTS_CMD;
-
-/*
- *  WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
- *  Sets the error reporting event bitmask in target. Target clears it
- *  upon an error. Subsequent errors are counted, but not reported
- *  via event, unless the bitmask is set again.
- */
-typedef PREPACK struct {
-    u32 bitmask;
-} POSTPACK  WMI_TARGET_ERROR_REPORT_BITMASK;
-
-/*
- * WMI_SET_TX_PWR_CMDID
- */
-typedef PREPACK struct {
-    u8 dbM;                  /* in dbM units */
-} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY;
-
-/*
- * WMI_SET_ASSOC_INFO_CMDID
- *
- * A maximum of 2 private IEs can be sent in the [Re]Assoc request.
- * A 3rd one, the CCX version IE can also be set from the host.
- */
-#define WMI_MAX_ASSOC_INFO_TYPE    2
-#define WMI_CCX_VER_IE             2 /* ieType to set CCX Version IE */
-
-#define WMI_MAX_ASSOC_INFO_LEN     240
-
-typedef PREPACK struct {
-    u8 ieType;
-    u8 bufferSize;
-    u8 assocInfo[1];       /* up to WMI_MAX_ASSOC_INFO_LEN */
-} POSTPACK WMI_SET_ASSOC_INFO_CMD;
-
-
-/*
- * WMI_GET_TX_PWR_CMDID does not take any parameters
- */
-
-/*
- * WMI_ADD_BAD_AP_CMDID
- */
-#define WMI_MAX_BAD_AP_INDEX      1
-
-typedef PREPACK struct {
-    u8 badApIndex;         /* 0 to WMI_MAX_BAD_AP_INDEX */
-    u8 bssid[ATH_MAC_LEN];
-} POSTPACK WMI_ADD_BAD_AP_CMD;
-
-/*
- * WMI_DELETE_BAD_AP_CMDID
- */
-typedef PREPACK struct {
-    u8 badApIndex;         /* 0 to WMI_MAX_BAD_AP_INDEX */
-} POSTPACK WMI_DELETE_BAD_AP_CMD;
-
-/*
- * WMI_SET_ACCESS_PARAMS_CMDID
- */
-#define WMI_DEFAULT_TXOP_ACPARAM    0       /* implies one MSDU */
-#define WMI_DEFAULT_ECWMIN_ACPARAM  4       /* corresponds to CWmin of 15 */
-#define WMI_DEFAULT_ECWMAX_ACPARAM  10      /* corresponds to CWmax of 1023 */
-#define WMI_MAX_CW_ACPARAM          15      /* maximum eCWmin or eCWmax */
-#define WMI_DEFAULT_AIFSN_ACPARAM   2
-#define WMI_MAX_AIFSN_ACPARAM       15
-typedef PREPACK struct {
-    u16 txop;                      /* in units of 32 usec */
-    u8 eCWmin;
-    u8 eCWmax;
-    u8 aifsn;
-    u8 ac;
-} POSTPACK WMI_SET_ACCESS_PARAMS_CMD;
-
-
-/*
- * WMI_SET_RETRY_LIMITS_CMDID
- *
- * This command is used to customize the number of retries the
- * wlan device will perform on a given frame.
- */
-#define WMI_MIN_RETRIES 2
-#define WMI_MAX_RETRIES 13
-typedef enum {
-    MGMT_FRAMETYPE    = 0,
-    CONTROL_FRAMETYPE = 1,
-    DATA_FRAMETYPE    = 2
-} WMI_FRAMETYPE;
-
-typedef PREPACK struct {
-    u8 frameType;                      /* WMI_FRAMETYPE */
-    u8 trafficClass;                   /* applies only to DATA_FRAMETYPE */
-    u8 maxRetries;
-    u8 enableNotify;
-} POSTPACK WMI_SET_RETRY_LIMITS_CMD;
-
-/*
- * WMI_SET_ROAM_CTRL_CMDID
- *
- * This command is used to influence the Roaming behaviour
- * Set the host biases of the BSSs before setting the roam mode as bias
- * based.
- */
-
-/*
- * Different types of Roam Control
- */
-
-typedef enum {
-        WMI_FORCE_ROAM          = 1,      /* Roam to the specified BSSID */
-        WMI_SET_ROAM_MODE       = 2,      /* default ,progd bias, no roam */
-        WMI_SET_HOST_BIAS       = 3,     /* Set the Host Bias */
-        WMI_SET_LOWRSSI_SCAN_PARAMS = 4, /* Set lowrssi Scan parameters */
-} WMI_ROAM_CTRL_TYPE;
-
-#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM
-#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_LOWRSSI_SCAN_PARAMS
-
-/*
- * ROAM MODES
- */
-
-typedef enum {
-        WMI_DEFAULT_ROAM_MODE   = 1,  /* RSSI based ROAM */
-        WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */
-        WMI_LOCK_BSS_MODE  = 3  /* Lock to the Current BSS - no Roam */
-} WMI_ROAM_MODE;
-
-/*
- * BSS HOST BIAS INFO
- */
-
-typedef PREPACK struct {
-        u8 bssid[ATH_MAC_LEN];
-        s8 bias;
-} POSTPACK WMI_BSS_BIAS;
-
-typedef PREPACK struct {
-        u8 numBss;
-        WMI_BSS_BIAS bssBias[1];
-} POSTPACK WMI_BSS_BIAS_INFO;
-
-typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS {
-        u16 lowrssi_scan_period;
-        s16 lowrssi_scan_threshold;
-        s16 lowrssi_roam_threshold;
-        u8 roam_rssi_floor;
-        u8 reserved[1];              /* For alignment */
-} POSTPACK WMI_LOWRSSI_SCAN_PARAMS;
-
-typedef PREPACK struct {
-    PREPACK union {
-        u8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */
-        u8 roamMode;           /* WMI_SET_ROAM_MODE  */
-        WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */
-        WMI_LOWRSSI_SCAN_PARAMS lrScanParams;
-    } POSTPACK info;
-    u8 roamCtrlType ;
-} POSTPACK WMI_SET_ROAM_CTRL_CMD;
-
-/*
- * WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID
- */
-typedef enum {
-    BT_WLAN_CONN_PRECDENCE_WLAN=0,  /* Default */
-    BT_WLAN_CONN_PRECDENCE_PAL,
-} BT_WLAN_CONN_PRECEDENCE;
-
-typedef PREPACK struct {
-    u8 precedence;
-} POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE;
-
-/*
- * WMI_ENABLE_RM_CMDID
- */
-typedef PREPACK struct {
-        u32 enable_radio_measurements;
-} POSTPACK WMI_ENABLE_RM_CMD;
-
-/*
- * WMI_SET_MAX_OFFHOME_DURATION_CMDID
- */
-typedef PREPACK struct {
-        u8 max_offhome_duration;
-} POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD;
-
-typedef PREPACK struct {
-    u32 frequency;
-    u8 threshold;
-} POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD;
-/*---------------------- BTCOEX RELATED -------------------------------------*/
-/*----------------------COMMON to AR6002 and AR6003 -------------------------*/
-typedef enum {
-    BT_STREAM_UNDEF = 0,
-    BT_STREAM_SCO,             /* SCO stream */
-    BT_STREAM_A2DP,            /* A2DP stream */
-    BT_STREAM_SCAN,            /* BT Discovery or Page */
-    BT_STREAM_ESCO,
-    BT_STREAM_MAX
-} BT_STREAM_TYPE;
-
-typedef enum {
-    BT_PARAM_SCO_PSPOLL_LATENCY_ONE_FOURTH =1,
-    BT_PARAM_SCO_PSPOLL_LATENCY_HALF,
-    BT_PARAM_SCO_PSPOLL_LATENCY_THREE_FOURTH,
-} BT_PARAMS_SCO_PSPOLL_LATENCY;
-
-typedef enum {
-    BT_PARAMS_SCO_STOMP_SCO_NEVER =1,
-    BT_PARAMS_SCO_STOMP_SCO_ALWAYS,
-    BT_PARAMS_SCO_STOMP_SCO_IN_LOWRSSI,
-} BT_PARAMS_SCO_STOMP_RULES;
-
-typedef enum {
-    BT_STATUS_UNDEF = 0,
-    BT_STATUS_ON,
-    BT_STATUS_OFF,
-    BT_STATUS_MAX
-} BT_STREAM_STATUS;
-
-typedef PREPACK struct {
-    u8 streamType;
-    u8 status;
-} POSTPACK WMI_SET_BT_STATUS_CMD;
-
-typedef enum {
-    BT_ANT_TYPE_UNDEF=0,
-    BT_ANT_TYPE_DUAL,
-    BT_ANT_TYPE_SPLITTER,
-    BT_ANT_TYPE_SWITCH,
-    BT_ANT_TYPE_HIGH_ISO_DUAL
-} BT_ANT_FRONTEND_CONFIG;
-
-typedef enum {
-    BT_COLOCATED_DEV_BTS4020=0,
-    BT_COLCATED_DEV_CSR ,
-    BT_COLOCATED_DEV_VALKYRIE
-} BT_COLOCATED_DEV_TYPE;
-
-/*********************** Applicable to AR6002 ONLY ******************************/
-
-typedef enum {
-    BT_PARAM_SCO = 1,         /* SCO stream parameters */
-    BT_PARAM_A2DP ,
-    BT_PARAM_ANTENNA_CONFIG,
-    BT_PARAM_COLOCATED_BT_DEVICE,
-    BT_PARAM_ACLCOEX,
-    BT_PARAM_11A_SEPARATE_ANT,
-    BT_PARAM_MAX
-} BT_PARAM_TYPE;
-
-
-#define BT_SCO_ALLOW_CLOSE_RANGE_OPT    (1 << 0)
-#define BT_SCO_FORCE_AWAKE_OPT          (1 << 1)
-#define BT_SCO_SET_RSSI_OVERRIDE(flags)        ((flags) |= (1 << 2))
-#define BT_SCO_GET_RSSI_OVERRIDE(flags)        (((flags) >> 2) & 0x1)
-#define BT_SCO_SET_RTS_OVERRIDE(flags)   ((flags) |= (1 << 3))
-#define BT_SCO_GET_RTS_OVERRIDE(flags)   (((flags) >> 3) & 0x1)
-#define BT_SCO_GET_MIN_LOW_RATE_CNT(flags)     (((flags) >> 8) & 0xFF)
-#define BT_SCO_GET_MAX_LOW_RATE_CNT(flags)     (((flags) >> 16) & 0xFF)
-#define BT_SCO_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
-#define BT_SCO_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
-
-typedef PREPACK struct {
-    u32 numScoCyclesForceTrigger;  /* Number SCO cycles after which
-                                           force a pspoll. default = 10 */
-    u32 dataResponseTimeout;       /* Timeout Waiting for Downlink pkt
-                                           in response for ps-poll,
-                                           default = 10 msecs */
-    u32 stompScoRules;
-    u32 scoOptFlags;               /* SCO Options Flags :
-                                            bits:     meaning:
-                                             0        Allow Close Range Optimization
-                                             1        Force awake during close range
-                                             2        If set use host supplied RSSI for OPT
-                                             3        If set use host supplied RTS COUNT for OPT
-                                             4..7     Unused
-                                             8..15    Low Data Rate Min Cnt
-                                             16..23   Low Data Rate Max Cnt
-                                        */
-
-    u8 stompDutyCyleVal;           /* Sco cycles to limit ps-poll queuing
-                                           if stomped */
-    u8 stompDutyCyleMaxVal;        /*firm ware increases stomp duty cycle
-                                          gradually uptill this value on need basis*/
-    u8 psPollLatencyFraction;      /* Fraction of idle
-                                           period, within which
-                                           additional ps-polls
-                                           can be queued */
-    u8 noSCOSlots;                 /* Number of SCO Tx/Rx slots.
-                                           HVx, EV3, 2EV3 = 2 */
-    u8 noIdleSlots;                /* Number of Bluetooth idle slots between
-                                           consecutive SCO Tx/Rx slots
-                                           HVx, EV3 = 4
-                                           2EV3 = 10 */
-    u8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/
-    u8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/
-    u8 scoOptRtsCount;
-} POSTPACK BT_PARAMS_SCO;
-
-#define BT_A2DP_ALLOW_CLOSE_RANGE_OPT  (1 << 0)
-#define BT_A2DP_FORCE_AWAKE_OPT        (1 << 1)
-#define BT_A2DP_SET_RSSI_OVERRIDE(flags)        ((flags) |= (1 << 2))
-#define BT_A2DP_GET_RSSI_OVERRIDE(flags)        (((flags) >> 2) & 0x1)
-#define BT_A2DP_SET_RTS_OVERRIDE(flags)   ((flags) |= (1 << 3))
-#define BT_A2DP_GET_RTS_OVERRIDE(flags)   (((flags) >> 3) & 0x1)
-#define BT_A2DP_GET_MIN_LOW_RATE_CNT(flags)     (((flags) >> 8) & 0xFF)
-#define BT_A2DP_GET_MAX_LOW_RATE_CNT(flags)     (((flags) >> 16) & 0xFF)
-#define BT_A2DP_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
-#define BT_A2DP_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
-
-typedef PREPACK struct {
-    u32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for
-                                    wlan, after it identifies the idle time
-                                    default (30 msecs) */
-    u32 a2dpBurstCntMin;   /* Minimum number of bluetooth data frames
-                                   to replenish Wlan Usage  limit (default 3) */
-    u32 a2dpDataRespTimeout;
-    u32 a2dpOptFlags;      /* A2DP Option flags:
-                                       bits:    meaning:
-                                        0       Allow Close Range Optimization
-                                        1       Force awake during close range
-                                        2        If set use host supplied RSSI for OPT
-                                        3        If set use host supplied RTS COUNT for OPT
-                                        4..7    Unused
-                                        8..15   Low Data Rate Min Cnt
-                                        16..23  Low Data Rate Max Cnt
-                                 */
-    u8 isCoLocatedBtRoleMaster;
-    u8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/
-    u8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/
-    u8 a2dpOptRtsCount;
-}POSTPACK BT_PARAMS_A2DP;
-
-/* During BT ftp/ BT OPP or any another data based acl profile on bluetooth
-   (non a2dp).*/
-typedef PREPACK struct {
-    u32 aclWlanMediumUsageTime;  /* Wlan usage time during Acl (non-a2dp)
-                                       coexistence (default 30 msecs) */
-    u32 aclBtMediumUsageTime;   /* Bt usage time during acl coexistence
-                                       (default 30 msecs)*/
-    u32 aclDataRespTimeout;
-    u32 aclDetectTimeout;      /* ACL coexistence enabled if we get
-                                       10 Pkts in X msec(default 100 msecs) */
-    u32 aclmaxPktCnt;          /* No of ACL pkts to receive before
-                                         enabling ACL coex */
-
-}POSTPACK BT_PARAMS_ACLCOEX;
-
-typedef PREPACK struct {
-    PREPACK union {
-        BT_PARAMS_SCO scoParams;
-        BT_PARAMS_A2DP a2dpParams;
-        BT_PARAMS_ACLCOEX  aclCoexParams;
-        u8 antType;         /* 0 -Disabled (default)
-                                     1 - BT_ANT_TYPE_DUAL
-                                     2 - BT_ANT_TYPE_SPLITTER
-                                     3 - BT_ANT_TYPE_SWITCH */
-        u8 coLocatedBtDev;  /* 0 - BT_COLOCATED_DEV_BTS4020 (default)
-                                     1 - BT_COLCATED_DEV_CSR
-                                     2 - BT_COLOCATED_DEV_VALKYRIe
-                                   */
-    } POSTPACK info;
-    u8 paramType ;
-} POSTPACK WMI_SET_BT_PARAMS_CMD;
-
-/************************ END AR6002 BTCOEX *******************************/
-/*-----------------------AR6003 BTCOEX -----------------------------------*/
-
-/*  ---------------WMI_SET_BTCOEX_FE_ANT_CMDID --------------------------*/
-/* Indicates front end antenna configuration. This command needs to be issued
- * right after initialization and after WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID.
- * AR6003 enables coexistence and antenna switching based on the configuration.
- */
-typedef enum {
-    WMI_BTCOEX_NOT_ENABLED = 0,
-    WMI_BTCOEX_FE_ANT_SINGLE =1,
-    WMI_BTCOEX_FE_ANT_DUAL=2,
-    WMI_BTCOEX_FE_ANT_DUAL_HIGH_ISO=3,
-    WMI_BTCOEX_FE_ANT_TYPE_MAX
-}WMI_BTCOEX_FE_ANT_TYPE;
-
-typedef PREPACK struct {
-       u8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end
-                                2 - WMI_BTCOEX_FE_ANT_DUAL for dual antenna front end
-                                    (for isolations less 35dB, for higher isolation there
-                                    is not need to pass this command).
-                                    (not implemented)
-                              */
-}POSTPACK WMI_SET_BTCOEX_FE_ANT_CMD;
-
-/* -------------WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID ----------------*/
-/* Indicate the bluetooth chip to the firmware. Firmware can have different algorithm based
- * bluetooth chip type.Based on bluetooth device, different coexistence protocol would be used.
- */
-typedef PREPACK struct {
-       u8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA)
-                                    2 - CSR BT  (3 wire PTA)
-                                    3 - Atheros 3001 BT (3 wire PTA)
-                                    4 - STE bluetooth (4-wire ePTA)
-                                    5 - Atheros 3002 BT (4-wire MCI)
-                                    defaults= 3 (Atheros 3001 BT )
-                                    */
-}POSTPACK WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD;
-
-/* -------------WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID ------------*/
-/* Configuration parameters during bluetooth inquiry and page. Page configuration
- * is applicable only on interfaces which can distinguish page (applicable only for ePTA -
- * STE bluetooth).
- * Bluetooth inquiry start and end is indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID.
- * During this the station will be  power-save mode.
- */
-typedef PREPACK struct {
-       u32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data
-                                            (via pspoll) is configured by this parameter.
-                                            "default = 10 ms" */
-
-       u32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state
-                                             for configured duration, after inquiry completion
-                                             . This is to ensure other bluetooth transactions
-                                             (RDP, SDP profiles, link key exchange ...etc)
-                                             goes through smoothly without wifi stomping.
-                                             default = 10 secs*/
-
-       u32 maxpageStomp;                 /*Applicable only for STE-BT interface. Currently not
-                                             used */
-       u32 btInquiryPageFlag;           /* Not used */
-}POSTPACK WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD;
-
-/*---------------------WMI_SET_BTCOEX_SCO_CONFIG_CMDID ---------------*/
-/* Configure  SCO parameters. These parameters would be used whenever firmware is indicated
- * of (e)SCO profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
- * Configration of BTCOEX_SCO_CONFIG data structure are common configuration and applies
- * ps-poll mode and opt mode.
- * Ps-poll Mode - Station is in power-save and retrieves downlink data between sco gaps.
- * Opt Mode - station is in awake state and access point can send data to station any time.
- * BTCOEX_PSPOLLMODE_SCO_CONFIG - Configuration applied only during ps-poll mode.
- * BTCOEX_OPTMODE_SCO_CONFIG - Configuration applied only during opt mode.
- */
-#define WMI_SCO_CONFIG_FLAG_ALLOW_OPTIMIZATION   (1 << 0)
-#define WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE       (1 << 1)
-#define WMI_SCO_CONFIG_FLAG_IS_BT_MASTER         (1 << 2)
-#define WMI_SCO_CONFIG_FLAG_FW_DETECT_OF_PER     (1 << 3)
-typedef PREPACK struct {
-       u32 scoSlots;                                   /* Number of SCO Tx/Rx slots.
-                                                                                  HVx, EV3, 2EV3 = 2 */
-       u32 scoIdleSlots;                               /* Number of Bluetooth idle slots between
-                                                                                  consecutive SCO Tx/Rx slots
-                                                                                  HVx, EV3 = 4
-                                                                                  2EV3 = 10
-                                         */
-       u32 scoFlags;                              /* SCO Options Flags :
-                                                                                 bits:    meaning:
-                                                                                 0   Allow Close Range Optimization
-                                                                                 1   Is EDR capable or Not
-                                                                                 2   IS Co-located Bt role Master
-                                          3   Firmware determines the periodicity of SCO.
-                                                                                */
-
-    u32 linkId;                      /* applicable to STE-BT - not used */
-}POSTPACK BTCOEX_SCO_CONFIG;
-
-typedef PREPACK struct {
-       u32 scoCyclesForceTrigger;      /* Number SCO cycles after which
-                                                                                       force a pspoll. default = 10 */
-    u32 scoDataResponseTimeout;         /* Timeout Waiting for Downlink pkt
-                                                                                       in response for ps-poll,
-                                                                                       default = 20 msecs */
-
-       u32 scoStompDutyCyleVal;                 /* not implemented */
-
-       u32 scoStompDutyCyleMaxVal;     /*Not implemented */
-
-       u32 scoPsPollLatencyFraction;    /* Fraction of idle
-                                                                                       period, within which
-                                                                                       additional ps-polls can be queued
-                                            1 - 1/4 of idle duration
-                                            2 - 1/2 of idle duration
-                                            3 - 3/4 of idle duration
-                                            default =2 (1/2)
-                                           */
-}POSTPACK BTCOEX_PSPOLLMODE_SCO_CONFIG;
-
-typedef PREPACK struct {
-       u32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in
-                                   opt mode. If exceeds the configured value,
-                                   switch to ps-poll mode
-                                  default = 3 */
-
-       u32 scoContStompMax;   /* max number of continuous stomp allowed in opt mode.
-                                   if exceeded switch to pspoll mode
-                                    default = 3 */
-
-       u32 scoMinlowRateMbps; /* Low rate threshold */
-
-       u32 scoLowRateCnt;     /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms.
-                                   If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
-                                   default = 36
-                                 */
-
-       u32 scoHighPktRatio;   /*(Total Rx pkts in 100 ms + 1)/
-                                  ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
-                                  if exceeded switch/stay in opt mode and if lower switch/stay in  pspoll mode.
-                                  default = 5 (80% of high rates)
-                                 */
-
-       u32 scoMaxAggrSize;    /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
-                                   max number of aggregates if it was negogiated to higher value
-                                   default = 1
-                                   Recommended value Basic rate headsets = 1, EDR (2-EV3)  =4.
-                                 */
-}POSTPACK BTCOEX_OPTMODE_SCO_CONFIG;
-
-typedef PREPACK struct {
-    u32 scanInterval;
-    u32 maxScanStompCnt;
-}POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG;
-
-typedef PREPACK struct {
-       BTCOEX_SCO_CONFIG scoConfig;
-       BTCOEX_PSPOLLMODE_SCO_CONFIG scoPspollConfig;
-       BTCOEX_OPTMODE_SCO_CONFIG scoOptModeConfig;
-       BTCOEX_WLANSCAN_SCO_CONFIG scoWlanScanConfig;
-}POSTPACK WMI_SET_BTCOEX_SCO_CONFIG_CMD;
-
-/* ------------------WMI_SET_BTCOEX_A2DP_CONFIG_CMDID -------------------*/
-/* Configure A2DP profile parameters. These parameters would be used whenver firmware is indicated
- * of A2DP profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
- * Configuration of BTCOEX_A2DP_CONFIG data structure are common configuration and applies to
- * ps-poll mode and opt mode.
- * Ps-poll Mode - Station is in power-save and retrieves downlink data between a2dp data bursts.
- * Opt Mode - station is in power save during a2dp bursts and awake in the gaps.
- * BTCOEX_PSPOLLMODE_A2DP_CONFIG - Configuration applied only during ps-poll mode.
- * BTCOEX_OPTMODE_A2DP_CONFIG - Configuration applied only during opt mode.
- */
-
-#define WMI_A2DP_CONFIG_FLAG_ALLOW_OPTIMIZATION    (1 << 0)
-#define WMI_A2DP_CONFIG_FLAG_IS_EDR_CAPABLE        (1 << 1)
-#define WMI_A2DP_CONFIG_FLAG_IS_BT_ROLE_MASTER     (1 << 2)
-#define WMI_A2DP_CONFIG_FLAG_IS_A2DP_HIGH_PRI      (1 << 3)
-#define WMI_A2DP_CONFIG_FLAG_FIND_BT_ROLE          (1 << 4)
-
-typedef PREPACK struct {
-    u32 a2dpFlags;      /* A2DP Option flags:
-                                       bits:    meaning:
-                                           0       Allow Close Range Optimization
-                                       1       IS EDR capable
-                                       2       IS Co-located Bt role Master
-                                3       a2dp traffic is high priority
-                                4       Fw detect the role of bluetooth.
-                             */
-       u32 linkId;         /* Applicable only to STE-BT - not used */
-
-}POSTPACK BTCOEX_A2DP_CONFIG;
-
-typedef PREPACK struct {
-    u32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for
-                                       wlan, after it identifies the idle time
-                                default (30 msecs) */
-
-    u32 a2dpMinBurstCnt;   /* Minimum number of bluetooth data frames
-                                               to replenish Wlan Usage  limit (default 3) */
-
-    u32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink
-                                     by stomping on  bluetooth
-                                     after ps-poll is acknowledged.
-                                     default = 20 ms
-                                   */
-}POSTPACK BTCOEX_PSPOLLMODE_A2DP_CONFIG;
-
-typedef PREPACK struct {
-       u32 a2dpMinlowRateMbps;  /* Low rate threshold */
-
-       u32 a2dpLowRateCnt;    /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms.
-                                   If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
-                                   default = 36
-                                 */
-
-       u32 a2dpHighPktRatio;   /*(Total Rx pkts in 100 ms + 1)/
-                                  ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
-                                  if exceeded switch/stay in opt mode and if lower switch/stay in  pspoll mode.
-                                  default = 5 (80% of high rates)
-                                 */
-
-       u32 a2dpMaxAggrSize;    /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
-                                   max number of aggregates if it was negogiated to higher value
-                                   default = 1
-                                  Recommended value Basic rate headsets = 1, EDR (2-EV3)  =8.
-                                 */
-       u32 a2dpPktStompCnt;    /*number of a2dp pkts that can be stomped per burst.
-                                   default = 6*/
-
-}POSTPACK BTCOEX_OPTMODE_A2DP_CONFIG;
-
-typedef PREPACK struct {
-       BTCOEX_A2DP_CONFIG a2dpConfig;
-       BTCOEX_PSPOLLMODE_A2DP_CONFIG a2dppspollConfig;
-       BTCOEX_OPTMODE_A2DP_CONFIG a2dpOptConfig;
-}POSTPACK WMI_SET_BTCOEX_A2DP_CONFIG_CMD;
-
-/*------------ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID---------------------*/
-/* Configure non-A2dp ACL profile parameters.The starts of ACL profile can either be
- * indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID orenabled via firmware detection
- *  which is configured via "aclCoexFlags".
- * Configration of BTCOEX_ACLCOEX_CONFIG data structure are common configuration and applies
- * ps-poll mode and opt mode.
- * Ps-poll Mode - Station is in power-save and retrieves downlink data during wlan medium.
- * Opt Mode - station is in power save during bluetooth medium time and awake during wlan duration.
- *             (Not implemented yet)
- *
- * BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG - Configuration applied only during ps-poll mode.
- * BTCOEX_OPTMODE_ACLCOEX_CONFIG - Configuration applied only during opt mode.
- */
-
-#define WMI_ACLCOEX_FLAGS_ALLOW_OPTIMIZATION   (1 << 0)
-#define WMI_ACLCOEX_FLAGS_DISABLE_FW_DETECTION (1 << 1)
-
-typedef PREPACK struct {
-    u32 aclWlanMediumDur;          /* Wlan usage time during Acl (non-a2dp)
-                                                       coexistence (default 30 msecs)
-                                    */
-
-    u32 aclBtMediumDur;           /* Bt usage time during acl coexistence
-                                                            (default 30 msecs)
-                                   */
-
-       u32 aclDetectTimeout;      /* BT activity observation time limit.
-                                                                         In this time duration, number of bt pkts are counted.
-                                                                         If the Cnt reaches "aclPktCntLowerLimit" value
-                                                                         for "aclIterToEnableCoex" iteration continuously,
-                                                                         firmware gets into ACL coexistence mode.
-                                                                         Similarly, if bt traffic count during ACL coexistence
-                                                                         has not reached "aclPktCntLowerLimit" continuously
-                                                                         for "aclIterToEnableCoex", then ACL coexistence is
-                                                                         disabled.
-                                                                 -default 100 msecs
-                                    */
-
-        u32 aclPktCntLowerLimit;   /* Acl Pkt Cnt to be received in duration of
-                                                                               "aclDetectTimeout" for
-                                                                               "aclIterForEnDis" times to enabling ACL coex.
-                                        Similar logic is used to disable acl coexistence.
-                                        (If "aclPktCntLowerLimit"  cnt of acl pkts
-                                         are not seen by the for "aclIterForEnDis"
-                                         then acl coexistence is disabled).
-                                        default = 10
-                                   */
-
-        u32 aclIterForEnDis;      /* number of Iteration of "aclPktCntLowerLimit" for Enabling and
-                                       Disabling Acl Coexistence.
-                                       default = 3
-                                     */
-
-        u32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than
-                                                                         "aclPktCntUpperLimit" seen in "aclDetectTimeout",
-                                                                         ACL coexistence is enabled right away.
-                                                                         - default 15*/
-
-       u32 aclCoexFlags;                       /* A2DP Option flags:
-                                                 bits:    meaning:
-                                                 0       Allow Close Range Optimization
-                                         1       disable Firmware detection
-                                      (Currently supported configuration is aclCoexFlags =0)
-                                               */
-       u32 linkId;                /* Applicable only for STE-BT - not used */
-
-}POSTPACK BTCOEX_ACLCOEX_CONFIG;
-
-typedef PREPACK struct {
-    u32 aclDataRespTimeout;   /* Max duration firmware waits for downlink
-                                      by stomping on  bluetooth
-                                      after ps-poll is acknowledged.
-                                     default = 20 ms */
-
-}POSTPACK BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG;
-
-
-/* Not implemented yet*/
-typedef PREPACK struct {
-       u32 aclCoexMinlowRateMbps;
-       u32 aclCoexLowRateCnt;
-       u32 aclCoexHighPktRatio;
-       u32 aclCoexMaxAggrSize;
-       u32 aclPktStompCnt;
-}POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG;
-
-typedef PREPACK struct {
-       BTCOEX_ACLCOEX_CONFIG aclCoexConfig;
-       BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG aclCoexPspollConfig;
-       BTCOEX_OPTMODE_ACLCOEX_CONFIG aclCoexOptConfig;
-}POSTPACK WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD;
-
-/* -----------WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ------------------*/
-typedef enum {
-       WMI_BTCOEX_BT_PROFILE_SCO =1,
-       WMI_BTCOEX_BT_PROFILE_A2DP,
-       WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE,
-       WMI_BTCOEX_BT_PROFILE_ACLCOEX,
-}WMI_BTCOEX_BT_PROFILE;
-
-typedef PREPACK struct {
-       u32 btProfileType;
-       u32 btOperatingStatus;
-       u32 btLinkId;
-}WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD;
-
-/*--------------------- WMI_SET_BTCOEX_DEBUG_CMDID ---------------------*/
-/* Used for firmware development and debugging */
-typedef PREPACK struct {
-       u32 btcoexDbgParam1;
-       u32 btcoexDbgParam2;
-       u32 btcoexDbgParam3;
-       u32 btcoexDbgParam4;
-       u32 btcoexDbgParam5;
-}WMI_SET_BTCOEX_DEBUG_CMD;
-
-/*---------------------WMI_GET_BTCOEX_CONFIG_CMDID --------------------- */
-/* Command to firmware to get configuration parameters of the bt profile
- * reported via WMI_BTCOEX_CONFIG_EVENTID */
-typedef PREPACK struct {
-       u32 btProfileType; /* 1 - SCO
-                               2 - A2DP
-                               3 - INQUIRY_PAGE
-                               4 - ACLCOEX
-                            */
-       u32 linkId;    /* not used */
-}WMI_GET_BTCOEX_CONFIG_CMD;
-
-/*------------------WMI_REPORT_BTCOEX_CONFIG_EVENTID------------------- */
-/* Event from firmware to host, sent in response to WMI_GET_BTCOEX_CONFIG_CMDID
- * */
-typedef PREPACK struct {
-       u32 btProfileType;
-       u32 linkId; /* not used */
-       PREPACK union {
-               WMI_SET_BTCOEX_SCO_CONFIG_CMD scoConfigCmd;
-               WMI_SET_BTCOEX_A2DP_CONFIG_CMD a2dpConfigCmd;
-               WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD aclcoexConfig;
-        WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD btinquiryPageConfigCmd;
-    } POSTPACK info;
-} POSTPACK WMI_BTCOEX_CONFIG_EVENT;
-
-/*------------- WMI_REPORT_BTCOEX_BTCOEX_STATS_EVENTID--------------------*/
-/* Used for firmware development and debugging*/
-typedef PREPACK struct {
-       u32 highRatePktCnt;
-       u32 firstBmissCnt;
-       u32 psPollFailureCnt;
-       u32 nullFrameFailureCnt;
-       u32 optModeTransitionCnt;
-}BTCOEX_GENERAL_STATS;
-
-typedef PREPACK struct {
-       u32 scoStompCntAvg;
-       u32 scoStompIn100ms;
-       u32 scoMaxContStomp;
-       u32 scoAvgNoRetries;
-       u32 scoMaxNoRetriesIn100ms;
-}BTCOEX_SCO_STATS;
-
-typedef PREPACK struct {
-       u32 a2dpBurstCnt;
-       u32 a2dpMaxBurstCnt;
-       u32 a2dpAvgIdletimeIn100ms;
-       u32 a2dpAvgStompCnt;
-}BTCOEX_A2DP_STATS;
-
-typedef PREPACK struct {
-       u32 aclPktCntInBtTime;
-       u32 aclStompCntInWlanTime;
-       u32 aclPktCntIn100ms;
-}BTCOEX_ACLCOEX_STATS;
-
-typedef PREPACK struct {
-       BTCOEX_GENERAL_STATS coexStats;
-       BTCOEX_SCO_STATS scoStats;
-       BTCOEX_A2DP_STATS a2dpStats;
-       BTCOEX_ACLCOEX_STATS aclCoexStats;
-}WMI_BTCOEX_STATS_EVENT;
-
-
-/*--------------------------END OF BTCOEX -------------------------------------*/
-typedef PREPACK struct {
-    u32 sleepState;
-}WMI_REPORT_SLEEP_STATE_EVENT;
-
-typedef enum {
-    WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP =0,
-    WMI_REPORT_SLEEP_STATUS_IS_AWAKE
-} WMI_REPORT_SLEEP_STATUS;
-typedef enum {
-    DISCONN_EVT_IN_RECONN = 0,  /* default */
-    NO_DISCONN_EVT_IN_RECONN
-} TARGET_EVENT_REPORT_CONFIG;
-
-typedef PREPACK struct {
-    u32 evtConfig;
-} POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD;
-
-
-typedef PREPACK struct {
-    u16 cmd_buf_sz;     /* HCI cmd buffer size */
-    u8 buf[1];         /* Absolute HCI cmd */
-} POSTPACK WMI_HCI_CMD;
-
-/*
- * Command Replies
- */
-
-/*
- * WMI_GET_CHANNEL_LIST_CMDID reply
- */
-typedef PREPACK struct {
-    u8 reserved1;
-    u8 numChannels;            /* number of channels in reply */
-    u16 channelList[1];         /* channel in Mhz */
-} POSTPACK WMI_CHANNEL_LIST_REPLY;
-
-typedef enum {
-    A_SUCCEEDED = 0,
-    A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250,
-    A_SUCCEEDED_MODIFY_STREAM=251,
-    A_FAILED_INVALID_STREAM = 252,
-    A_FAILED_MAX_THINSTREAMS = 253,
-    A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254,
-} PSTREAM_REPLY_STATUS;
-
-typedef PREPACK struct {
-    u8 status;                 /* PSTREAM_REPLY_STATUS */
-    u8 txQueueNumber;
-    u8 rxQueueNumber;
-    u8 trafficClass;
-    u8 trafficDirection;       /* DIR_TYPE */
-} POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY;
-
-typedef PREPACK struct {
-    u8 status;                 /* PSTREAM_REPLY_STATUS */
-    u8 txQueueNumber;
-    u8 rxQueueNumber;
-    u8 trafficDirection;       /* DIR_TYPE */
-    u8 trafficClass;
-} POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY;
-
-/*
- * List of Events (target to host)
- */
-typedef enum {
-    WMI_READY_EVENTID           = 0x1001,
-    WMI_CONNECT_EVENTID,
-    WMI_DISCONNECT_EVENTID,
-    WMI_BSSINFO_EVENTID,
-    WMI_CMDERROR_EVENTID,
-    WMI_REGDOMAIN_EVENTID,
-    WMI_PSTREAM_TIMEOUT_EVENTID,
-    WMI_NEIGHBOR_REPORT_EVENTID,
-    WMI_TKIP_MICERR_EVENTID,
-    WMI_SCAN_COMPLETE_EVENTID,           /* 0x100a */
-    WMI_REPORT_STATISTICS_EVENTID,
-    WMI_RSSI_THRESHOLD_EVENTID,
-    WMI_ERROR_REPORT_EVENTID,
-    WMI_OPT_RX_FRAME_EVENTID,
-    WMI_REPORT_ROAM_TBL_EVENTID,
-    WMI_EXTENSION_EVENTID,
-    WMI_CAC_EVENTID,
-    WMI_SNR_THRESHOLD_EVENTID,
-    WMI_LQ_THRESHOLD_EVENTID,
-    WMI_TX_RETRY_ERR_EVENTID,            /* 0x1014 */
-    WMI_REPORT_ROAM_DATA_EVENTID,
-    WMI_TEST_EVENTID,
-    WMI_APLIST_EVENTID,
-    WMI_GET_WOW_LIST_EVENTID,
-    WMI_GET_PMKID_LIST_EVENTID,
-    WMI_CHANNEL_CHANGE_EVENTID,
-    WMI_PEER_NODE_EVENTID,
-    WMI_PSPOLL_EVENTID,
-    WMI_DTIMEXPIRY_EVENTID,
-    WMI_WLAN_VERSION_EVENTID,
-    WMI_SET_PARAMS_REPLY_EVENTID,
-    WMI_ADDBA_REQ_EVENTID,              /*0x1020 */
-    WMI_ADDBA_RESP_EVENTID,
-    WMI_DELBA_REQ_EVENTID,
-    WMI_TX_COMPLETE_EVENTID,
-    WMI_HCI_EVENT_EVENTID,
-    WMI_ACL_DATA_EVENTID,
-    WMI_REPORT_SLEEP_STATE_EVENTID,
-#ifdef WAPI_ENABLE
-    WMI_WAPI_REKEY_EVENTID,
-#endif
-    WMI_REPORT_BTCOEX_STATS_EVENTID,
-    WMI_REPORT_BTCOEX_CONFIG_EVENTID,
-       WMI_GET_PMK_EVENTID,
-
-       /* DFS Events */
-       WMI_DFS_HOST_ATTACH_EVENTID,
-       WMI_DFS_HOST_INIT_EVENTID,
-       WMI_DFS_RESET_DELAYLINES_EVENTID,
-       WMI_DFS_RESET_RADARQ_EVENTID,
-       WMI_DFS_RESET_AR_EVENTID,
-       WMI_DFS_RESET_ARQ_EVENTID,
-       WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
-       WMI_DFS_SET_BANGRADAR_EVENTID,
-       WMI_DFS_SET_DEBUGLEVEL_EVENTID,
-       WMI_DFS_PHYERR_EVENTID,
-       /* CCX Evants */
-       WMI_CCX_RM_STATUS_EVENTID,
-
-       /* P2P Events */
-       WMI_P2P_GO_NEG_RESULT_EVENTID,
-
-       WMI_WAC_SCAN_DONE_EVENTID,
-       WMI_WAC_REPORT_BSS_EVENTID,
-       WMI_WAC_START_WPS_EVENTID,
-       WMI_WAC_CTRL_REQ_REPLY_EVENTID,
-
-       /* RFKILL Events */
-       WMI_RFKILL_STATE_CHANGE_EVENTID,
-       WMI_RFKILL_GET_MODE_CMD_EVENTID,
-       WMI_THIN_RESERVED_START_EVENTID = 0x8000,
-
-       /*
-        * Events in this range are reserved for thinmode
-        * See wmi_thin.h for actual definitions
-        */
-       WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
-
-       WMI_SET_CHANNEL_EVENTID,
-       WMI_ASSOC_REQ_EVENTID,
-
-       /* generic ACS event */
-       WMI_ACS_EVENTID,
-       WMI_REPORT_WMM_PARAMS_EVENTID
-} WMI_EVENT_ID;
-
-
-typedef enum {
-    WMI_11A_CAPABILITY   = 1,
-    WMI_11G_CAPABILITY   = 2,
-    WMI_11AG_CAPABILITY  = 3,
-    WMI_11NA_CAPABILITY  = 4,
-    WMI_11NG_CAPABILITY  = 5,
-    WMI_11NAG_CAPABILITY = 6,
-    // END CAPABILITY
-    WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY),
-} WMI_PHY_CAPABILITY;
-
-typedef PREPACK struct {
-    u8 macaddr[ATH_MAC_LEN];
-    u8 phyCapability;              /* WMI_PHY_CAPABILITY */
-} POSTPACK WMI_READY_EVENT_1;
-
-typedef PREPACK struct {
-    u32 sw_version;
-    u32 abi_version;
-    u8 macaddr[ATH_MAC_LEN];
-    u8 phyCapability;              /* WMI_PHY_CAPABILITY */
-} POSTPACK WMI_READY_EVENT_2;
-
-#if defined(ATH_TARGET)
-#ifdef AR6002_REV2
-#define WMI_READY_EVENT WMI_READY_EVENT_1  /* AR6002_REV2 target code */
-#else
-#define WMI_READY_EVENT WMI_READY_EVENT_2  /* AR6001, AR6002_REV4, AR6002_REV5 */
-#endif
-#else
-#define WMI_READY_EVENT WMI_READY_EVENT_2 /* host code */
-#endif
-
-
-/*
- * Connect Event
- */
-typedef PREPACK struct {
-    u16 channel;
-    u8 bssid[ATH_MAC_LEN];
-    u16 listenInterval;
-    u16 beaconInterval;
-    u32 networkType;
-    u8 beaconIeLen;
-    u8 assocReqLen;
-    u8 assocRespLen;
-    u8 assocInfo[1];
-} POSTPACK WMI_CONNECT_EVENT;
-
-/*
- * Disconnect Event
- */
-typedef enum {
-    NO_NETWORK_AVAIL   = 0x01,
-    LOST_LINK          = 0x02,     /* bmiss */
-    DISCONNECT_CMD     = 0x03,
-    BSS_DISCONNECTED   = 0x04,
-    AUTH_FAILED        = 0x05,
-    ASSOC_FAILED       = 0x06,
-    NO_RESOURCES_AVAIL = 0x07,
-    CSERV_DISCONNECT   = 0x08,
-    INVALID_PROFILE    = 0x0a,
-    DOT11H_CHANNEL_SWITCH = 0x0b,
-    PROFILE_MISMATCH   = 0x0c,
-    CONNECTION_EVICTED = 0x0d,
-    IBSS_MERGE         = 0xe,
-} WMI_DISCONNECT_REASON;
-
-typedef PREPACK struct {
-    u16 protocolReasonStatus;  /* reason code, see 802.11 spec. */
-    u8 bssid[ATH_MAC_LEN];    /* set if known */
-    u8 disconnectReason ;      /* see WMI_DISCONNECT_REASON */
-    u8 assocRespLen;
-    u8 assocInfo[1];
-} POSTPACK WMI_DISCONNECT_EVENT;
-
-/*
- * BSS Info Event.
- * Mechanism used to inform host of the presence and characteristic of
- * wireless networks present.  Consists of bss info header followed by
- * the beacon or probe-response frame body.  The 802.11 header is not included.
- */
-typedef enum {
-    BEACON_FTYPE = 0x1,
-    PROBERESP_FTYPE,
-    ACTION_MGMT_FTYPE,
-    PROBEREQ_FTYPE,
-} WMI_BI_FTYPE;
-
-enum {
-    BSS_ELEMID_CHANSWITCH = 0x01,
-    BSS_ELEMID_ATHEROS = 0x02,
-};
-
-typedef PREPACK struct {
-    u16 channel;
-    u8 frameType;          /* see WMI_BI_FTYPE */
-    u8 snr;
-    s16 rssi;
-    u8 bssid[ATH_MAC_LEN];
-    u32 ieMask;
-} POSTPACK WMI_BSS_INFO_HDR;
-
-/*
- * BSS INFO HDR version 2.0
- * With 6 bytes HTC header and 6 bytes of WMI header
- * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
- * header space.
- * - Reduce the ieMask to 2 bytes as only two bit flags are used
- * - Remove rssi and compute it on the host. rssi = snr - 95
- */
-typedef PREPACK struct {
-    u16 channel;
-    u8 frameType;          /* see WMI_BI_FTYPE */
-    u8 snr;
-    u8 bssid[ATH_MAC_LEN];
-    u16 ieMask;
-} POSTPACK WMI_BSS_INFO_HDR2;
-
-/*
- * Command Error Event
- */
-typedef enum {
-    INVALID_PARAM  = 0x01,
-    ILLEGAL_STATE  = 0x02,
-    INTERNAL_ERROR = 0x03,
-} WMI_ERROR_CODE;
-
-typedef PREPACK struct {
-    u16 commandId;
-    u8 errorCode;
-} POSTPACK WMI_CMD_ERROR_EVENT;
-
-/*
- * New Regulatory Domain Event
- */
-typedef PREPACK struct {
-    u32 regDomain;
-} POSTPACK WMI_REG_DOMAIN_EVENT;
-
-typedef PREPACK struct {
-    u8 txQueueNumber;
-    u8 rxQueueNumber;
-    u8 trafficDirection;
-    u8 trafficClass;
-} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT;
-
-typedef PREPACK struct {
-    u8 reserve1;
-    u8 reserve2;
-    u8 reserve3;
-    u8 trafficClass;
-} POSTPACK WMI_ACM_REJECT_EVENT;
-
-/*
- * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
- * the host of BSS's it has found that matches the current profile.
- * It can be used by the host to cache PMKs and/to initiate pre-authentication
- * if the BSS supports it.  The first bssid is always the current associated
- * BSS.
- * The bssid and bssFlags information repeats according to the number
- * or APs reported.
- */
-typedef enum {
-    WMI_DEFAULT_BSS_FLAGS   = 0x00,
-    WMI_PREAUTH_CAPABLE_BSS = 0x01,
-    WMI_PMKID_VALID_BSS     = 0x02,
-} WMI_BSS_FLAGS;
-
-typedef PREPACK struct {
-    u8 bssid[ATH_MAC_LEN];
-    u8 bssFlags;            /* see WMI_BSS_FLAGS */
-} POSTPACK WMI_NEIGHBOR_INFO;
-
-typedef PREPACK struct {
-    s8 numberOfAps;
-    WMI_NEIGHBOR_INFO neighbor[1];
-} POSTPACK WMI_NEIGHBOR_REPORT_EVENT;
-
-/*
- * TKIP MIC Error Event
- */
-typedef PREPACK struct {
-    u8 keyid;
-    u8 ismcast;
-} POSTPACK WMI_TKIP_MICERR_EVENT;
-
-/*
- * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new)
- */
-typedef PREPACK struct {
-    s32 status;
-} POSTPACK WMI_SCAN_COMPLETE_EVENT;
-
-#define MAX_OPT_DATA_LEN 1400
-
-/*
- * WMI_SET_ADHOC_BSSID_CMDID
- */
-typedef PREPACK struct {
-    u8 bssid[ATH_MAC_LEN];
-} POSTPACK WMI_SET_ADHOC_BSSID_CMD;
-
-/*
- * WMI_SET_OPT_MODE_CMDID
- */
-typedef enum {
-    SPECIAL_OFF,
-    SPECIAL_ON,
-} OPT_MODE_TYPE;
-
-typedef PREPACK struct {
-    u8 optMode;
-} POSTPACK WMI_SET_OPT_MODE_CMD;
-
-/*
- * WMI_TX_OPT_FRAME_CMDID
- */
-typedef enum {
-    OPT_PROBE_REQ   = 0x01,
-    OPT_PROBE_RESP  = 0x02,
-    OPT_CPPP_START  = 0x03,
-    OPT_CPPP_STOP   = 0x04,
-} WMI_OPT_FTYPE;
-
-typedef PREPACK struct {
-    u16 optIEDataLen;
-    u8 frmType;
-    u8 dstAddr[ATH_MAC_LEN];
-    u8 bssid[ATH_MAC_LEN];
-    u8 reserved;               /* For alignment */
-    u8 optIEData[1];
-} POSTPACK WMI_OPT_TX_FRAME_CMD;
-
-/*
- * Special frame receive Event.
- * Mechanism used to inform host of the receiption of the special frames.
- * Consists of special frame info header followed by special frame body.
- * The 802.11 header is not included.
- */
-typedef PREPACK struct {
-    u16 channel;
-    u8 frameType;          /* see WMI_OPT_FTYPE */
-    s8 snr;
-    u8 srcAddr[ATH_MAC_LEN];
-    u8 bssid[ATH_MAC_LEN];
-} POSTPACK WMI_OPT_RX_INFO_HDR;
-
-/*
- * Reporting statistics.
- */
-typedef PREPACK struct {
-    u32 tx_packets;
-    u32 tx_bytes;
-    u32 tx_unicast_pkts;
-    u32 tx_unicast_bytes;
-    u32 tx_multicast_pkts;
-    u32 tx_multicast_bytes;
-    u32 tx_broadcast_pkts;
-    u32 tx_broadcast_bytes;
-    u32 tx_rts_success_cnt;
-    u32 tx_packet_per_ac[4];
-    u32 tx_errors_per_ac[4];
-
-    u32 tx_errors;
-    u32 tx_failed_cnt;
-    u32 tx_retry_cnt;
-    u32 tx_mult_retry_cnt;
-    u32 tx_rts_fail_cnt;
-    s32 tx_unicast_rate;
-}POSTPACK tx_stats_t;
-
-typedef PREPACK struct {
-    u32 rx_packets;
-    u32 rx_bytes;
-    u32 rx_unicast_pkts;
-    u32 rx_unicast_bytes;
-    u32 rx_multicast_pkts;
-    u32 rx_multicast_bytes;
-    u32 rx_broadcast_pkts;
-    u32 rx_broadcast_bytes;
-    u32 rx_fragment_pkt;
-
-    u32 rx_errors;
-    u32 rx_crcerr;
-    u32 rx_key_cache_miss;
-    u32 rx_decrypt_err;
-    u32 rx_duplicate_frames;
-    s32 rx_unicast_rate;
-}POSTPACK rx_stats_t;
-
-typedef PREPACK struct {
-    u32 tkip_local_mic_failure;
-    u32 tkip_counter_measures_invoked;
-    u32 tkip_replays;
-    u32 tkip_format_errors;
-    u32 ccmp_format_errors;
-    u32 ccmp_replays;
-}POSTPACK tkip_ccmp_stats_t;
-
-typedef PREPACK struct {
-    u32 power_save_failure_cnt;
-    u16 stop_tx_failure_cnt;
-    u16 atim_tx_failure_cnt;
-    u16 atim_rx_failure_cnt;
-    u16 bcn_rx_failure_cnt;
-}POSTPACK pm_stats_t;
-
-typedef PREPACK struct {
-    u32 cs_bmiss_cnt;
-    u32 cs_lowRssi_cnt;
-    u16 cs_connect_cnt;
-    u16 cs_disconnect_cnt;
-    s16 cs_aveBeacon_rssi;
-    u16 cs_roam_count;
-    s16 cs_rssi;
-    u8 cs_snr;
-    u8 cs_aveBeacon_snr;
-    u8 cs_lastRoam_msec;
-} POSTPACK cserv_stats_t;
-
-typedef PREPACK struct {
-    tx_stats_t          tx_stats;
-    rx_stats_t          rx_stats;
-    tkip_ccmp_stats_t   tkipCcmpStats;
-}POSTPACK wlan_net_stats_t;
-
-typedef PREPACK struct {
-    u32 arp_received;
-    u32 arp_matched;
-    u32 arp_replied;
-} POSTPACK arp_stats_t;
-
-typedef PREPACK struct {
-    u32 wow_num_pkts_dropped;
-    u16 wow_num_events_discarded;
-    u8 wow_num_host_pkt_wakeups;
-    u8 wow_num_host_event_wakeups;
-} POSTPACK wlan_wow_stats_t;
-
-typedef PREPACK struct {
-    u32 lqVal;
-    s32 noise_floor_calibation;
-    pm_stats_t          pmStats;
-    wlan_net_stats_t    txrxStats;
-    wlan_wow_stats_t    wowStats;
-    arp_stats_t         arpStats;
-    cserv_stats_t       cservStats;
-} POSTPACK WMI_TARGET_STATS;
-
-/*
- * WMI_RSSI_THRESHOLD_EVENTID.
- * Indicate the RSSI events to host. Events are indicated when we breach a
- * thresold value.
- */
-typedef enum{
-    WMI_RSSI_THRESHOLD1_ABOVE = 0,
-    WMI_RSSI_THRESHOLD2_ABOVE,
-    WMI_RSSI_THRESHOLD3_ABOVE,
-    WMI_RSSI_THRESHOLD4_ABOVE,
-    WMI_RSSI_THRESHOLD5_ABOVE,
-    WMI_RSSI_THRESHOLD6_ABOVE,
-    WMI_RSSI_THRESHOLD1_BELOW,
-    WMI_RSSI_THRESHOLD2_BELOW,
-    WMI_RSSI_THRESHOLD3_BELOW,
-    WMI_RSSI_THRESHOLD4_BELOW,
-    WMI_RSSI_THRESHOLD5_BELOW,
-    WMI_RSSI_THRESHOLD6_BELOW
-}WMI_RSSI_THRESHOLD_VAL;
-
-typedef PREPACK struct {
-    s16 rssi;
-    u8 range;
-}POSTPACK WMI_RSSI_THRESHOLD_EVENT;
-
-/*
- *  WMI_ERROR_REPORT_EVENTID
- */
-typedef enum{
-    WMI_TARGET_PM_ERR_FAIL      = 0x00000001,
-    WMI_TARGET_KEY_NOT_FOUND    = 0x00000002,
-    WMI_TARGET_DECRYPTION_ERR   = 0x00000004,
-    WMI_TARGET_BMISS            = 0x00000008,
-    WMI_PSDISABLE_NODE_JOIN     = 0x00000010,
-    WMI_TARGET_COM_ERR          = 0x00000020,
-    WMI_TARGET_FATAL_ERR        = 0x00000040
-} WMI_TARGET_ERROR_VAL;
-
-typedef PREPACK struct {
-    u32 errorVal;
-}POSTPACK  WMI_TARGET_ERROR_REPORT_EVENT;
-
-typedef PREPACK struct {
-    u8 retrys;
-}POSTPACK  WMI_TX_RETRY_ERR_EVENT;
-
-typedef enum{
-    WMI_SNR_THRESHOLD1_ABOVE = 1,
-    WMI_SNR_THRESHOLD1_BELOW,
-    WMI_SNR_THRESHOLD2_ABOVE,
-    WMI_SNR_THRESHOLD2_BELOW,
-    WMI_SNR_THRESHOLD3_ABOVE,
-    WMI_SNR_THRESHOLD3_BELOW,
-    WMI_SNR_THRESHOLD4_ABOVE,
-    WMI_SNR_THRESHOLD4_BELOW
-} WMI_SNR_THRESHOLD_VAL;
-
-typedef PREPACK struct {
-    u8 range;  /* WMI_SNR_THRESHOLD_VAL */
-    u8 snr;
-}POSTPACK  WMI_SNR_THRESHOLD_EVENT;
-
-typedef enum{
-    WMI_LQ_THRESHOLD1_ABOVE = 1,
-    WMI_LQ_THRESHOLD1_BELOW,
-    WMI_LQ_THRESHOLD2_ABOVE,
-    WMI_LQ_THRESHOLD2_BELOW,
-    WMI_LQ_THRESHOLD3_ABOVE,
-    WMI_LQ_THRESHOLD3_BELOW,
-    WMI_LQ_THRESHOLD4_ABOVE,
-    WMI_LQ_THRESHOLD4_BELOW
-} WMI_LQ_THRESHOLD_VAL;
-
-typedef PREPACK struct {
-    s32 lq;
-    u8 range;  /* WMI_LQ_THRESHOLD_VAL */
-}POSTPACK  WMI_LQ_THRESHOLD_EVENT;
-/*
- * WMI_REPORT_ROAM_TBL_EVENTID
- */
-#define MAX_ROAM_TBL_CAND   5
-
-typedef PREPACK struct {
-    s32 roam_util;
-    u8 bssid[ATH_MAC_LEN];
-    s8 rssi;
-    s8 rssidt;
-    s8 last_rssi;
-    s8 util;
-    s8 bias;
-    u8 reserved; /* For alignment */
-} POSTPACK WMI_BSS_ROAM_INFO;
-
-
-typedef PREPACK struct {
-    u16 roamMode;
-    u16 numEntries;
-    WMI_BSS_ROAM_INFO bssRoamInfo[1];
-} POSTPACK WMI_TARGET_ROAM_TBL;
-
-/*
- * WMI_HCI_EVENT_EVENTID
- */
-typedef PREPACK struct {
-    u16 evt_buf_sz;     /* HCI event buffer size */
-    u8 buf[1];         /* HCI  event */
-} POSTPACK WMI_HCI_EVENT;
-
-/*
- *  WMI_CAC_EVENTID
- */
-typedef enum {
-    CAC_INDICATION_ADMISSION = 0x00,
-    CAC_INDICATION_ADMISSION_RESP = 0x01,
-    CAC_INDICATION_DELETE = 0x02,
-    CAC_INDICATION_NO_RESP = 0x03,
-}CAC_INDICATION;
-
-#define WMM_TSPEC_IE_LEN   63
-
-typedef PREPACK struct {
-    u8 ac;
-    u8 cac_indication;
-    u8 statusCode;
-    u8 tspecSuggestion[WMM_TSPEC_IE_LEN];
-}POSTPACK  WMI_CAC_EVENT;
-
-/*
- * WMI_APLIST_EVENTID
- */
-
-typedef enum {
-    APLIST_VER1 = 1,
-} APLIST_VER;
-
-typedef PREPACK struct {
-    u8 bssid[ATH_MAC_LEN];
-    u16 channel;
-} POSTPACK  WMI_AP_INFO_V1;
-
-typedef PREPACK union {
-    WMI_AP_INFO_V1  apInfoV1;
-} POSTPACK WMI_AP_INFO;
-
-typedef PREPACK struct {
-    u8 apListVer;
-    u8 numAP;
-    WMI_AP_INFO apList[1];
-} POSTPACK WMI_APLIST_EVENT;
-
-/*
- * developer commands
- */
-
-/*
- * WMI_SET_BITRATE_CMDID
- *
- * Get bit rate cmd uses same definition as set bit rate cmd
- */
-typedef enum {
-    RATE_AUTO   = -1,
-    RATE_1Mb    = 0,
-    RATE_2Mb    = 1,
-    RATE_5_5Mb  = 2,
-    RATE_11Mb   = 3,
-    RATE_6Mb    = 4,
-    RATE_9Mb    = 5,
-    RATE_12Mb   = 6,
-    RATE_18Mb   = 7,
-    RATE_24Mb   = 8,
-    RATE_36Mb   = 9,
-    RATE_48Mb   = 10,
-    RATE_54Mb   = 11,
-    RATE_MCS_0_20 = 12,
-    RATE_MCS_1_20 = 13,
-    RATE_MCS_2_20 = 14,
-    RATE_MCS_3_20 = 15,
-    RATE_MCS_4_20 = 16,
-    RATE_MCS_5_20 = 17,
-    RATE_MCS_6_20 = 18,
-    RATE_MCS_7_20 = 19,
-    RATE_MCS_0_40 = 20,
-    RATE_MCS_1_40 = 21,
-    RATE_MCS_2_40 = 22,
-    RATE_MCS_3_40 = 23,
-    RATE_MCS_4_40 = 24,
-    RATE_MCS_5_40 = 25,
-    RATE_MCS_6_40 = 26,
-    RATE_MCS_7_40 = 27,
-} WMI_BIT_RATE;
-
-typedef PREPACK struct {
-    s8 rateIndex;          /* see WMI_BIT_RATE */
-    s8 mgmtRateIndex;
-    s8 ctlRateIndex;
-} POSTPACK WMI_BIT_RATE_CMD;
-
-
-typedef PREPACK struct {
-    s8 rateIndex;          /* see WMI_BIT_RATE */
-} POSTPACK  WMI_BIT_RATE_REPLY;
-
-
-/*
- * WMI_SET_FIXRATES_CMDID
- *
- * Get fix rates cmd uses same definition as set fix rates cmd
- */
-#define FIX_RATE_1Mb            ((u32)0x1)
-#define FIX_RATE_2Mb            ((u32)0x2)
-#define FIX_RATE_5_5Mb          ((u32)0x4)
-#define FIX_RATE_11Mb           ((u32)0x8)
-#define FIX_RATE_6Mb            ((u32)0x10)
-#define FIX_RATE_9Mb            ((u32)0x20)
-#define FIX_RATE_12Mb           ((u32)0x40)
-#define FIX_RATE_18Mb           ((u32)0x80)
-#define FIX_RATE_24Mb           ((u32)0x100)
-#define FIX_RATE_36Mb           ((u32)0x200)
-#define FIX_RATE_48Mb           ((u32)0x400)
-#define FIX_RATE_54Mb           ((u32)0x800)
-#define FIX_RATE_MCS_0_20       ((u32)0x1000)
-#define FIX_RATE_MCS_1_20       ((u32)0x2000)
-#define FIX_RATE_MCS_2_20       ((u32)0x4000)
-#define FIX_RATE_MCS_3_20       ((u32)0x8000)
-#define FIX_RATE_MCS_4_20       ((u32)0x10000)
-#define FIX_RATE_MCS_5_20       ((u32)0x20000)
-#define FIX_RATE_MCS_6_20       ((u32)0x40000)
-#define FIX_RATE_MCS_7_20       ((u32)0x80000)
-#define FIX_RATE_MCS_0_40       ((u32)0x100000)
-#define FIX_RATE_MCS_1_40       ((u32)0x200000)
-#define FIX_RATE_MCS_2_40       ((u32)0x400000)
-#define FIX_RATE_MCS_3_40       ((u32)0x800000)
-#define FIX_RATE_MCS_4_40       ((u32)0x1000000)
-#define FIX_RATE_MCS_5_40       ((u32)0x2000000)
-#define FIX_RATE_MCS_6_40       ((u32)0x4000000)
-#define FIX_RATE_MCS_7_40       ((u32)0x8000000)
-
-typedef PREPACK struct {
-    u32 fixRateMask;          /* see WMI_BIT_RATE */
-} POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY;
-
-typedef PREPACK struct {
-    u8 bEnableMask;
-    u8 frameType;               /*type and subtype*/
-    u32 frameRateMask;          /* see WMI_BIT_RATE */
-} POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY;
-
-/*
- * WMI_SET_RECONNECT_AUTH_MODE_CMDID
- *
- * Set authentication mode
- */
-typedef enum {
-    RECONN_DO_AUTH = 0x00,
-    RECONN_NOT_AUTH = 0x01
-} WMI_AUTH_MODE;
-
-typedef PREPACK struct {
-    u8 mode;
-} POSTPACK WMI_SET_AUTH_MODE_CMD;
-
-/*
- * WMI_SET_REASSOC_MODE_CMDID
- *
- * Set authentication mode
- */
-typedef enum {
-    REASSOC_DO_DISASSOC = 0x00,
-    REASSOC_DONOT_DISASSOC = 0x01
-} WMI_REASSOC_MODE;
-
-typedef PREPACK struct {
-    u8 mode;
-}POSTPACK WMI_SET_REASSOC_MODE_CMD;
-
-typedef enum {
-    ROAM_DATA_TIME = 1,            /* Get The Roam Time Data */
-} ROAM_DATA_TYPE;
-
-typedef PREPACK struct {
-    u32 disassoc_time;
-    u32 no_txrx_time;
-    u32 assoc_time;
-    u32 allow_txrx_time;
-    u8 disassoc_bssid[ATH_MAC_LEN];
-    s8 disassoc_bss_rssi;
-    u8 assoc_bssid[ATH_MAC_LEN];
-    s8 assoc_bss_rssi;
-} POSTPACK WMI_TARGET_ROAM_TIME;
-
-typedef PREPACK struct {
-    PREPACK union {
-        WMI_TARGET_ROAM_TIME roamTime;
-    } POSTPACK u;
-    u8 roamDataType ;
-} POSTPACK WMI_TARGET_ROAM_DATA;
-
-typedef enum {
-    WMI_WMM_DISABLED = 0,
-    WMI_WMM_ENABLED
-} WMI_WMM_STATUS;
-
-typedef PREPACK struct {
-    u8 status;
-}POSTPACK WMI_SET_WMM_CMD;
-
-typedef PREPACK struct {
-    u8 status;
-}POSTPACK WMI_SET_QOS_SUPP_CMD;
-
-typedef enum {
-    WMI_TXOP_DISABLED = 0,
-    WMI_TXOP_ENABLED
-} WMI_TXOP_CFG;
-
-typedef PREPACK struct {
-    u8 txopEnable;
-}POSTPACK WMI_SET_WMM_TXOP_CMD;
-
-typedef PREPACK struct {
-    u8 keepaliveInterval;
-} POSTPACK WMI_SET_KEEPALIVE_CMD;
-
-typedef PREPACK struct {
-    u32 configured;
-    u8 keepaliveInterval;
-} POSTPACK WMI_GET_KEEPALIVE_CMD;
-
-/*
- * Add Application specified IE to a management frame
- */
-#define WMI_MAX_IE_LEN  255
-
-typedef PREPACK struct {
-    u8 mgmtFrmType;  /* one of WMI_MGMT_FRAME_TYPE */
-    u8 ieLen;    /* Length  of the IE that should be added to the MGMT frame */
-    u8 ieInfo[1];
-} POSTPACK WMI_SET_APPIE_CMD;
-
-/*
- * Notify the WSC registration status to the target
- */
-#define WSC_REG_ACTIVE     1
-#define WSC_REG_INACTIVE   0
-/* Generic Hal Interface for setting hal paramters. */
-/* Add new Set HAL Param cmdIds here for newer params */
-typedef enum {
-   WHAL_SETCABTO_CMDID = 1,
-}WHAL_CMDID;
-
-typedef PREPACK struct {
-    u8 cabTimeOut;
-} POSTPACK WHAL_SETCABTO_PARAM;
-
-typedef PREPACK struct {
-    u8 whalCmdId;
-    u8 data[1];
-} POSTPACK WHAL_PARAMCMD;
-
-
-#define WOW_MAX_FILTER_LISTS 1 /*4*/
-#define WOW_MAX_FILTERS_PER_LIST 4
-#define WOW_PATTERN_SIZE 64
-#define WOW_MASK_SIZE 64
-
-#define MAC_MAX_FILTERS_PER_LIST 4
-
-typedef PREPACK struct {
-    u8 wow_valid_filter;
-    u8 wow_filter_id;
-    u8 wow_filter_size;
-    u8 wow_filter_offset;
-    u8 wow_filter_mask[WOW_MASK_SIZE];
-    u8 wow_filter_pattern[WOW_PATTERN_SIZE];
-} POSTPACK WOW_FILTER;
-
-
-typedef PREPACK struct {
-    u8 wow_valid_list;
-    u8 wow_list_id;
-    u8 wow_num_filters;
-    u8 wow_total_list_size;
-    WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST];
-} POSTPACK WOW_FILTER_LIST;
-
-typedef PREPACK struct {
-    u8 valid_filter;
-    u8 mac_addr[ATH_MAC_LEN];
-} POSTPACK MAC_FILTER;
-
-
-typedef PREPACK struct {
-    u8 total_list_size;
-    u8 enable;
-    MAC_FILTER list[MAC_MAX_FILTERS_PER_LIST];
-} POSTPACK MAC_FILTER_LIST;
-
-#define MAX_IP_ADDRS  2
-typedef PREPACK struct {
-    u32 ips[MAX_IP_ADDRS];  /* IP in Network Byte Order */
-} POSTPACK WMI_SET_IP_CMD;
-
-typedef PREPACK struct {
-    u32 awake;
-    u32 asleep;
-} POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD;
-
-typedef enum {
-    WOW_FILTER_SSID = 0x1
-} WMI_WOW_FILTER;
-
-typedef PREPACK struct {
-    u32 enable_wow;
-    WMI_WOW_FILTER filter;
-    u16 hostReqDelay;
-} POSTPACK WMI_SET_WOW_MODE_CMD;
-
-typedef PREPACK struct {
-    u8 filter_list_id;
-} POSTPACK WMI_GET_WOW_LIST_CMD;
-
-/*
- * WMI_GET_WOW_LIST_CMD reply
- */
-typedef PREPACK struct {
-    u8 num_filters;     /* number of patterns in reply */
-    u8 this_filter_num; /*  this is filter # x of total num_filters */
-    u8 wow_mode;
-    u8 host_mode;
-    WOW_FILTER  wow_filters[1];
-} POSTPACK WMI_GET_WOW_LIST_REPLY;
-
-typedef PREPACK struct {
-    u8 filter_list_id;
-    u8 filter_size;
-    u8 filter_offset;
-    u8 filter[1];
-} POSTPACK WMI_ADD_WOW_PATTERN_CMD;
-
-typedef PREPACK struct {
-    u16 filter_list_id;
-    u16 filter_id;
-} POSTPACK WMI_DEL_WOW_PATTERN_CMD;
-
-typedef PREPACK struct {
-    u8 macaddr[ATH_MAC_LEN];
-} POSTPACK WMI_SET_MAC_ADDRESS_CMD;
-
-/*
- * WMI_SET_AKMP_PARAMS_CMD
- */
-
-#define WMI_AKMP_MULTI_PMKID_EN   0x000001
-
-typedef PREPACK struct {
-    u32 akmpInfo;
-} POSTPACK WMI_SET_AKMP_PARAMS_CMD;
-
-typedef PREPACK struct {
-    u8 pmkid[WMI_PMKID_LEN];
-} POSTPACK WMI_PMKID;
-
-/*
- * WMI_SET_PMKID_LIST_CMD
- */
-#define WMI_MAX_PMKID_CACHE   8
-
-typedef PREPACK struct {
-    u32 numPMKID;
-    WMI_PMKID   pmkidList[WMI_MAX_PMKID_CACHE];
-} POSTPACK WMI_SET_PMKID_LIST_CMD;
-
-/*
- * WMI_GET_PMKID_LIST_CMD  Reply
- * Following the Number of PMKIDs is the list of PMKIDs
- */
-typedef PREPACK struct {
-    u32 numPMKID;
-    u8 bssidList[ATH_MAC_LEN][1];
-    WMI_PMKID   pmkidList[1];
-} POSTPACK WMI_PMKID_LIST_REPLY;
-
-typedef PREPACK struct {
-    u16 oldChannel;
-    u32 newChannel;
-} POSTPACK WMI_CHANNEL_CHANGE_EVENT;
-
-typedef PREPACK struct {
-    u32 version;
-} POSTPACK WMI_WLAN_VERSION_EVENT;
-
-
-/* WMI_ADDBA_REQ_EVENTID */
-typedef PREPACK struct {
-    u8 tid;
-    u8 win_sz;
-    u16 st_seq_no;
-    u8 status;         /* f/w response for ADDBA Req; OK(0) or failure(!=0) */
-} POSTPACK WMI_ADDBA_REQ_EVENT;
-
-/* WMI_ADDBA_RESP_EVENTID */
-typedef PREPACK struct {
-    u8 tid;
-    u8 status;         /* OK(0), failure (!=0) */
-    u16 amsdu_sz;       /* Three values: Not supported(0), 3839, 8k */
-} POSTPACK WMI_ADDBA_RESP_EVENT;
-
-/* WMI_DELBA_EVENTID
- * f/w received a DELBA for peer and processed it.
- * Host is notified of this
- */
-typedef PREPACK struct {
-    u8 tid;
-    u8 is_peer_initiator;
-    u16 reason_code;
-} POSTPACK WMI_DELBA_EVENT;
-
-
-#ifdef WAPI_ENABLE
-#define WAPI_REKEY_UCAST    1
-#define WAPI_REKEY_MCAST    2
-typedef PREPACK struct {
-    u8 type;
-    u8 macAddr[ATH_MAC_LEN];
-} POSTPACK WMI_WAPIREKEY_EVENT;
-#endif
-
-
-/* WMI_ALLOW_AGGR_CMDID
- * Configures tid's to allow ADDBA negotiations
- * on each tid, in each direction
- */
-typedef PREPACK struct {
-    u16 tx_allow_aggr;  /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/
-    u16 rx_allow_aggr;  /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/
-} POSTPACK WMI_ALLOW_AGGR_CMD;
-
-/* WMI_ADDBA_REQ_CMDID
- * f/w starts performing ADDBA negotiations with peer
- * on the given tid
- */
-typedef PREPACK struct {
-    u8 tid;
-} POSTPACK WMI_ADDBA_REQ_CMD;
-
-/* WMI_DELBA_REQ_CMDID
- * f/w would teardown BA with peer.
- * is_send_initiator indicates if it's or tx or rx side
- */
-typedef PREPACK struct {
-    u8 tid;
-    u8 is_sender_initiator;
-
-} POSTPACK WMI_DELBA_REQ_CMD;
-
-#define PEER_NODE_JOIN_EVENT 0x00
-#define PEER_NODE_LEAVE_EVENT 0x01
-#define PEER_FIRST_NODE_JOIN_EVENT 0x10
-#define PEER_LAST_NODE_LEAVE_EVENT 0x11
-typedef PREPACK struct {
-    u8 eventCode;
-    u8 peerMacAddr[ATH_MAC_LEN];
-} POSTPACK WMI_PEER_NODE_EVENT;
-
-#define IEEE80211_FRAME_TYPE_MGT          0x00
-#define IEEE80211_FRAME_TYPE_CTL          0x04
-
-/*
- * Transmit complete event data structure(s)
- */
-
-
-typedef PREPACK struct {
-#define TX_COMPLETE_STATUS_SUCCESS 0
-#define TX_COMPLETE_STATUS_RETRIES 1
-#define TX_COMPLETE_STATUS_NOLINK  2
-#define TX_COMPLETE_STATUS_TIMEOUT 3
-#define TX_COMPLETE_STATUS_OTHER   4
-
-    u8 status; /* one of TX_COMPLETE_STATUS_... */
-    u8 pktID; /* packet ID to identify parent packet */
-    u8 rateIdx; /* rate index on successful transmission */
-    u8 ackFailures; /* number of ACK failures in tx attempt */
-#if 0 /* optional params currently omitted. */
-    u32 queueDelay; // usec delay measured Tx Start time - host delivery time
-    u32 mediaDelay; // usec delay measured ACK rx time - host delivery time
-#endif
-} POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */
-
-typedef PREPACK struct {
-    u8 numMessages; /* number of tx comp msgs following this struct */
-    u8 msgLen; /* length in bytes for each individual msg following this struct */
-    u8 msgType; /* version of tx complete msg data following this struct */
-    u8 reserved; /* individual messages follow this header */
-} POSTPACK WMI_TX_COMPLETE_EVENT;
-
-#define WMI_TXCOMPLETE_VERSION_1 (0x01)
-
-
-/*
- * ------- AP Mode definitions --------------
- */
-
-/*
- * !!! Warning !!!
- * -Changing the following values needs compilation of both driver and firmware
- */
-#ifdef AR6002_REV2
-#define AP_MAX_NUM_STA          4
-#else
-#define AP_MAX_NUM_STA          8
-#endif
-#define AP_ACL_SIZE             10
-#define IEEE80211_MAX_IE        256
-#define MCAST_AID               0xFF /* Spl. AID used to set DTIM flag in the beacons */
-#define DEF_AP_COUNTRY_CODE     "US "
-#define DEF_AP_WMODE_G          WMI_11G_MODE
-#define DEF_AP_WMODE_AG         WMI_11AG_MODE
-#define DEF_AP_DTIM             5
-#define DEF_BEACON_INTERVAL     100
-
-/* AP mode disconnect reasons */
-#define AP_DISCONNECT_STA_LEFT      101
-#define AP_DISCONNECT_FROM_HOST     102
-#define AP_DISCONNECT_COMM_TIMEOUT  103
-
-/*
- * Used with WMI_AP_HIDDEN_SSID_CMDID
- */
-#define HIDDEN_SSID_FALSE   0
-#define HIDDEN_SSID_TRUE    1
-typedef PREPACK struct {
-    u8 hidden_ssid;
-} POSTPACK WMI_AP_HIDDEN_SSID_CMD;
-
-/*
- * Used with WMI_AP_ACL_POLICY_CMDID
- */
-#define AP_ACL_DISABLE          0x00
-#define AP_ACL_ALLOW_MAC        0x01
-#define AP_ACL_DENY_MAC         0x02
-#define AP_ACL_RETAIN_LIST_MASK 0x80
-typedef PREPACK struct {
-    u8 policy;
-} POSTPACK WMI_AP_ACL_POLICY_CMD;
-
-/*
- * Used with WMI_AP_ACL_MAC_LIST_CMDID
- */
-#define ADD_MAC_ADDR    1
-#define DEL_MAC_ADDR    2
-typedef PREPACK struct {
-    u8 action;
-    u8 index;
-    u8 mac[ATH_MAC_LEN];
-    u8 wildcard;
-} POSTPACK WMI_AP_ACL_MAC_CMD;
-
-typedef PREPACK struct {
-    u16 index;
-    u8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN];
-    u8 wildcard[AP_ACL_SIZE];
-    u8 policy;
-} POSTPACK WMI_AP_ACL;
-
-/*
- * Used with WMI_AP_SET_NUM_STA_CMDID
- */
-typedef PREPACK struct {
-    u8 num_sta;
-} POSTPACK WMI_AP_SET_NUM_STA_CMD;
-
-/*
- * Used with WMI_AP_SET_MLME_CMDID
- */
-typedef PREPACK struct {
-    u8 mac[ATH_MAC_LEN];
-    u16 reason;              /* 802.11 reason code */
-    u8 cmd;                 /* operation to perform */
-#define WMI_AP_MLME_ASSOC       1   /* associate station */
-#define WMI_AP_DISASSOC         2   /* disassociate station */
-#define WMI_AP_DEAUTH           3   /* deauthenticate station */
-#define WMI_AP_MLME_AUTHORIZE   4   /* authorize station */
-#define WMI_AP_MLME_UNAUTHORIZE 5   /* unauthorize station */
-} POSTPACK WMI_AP_SET_MLME_CMD;
-
-typedef PREPACK struct {
-    u32 period;
-} POSTPACK WMI_AP_CONN_INACT_CMD;
-
-typedef PREPACK struct {
-    u32 period_min;
-    u32 dwell_ms;
-} POSTPACK WMI_AP_PROT_SCAN_TIME_CMD;
-
-typedef PREPACK struct {
-    u32 flag;
-    u16 aid;
-} POSTPACK WMI_AP_SET_PVB_CMD;
-
-#define WMI_DISABLE_REGULATORY_CODE "FF"
-
-typedef PREPACK struct {
-    u8 countryCode[3];
-} POSTPACK WMI_AP_SET_COUNTRY_CMD;
-
-typedef PREPACK struct {
-    u8 dtim;
-} POSTPACK WMI_AP_SET_DTIM_CMD;
-
-typedef PREPACK struct {
-    u8 band; /* specifies which band to apply these values */
-    u8 enable; /* allows 11n to be disabled on a per band basis */
-    u8 chan_width_40M_supported;
-    u8 short_GI_20MHz;
-    u8 short_GI_40MHz;
-    u8 intolerance_40MHz;
-    u8 max_ampdu_len_exp;
-} POSTPACK WMI_SET_HT_CAP_CMD;
-
-typedef PREPACK struct {
-    u8 sta_chan_width;
-} POSTPACK WMI_SET_HT_OP_CMD;
-
-typedef PREPACK struct {
-    u32 rateMasks[8];
-} POSTPACK WMI_SET_TX_SELECT_RATES_CMD;
-
-typedef PREPACK struct {
-    u32 sgiMask;
-    u8 sgiPERThreshold;
-} POSTPACK WMI_SET_TX_SGI_PARAM_CMD;
-
-#define DEFAULT_SGI_MASK 0x08080000
-#define DEFAULT_SGI_PER 10
-
-typedef PREPACK struct {
-    u32 rateField; /* 1 bit per rate corresponding to index */
-    u8 id;
-    u8 shortTrys;
-    u8 longTrys;
-    u8 reserved; /* padding */
-} POSTPACK WMI_SET_RATE_POLICY_CMD;
-
-typedef PREPACK struct {
-    u8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */
-    u8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 <default> */
-    u8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target <default> */
-    u8 reserved[1]; /* alignment */
-} POSTPACK WMI_RX_FRAME_FORMAT_CMD;
-
-
-typedef PREPACK struct {
-    u8 enable;     /* 1 == device operates in thin mode , 0 == normal mode <default> */
-    u8 reserved[3];
-} POSTPACK WMI_SET_THIN_MODE_CMD;
-
-/* AP mode events */
-/* WMI_PS_POLL_EVENT */
-typedef PREPACK struct {
-    u16 aid;
-} POSTPACK WMI_PSPOLL_EVENT;
-
-typedef PREPACK struct {
-    u32 tx_bytes;
-    u32 tx_pkts;
-    u32 tx_error;
-    u32 tx_discard;
-    u32 rx_bytes;
-    u32 rx_pkts;
-    u32 rx_error;
-    u32 rx_discard;
-    u32 aid;
-} POSTPACK WMI_PER_STA_STAT;
-
-#define AP_GET_STATS    0
-#define AP_CLEAR_STATS  1
-
-typedef PREPACK struct {
-    u32 action;
-    WMI_PER_STA_STAT    sta[AP_MAX_NUM_STA+1];
-} POSTPACK WMI_AP_MODE_STAT;
-#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(u32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT)))
-
-#define AP_11BG_RATESET1        1
-#define AP_11BG_RATESET2        2
-#define DEF_AP_11BG_RATESET     AP_11BG_RATESET1
-typedef PREPACK struct {
-    u8 rateset;
-} POSTPACK WMI_AP_SET_11BG_RATESET_CMD;
-/*
- * End of AP mode definitions
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _WMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h
deleted file mode 100644 (file)
index 9435eab..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wmix.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-/*
- * This file contains extensions of the WMI protocol specified in the
- * Wireless Module Interface (WMI).  It includes definitions of all
- * extended commands and events.  Extensions include useful commands
- * that are not directly related to wireless activities.  They may
- * be hardware-specific, and they might not be supported on all
- * implementations.
- *
- * Extended WMIX commands are encapsulated in a WMI message with
- * cmd=WMI_EXTENSION_CMD.
- */
-
-#ifndef _WMIX_H_
-#define _WMIX_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "dbglog.h"
-
-/*
- * Extended WMI commands are those that are needed during wireless
- * operation, but which are not really wireless commands.  This allows,
- * for instance, platform-specific commands.  Extended WMI commands are
- * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
- * Extended WMI events are similarly embedded in a WMI event message with
- * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
- */
-typedef PREPACK struct {
-    u32 commandId;
-} POSTPACK WMIX_CMD_HDR;
-
-typedef enum {
-    WMIX_DSETOPEN_REPLY_CMDID           = 0x2001,
-    WMIX_DSETDATA_REPLY_CMDID,
-    WMIX_GPIO_OUTPUT_SET_CMDID,
-    WMIX_GPIO_INPUT_GET_CMDID,
-    WMIX_GPIO_REGISTER_SET_CMDID,
-    WMIX_GPIO_REGISTER_GET_CMDID,
-    WMIX_GPIO_INTR_ACK_CMDID,
-    WMIX_HB_CHALLENGE_RESP_CMDID,
-    WMIX_DBGLOG_CFG_MODULE_CMDID,
-    WMIX_PROF_CFG_CMDID,                 /* 0x200a */
-    WMIX_PROF_ADDR_SET_CMDID,
-    WMIX_PROF_START_CMDID,
-    WMIX_PROF_STOP_CMDID,
-    WMIX_PROF_COUNT_GET_CMDID,
-} WMIX_COMMAND_ID;
-
-typedef enum {
-    WMIX_DSETOPENREQ_EVENTID            = 0x3001,
-    WMIX_DSETCLOSE_EVENTID,
-    WMIX_DSETDATAREQ_EVENTID,
-    WMIX_GPIO_INTR_EVENTID,
-    WMIX_GPIO_DATA_EVENTID,
-    WMIX_GPIO_ACK_EVENTID,
-    WMIX_HB_CHALLENGE_RESP_EVENTID,
-    WMIX_DBGLOG_EVENTID,
-    WMIX_PROF_COUNT_EVENTID,
-} WMIX_EVENT_ID;
-
-/*
- * =============DataSet support=================
- */
-
-/*
- * WMIX_DSETOPENREQ_EVENTID
- * DataSet Open Request Event
- */
-typedef PREPACK struct {
-    u32 dset_id;
-    u32 targ_dset_handle;  /* echo'ed, not used by Host, */
-    u32 targ_reply_fn;     /* echo'ed, not used by Host, */
-    u32 targ_reply_arg;    /* echo'ed, not used by Host, */
-} POSTPACK WMIX_DSETOPENREQ_EVENT;
-
-/*
- * WMIX_DSETCLOSE_EVENTID
- * DataSet Close Event
- */
-typedef PREPACK struct {
-    u32 access_cookie;
-} POSTPACK WMIX_DSETCLOSE_EVENT;
-
-/*
- * WMIX_DSETDATAREQ_EVENTID
- * DataSet Data Request Event
- */
-typedef PREPACK struct {
-    u32 access_cookie;
-    u32 offset;
-    u32 length;
-    u32 targ_buf;         /* echo'ed, not used by Host, */
-    u32 targ_reply_fn;    /* echo'ed, not used by Host, */
-    u32 targ_reply_arg;   /* echo'ed, not used by Host, */
-} POSTPACK WMIX_DSETDATAREQ_EVENT;
-
-typedef PREPACK struct {
-    u32 status;
-    u32 targ_dset_handle;
-    u32 targ_reply_fn;
-    u32 targ_reply_arg;
-    u32 access_cookie;
-    u32 size;
-    u32 version;
-} POSTPACK WMIX_DSETOPEN_REPLY_CMD;
-
-typedef PREPACK struct {
-    u32 status;
-    u32 targ_buf;
-    u32 targ_reply_fn;
-    u32 targ_reply_arg;
-    u32 length;
-    u8 buf[1];
-} POSTPACK WMIX_DSETDATA_REPLY_CMD;
-
-
-/* 
- * =============GPIO support=================
- * All masks are 18-bit masks with bit N operating on GPIO pin N.
- */
-
-
-/*
- * Set GPIO pin output state.
- * In order for output to be driven, a pin must be enabled for output.
- * This can be done during initialization through the GPIO Configuration
- * DataSet, or during operation with the enable_mask.
- *
- * If a request is made to simultaneously set/clear or set/disable or
- * clear/disable or disable/enable, results are undefined.
- */
-typedef PREPACK struct {
-    u32 set_mask;             /* pins to set */
-    u32 clear_mask;           /* pins to clear */
-    u32 enable_mask;          /* pins to enable for output */
-    u32 disable_mask;         /* pins to disable/tristate */
-} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD;
-
-/* 
- * Set a GPIO register.  For debug/exceptional cases.
- * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a
- * platform-dependent header.
- */
-typedef PREPACK struct {
-    u32 gpioreg_id;           /* GPIO register ID */
-    u32 value;                /* value to write */
-} POSTPACK WMIX_GPIO_REGISTER_SET_CMD;
-
-/* Get a GPIO register.  For debug/exceptional cases. */
-typedef PREPACK struct {
-    u32 gpioreg_id;           /* GPIO register to read */
-} POSTPACK WMIX_GPIO_REGISTER_GET_CMD;
-
-/*
- * Host acknowledges and re-arms GPIO interrupts.  A single
- * message should be used to acknowledge all interrupts that
- * were delivered in an earlier WMIX_GPIO_INTR_EVENT message.
- */
-typedef PREPACK struct {
-    u32 ack_mask;             /* interrupts to acknowledge */
-} POSTPACK WMIX_GPIO_INTR_ACK_CMD;
-
-/*
- * Target informs Host of GPIO interrupts that have occurred since the
- * last WMIX_GIPO_INTR_ACK_CMD was received.  Additional information --
- * the current GPIO input values is provided -- in order to support
- * use of a GPIO interrupt as a Data Valid signal for other GPIO pins.
- */
-typedef PREPACK struct {
-    u32 intr_mask;            /* pending GPIO interrupts */
-    u32 input_values;         /* recent GPIO input values */
-} POSTPACK WMIX_GPIO_INTR_EVENT;
-
-/*
- * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request
- * using a GPIO_DATA_EVENT with
- *   value set to the mask of GPIO pin inputs and
- *   reg_id set to GPIO_ID_NONE
- * 
- *
- * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request
- * using a GPIO_DATA_EVENT with
- *   value set to the value of the requested register and
- *   reg_id identifying the register (reflects the original request)
- * NB: reg_id supports the future possibility of unsolicited
- * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may
- * simplify Host GPIO support.
- */
-typedef PREPACK struct {
-    u32 value;
-    u32 reg_id;
-} POSTPACK WMIX_GPIO_DATA_EVENT;
-
-/*
- * =============Error Detection support=================
- */
-
-/*
- * WMIX_HB_CHALLENGE_RESP_CMDID
- * Heartbeat Challenge Response command
- */
-typedef PREPACK struct {
-    u32 cookie;
-    u32 source;
-} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD;
-
-/*
- * WMIX_HB_CHALLENGE_RESP_EVENTID
- * Heartbeat Challenge Response Event
- */
-#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD
-
-typedef PREPACK struct {
-    struct dbglog_config_s config;
-} POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD;
-
-/*
- * =============Target Profiling support=================
- */
-
-typedef PREPACK struct {
-    u32 period; /* Time (in 30.5us ticks) between samples */
-    u32 nbins;
-} POSTPACK WMIX_PROF_CFG_CMD;
-
-typedef PREPACK struct {
-    u32 addr;
-} POSTPACK WMIX_PROF_ADDR_SET_CMD;
-
-/*
- * Target responds to Hosts's earlier WMIX_PROF_COUNT_GET_CMDID request
- * using a WMIX_PROF_COUNT_EVENT with
- *   addr set to the next address
- *   count set to the corresponding count
- */
-typedef PREPACK struct {
-    u32 addr;
-    u32 count;
-} POSTPACK WMIX_PROF_COUNT_EVENT;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _WMIX_H_ */
diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h
deleted file mode 100644 (file)
index 34db299..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef COMMON_DRV_H_
-#define COMMON_DRV_H_
-
-#include "hif.h"
-#include "htc_packet.h"
-#include "htc_api.h"
-
-/* structure that is the state information for the default credit distribution callback
- * drivers should instantiate (zero-init as well) this structure in their driver instance
- * and pass it as a context to the HTC credit distribution functions */
-struct common_credit_state_info {
-    int TotalAvailableCredits;      /* total credits in the system at startup */
-    int CurrentFreeCredits;         /* credits available in the pool that have not been
-                                       given out to endpoints */
-    struct htc_endpoint_credit_dist *pLowestPriEpDist;  /* pointer to the lowest priority endpoint dist struct */
-};
-
-struct hci_transport_callbacks {
-    s32 (*setupTransport)(void *ar);
-    void (*cleanupTransport)(void *ar);
-};
-
-struct hci_transport_misc_handles {
-   void *netDevice;
-   void *hifDevice;
-   void *htcHandle;
-};
-
-/* HTC TX packet tagging definitions */
-#define AR6K_CONTROL_PKT_TAG    HTC_TX_PACKET_TAG_USER_DEFINED
-#define AR6K_DATA_PKT_TAG       (AR6K_CONTROL_PKT_TAG + 1)
-
-#define AR6002_VERSION_REV1     0x20000086
-#define AR6002_VERSION_REV2     0x20000188
-#define AR6003_VERSION_REV1     0x300002ba
-#define AR6003_VERSION_REV2     0x30000384
-
-#define AR6002_CUST_DATA_SIZE 112
-#define AR6003_CUST_DATA_SIZE 16
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* OS-independent APIs */
-int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo);
-
-int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
-
-int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
-
-int ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,  u8 *data, u32 length);
-
-int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset);
-
-void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType);
-
-int ar6000_set_htc_params(struct hif_device *hifDevice,
-                               u32 TargetType,
-                               u32 MboxIsrYieldValue,
-                               u8 HtcControlBuffers);
-
-int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
-                                     u32 TargetType,
-                                     u32 Flags);
-
-void ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType);
-
-u8 *ar6000_get_cust_data_buffer(u32 TargetType);
-
-int ar6000_setBTState(void *context, u8 *pInBuf, u32 InBufSize);
-
-int ar6000_setDevicePowerState(void *context, u8 *pInBuf, u32 InBufSize);
-
-int ar6000_setWowMode(void *context, u8 *pInBuf, u32 InBufSize);
-
-int ar6000_setHostMode(void *context, u8 *pInBuf, u32 InBufSize);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*COMMON_DRV_H_*/
diff --git a/drivers/staging/ath6kl/include/dbglog_api.h b/drivers/staging/ath6kl/include/dbglog_api.h
deleted file mode 100644 (file)
index a53aed3..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dbglog_api.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 host side debug primitives.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _DBGLOG_API_H_
-#define _DBGLOG_API_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "dbglog.h"
-
-#define DBGLOG_HOST_LOG_BUFFER_SIZE            DBGLOG_LOG_BUFFER_SIZE
-
-#define DBGLOG_GET_DBGID(arg) \
-    ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET)
-
-#define DBGLOG_GET_MODULEID(arg) \
-    ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET)
-
-#define DBGLOG_GET_NUMARGS(arg) \
-    ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET)
-
-#define DBGLOG_GET_TIMESTAMP(arg) \
-    ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DBGLOG_API_H_ */
diff --git a/drivers/staging/ath6kl/include/dl_list.h b/drivers/staging/ath6kl/include/dl_list.h
deleted file mode 100644 (file)
index 13b1e69..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dl_list.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Double-link list definitions (adapted from Atheros SDIO stack)
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef __DL_LIST_H___
-#define __DL_LIST_H___
-
-#include "a_osapi.h"
-
-#define A_CONTAINING_STRUCT(address, struct_type, field_name)\
-            ((struct_type *)((unsigned long)(address) - (unsigned long)(&((struct_type *)0)->field_name)))
-         
-/* list functions */
-/* pointers for the list */
-struct dl_list {
-       struct dl_list *pPrev;
-       struct dl_list *pNext;
-};
-/*
- * DL_LIST_INIT , initialize doubly linked list
-*/
-#define DL_LIST_INIT(pList)\
-    {(pList)->pPrev = pList; (pList)->pNext = pList;}
-
-/* faster macro to init list and add a single item */    
-#define DL_LIST_INIT_AND_ADD(pList,pItem) \
-{   (pList)->pPrev = (pItem); \
-    (pList)->pNext = (pItem); \
-    (pItem)->pNext = (pList); \
-    (pItem)->pPrev = (pList); \
-}
-    
-#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList)))
-#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext
-#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev
-/*
- * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member
- * NOT: do not use this function if the items in the list are deleted inside the
- * iteration loop
-*/
-#define ITERATE_OVER_LIST(pStart, pTemp) \
-    for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext)
-
-
-/* safe iterate macro that allows the item to be removed from the list
- * the iteration continues to the next item in the list
- */
-#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset)  \
-{                                                       \
-    struct dl_list *  pTemp;                                     \
-    pTemp = (pStart)->pNext;                            \
-    while (pTemp != (pStart)) {                         \
-        (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset);   \
-         pTemp = pTemp->pNext;                          \
-
-#define ITERATE_END }}
-
-/*
- * DL_ListInsertTail - insert pAdd to the end of the list
-*/
-static INLINE struct dl_list *DL_ListInsertTail(struct dl_list *pList, struct dl_list *pAdd) {
-        /* insert at tail */
-    pAdd->pPrev = pList->pPrev;
-    pAdd->pNext = pList;
-    pList->pPrev->pNext = pAdd;
-    pList->pPrev = pAdd;
-    return pAdd;
-}
-
-/*
- * DL_ListInsertHead - insert pAdd into the head of the list
-*/
-static INLINE struct dl_list * DL_ListInsertHead(struct dl_list * pList, struct dl_list * pAdd) {
-        /* insert at head */
-    pAdd->pPrev = pList;
-    pAdd->pNext = pList->pNext;
-    pList->pNext->pPrev = pAdd;
-    pList->pNext = pAdd;
-    return pAdd;
-}
-
-#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem))
-/*
- * DL_ListRemove - remove pDel from list
-*/
-static INLINE struct dl_list * DL_ListRemove(struct dl_list * pDel) {
-    pDel->pNext->pPrev = pDel->pPrev;
-    pDel->pPrev->pNext = pDel->pNext;
-        /* point back to itself just to be safe, incase remove is called again */
-    pDel->pNext = pDel;
-    pDel->pPrev = pDel;
-    return pDel;
-}
-
-/*
- * DL_ListRemoveItemFromHead - get a list item from the head
-*/
-static INLINE struct dl_list * DL_ListRemoveItemFromHead(struct dl_list * pList) {
-    struct dl_list * pItem = NULL;
-    if (pList->pNext != pList) {
-        pItem = pList->pNext;
-            /* remove the first item from head */
-        DL_ListRemove(pItem);
-    }
-    return pItem;
-}
-
-static INLINE struct dl_list * DL_ListRemoveItemFromTail(struct dl_list * pList) {
-    struct dl_list * pItem = NULL;
-    if (pList->pPrev != pList) {
-        pItem = pList->pPrev;
-            /* remove the item from tail */
-        DL_ListRemove(pItem);
-    }
-    return pItem;
-}
-
-/* transfer src list items to the tail of the destination list */
-static INLINE void DL_ListTransferItemsToTail(struct dl_list * pDest, struct dl_list * pSrc) {
-        /* only concatenate if src is not empty */
-    if (!DL_LIST_IS_EMPTY(pSrc)) {
-            /* cut out circular list in src and re-attach to end of dest */
-        pSrc->pPrev->pNext = pDest;
-        pSrc->pNext->pPrev = pDest->pPrev;
-        pDest->pPrev->pNext = pSrc->pNext; 
-        pDest->pPrev = pSrc->pPrev;
-            /* terminate src list, it is now empty */      
-        pSrc->pPrev = pSrc;
-        pSrc->pNext = pSrc;
-    }
-}
-
-#endif /* __DL_LIST_H___ */
diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h
deleted file mode 100644 (file)
index fe901ba..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dset_api.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Host-side DataSet API.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _DSET_API_H_
-#define _DSET_API_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/*
- * Host-side DataSet support is optional, and is not
- * currently required for correct operation.  To disable
- * Host-side DataSet support, set this to 0.
- */
-#ifndef CONFIG_HOST_DSET_SUPPORT
-#define CONFIG_HOST_DSET_SUPPORT 1
-#endif
-
-/* Called to send a DataSet Open Reply back to the Target. */
-int wmi_dset_open_reply(struct wmi_t *wmip,
-                             u32 status,
-                             u32 access_cookie,
-                             u32 size,
-                             u32 version,
-                             u32 targ_handle,
-                             u32 targ_reply_fn,
-                             u32 targ_reply_arg);
-
-/* Called to send a DataSet Data Reply back to the Target. */
-int wmi_dset_data_reply(struct wmi_t *wmip,
-                             u32 status,
-                             u8 *host_buf,
-                             u32 length,
-                             u32 targ_buf,
-                             u32 targ_reply_fn,
-                             u32 targ_reply_arg);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* _DSET_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h
deleted file mode 100644 (file)
index 5e903fa..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HCI_TRANSPORT_API_H_
-#define _HCI_TRANSPORT_API_H_
-
-    /* Bluetooth HCI packets are stored in HTC packet containers */
-#include "htc_packet.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-typedef void *HCI_TRANSPORT_HANDLE;
-
-typedef HTC_ENDPOINT_ID HCI_TRANSPORT_PACKET_TYPE; 
-
-    /* we map each HCI packet class to a static Endpoint ID */
-#define HCI_COMMAND_TYPE   ENDPOINT_1
-#define HCI_EVENT_TYPE     ENDPOINT_2
-#define HCI_ACL_TYPE       ENDPOINT_3
-#define HCI_PACKET_INVALID ENDPOINT_MAX
-
-#define HCI_GET_PACKET_TYPE(pP)    (pP)->Endpoint
-#define HCI_SET_PACKET_TYPE(pP,s)  (pP)->Endpoint = (s)
-
-/* callback when an HCI packet was completely sent */
-typedef void   (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, struct htc_packet *);
-/* callback when an HCI packet is received */
-typedef void   (*HCI_TRANSPORT_RECV_PKT)(void *, struct htc_packet *);
-/* Optional receive buffer re-fill callback,
- * On some OSes (like Linux) packets are allocated from a global pool and indicated up
- * to the network stack.  The driver never gets the packets back from the OS.  For these OSes
- * a refill callback can be used to allocate and re-queue buffers into HTC.
- * A refill callback is used for the reception of ACL and EVENT packets.  The caller must
- * set the watermark trigger point to cause a refill.
- */
-typedef void   (*HCI_TRANSPORT_RECV_REFILL)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable);
-/* Optional receive packet refill
- * On some systems packet buffers are an extremely limited resource.  Rather than
- * queue largest-possible-sized buffers to the HCI bridge, some systems would rather
- * allocate a specific size as the packet is received.  The trade off is
- * slightly more processing (callback invoked for each RX packet)
- * for the benefit of committing fewer buffer resources into the bridge.
- *
- * The callback is provided the length of the pending packet to fetch. This includes the
- * full transport header, HCI header, plus the length of payload.  The callback can return a pointer to
- * the allocated HTC packet for immediate use.
- *
- * NOTE*** This callback is mutually exclusive with the the refill callback above.
- *
- * */
-typedef struct htc_packet *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length);
-
-typedef enum _HCI_SEND_FULL_ACTION {
-    HCI_SEND_FULL_KEEP = 0,  /* packet that overflowed should be kept in the queue */
-    HCI_SEND_FULL_DROP = 1,  /* packet that overflowed should be dropped */
-} HCI_SEND_FULL_ACTION;
-
-/* callback when an HCI send queue exceeds the caller's MaxSendQueueDepth threshold,
- * the callback must return the send full action to take (either DROP or KEEP) */
-typedef HCI_SEND_FULL_ACTION  (*HCI_TRANSPORT_SEND_FULL)(void *, struct htc_packet *);
-
-struct hci_transport_properties {
-    int    HeadRoom;      /* number of bytes in front of HCI packet for header space */
-    int    TailRoom;      /* number of bytes at the end of the HCI packet for tail space */
-    int    IOBlockPad;    /* I/O block padding required (always a power of 2) */
-};
-
-struct hci_transport_config_info {
-    int      ACLRecvBufferWaterMark;     /* low watermark to trigger recv refill */
-    int      EventRecvBufferWaterMark;   /* low watermark to trigger recv refill */  
-    int      MaxSendQueueDepth;          /* max number of packets in the single send queue */
-    void     *pContext;                  /* context for all callbacks */
-    void     (*TransportFailure)(void *pContext, int Status); /* transport failure callback */
-    int (*TransportReady)(HCI_TRANSPORT_HANDLE, struct hci_transport_properties *,void *pContext); /* transport is ready */
-    void     (*TransportRemoved)(void *pContext);                  /* transport was removed */
-        /* packet processing callbacks */
-    HCI_TRANSPORT_SEND_PKT_COMPLETE    pHCISendComplete;
-    HCI_TRANSPORT_RECV_PKT             pHCIPktRecv;
-    HCI_TRANSPORT_RECV_REFILL          pHCIPktRecvRefill;
-    HCI_TRANSPORT_RECV_ALLOC           pHCIPktRecvAlloc;
-    HCI_TRANSPORT_SEND_FULL            pHCISendFull;
-};
-
-/* ------ Function Prototypes ------ */
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Attach to the HCI transport module
-  @function name: HCI_TransportAttach
-  @input:  HTCHandle - HTC handle (see HTC apis)
-           pInfo - initialization information
-  @output:
-  @return: HCI_TRANSPORT_HANDLE on success, NULL on failure
-  @notes:    The HTC module provides HCI transport services.
-  @example:
-  @see also: HCI_TransportDetach
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Detach from the HCI transport module
-  @function name: HCI_TransportDetach
-  @input:  HciTrans - HCI transport handle
-           pInfo - initialization information
-  @output:
-  @return: 
-  @notes:  
-  @example:
-  @see also: 
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Add receive packets to the HCI transport
-  @function name: HCI_TransportAddReceivePkts
-  @input:  HciTrans - HCI transport handle
-           pQueue - a queue holding one or more packets
-  @output:
-  @return: 0 on success
-  @notes:  user must supply HTC packets for capturing incomming HCI packets.  The caller
-           must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
-           macro. Each packet in the queue must be of the same type and length 
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Send an HCI packet packet
-  @function name: HCI_TransportSendPkt
-  @input:  HciTrans - HCI transport handle
-           pPacket - packet to send
-           Synchronous - send the packet synchronously (blocking)
-  @output:
-  @return: 0
-  @notes:  Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and
-           HCI_SET_PACKET_TYPE() macros to prepare the packet. 
-           If Synchronous is set to false the call is fully asynchronous.  On error or completion,
-           the registered send complete callback will be called.
-           If Synchronous is set to true, the call will block until the packet is sent, if the
-           interface cannot send the packet within a 2 second timeout, the function will return 
-           the failure code : A_EBUSY.
-           
-           Synchronous Mode should only be used at start-up to initialize the HCI device using 
-           custom HCI commands.  It should NOT be mixed with Asynchronous operations.  Mixed synchronous
-           and asynchronous operation behavior is undefined.
-           
-  @example:
-  @see also: 
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
-
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Stop HCI transport
-  @function name: HCI_TransportStop
-  @input:  HciTrans - hci transport handle 
-  @output:
-  @return:
-  @notes: HCI transport communication will be halted.  All receive and pending TX packets will
-          be flushed.
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Start the HCI transport
-  @function name: HCI_TransportStart
-  @input:  HciTrans - hci transport handle 
-  @output:
-  @return: 0 on success
-  @notes: HCI transport communication will begin, the caller can expect the arrival
-          of HCI recv packets as soon as this call returns.
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Enable or Disable Asynchronous Recv
-  @function name: HCI_TransportEnableDisableAsyncRecv
-  @input:  HciTrans - hci transport handle 
-           Enable - enable or disable asynchronous recv
-  @output:
-  @return: 0 on success
-  @notes: This API must be called when HCI recv is handled synchronously
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Receive an event packet from the HCI transport synchronously using polling
-  @function name: HCI_TransportRecvHCIEventSync
-  @input:  HciTrans - hci transport handle 
-           pPacket - HTC packet to hold the recv data
-           MaxPollMS - maximum polling duration in Milliseconds;
-  @output: 
-  @return: 0 on success
-  @notes: This API should be used only during HCI device initialization, the caller must call
-          HCI_TransportEnableDisableAsyncRecv with Enable=false prior to using this API.
-          This API will only capture HCI Event packets.
-  @example:
-  @see also: HCI_TransportEnableDisableAsyncRecv
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
-                                          struct htc_packet           *pPacket,
-                                          int                  MaxPollMS);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Set the desired baud rate for the underlying transport layer
-  @function name: HCI_TransportSetBaudRate
-  @input:  HciTrans - hci transport handle 
-           Baud - baud rate in bps
-  @output: 
-  @return: 0 on success
-  @notes: This API should be used only after HCI device initialization
-  @example:
-  @see also: 
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Enable/Disable HCI Transport Power Management
-  @function name: HCI_TransportEnablePowerMgmt
-  @input:  HciTrans - hci transport handle 
-           Enable - 1 = Enable, 0 = Disable
-  @output: 
-  @return: 0 on success
-  @notes: 
-  @example:
-  @see also: 
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HCI_TRANSPORT_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h
deleted file mode 100644 (file)
index 24200e7..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="hif.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// HIF specific declarations and prototypes
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HIF_H_
-#define _HIF_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Header files */
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#include "dl_list.h"
-
-
-typedef struct htc_callbacks HTC_CALLBACKS;
-struct hif_device;
-
-/*
- * direction - Direction of transfer (HIF_READ/HIF_WRITE).
- */
-#define HIF_READ                    0x00000001
-#define HIF_WRITE                   0x00000002
-#define HIF_DIR_MASK                (HIF_READ | HIF_WRITE)
-
-/*
- *     type - An interface may support different kind of read/write commands.
- *            For example: SDIO supports CMD52/CMD53s. In case of MSIO it
- *            translates to using different kinds of TPCs. The command type
- *            is thus divided into a basic and an extended command and can
- *            be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
- */
-#define HIF_BASIC_IO                0x00000004
-#define HIF_EXTENDED_IO             0x00000008
-#define HIF_TYPE_MASK               (HIF_BASIC_IO | HIF_EXTENDED_IO)
-
-/*
- *     emode - This indicates the whether the command is to be executed in a
- *             blocking or non-blocking fashion (HIF_SYNCHRONOUS/
- *             HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
- *             implemented using the asynchronous mode allowing the the bus
- *             driver to indicate the completion of operation through the
- *             registered callback routine. The requirement primarily comes
- *             from the contexts these operations get called from (a driver's
- *             transmit context or the ISR context in case of receive).
- *             Support for both of these modes is essential.
- */
-#define HIF_SYNCHRONOUS             0x00000010
-#define HIF_ASYNCHRONOUS            0x00000020
-#define HIF_EMODE_MASK              (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
-
-/*
- *     dmode - An interface may support different kinds of commands based on
- *             the tradeoff between the amount of data it can carry and the
- *             setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
- *             HIF_BLOCK_BASIS). In case of latter, the data is rounded off
- *             to the nearest block size by padding. The size of the block is
- *             configurable at compile time using the HIF_BLOCK_SIZE and is
- *             negotiated with the target during initialization after the
- *             AR6000 interrupts are enabled.
- */
-#define HIF_BYTE_BASIS              0x00000040
-#define HIF_BLOCK_BASIS             0x00000080
-#define HIF_DMODE_MASK              (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
-
-/*
- *     amode - This indicates if the address has to be incremented on AR6000 
- *             after every read/write operation (HIF?FIXED_ADDRESS/
- *             HIF_INCREMENTAL_ADDRESS).
- */
-#define HIF_FIXED_ADDRESS           0x00000100
-#define HIF_INCREMENTAL_ADDRESS     0x00000200
-#define HIF_AMODE_MASK              (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_WR_ASYNC_BYTE_FIX   \
-    (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_WR_ASYNC_BYTE_INC   \
-    (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_WR_ASYNC_BLOCK_INC  \
-    (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_WR_SYNC_BYTE_FIX    \
-    (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_WR_SYNC_BYTE_INC    \
-    (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_WR_SYNC_BLOCK_INC  \
-    (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_WR_ASYNC_BLOCK_FIX \
-    (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_WR_SYNC_BLOCK_FIX  \
-    (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_RD_SYNC_BYTE_INC    \
-    (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_RD_SYNC_BYTE_FIX    \
-    (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_RD_ASYNC_BYTE_FIX   \
-    (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_RD_ASYNC_BLOCK_FIX  \
-    (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
-#define HIF_RD_ASYNC_BYTE_INC   \
-    (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_RD_ASYNC_BLOCK_INC  \
-    (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_RD_SYNC_BLOCK_INC  \
-    (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
-#define HIF_RD_SYNC_BLOCK_FIX  \
-    (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
-    
-typedef enum {
-    HIF_DEVICE_POWER_STATE = 0,
-    HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
-    HIF_DEVICE_GET_MBOX_ADDR,
-    HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
-    HIF_DEVICE_GET_IRQ_PROC_MODE,
-    HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
-    HIF_DEVICE_POWER_STATE_CHANGE,
-    HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
-    HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
-    HIF_DEVICE_GET_OS_DEVICE,
-    HIF_DEVICE_DEBUG_BUS_STATE,
-} HIF_DEVICE_CONFIG_OPCODE;
-
-/*
- * HIF CONFIGURE definitions:
- *
- *   HIF_DEVICE_GET_MBOX_BLOCK_SIZE
- *   input : none
- *   output : array of 4 u32s
- *   notes: block size is returned for each mailbox (4)
- *
- *   HIF_DEVICE_GET_MBOX_ADDR
- *   input : none
- *   output : struct hif_device_mbox_info
- *   notes: 
- *
- *   HIF_DEVICE_GET_PENDING_EVENTS_FUNC
- *   input : none
- *   output: HIF_PENDING_EVENTS_FUNC function pointer
- *   notes: this is optional for the HIF layer, if the request is
- *          not handled then it indicates that the upper layer can use
- *          the standard device methods to get pending events (IRQs, mailbox messages etc..)
- *          otherwise it can call the function pointer to check pending events.
- *
- *   HIF_DEVICE_GET_IRQ_PROC_MODE
- *   input : none
- *   output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode)
- *   note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF
- *         layer can report whether IRQ processing is requires synchronous behavior or
- *         can be processed using asynchronous bus requests (typically faster).
- *
- *   HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
- *   input :
- *   output : HIF_MASK_UNMASK_RECV_EVENT function pointer
- *   notes: this is optional for the HIF layer.  The HIF layer may require a special mechanism
- *          to mask receive message events.  The upper layer can call this pointer when it needs
- *          to mask/unmask receive events (in case it runs out of buffers).
- *
- *   HIF_DEVICE_POWER_STATE_CHANGE
- *
- *   input : HIF_DEVICE_POWER_CHANGE_TYPE
- *   output : none
- *   note: this is optional for the HIF layer.  The HIF layer can handle power on/off state change
- *         requests in an interconnect specific way.  This is highly OS and bus driver dependent.
- *         The caller must guarantee that no HIF read/write requests will be made after the device
- *         is powered down.
- *
- *   HIF_DEVICE_GET_IRQ_YIELD_PARAMS
- * 
- *   input : none
- *   output : struct hif_device_irq_yield_params
- *   note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler.
- *   The DSR callback handler will exit after a fixed number of RX packets or events are processed.  
- *   This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY. 
- *   The HIF implementation can ignore this command if it does not desire the DSR callback to yield.
- *   The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the
- *   DSR handler callback must yield and return control back to the HIF layer.  When a yield limit is 
- *   used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning.  
- *   The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared
- *   to process interrupts again.
- *   
- *   HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
- *   input : none
- *   output : struct hif_device_scatter_support_info
- *   note:  This query checks if the HIF layer implements the SCATTER request interface.  Scatter requests
- *   allows upper layers to submit mailbox I/O operations using a list of buffers.  This is useful for
- *   multi-message transfers that can better utilize the bus interconnect.
- * 
- * 
- *   HIF_DEVICE_GET_OS_DEVICE
- *   intput : none
- *   output : struct hif_device_os_device_info;
- *   note: On some operating systems, the HIF layer has a parent device object for the bus.  This object
- *         may be required to register certain types of logical devices.
- * 
- *   HIF_DEVICE_DEBUG_BUS_STATE
- *   input : none
- *   output : none
- *   note: This configure option triggers the HIF interface to dump as much bus interface state.  This 
- *   configuration request is optional (No-OP on some HIF implementations)
- * 
- */
-
-struct hif_mbox_properties {
-    u32 ExtendedAddress;  /* extended address for larger writes */
-    u32 ExtendedSize;
-};
-
-#define HIF_MBOX_FLAG_NO_BUNDLING   (1 << 0)   /* do not allow bundling over the mailbox */
-
-typedef enum _MBOX_BUF_IF_TYPE {
-    MBOX_BUS_IF_SDIO = 0,
-    MBOX_BUS_IF_SPI = 1,    
-} MBOX_BUF_IF_TYPE;
-
-struct hif_device_mbox_info {
-    u32 MboxAddresses[4];  /* must be first element for legacy HIFs that return the address in
-                                   and ARRAY of 32-bit words */
-    
-        /* the following describe extended mailbox properties */
-    struct hif_mbox_properties MboxProp[4];
-        /* if the HIF supports the GMbox extended address region it can report it
-         * here, some interfaces cannot support the GMBOX address range and not set this */
-    u32 GMboxAddress;
-    u32 GMboxSize;
-    u32 Flags;             /* flags to describe mbox behavior or usage */
-    MBOX_BUF_IF_TYPE MboxBusIFType;   /* mailbox bus interface type */
-};
-
-typedef enum {
-    HIF_DEVICE_IRQ_SYNC_ONLY,   /* for HIF implementations that require the DSR to process all
-                                   interrupts before returning */
-    HIF_DEVICE_IRQ_ASYNC_SYNC,  /* for HIF implementations that allow DSR to process interrupts
-                                   using ASYNC I/O (that is HIFAckInterrupt can be called at a
-                                   later time */
-} HIF_DEVICE_IRQ_PROCESSING_MODE;
-
-typedef enum {
-    HIF_DEVICE_POWER_UP,    /* HIF layer should power up interface and/or module */
-    HIF_DEVICE_POWER_DOWN,  /* HIF layer should initiate bus-specific measures to minimize power */
-    HIF_DEVICE_POWER_CUT    /* HIF layer should initiate bus-specific AND/OR platform-specific measures
-                               to completely power-off the module and associated hardware (i.e. cut power supplies)
-                            */
-} HIF_DEVICE_POWER_CHANGE_TYPE;
-
-struct hif_device_irq_yield_params {
-    int     RecvPacketYieldCount; /* max number of packets to force DSR to return */
-};
-
-
-struct hif_scatter_item {
-    u8 *pBuffer;             /* CPU accessible address of buffer */
-    int          Length;              /* length of transfer to/from this buffer */
-    void        *pCallerContexts[2];  /* space for caller to insert a context associated with this item */
-};
-
-struct hif_scatter_req;
-typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *);
-
-typedef enum _HIF_SCATTER_METHOD {
-    HIF_SCATTER_NONE = 0,
-    HIF_SCATTER_DMA_REAL,              /* Real SG support no restrictions */
-    HIF_SCATTER_DMA_BOUNCE,            /* Uses SG DMA but HIF layer uses an internal bounce buffer */    
-} HIF_SCATTER_METHOD;
-
-struct hif_scatter_req {
-    struct dl_list             ListLink;           /* link management */
-    u32 Address;            /* address for the read/write operation */
-    u32 Request;            /* request flags */
-    u32 TotalLength;        /* total length of entire transfer */
-    u32 CallerFlags;        /* caller specific flags can be stored here */
-    HIF_SCATTER_COMP_CB CompletionRoutine;  /* completion routine set by caller */
-    int            CompletionStatus;   /* status of completion */
-    void                *Context;           /* caller context for this request */
-    int                 ValidScatterEntries;  /* number of valid entries set by caller */
-    HIF_SCATTER_METHOD  ScatterMethod;        /* scatter method handled by HIF */  
-    void                *HIFPrivate[4];     /* HIF private area */
-    u8 *pScatterBounceBuffer;  /* bounce buffer for upper layers to copy to/from */
-    struct hif_scatter_item    ScatterList[1];     /* start of scatter list */
-};
-
-typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(struct hif_device *device);
-typedef void ( *HIF_FREE_SCATTER_REQUEST)(struct hif_device *device, struct hif_scatter_req *request);
-typedef int ( *HIF_READWRITE_SCATTER)(struct hif_device *device, struct hif_scatter_req *request);
-
-struct hif_device_scatter_support_info {
-        /* information returned from HIF layer */
-    HIF_ALLOCATE_SCATTER_REQUEST    pAllocateReqFunc;
-    HIF_FREE_SCATTER_REQUEST        pFreeReqFunc;
-    HIF_READWRITE_SCATTER           pReadWriteScatterFunc;    
-    int                             MaxScatterEntries;
-    int                             MaxTransferSizePerScatterReq;
-};
-                      
-struct hif_device_os_device_info {
-    void    *pOSDevice;
-};
-                      
-#define HIF_MAX_DEVICES                 1
-
-struct htc_callbacks {
-    void      *context;     /* context to pass to the dsrhandler
-                               note : rwCompletionHandler is provided the context passed to HIFReadWrite  */
-    int (* rwCompletionHandler)(void *rwContext, int status);
-    int (* dsrHandler)(void *context);
-};
-
-typedef struct osdrv_callbacks {
-    void      *context;     /* context to pass for all callbacks except deviceRemovedHandler 
-                               the deviceRemovedHandler is only called if the device is claimed */
-    int (* deviceInsertedHandler)(void *context, void *hif_handle);
-    int (* deviceRemovedHandler)(void *claimedContext, void *hif_handle);
-    int (* deviceSuspendHandler)(void *context);
-    int (* deviceResumeHandler)(void *context);
-    int (* deviceWakeupHandler)(void *context);
-    int (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config);
-} OSDRV_CALLBACKS;
-
-#define HIF_OTHER_EVENTS     (1 << 0)   /* other interrupts (non-Recv) are pending, host
-                                           needs to read the register table to figure out what */
-#define HIF_RECV_MSG_AVAIL   (1 << 1)   /* pending recv packet */
-
-struct hif_pending_events_info {
-    u32 Events;
-    u32 LookAhead;
-    u32 AvailableRecvBytes;
-#ifdef THREAD_X
-    u32 Polling;
-    u32 INT_CAUSE_REG;
-#endif
-};
-
-    /* function to get pending events , some HIF modules use special mechanisms
-     * to detect packet available and other interrupts */
-typedef int ( *HIF_PENDING_EVENTS_FUNC)(struct hif_device              *device,
-                                             struct hif_pending_events_info *pEvents,
-                                             void                    *AsyncContext);
-
-#define HIF_MASK_RECV    true
-#define HIF_UNMASK_RECV  false
-    /* function to mask recv events */
-typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(struct hif_device  *device,
-                                                bool      Mask,
-                                                void        *AsyncContext);
-
-
-/*
- * This API is used to perform any global initialization of the HIF layer
- * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
- * 
- */
-int HIFInit(OSDRV_CALLBACKS *callbacks);
-
-/* This API claims the HIF device and provides a context for handling removal.
- * The device removal callback is only called when the OSDRV layer claims
- * a device.  The claimed context must be non-NULL */
-void HIFClaimDevice(struct hif_device *device, void *claimedContext);
-/* release the claimed device */
-void HIFReleaseDevice(struct hif_device *device);
-
-/* This API allows the HTC layer to attach to the HIF device */
-int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks);
-/* This API detaches the HTC layer from the HIF device */
-void     HIFDetachHTC(struct hif_device *device);
-
-/*
- * This API is used to provide the read/write interface over the specific bus
- * interface.
- * address - Starting address in the AR6000's address space. For mailbox
- *           writes, it refers to the start of the mbox boundary. It should
- *           be ensured that the last byte falls on the mailbox's EOM. For
- *           mailbox reads, it refers to the end of the mbox boundary.
- * buffer - Pointer to the buffer containg the data to be transmitted or
- *          received.
- * length - Amount of data to be transmitted or received.
- * request - Characterizes the attributes of the command.
- */
-int
-HIFReadWrite(struct hif_device    *device,
-             u32 address,
-             u8       *buffer,
-             u32 length,
-             u32 request,
-             void          *context);
-
-/*
- * This can be initiated from the unload driver context when the OSDRV layer has no more use for
- * the device.
- */
-void HIFShutDownDevice(struct hif_device *device);
-
-/*
- * This should translate to an acknowledgment to the bus driver indicating that
- * the previous interrupt request has been serviced and the all the relevant
- * sources have been cleared. HTC is ready to process more interrupts.
- * This should prevent the bus driver from raising an interrupt unless the
- * previous one has been serviced and acknowledged using the previous API.
- */
-void HIFAckInterrupt(struct hif_device *device);
-
-void HIFMaskInterrupt(struct hif_device *device);
-
-void HIFUnMaskInterrupt(struct hif_device *device);
-#ifdef THREAD_X
-/*
- * This set of functions are to be used by the bus driver to notify
- * the HIF module about various events.
- * These are not implemented if the bus driver provides an alternative
- * way for this notification though callbacks for instance.
- */
-int HIFInsertEventNotify(void);
-
-int HIFRemoveEventNotify(void);
-
-int HIFIRQEventNotify(void);
-
-int HIFRWCompleteEventNotify(void);
-#endif
-
-int
-HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode,
-                   void *config, u32 configLen);
-
-/* 
- * This API wait for the remaining MBOX messages to be drained
- * This should be moved to HTC AR6K layer
- */
-int hifWaitForPendingRecv(struct hif_device *device);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HIF_H_ */
diff --git a/drivers/staging/ath6kl/include/host_version.h b/drivers/staging/ath6kl/include/host_version.h
deleted file mode 100644 (file)
index 74f1982..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="host_version.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 version information for the sample host driver for the
-// AR6000 chip
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HOST_VERSION_H_
-#define _HOST_VERSION_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <AR6002/AR6K_version.h>
-
-/*
- * The version number is made up of major, minor, patch and build
- * numbers. These are 16 bit numbers.  The build and release script will
- * set the build number using a Perforce counter.  Here the build number is
- * set to 9999 so that builds done without the build-release script are easily
- * identifiable.
- */
-
-#define ATH_SW_VER_MAJOR      __VER_MAJOR_
-#define ATH_SW_VER_MINOR      __VER_MINOR_
-#define ATH_SW_VER_PATCH      __VER_PATCH_
-#define ATH_SW_VER_BUILD      __BUILD_NUMBER_ 
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HOST_VERSION_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h
deleted file mode 100644 (file)
index 4fb7675..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_api.h" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HTC_API_H_
-#define _HTC_API_H_
-
-#include "htc_packet.h"
-#include <htc.h>
-#include <htc_services.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* TODO.. for BMI */
-#define ENDPOINT1 0
-// TODO -remove me, but we have to fix BMI first
-#define HTC_MAILBOX_NUM_MAX    4
-
-/* this is the amount of header room required by users of HTC */
-#define HTC_HEADER_LEN         HTC_HDR_LENGTH
-
-typedef void *HTC_HANDLE;
-
-typedef u16 HTC_SERVICE_ID;
-
-struct htc_init_info {
-    void   *pContext;           /* context for target failure notification */
-    void   (*TargetFailure)(void *Instance, int Status);
-};
-
-/* per service connection send completion */
-typedef void   (*HTC_EP_SEND_PKT_COMPLETE)(void *,struct htc_packet *);
-/* per service connection callback when a plurality of packets have been sent
- * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback)
- * to hold a list of completed send packets.
- * If the handler cannot fully traverse the packet queue before returning, it should
- * transfer the items of the queue into the caller's private queue using:
- *   HTC_PACKET_ENQUEUE() */
-typedef void   (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,struct htc_packet_queue *);
-/* per service connection pkt received */
-typedef void   (*HTC_EP_RECV_PKT)(void *,struct htc_packet *);
-/* per service connection callback when a plurality of packets are received
- * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback)
- * to hold a list of recv packets.
- * If the handler cannot fully traverse the packet queue before returning, it should
- * transfer the items of the queue into the caller's private queue using:
- *   HTC_PACKET_ENQUEUE() */
-typedef void   (*HTC_EP_RECV_PKT_MULTIPLE)(void *,struct htc_packet_queue *);
-
-/* Optional per service connection receive buffer re-fill callback,
- * On some OSes (like Linux) packets are allocated from a global pool and indicated up
- * to the network stack.  The driver never gets the packets back from the OS.  For these OSes
- * a refill callback can be used to allocate and re-queue buffers into HTC.
- *
- * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and
- * the driver can re-queue these buffers into HTC. In this regard a refill callback is
- * unnecessary */
-typedef void   (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint);
-
-/* Optional per service connection receive buffer allocation callback.
- * On some systems packet buffers are an extremely limited resource.  Rather than
- * queue largest-possible-sized buffers to HTC, some systems would rather
- * allocate a specific size as the packet is received.  The trade off is
- * slightly more processing (callback invoked for each RX packet)
- * for the benefit of committing fewer buffer resources into HTC.
- *
- * The callback is provided the length of the pending packet to fetch. This includes the
- * HTC header length plus the length of payload.  The callback can return a pointer to
- * the allocated HTC packet for immediate use.
- *
- * Alternatively a variant of this handler can be used to allocate large receive packets as needed.  
- * For example an application can use the refill mechanism for normal packets and the recv-alloc mechanism to 
- * handle the case where a large packet buffer is required.  This can significantly reduce the
- * amount of "committed" memory used to receive packets.
- *  
- * */
-typedef struct htc_packet *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length);
-
-typedef enum _HTC_SEND_FULL_ACTION {
-    HTC_SEND_FULL_KEEP = 0,  /* packet that overflowed should be kept in the queue */
-    HTC_SEND_FULL_DROP = 1,  /* packet that overflowed should be dropped */
-} HTC_SEND_FULL_ACTION;
-
-/* Optional per service connection callback when a send queue is full. This can occur if the
- * host continues queueing up TX packets faster than credits can arrive
- * To prevent the host (on some Oses like Linux) from continuously queueing packets
- * and consuming resources, this callback is provided so that that the host
- * can disable TX in the subsystem (i.e. network stack).
- * This callback is invoked for each packet that "overflows" the HTC queue. The callback can
- * determine whether the new packet that overflowed the queue can be kept (HTC_SEND_FULL_KEEP) or
- * dropped (HTC_SEND_FULL_DROP).  If a packet is dropped, the EpTxComplete handler will be called
- * and the packet's status field will be set to A_NO_RESOURCE.
- * Other OSes require a "per-packet" indication for each completed TX packet, this
- * closed loop mechanism will prevent the network stack from overunning the NIC
- * The packet to keep or drop is passed for inspection to the registered handler the handler
- * must ONLY inspect the packet, it may not free or reclaim the packet. */
-typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, struct htc_packet *pPacket);
-
-struct htc_ep_callbacks {
-    void                     *pContext;     /* context for each callback */
-    HTC_EP_SEND_PKT_COMPLETE EpTxComplete;  /* tx completion callback for connected endpoint */
-    HTC_EP_RECV_PKT          EpRecv;        /* receive callback for connected endpoint */
-    HTC_EP_RECV_REFILL       EpRecvRefill;  /* OPTIONAL receive re-fill callback for connected endpoint */
-    HTC_EP_SEND_QUEUE_FULL   EpSendFull;    /* OPTIONAL send full callback */
-    HTC_EP_RECV_ALLOC        EpRecvAlloc;   /* OPTIONAL recv allocation callback */
-    HTC_EP_RECV_ALLOC        EpRecvAllocThresh;  /* OPTIONAL recv allocation callback based on a threshold */
-    HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; /* OPTIONAL completion handler for multiple complete
-                                                             indications (EpTxComplete must be NULL) */
-    HTC_EP_RECV_PKT_MULTIPLE      EpRecvPktMultiple;      /* OPTIONAL completion handler for multiple
-                                                             recv packet indications (EpRecv must be NULL) */           
-    int                      RecvAllocThreshold;    /* if EpRecvAllocThresh is non-NULL, HTC will compare the 
-                                                       threshold value to the current recv packet length and invoke
-                                                       the EpRecvAllocThresh callback to acquire a packet buffer */
-    int                      RecvRefillWaterMark;   /* if a EpRecvRefill handler is provided, this value
-                                                       can be used to set a trigger refill callback 
-                                                       when the recv queue drops below this value 
-                                                       if set to 0, the refill is only called when packets 
-                                                       are empty */
-};
-
-/* service connection information */
-struct htc_service_connect_req {
-    HTC_SERVICE_ID   ServiceID;                 /* service ID to connect to */
-    u16 ConnectionFlags;           /* connection flags, see htc protocol definition */
-    u8 *pMetaData;                 /* ptr to optional service-specific meta-data */
-    u8 MetaDataLength;            /* optional meta data length */
-    struct htc_ep_callbacks EpCallbacks;               /* endpoint callbacks */
-    int              MaxSendQueueDepth;         /* maximum depth of any send queue */
-    u32 LocalConnectionFlags;      /* HTC flags for the host-side (local) connection */
-    unsigned int     MaxSendMsgSize;            /* override max message size in send direction */
-};
-
-#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0)  /* enable send bundle padding for this endpoint */
-
-/* service connection response information */
-struct htc_service_connect_resp {
-    u8 *pMetaData;         /* caller supplied buffer to optional meta-data */
-    u8 BufferLength;       /* length of caller supplied buffer */
-    u8 ActualLength;       /* actual length of meta data */
-    HTC_ENDPOINT_ID Endpoint;           /* endpoint to communicate over */
-    unsigned int    MaxMsgLength;       /* max length of all messages over this endpoint */
-    u8 ConnectRespCode;    /* connect response code from target */
-};
-
-/* endpoint distribution structure */
-struct htc_endpoint_credit_dist {
-    struct htc_endpoint_credit_dist *pNext;
-    struct htc_endpoint_credit_dist *pPrev;
-    HTC_SERVICE_ID      ServiceID;          /* Service ID (set by HTC) */
-    HTC_ENDPOINT_ID     Endpoint;           /* endpoint for this distribution struct (set by HTC) */
-    u32 DistFlags;          /* distribution flags, distribution function can
-                                               set default activity using SET_EP_ACTIVE() macro */
-    int                 TxCreditsNorm;      /* credits for normal operation, anything above this
-                                               indicates the endpoint is over-subscribed, this field
-                                               is only relevant to the credit distribution function */
-    int                 TxCreditsMin;       /* floor for credit distribution, this field is
-                                               only relevant to the credit distribution function */
-    int                 TxCreditsAssigned;  /* number of credits assigned to this EP, this field
-                                               is only relevant to the credit dist function */
-    int                 TxCredits;          /* current credits available, this field is used by
-                                               HTC to determine whether a message can be sent or
-                                               must be queued */
-    int                 TxCreditsToDist;    /* pending credits to distribute on this endpoint, this
-                                               is set by HTC when credit reports arrive.
-                                               The credit distribution functions sets this to zero
-                                               when it distributes the credits */
-    int                 TxCreditsSeek;      /* this is the number of credits that the current pending TX
-                                               packet needs to transmit.  This is set by HTC when
-                                               and endpoint needs credits in order to transmit */
-    int                 TxCreditSize;       /* size in bytes of each credit (set by HTC) */
-    int                 TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */
-    void                *pHTCReserved;      /* reserved for HTC use */    
-    int                 TxQueueDepth;       /* current depth of TX queue , i.e. messages waiting for credits
-                                               This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
-                                               or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
-                                               that has non-zero credits to recover
-                                              */
-};
-
-#define HTC_EP_ACTIVE                            ((u32) (1u << 31))
-
-/* macro to check if an endpoint has gone active, useful for credit
- * distributions */
-#define IS_EP_ACTIVE(epDist)  ((epDist)->DistFlags & HTC_EP_ACTIVE)
-#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE
-
-    /* credit distibution code that is passed into the distrbution function,
-     * there are mandatory and optional codes that must be handled */
-typedef enum _HTC_CREDIT_DIST_REASON {
-    HTC_CREDIT_DIST_SEND_COMPLETE = 0,     /* credits available as a result of completed
-                                              send operations (MANDATORY) resulting in credit reports */
-    HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1,   /* a change in endpoint activity occurred (OPTIONAL) */
-    HTC_CREDIT_DIST_SEEK_CREDITS,          /* an endpoint needs to "seek" credits (OPTIONAL) */
-    HTC_DUMP_CREDIT_STATE                  /* for debugging, dump any state information that is kept by
-                                              the distribution function */
-} HTC_CREDIT_DIST_REASON;
-
-typedef void (*HTC_CREDIT_DIST_CALLBACK)(void                     *Context,
-                                         struct htc_endpoint_credit_dist *pEPList,
-                                         HTC_CREDIT_DIST_REASON   Reason);
-
-typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context,
-                                         struct htc_endpoint_credit_dist *pEPList,
-                                         int                      TotalCredits);
-
-    /* endpoint statistics action */
-typedef enum _HTC_ENDPOINT_STAT_ACTION {
-    HTC_EP_STAT_SAMPLE = 0,                /* only read statistics */
-    HTC_EP_STAT_SAMPLE_AND_CLEAR = 1,      /* sample and immediately clear statistics */
-    HTC_EP_STAT_CLEAR                      /* clear only */
-} HTC_ENDPOINT_STAT_ACTION;
-
-    /* endpoint statistics */
-struct htc_endpoint_stats {
-    u32 TxCreditLowIndications;  /* number of times the host set the credit-low flag in a send message on
-                                        this endpoint */
-    u32 TxIssued;               /* running count of total TX packets issued */
-    u32 TxPacketsBundled;       /* running count of TX packets that were issued in bundles */
-    u32 TxBundles;              /* running count of TX bundles that were issued */
-    u32 TxDropped;              /* tx packets that were dropped */
-    u32 TxCreditRpts;           /* running count of total credit reports received for this endpoint */
-    u32 TxCreditRptsFromRx;     /* credit reports received from this endpoint's RX packets */
-    u32 TxCreditRptsFromOther;  /* credit reports received from RX packets of other endpoints */
-    u32 TxCreditRptsFromEp0;    /* credit reports received from endpoint 0 RX packets */
-    u32 TxCreditsFromRx;        /* count of credits received via Rx packets on this endpoint */
-    u32 TxCreditsFromOther;     /* count of credits received via another endpoint */
-    u32 TxCreditsFromEp0;       /* count of credits received via another endpoint */
-    u32 TxCreditsConsummed;     /* count of consummed credits */
-    u32 TxCreditsReturned;      /* count of credits returned */
-    u32 RxReceived;             /* count of RX packets received */
-    u32 RxLookAheads;           /* count of lookahead records
-                                         found in messages received on this endpoint */
-    u32 RxPacketsBundled;       /* count of recv packets received in a bundle */
-    u32 RxBundleLookAheads;     /* count of number of bundled lookaheads */
-    u32 RxBundleIndFromHdr;     /* count of the number of bundle indications from the HTC header */
-    u32 RxAllocThreshHit;       /* count of the number of times the recv allocation threshold was hit */
-    u32 RxAllocThreshBytes;     /* total number of bytes */
-};
-
-/* ------ Function Prototypes ------ */
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Create an instance of HTC over the underlying HIF device
-  @function name: HTCCreate
-  @input:  HifDevice - hif device handle,
-           pInfo - initialization information
-  @output:
-  @return: HTC_HANDLE on success, NULL on failure
-  @notes: 
-  @example:
-  @see also: HTCDestroy
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-HTC_HANDLE HTCCreate(void *HifDevice, struct htc_init_info *pInfo);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Get the underlying HIF device handle
-  @function name: HTCGetHifDevice
-  @input:  HTCHandle - handle passed into the AddInstance callback
-  @output:
-  @return: opaque HIF device handle usable in HIF API calls.
-  @notes:
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void       *HTCGetHifDevice(HTC_HANDLE HTCHandle);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Set credit distribution parameters
-  @function name: HTCSetCreditDistribution
-  @input:  HTCHandle - HTC handle
-           pCreditDistCont - caller supplied context to pass into distribution functions
-           CreditDistFunc - Distribution function callback
-           CreditDistInit - Credit Distribution initialization callback
-           ServicePriorityOrder - Array containing list of service IDs, lowest index is highest
-                                  priority
-           ListLength - number of elements in ServicePriorityOrder
-  @output:
-  @return:
-  @notes:  The user can set a custom credit distribution function to handle special requirements
-           for each endpoint.  A default credit distribution routine can be used by setting
-           CreditInitFunc to NULL.  The default credit distribution is only provided for simple
-           "fair" credit distribution without regard to any prioritization.
-
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HTCSetCreditDistribution(HTC_HANDLE               HTCHandle,
-                                     void                     *pCreditDistContext,
-                                     HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
-                                     HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
-                                     HTC_SERVICE_ID           ServicePriorityOrder[],
-                                     int                      ListLength);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Wait for the target to indicate the HTC layer is ready
-  @function name: HTCWaitTarget
-  @input:  HTCHandle - HTC handle
-  @output:
-  @return:
-  @notes:  This API blocks until the target responds with an HTC ready message.
-           The caller should not connect services until the target has indicated it is
-           ready.
-  @example:
-  @see also: HTCConnectService
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCWaitTarget(HTC_HANDLE HTCHandle);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Start target service communications
-  @function name: HTCStart
-  @input:  HTCHandle - HTC handle
-  @output:
-  @return:
-  @notes: This API indicates to the target that the service connection phase is complete
-          and the target can freely start all connected services.  This API should only be
-          called AFTER all service connections have been made.  TCStart will issue a
-          SETUP_COMPLETE message to the target to indicate that all service connections
-          have been made and the target can start communicating over the endpoints.
-  @example:
-  @see also: HTCConnectService
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCStart(HTC_HANDLE HTCHandle);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Add receive packet to HTC
-  @function name: HTCAddReceivePkt
-  @input:  HTCHandle - HTC handle
-           pPacket - HTC receive packet to add
-  @output:
-  @return: 0 on success
-  @notes:  user must supply HTC packets for capturing incomming HTC frames.  The caller
-           must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
-           macro.
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Connect to an HTC service
-  @function name: HTCConnectService
-  @input:  HTCHandle - HTC handle
-           pReq - connection details
-  @output: pResp - connection response
-  @return:
-  @notes:  Service connections must be performed before HTCStart.  User provides callback handlers
-           for various endpoint events.
-  @example:
-  @see also: HTCStart
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCConnectService(HTC_HANDLE HTCHandle,
-                              struct htc_service_connect_req  *pReq,
-                              struct htc_service_connect_resp *pResp);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Send an HTC packet
-  @function name: HTCSendPkt
-  @input:  HTCHandle - HTC handle
-           pPacket - packet to send
-  @output:
-  @return: 0
-  @notes:  Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro.
-           This interface is fully asynchronous.  On error, HTC SendPkt will
-           call the registered Endpoint callback to cleanup the packet.
-  @example:
-  @see also: HTCFlushEndpoint
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Stop HTC service communications
-  @function name: HTCStop
-  @input:  HTCHandle - HTC handle
-  @output:
-  @return:
-  @notes: HTC communications is halted.  All receive and pending TX packets will
-          be flushed.
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HTCStop(HTC_HANDLE HTCHandle);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Destroy HTC service
-  @function name: HTCDestroy
-  @input: HTCHandle 
-  @output:
-  @return:
-  @notes:  This cleans up all resources allocated by HTCCreate().
-  @example:
-  @see also: HTCCreate
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HTCDestroy(HTC_HANDLE HTCHandle);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Flush pending TX packets
-  @function name: HTCFlushEndpoint
-  @input:  HTCHandle - HTC handle
-           Endpoint - Endpoint to flush
-           Tag - flush tag
-  @output:
-  @return:
-  @notes:  The Tag parameter is used to selectively flush packets with matching tags.
-           The value of 0 forces all packets to be flush regardless of tag.
-  @example:
-  @see also: HTCSendPkt
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Dump credit distribution state
-  @function name: HTCDumpCreditStates
-  @input:  HTCHandle - HTC handle
-  @output:
-  @return:
-  @notes:  This dumps all credit distribution information to the debugger
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HTCDumpCreditStates(HTC_HANDLE HTCHandle);
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Indicate a traffic activity change on an endpoint
-  @function name: HTCIndicateActivityChange
-  @input:  HTCHandle - HTC handle
-           Endpoint - endpoint in which activity has changed
-           Active - true if active, false if it has become inactive
-  @output:
-  @return:
-  @notes:  This triggers the registered credit distribution function to
-           re-adjust credits for active/inactive endpoints.
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void        HTCIndicateActivityChange(HTC_HANDLE      HTCHandle,
-                                      HTC_ENDPOINT_ID Endpoint,
-                                      bool          Active);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Get endpoint statistics
-  @function name: HTCGetEndpointStatistics
-  @input:  HTCHandle - HTC handle
-           Endpoint - Endpoint identifier
-           Action - action to take with statistics
-  @output:
-           pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR)
-
-  @return: true if statistics profiling is enabled, otherwise false.
-
-  @notes:  Statistics is a compile-time option and this function may return false
-           if HTC is not compiled with profiling.
-
-           The caller can specify the statistic "action" to take when sampling
-           the statistics.  This includes:
-
-           HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values.
-           HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics
-                             are cleared.
-           HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for
-                   pStats
-
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-bool       HTCGetEndpointStatistics(HTC_HANDLE               HTCHandle,
-                                      HTC_ENDPOINT_ID          Endpoint,
-                                      HTC_ENDPOINT_STAT_ACTION Action,
-                                      struct htc_endpoint_stats       *pStats);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Unblock HTC message reception
-  @function name: HTCUnblockRecv
-  @input:  HTCHandle - HTC handle
-  @output:
-  @return:
-  @notes:
-           HTC will block the receiver if the EpRecvAlloc callback fails to provide a packet.
-           The caller can use this API to indicate to HTC when resources (buffers) are available
-           such that the  receiver can be unblocked and HTC may re-attempt fetching the pending message.
-
-           This API is not required if the user uses the EpRecvRefill callback or uses the HTCAddReceivePacket()
-           API to recycle or provide receive packets to HTC.
-
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void HTCUnblockRecv(HTC_HANDLE HTCHandle);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: send a series of HTC packets  
-  @function name: HTCSendPktsMultiple
-  @input:  HTCHandle - HTC handle
-           pPktQueue - local queue holding packets to send
-  @output:
-  @return: 0
-  @notes:  Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro.
-           The queue must only contain packets directed at the same endpoint.
-           Caller supplies a pointer to an struct htc_packet_queue structure holding the TX packets in FIFO order.
-           This API will remove the packets from the pkt queue and place them into the HTC Tx Queue
-           and bundle messages where possible.
-           The caller may allocate the pkt queue on the stack to hold the packets.           
-           This interface is fully asynchronous.  On error, HTCSendPkts will
-           call the registered Endpoint callback to cleanup the packet.
-  @example:
-  @see also: HTCFlushEndpoint
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Add multiple receive packets to HTC
-  @function name: HTCAddReceivePktMultiple
-  @input:  HTCHandle - HTC handle
-           pPktQueue - HTC receive packet queue holding packets to add
-  @output:
-  @return: 0 on success
-  @notes:  user must supply HTC packets for capturing incomming HTC frames.  The caller
-           must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
-           macro. The queue must only contain recv packets for the same endpoint.
-           Caller supplies a pointer to an struct htc_packet_queue structure holding the recv packet.
-           This API will remove the packets from the pkt queue and place them into internal
-           recv packet list.
-           The caller may allocate the pkt queue on the stack to hold the packets.           
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int    HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue);
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Check if an endpoint is marked active
-  @function name: HTCIsEndpointActive
-  @input:  HTCHandle - HTC handle
-           Endpoint - endpoint to check for active state
-  @output:
-  @return: returns true if Endpoint is Active
-  @notes:  
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-bool      HTCIsEndpointActive(HTC_HANDLE      HTCHandle,
-                                HTC_ENDPOINT_ID Endpoint);
-
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  @desc: Get the number of recv buffers currently queued into an HTC endpoint
-  @function name: HTCGetNumRecvBuffers
-  @input:  HTCHandle - HTC handle
-           Endpoint - endpoint to check
-  @output:
-  @return: returns number of buffers in queue
-  @notes:  
-  @example:
-  @see also:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-int         HTCGetNumRecvBuffers(HTC_HANDLE      HTCHandle,
-                                 HTC_ENDPOINT_ID Endpoint);
-                                                                      
-/* internally used functions for testing... */
-void HTCEnableRecv(HTC_HANDLE HTCHandle);
-void HTCDisableRecv(HTC_HANDLE HTCHandle);
-int HTCWaitForPendingRecv(HTC_HANDLE   HTCHandle,
-                               u32 TimeoutInMs,
-                               bool      *pbIsRecvPending);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HTC_API_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h
deleted file mode 100644 (file)
index ba65c34..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="htc_packet.h" company="Atheros">
-//    Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef HTC_PACKET_H_
-#define HTC_PACKET_H_
-
-
-#include "dl_list.h"
-
-/* ------ Endpoint IDS ------ */
-typedef enum
-{
-    ENDPOINT_UNUSED = -1,
-    ENDPOINT_0 = 0,
-    ENDPOINT_1 = 1,
-    ENDPOINT_2 = 2,
-    ENDPOINT_3,
-    ENDPOINT_4,
-    ENDPOINT_5,
-    ENDPOINT_6,
-    ENDPOINT_7,
-    ENDPOINT_8,
-    ENDPOINT_MAX,
-} HTC_ENDPOINT_ID;
-
-struct htc_packet;
-
-typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *);
-
-typedef u16 HTC_TX_TAG;
-
-struct htc_tx_packet_info {
-    HTC_TX_TAG    Tag;            /* tag used to selective flush packets */
-    int           CreditsUsed;    /* number of credits used for this TX packet (HTC internal) */
-    u8 SendFlags;      /* send flags (HTC internal) */
-    int           SeqNo;          /* internal seq no for debugging (HTC internal) */
-};
-
-#define HTC_TX_PACKET_TAG_ALL          0    /* a tag of zero is reserved and used to flush ALL packets */
-#define HTC_TX_PACKET_TAG_INTERNAL     1                                /* internal tags start here */
-#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */
-
-struct htc_rx_packet_info {
-    u32 ExpectedHdr;        /* HTC internal use */
-    u32 HTCRxFlags;         /* HTC internal use */
-    u32 IndicationFlags;    /* indication flags set on each RX packet indication */
-};
-
-#define HTC_RX_FLAGS_INDICATE_MORE_PKTS  (1 << 0)   /* more packets on this endpoint are being fetched */
-
-/* wrapper around endpoint-specific packets */
-struct htc_packet {
-    struct dl_list         ListLink;       /* double link */
-    void            *pPktContext;   /* caller's per packet specific context */
-
-    u8 *pBufferStart;  /* the true buffer start , the caller can
-                                       store the real buffer start here.  In
-                                       receive callbacks, the HTC layer sets pBuffer
-                                       to the start of the payload past the header. This
-                                       field allows the caller to reset pBuffer when it
-                                       recycles receive packets back to HTC */
-    /*
-     * Pointer to the start of the buffer. In the transmit
-     * direction this points to the start of the payload. In the
-     * receive direction, however, the buffer when queued up
-     * points to the start of the HTC header but when returned
-     * to the caller points to the start of the payload
-     */
-    u8 *pBuffer;       /* payload start (RX/TX) */
-    u32 BufferLength;   /* length of buffer */
-    u32 ActualLength;   /* actual length of payload */
-    HTC_ENDPOINT_ID Endpoint;       /* endpoint that this packet was sent/recv'd from */
-    int        Status;         /* completion status */
-    union {
-        struct htc_tx_packet_info  AsTx;   /* Tx Packet specific info */
-        struct htc_rx_packet_info  AsRx;   /* Rx Packet specific info */
-    } PktInfo;
-
-    /* the following fields are for internal HTC use */
-    HTC_PACKET_COMPLETION Completion;   /* completion */
-    void                  *pContext;    /* HTC private completion context */
-};
-
-
-
-#define COMPLETE_HTC_PACKET(p,status)        \
-{                                            \
-    (p)->Status = (status);                  \
-    (p)->Completion((p)->pContext,(p));      \
-}
-
-#define INIT_HTC_PACKET_INFO(p,b,len)             \
-{                                                 \
-    (p)->pBufferStart = (b);                      \
-    (p)->BufferLength = (len);                    \
-}
-
-/* macro to set an initial RX packet for refilling HTC */
-#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \
-{                                                 \
-    (p)->pPktContext = (c);                       \
-    (p)->pBuffer = (b);                           \
-    (p)->pBufferStart = (b);                      \
-    (p)->BufferLength = (len);                    \
-    (p)->Endpoint = (ep);                         \
-}
-
-/* fast macro to recycle an RX packet that will be re-queued to HTC */
-#define HTC_PACKET_RESET_RX(p)              \
-    { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; }  
-
-/* macro to set packet parameters for TX */
-#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag)  \
-{                                                 \
-    (p)->pPktContext = (c);                       \
-    (p)->pBuffer = (b);                           \
-    (p)->ActualLength = (len);                    \
-    (p)->Endpoint = (ep);                         \
-    (p)->PktInfo.AsTx.Tag = (tag);                \
-}
-
-/* HTC Packet Queueing Macros */
-struct htc_packet_queue {
-    struct dl_list     QueueHead;
-    int         Depth;    
-};
-/* initialize queue */
-#define INIT_HTC_PACKET_QUEUE(pQ)   \
-{                                   \
-    DL_LIST_INIT(&(pQ)->QueueHead); \
-    (pQ)->Depth = 0;                \
-}
-
-/* enqueue HTC packet to the tail of the queue */
-#define HTC_PACKET_ENQUEUE(pQ,p)                        \
-{   DL_ListInsertTail(&(pQ)->QueueHead,&(p)->ListLink); \
-    (pQ)->Depth++;                                      \
-}
-
-/* enqueue HTC packet to the tail of the queue */
-#define HTC_PACKET_ENQUEUE_TO_HEAD(pQ,p)                \
-{   DL_ListInsertHead(&(pQ)->QueueHead,&(p)->ListLink); \
-    (pQ)->Depth++;                                      \
-}
-/* test if a queue is empty */
-#define HTC_QUEUE_EMPTY(pQ)       ((pQ)->Depth == 0)
-/* get packet at head without removing it */
-static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(struct htc_packet_queue *queue)   {
-    if (queue->Depth == 0) {
-        return NULL; 
-    }  
-    return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),struct htc_packet,ListLink);
-}
-/* remove a packet from a queue, where-ever it is in the queue */
-#define HTC_PACKET_REMOVE(pQ,p)     \
-{                                   \
-    DL_ListRemove(&(p)->ListLink);  \
-    (pQ)->Depth--;                  \
-}
-
-/* dequeue an HTC packet from the head of the queue */
-static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(struct htc_packet_queue *queue) {
-    struct dl_list    *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead);
-    if (pItem != NULL) {
-        queue->Depth--;
-        return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink);
-    }
-    return NULL;
-}
-
-/* dequeue an HTC packet from the tail of the queue */
-static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(struct htc_packet_queue *queue) {
-    struct dl_list    *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead);
-    if (pItem != NULL) {
-        queue->Depth--;
-        return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink);
-    }
-    return NULL;
-}
-
-#define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth
-
-
-#define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint
-#define HTC_GET_TAG_FROM_PKT(p)      (p)->PktInfo.AsTx.Tag
-
-    /* transfer the packets from one queue to the tail of another queue */
-#define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest,pQSrc) \
-{                                                                           \
-    DL_ListTransferItemsToTail(&(pQDest)->QueueHead,&(pQSrc)->QueueHead);   \
-    (pQDest)->Depth += (pQSrc)->Depth;                                      \
-    (pQSrc)->Depth = 0;                                                     \
-}
-
-    /* fast version to init and add a single packet to a queue */
-#define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ,pP) \
-{                                            \
-    DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead,&(pP)->ListLink)  \
-    (pQ)->Depth = 1;                                        \
-}
-    
-#define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \
-    ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), struct htc_packet, ListLink) 
-
-#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END
-        
-#endif /*HTC_PACKET_H_*/
diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h
deleted file mode 100644 (file)
index 9eea587..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 API for the host wlan module
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HOST_WLAN_API_H_
-#define _HOST_WLAN_API_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <a_osapi.h>
-
-struct ieee80211_node_table;
-struct ieee80211_frame;
-
-struct ieee80211_common_ie {
-    u16 ie_chan;
-    u8 *ie_tstamp;
-    u8 *ie_ssid;
-    u8 *ie_rates;
-    u8 *ie_xrates;
-    u8 *ie_country;
-    u8 *ie_wpa;
-    u8 *ie_rsn;
-    u8 *ie_wmm;
-    u8 *ie_ath;
-    u16 ie_capInfo;
-    u16 ie_beaconInt;
-    u8 *ie_tim;
-    u8 *ie_chswitch;
-    u8 ie_erp;
-    u8 *ie_wsc;
-    u8 *ie_htcap;
-    u8 *ie_htop;
-#ifdef WAPI_ENABLE
-    u8 *ie_wapi;
-#endif
-};
-
-typedef struct bss {
-    u8 ni_macaddr[6];
-    u8 ni_snr;
-    s16 ni_rssi;
-    struct bss                   *ni_list_next;
-    struct bss                   *ni_list_prev;
-    struct bss                   *ni_hash_next;
-    struct bss                   *ni_hash_prev;
-    struct ieee80211_common_ie   ni_cie;
-    u8 *ni_buf;
-    u16 ni_framelen;
-    struct ieee80211_node_table *ni_table;
-    u32 ni_refcnt;
-    int                          ni_scangen;
-
-    u32 ni_tstamp;
-    u32 ni_actcnt;
-#ifdef OS_ROAM_MANAGEMENT
-    u32 ni_si_gen;
-#endif
-} bss_t;
-
-typedef void wlan_node_iter_func(void *arg, bss_t *);
-
-bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size);
-void wlan_node_free(bss_t *ni);
-void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
-                const u8 *macaddr);
-bss_t *wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr);
-void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni);
-void wlan_free_allnodes(struct ieee80211_node_table *nt);
-void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
-                        void *arg);
-
-void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt);
-void wlan_node_table_reset(struct ieee80211_node_table *nt);
-void wlan_node_table_cleanup(struct ieee80211_node_table *nt);
-
-int wlan_parse_beacon(u8 *buf, int framelen,
-                           struct ieee80211_common_ie *cie);
-
-u16 wlan_ieee2freq(int chan);
-u32 wlan_freq2ieee(u16 freq);
-
-void wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge);
-
-void
-wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt);
-
-bss_t *
-wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
-                    u32 ssidLength, bool bIsWPA2, bool bMatchSSID);
-
-void
-wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni);
-
-bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid);
-
-bss_t *
-wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
-                    u32 ssidLength, u32 dot11AuthMode, u32 authMode,
-                   u32 pairwiseCryptoType, u32 grpwiseCryptoTyp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HOST_WLAN_API_H_ */
diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h
deleted file mode 100644 (file)
index c8583e0..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wmi_api.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 for the Wireless Module Interface (WMI).
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _WMI_API_H_
-#define _WMI_API_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-    /* WMI converts a dix frame with an ethernet payload (up to 1500 bytes) 
-     * to an 802.3 frame (adds SNAP header) and adds on a WMI data header */
-#define WMI_MAX_TX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
-
-    /* A normal WMI data frame */
-#define WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
-    
-    /* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
-#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH  (3840 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
-
-/*
- * IP QoS Field definitions according to 802.1p
- */
-#define BEST_EFFORT_PRI         0
-#define BACKGROUND_PRI          1
-#define EXCELLENT_EFFORT_PRI    3
-#define CONTROLLED_LOAD_PRI     4
-#define VIDEO_PRI               5
-#define VOICE_PRI               6
-#define NETWORK_CONTROL_PRI     7
-#define MAX_NUM_PRI             8
-
-#define UNDEFINED_PRI           (0xff)
-
-#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */
-
-#define A_ROUND_UP(x, y)  ((((x) + ((y) - 1)) / (y)) * (y))
-
-typedef enum {
-    ATHEROS_COMPLIANCE = 0x1,
-}TSPEC_PARAM_COMPLIANCE;
-
-struct wmi_t;
-
-void *wmi_init(void *devt);
-
-void wmi_qos_state_init(struct wmi_t *wmip);
-void wmi_shutdown(struct wmi_t *wmip);
-HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip);
-void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid);
-u16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 );
-int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf);
-int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS);
-int wmi_dot3_2_dix(void *osbuf);
-
-int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf);
-int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode);
-
-int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf);
-int wmi_syncpoint(struct wmi_t *wmip);
-int wmi_syncpoint_reset(struct wmi_t *wmip);
-u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled);
-
-u8 wmi_determine_userPriority (u8 *pkt, u32 layer2Pri);
-
-int wmi_control_rx(struct wmi_t *wmip, void *osbuf);
-void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg);
-void wmi_free_allnodes(struct wmi_t *wmip);
-bss_t *wmi_find_node(struct wmi_t *wmip, const u8 *macaddr);
-void wmi_free_node(struct wmi_t *wmip, const u8 *macaddr);
-
-
-typedef enum {
-    NO_SYNC_WMIFLAG = 0,
-    SYNC_BEFORE_WMIFLAG,            /* transmit all queued data before cmd */
-    SYNC_AFTER_WMIFLAG,             /* any new data waits until cmd execs */
-    SYNC_BOTH_WMIFLAG,
-    END_WMIFLAG                     /* end marker */
-} WMI_SYNC_FLAG;
-
-int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
-                      WMI_SYNC_FLAG flag);
-
-int wmi_connect_cmd(struct wmi_t *wmip,
-                         NETWORK_TYPE netType,
-                         DOT11_AUTH_MODE dot11AuthMode,
-                         AUTH_MODE authMode,
-                         CRYPTO_TYPE pairwiseCrypto,
-                         u8 pairwiseCryptoLen,
-                         CRYPTO_TYPE groupCrypto,
-                         u8 groupCryptoLen,
-                         int ssidLength,
-                         u8 *ssid,
-                         u8 *bssid,
-                         u16 channel,
-                         u32 ctrl_flags);
-
-int wmi_reconnect_cmd(struct wmi_t *wmip,
-                           u8 *bssid,
-                           u16 channel);
-int wmi_disconnect_cmd(struct wmi_t *wmip);
-int wmi_getrev_cmd(struct wmi_t *wmip);
-int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
-                           u32 forceFgScan, u32 isLegacy,
-                           u32 homeDwellTime, u32 forceScanInterval,
-                           s8 numChan, u16 *channelList);
-int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
-                            u16 fg_end_sec, u16 bg_sec,
-                            u16 minact_chdw_msec,
-                            u16 maxact_chdw_msec, u16 pas_chdw_msec,
-                            u8 shScanRatio, u8 scanCtrlFlags,
-                            u32 max_dfsch_act_time,
-                            u16 maxact_scan_per_ssid);
-int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask);
-int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
-                            u8 ssidLength, u8 *ssid);
-int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons);
-int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons);
-int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
-                           u8 ieLen, u8 *ieInfo);
-int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode);
-int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
-                            u16 atim_windows, u16 timeout_value);
-int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
-                   u32 ps_period, u8 sleep_period);
-int wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
-                           u16 psPollNum, u16 dtimPolicy,
-                           u16 wakup_tx_policy, u16 num_tx_to_wakeup,
-                           u16 ps_fail_event_policy);
-int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout);
-int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber);
-int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream);
-int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID);
-int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask);
-int wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate);
-int wmi_get_bitrate_cmd(struct wmi_t *wmip);
-s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx);
-int wmi_get_regDomain_cmd(struct wmi_t *wmip);
-int wmi_get_channelList_cmd(struct wmi_t *wmip);
-int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
-                                   WMI_PHY_MODE mode, s8 numChan,
-                                   u16 *channelList);
-
-int wmi_set_snr_threshold_params(struct wmi_t *wmip,
-                                       WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
-int wmi_set_rssi_threshold_params(struct wmi_t *wmip,
-                                        WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
-int wmi_clr_rssi_snr(struct wmi_t *wmip);
-int wmi_set_lq_threshold_params(struct wmi_t *wmip,
-                                      WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd);
-int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold);
-int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy);
-
-int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 bitmask);
-
-int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie,
-                                    u32 source);
-
-int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
-                                     u16 tsr, bool rep, u16 size,
-                                     u32 valid);
-
-int wmi_get_stats_cmd(struct wmi_t *wmip);
-
-int wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex,
-                        CRYPTO_TYPE keyType, u8 keyUsage,
-                        u8 keyLength,u8 *keyRSC,
-                        u8 *keyMaterial, u8 key_op_ctrl, u8 *mac,
-                        WMI_SYNC_FLAG sync_flag);
-int wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk);
-int wmi_delete_krk_cmd(struct wmi_t *wmip);
-int wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex);
-int wmi_set_akmp_params_cmd(struct wmi_t *wmip,
-                                 WMI_SET_AKMP_PARAMS_CMD *akmpParams);
-int wmi_get_pmkid_list_cmd(struct wmi_t *wmip);
-int wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
-                                WMI_SET_PMKID_LIST_CMD *pmkInfo);
-int wmi_abort_scan_cmd(struct wmi_t *wmip);
-int wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM);
-int wmi_get_txPwr_cmd(struct wmi_t *wmip);
-int wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid);
-int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex);
-int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en);
-int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
-                          bool set);
-int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop,
-                                   u8 eCWmin, u8 eCWmax,
-                                   u8 aifsn);
-int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
-                                  u8 trafficClass, u8 maxRetries,
-                                  u8 enableNotify);
-
-void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid);
-
-int wmi_get_roam_tbl_cmd(struct wmi_t *wmip);
-int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType);
-int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
-                               u8 size);
-int wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
-                            WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
-                            u8 size);
-
-int wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode);
-int wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
-                              u8 frmType,
-                              u8 *dstMacAddr,
-                              u8 *bssid,
-                              u16 optIEDataLen,
-                              u8 *optIEData);
-
-int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl);
-int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize);
-int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen);
-u8 convert_userPriority_to_trafficClass(u8 userPriority);
-u8 wmi_get_power_mode_cmd(struct wmi_t *wmip);
-int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance);
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len);
-#endif
-
-int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status);
-int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd);
-
-int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd);
-
-int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
-                                               WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd);
-
-int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
-                                                       WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd);
-
-int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
-                                             WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd);
-
-int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
-                                                WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd);
-
-
-int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd);
-
-int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd);
-
-int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
-                                                       WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd);
-
-int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd);
-
-int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip);
-
-int wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold);
-
-/*
- *  This function is used to configure the fix rates mask to the target.
- */
-int wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask);
-int wmi_get_ratemask_cmd(struct wmi_t *wmip);
-
-int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode);
-
-int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode);
-
-int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status);
-int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status);
-int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable);
-int wmi_set_country(struct wmi_t *wmip, u8 *countryCode);
-
-int wmi_get_keepalive_configured(struct wmi_t *wmip);
-u8 wmi_get_keepalive_cmd(struct wmi_t *wmip);
-int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval);
-
-int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType,
-                           u8 ieLen,u8 *ieInfo);
-
-int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen);
-
-s32 wmi_get_rate(s8 rateindex);
-
-int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd);
-
-/*Wake on Wireless WMI commands*/
-int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd);
-int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd);
-int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd);
-int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
-                                 WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size);
-int wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
-                                 WMI_DEL_WOW_PATTERN_CMD *cmd);
-int wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status);
-
-int
-wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer);
-
-int
-wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4);
-
-int
-wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4);
-
-int
-wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable);
-
-bss_t *
-wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
-                   u32 ssidLength, bool bIsWPA2, bool bMatchSSID);
-
-
-void
-wmi_node_return (struct wmi_t *wmip, bss_t *bss);
-
-void
-wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge);
-
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-int wmi_prof_cfg_cmd(struct wmi_t *wmip, u32 period, u32 nbins);
-int wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr);
-int wmi_prof_start_cmd(struct wmi_t *wmip);
-int wmi_prof_stop_cmd(struct wmi_t *wmip);
-int wmi_prof_count_get_cmd(struct wmi_t *wmip);
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-#ifdef OS_ROAM_MANAGEMENT
-void wmi_scan_indication (struct wmi_t *wmip);
-#endif
-
-int
-wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd);
-
-bss_t   *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id);
-int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss);
-
-
-/*
- * AP mode
- */
-int
-wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p);
-
-int
-wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid);
-
-int
-wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta);
-
-int
-wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy);
-
-int
-wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a);
-
-u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl);
-
-int
-wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason);
-
-int
-wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag);
-
-int
-wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period);
-
-int
-wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell);
-
-int
-wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim);
-
-int
-wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset);
-
-int
-wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd);
-
-int
-wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width);
-
-int
-wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz);
-
-int
-wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray);
-
-int
-wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid);
-
-int
-wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink);
-
-int
-wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask);
-
-int
-wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost);
-
-int
-wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode);
-
-int
-wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence);
-
-int
-wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk);
-
-int
-wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd);
-
-u16 wmi_ieee2freq (int chan);
-
-u32 wmi_freq2ieee (u16 freq);
-
-bss_t *
-wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
-                   u32 ssidLength,
-                   u32 dot11AuthMode, u32 authMode,
-                   u32 pairwiseCryptoType, u32 grpwiseCryptoTyp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _WMI_API_H_ */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
deleted file mode 100644 (file)
index e0ea218..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// AR3K configuration implementation
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#define ATH_MODULE_NAME misc
-#include "a_debug.h"
-#include "common_drv.h"
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-#include "export_hci_transport.h"
-#else
-#include "hci_transport_api.h"
-#endif
-#include "ar3kconfig.h"
-#include "tlpm.h"
-
-#define BAUD_CHANGE_COMMAND_STATUS_OFFSET   5
-#define HCI_EVENT_RESP_TIMEOUTMS            3000
-#define HCI_CMD_OPCODE_BYTE_LOW_OFFSET      0
-#define HCI_CMD_OPCODE_BYTE_HI_OFFSET       1
-#define HCI_EVENT_OPCODE_BYTE_LOW           3
-#define HCI_EVENT_OPCODE_BYTE_HI            4
-#define HCI_CMD_COMPLETE_EVENT_CODE         0xE
-#define HCI_MAX_EVT_RECV_LENGTH             257
-#define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET  5
-
-int AthPSInitialize(struct ar3k_config_info *hdev);
-
-static int SendHCICommand(struct ar3k_config_info *pConfig,
-                               u8 *pBuffer,
-                               int              Length)
-{
-    struct htc_packet  *pPacket = NULL;
-    int    status = 0;
-       
-    do {   
-        
-        pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));     
-        if (NULL == pPacket) {
-            status = A_NO_MEMORY;
-            break;    
-        }       
-        
-        A_MEMZERO(pPacket,sizeof(struct htc_packet));      
-        SET_HTC_PACKET_INFO_TX(pPacket,
-                               NULL,
-                               pBuffer, 
-                               Length,
-                               HCI_COMMAND_TYPE, 
-                               AR6K_CONTROL_PKT_TAG);
-        
-            /* issue synchronously */                                      
-        status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true);
-        
-    } while (false);
-   
-    if (pPacket != NULL) {
-        kfree(pPacket);
-    }
-        
-    return status;
-}
-
-static int RecvHCIEvent(struct ar3k_config_info *pConfig,
-                             u8 *pBuffer,
-                             int              *pLength)
-{
-    int    status = 0;
-    struct htc_packet  *pRecvPacket = NULL;
-    
-    do {
-                 
-        pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
-        if (NULL == pRecvPacket) {
-            status = A_NO_MEMORY;
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
-            break;    
-        }     
-        
-        A_MEMZERO(pRecvPacket,sizeof(struct htc_packet)); 
-         
-        SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);
-        
-        status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
-                                               pRecvPacket,
-                                               HCI_EVENT_RESP_TIMEOUTMS);
-        if (status) {
-            break;    
-        }
-
-        *pLength = pRecvPacket->ActualLength;
-        
-    } while (false);
-       
-    if (pRecvPacket != NULL) {
-        kfree(pRecvPacket);    
-    }
-    
-    return status;
-} 
-    
-int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
-                                           u8 *pHCICommand,
-                                           int              CmdLength,
-                                           u8 **ppEventBuffer,
-                                           u8 **ppBufferToFree)
-{
-    int    status = 0;
-    u8 *pBuffer = NULL;
-    u8 *pTemp;
-    int         length;
-    bool      commandComplete = false;
-    u8 opCodeBytes[2];
-                               
-    do {
-        
-        length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
-        length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
-        length += pConfig->pHCIProps->IOBlockPad;
-                                     
-        pBuffer = (u8 *)A_MALLOC(length);
-        if (NULL == pBuffer) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n"));
-            status = A_NO_MEMORY;
-            break;    
-        }
-        
-            /* get the opcodes to check the command complete event */
-        opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET];
-        opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET];
-        
-            /* copy HCI command */
-        memcpy(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);         
-            /* send command */
-        status = SendHCICommand(pConfig,
-                                pBuffer + pConfig->pHCIProps->HeadRoom,
-                                CmdLength);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status));
-            AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
-            break;    
-        }   
-        
-            /* reuse buffer to capture command complete event */
-        A_MEMZERO(pBuffer,length);
-        status = RecvHCIEvent(pConfig,pBuffer,&length);        
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n"));
-            AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
-            break;    
-        }
-        
-        pTemp = pBuffer + pConfig->pHCIProps->HeadRoom;        
-        if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) {
-            if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) &&
-                (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) {
-                commandComplete = true;
-            }
-        }
-        
-        if (!commandComplete) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0]));
-            AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event");
-            status = A_ECOMM;
-            break;    
-        }       
-        
-        if (ppEventBuffer != NULL) {
-                /* caller wants to look at the event */
-            *ppEventBuffer = pTemp;
-            if (ppBufferToFree == NULL) {
-                status = A_EINVAL;
-                break;        
-            }
-                /* caller must free the buffer */
-            *ppBufferToFree = pBuffer;
-            pBuffer = NULL;            
-        }
-        
-    } while (false);
-
-    if (pBuffer != NULL) {
-        kfree(pBuffer);    
-    }
-    
-    return status;    
-}
-
-static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig)
-{
-    int    status = 0;
-    u8 hciBaudChangeCommand[] =  {0x0c,0xfc,0x2,0,0};
-    u16 baudVal;
-    u8 *pEvent = NULL;
-    u8 *pBufferToFree = NULL;
-    
-    do {
-        
-        if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) {
-            baudVal = (u16)(pConfig->AR3KBaudRate / 100);
-            hciBaudChangeCommand[3] = (u8)baudVal;
-            hciBaudChangeCommand[4] = (u8)(baudVal >> 8);
-            
-            status = SendHCICommandWaitCommandComplete(pConfig,
-                                                       hciBaudChangeCommand,
-                                                       sizeof(hciBaudChangeCommand),
-                                                       &pEvent,
-                                                       &pBufferToFree);          
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n"));  
-                break;    
-            }
-            
-            if (pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET] != 0) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("AR3K Config: Baud change command event status failed: %d \n", 
-                                pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET]));
-                status = A_ECOMM; 
-                break;           
-            } 
-            
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                    ("AR3K Config: Baud Changed to %d \n",pConfig->AR3KBaudRate));  
-        }
-        
-        if (pConfig->Flags & AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY) {
-                /* some versions of AR3K do not switch baud immediately, up to 300MS */
-            A_MDELAY(325);
-        }
-        
-        if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP) {
-            /* Tell target to change UART baud rate for AR6K */
-            status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate);
-
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                    ("AR3K Config: failed to set scale and step values: %d \n", status));
-                break;    
-            }
-    
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
-                    ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate));            
-        }
-                
-    } while (false);
-                        
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-        
-    return status;
-}
-
-static int AR3KExitMinBoot(struct ar3k_config_info *pConfig)
-{
-    int  status;
-    char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
-                                  0x00,0x00,0x00,0x00,0x00};
-    u8 *pEvent = NULL;
-    u8 *pBufferToFree = NULL;
-    
-    status = SendHCICommandWaitCommandComplete(pConfig,
-                                               exitMinBootCmd,
-                                               sizeof(exitMinBootCmd),
-                                               &pEvent,
-                                               &pBufferToFree);
-    
-    if (!status) {
-        if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                ("AR3K Config: MinBoot exit command event status failed: %d \n", 
-                            pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET]));
-            status = A_ECOMM;            
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, 
-                                ("AR3K Config: MinBoot Exit Command Complete (Success) \n"));
-            A_MDELAY(1);
-        }
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: MinBoot Exit Failed! \n"));    
-    }
-    
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-    
-    return status;                                              
-}
-                                 
-static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig)
-{
-    int status = 0;
-    u8 hciResetCommand[] = {0x03,0x0c,0x0};
-    u8 *pEvent = NULL;
-    u8 *pBufferToFree = NULL;
-
-    status = SendHCICommandWaitCommandComplete( pConfig,
-                                                hciResetCommand,
-                                                sizeof(hciResetCommand),
-                                                &pEvent,
-                                                &pBufferToFree );
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n"));
-    }
-
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);
-    }
-
-    return status;
-}
-
-static int AR3KEnableTLPM(struct ar3k_config_info *pConfig)
-{
-    int  status;
-    /* AR3K vendor specific command for Host Wakeup Config */
-    char hostWakeupConfig[] = {0x31,0xFC,0x18,
-                                    0x02,0x00,0x00,0x00,
-                                    0x01,0x00,0x00,0x00,
-                                    TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00,    //idle timeout in ms
-                                    0x00,0x00,0x00,0x00,
-                                    TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00,    //wakeup timeout in ms
-                                    0x00,0x00,0x00,0x00};
-    /* AR3K vendor specific command for Target Wakeup Config */
-    char targetWakeupConfig[] = {0x31,0xFC,0x18,
-                                      0x04,0x00,0x00,0x00,
-                                      0x01,0x00,0x00,0x00,
-                                      TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00,  //idle timeout in ms
-                                      0x00,0x00,0x00,0x00,
-                                      TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00,  //wakeup timeout in ms
-                                      0x00,0x00,0x00,0x00};
-    /* AR3K vendor specific command for Host Wakeup Enable */
-    char hostWakeupEnable[] = {0x31,0xFC,0x4,
-                                    0x01,0x00,0x00,0x00};
-    /* AR3K vendor specific command for Target Wakeup Enable */
-    char targetWakeupEnable[] = {0x31,0xFC,0x4,
-                                      0x06,0x00,0x00,0x00};
-    /* AR3K vendor specific command for Sleep Enable */
-    char sleepEnable[] = {0x4,0xFC,0x1,
-                               0x1};
-    u8 *pEvent = NULL;
-    u8 *pBufferToFree = NULL;
-    
-    if (0 != pConfig->IdleTimeout) {
-        u8 idle_lsb = pConfig->IdleTimeout & 0xFF;
-        u8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8;
-        hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb;
-        hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb;
-    }
-
-    if (0 != pConfig->WakeupTimeout) {
-        hostWakeupConfig[19] = targetWakeupConfig[19] = (pConfig->WakeupTimeout & 0xFF);
-    }
-
-    status = SendHCICommandWaitCommandComplete(pConfig,
-                                               hostWakeupConfig,
-                                               sizeof(hostWakeupConfig),
-                                               &pEvent,
-                                               &pBufferToFree);
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n"));    
-        return status;
-    }
-    
-    pEvent = NULL;
-    pBufferToFree = NULL;
-    status = SendHCICommandWaitCommandComplete(pConfig,
-                                               targetWakeupConfig,
-                                               sizeof(targetWakeupConfig),
-                                               &pEvent,
-                                               &pBufferToFree);
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n"));    
-        return status;
-    }
-
-    pEvent = NULL;
-    pBufferToFree = NULL;
-    status = SendHCICommandWaitCommandComplete(pConfig,
-                                               hostWakeupEnable,
-                                               sizeof(hostWakeupEnable),
-                                               &pEvent,
-                                               &pBufferToFree);
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n"));    
-        return status;
-    }
-
-    pEvent = NULL;
-    pBufferToFree = NULL;
-    status = SendHCICommandWaitCommandComplete(pConfig,
-                                               targetWakeupEnable,
-                                               sizeof(targetWakeupEnable),
-                                               &pEvent,
-                                               &pBufferToFree);
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n"));    
-        return status;
-    }
-
-    pEvent = NULL;
-    pBufferToFree = NULL;
-    status = SendHCICommandWaitCommandComplete(pConfig,
-                                               sleepEnable,
-                                               sizeof(sleepEnable),
-                                               &pEvent,
-                                               &pBufferToFree);
-    if (pBufferToFree != NULL) {
-        kfree(pBufferToFree);    
-    }
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n"));    
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Enable TLPM Completed (status = %d) \n",status));
-
-    return status;                                              
-}
-
-int AR3KConfigure(struct ar3k_config_info *pConfig)
-{
-    int        status = 0;
-        
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n"));
-                                
-    do {
-        
-        if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
-            status = A_EINVAL;
-            break;    
-        }
-        
-            /* disable asynchronous recv while we issue commands and receive events synchronously */
-        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
-        if (status) {
-            break;    
-        }
-      
-        if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) {
-            status =  AR3KExitMinBoot(pConfig);   
-            if (status) {
-                break;    
-            }    
-        }
-        
-       
-        /* Load patching and PST file if available*/
-        if (0 != AthPSInitialize(pConfig)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n"));
-        }
-
-        /* Send HCI reset to make PS tags take effect*/
-        AR3KConfigureSendHCIReset(pConfig);
-
-       if (pConfig->Flags & 
-                (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
-            status = AR3KConfigureHCIBaud(pConfig);      
-            if (status) {
-                break;    
-            }
-        }     
-
-
-
-        if (pConfig->PwrMgmtEnabled) {
-            /* the delay is required after the previous HCI reset before further
-             * HCI commands can be issued
-             */
-            A_MDELAY(200);
-            AR3KEnableTLPM(pConfig);
-        }
-               
-           /* re-enable asynchronous recv */
-        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
-        if (status) {
-            break;    
-        }     
-    
-    
-    } while (false);
-    
-  
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status));
-    
-    return status;
-}
-
-int AR3KConfigureExit(void *config)
-{
-    int        status = 0;
-    struct ar3k_config_info *pConfig = (struct ar3k_config_info *)config;
-        
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n"));
-                                
-    do {
-        
-        if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
-            status = A_EINVAL;
-            break;    
-        }
-        
-            /* disable asynchronous recv while we issue commands and receive events synchronously */
-        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
-        if (status) {
-            break;    
-        }
-      
-        if (pConfig->Flags & 
-                (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
-            status = AR3KConfigureHCIBaud(pConfig);      
-            if (status) {
-                break;    
-            }
-        }
-
-           /* re-enable asynchronous recv */
-        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
-        if (status) {
-            break;    
-        }     
-    
-    
-    } while (false);
-    
-  
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status));
-    
-    return status;
-}
-
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
deleted file mode 100644 (file)
index 282ceac..0000000
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver.
- * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO
- * defined.
- *
- *
- * ar3kcpsconfig.c
- *
- *
- *
- * The software source and binaries included in this development package are
- * licensed, not sold. You, or your company, received the package under one
- * or more license agreements. The rights granted to you are specifically
- * listed in these license agreement(s). All other rights remain with Atheros
- * Communications, Inc., its subsidiaries, or the respective owner including
- * those listed on the included copyright notices..  Distribution of any
- * portion of this package must be in strict compliance with the license
- * agreement(s) terms.
- *
- *
- *
- */
-
-
-
-#include "ar3kpsconfig.h"
-#ifndef HCI_TRANSPORT_SDIO
-#include "hci_ath.h"
-#include "hci_uart.h"
-#endif /* #ifndef HCI_TRANSPORT_SDIO */
-
-#define MAX_FW_PATH_LEN             50
-#define MAX_BDADDR_FORMAT_LENGTH    30
-
-/*
- *  Structure used to send HCI packet, hci packet length and device info 
- *  together as parameter to PSThread.
- */
-typedef struct {
-
-    struct ps_cmd_packet *HciCmdList;
-    u32 num_packets;
-    struct ar3k_config_info *dev;
-}HciCommandListParam;
-
-int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
-                                           u8 *pHCICommand,
-                                           int              CmdLength,
-                                           u8 **ppEventBuffer,
-                                           u8 **ppBufferToFree);
-
-u32 Rom_Version;
-u32 Build_Version;
-extern bool BDADDR;
-
-int getDeviceType(struct ar3k_config_info *pConfig, u32 *code);
-int ReadVersionInfo(struct ar3k_config_info *pConfig);
-#ifndef HCI_TRANSPORT_SDIO
-
-DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
-DECLARE_WAIT_QUEUE_HEAD(HciEvent);
-u8 *HciEventpacket;
-rwlock_t syncLock;
-wait_queue_t Eventwait;
-
-int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len);
-extern char *bdaddr;
-#endif /* HCI_TRANSPORT_SDIO */
-
-int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type);
-
-int PSSendOps(void *arg);
-
-#ifdef BT_PS_DEBUG
-void Hci_log(u8 * log_string,u8 *data,u32 len)
-{
-    int i;
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
-    for (i = 0; i < len; i++) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i]));
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
-}
-#else
-#define Hci_log(string,data,len)
-#endif /* BT_PS_DEBUG */
-
-
-
-
-int AthPSInitialize(struct ar3k_config_info *hdev)
-{
-    int status = 0;
-    if(hdev == NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n"));
-        return A_ERROR;
-    }
-
-#ifndef HCI_TRANSPORT_SDIO
-    DECLARE_WAITQUEUE(wait, current);
-#endif /* HCI_TRANSPORT_SDIO */
-    
-
-#ifdef HCI_TRANSPORT_SDIO
-    status = PSSendOps((void*)hdev);
-#else
-    if(InitPSState(hdev) == -1) {
-        return A_ERROR;
-    }
-    allow_signal(SIGKILL);
-    add_wait_queue(&PsCompleteEvent,&wait);
-    set_current_state(TASK_INTERRUPTIBLE);
-    if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n"));
-        remove_wait_queue(&PsCompleteEvent,&wait);
-        return A_ERROR;
-    }
-    wait_event_interruptible(PsCompleteEvent,(PSTagMode == false));
-    set_current_state(TASK_RUNNING);
-    remove_wait_queue(&PsCompleteEvent,&wait);
-
-#endif /* HCI_TRANSPORT_SDIO */
-
-
-    return status;
-    
-}
-
-int PSSendOps(void *arg) 
-{
-    int i;
-    int status = 0;
-    struct ps_cmd_packet *HciCmdList; /* List storing the commands */
-    const struct firmware* firmware;
-    u32 numCmds;
-    u8 *event;
-    u8 *bufferToFree;
-    struct hci_dev *device;
-    u8 *buffer;
-    u32 len;
-    u32 DevType;
-    u8 *PsFileName;
-    u8 *patchFileName;
-    u8 *path = NULL;
-    u8 *config_path = NULL;
-    u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
-    struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg;
-    struct device *firmwareDev = NULL;
-    status = 0;
-    HciCmdList = NULL;
-#ifdef HCI_TRANSPORT_SDIO
-    device = hdev->pBtStackHCIDev; 
-    firmwareDev = device->parent;
-#else 
-    device = hdev;
-    firmwareDev = &device->dev;
-    AthEnableSyncCommandOp(true);
-#endif /* HCI_TRANSPORT_SDIO */
-    /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
-     */
-
-    path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN);
-    if(path == NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
-        goto complete;
-    }
-    config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN);
-    if(config_path == NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
-        goto complete;
-    }
-
-    if(A_ERROR == getDeviceType(hdev,&DevType)) {
-        status = 1;
-        goto complete;
-    }
-    if(A_ERROR == ReadVersionInfo(hdev)) {
-        status = 1;
-        goto complete;
-    }
-
-    patchFileName = PATCH_FILE;
-    snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
-    if(DevType){
-        if(DevType == 0xdeadc0de){
-               PsFileName =  PS_ASIC_FILE;
-           } else{
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x  \n",Rom_Version,Build_Version));
-                if((Rom_Version == 0x99999999) && (Build_Version == 1)){
-                        
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
-                       patchFileName = NULL;
-               }
-               PsFileName =  PS_FPGA_FILE;
-           }
-    }
-    else{
-           PsFileName =  PS_ASIC_FILE;
-    }
-
-    snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
-    /* Read the PS file to a dynamically allocated buffer */
-    if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
-        status = 1;
-        goto complete;
-
-    }
-    if(NULL == firmware || firmware->size == 0) {
-        status = 1;
-        goto complete;
-    }
-    buffer = (u8 *)A_MALLOC(firmware->size);
-    if(buffer != NULL) {
-    /* Copy the read file to a local Dynamic buffer */
-        memcpy(buffer,firmware->data,firmware->size);
-        len = firmware->size;
-        A_RELEASE_FIRMWARE(firmware);
-        /* Parse the PS buffer to a global variable */
-        status = AthDoParsePS(buffer,len);
-        kfree(buffer);
-    } else {
-        A_RELEASE_FIRMWARE(firmware);
-    }
-
-
-    /* Read the patch file to a dynamically allocated buffer */
-       if(patchFileName != NULL)
-                snprintf(config_path,
-                         MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
-       else {
-               status = 0;
-       }
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
-    if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
-        /* 
-         *  It is not necessary that Patch file be available, continue with PS Operations if.
-         *  failed.
-         */
-        status = 0;
-
-    } else {
-        if(NULL == firmware || firmware->size == 0) {
-            status = 0;
-        } else {
-            buffer = (u8 *)A_MALLOC(firmware->size);
-            if(buffer != NULL) {
-                /* Copy the read file to a local Dynamic buffer */
-                memcpy(buffer,firmware->data,firmware->size);
-                len = firmware->size;
-                A_RELEASE_FIRMWARE(firmware);
-                /* parse and store the Patch file contents to a global variables */
-                status = AthDoParsePatch(buffer,len);
-                kfree(buffer);
-            } else {
-                A_RELEASE_FIRMWARE(firmware);
-            }
-        }
-    }
-
-    /* Create an HCI command list from the parsed PS and patch information */
-    AthCreateCommandList(&HciCmdList,&numCmds);
-
-    /* Form the parameter for PSSendOps() API */
-
-    /*
-     * First Send the CRC packet, 
-     * We have to continue with the PS operations only if the CRC packet has been replied with 
-     * a Command complete event with status Error.
-     */
-
-    if(SendHCICommandWaitCommandComplete
-    (hdev,
-    HciCmdList[0].Hcipacket,
-    HciCmdList[0].packetLen,
-    &event,
-    &bufferToFree) == 0) {
-        if(ReadPSEvent(event) == 0) { /* Exit if the status is success */
-            if(bufferToFree != NULL) {
-                kfree(bufferToFree);
-                }
-       
-#ifndef HCI_TRANSPORT_SDIO
-                       if(bdaddr && bdaddr[0] !='\0') {
-                               write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
-                       }
-#endif 
-               status = 1;
-               goto complete;
-        }
-        if(bufferToFree != NULL) {
-               kfree(bufferToFree);
-        }
-    } else {
-        status = 0;
-        goto complete;
-    }
-    for(i = 1; i <numCmds; i++) {
-    
-        if(SendHCICommandWaitCommandComplete
-        (hdev,
-        HciCmdList[i].Hcipacket,
-        HciCmdList[i].packetLen,
-        &event,
-        &bufferToFree) == 0) {
-            if(ReadPSEvent(event) != 0) { /* Exit if the status is success */
-                if(bufferToFree != NULL) {
-                    kfree(bufferToFree);
-                    }
-                   status = 1;
-                    goto complete;
-            }
-            if(bufferToFree != NULL) {
-                   kfree(bufferToFree);
-            }
-        } else {
-            status = 0;
-            goto complete;
-        }
-    }
-#ifdef HCI_TRANSPORT_SDIO
-       if(BDADDR == false)
-               if(hdev->bdaddr[0] !=0x00 ||
-                  hdev->bdaddr[1] !=0x00 ||
-                  hdev->bdaddr[2] !=0x00 ||
-                  hdev->bdaddr[3] !=0x00 ||
-                  hdev->bdaddr[4] !=0x00 ||
-                  hdev->bdaddr[5] !=0x00)
-                       write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);
-
-#ifndef HCI_TRANSPORT_SDIO
-
-       if(bdaddr && bdaddr[0] != '\0') {
-               write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
-       } else
-#endif /* HCI_TRANSPORT_SDIO */
-    /* Write BDADDR Read from OTP here */
-
-
-
-#endif
-
-       {
-                /* Read Contents of BDADDR file if user has not provided any option */
-        snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
-       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
-       if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
-               status = 1;
-               goto complete;
-       }
-       if(NULL == firmware || firmware->size == 0) {
-               status = 1;
-               goto complete;
-       }
-       len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1);
-       memcpy(config_bdaddr, firmware->data, len);
-       config_bdaddr[len] = '\0';
-       write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
-               A_RELEASE_FIRMWARE(firmware);
-       }
-complete:
-#ifndef HCI_TRANSPORT_SDIO
-    AthEnableSyncCommandOp(false);
-    PSTagMode = false;
-    wake_up_interruptible(&PsCompleteEvent);
-#endif /* HCI_TRANSPORT_SDIO */
-    if(NULL != HciCmdList) {
-        AthFreeCommandList(&HciCmdList,numCmds);
-    }
-    if(path) {
-        kfree(path);
-    }
-    if(config_path) {
-        kfree(config_path);
-    }
-    return status;
-}
-#ifndef HCI_TRANSPORT_SDIO
-/*
- *  This API is used to send the HCI command to controller and return
- *  with a HCI Command Complete event.
- *  For HCI SDIO transport, this will be internally defined. 
- */
-int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
-                                           u8 *pHCICommand,
-                                           int              CmdLength,
-                                           u8 **ppEventBuffer,
-                                           u8 **ppBufferToFree)
-{
-    if(CmdLength == 0) {
-        return A_ERROR;
-    }
-    Hci_log("COM Write -->",pHCICommand,CmdLength);
-    PSAcked = false;
-    if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) {
-        /* If the controller is not available, return Error */
-        return A_ERROR;
-    }
-    //add_timer(&psCmdTimer);
-    wait_event_interruptible(HciEvent,(PSAcked == true));
-    if(NULL != HciEventpacket) {
-        *ppEventBuffer = HciEventpacket;
-        *ppBufferToFree = HciEventpacket;
-    } else {
-        /* Did not get an event from controller. return error */
-        *ppBufferToFree = NULL;
-        return A_ERROR;
-    }
-
-    return 0;
-}
-#endif /* HCI_TRANSPORT_SDIO */
-
-int ReadPSEvent(u8* Data){
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3]));
-                                
-    if(Data[4] == 0xFC && Data[5] == 0x00)
-    {
-         switch(Data[3]){
-             case 0x0B:
-                     return 0;
-                 break;
-                 case 0x0C:
-                    /* Change Baudrate */
-                        return 0;
-                 break;  
-                 case 0x04:
-                     return 0;
-                 break;  
-               case 0x1E:
-                       Rom_Version = Data[9];
-                       Rom_Version = ((Rom_Version << 8) |Data[8]);
-                       Rom_Version = ((Rom_Version << 8) |Data[7]);
-                       Rom_Version = ((Rom_Version << 8) |Data[6]);
-
-                       Build_Version = Data[13];
-                       Build_Version = ((Build_Version << 8) |Data[12]);
-                       Build_Version = ((Build_Version << 8) |Data[11]);
-                       Build_Version = ((Build_Version << 8) |Data[10]);
-                       return 0;
-               break;
-
-        
-                }
-    }                       
-        
-    return A_ERROR;           
-}
-int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr)
-{
-       unsigned char bdbyte[3];
-       unsigned char *str_byte = str_bdaddr;
-       int i,j;
-       unsigned char colon_present = 0;
-
-       if(NULL != strstr(str_bdaddr,":")) {
-               colon_present = 1;
-       }
-
-
-       bdbyte[2] = '\0';
-
-       for( i = 0,j = 5; i < 6; i++, j--) {
-               bdbyte[0] = str_byte[0];
-               bdbyte[1] = str_byte[1];
-               bdaddr[j] = A_STRTOL(bdbyte,NULL,16);
-               if(colon_present == 1) {
-                       str_byte+=3;
-               } else {
-                       str_byte+=2;
-               }
-       }
-       return 0; 
-}
-
-int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type)
-{
-       u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, 
-                                                       0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-    u8 *event;
-    u8 *bufferToFree = NULL;
-    int result = A_ERROR;
-       int inc,outc;
-
-       if (type == BDADDR_TYPE_STRING)
-               str2ba(bdaddr,&bdaddr_cmd[7]);
-       else {
-               /* Bdaddr has to be sent as LAP first */
-               for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
-                       bdaddr_cmd[outc] = bdaddr[inc];
-       }
-
-    if(0 == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
-                                                                                               sizeof(bdaddr_cmd),
-                                                                                               &event,&bufferToFree)) {
-
-        if(event[4] == 0xFC && event[5] == 0x00){
-               if(event[3] == 0x0B){
-                result = 0;
-            }
-        }
-
-    }
-    if(bufferToFree != NULL) {
-        kfree(bufferToFree);
-   }
-    return result;
-
-}
-int ReadVersionInfo(struct ar3k_config_info *pConfig)
-{
-    u8 hciCommand[] =  {0x1E,0xfc,0x00};
-    u8 *event;
-    u8 *bufferToFree = NULL;
-    int result = A_ERROR;
-    if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
-       result = ReadPSEvent(event);
-
-    }
-    if(bufferToFree != NULL) {
-        kfree(bufferToFree);
-   }
-    return result;
-}
-int getDeviceType(struct ar3k_config_info *pConfig, u32 *code)
-{
-    u8 hciCommand[] =  {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
-    u8 *event;
-    u8 *bufferToFree = NULL;
-    u32 reg;
-    int result = A_ERROR;
-    *code = 0;
-    hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF);
-    hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF);
-    hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF);
-    hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF);
-    if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
-
-        if(event[4] == 0xFC && event[5] == 0x00){
-               switch(event[3]){
-                case 0x05:
-                reg = event[9];
-                reg = ((reg << 8) |event[8]);
-                reg = ((reg << 8) |event[7]);
-                reg = ((reg << 8) |event[6]);
-                *code = reg;
-                result = 0;
-
-                break;
-                case 0x06:
-                    //Sleep(500);
-                break;
-            }
-        }
-
-    }
-    if(bufferToFree != NULL) {
-        kfree(bufferToFree);
-   }
-    return result;
-}
-
-
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
deleted file mode 100644 (file)
index d443513..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * This file defines the symbols exported by Atheros PS and patch download module.
- * define the constant HCI_TRANSPORT_SDIO if the module is being used for HCI SDIO transport.
- * defined.
- *
- *
- * ar3kcpsconfig.h
- *
- *
- *
- * The software source and binaries included in this development package are
- * licensed, not sold. You, or your company, received the package under one
- * or more license agreements. The rights granted to you are specifically
- * listed in these license agreement(s). All other rights remain with Atheros
- * Communications, Inc., its subsidiaries, or the respective owner including
- * those listed on the included copyright notices..  Distribution of any
- * portion of this package must be in strict compliance with the license
- * agreement(s) terms.
- *
- *
- *
- */
-
-
-
-#ifndef __AR3KPSCONFIG_H
-#define __AR3KPSCONFIG_H
-
-/* 
- * Define the flag HCI_TRANSPORT_SDIO and undefine HCI_TRANSPORT_UART if the transport being used is SDIO.
- */
-#undef HCI_TRANSPORT_UART
-
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-
-
-#include <linux/ioctl.h>
-#include <linux/firmware.h>
-
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-#include "ar3kpsparser.h"
-
-#define FPGA_REGISTER  0x4FFC
-#define BDADDR_TYPE_STRING     0
-#define BDADDR_TYPE_HEX                1
-#define CONFIG_PATH      "ar3k"
-
-#define PS_ASIC_FILE      "PS_ASIC.pst"
-#define PS_FPGA_FILE      "PS_FPGA.pst"
-
-#define PATCH_FILE      "RamPatch.txt"
-#define BDADDR_FILE "ar3kbdaddr.pst"
-
-#define ROM_VER_AR3001_3_1_0   30000
-#define ROM_VER_AR3001_3_1_1   30101   
-
-
-#ifndef HCI_TRANSPORT_SDIO
-#define struct ar3k_config_info        struct hci_dev
-extern wait_queue_head_t HciEvent;
-extern wait_queue_t Eventwait;
-extern u8 *HciEventpacket;
-#endif /* #ifndef HCI_TRANSPORT_SDIO */
-
-int AthPSInitialize(struct ar3k_config_info *hdev);
-int ReadPSEvent(u8* Data);
-#endif /* __AR3KPSCONFIG_H */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
deleted file mode 100644 (file)
index b99a11a..0000000
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * This file implements the Atheros PS and patch parser.
- * It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
- *
- *
- *
- * ar3kpsparser.c
- *
- *
- *
- * The software source and binaries included in this development package are
- * licensed, not sold. You, or your company, received the package under one
- * or more license agreements. The rights granted to you are specifically
- * listed in these license agreement(s). All other rights remain with Atheros
- * Communications, Inc., its subsidiaries, or the respective owner including
- * those listed on the included copyright notices..  Distribution of any
- * portion of this package must be in strict compliance with the license
- * agreement(s) terms.
- *
- *
- *
- */
-
-
-#include "ar3kpsparser.h"
-
-#include <linux/ctype.h>
-#include <linux/kernel.h>
-
-#define BD_ADDR_SIZE            6
-#define WRITE_PATCH             8
-#define ENABLE_PATCH            11
-#define PS_RESET                2
-#define PS_WRITE                1
-#define PS_VERIFY_CRC           9
-#define CHANGE_BDADDR           15
-
-#define HCI_COMMAND_HEADER      7
-
-#define HCI_EVENT_SIZE          7
-
-#define WRITE_PATCH_COMMAND_STATUS_OFFSET 5
-
-#define PS_RAM_SIZE    2048
-
-#define RAM_PS_REGION           (1<<0)
-#define RAM_PATCH_REGION        (1<<1)
-#define RAMPS_MAX_PS_DATA_PER_TAG         20000
-#define MAX_RADIO_CFG_TABLE_SIZE  244
-#define RAMPS_MAX_PS_TAGS_PER_FILE        50
-
-#define PS_MAX_LEN                        500 
-#define LINE_SIZE_MAX                     (PS_MAX_LEN *2) 
-
-/* Constant values used by parser */
-#define BYTES_OF_PS_DATA_PER_LINE         16
-#define RAMPS_MAX_PS_DATA_PER_TAG         20000
-
-
-/* Number pf PS/Patch entries in an HCI packet */
-#define MAX_BYTE_LENGTH                   244
-
-#define SKIP_BLANKS(str) while (*str == ' ') str++
-
-enum MinBootFileFormatE
-{
-   MB_FILEFORMAT_RADIOTBL,
-   MB_FILEFORMAT_PATCH,
-   MB_FILEFORMAT_COEXCONFIG
-};
-
-enum RamPsSection
-{
-   RAM_PS_SECTION,
-   RAM_PATCH_SECTION,
-   RAM_DYN_MEM_SECTION
-};
-
-enum eType {
-   eHex,
-   edecimal
-};
-
-
-typedef struct tPsTagEntry
-{
-   u32 TagId;
-   u32 TagLen;
-   u8 *TagData;
-} tPsTagEntry, *tpPsTagEntry;
-
-typedef struct tRamPatch
-{
-   u16 Len;
-   u8 *Data;
-} tRamPatch, *ptRamPatch;
-
-
-
-struct st_ps_data_format {
-   enum eType   eDataType;
-   bool    bIsArray;
-};
-
-struct st_read_status {
-    unsigned uTagID;
-    unsigned uSection;
-    unsigned uLineCount;
-    unsigned uCharCount;
-    unsigned uByteCount;
-};
-
-
-/* Stores the number of PS Tags */
-static u32 Tag_Count = 0;
-
-/* Stores the number of patch commands */
-static u32 Patch_Count = 0;
-static u32 Total_tag_lenght = 0;
-bool BDADDR = false;
-u32 StartTagId;
-
-tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE];
-tRamPatch   RamPatch[MAX_NUM_PATCH_ENTRY];
-
-
-int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat);
-char AthReadChar(u8 *buffer, u32 len,u32 *pos);
-char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos);
-static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index);
-
-/* Function to reads the next character from the input buffer */
-char AthReadChar(u8 *buffer, u32 len,u32 *pos)
-{
-    char Ch;
-    if(buffer == NULL || *pos >=len )
-    {
-        return '\0';
-    } else {
-        Ch = buffer[*pos];
-        (*pos)++;
-        return Ch;
-    }
-}
-/* PS parser helper function */
-unsigned int uGetInputDataFormat(char *pCharLine, struct st_ps_data_format *pstFormat)
-{
-    if(pCharLine[0] != '[') {
-        pstFormat->eDataType = eHex;
-        pstFormat->bIsArray = true;
-        return 0;
-    }
-    switch(pCharLine[1]) {
-        case 'H':
-        case 'h':
-        if(pCharLine[2]==':') {
-            if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) {
-                if(pCharLine[4] == ']') {
-                    pstFormat->eDataType = eHex;
-                    pstFormat->bIsArray = true;
-                    pCharLine += 5;
-                    return 0;
-                }
-                else {
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
-                    return 1;
-                }
-            }
-            if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) {
-                if(pCharLine[4] == ']') {
-                    pstFormat->eDataType = eHex;
-                    pstFormat->bIsArray = false;
-                    pCharLine += 5;
-                    return 0;
-                }
-                else {
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
-                    return 1;
-                }
-            }
-            else if(pCharLine[3] == ']') {         //[H:]
-                pstFormat->eDataType = eHex;
-                pstFormat->bIsArray = true;
-                pCharLine += 4;
-                return 0;
-            }
-            else {                            //[H:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
-                return 1;                    
-            }
-        }
-        else if(pCharLine[2]==']') {    //[H]
-            pstFormat->eDataType = eHex;
-            pstFormat->bIsArray = true;
-            pCharLine += 3;
-            return 0;
-        }
-        else {                      //[H
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
-            return 1;            
-        }
-        break;
-
-        case 'A':
-        case 'a':
-        if(pCharLine[2]==':') {
-            if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
-                if(pCharLine[4] == ']') {
-                    pstFormat->eDataType = eHex;
-                    pstFormat->bIsArray = true;
-                    pCharLine += 5;
-                    return 0;
-                }
-                else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 1\n")); //[A:H
-                    return 1;
-                }
-             }
-            else if(pCharLine[3]== ']') {         //[A:]
-                pstFormat->eDataType = eHex;
-                pstFormat->bIsArray = true;
-                pCharLine += 4;
-                return 0;
-            }
-            else {                            //[A:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 2\n"));
-                return 1;                    
-            }
-        }
-        else if(pCharLine[2]==']') {    //[H]
-            pstFormat->eDataType = eHex;
-            pstFormat->bIsArray = true;
-            pCharLine += 3;
-            return 0;
-        }
-        else {                      //[H
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 3\n"));
-            return 1;            
-        }
-        break;
-
-        case 'S':
-        case 's':
-        if(pCharLine[2]==':') {
-            if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
-                if(pCharLine[4] == ']') {
-                    pstFormat->eDataType = eHex;
-                    pstFormat->bIsArray = true;
-                    pCharLine += 5;
-                    return 0;
-                }
-                else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 5\n")); //[A:H
-                    return 1;
-                }
-             }
-            else if(pCharLine[3]== ']') {         //[A:]
-                pstFormat->eDataType = eHex;
-                pstFormat->bIsArray = true;
-                pCharLine += 4;
-                return 0;
-            }
-            else {                            //[A:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 6\n"));
-                return 1;                    
-            }
-        }
-        else if(pCharLine[2]==']') {    //[H]
-            pstFormat->eDataType = eHex;
-            pstFormat->bIsArray = true;
-            pCharLine += 3;
-            return 0;
-        }
-        else {                      //[H
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 7\n"));
-            return 1;            
-        }
-        break;
-    
-        default:
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 8\n"));
-        return 1;
-    }
-}
-
-unsigned int uReadDataInSection(char *pCharLine, struct st_ps_data_format stPS_DataFormat)
-{
-    char *pTokenPtr = pCharLine;
-
-    if(pTokenPtr[0] == '[') {
-        while(pTokenPtr[0] != ']' && pTokenPtr[0] != '\0') {
-            pTokenPtr++;
-        }
-        if(pTokenPtr[0] == '\0') {
-            return (0x0FFF);
-        }
-        pTokenPtr++;
-            
-
-    }
-    if(stPS_DataFormat.eDataType == eHex) {
-        if(stPS_DataFormat.bIsArray == true) {
-            //Not implemented
-            return (0x0FFF);
-        }
-        else {
-            return (A_STRTOL(pTokenPtr, NULL, 16));
-        }
-    }
-    else {
-        //Not implemented
-        return (0x0FFF);
-    }
-}
-int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat)
-{
-   char *Buffer;
-   char *pCharLine;
-   u8 TagCount;
-   u16 ByteCount;
-   u8 ParseSection=RAM_PS_SECTION;
-   u32 pos;
-
-
-
-   int uReadCount;
-   struct st_ps_data_format stPS_DataFormat;
-   struct st_read_status   stReadStatus = {0, 0, 0,0};
-   pos = 0;
-   Buffer = NULL;
-
-   if (srcbuffer == NULL || srclen == 0)
-   {
-      AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not open .\n"));
-      return A_ERROR;
-   }
-   TagCount = 0;
-   ByteCount = 0;
-   Buffer = A_MALLOC(LINE_SIZE_MAX + 1);
-   if(NULL == Buffer) {
-       return A_ERROR;
-   }
-   if (FileFormat == MB_FILEFORMAT_PATCH)
-   {
-      int LineRead = 0;
-      while((pCharLine = AthGetLine(Buffer, LINE_SIZE_MAX, srcbuffer,srclen,&pos)) != NULL)
-      {
-
-         SKIP_BLANKS(pCharLine);
-
-         // Comment line or empty line
-         if ((pCharLine[0] == '/') && (pCharLine[1] == '/'))
-         {
-            continue;
-         }
-         
-         if ((pCharLine[0] == '#')) { 
-             if (stReadStatus.uSection != 0)
-             {
-                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n"));
-                 if(Buffer != NULL) {
-                     kfree(Buffer);
-                 }
-                 return A_ERROR;
-             }
-             else {
-                 stReadStatus.uSection = 1;
-                 continue;
-             }
-         }
-         if ((pCharLine[0] == '/') && (pCharLine[1] == '*'))
-         {
-            pCharLine+=2;
-            SKIP_BLANKS(pCharLine);
-
-            if(!strncmp(pCharLine,"PA",2)||!strncmp(pCharLine,"Pa",2)||!strncmp(pCharLine,"pa",2))
-                ParseSection=RAM_PATCH_SECTION;
-
-            if(!strncmp(pCharLine,"DY",2)||!strncmp(pCharLine,"Dy",2)||!strncmp(pCharLine,"dy",2))
-                ParseSection=RAM_DYN_MEM_SECTION;
-
-            if(!strncmp(pCharLine,"PS",2)||!strncmp(pCharLine,"Ps",2)||!strncmp(pCharLine,"ps",2))
-                ParseSection=RAM_PS_SECTION;
-
-            LineRead = 0;
-            stReadStatus.uSection = 0;
-
-            continue;
-    }
-         
-         switch(ParseSection)
-         {
-             case RAM_PS_SECTION:
-             {
-                 if (stReadStatus.uSection == 1)  //TagID
-                 {
-                    SKIP_BLANKS(pCharLine);
-                    if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
-                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n"));
-                     if(Buffer != NULL) {
-                             kfree(Buffer);
-                     }
-                        return A_ERROR;
-                    }    
-                    //pCharLine +=5;
-                    PsTagEntry[TagCount].TagId = uReadDataInSection(pCharLine, stPS_DataFormat);                            
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG ID %d \n",PsTagEntry[TagCount].TagId));
-
-                    //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag # %x\n", PsTagEntry[TagCount].TagId);
-                    if (TagCount == 0)
-                    {
-                       StartTagId = PsTagEntry[TagCount].TagId;
-                    }
-                    stReadStatus.uSection = 2;
-                 }
-                 else if (stReadStatus.uSection == 2) //TagLength
-                 {
-            
-                    if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
-                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n"));
-                     if(Buffer != NULL) {
-                             kfree(Buffer);
-                     }
-                        return A_ERROR;
-                    }
-                    //pCharLine +=5;
-                    ByteCount = uReadDataInSection(pCharLine, stPS_DataFormat);
-
-                    //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag length %x\n", ByteCount));
-                    if (ByteCount > LINE_SIZE_MAX/2)
-                    {
-                     if(Buffer != NULL) {
-                             kfree(Buffer);
-                     }
-                       return A_ERROR;
-                    }
-                    PsTagEntry[TagCount].TagLen = ByteCount;
-                    PsTagEntry[TagCount].TagData = (u8 *)A_MALLOC(ByteCount);
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d  Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount));
-                    stReadStatus.uSection = 3;
-                    stReadStatus.uLineCount = 0;
-                 }
-                 else if( stReadStatus.uSection == 3) {  //Data
-
-                    if(stReadStatus.uLineCount == 0) {
-                        if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) {
-                            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n"));
-                            if(Buffer != NULL) {
-                                 kfree(Buffer);
-                         }
-                            return A_ERROR;
-                        }
-                        //pCharLine +=5;
-                    }
-           SKIP_BLANKS(pCharLine);
-                    stReadStatus.uCharCount = 0;
-            if(pCharLine[stReadStatus.uCharCount] == '[') {
-            while(pCharLine[stReadStatus.uCharCount] != ']' && pCharLine[stReadStatus.uCharCount] != '\0' ) {
-                            stReadStatus.uCharCount++;
-            }
-            if(pCharLine[stReadStatus.uCharCount] == ']' ) {
-                            stReadStatus.uCharCount++;
-            } else {
-                            stReadStatus.uCharCount = 0;
-            }
-            }
-                    uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount;
-                    //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" "));
-                    if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) {
-                       while(uReadCount > 0) {
-                           PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] =
-                                                     (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4)
-                                                     | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1]));
-
-                           PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] =
-                                                     (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4)
-                                                     | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4]));
-
-                           stReadStatus.uCharCount += 6; // read two bytes, plus a space;
-                           stReadStatus.uByteCount += 2;
-                           uReadCount -= 2;
-                       }
-                       if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) {
-                              ByteCount -= BYTES_OF_PS_DATA_PER_LINE;
-                       }
-                       else {
-                          ByteCount = 0;
-                       }
-                    }
-                    else {
-                        //to be implemented
-                    }
-
-                    stReadStatus.uLineCount++;
-                    
-                    if(ByteCount == 0) {
-                        stReadStatus.uSection = 0;
-                        stReadStatus.uCharCount = 0;
-                        stReadStatus.uLineCount = 0;
-                        stReadStatus.uByteCount = 0;
-                    }
-                    else { 
-                        stReadStatus.uCharCount = 0;
-                    }
-
-                    if((stReadStatus.uSection == 0)&&(++TagCount == RAMPS_MAX_PS_TAGS_PER_FILE))
-                    {
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!"));
-                       if(Buffer != NULL) {
-                           kfree(Buffer);
-                       }
-                       return A_ERROR;
-                       //Sleep (3000);
-                       //exit(1);
-                    }
-        
-                 }
-             }
-
-             break;
-             default:
-             {
-                   if(Buffer != NULL) {
-                       kfree(Buffer);
-                   }
-                   return A_ERROR;
-             }
-             break;
-         }
-         LineRead++;
-      }
-      Tag_Count = TagCount;
-      AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Number of Tags %d\n", Tag_Count));
-   }
-
-
-   if (TagCount > RAMPS_MAX_PS_TAGS_PER_FILE)
-   {
-
-      if(Buffer != NULL) {
-           kfree(Buffer);
-      }
-      return A_ERROR;
-   }
-
-   if(Buffer != NULL) {
-        kfree(Buffer);
-   }
-   return 0;
-
-}
-
-
-
-/********************/
-
-
-int GetNextTwoChar(u8 *srcbuffer,u32 len, u32 *pos, char *buffer)
-{
-    unsigned char ch;
-
-    ch = AthReadChar(srcbuffer,len,pos);
-    if(ch != '\0' && isxdigit(ch)) {
-        buffer[0] =  ch;
-    } else 
-    {
-        return A_ERROR;
-    }
-    ch = AthReadChar(srcbuffer,len,pos);
-    if(ch != '\0' && isxdigit(ch)) {
-        buffer[1] =  ch;
-    } else 
-    {
-        return A_ERROR;
-    }
-    return 0;
-}
-
-int AthDoParsePatch(u8 *patchbuffer, u32 patchlen)
-{
-
-    char Byte[3];
-    char Line[MAX_BYTE_LENGTH + 1];
-    int    ByteCount,ByteCount_Org;
-    int count;
-    int i,j,k;
-    int data;
-    u32 filepos;
-    Byte[2] = '\0';
-    j = 0;
-    filepos = 0;
-    Patch_Count = 0;
-
-    while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) {
-        if(strlen(Line) <= 1 || !isxdigit(Line[0])) {
-            continue;
-        } else {
-            break;
-        }
-    }
-    ByteCount = A_STRTOL(Line, NULL, 16);
-    ByteCount_Org = ByteCount;
-
-    while(ByteCount > MAX_BYTE_LENGTH){
-
-        /* Handle case when the number of patch buffer is more than the 20K */
-        if(MAX_NUM_PATCH_ENTRY == Patch_Count) {
-            for(i = 0; i < Patch_Count; i++) {
-                kfree(RamPatch[i].Data);
-            }
-            return A_ERROR;
-        }
-        RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH;
-        RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(MAX_BYTE_LENGTH);
-        Patch_Count ++;
-
-
-        ByteCount= ByteCount - MAX_BYTE_LENGTH;
-    }
-
-    RamPatch[Patch_Count].Len= (ByteCount & 0xFF);
-    if(ByteCount != 0) {
-        RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(ByteCount);
-        Patch_Count ++;
-    }
-    count = 0;
-    while(ByteCount_Org > MAX_BYTE_LENGTH){
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
-        for (i = 0,k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++,count +=2) {
-            if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
-                return A_ERROR;
-            }
-            data = A_STRTOUL(&Byte[0], NULL, 16);
-            RamPatch[j].Data[k] = (data & 0xFF);
-
-
-        }
-        j++;
-        ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH;
-    }
-    if(j == 0){
-        j++;
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
-    for (k=0; k < ByteCount_Org; i += 2,k++,count+=2) {
-        if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
-            return A_ERROR;
-        }
-        data = A_STRTOUL(Byte, NULL, 16);
-        RamPatch[j].Data[k] = (data & 0xFF);
-
-
-    }
-    return 0;
-}
-
-
-/********************/
-int AthDoParsePS(u8 *srcbuffer, u32 srclen)
-{
-    int status;
-    int i;
-    bool BDADDR_Present = false;
-
-    Tag_Count = 0;
-
-    Total_tag_lenght = 0;
-    BDADDR = false;
-
-
-    status = A_ERROR;
-
-    if(NULL != srcbuffer && srclen != 0)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("File Open Operation Successful\n"));
-
-        status = AthParseFilesUnified(srcbuffer,srclen,MB_FILEFORMAT_PATCH); 
-    }
-    
-
-
-        if(Tag_Count == 0){
-                Total_tag_lenght = 10;
-
-        }
-        else{
-                for(i=0; i<Tag_Count; i++){
-                        if(PsTagEntry[i].TagId == 1){
-                                BDADDR_Present = true;
-                                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is present in Patch File \r\n"));
-
-                        }
-                        if(PsTagEntry[i].TagLen % 2 == 1){
-                                Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1;
-                        }
-                        else{
-                                Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen;
-                        }
-
-                }
-        }
-
-        if(Tag_Count > 0 && !BDADDR_Present){
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is not present adding 10 extra bytes \r\n"));
-                Total_tag_lenght=Total_tag_lenght + 10;
-        }
-        Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4);
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Total Length %d\n",Total_tag_lenght));
-
-
-    return status;
-}
-char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos)
-{
-
-    int count;
-    static short flag;
-    char CharRead;
-    count = 0;
-    flag = A_ERROR;
-
-    do
-    {
-        CharRead = AthReadChar(srcbuffer,len,pos);
-        if( CharRead == '\0' ) {
-            buffer[count+1] = '\0';
-            if(count == 0) {
-                return NULL;
-            }
-            else {
-                return buffer;
-            }
-        }
-
-        if(CharRead == 13) {
-        } else if(CharRead == 10) {
-            buffer[count] ='\0';  
-            flag = A_ERROR;
-            return buffer;
-        }else {
-            buffer[count++] = CharRead;
-        }
-
-    }
-    while(count < maxlen-1 && CharRead != '\0');
-    buffer[count] = '\0';
-
-    return buffer;
-}
-
-static void LoadHeader(u8 *HCI_PS_Command,u8 opcode,int length,int index){
-
-        HCI_PS_Command[0]= 0x0B;
-        HCI_PS_Command[1]= 0xFC;
-        HCI_PS_Command[2]= length + 4;
-        HCI_PS_Command[3]= opcode;
-        HCI_PS_Command[4]= (index & 0xFF);
-        HCI_PS_Command[5]= ((index>>8) & 0xFF);
-        HCI_PS_Command[6]= length;
-}
-
-/////////////////////////
-//
-int AthCreateCommandList(struct ps_cmd_packet **HciPacketList, u32 *numPackets)
-{
-
-    u8 count;
-    u32 NumcmdEntry = 0;
-
-    u32 Crc = 0;
-    *numPackets = 0;
-
-
-    if(Patch_Count > 0)
-            Crc |= RAM_PATCH_REGION;
-    if(Tag_Count > 0)
-            Crc |= RAM_PS_REGION;
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Thread Started CRC %x Patch Count %d  Tag Count %d \n",Crc,Patch_Count,Tag_Count));
-    
-    if(Patch_Count || Tag_Count ){
-    NumcmdEntry+=(2 + Patch_Count + Tag_Count); /* CRC Packet + PS Reset Packet  + Patch List + PS List*/
-        if(Patch_Count > 0) {
-            NumcmdEntry++; /* Patch Enable Command */
-        }
-           AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size  %d  \r\n",NumcmdEntry,(u32)sizeof(struct ps_cmd_packet) * NumcmdEntry));
-        (*HciPacketList) = A_MALLOC(sizeof(struct ps_cmd_packet) * NumcmdEntry);
-    if(NULL == *HciPacketList) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed  \r\n"));
-        }
-        AthPSCreateHCICommand(PS_VERIFY_CRC,Crc,*HciPacketList,numPackets);
-        if(Patch_Count > 0){
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Write Patch**** \r\n"));
-                AthPSCreateHCICommand(WRITE_PATCH,Patch_Count,*HciPacketList,numPackets);
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Enable Patch**** \r\n"));
-                AthPSCreateHCICommand(ENABLE_PATCH,0,*HciPacketList,numPackets);
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Reset**** %d[0x%x] \r\n",PS_RAM_SIZE,PS_RAM_SIZE));
-               AthPSCreateHCICommand(PS_RESET,PS_RAM_SIZE,*HciPacketList,numPackets);
-        if(Tag_Count > 0){
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Write**** \r\n"));
-                AthPSCreateHCICommand(PS_WRITE,Tag_Count,*HciPacketList,numPackets);
-        }    
-    }
-    if(!BDADDR){
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR not present \r\n"));
-    
-    }
-    for(count = 0; count < Patch_Count; count++) {
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count));
-       kfree(RamPatch[count].Data);
-    }
-
-    for(count = 0; count < Tag_Count; count++) {
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count));
-        kfree(PsTagEntry[count].TagData);
-    }
-
-/* 
- *  SDIO Transport uses synchronous mode of data transfer 
- *  So, AthPSOperations() call returns only after receiving the 
- *  command complete event.
- */
-    return *numPackets;
-}
-
-
-////////////////////////
-
-/////////////
-static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index)
-{
-    u8 *HCI_PS_Command;
-    u32 Length;
-    int i,j;
-    
-    switch(Opcode)
-    {
-    case WRITE_PATCH:
-
-
-         for(i=0;i< Param1;i++){
-
-             HCI_PS_Command = (u8 *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER);
-             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER));
-                 if(HCI_PS_Command == NULL){
-                     AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
-                         return A_ERROR;
-                 }
-                 memset (HCI_PS_Command, 0, RamPatch[i].Len+HCI_COMMAND_HEADER);
-                 LoadHeader(HCI_PS_Command,Opcode,RamPatch[i].Len,i);
-                 for(j=0;j<RamPatch[i].Len;j++){
-                        HCI_PS_Command[HCI_COMMAND_HEADER+j]=RamPatch[i].Data[j];
-                 }
-                 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
-                 PSPatchPacket[*index].packetLen = RamPatch[i].Len+HCI_COMMAND_HEADER;
-                 (*index)++;
-
-          
-         }
-
-    break;
-
-    case ENABLE_PATCH:
-
-
-         Length = 0;
-         i= 0;
-         HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
-         if(HCI_PS_Command == NULL){
-             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
-            return A_ERROR;
-         }
-
-         memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
-         LoadHeader(HCI_PS_Command,Opcode,Length,i);
-         PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
-         PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
-         (*index)++;
-
-    break;
-
-    case PS_RESET:
-                        Length = 0x06;
-                        i=0;
-                        HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
-                        if(HCI_PS_Command == NULL){
-                                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
-                                return A_ERROR;
-                        }
-                        memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
-                        LoadHeader(HCI_PS_Command,Opcode,Length,i);
-                        HCI_PS_Command[7]= 0x00;
-                        HCI_PS_Command[Length+HCI_COMMAND_HEADER -2]= (Param1 & 0xFF);
-                        HCI_PS_Command[Length+HCI_COMMAND_HEADER -1]= ((Param1 >>  8) & 0xFF);
-                 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
-                 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
-                 (*index)++;
-
-    break;
-
-    case PS_WRITE:
-                       for(i=0;i< Param1;i++){
-                                if(PsTagEntry[i].TagId ==1)
-                                        BDADDR = true;
-
-                                HCI_PS_Command = (u8 *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
-                                if(HCI_PS_Command == NULL){
-                                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
-                                        return A_ERROR;
-                                }
-
-                                memset (HCI_PS_Command, 0, PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
-                                LoadHeader(HCI_PS_Command,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId);
-
-                                for(j=0;j<PsTagEntry[i].TagLen;j++){
-                                        HCI_PS_Command[HCI_COMMAND_HEADER+j]=PsTagEntry[i].TagData[j];
-                                }
-
-                     PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
-                     PSPatchPacket[*index].packetLen = PsTagEntry[i].TagLen+HCI_COMMAND_HEADER;
-                     (*index)++;
-
-                        }
-
-    break;
-
-
-    case PS_VERIFY_CRC:
-                        Length = 0x0;
-
-                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index));
-
-                        HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER);
-                        if(HCI_PS_Command == NULL){
-                                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
-                                return A_ERROR;
-                        }
-                        memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
-                        LoadHeader(HCI_PS_Command,Opcode,Length,Param1);
-
-                 PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
-                 PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
-                 (*index)++;
-
-    break;
-
-    case CHANGE_BDADDR:
-    break;
-    }
-    return 0;
-}
-int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets)
-{
-    int i;
-    if(*HciPacketList == NULL) {
-        return A_ERROR;
-    }
-    for(i = 0; i < numPackets;i++) {
-        kfree((*HciPacketList)[i].Hcipacket);
-    }  
-    kfree(*HciPacketList);
-    return 0;
-}
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
deleted file mode 100644 (file)
index 4e0f2f7..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 is the include file for Atheros PS and patch parser.
-// It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
-//
-
-#ifndef __AR3KPSPARSER_H
-#define __AR3KPSPARSER_H
-
-
-
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "athdefs.h"
-#ifdef HCI_TRANSPORT_SDIO
-#include "a_config.h"
-#include "a_osapi.h"
-#define ATH_MODULE_NAME misc
-#include "a_debug.h"
-#include "common_drv.h"
-#include "hci_transport_api.h"
-#include "ar3kconfig.h"
-#else
-#ifndef A_PRINTF
-#define A_PRINTF(args...)     printk(KERN_ALERT args)
-#endif /* A_PRINTF */
-#include "debug_linux.h"
-
-/* Helper data type declaration */
-
-#define ATH_DEBUG_ERR          (1 << 0)
-#define ATH_DEBUG_WARN         (1 << 1)
-#define ATH_DEBUG_INFO         (1 << 2)
-
-
-
-#define false   0
-#define true    1
-
-#ifndef A_MALLOC
-#define A_MALLOC(size)  kmalloc((size),GFP_KERNEL)
-#endif /* A_MALLOC */
-#endif /* HCI_TRANSPORT_UART */
-
-/* String manipulation APIs */
-#ifndef A_STRTOUL
-#define A_STRTOUL               simple_strtoul
-#endif  /* A_STRTOL */
-
-#ifndef A_STRTOL 
-#define A_STRTOL                simple_strtol
-#endif /* A_STRTOL */
-
-
-/* The maximum number of bytes possible in a patch entry */
-#define MAX_PATCH_SIZE                    20000
-
-/* Maximum HCI packets that will be formed from the Patch file */
-#define MAX_NUM_PATCH_ENTRY               (MAX_PATCH_SIZE/MAX_BYTE_LENGTH) + 1
-
-
-
-
-
-
-
-struct ps_cmd_packet
-{
-    u8 *Hcipacket;
-    int packetLen;
-};
-
-/* Parses a Patch information buffer and store it in global structure */
-int AthDoParsePatch(u8 *, u32 );
-
-/* parses a PS information buffer and stores it in a global structure */
-int AthDoParsePS(u8 *, u32 );
-
-/* 
- *  Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with
- *  all the PS and patch commands.
- *  The list will have the below mentioned commands in order.
- *  CRC command packet
- *  Download patch command(s)
- *  Enable patch Command
- *  PS Reset Command
- *  PS Tag Command(s)
- *
- */  
-int AthCreateCommandList(struct ps_cmd_packet **, u32 *);
-
-/* Cleanup the dynamically allicated HCI command list */
-int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets);
-#endif /* __AR3KPSPARSER_H */
diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c
deleted file mode 100644 (file)
index 1ce539a..0000000
+++ /dev/null
@@ -1,910 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="common_drv.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "a_config.h"
-#include "athdefs.h"
-
-#include "hw/mbox_host_reg.h"
-#include "gpio_reg.h"
-#include "hw/rtc_reg.h"
-#include "hw/mbox_reg.h"
-#include "hw/apb_map.h"
-
-#include "a_osapi.h"
-#include "targaddrs.h"
-#include "hif.h"
-#include "htc_api.h"
-#include "wmi.h"
-#include "bmi.h"
-#include "bmi_msg.h"
-#include "common_drv.h"
-#define ATH_MODULE_NAME misc
-#include "a_debug.h"
-#include "ar6000_diag.h"
-
-static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL;
-static A_MUTEX_T                 g_ModuleListLock;
-static bool                    g_ModuleDebugInit = false;
-
-#ifdef ATH_DEBUG_MODULE
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc,
-                                 "misc",
-                                 "Common and misc APIs",
-                                 ATH_DEBUG_MASK_DEFAULTS,
-                                 0,
-                                 NULL);
-
-#endif
-
-#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
-        ((((target) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
-         (((target) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)))
-
-
-#define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080
-#define AR6002_LOCAL_COUNT_ADDRESS 0x00018080
-#define AR6003_LOCAL_COUNT_ADDRESS 0x00018080
-#define CPU_DBG_SEL_ADDRESS                      0x00000483
-#define CPU_DBG_ADDRESS                          0x00000484
-
-static u8 custDataAR6002[AR6002_CUST_DATA_SIZE];
-static u8 custDataAR6003[AR6003_CUST_DATA_SIZE];
-
-/* Compile the 4BYTE version of the window register setup routine,
- * This mitigates host interconnect issues with non-4byte aligned bus requests, some
- * interconnects use bus adapters that impose strict limitations.
- * Since diag window access is not intended for performance critical operations, the 4byte mode should
- * be satisfactory even though it generates 4X the bus activity. */
-
-#ifdef USE_4BYTE_REGISTER_ACCESS
-
-    /* set the window address register (using 4-byte register access ). */
-int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
-{
-    int status;
-    u8 addrValue[4];
-    s32 i;
-
-        /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
-         * last to initiate the access cycle */
-
-    for (i = 1; i <= 3; i++) {
-            /* fill the buffer with the address byte value we want to hit 4 times*/
-        addrValue[0] = ((u8 *)&Address)[i];
-        addrValue[1] = addrValue[0];
-        addrValue[2] = addrValue[0];
-        addrValue[3] = addrValue[0];
-
-            /* hit each byte of the register address with a 4-byte write operation to the same address,
-             * this is a harmless operation */
-        status = HIFReadWrite(hifDevice,
-                              RegisterAddr+i,
-                              addrValue,
-                              4,
-                              HIF_WR_SYNC_BYTE_FIX,
-                              NULL);
-        if (status) {
-            break;
-        }
-    }
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
-            Address, RegisterAddr));
-        return status;
-    }
-
-        /* write the address register again, this time write the whole 4-byte value.
-         * The effect here is that the LSB write causes the cycle to start, the extra
-         * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */
-    status = HIFReadWrite(hifDevice,
-                          RegisterAddr,
-                          (u8 *)(&Address),
-                          4,
-                          HIF_WR_SYNC_BYTE_INC,
-                          NULL);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
-            Address, RegisterAddr));
-        return status;
-    }
-
-    return 0;
-
-
-
-}
-
-
-#else
-
-    /* set the window address register */
-int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
-{
-    int status;
-
-        /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
-         * last to initiate the access cycle */
-    status = HIFReadWrite(hifDevice,
-                          RegisterAddr+1,  /* write upper 3 bytes */
-                          ((u8 *)(&Address))+1,
-                          sizeof(u32)-1,
-                          HIF_WR_SYNC_BYTE_INC,
-                          NULL);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
-             RegisterAddr, Address));
-        return status;
-    }
-
-        /* write the LSB of the register, this initiates the operation */
-    status = HIFReadWrite(hifDevice,
-                          RegisterAddr,
-                          (u8 *)(&Address),
-                          sizeof(u8),
-                          HIF_WR_SYNC_BYTE_INC,
-                          NULL);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
-            RegisterAddr, Address));
-        return status;
-    }
-
-    return 0;
-}
-
-#endif
-
-/*
- * Read from the AR6000 through its diagnostic window.
- * No cooperation from the Target is required for this.
- */
-int
-ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
-{
-    int status;
-
-        /* set window register to start read cycle */
-    status = ar6000_SetAddressWindowRegister(hifDevice,
-                                             WINDOW_READ_ADDR_ADDRESS,
-                                             *address);
-
-    if (status) {
-        return status;
-    }
-
-        /* read the data */
-    status = HIFReadWrite(hifDevice,
-                          WINDOW_DATA_ADDRESS,
-                          (u8 *)data,
-                          sizeof(u32),
-                          HIF_RD_SYNC_BYTE_INC,
-                          NULL);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
-        return status;
-    }
-
-    return status;
-}
-
-
-/*
- * Write to the AR6000 through its diagnostic window.
- * No cooperation from the Target is required for this.
- */
-int
-ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
-{
-    int status;
-
-        /* set write data */
-    status = HIFReadWrite(hifDevice,
-                          WINDOW_DATA_ADDRESS,
-                          (u8 *)data,
-                          sizeof(u32),
-                          HIF_WR_SYNC_BYTE_INC,
-                          NULL);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data));
-        return status;
-    }
-
-        /* set window register, which starts the write cycle */
-    return ar6000_SetAddressWindowRegister(hifDevice,
-                                           WINDOW_WRITE_ADDR_ADDRESS,
-                                           *address);
-    }
-
-int
-ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
-                    u8 *data, u32 length)
-{
-    u32 count;
-    int status = 0;
-
-    for (count = 0; count < length; count += 4, address += 4) {
-        if ((status = ar6000_ReadRegDiag(hifDevice, &address,
-                                         (u32 *)&data[count])) != 0)
-        {
-            break;
-        }
-    }
-
-    return status;
-}
-
-int
-ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
-                    u8 *data, u32 length)
-{
-    u32 count;
-    int status = 0;
-
-    for (count = 0; count < length; count += 4, address += 4) {
-        if ((status = ar6000_WriteRegDiag(hifDevice, &address,
-                                         (u32 *)&data[count])) != 0)
-        {
-            break;
-        }
-    }
-
-    return status;
-}
-
-int
-ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval)
-{
-    int status;
-    u8 vals[4];
-    u8 register_selection[4];
-
-    register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff);
-    status = HIFReadWrite(hifDevice,
-                          CPU_DBG_SEL_ADDRESS,
-                          register_selection,
-                          4,
-                          HIF_WR_SYNC_BYTE_FIX,
-                          NULL);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
-        return status;
-    }
-
-    status = HIFReadWrite(hifDevice,
-                          CPU_DBG_ADDRESS,
-                          (u8 *)vals,
-                          sizeof(vals),
-                          HIF_RD_SYNC_BYTE_INC,
-                          NULL);
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n"));
-        return status;
-    }
-
-    *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24;
-
-    return status;
-}
-
-void
-ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs)
-{
-    int i;
-    u32 val;
-
-    for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
-        val=0xffffffff;
-        (void)ar6k_ReadTargetRegister(hifDevice, i, &val);
-        targregs[i] = val;
-    }
-}
-
-#if 0
-static int
-_do_write_diag(struct hif_device *hifDevice, u32 addr, u32 value)
-{
-    int status;
-
-    status = ar6000_WriteRegDiag(hifDevice, &addr, &value);
-    if (status)
-    {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
-    }
-
-    return status;
-}
-#endif
-
-
-/*
- * Delay up to wait_msecs millisecs to allow Target to enter BMI phase,
- * which is a good sign that it's alive and well.  This is used after
- * explicitly forcing the Target to reset.
- *
- * The wait_msecs time should be sufficiently long to cover any reasonable
- * boot-time delay.  For instance, AR6001 firmware allow one second for a
- * low frequency crystal to settle before it calibrates the refclk frequency.
- *
- * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE.
- */
-#if 0
-static int
-_delay_until_target_alive(struct hif_device *hifDevice, s32 wait_msecs, u32 TargetType)
-{
-    s32 actual_wait;
-    s32 i;
-    u32 address;
-
-    actual_wait = 0;
-
-    /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */
-    if (TargetType == TARGET_TYPE_AR6002) {
-       address = AR6002_LOCAL_COUNT_ADDRESS;
-    } else if (TargetType == TARGET_TYPE_AR6003) {
-       address = AR6003_LOCAL_COUNT_ADDRESS;
-    } else {
-       A_ASSERT(0);
-    }
-    address += 0x10;
-    for (i=0; actual_wait < wait_msecs; i++) {
-        u32 data;
-
-        A_MDELAY(100);
-        actual_wait += 100;
-
-        data = 0;
-        if (ar6000_ReadRegDiag(hifDevice, &address, &data) != 0) {
-            return A_ERROR;
-        }
-
-        if (data != 0) {
-            /* No need to wait longer -- we have a BMI credit */
-            return 0;
-        }
-    }
-    return A_ERROR; /* timed out */
-}
-#endif
-
-#define AR6001_RESET_CONTROL_ADDRESS 0x0C000000
-#define AR6002_RESET_CONTROL_ADDRESS 0x00004000
-#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
-/* reset device */
-int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset)
-{
-    int status = 0;
-    u32 address;
-    u32 data;
-
-    do {
-// Workaround BEGIN
-        // address = RESET_CONTROL_ADDRESS;
-       
-       if (coldReset) {
-            data = RESET_CONTROL_COLD_RST_MASK;
-       }
-       else {
-            data = RESET_CONTROL_MBOX_RST_MASK;
-       }
-
-          /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
-        if (TargetType == TARGET_TYPE_AR6002) {
-            address = AR6002_RESET_CONTROL_ADDRESS;
-        } else if (TargetType == TARGET_TYPE_AR6003) {
-            address = AR6003_RESET_CONTROL_ADDRESS;
-        } else {
-            A_ASSERT(0);
-        }
-
-
-        status = ar6000_WriteRegDiag(hifDevice, &address, &data);
-
-        if (status) {
-            break;
-        }
-
-        if (!waitForCompletion) {
-            break;
-        }
-
-#if 0
-        /* Up to 2 second delay to allow things to settle down */
-        (void)_delay_until_target_alive(hifDevice, 2000, TargetType);
-
-        /*
-         * Read back the RESET CAUSE register to ensure that the cold reset
-         * went through.
-         */
-
-        // address = RESET_CAUSE_ADDRESS;
-        /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
-        if (TargetType == TARGET_TYPE_AR6002) {
-            address = 0x000040C0;
-        } else if (TargetType == TARGET_TYPE_AR6003) {
-            address = 0x000040C0;
-        } else {
-            A_ASSERT(0);
-        }
-
-        data = 0;
-        status = ar6000_ReadRegDiag(hifDevice, &address, &data);
-
-        if (status) {
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
-        data &= RESET_CAUSE_LAST_MASK;
-        if (data != 2) {
-            AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
-        }
-#endif
-// Workaroud END
-
-    } while (false);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
-    }
-
-    return 0;
-}
-
-/* This should be called in BMI phase after firmware is downloaded */
-void
-ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType)
-{
-    u32 eepHeaderAddr;
-    u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
-    s32 i;
-
-    if (BMIReadMemory(hifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
-            (u8 *)&eepHeaderAddr,
-            4)!= 0)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
-        return;
-    }
-
-    if (TargetType == TARGET_TYPE_AR6003) {
-        eepHeaderAddr += 36;  /* AR6003 customer data section offset is 37 */
-
-        for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){
-            if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&AR6003CustDataShadow[i])!= 0) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
-                return ;
-            }  
-            eepHeaderAddr +=4;
-        }
-
-        memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE);
-    }
-
-    if (TargetType == TARGET_TYPE_AR6002) {
-        eepHeaderAddr += 64;  /* AR6002 customer data sectioin offset is 64 */
-
-        for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){
-            if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&custDataAR6002[i])!= 0) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
-                return ;
-            }  
-            eepHeaderAddr +=4;
-        }
-    }
-
-    return;
-}
-
-/* This is the function to call when need to use the cust data */
-u8 *ar6000_get_cust_data_buffer(u32 TargetType)
-{
-    if (TargetType == TARGET_TYPE_AR6003)
-        return custDataAR6003;
-
-    if (TargetType == TARGET_TYPE_AR6002)
-        return custDataAR6002;
-
-    return NULL;
-}
-
-#define REG_DUMP_COUNT_AR6001   38  /* WORDs, derived from AR600x_regdump.h */
-#define REG_DUMP_COUNT_AR6002   60
-#define REG_DUMP_COUNT_AR6003   60
-#define REGISTER_DUMP_LEN_MAX   60
-#if REG_DUMP_COUNT_AR6001 > REGISTER_DUMP_LEN_MAX
-#error "REG_DUMP_COUNT_AR6001 too large"
-#endif
-#if REG_DUMP_COUNT_AR6002 > REGISTER_DUMP_LEN_MAX
-#error "REG_DUMP_COUNT_AR6002 too large"
-#endif
-#if REG_DUMP_COUNT_AR6003 > REGISTER_DUMP_LEN_MAX
-#error "REG_DUMP_COUNT_AR6003 too large"
-#endif
-
-
-void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType)
-{
-    u32 address;
-    u32 regDumpArea = 0;
-    int status;
-    u32 regDumpValues[REGISTER_DUMP_LEN_MAX];
-    u32 regDumpCount = 0;
-    u32 i;
-
-    do {
-
-            /* the reg dump pointer is copied to the host interest area */
-        address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
-        address = TARG_VTOP(TargetType, address);
-
-        if (TargetType == TARGET_TYPE_AR6002) {
-            regDumpCount = REG_DUMP_COUNT_AR6002;
-        } else  if (TargetType == TARGET_TYPE_AR6003) {
-            regDumpCount = REG_DUMP_COUNT_AR6003;
-        } else {
-            A_ASSERT(0);
-        }
-
-            /* read RAM location through diagnostic window */
-        status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));
-
-        if (regDumpArea == 0) {
-                /* no reg dump */
-            break;
-        }
-
-        regDumpArea = TARG_VTOP(TargetType, regDumpArea);
-
-            /* fetch register dump data */
-        status = ar6000_ReadDataDiag(hifDevice,
-                                     regDumpArea,
-                                     (u8 *)&regDumpValues[0],
-                                     regDumpCount * (sizeof(u32)));
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
-            break;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));
-
-        for (i = 0; i < regDumpCount; i++) {
-            //ATHR_DISPLAY_MSG (_T(" %d :  0x%8.8X \n"), i, regDumpValues[i]);
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d :  0x%8.8X \n",i, regDumpValues[i]));
-
-#ifdef UNDER_CE
-        /*
-         * For Every logPrintf() Open the File so that in case of Crashes
-         * We will have until the Last Message Flushed on to the File
-         * So use logPrintf Sparingly..!!
-         */
-        tgtassertPrintf (ATH_DEBUG_TRC," %d:  0x%8.8X \n",i, regDumpValues[i]);
-#endif
-        }
-
-    } while (false);
-
-}
-
-/* set HTC/Mbox operational parameters, this can only be called when the target is in the
- * BMI phase */
-int ar6000_set_htc_params(struct hif_device *hifDevice,
-                               u32 TargetType,
-                               u32 MboxIsrYieldValue,
-                               u8 HtcControlBuffers)
-{
-    int status;
-    u32 blocksizes[HTC_MAILBOX_NUM_MAX];
-
-    do {
-            /* get the block sizes */
-        status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
-                                    blocksizes, sizeof(blocksizes));
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n"));
-            break;
-        }
-            /* note: we actually get the block size for mailbox 1, for SDIO the block
-             * size on mailbox 0 is artificially set to 1 */
-            /* must be a power of 2 */
-        A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);
-
-        if (HtcControlBuffers != 0) {
-                /* set override for number of control buffers to use */
-            blocksizes[1] |=  ((u32)HtcControlBuffers) << 16;
-        }
-
-            /* set the host interest area for the block size */
-        status = BMIWriteMemory(hifDevice,
-                                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
-                                (u8 *)&blocksizes[1],
-                                4);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n"));
-            break;
-        }
-
-        AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n",
-                blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz)));
-
-        if (MboxIsrYieldValue != 0) {
-                /* set the host interest area for the mbox ISR yield limit */
-            status = BMIWriteMemory(hifDevice,
-                                    HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit),
-                                    (u8 *)&MboxIsrYieldValue,
-                                    4);
-
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
-                break;
-            }
-        }
-
-    } while (false);
-
-    return status;
-}
-
-void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription)
-{
-    char stream[60];
-    char byteOffsetStr[10];
-    u32 i;
-    u16 offset, count, byteOffset;
-
-    A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription);
-
-    count = 0;
-    offset = 0;
-    byteOffset = 0;
-    for(i = 0; i < length; i++) {
-        A_SPRINTF(stream + offset, "%2.2X ", buffer[i]);
-        count ++;
-        offset += 3;
-
-        if(count == 16) {
-            count = 0;
-            offset = 0;
-            A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
-            A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
-            A_MEMZERO(stream, 60);
-            byteOffset += 16;
-        }
-    }
-
-    if(offset != 0) {
-        A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
-        A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
-    }
-
-    A_PRINTF("<------------------------------------------------->\n");
-}
-
-void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
-{
-    int                         i;
-    struct ath_debug_mask_description *pDesc;
-
-    if (pInfo == NULL) {
-        return;
-    }
-
-    pDesc = pInfo->pMaskDescriptions;
-
-    A_PRINTF("========================================================\n\n");
-    A_PRINTF("Module Debug Info => Name   : %s    \n", pInfo->ModuleName);
-    A_PRINTF("                  => Descr. : %s \n", pInfo->ModuleDescription);
-    A_PRINTF("\n  Current mask    => 0x%8.8X \n", pInfo->CurrentMask);
-    A_PRINTF("\n  Avail. Debug Masks :\n\n");
-
-    for (i = 0; i < pInfo->MaxDescriptions; i++,pDesc++) {
-        A_PRINTF("                  => 0x%8.8X -- %s \n", pDesc->Mask, pDesc->Description);
-    }
-
-    if (0 == i) {
-        A_PRINTF("                  => * none defined * \n");
-    }
-
-    A_PRINTF("\n  Standard Debug Masks :\n\n");
-        /* print standard masks */
-    A_PRINTF("                  => 0x%8.8X -- Errors \n", ATH_DEBUG_ERR);
-    A_PRINTF("                  => 0x%8.8X -- Warnings \n", ATH_DEBUG_WARN);
-    A_PRINTF("                  => 0x%8.8X -- Informational \n", ATH_DEBUG_INFO);
-    A_PRINTF("                  => 0x%8.8X -- Tracing \n", ATH_DEBUG_TRC);
-    A_PRINTF("\n========================================================\n");
-
-}
-
-
-static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name)
-{
-    ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
-
-    if (!g_ModuleDebugInit) {
-        return NULL;
-    }
-
-    while (pInfo != NULL) {
-            /* TODO: need to use something other than strlen */
-        if (memcmp(pInfo->ModuleName,module_name,strlen(module_name)) == 0) {
-            break;
-        }
-        pInfo = pInfo->pNext;
-    }
-
-    return pInfo;
-}
-
-
-void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
-{
-    if (!g_ModuleDebugInit) {
-        return;
-    }
-
-    A_MUTEX_LOCK(&g_ModuleListLock);
-
-    if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) {
-        if (g_pModuleInfoHead == NULL) {
-            g_pModuleInfoHead = pInfo;
-        } else {
-           pInfo->pNext = g_pModuleInfoHead;
-           g_pModuleInfoHead = pInfo;
-        }
-        pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED;
-    }
-
-    A_MUTEX_UNLOCK(&g_ModuleListLock);
-}
-
-void a_dump_module_debug_info_by_name(char *module_name)
-{
-    ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
-
-    if (!g_ModuleDebugInit) {
-        return;
-    }
-
-    if (memcmp(module_name,"all",3) == 0) {
-            /* dump all */
-        while (pInfo != NULL) {
-            a_dump_module_debug_info(pInfo);
-            pInfo = pInfo->pNext;
-        }
-        return;
-    }
-
-    pInfo = FindModule(module_name);
-
-    if (pInfo != NULL) {
-         a_dump_module_debug_info(pInfo);
-    }
-
-}
-
-int a_get_module_mask(char *module_name, u32 *pMask)
-{
-    ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
-
-    if (NULL == pInfo) {
-        return A_ERROR;
-    }
-
-    *pMask = pInfo->CurrentMask;
-    return 0;
-}
-
-int a_set_module_mask(char *module_name, u32 Mask)
-{
-    ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
-
-    if (NULL == pInfo) {
-        return A_ERROR;
-    }
-
-    pInfo->CurrentMask = Mask;
-    A_PRINTF("Module %s,  new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask);
-    return 0;
-}
-
-
-void a_module_debug_support_init(void)
-{
-    if (g_ModuleDebugInit) {
-        return;
-    }
-    A_MUTEX_INIT(&g_ModuleListLock);
-    g_pModuleInfoHead = NULL;
-    g_ModuleDebugInit = true;
-    A_REGISTER_MODULE_DEBUG_INFO(misc);
-}
-
-void a_module_debug_support_cleanup(void)
-{
-    ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
-    ATH_DEBUG_MODULE_DBG_INFO *pCur;
-
-    if (!g_ModuleDebugInit) {
-        return;
-    }
-
-    g_ModuleDebugInit = false;
-
-    A_MUTEX_LOCK(&g_ModuleListLock);
-
-    while (pInfo != NULL) {
-        pCur = pInfo;
-        pInfo = pInfo->pNext;
-        pCur->pNext = NULL;
-            /* clear registered flag */
-        pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED;
-    }
-
-    A_MUTEX_UNLOCK(&g_ModuleListLock);
-
-    A_MUTEX_DELETE(&g_ModuleListLock);
-    g_pModuleInfoHead = NULL;
-}
-
-    /* can only be called during bmi init stage */
-int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
-                                     u32 TargetType,
-                                     u32 Flags)
-{
-    int status = 0;
-
-    do {
-
-        if (TargetType != TARGET_TYPE_AR6003) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n",
-                TargetType));
-            break;
-        }
-
-            /* set hci bridge flags */
-        status = BMIWriteMemory(hifDevice,
-                                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags),
-                                (u8 *)&Flags,
-                                4);
-
-
-    } while (false);
-
-    return status;
-}
-
diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c
deleted file mode 100644 (file)
index c777e98..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="credit_dist.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#define ATH_MODULE_NAME misc
-#include "a_debug.h"
-#include "htc_api.h"
-#include "common_drv.h"
-
-/********* CREDIT DISTRIBUTION FUNCTIONS ******************************************/
-
-#define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave VO service inactive */
-#define CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS 1
-
-#ifdef NO_VO_SERVICE
-#define DATA_SVCS_USED 3
-#else
-#define DATA_SVCS_USED 4
-#endif
-
-static void RedistributeCredits(struct common_credit_state_info *pCredInfo,
-                                struct htc_endpoint_credit_dist *pEPDistList);
-
-static void SeekCredits(struct common_credit_state_info *pCredInfo,
-                        struct htc_endpoint_credit_dist *pEPDistList);
-
-/* reduce an ep's credits back to a set limit */
-static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo,
-                                struct htc_endpoint_credit_dist  *pEpDist,
-                                int                       Limit)
-{
-    int credits;
-
-        /* set the new limit */
-    pEpDist->TxCreditsAssigned = Limit;
-
-    if (pEpDist->TxCredits <= Limit) {
-        return;
-    }
-
-        /* figure out how much to take away */
-    credits = pEpDist->TxCredits - Limit;
-        /* take them away */
-    pEpDist->TxCredits -= credits;
-    pCredInfo->CurrentFreeCredits += credits;
-}
-
-/* give an endpoint some credits from the free credit pool */
-#define GiveCredits(pCredInfo,pEpDist,credits)      \
-{                                                   \
-    (pEpDist)->TxCredits += (credits);              \
-    (pEpDist)->TxCreditsAssigned += (credits);      \
-    (pCredInfo)->CurrentFreeCredits -= (credits);   \
-}
-
-
-/* default credit init callback.
- * This function is called in the context of HTCStart() to setup initial (application-specific)
- * credit distributions */
-static void ar6000_credit_init(void                     *Context,
-                               struct htc_endpoint_credit_dist *pEPList,
-                               int                      TotalCredits)
-{
-    struct htc_endpoint_credit_dist *pCurEpDist;
-    int                      count;
-    struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context;
-
-    pCredInfo->CurrentFreeCredits = TotalCredits;
-    pCredInfo->TotalAvailableCredits = TotalCredits;
-
-    pCurEpDist = pEPList;
-
-        /* run through the list and initialize */
-    while (pCurEpDist != NULL) {
-
-            /* set minimums for each endpoint */
-        pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
-
-#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
-      if (TotalCredits > 4)
-      {
-          if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC)  || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)){
-                    /* assign at least min credits to lower than VO priority services */
-                GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
-                    /* force active */
-                SET_EP_ACTIVE(pCurEpDist);
-          }
-      }
-#endif
-
-        if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
-                /* give control service some credits */
-            GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
-                /* control service is always marked active, it never goes inactive EVER */
-            SET_EP_ACTIVE(pCurEpDist);
-        } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) {
-                /* this is the lowest priority data endpoint, save this off for easy access */
-            pCredInfo->pLowestPriEpDist = pCurEpDist;
-        }
-
-        /* Streams have to be created (explicit | implicit)for all kinds
-         * of traffic. BE endpoints are also inactive in the beginning.
-         * When BE traffic starts it creates implicit streams that
-         * redistributes credits.
-         */
-
-        /* note, all other endpoints have minimums set but are initially given NO credits.
-         * Credits will be distributed as traffic activity demands */
-        pCurEpDist = pCurEpDist->pNext;
-    }
-
-    if (pCredInfo->CurrentFreeCredits <= 0) {
-        AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits));
-        A_ASSERT(false);
-        return;
-    }
-
-        /* reset list */
-    pCurEpDist = pEPList;
-        /* now run through the list and set max operating credit limits for everyone */
-    while (pCurEpDist != NULL) {
-        if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
-                /* control service max is just 1 max message */
-            pCurEpDist->TxCreditsNorm = pCurEpDist->TxCreditsPerMaxMsg;
-        } else {
-                /* for the remaining data endpoints, we assume that each TxCreditsPerMaxMsg are
-                 * the same.
-                 * We use a simple calculation here, we take the remaining credits and
-                 * determine how many max messages this can cover and then set each endpoint's
-                 * normal value equal to 3/4 this amount.
-                 * */
-            count = (pCredInfo->CurrentFreeCredits/pCurEpDist->TxCreditsPerMaxMsg) * pCurEpDist->TxCreditsPerMaxMsg;
-            count = (count * 3) >> 2;
-            count = max(count,pCurEpDist->TxCreditsPerMaxMsg);
-                /* set normal */
-            pCurEpDist->TxCreditsNorm = count;
-
-        }
-        pCurEpDist = pCurEpDist->pNext;
-    }
-
-}
-
-
-/* default credit distribution callback
- * This callback is invoked whenever endpoints require credit distributions.
- * A lock is held while this function is invoked, this function shall NOT block.
- * The pEPDistList is a list of distribution structures in prioritized order as
- * defined by the call to the HTCSetCreditDistribution() api.
- *
- */
-static void ar6000_credit_distribute(void                     *Context,
-                                     struct htc_endpoint_credit_dist *pEPDistList,
-                                     HTC_CREDIT_DIST_REASON   Reason)
-{
-    struct htc_endpoint_credit_dist *pCurEpDist;
-    struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context;
-
-    switch (Reason) {
-        case HTC_CREDIT_DIST_SEND_COMPLETE :
-            pCurEpDist = pEPDistList;
-                /* we are given the start of the endpoint distribution list.
-                 * There may be one or more endpoints to service.
-                 * Run through the list and distribute credits */
-            while (pCurEpDist != NULL) {
-
-                if (pCurEpDist->TxCreditsToDist > 0) {
-                        /* return the credits back to the endpoint */
-                    pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
-                        /* always zero out when we are done */
-                    pCurEpDist->TxCreditsToDist = 0;
-
-                    if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsAssigned) {
-                            /* reduce to the assigned limit, previous credit reductions
-                             * could have caused the limit to change */
-                        ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned);
-                    }
-
-                    if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsNorm) {
-                            /* oversubscribed endpoints need to reduce back to normal */
-                        ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsNorm);
-                    }
-                
-                    if (!IS_EP_ACTIVE(pCurEpDist)) {
-                            /* endpoint is inactive, now check for messages waiting for credits */
-                        if (pCurEpDist->TxQueueDepth == 0) {
-                                /* EP is inactive and there are no pending messages, 
-                                 * reduce credits back to zero to recover credits */
-                            ReduceCredits(pCredInfo, pCurEpDist, 0);
-                        }
-                    }
-                }
-
-                pCurEpDist = pCurEpDist->pNext;
-            }
-
-            break;
-
-        case HTC_CREDIT_DIST_ACTIVITY_CHANGE :
-            RedistributeCredits(pCredInfo,pEPDistList);
-            break;
-        case HTC_CREDIT_DIST_SEEK_CREDITS :
-            SeekCredits(pCredInfo,pEPDistList);
-            break;
-        case HTC_DUMP_CREDIT_STATE :
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Credit Distribution, total : %d, free : %d\n",
-                                                                       pCredInfo->TotalAvailableCredits, pCredInfo->CurrentFreeCredits));
-            break;
-        default:
-            break;
-
-    }
-
-        /* sanity checks done after each distribution action */
-    A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits);
-    A_ASSERT(pCredInfo->CurrentFreeCredits >= 0);
-
-}
-
-/* redistribute credits based on activity change */
-static void RedistributeCredits(struct common_credit_state_info *pCredInfo,
-                                struct htc_endpoint_credit_dist *pEPDistList)
-{
-    struct htc_endpoint_credit_dist *pCurEpDist = pEPDistList;
-
-        /* walk through the list and remove credits from inactive endpoints */
-    while (pCurEpDist != NULL) {
-
-#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
-
-        if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC)  || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)) {
-              /* force low priority streams to always be active to retain their minimum credit distribution */
-             SET_EP_ACTIVE(pCurEpDist);
-        }
-#endif
-
-        if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) {
-            if (!IS_EP_ACTIVE(pCurEpDist)) {
-                if (pCurEpDist->TxQueueDepth == 0) {
-                        /* EP is inactive and there are no pending messages, reduce credits back to zero */
-                    ReduceCredits(pCredInfo, pCurEpDist, 0);
-                } else {
-                        /* we cannot zero the credits assigned to this EP, but to keep
-                         * the credits available for these leftover packets, reduce to
-                         * a minimum */
-                    ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMin);
-                }
-            }
-        }
-
-        /* NOTE in the active case, we do not need to do anything further,
-         * when an EP goes active and needs credits, HTC will call into
-         * our distribution function using a reason code of HTC_CREDIT_DIST_SEEK_CREDITS  */
-
-        pCurEpDist = pCurEpDist->pNext;
-    }
-
-}
-
-/* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */
-static void SeekCredits(struct common_credit_state_info *pCredInfo,
-                        struct htc_endpoint_credit_dist *pEPDist)
-{
-    struct htc_endpoint_credit_dist *pCurEpDist;
-    int                      credits = 0;
-    int                      need;
-
-    do {
-
-        if (pEPDist->ServiceID == WMI_CONTROL_SVC) {
-                /* we never oversubscribe on the control service, this is not
-                 * a high performance path and the target never holds onto control
-                 * credits for too long */
-            break;
-        }
-
-#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
-        if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
-            if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
-                 /* limit VI service from oversubscribing */
-                 break;
-            }
-        }
-        if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
-            if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
-                 /* limit VO service from oversubscribing */
-                break;
-            }
-        }
-#else
-        if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
-            if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
-                (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
-                 /* limit VI service from oversubscribing */
-                 /* at least one free credit will not be used by VI */
-                 break;
-            }
-        }
-        if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
-            if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
-                (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
-                 /* limit VO service from oversubscribing */
-                 /* at least one free credit will not be used by VO */
-                break;
-            }
-        }
-#endif
-
-        /* for all other services, we follow a simple algorithm of
-         * 1. checking the free pool for credits
-         * 2. checking lower priority endpoints for credits to take */
-
-            /* give what we can */
-        credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
-
-        if (credits >= pEPDist->TxCreditsSeek) {
-                /* we found some to fulfill the seek request */
-            break;
-        }
-
-        /* we don't have enough in the free pool, try taking away from lower priority services
-         *
-         * The rule for taking away credits:
-         *   1. Only take from lower priority endpoints
-         *   2. Only take what is allocated above the minimum (never starve an endpoint completely)
-         *   3. Only take what you need.
-         *
-         * */
-
-            /* starting at the lowest priority */
-        pCurEpDist = pCredInfo->pLowestPriEpDist;
-
-            /* work backwards until we hit the endpoint again */
-        while (pCurEpDist != pEPDist) {
-                /* calculate how many we need so far */
-            need = pEPDist->TxCreditsSeek - pCredInfo->CurrentFreeCredits;
-
-            if ((pCurEpDist->TxCreditsAssigned - need) >= pCurEpDist->TxCreditsMin) {
-                    /* the current one has been allocated more than it's minimum and it
-                     * has enough credits assigned above it's minimum to fulfill our need
-                     * try to take away just enough to fulfill our need */
-                ReduceCredits(pCredInfo,
-                              pCurEpDist,
-                              pCurEpDist->TxCreditsAssigned - need);
-
-                if (pCredInfo->CurrentFreeCredits >= pEPDist->TxCreditsSeek) {
-                        /* we have enough */
-                    break;
-                }
-            }
-
-            pCurEpDist = pCurEpDist->pPrev;
-        }
-
-            /* return what we can get */
-        credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
-
-    } while (false);
-
-        /* did we find some credits? */
-    if (credits) {
-            /* give what we can */
-        GiveCredits(pCredInfo, pEPDist, credits);
-    }
-
-}
-
-/* initialize and setup credit distribution */
-int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo)
-{
-    HTC_SERVICE_ID servicepriority[5];
-
-    A_MEMZERO(pCredInfo,sizeof(struct common_credit_state_info));
-
-    servicepriority[0] = WMI_CONTROL_SVC;  /* highest */
-    servicepriority[1] = WMI_DATA_VO_SVC;
-    servicepriority[2] = WMI_DATA_VI_SVC;
-    servicepriority[3] = WMI_DATA_BE_SVC;
-    servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
-
-        /* set callbacks and priority list */
-    HTCSetCreditDistribution(HTCHandle,
-                             pCredInfo,
-                             ar6000_credit_distribute,
-                             ar6000_credit_init,
-                             servicepriority,
-                             5);
-
-    return 0;
-}
-
diff --git a/drivers/staging/ath6kl/miscdrv/miscdrv.h b/drivers/staging/ath6kl/miscdrv/miscdrv.h
deleted file mode 100644 (file)
index 41be567..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="miscdrv.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _MISCDRV_H
-#define _MISCDRV_H
-
-
-#define HOST_INTEREST_ITEM_ADDRESS(target, item)    \
-   AR6002_HOST_INTEREST_ITEM_ADDRESS(item)
-
-u32 ar6kRev2Array[][128]   = {
-                                    {0xFFFF, 0xFFFF},      // No Patches
-                               };
-
-#define CFG_REV2_ITEMS                0     // no patches so far
-#define AR6K_RESET_ADDR               0x4000
-#define AR6K_RESET_VAL                0x100
-
-#define EEPROM_SZ                     768
-#define EEPROM_WAIT_LIMIT             4
-
-#endif
-
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
deleted file mode 100644 (file)
index 32ee39a..0000000
+++ /dev/null
@@ -1,6267 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-/*
- * This driver is a pseudo ethernet driver to access the Atheros AR6000
- * WLAN Device
- */
-
-#include "ar6000_drv.h"
-#include "cfg80211.h"
-#include "htc.h"
-#include "wmi_filter_linux.h"
-#include "epping_test.h"
-#include "wlan_config.h"
-#include "ar3kconfig.h"
-#include "ar6k_pal.h"
-#include "AR6002/addrs.h"
-
-
-/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior.  When
- *  the meta data was added to the header it was found that linux did not correctly provide
- *  enough headroom.  However when more headroom was requested beyond what was truly needed
- *  Linux gave the requested headroom. Therefore to get the necessary headroom from Linux
- *  the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */
-#define LINUX_HACK_FUDGE_FACTOR 16
-#define BDATA_BDADDR_OFFSET     28
-
-u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-
-#ifdef DEBUG
-
-#define  ATH_DEBUG_DBG_LOG       ATH_DEBUG_MAKE_MODULE_MASK(0)
-#define  ATH_DEBUG_WLAN_CONNECT  ATH_DEBUG_MAKE_MODULE_MASK(1)
-#define  ATH_DEBUG_WLAN_SCAN     ATH_DEBUG_MAKE_MODULE_MASK(2)
-#define  ATH_DEBUG_WLAN_TX       ATH_DEBUG_MAKE_MODULE_MASK(3)
-#define  ATH_DEBUG_WLAN_RX       ATH_DEBUG_MAKE_MODULE_MASK(4)
-#define  ATH_DEBUG_HTC_RAW       ATH_DEBUG_MAKE_MODULE_MASK(5)
-#define  ATH_DEBUG_HCI_BRIDGE    ATH_DEBUG_MAKE_MODULE_MASK(6)
-
-static struct ath_debug_mask_description driver_debug_desc[] = {
-    { ATH_DEBUG_DBG_LOG      , "Target Debug Logs"},
-    { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
-    { ATH_DEBUG_WLAN_SCAN    , "WLAN scan"},
-    { ATH_DEBUG_WLAN_TX      , "WLAN Tx"},
-    { ATH_DEBUG_WLAN_RX      , "WLAN Rx"},
-    { ATH_DEBUG_HTC_RAW      , "HTC Raw IF tracing"},
-    { ATH_DEBUG_HCI_BRIDGE   , "HCI Bridge Setup"},
-    { ATH_DEBUG_HCI_RECV     , "HCI Recv tracing"},
-    { ATH_DEBUG_HCI_DUMP     , "HCI Packet dumps"},
-};
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
-                                 "driver",
-                                 "Linux Driver Interface",
-                                 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
-                                 ATH_DEBUG_HCI_BRIDGE,
-                                 ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
-                                 driver_debug_desc);
-
-#endif
-
-
-#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0)
-#define IS_MAC_BCAST(mac) (*mac==0xff)
-
-#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_)
-
-MODULE_AUTHOR("Atheros Communications, Inc.");
-MODULE_DESCRIPTION(DESCRIPTION);
-MODULE_LICENSE("Dual BSD/GPL");
-
-#ifndef REORG_APTC_HEURISTICS
-#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-#endif /* REORG_APTC_HEURISTICS */
-
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-#define APTC_TRAFFIC_SAMPLING_INTERVAL     100  /* msec */
-#define APTC_UPPER_THROUGHPUT_THRESHOLD    3000 /* Kbps */
-#define APTC_LOWER_THROUGHPUT_THRESHOLD    2000 /* Kbps */
-
-typedef struct aptc_traffic_record {
-    bool timerScheduled;
-    struct timeval samplingTS;
-    unsigned long bytesReceived;
-    unsigned long bytesTransmitted;
-} APTC_TRAFFIC_RECORD;
-
-A_TIMER aptcTimer;
-APTC_TRAFFIC_RECORD aptcTR;
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-// callbacks registered by HCI transport driver
-struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL };
-#endif
-
-unsigned int processDot11Hdr = 0;
-
-char ifname[IFNAMSIZ] = {0,};
-
-int wlaninitmode = WLAN_INIT_MODE_DEFAULT;
-static bool bypasswmi;
-unsigned int debuglevel = 0;
-int tspecCompliance = ATHEROS_COMPLIANCE;
-unsigned int busspeedlow = 0;
-unsigned int onebitmode = 0;
-unsigned int skipflash = 0;
-unsigned int wmitimeout = 2;
-unsigned int wlanNodeCaching = 1;
-unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
-unsigned int logWmiRawMsgs = 0;
-unsigned int enabletimerwar = 0;
-unsigned int num_device = 1;
-unsigned int regscanmode;
-unsigned int fwmode = 1;
-unsigned int mbox_yield_limit = 99;
-unsigned int enablerssicompensation = 0;
-int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
-int allow_trace_signal = 0;
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-unsigned int testmode =0;
-#endif
-
-unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC;
-unsigned int panic_on_assert = 1;
-unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
-
-unsigned int setuphci = SETUPHCI_DEFAULT;
-unsigned int loghci = 0;
-unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT;
-unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
-unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
-#endif
-unsigned int csumOffload=0;
-unsigned int csumOffloadTest=0;
-unsigned int eppingtest=0;
-unsigned int mac_addr_method;
-unsigned int firmware_bridge;
-
-module_param_string(ifname, ifname, sizeof(ifname), 0644);
-module_param(wlaninitmode, int, 0644);
-module_param(bypasswmi, bool, 0644);
-module_param(debuglevel, uint, 0644);
-module_param(tspecCompliance, int, 0644);
-module_param(onebitmode, uint, 0644);
-module_param(busspeedlow, uint, 0644);
-module_param(skipflash, uint, 0644);
-module_param(wmitimeout, uint, 0644);
-module_param(wlanNodeCaching, uint, 0644);
-module_param(logWmiRawMsgs, uint, 0644);
-module_param(enableuartprint, uint, 0644);
-module_param(enabletimerwar, uint, 0644);
-module_param(fwmode, uint, 0644);
-module_param(mbox_yield_limit, uint, 0644);
-module_param(reduce_credit_dribble, int, 0644);
-module_param(allow_trace_signal, int, 0644);
-module_param(enablerssicompensation, uint, 0644);
-module_param(processDot11Hdr, uint, 0644);
-module_param(csumOffload, uint, 0644);
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-module_param(testmode, uint, 0644);
-#endif
-module_param(irqprocmode, uint, 0644);
-module_param(nohifscattersupport, uint, 0644);
-module_param(panic_on_assert, uint, 0644);
-module_param(setuphci, uint, 0644);
-module_param(loghci, uint, 0644);
-module_param(setupbtdev, uint, 0644);
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-module_param(ar3khcibaud, uint, 0644);
-module_param(hciuartscale, uint, 0644);
-module_param(hciuartstep, uint, 0644);
-#endif
-module_param(eppingtest, uint, 0644);
-
-/* in 2.6.10 and later this is now a pointer to a uint */
-unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
-#define mboxnum &_mboxnum
-
-#ifdef DEBUG
-u32 g_dbg_flags = DBG_DEFAULTS;
-unsigned int debugflags = 0;
-int debugdriver = 0;
-unsigned int debughtc = 0;
-unsigned int debugbmi = 0;
-unsigned int debughif = 0;
-unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
-unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
-unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
-unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
-module_param(debugflags, uint, 0644);
-module_param(debugdriver, int, 0644);
-module_param(debughtc, uint, 0644);
-module_param(debugbmi, uint, 0644);
-module_param(debughif, uint, 0644);
-module_param_array(txcreditsavailable, uint, mboxnum, 0644);
-module_param_array(txcreditsconsumed, uint, mboxnum, 0644);
-module_param_array(txcreditintrenable, uint, mboxnum, 0644);
-module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644);
-
-#endif /* DEBUG */
-
-unsigned int resetok = 1;
-unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
-unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
-unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
-unsigned int hifBusRequestNumMax = 40;
-unsigned int war23838_disabled = 0;
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-unsigned int enableAPTCHeuristics = 1;
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-module_param_array(tx_attempt, uint, mboxnum, 0644);
-module_param_array(tx_post, uint, mboxnum, 0644);
-module_param_array(tx_complete, uint, mboxnum, 0644);
-module_param(hifBusRequestNumMax, uint, 0644);
-module_param(war23838_disabled, uint, 0644);
-module_param(resetok, uint, 0644);
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-module_param(enableAPTCHeuristics, uint, 0644);
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-#ifdef BLOCK_TX_PATH_FLAG
-int blocktx = 0;
-module_param(blocktx, int, 0644);
-#endif /* BLOCK_TX_PATH_FLAG */
-
-typedef struct user_rssi_compensation_t {
-    u16 customerID;
-    union {
-    u16 a_enable;
-    u16 bg_enable;
-    u16 enable;
-    };
-    s16 bg_param_a;
-    s16 bg_param_b;
-    s16 a_param_a;
-    s16 a_param_b;
-    u32 reserved;
-} USER_RSSI_CPENSATION;
-
-static USER_RSSI_CPENSATION rssi_compensation_param;
-
-static s16 rssi_compensation_table[96];
-
-int reconnect_flag = 0;
-static ar6k_pal_config_t ar6k_pal_config_g;
-
-/* Function declarations */
-static int ar6000_init_module(void);
-static void ar6000_cleanup_module(void);
-
-int ar6000_init(struct net_device *dev);
-static int ar6000_open(struct net_device *dev);
-static int ar6000_close(struct net_device *dev);
-static void ar6000_init_control_info(struct ar6_softc *ar);
-static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
-
-void ar6000_destroy(struct net_device *dev, unsigned int unregister);
-static void ar6000_detect_error(unsigned long ptr);
-static void    ar6000_set_multicast_list(struct net_device *dev);
-static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
-
-static void disconnect_timer_handler(unsigned long ptr);
-
-void read_rssi_compensation_param(struct ar6_softc *ar);
-
-/*
- * HTC service connection handlers
- */
-static int ar6000_avail_ev(void *context, void *hif_handle);
-
-static int ar6000_unavail_ev(void *context, void *hif_handle);
-
-int ar6000_configure_target(struct ar6_softc *ar);
-
-static void ar6000_target_failure(void *Instance, int Status);
-
-static void ar6000_rx(void *Context, struct htc_packet *pPacket);
-
-static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
-
-static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets);
-
-static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket);
-
-static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num);
-static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
-//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
-
-static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length);
-
-static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count);
-
-static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar);
-
-static ssize_t
-ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
-                      struct bin_attribute *bin_attr,
-                      char *buf, loff_t pos, size_t count);
-
-static ssize_t
-ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
-                       struct bin_attribute *bin_attr,
-                       char *buf, loff_t pos, size_t count);
-
-static int
-ar6000_sysfs_bmi_init(struct ar6_softc *ar);
-
-void  ar6k_cleanup_hci_pal(struct ar6_softc *ar);
-
-static void
-ar6000_sysfs_bmi_deinit(struct ar6_softc *ar);
-
-int
-ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode);
-
-/*
- * Static variables
- */
-
-struct net_device *ar6000_devices[MAX_AR6000];
-static int is_netdev_registered;
-DECLARE_WAIT_QUEUE_HEAD(arEvent);
-static void ar6000_cookie_init(struct ar6_softc *ar);
-static void ar6000_cookie_cleanup(struct ar6_softc *ar);
-static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie);
-static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar);
-
-static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl);
-
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-struct net_device *arApNetDev;
-#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-
-static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
-
-#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
-        (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
-        (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
-
-
-static struct net_device_ops ar6000_netdev_ops = {
-    .ndo_init               = NULL,
-    .ndo_open               = ar6000_open,
-    .ndo_stop               = ar6000_close,
-    .ndo_get_stats          = ar6000_get_stats,
-    .ndo_start_xmit         = ar6000_data_tx,
-    .ndo_set_multicast_list = ar6000_set_multicast_list,
-};
-
-/* Debug log support */
-
-/*
- * Flag to govern whether the debug logs should be parsed in the kernel
- * or reported to the application.
- */
-#define REPORT_DEBUG_LOGS_TO_APP
-
-int
-ar6000_set_host_app_area(struct ar6_softc *ar)
-{
-    u32 address, data;
-    struct host_app_area_s host_app_area;
-
-    /* Fetch the address of the host_app_area_s instance in the host interest area */
-    address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest));
-    if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != 0) {
-        return A_ERROR;
-    }
-    address = TARG_VTOP(ar->arTargetType, data);
-    host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
-    if (ar6000_WriteDataDiag(ar->arHifDevice, address,
-                             (u8 *)&host_app_area,
-                             sizeof(struct host_app_area_s)) != 0)
-    {
-        return A_ERROR;
-    }
-
-    return 0;
-}
-
-u32 dbglog_get_debug_hdr_ptr(struct ar6_softc *ar)
-{
-    u32 param;
-    u32 address;
-    int status;
-
-    address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr));
-    if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
-                                      (u8 *)&param, 4)) != 0)
-    {
-        param = 0;
-    }
-
-    return param;
-}
-
-/*
- * The dbglog module has been initialized. Its ok to access the relevant
- * data stuctures over the diagnostic window.
- */
-void
-ar6000_dbglog_init_done(struct ar6_softc *ar)
-{
-    ar->dbglog_init_done = true;
-}
-
-u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit)
-{
-    s32 *buffer;
-    u32 count;
-    u32 numargs;
-    u32 length;
-    u32 fraglen;
-
-    count = fraglen = 0;
-    buffer = (s32 *)datap;
-    length = (limit >> 2);
-
-    if (len <= limit) {
-        fraglen = len;
-    } else {
-        while (count < length) {
-            numargs = DBGLOG_GET_NUMARGS(buffer[count]);
-            fraglen = (count << 2);
-            count += numargs + 1;
-        }
-    }
-
-    return fraglen;
-}
-
-void
-dbglog_parse_debug_logs(s8 *datap, u32 len)
-{
-    s32 *buffer;
-    u32 count;
-    u32 timestamp;
-    u32 debugid;
-    u32 moduleid;
-    u32 numargs;
-    u32 length;
-
-    count = 0;
-    buffer = (s32 *)datap;
-    length = (len >> 2);
-    while (count < length) {
-        debugid = DBGLOG_GET_DBGID(buffer[count]);
-        moduleid = DBGLOG_GET_MODULEID(buffer[count]);
-        numargs = DBGLOG_GET_NUMARGS(buffer[count]);
-        timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
-        switch (numargs) {
-            case 0:
-            AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp));
-            break;
-
-            case 1:
-            AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid,
-                            timestamp, buffer[count+1]));
-            break;
-
-            case 2:
-            AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
-                            timestamp, buffer[count+1], buffer[count+2]));
-            break;
-
-            default:
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
-        }
-        count += numargs + 1;
-    }
-}
-
-int
-ar6000_dbglog_get_debug_logs(struct ar6_softc *ar)
-{
-    u32 data[8]; /* Should be able to accommodate struct dbglog_buf_s */
-    u32 address;
-    u32 length;
-    u32 dropped;
-    u32 firstbuf;
-    u32 debug_hdr_ptr;
-
-    if (!ar->dbglog_init_done) return A_ERROR;
-
-
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    if (ar->dbgLogFetchInProgress) {
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        return A_EBUSY;
-    }
-
-        /* block out others */
-    ar->dbgLogFetchInProgress = true;
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
-    printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
-
-    /* Get the contents of the ring buffer */
-    if (debug_hdr_ptr) {
-        address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
-        length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */;
-        A_MEMZERO(data, sizeof(data));
-        ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)data, length);
-        address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */);
-        firstbuf = address;
-        dropped = data[1]; /* dropped */
-        length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
-        A_MEMZERO(data, sizeof(data));
-        ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)&data, length);
-
-        do {
-            address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/);
-            length = data[3]; /* length */
-            if ((length) && (length <= data[2] /* bufsize*/)) {
-                /* Rewind the index if it is about to overrun the buffer */
-                if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
-                    ar->log_cnt = 0;
-                }
-                if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
-                                    (u8 *)&ar->log_buffer[ar->log_cnt], length))
-                {
-                    break;
-                }
-                ar6000_dbglog_event(ar, dropped, (s8 *)&ar->log_buffer[ar->log_cnt], length);
-                ar->log_cnt += length;
-            } else {
-                AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n",
-                                data[3], data[2]));
-            }
-
-            address = TARG_VTOP(ar->arTargetType, data[0] /* next */);
-            length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
-            A_MEMZERO(data, sizeof(data));
-            if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address,
-                                (u8 *)&data, length))
-            {
-                break;
-            }
-
-        } while (address != firstbuf);
-    }
-
-    ar->dbgLogFetchInProgress = false;
-
-    return 0;
-}
-
-void
-ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
-                    s8 *buffer, u32 length)
-{
-#ifdef REPORT_DEBUG_LOGS_TO_APP
-    #define MAX_WIRELESS_EVENT_SIZE 252
-    /*
-     * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
-     * There seems to be a limitation on the length of message that could be
-     * transmitted to the user app via this mechanism.
-     */
-    u32 send, sent;
-
-    sent = 0;
-    send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
-                                     MAX_WIRELESS_EVENT_SIZE);
-    while (send) {
-        sent += send;
-        send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
-                                         MAX_WIRELESS_EVENT_SIZE);
-    }
-#else
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n",
-                    dropped, length));
-
-    /* Interpret the debug logs */
-    dbglog_parse_debug_logs((s8 *)buffer, length);
-#endif /* REPORT_DEBUG_LOGS_TO_APP */
-}
-
-
-static int __init
-ar6000_init_module(void)
-{
-    static int probed = 0;
-    int r;
-    OSDRV_CALLBACKS osdrvCallbacks;
-
-    a_module_debug_support_init();
-
-#ifdef DEBUG
-        /* check for debug mask overrides */
-    if (debughtc != 0) {
-        ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
-    }
-    if (debugbmi != 0) {
-        ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
-    }
-    if (debughif != 0) {
-        ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
-    }
-    if (debugdriver != 0) {
-        ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
-    }
-
-#endif
-
-    A_REGISTER_MODULE_DEBUG_INFO(driver);
-
-    A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
-    osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
-    osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
-#ifdef CONFIG_PM
-    osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev;
-    osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev;
-    osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
-#endif
-
-#ifdef DEBUG
-    /* Set the debug flags if specified at load time */
-    if(debugflags != 0)
-    {
-        g_dbg_flags = debugflags;
-    }
-#endif
-
-    if (probed) {
-        return -ENODEV;
-    }
-    probed++;
-
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-    memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-    r = HIFInit(&osdrvCallbacks);
-    if (r)
-        return r;
-
-    return 0;
-}
-
-static void __exit
-ar6000_cleanup_module(void)
-{
-    int i = 0;
-    struct net_device *ar6000_netdev;
-
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-    /* Delete the Adaptive Power Control timer */
-    if (timer_pending(&aptcTimer)) {
-        del_timer_sync(&aptcTimer);
-    }
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-    for (i=0; i < MAX_AR6000; i++) {
-        if (ar6000_devices[i] != NULL) {
-            ar6000_netdev = ar6000_devices[i];
-            ar6000_devices[i] = NULL;
-            ar6000_destroy(ar6000_netdev, 1);
-        }
-    }
-
-    HIFShutDownDevice(NULL);
-
-    a_module_debug_support_cleanup();
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
-}
-
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-void
-aptcTimerHandler(unsigned long arg)
-{
-    u32 numbytes;
-    u32 throughput;
-    struct ar6_softc *ar;
-    int status;
-
-    ar = (struct ar6_softc *)arg;
-    A_ASSERT(ar != NULL);
-    A_ASSERT(!timer_pending(&aptcTimer));
-
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    /* Get the number of bytes transferred */
-    numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
-    aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
-
-    /* Calculate and decide based on throughput thresholds */
-    throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
-    if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
-        /* Enable Sleep and delete the timer */
-        A_ASSERT(ar->arWmiReady == true);
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-        A_ASSERT(status == 0);
-        aptcTR.timerScheduled = false;
-    } else {
-        A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
-    }
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-}
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-static void
-ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num)
-{
-    void * osbuf;
-
-    while(num) {
-        if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
-            A_NETBUF_ENQUEUE(q, osbuf);
-        } else {
-            break;
-        }
-        num--;
-    }
-
-    if(num) {
-        A_PRINTF("%s(), allocation of netbuf failed", __func__);
-    }
-}
-
-static struct bin_attribute bmi_attr = {
-    .attr = {.name = "bmi", .mode = 0600},
-    .read = ar6000_sysfs_bmi_read,
-    .write = ar6000_sysfs_bmi_write,
-};
-
-static ssize_t
-ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
-                      struct bin_attribute *bin_attr,
-                      char *buf, loff_t pos, size_t count)
-{
-    int index;
-    struct ar6_softc *ar;
-    struct hif_device_os_device_info   *osDevInfo;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count));
-    for (index=0; index < MAX_AR6000; index++) {
-        ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
-        osDevInfo = &ar->osDevInfo;
-        if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
-            break;
-        }
-    }
-
-    if (index == MAX_AR6000) return 0;
-
-    if ((BMIRawRead(ar->arHifDevice, (u8*)buf, count, true)) != 0) {
-        return 0;
-    }
-
-    return count;
-}
-
-static ssize_t
-ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
-                       struct bin_attribute *bin_attr,
-                       char *buf, loff_t pos, size_t count)
-{
-    int index;
-    struct ar6_softc *ar;
-    struct hif_device_os_device_info   *osDevInfo;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count));
-    for (index=0; index < MAX_AR6000; index++) {
-        ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]);
-        osDevInfo = &ar->osDevInfo;
-        if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
-            break;
-        }
-    }
-
-    if (index == MAX_AR6000) return 0;
-
-    if ((BMIRawWrite(ar->arHifDevice, (u8*)buf, count)) != 0) {
-        return 0;
-    }
-
-    return count;
-}
-
-static int
-ar6000_sysfs_bmi_init(struct ar6_softc *ar)
-{
-    int status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
-    A_MEMZERO(&ar->osDevInfo, sizeof(struct hif_device_os_device_info));
-
-    /* Get the underlying OS device */
-    status = HIFConfigureDevice(ar->arHifDevice,
-                                HIF_DEVICE_GET_OS_DEVICE,
-                                &ar->osDevInfo,
-                                sizeof(struct hif_device_os_device_info));
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
-        return A_ERROR;
-    }
-
-    /* Create a bmi entry in the sysfs filesystem */
-    if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n"));
-        return A_ERROR;
-    }
-
-    return 0;
-}
-
-static void
-ar6000_sysfs_bmi_deinit(struct ar6_softc *ar)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
-
-    sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr);
-}
-
-#define bmifn(fn) do { \
-    if ((fn) < 0) { \
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \
-        return A_ERROR; \
-    } \
-} while(0)
-
-#ifdef SOFTMAC_FILE_USED
-#define AR6002_MAC_ADDRESS_OFFSET     0x0A
-#define AR6003_MAC_ADDRESS_OFFSET     0x16
-static
-void calculate_crc(u32 TargetType, u8 *eeprom_data)
-{
-    u16 *ptr_crc;
-    u16 *ptr16_eeprom;
-    u16 checksum;
-    u32 i;
-    u32 eeprom_size;
-
-    if (TargetType == TARGET_TYPE_AR6001)
-    {
-        eeprom_size = 512;
-        ptr_crc = (u16 *)eeprom_data;
-    }
-    else if (TargetType == TARGET_TYPE_AR6003)
-    {
-        eeprom_size = 1024;
-        ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
-    }
-    else
-    {
-        eeprom_size = 768;
-        ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04);
-    }
-
-
-    // Clear the crc
-    *ptr_crc = 0;
-
-    // Recalculate new CRC
-    checksum = 0;
-    ptr16_eeprom = (u16 *)eeprom_data;
-    for (i = 0;i < eeprom_size; i += 2)
-    {
-        checksum = checksum ^ (*ptr16_eeprom);
-        ptr16_eeprom++;
-    }
-    checksum = 0xFFFF ^ checksum;
-    *ptr_crc = checksum;
-}
-
-static void 
-ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size)
-{
-    const char *source = "random generated";
-    const struct firmware *softmac_entry;
-    u8 *ptr_mac;
-    switch (ar->arTargetType) {
-    case TARGET_TYPE_AR6002:
-        ptr_mac = (u8 *)((u8 *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET);
-        break;
-    case TARGET_TYPE_AR6003:
-        ptr_mac = (u8 *)((u8 *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET);
-        break;
-    default:
-       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n"));
-        return;
-    }
-       printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac);
-
-    /* create a random MAC in case we cannot read file from system */
-    ptr_mac[0] = 0;
-    ptr_mac[1] = 0x03;
-    ptr_mac[2] = 0x7F;
-    ptr_mac[3] = random32() & 0xff; 
-    ptr_mac[4] = random32() & 0xff; 
-    ptr_mac[5] = random32() & 0xff; 
-    if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0)
-    {
-        char *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1);
-        if (macbuf) {            
-            unsigned int softmac[6];
-            memcpy(macbuf, softmac_entry->data, softmac_entry->size);
-            macbuf[softmac_entry->size] = '\0';
-            if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x", 
-                        &softmac[0], &softmac[1], &softmac[2],
-                        &softmac[3], &softmac[4], &softmac[5])==6) {
-                int i;
-                for (i=0; i<6; ++i) {
-                    ptr_mac[i] = softmac[i] & 0xff;
-                }
-                source = "softmac file";
-            }
-            kfree(macbuf);
-        }
-        A_RELEASE_FIRMWARE(softmac_entry);
-    }
-       printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac);
-   calculate_crc(ar->arTargetType, eeprom_data);
-}
-#endif /* SOFTMAC_FILE_USED */
-
-static int
-ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, bool compressed)
-{
-    int status;
-    const char *filename;
-    const struct firmware *fw_entry;
-    u32 fw_entry_size;
-    u8 **buf;
-    size_t *buf_len;
-
-    switch (file) {
-        case AR6K_OTP_FILE:
-               buf = &ar->fw_otp;
-               buf_len = &ar->fw_otp_len;
-            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                filename = AR6003_REV1_OTP_FILE;
-            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                filename = AR6003_REV2_OTP_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
-                        filename = AR6003_REV3_OTP_FILE;
-            } else {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
-                return A_ERROR;
-            }
-            break;
-
-        case AR6K_FIRMWARE_FILE:
-               buf = &ar->fw;
-               buf_len = &ar->fw_len;
-            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                filename = AR6003_REV1_FIRMWARE_FILE;
-            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                filename = AR6003_REV2_FIRMWARE_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
-                        filename = AR6003_REV3_FIRMWARE_FILE;
-            } else {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
-                return A_ERROR;
-            }
-            
-            if (eppingtest) {
-                bypasswmi = true;
-                if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                    filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                    filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
-                        filename = AR6003_REV3_EPPING_FIRMWARE_FILE;
-                } else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n", 
-                        ar->arVersion.target_ver));
-                    return A_ERROR;
-                }
-                compressed = false;
-            }
-            
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-            if(testmode) {
-                if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                    filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                    filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
-                        filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
-                } else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
-                    return A_ERROR;
-                }
-                compressed = false;
-            }
-#endif 
-#ifdef HTC_RAW_INTERFACE
-            if (!eppingtest && bypasswmi) {
-                if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                    filename = AR6003_REV1_ART_FIRMWARE_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                    filename = AR6003_REV2_ART_FIRMWARE_FILE;
-                } else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
-                    return A_ERROR;
-                }
-                compressed = false;
-            }
-#endif 
-            break;
-
-        case AR6K_PATCH_FILE:
-               buf = &ar->fw_patch;
-               buf_len = &ar->fw_patch_len;
-            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                filename = AR6003_REV1_PATCH_FILE;
-            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                filename = AR6003_REV2_PATCH_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
-                        filename = AR6003_REV3_PATCH_FILE;
-            } else {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
-                return A_ERROR;
-            }
-            break;
-
-        case AR6K_BOARD_DATA_FILE:
-               buf = &ar->fw_data;
-               buf_len = &ar->fw_data_len;
-            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                filename = AR6003_REV1_BOARD_DATA_FILE;
-            } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                filename = AR6003_REV2_BOARD_DATA_FILE;
-                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
-                        filename = AR6003_REV3_BOARD_DATA_FILE;
-            } else {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
-                return A_ERROR;
-            }
-            break;
-
-        default:
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
-            return A_ERROR;
-    }
-
-    if (*buf == NULL) {
-           if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) {
-                   AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
-                   return A_ENOENT;
-           }
-
-           *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
-           *buf_len = fw_entry->size;
-           A_RELEASE_FIRMWARE(fw_entry);
-    }
-
-#ifdef SOFTMAC_FILE_USED
-    if (file==AR6K_BOARD_DATA_FILE && *buf_len) {
-        ar6000_softmac_update(ar, *buf, *buf_len);
-    }
-#endif 
-
-
-    fw_entry_size = *buf_len;
-
-    /* Load extended board data for AR6003 */
-    if ((file==AR6K_BOARD_DATA_FILE) && *buf) {
-        u32 board_ext_address;
-        u32 board_ext_data_size;
-        u32 board_data_size;
-
-        board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \
-                               (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0));
-
-        board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \
-                          (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0));
-        
-        /* Determine where in Target RAM to write Board Data */
-        bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (u8 *)&board_ext_address, 4));
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
-
-        /* check whether the target has allocated memory for extended board data and file contains extended board data */
-        if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) {
-            u32 param;
-
-            status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size);
-
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
-                return A_ERROR;
-            }
-
-            /* Record the fact that extended board Data IS initialized */
-            param = (board_ext_data_size << 16) | 1;
-            bmifn(BMIWriteMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_config),
-                                      (unsigned char *)&param, 4));
-        }
-        fw_entry_size = board_data_size;
-    }
-
-    if (compressed) {
-        status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size);
-    } else {
-        status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size);
-    }
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
-        return A_ERROR;
-    }
-
-    return 0;
-}
-
-int
-ar6000_update_bdaddr(struct ar6_softc *ar)
-{
-
-        if (setupbtdev != 0) {
-            u32 address;
-
-           if (BMIReadMemory(ar->arHifDevice,
-               HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4) != 0)
-           {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n"));
-               return A_ERROR;
-           }
-
-           if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (u8 *)ar->bdaddr, 6) != 0)
-           {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n"));
-               return A_ERROR;
-           }
-          AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0],
-                                                               ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3],
-                                                               ar->bdaddr[4], ar->bdaddr[5]));
-        }
-
-return 0;
-}
-
-int
-ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n"));
-
-    if (mode == WLAN_INIT_MODE_UDEV) {
-        char version[16];
-        const struct firmware *fw_entry;
-
-        /* Get config using udev through a script in user space */
-        sprintf(version, "%2.2x", ar->arVersion.target_ver);
-        if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version));
-            return A_ERROR;
-        }
-
-        A_RELEASE_FIRMWARE(fw_entry);
-    } else {
-        /* The config is contained within the driver itself */
-        int status;
-        u32 param, options, sleep, address;
-
-        /* Temporarily disable system sleep */
-        address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
-        bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
-        options = param;
-        param |= AR6K_OPTION_SLEEP_DISABLE;
-        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-
-        address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
-        bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
-        sleep = param;
-        param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
-        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep));
-
-        if (ar->arTargetType == TARGET_TYPE_AR6003) {
-            /* Program analog PLL register */
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001));
-            /* Run at 80/88MHz by default */
-            param = CPU_CLOCK_STANDARD_SET(1);
-        } else {
-            /* Run at 40/44MHz by default */
-            param = CPU_CLOCK_STANDARD_SET(0);
-        }
-        address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
-        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-
-        param = 0;
-        if (ar->arTargetType == TARGET_TYPE_AR6002) {
-            bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
-        }
-
-        /* LPO_CAL.ENABLE = 1 if no external clk is detected */
-        if (param != 1) {
-            address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
-            param = LPO_CAL_ENABLE_SET(1);
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-        }
-
-        /* Venus2.0: Lower SDIO pad drive strength,
-         * temporary WAR to avoid SDIO CRC error */
-        if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n"));
-            param = 0x20;
-            address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-
-            address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-
-            address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-
-            address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-        }
-
-#ifdef FORCE_INTERNAL_CLOCK
-        /* Ignore external clock, if any, and force use of internal clock */
-        if (ar->arTargetType == TARGET_TYPE_AR6003) {
-            /* hi_ext_clk_detected = 0 */
-            param = 0;
-            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)&param, 4));
-
-            /* CLOCK_CONTROL &= ~LF_CLK32 */
-            address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS;
-            bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
-            param &= (~CLOCK_CONTROL_LF_CLK32_SET(1));
-            bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-        }
-#endif /* FORCE_INTERNAL_CLOCK */
-
-        /* Transfer Board Data from Target EEPROM to Target RAM */
-        if (ar->arTargetType == TARGET_TYPE_AR6003) {
-            /* Determine where in Target RAM to write Board Data */
-            bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address));
-
-            /* Write EEPROM data to Target RAM */
-            if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != 0) {
-                return A_ERROR;
-            }
-
-            /* Record the fact that Board Data IS initialized */
-            param = 1;
-            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)&param, 4));
-
-            /* Transfer One time Programmable data */
-           AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
-           if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
-                 address = 0x1234;
-            status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true);
-            if (status == 0) {
-                /* Execute the OTP code */
-                param = 0;
-                AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
-                bmifn(BMIExecute(ar->arHifDevice, address, &param));
-            } else if (status != A_ENOENT) {
-                return A_ERROR;
-            } 
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType));
-            return A_ERROR;
-        }
-
-        /* Download Target firmware */
-        AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
-        if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
-                address = 0x1234;
-        if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) {
-            return A_ERROR;
-        }
-
-        /* Set starting address for firmware */
-        AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
-        bmifn(BMISetAppStart(ar->arHifDevice, address));
-
-       if(ar->arTargetType == TARGET_TYPE_AR6003) {
-               AR6K_DATASET_PATCH_ADDRESS(address, ar->arVersion.target_ver);
-               if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE,
-                                             address, false)) != 0)
-                       return A_ERROR;
-               param = address;
-               bmifn(BMIWriteMemory(ar->arHifDevice,
-               HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head),
-                                          (unsigned char *)&param, 4));
-       }
-
-        /* Restore system sleep */
-        address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
-        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
-
-        address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
-        param = options | 0x20;
-        bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-
-        if (ar->arTargetType == TARGET_TYPE_AR6003) {
-            /* Configure GPIO AR6003 UART */
-#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN
-#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
-#endif
-            param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
-            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (u8 *)&param, 4));
-
-#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23)
-            {
-                address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS;
-                bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
-                param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1);
-                bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
-            }
-#endif
-
-            /* Configure GPIO for BT Reset */
-#ifdef ATH6KL_CONFIG_GPIO_BT_RESET
-#define CONFIG_AR600x_BT_RESET_PIN     0x16
-            param = CONFIG_AR600x_BT_RESET_PIN;
-            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (u8 *)&param, 4));
-#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */
-
-            /* Configure UART flow control polarity */
-#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY
-#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0
-#endif
-
-#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1)
-            if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2);
-                bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (u8 *)&param, 4));
-            }
-#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */
-        }
-
-#ifdef HTC_RAW_INTERFACE
-        if (!eppingtest && bypasswmi) {
-            /* Don't run BMIDone for ART mode and force resetok=0 */
-            resetok = 0;
-            msleep(1000);
-        }
-#endif /* HTC_RAW_INTERFACE */
-    }
-
-    return 0;
-}
-
-int
-ar6000_configure_target(struct ar6_softc *ar)
-{
-    u32 param;
-    if (enableuartprint) {
-        param = 1;
-        if (BMIWriteMemory(ar->arHifDevice,
-                           HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
-                           (u8 *)&param,
-                           4)!= 0)
-        {
-             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
-             return A_ERROR;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
-    }
-
-    /* Tell target which HTC version it is used*/
-    param = HTC_PROTOCOL_VERSION;
-    if (BMIWriteMemory(ar->arHifDevice,
-                       HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
-                       (u8 *)&param,
-                       4)!= 0)
-    {
-         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n"));
-         return A_ERROR;
-    }
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-    if(testmode) {
-        ar->arTargetMode = AR6000_TCMD_MODE;
-    }else {
-        ar->arTargetMode = AR6000_WLAN_MODE;
-    }
-#endif
-    if (enabletimerwar) {
-        u32 param;
-
-        if (BMIReadMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
-            (u8 *)&param,
-            4)!= 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n"));
-            return A_ERROR;
-        }
-
-        param |= HI_OPTION_TIMER_WAR;
-
-        if (BMIWriteMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
-            (u8 *)&param,
-            4) != 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n"));
-            return A_ERROR;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
-    }
-
-    /* set the firmware mode to STA/IBSS/AP */
-    {
-        u32 param;
-
-        if (BMIReadMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
-            (u8 *)&param,
-            4)!= 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n"));
-            return A_ERROR;
-        }
-
-        param |= (num_device << HI_OPTION_NUM_DEV_SHIFT);
-        param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
-        param |= (mac_addr_method << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
-        param |= (firmware_bridge << HI_OPTION_FW_BRIDGE_SHIFT);
-
-
-        if (BMIWriteMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
-            (u8 *)&param,
-            4) != 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n"));
-            return A_ERROR;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
-    }
-
-#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS
-    {
-        u32 param;
-
-        if (BMIReadMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
-            (u8 *)&param,
-            4)!= 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n"));
-            return A_ERROR;
-        }
-
-        param |= HI_OPTION_DISABLE_DBGLOG;
-
-        if (BMIWriteMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
-            (u8 *)&param,
-            4) != 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n"));
-            return A_ERROR;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
-    }
-#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */
-
-    /* 
-     * Hardcode the address use for the extended board data 
-     * Ideally this should be pre-allocate by the OS at boot time
-     * But since it is a new feature and board data is loaded 
-     * at init time, we have to workaround this from host.
-     * It is difficult to patch the firmware boot code,
-     * but possible in theory.
-     */
-
-       if (ar->arTargetType == TARGET_TYPE_AR6003) {
-               u32 ramReservedSz;
-               if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
-                       param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
-                       ramReservedSz =  AR6003_REV2_RAM_RESERVE_SIZE;
-                } else {
-                       param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
-                       ramReservedSz =  AR6003_REV3_RAM_RESERVE_SIZE;
-               }
-               if (BMIWriteMemory(ar->arHifDevice,
-                       HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
-                                                  (u8 *)&param, 4) != 0) {
-                               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                                               ("BMIWriteMemory for "
-                                                "hi_board_ext_data failed\n"));
-                               return A_ERROR;
-               }
-               if (BMIWriteMemory(ar->arHifDevice,
-                                  HOST_INTEREST_ITEM_ADDRESS(ar,
-                                  hi_end_RAM_reserve_sz),
-                                  (u8 *)&ramReservedSz, 4) != 0) {
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR ,
-                                       ("BMIWriteMemory for "
-                                        "hi_end_RAM_reserve_sz failed\n"));
-                       return A_ERROR;
-               }
-       }
-
-        /* since BMIInit is called in the driver layer, we have to set the block
-         * size here for the target */
-
-    if (ar6000_set_htc_params(ar->arHifDevice, ar->arTargetType,
-                             mbox_yield_limit, 0)) {
-                               /* use default number of control buffers */
-        return A_ERROR;
-    }
-
-    if (setupbtdev != 0) {
-        if (ar6000_set_hci_bridge_flags(ar->arHifDevice,
-                                       ar->arTargetType,
-                                       setupbtdev)) {
-            return A_ERROR;
-        }
-    }
-    return 0;
-}
-
-static void
-init_netdev(struct net_device *dev, char *name)
-{
-    dev->netdev_ops = &ar6000_netdev_ops;
-    dev->watchdog_timeo = AR6000_TX_TIMEOUT;
-
-   /*
-    * We need the OS to provide us with more headroom in order to
-    * perform dix to 802.3, WMI header encap, and the HTC header
-    */
-    if (processDot11Hdr) {
-        dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
-    } else {
-        dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
-            sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
-    }
-
-    if (name[0])
-    {
-        strcpy(dev->name, name);
-    }
-
-#ifdef CONFIG_CHECKSUM_OFFLOAD
-    if(csumOffload){
-        dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
-    }
-#endif
-
-    return;
-}
-
-static int __ath6kl_init_netdev(struct net_device *dev)
-{
-       int r;
-
-       rtnl_lock();
-       r = ar6000_init(dev);
-       rtnl_unlock();
-
-       if (r) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
-               return r;
-       }
-
-       return 0;
-}
-
-#ifdef HTC_RAW_INTERFACE
-static int ath6kl_init_netdev_wmi(struct net_device *dev)
-{
-       if (!eppingtest && bypasswmi)
-               return 0;
-
-       return __ath6kl_init_netdev(dev);
-}
-#else
-static int ath6kl_init_netdev_wmi(struct net_device *dev)
-{
-       return __ath6kl_init_netdev(dev);
-}
-#endif
-
-static int ath6kl_init_netdev(struct ar6_softc *ar)
-{
-       int r;
-
-        r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode);
-        if (r) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                               ("ar6000_avail: "
-                                "ar6000_sysfs_bmi_get_config failed\n"));
-               return r;
-        }
-
-       return ath6kl_init_netdev_wmi(ar->arNetDev);
-}
-
-/*
- * HTC Event handlers
- */
-static int
-ar6000_avail_ev(void *context, void *hif_handle)
-{
-    int i;
-    struct net_device *dev;
-    void *ar_netif;
-    struct ar6_softc *ar;
-    int device_index = 0;
-    struct htc_init_info  htcInfo;
-    struct wireless_dev *wdev;
-    int r = 0;
-    struct hif_device_os_device_info osDevInfo;
-
-    memset(&osDevInfo, 0, sizeof(osDevInfo));
-    if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE,
-        &osDevInfo, sizeof(osDevInfo))) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Failed to get OS device instance\n", __func__));
-        return A_ERROR;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
-
-    for (i=0; i < MAX_AR6000; i++) {
-        if (ar6000_devices[i] == NULL) {
-            break;
-        }
-    }
-
-    if (i == MAX_AR6000) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n"));
-        return A_ERROR;
-    }
-
-    /* Save this. It gives a bit better readability especially since */
-    /* we use another local "i" variable below.                      */
-    device_index = i;
-
-    wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice);
-    if (IS_ERR(wdev)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
-        return A_ERROR;
-    }
-    ar_netif = wdev_priv(wdev);
-
-    if (ar_netif == NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
-        return A_ERROR;
-    }
-
-    A_MEMZERO(ar_netif, sizeof(struct ar6_softc));
-    ar = (struct ar6_softc *)ar_netif;
-
-    ar->wdev = wdev;
-    wdev->iftype = NL80211_IFTYPE_STATION;
-
-    dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1);
-    if (!dev) {
-        printk(KERN_CRIT "AR6K: no memory for network device instance\n");
-        ar6k_cfg80211_deinit(ar);
-        return A_ERROR;
-    }
-
-    dev->ieee80211_ptr = wdev;
-    SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
-    wdev->netdev = dev;
-    ar->arNetworkType = INFRA_NETWORK;
-    ar->smeState = SME_DISCONNECTED;
-    ar->arAutoAuthStage = AUTH_IDLE;
-
-    init_netdev(dev, ifname);
-
-
-    ar->arNetDev             = dev;
-    ar->arHifDevice          = hif_handle;
-    ar->arWlanState          = WLAN_ENABLED;
-    ar->arDeviceIndex        = device_index;
-
-    ar->arWlanPowerState     = WLAN_POWER_STATE_ON;
-    ar->arWlanOff            = false;   /* We are in ON state */
-#ifdef CONFIG_PM
-    ar->arWowState           = WLAN_WOW_STATE_NONE;
-    ar->arBTOff              = true;   /* BT chip assumed to be OFF */
-    ar->arBTSharing          = WLAN_CONFIG_BT_SHARING; 
-    ar->arWlanOffConfig      = WLAN_CONFIG_WLAN_OFF;
-    ar->arSuspendConfig      = WLAN_CONFIG_PM_SUSPEND;
-    ar->arWow2Config         = WLAN_CONFIG_PM_WOW2;
-#endif /* CONFIG_PM */
-
-    A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
-    ar->arHBChallengeResp.seqNum = 0;
-    ar->arHBChallengeResp.outstanding = false;
-    ar->arHBChallengeResp.missCnt = 0;
-    ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
-    ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
-
-    ar6000_init_control_info(ar);
-    init_waitqueue_head(&arEvent);
-    sema_init(&ar->arSem, 1);
-    ar->bIsDestroyProgress = false;
-
-    INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
-
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-    A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-    A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
-
-    BMIInit();
-
-    ar6000_sysfs_bmi_init(ar);
-
-    {
-        struct bmi_target_info targ_info;
-
-        r = BMIGetTargetInfo(ar->arHifDevice, &targ_info);
-        if (r)
-            goto avail_ev_failed;
-
-        ar->arVersion.target_ver = targ_info.target_ver;
-        ar->arTargetType = targ_info.target_type;
-       wdev->wiphy->hw_version = targ_info.target_ver;
-    }
-
-    r = ar6000_configure_target(ar);
-    if (r)
-            goto avail_ev_failed;
-
-    A_MEMZERO(&htcInfo,sizeof(htcInfo));
-    htcInfo.pContext = ar;
-    htcInfo.TargetFailure = ar6000_target_failure;
-
-    ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
-
-    if (!ar->arHtcTarget) {
-        r = -ENOMEM;
-        goto avail_ev_failed;
-    }
-
-    spin_lock_init(&ar->arLock);
-
-#ifdef WAPI_ENABLE
-    ar->arWapiEnable = 0;
-#endif
-
-
-    if(csumOffload){
-        /*if external frame work is also needed, change and use an extended rxMetaVerion*/
-        ar->rxMetaVersion=WMI_META_VERSION_2;
-    }
-
-    ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs);
-    if (!ar->aggr_cntxt) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
-            r = -ENOMEM;
-            goto avail_ev_failed;
-    }
-
-    aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
-
-    HIFClaimDevice(ar->arHifDevice, ar);
-
-    /* We only register the device in the global list if we succeed. */
-    /* If the device is in the global list, it will be destroyed     */
-    /* when the module is unloaded.                                  */
-    ar6000_devices[device_index] = dev;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
-    if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
-        (wlaninitmode == WLAN_INIT_MODE_DRV)) {
-       r = ath6kl_init_netdev(ar);
-       if (r)
-            goto avail_ev_failed;
-    }
-
-    /* This runs the init function if registered */
-    r = register_netdev(dev);
-    if (r) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
-        ar6000_destroy(dev, 0);
-        return r;
-    }
-
-       is_netdev_registered = 1;
-
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-    arApNetDev = NULL;
-#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n",
-                    dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index,
-                    (unsigned long)ar));
-
-avail_ev_failed :
-    if (r)
-        ar6000_sysfs_bmi_deinit(ar);  
-
-    return r;
-}
-
-static void ar6000_target_failure(void *Instance, int Status)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)Instance;
-    WMI_TARGET_ERROR_REPORT_EVENT errEvent;
-    static bool sip = false;
-
-    if (Status != 0) {
-
-        printk(KERN_ERR "ar6000_target_failure: target asserted \n");
-
-        if (timer_pending(&ar->arHBChallengeResp.timer)) {
-            A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
-        }
-
-        /* try dumping target assertion information (if any) */
-        ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
-
-        /*
-         * Fetch the logs from the target via the diagnostic
-         * window.
-         */
-        ar6000_dbglog_get_debug_logs(ar);
-
-        /* Report the error only once */
-        if (!sip) {
-            sip = true;
-            errEvent.errorVal = WMI_TARGET_COM_ERR |
-                                WMI_TARGET_FATAL_ERR;
-        }
-    }
-}
-
-static int
-ar6000_unavail_ev(void *context, void *hif_handle)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)context;
-        /* NULL out it's entry in the global list */
-    ar6000_devices[ar->arDeviceIndex] = NULL;
-    ar6000_destroy(ar->arNetDev, 1);
-
-    return 0;
-}
-
-void
-ar6000_restart_endpoint(struct net_device *dev)
-{
-    int status = 0;
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    BMIInit();
-    do {
-        if ( (status=ar6000_configure_target(ar))!= 0)
-            break;
-        if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
-            break;
-        }
-        rtnl_lock();
-        status = (ar6000_init(dev)==0) ? 0 : A_ERROR;
-        rtnl_unlock();
-
-        if (status) {
-            break;
-        }
-        if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) {
-            ar6000_connect_to_ap(ar);
-        }  
-    } while (0);
-
-    if (status== 0) {
-        return;
-    }
-
-    ar6000_devices[ar->arDeviceIndex] = NULL;
-    ar6000_destroy(ar->arNetDev, 1);
-}
-
-void
-ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    /* Stop the transmit queues */
-    netif_stop_queue(dev);
-
-    /* Disable the target and the interrupts associated with it */
-    if (ar->arWmiReady == true)
-    {
-        if (!bypasswmi)
-        {
-            bool disconnectIssued;
-            disconnectIssued = (ar->arConnected) || (ar->arConnectPending);
-            ar6000_disconnect(ar);
-            if (!keepprofile) {
-                ar6000_init_profile_info(ar);
-            }
-
-            A_UNTIMEOUT(&ar->disconnect_timer);
-
-            if (getdbglogs) {
-                ar6000_dbglog_get_debug_logs(ar);
-            }
-
-            ar->arWmiReady  = false;
-            wmi_shutdown(ar->arWmi);
-            ar->arWmiEnabled = false;
-            ar->arWmi = NULL;
-            /* 
-             * After wmi_shudown all WMI events will be dropped.
-             * We need to cleanup the buffers allocated in AP mode
-             * and give disconnect notification to stack, which usually
-             * happens in the disconnect_event. 
-             * Simulate the disconnect_event by calling the function directly.
-             * Sometimes disconnect_event will be received when the debug logs 
-             * are collected.
-             */
-            if (disconnectIssued) {
-                if(ar->arNetworkType & AP_NETWORK) {
-                    ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0);
-                } else {
-                    ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
-                }
-            }
-            ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
-            ar->user_key_ctrl      = 0;
-        }
-
-         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
-    }
-    else
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n",
-            __func__, (unsigned long) ar, (unsigned long) ar->arWmi));
-
-        /* Shut down WMI if we have started it */
-        if(ar->arWmiEnabled == true)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
-            wmi_shutdown(ar->arWmi);
-            ar->arWmiEnabled = false;
-            ar->arWmi = NULL;
-        }
-    }
-
-    if (ar->arHtcTarget != NULL) {
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
-            ar6kHciTransCallbacks.cleanupTransport(NULL);
-        }
-#else
-        // FIXME: workaround to reset BT's UART baud rate to default
-        if (NULL != ar->exitCallback) {
-            struct ar3k_config_info ar3kconfig;
-            int status;
-
-            A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
-            ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
-            status = ar->exitCallback(&ar3kconfig);
-            if (0 != status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
-            }
-        }
-        // END workaround
-        if (setuphci)
-               ar6000_cleanup_hci(ar);
-#endif
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
-        /* stop HTC */
-        HTCStop(ar->arHtcTarget);
-    }
-
-    if (resetok) {
-        /* try to reset the device if we can
-         * The driver may have been configure NOT to reset the target during
-         * a debug session */
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
-        if (ar->arHifDevice != NULL) {
-            bool coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? true: false;
-            ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, coldReset);
-        }
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n"));
-    }
-       /* Done with cookies */
-    ar6000_cookie_cleanup(ar);
-
-    /* cleanup any allocated AMSDU buffers */
-    ar6000_cleanup_amsdu_rxbufs(ar);
-}
-/*
- * We need to differentiate between the surprise and planned removal of the
- * device because of the following consideration:
- * - In case of surprise removal, the hcd already frees up the pending
- *   for the device and hence there is no need to unregister the function
- *   driver inorder to get these requests. For planned removal, the function
- *   driver has to explicitly unregister itself to have the hcd return all the
- *   pending requests before the data structures for the devices are freed up.
- *   Note that as per the current implementation, the function driver will
- *   end up releasing all the devices since there is no API to selectively
- *   release a particular device.
- * - Certain commands issued to the target can be skipped for surprise
- *   removal since they will anyway not go through.
- */
-void
-ar6000_destroy(struct net_device *dev, unsigned int unregister)
-{
-    struct ar6_softc *ar;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
-    
-    if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__));
-        return;
-    }
-
-    ar->bIsDestroyProgress = true;
-
-    if (down_interruptible(&ar->arSem)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__));
-        return;
-    }
-
-    if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
-        /* only stop endpoint if we are not stop it in suspend_ev */
-        ar6000_stop_endpoint(dev, false, true);
-    }
-
-    ar->arWlanState = WLAN_DISABLED;
-    if (ar->arHtcTarget != NULL) {
-        /* destroy HTC */
-        HTCDestroy(ar->arHtcTarget);
-    }
-    if (ar->arHifDevice != NULL) {
-        /*release the device so we do not get called back on remove incase we
-         * we're explicity destroyed by module unload */
-        HIFReleaseDevice(ar->arHifDevice);
-        HIFShutDownDevice(ar->arHifDevice);
-    }
-    aggr_module_destroy(ar->aggr_cntxt);
-
-       /* Done with cookies */
-    ar6000_cookie_cleanup(ar);
-
-        /* cleanup any allocated AMSDU buffers */
-    ar6000_cleanup_amsdu_rxbufs(ar);
-
-    ar6000_sysfs_bmi_deinit(ar);
-
-    /* Cleanup BMI */
-    BMICleanup();
-
-    /* Clear the tx counters */
-    memset(tx_attempt, 0, sizeof(tx_attempt));
-    memset(tx_post, 0, sizeof(tx_post));
-    memset(tx_complete, 0, sizeof(tx_complete));
-
-#ifdef HTC_RAW_INTERFACE
-    if (ar->arRawHtc) {
-        kfree(ar->arRawHtc);
-        ar->arRawHtc = NULL;
-    }
-#endif 
-    /* Free up the device data structure */
-    if (unregister && is_netdev_registered) {          
-        unregister_netdev(dev);
-        is_netdev_registered = 0;
-    }
-    free_netdev(dev);
-
-    ar6k_cfg80211_deinit(ar);
-
-#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
-    ar6000_remove_ap_interface();
-#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-
-    kfree(ar->fw_otp);
-    kfree(ar->fw);
-    kfree(ar->fw_patch);
-    kfree(ar->fw_data);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
-}
-
-static void disconnect_timer_handler(unsigned long ptr)
-{
-    struct net_device *dev = (struct net_device *)ptr;
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    A_UNTIMEOUT(&ar->disconnect_timer);
-
-    ar6000_init_profile_info(ar);
-    ar6000_disconnect(ar);
-}
-
-static void ar6000_detect_error(unsigned long ptr)
-{
-    struct net_device *dev = (struct net_device *)ptr;
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_TARGET_ERROR_REPORT_EVENT errEvent;
-
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    if (ar->arHBChallengeResp.outstanding) {
-        ar->arHBChallengeResp.missCnt++;
-    } else {
-        ar->arHBChallengeResp.missCnt = 0;
-    }
-
-    if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
-        /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
-        ar->arHBChallengeResp.missCnt = 0;
-        ar->arHBChallengeResp.seqNum = 0;
-        errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        return;
-    }
-
-    /* Generate the sequence number for the next challenge */
-    ar->arHBChallengeResp.seqNum++;
-    ar->arHBChallengeResp.outstanding = true;
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    /* Send the challenge on the control channel */
-    if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n"));
-    }
-
-
-    /* Reschedule the timer for the next challenge */
-    A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
-}
-
-void ar6000_init_profile_info(struct ar6_softc *ar)
-{
-    ar->arSsidLen            = 0;
-    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-
-    switch(fwmode) {
-        case HI_OPTION_FW_MODE_IBSS:
-            ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
-            break;
-        case HI_OPTION_FW_MODE_BSS_STA:
-            ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
-            break;
-        case HI_OPTION_FW_MODE_AP:
-            ar->arNetworkType = ar->arNextMode = AP_NETWORK;
-            break;
-    }
-
-    ar->arDot11AuthMode      = OPEN_AUTH;
-    ar->arAuthMode           = NONE_AUTH;
-    ar->arPairwiseCrypto     = NONE_CRYPT;
-    ar->arPairwiseCryptoLen  = 0;
-    ar->arGroupCrypto        = NONE_CRYPT;
-    ar->arGroupCryptoLen     = 0;
-    A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
-    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-    A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
-    ar->arBssChannel = 0;
-}
-
-static void
-ar6000_init_control_info(struct ar6_softc *ar)
-{
-    ar->arWmiEnabled         = false;
-    ar6000_init_profile_info(ar);
-    ar->arDefTxKeyIndex      = 0;
-    A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
-    ar->arChannelHint        = 0;
-    ar->arListenIntervalT    = A_DEFAULT_LISTEN_INTERVAL;
-    ar->arListenIntervalB    = 0;
-    ar->arVersion.host_ver   = AR6K_SW_VERSION;
-    ar->arRssi               = 0;
-    ar->arTxPwr              = 0;
-    ar->arTxPwrSet           = false;
-    ar->arSkipScan           = 0;
-    ar->arBeaconInterval     = 0;
-    ar->arBitRate            = 0;
-    ar->arMaxRetries         = 0;
-    ar->arWmmEnabled         = true;
-    ar->intra_bss            = 1;
-    ar->scan_triggered       = 0;
-    A_MEMZERO(&ar->scParams, sizeof(ar->scParams));
-    ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT;
-    ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS;
-
-    /* Initialize the AP mode state info */
-    {
-        u8 ctr;
-        A_MEMZERO((u8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
-
-        /* init the Mutexes */
-        A_MUTEX_INIT(&ar->mcastpsqLock);
-
-        /* Init the PS queues */
-        for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
-            A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
-            A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
-        }
-
-        ar->ap_profile_flag = 0;
-        A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
-
-        memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
-        ar->ap_wmode = DEF_AP_WMODE_G;
-        ar->ap_dtim_period = DEF_AP_DTIM;
-        ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
-    }
-}
-
-static int
-ar6000_open(struct net_device *dev)
-{
-    unsigned long  flags;
-    struct ar6_softc    *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    spin_lock_irqsave(&ar->arLock, flags);
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        ar->arWlanState = WLAN_ENABLED;
-    }
-
-    if( ar->arConnected || bypasswmi) {
-        netif_carrier_on(dev);
-        /* Wake up the queues */
-        netif_wake_queue(dev);
-    }
-    else
-        netif_carrier_off(dev);
-
-    spin_unlock_irqrestore(&ar->arLock, flags);
-    return 0;
-}
-
-static int
-ar6000_close(struct net_device *dev)
-{
-    struct ar6_softc    *ar = (struct ar6_softc *)ar6k_priv(dev);
-    netif_stop_queue(dev);
-
-    ar6000_disconnect(ar);
-
-    if(ar->arWmiReady == true) {
-        if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
-                               0, 0, 0, 0, 0, 0, 0, 0) != 0) {
-            return -EIO;
-        }
-        ar->arWlanState = WLAN_DISABLED;
-    }
-       ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED);
-
-    return 0;
-}
-
-/* connect to a service */
-static int ar6000_connectservice(struct ar6_softc               *ar,
-                                      struct htc_service_connect_req  *pConnect,
-                                      char *pDesc)
-{
-    int                 status;
-    struct htc_service_connect_resp response;
-
-    do {
-
-        A_MEMZERO(&response,sizeof(response));
-
-        status = HTCConnectService(ar->arHtcTarget,
-                                   pConnect,
-                                   &response);
-
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n",
-                              pDesc, status));
-            break;
-        }
-        switch (pConnect->ServiceID) {
-            case WMI_CONTROL_SVC :
-                if (ar->arWmiEnabled) {
-                        /* set control endpoint for WMI use */
-                    wmi_set_control_ep(ar->arWmi, response.Endpoint);
-                }
-                    /* save EP for fast lookup */
-                ar->arControlEp = response.Endpoint;
-                break;
-            case WMI_DATA_BE_SVC :
-                arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
-                break;
-            case WMI_DATA_BK_SVC :
-                arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
-                break;
-            case WMI_DATA_VI_SVC :
-                arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
-                 break;
-           case WMI_DATA_VO_SVC :
-                arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
-                break;
-           default:
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID));
-                status = A_EINVAL;
-            break;
-        }
-
-    } while (false);
-
-    return status;
-}
-
-void ar6000_TxDataCleanup(struct ar6_softc *ar)
-{
-        /* flush all the data (non-control) streams
-         * we only flush packets that are tagged as data, we leave any control packets that
-         * were in the TX queues alone */
-    HTCFlushEndpoint(ar->arHtcTarget,
-                     arAc2EndpointID(ar, WMM_AC_BE),
-                     AR6K_DATA_PKT_TAG);
-    HTCFlushEndpoint(ar->arHtcTarget,
-                     arAc2EndpointID(ar, WMM_AC_BK),
-                     AR6K_DATA_PKT_TAG);
-    HTCFlushEndpoint(ar->arHtcTarget,
-                     arAc2EndpointID(ar, WMM_AC_VI),
-                     AR6K_DATA_PKT_TAG);
-    HTCFlushEndpoint(ar->arHtcTarget,
-                     arAc2EndpointID(ar, WMM_AC_VO),
-                     AR6K_DATA_PKT_TAG);
-}
-
-HTC_ENDPOINT_ID
-ar6000_ac2_endpoint_id ( void * devt, u8 ac)
-{
-    struct ar6_softc *ar = (struct ar6_softc *) devt;
-    return(arAc2EndpointID(ar, ac));
-}
-
-u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
-{
-    struct ar6_softc *ar = (struct ar6_softc *) devt;
-    return(arEndpoint2Ac(ar, ep ));
-}
-
-#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
-static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
-{
-       int r;
-       WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
-       WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
-
-       /* Configure the type of BT collocated with WLAN */
-       memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
-       sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV;
-
-       r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd);
-
-       if (r) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                               ("Unable to set collocated BT type\n"));
-               return r;
-       }
-
-       /* Configure the type of BT collocated with WLAN */
-       memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
-
-       sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA;
-
-       r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd);
-       if (r) {
-               AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                               ("Unable to set fornt end antenna configuration\n"));
-               return r;
-       }
-
-       return 0;
-}
-#else
-static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
-{
-       return 0;
-}
-#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
-
-/*
- * This function applies WLAN specific configuration defined in wlan_config.h
- */
-int ar6000_target_config_wlan_params(struct ar6_softc *ar)
-{
-    int status = 0;
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-    if (ar->arTargetMode != AR6000_WLAN_MODE) {
-        return 0;
-    }
-#endif /* CONFIG_HOST_TCMD_SUPPORT */
-
-    /* 
-     * configure the device for rx dot11 header rules 0,0 are the default values
-     * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required
-     * if checksum offload is needed. Set RxMetaVersion to 2
-     */
-    if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n"));
-        status = A_ERROR;
-    }
-
-    status = ath6kl_config_btcoex_params(ar);
-    if (status)
-       return status;
-
-#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
-    if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power save fail event policy\n"));
-        status = A_ERROR;
-    }
-#endif
-
-#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
-    if ((wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set barker preamble policy\n"));
-        status = A_ERROR;
-    }
-#endif
-
-    if ((wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set keep alive interval\n"));
-        status = A_ERROR;
-    }
-
-#if WLAN_CONFIG_DISABLE_11N
-    {
-        WMI_SET_HT_CAP_CMD htCap;
-
-        memset(&htCap, 0, sizeof(WMI_SET_HT_CAP_CMD));
-        htCap.band = 0;
-        if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
-            status = A_ERROR;
-        }
-
-        htCap.band = 1;
-        if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n"));
-            status = A_ERROR;
-        }
-    }
-#endif /* WLAN_CONFIG_DISABLE_11N */
-
-#ifdef ATH6K_CONFIG_OTA_MODE
-    if ((wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power mode \n"));
-        status = A_ERROR;
-    }
-#endif
-
-    if ((wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set disconnect timeout \n"));
-        status = A_ERROR;
-    }
-
-#if WLAN_CONFIG_DISABLE_TX_BURSTING  
-    if ((wmi_set_wmm_txop(ar->arWmi, WMI_TXOP_DISABLED)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set txop bursting \n"));
-        status = A_ERROR;
-    }
-#endif 
-
-    return status;
-}
-
-/* This function does one time initialization for the lifetime of the device */
-int ar6000_init(struct net_device *dev)
-{
-    struct ar6_softc *ar;
-    int    status;
-    s32 timeleft;
-    s16 i;
-    int         ret = 0;
-
-    if((ar = ar6k_priv(dev)) == NULL)
-    {
-        return -EIO;
-    }
-
-    if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) {
-    
-        ar6000_update_bdaddr(ar);
-
-        if (enablerssicompensation) {
-            ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType);
-            read_rssi_compensation_param(ar);
-            for (i=-95; i<=0; i++) {
-                rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
-            }
-        }
-    }
-
-    dev_hold(dev);
-    rtnl_unlock();
-
-    /* Do we need to finish the BMI phase */
-    if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) && 
-        (BMIDone(ar->arHifDevice) != 0))
-    {
-        ret = -EIO;
-        goto ar6000_init_done;
-    }
-
-    if (!bypasswmi)
-    {
-#if 0 /* TBDXXX */
-        if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
-            A_PRINTF("WARNING: Host version 0x%x does not match Target "
-                    " version 0x%x!\n",
-                    ar->arVersion.host_ver, ar->arVersion.target_ver);
-        }
-#endif
-
-        /* Indicate that WMI is enabled (although not ready yet) */
-        ar->arWmiEnabled = true;
-        if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__));
-            ret = -EIO;
-            goto ar6000_init_done;
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__,
-            (unsigned long) ar->arWmi));
-    }
-
-    do {
-        struct htc_service_connect_req connect;
-
-            /* the reason we have to wait for the target here is that the driver layer
-             * has to init BMI in order to set the host block size,
-             */
-        status = HTCWaitTarget(ar->arHtcTarget);
-
-        if (status) {
-            break;
-        }
-
-        A_MEMZERO(&connect,sizeof(connect));
-            /* meta data is unused for now */
-        connect.pMetaData = NULL;
-        connect.MetaDataLength = 0;
-            /* these fields are the same for all service endpoints */
-        connect.EpCallbacks.pContext = ar;
-        connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
-        connect.EpCallbacks.EpRecv = ar6000_rx;
-        connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
-        connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
-            /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
-             * Linux has the peculiarity of not providing flow control between the
-             * NIC and the network stack. There is no API to indicate that a TX packet
-             * was sent which could provide some back pressure to the network stack.
-             * Under linux you would have to wait till the network stack consumed all sk_buffs
-             * before any back-flow kicked in. Which isn't very friendly.
-             * So we have to manage this ourselves */
-        connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
-        connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
-        if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
-            connect.EpCallbacks.RecvRefillWaterMark++;
-        }
-            /* connect to control service */
-        connect.ServiceID = WMI_CONTROL_SVC;
-        status = ar6000_connectservice(ar,
-                                       &connect,
-                                       "WMI CONTROL");
-        if (status) {
-            break;
-        }
-
-        connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING;
-            /* limit the HTC message size on the send path, although we can receive A-MSDU frames of
-             * 4K, we will only send ethernet-sized (802.3) frames on the send path. */
-        connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
-
-            /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold
-             * mechanism for larger packets */
-        connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
-        connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
-
-            /* for the remaining data services set the connection flag to reduce dribbling,
-             * if configured to do so */
-        if (reduce_credit_dribble) {
-            connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
-            /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
-             * of 0-3 */
-            connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
-            connect.ConnectionFlags |=
-                        ((u16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
-        }
-            /* connect to best-effort service */
-        connect.ServiceID = WMI_DATA_BE_SVC;
-
-        status = ar6000_connectservice(ar,
-                                       &connect,
-                                       "WMI DATA BE");
-        if (status) {
-            break;
-        }
-
-            /* connect to back-ground
-             * map this to WMI LOW_PRI */
-        connect.ServiceID = WMI_DATA_BK_SVC;
-        status = ar6000_connectservice(ar,
-                                       &connect,
-                                       "WMI DATA BK");
-        if (status) {
-            break;
-        }
-
-            /* connect to Video service, map this to
-             * to HI PRI */
-        connect.ServiceID = WMI_DATA_VI_SVC;
-        status = ar6000_connectservice(ar,
-                                       &connect,
-                                       "WMI DATA VI");
-        if (status) {
-            break;
-        }
-
-            /* connect to VO service, this is currently not
-             * mapped to a WMI priority stream due to historical reasons.
-             * WMI originally defined 3 priorities over 3 mailboxes
-             * We can change this when WMI is reworked so that priorities are not
-             * dependent on mailboxes */
-        connect.ServiceID = WMI_DATA_VO_SVC;
-        status = ar6000_connectservice(ar,
-                                       &connect,
-                                       "WMI DATA VO");
-        if (status) {
-            break;
-        }
-
-        A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
-        A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
-        A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
-        A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
-
-            /* setup access class priority mappings */
-        ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest  */
-        ar->arAcStreamPriMap[WMM_AC_BE] = 1; /*         */
-        ar->arAcStreamPriMap[WMM_AC_VI] = 2; /*         */
-        ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
-            struct hci_transport_misc_handles hciHandles;
-
-            hciHandles.netDevice = ar->arNetDev;
-            hciHandles.hifDevice = ar->arHifDevice;
-            hciHandles.htcHandle = ar->arHtcTarget;
-            status = (int)(ar6kHciTransCallbacks.setupTransport(&hciHandles));
-        }
-#else
-        if (setuphci) {
-                /* setup HCI */
-            status = ar6000_setup_hci(ar);
-        }
-#endif
-
-    } while (false);
-
-    if (status) {
-        ret = -EIO;
-        goto ar6000_init_done;
-    }
-
-       if (regscanmode) {
-               u32 param;
-
-               if (BMIReadMemory(ar->arHifDevice,
-                                 HOST_INTEREST_ITEM_ADDRESS(ar,
-                                                            hi_option_flag),
-                                                            (u8 *)&param,
-                                                            4) != 0) {
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                                       ("BMIReadMemory forsetting "
-                                        "regscanmode failed\n"));
-                       return A_ERROR;
-               }
-
-               if (regscanmode == 1)
-                       param |= HI_OPTION_SKIP_REG_SCAN;
-               else if (regscanmode == 2)
-                       param |= HI_OPTION_INIT_REG_SCAN;
-
-               if (BMIWriteMemory(ar->arHifDevice,
-                                  HOST_INTEREST_ITEM_ADDRESS(ar,
-                                                             hi_option_flag),
-                                                             (u8 *)&param,
-                                                             4) != 0) {
-                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                                       ("BMIWriteMemory forsetting "
-                                       "regscanmode failed\n"));
-                       return A_ERROR;
-               }
-               AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Regulatory scan mode set\n"));
-       }
-
-    /*
-     * give our connected endpoints some buffers
-     */
-
-    ar6000_rx_refill(ar, ar->arControlEp);
-    ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
-
-    /*
-     * We will post the receive buffers only for SPE or endpoint ping testing so we are
-     * making it conditional on the 'bypasswmi' flag.
-     */
-    if (bypasswmi) {
-        ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
-        ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
-        ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
-    }
-
-    /* allocate some buffers that handle larger AMSDU frames */
-    ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
-
-        /* setup credit distribution */
-    ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
-
-    /* Since cookies are used for HTC transports, they should be */
-    /* initialized prior to enabling HTC.                        */
-    ar6000_cookie_init(ar);
-
-    /* start HTC */
-    status = HTCStart(ar->arHtcTarget);
-
-    if (status) {
-        if (ar->arWmiEnabled == true) {
-            wmi_shutdown(ar->arWmi);
-            ar->arWmiEnabled = false;
-            ar->arWmi = NULL;
-        }
-        ar6000_cookie_cleanup(ar);
-        ret = -EIO;
-        goto ar6000_init_done;
-    }
-
-    if (!bypasswmi) {
-        /* Wait for Wmi event to be ready */
-        timeleft = wait_event_interruptible_timeout(arEvent,
-            (ar->arWmiReady == true), wmitimeout * HZ);
-
-        if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver));
-#ifndef ATH6K_SKIP_ABI_VERSION_CHECK
-            ret = -EIO;
-            goto ar6000_init_done;
-#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */
-        }
-
-        if(!timeleft || signal_pending(current))
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n"));
-            ret = -EIO;
-            goto ar6000_init_done;
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
-
-        /* Communicate the wmi protocol verision to the target */
-        if ((ar6000_set_host_app_area(ar)) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n"));
-        }
-        ar6000_target_config_wlan_params(ar);
-    }
-
-    ar->arNumDataEndPts = 1;
-
-    if (bypasswmi) {
-            /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise
-             * the data path through a raw socket is disabled */
-        dev->dev_addr[0] = 0x00;
-        dev->dev_addr[1] = 0x01;
-        dev->dev_addr[2] = 0x02;
-        dev->dev_addr[3] = 0xAA;
-        dev->dev_addr[4] = 0xBB;
-        dev->dev_addr[5] = 0xCC;
-    }
-
-ar6000_init_done:
-    rtnl_lock();
-    dev_put(dev);
-
-    return ret;
-}
-
-
-void
-ar6000_bitrate_rx(void *devt, s32 rateKbps)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-
-    ar->arBitRate = rateKbps;
-    wake_up(&arEvent);
-}
-
-void
-ar6000_ratemask_rx(void *devt, u32 ratemask)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-
-    ar->arRateMask = ratemask;
-    wake_up(&arEvent);
-}
-
-void
-ar6000_txPwr_rx(void *devt, u8 txPwr)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-
-    ar->arTxPwr = txPwr;
-    wake_up(&arEvent);
-}
-
-
-void
-ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-
-    memcpy(ar->arChannelList, chanList, numChan * sizeof (u16));
-    ar->arNumChannels = numChan;
-
-    wake_up(&arEvent);
-}
-
-u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo)
-{
-    struct ar6_softc      *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u8 *datap;
-    ATH_MAC_HDR     *macHdr;
-    u32 i, eptMap;
-
-    (*mapNo) = 0;
-    datap = A_NETBUF_DATA(skb);
-    macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
-    if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
-        return ENDPOINT_2;
-    }
-
-    eptMap = -1;
-    for (i = 0; i < ar->arNodeNum; i ++) {
-        if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
-            (*mapNo) = i + 1;
-            ar->arNodeMap[i].txPending ++;
-            return ar->arNodeMap[i].epId;
-        }
-
-        if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
-            eptMap = i;
-        }
-    }
-
-    if (eptMap == -1) {
-        eptMap = ar->arNodeNum;
-        ar->arNodeNum ++;
-        A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
-    }
-
-    memcpy(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
-
-    for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
-        if (!ar->arTxPending[i]) {
-            ar->arNodeMap[eptMap].epId = i;
-            break;
-        }
-        // No free endpoint is available, start redistribution on the inuse endpoints.
-        if (i == ENDPOINT_5) {
-            ar->arNodeMap[eptMap].epId = ar->arNexEpId;
-            ar->arNexEpId ++;
-            if (ar->arNexEpId > ENDPOINT_5) {
-                ar->arNexEpId = ENDPOINT_2;
-            }
-        }
-    }
-
-    (*mapNo) = eptMap + 1;
-    ar->arNodeMap[eptMap].txPending ++;
-
-    return ar->arNodeMap[eptMap].epId;
-}
-
-#ifdef DEBUG
-static void ar6000_dump_skb(struct sk_buff *skb)
-{
-   u_char *ch;
-   for (ch = A_NETBUF_DATA(skb);
-        (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) +
-        A_NETBUF_LEN(skb)); ch++)
-    {
-         AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
-}
-#endif
-
-#ifdef HTC_TEST_SEND_PKTS
-static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb);
-#endif
-
-static int
-ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
-{
-#define AC_NOT_MAPPED   99
-    struct ar6_softc        *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u8 ac = AC_NOT_MAPPED;
-    HTC_ENDPOINT_ID    eid = ENDPOINT_UNUSED;
-    u32 mapNo = 0;
-    int               len;
-    struct ar_cookie *cookie;
-    bool            checkAdHocPsMapping = false,bMoreData = false;
-    HTC_TX_TAG        htc_tag = AR6K_DATA_PKT_TAG;
-    u8 dot11Hdr = processDot11Hdr;
-#ifdef CONFIG_PM
-    if (ar->arWowState != WLAN_WOW_STATE_NONE) {
-        A_NETBUF_FREE(skb);
-        return 0;
-    }
-#endif /* CONFIG_PM */
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n",
-                     (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb),
-                     A_NETBUF_LEN(skb)));
-
-    /* If target is not associated */
-    if( (!ar->arConnected && !bypasswmi)
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-     /* TCMD doesn't support any data, free the buf and return */
-    || (ar->arTargetMode == AR6000_TCMD_MODE)
-#endif
-                                            ) {
-        A_NETBUF_FREE(skb);
-        return 0;
-    }
-
-    do {
-
-        if (ar->arWmiReady == false && bypasswmi == 0) {
-            break;
-        }
-
-#ifdef BLOCK_TX_PATH_FLAG
-        if (blocktx) {
-            break;
-        }
-#endif /* BLOCK_TX_PATH_FLAG */
-
-        /* AP mode Power save processing */
-        /* If the dst STA is in sleep state, queue the pkt in its PS queue */
-
-        if (ar->arNetworkType == AP_NETWORK) {
-            ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
-            sta_t *conn = NULL;
-
-            /* If the dstMac is a Multicast address & atleast one of the
-             * associated STA is in PS mode, then queue the pkt to the
-             * mcastq
-             */
-            if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
-                u8 ctr=0;
-                bool qMcast=false;
-
-
-                for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
-                    if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
-                        qMcast = true;
-                    }
-                }
-                if(qMcast) {
-
-                    /* If this transmit is not because of a Dtim Expiry q it */
-                    if (ar->DTIMExpired == false) {
-                        bool isMcastqEmpty = false;
-
-                        A_MUTEX_LOCK(&ar->mcastpsqLock);
-                        isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
-                        A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
-                        A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-
-                        /* If this is the first Mcast pkt getting queued
-                         * indicate to the target to set the BitmapControl LSB
-                         * of the TIM IE.
-                         */
-                        if (isMcastqEmpty) {
-                             wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
-                        }
-                        return 0;
-                    } else {
-                     /* This transmit is because of Dtim expiry. Determine if
-                      * MoreData bit has to be set.
-                      */
-                         A_MUTEX_LOCK(&ar->mcastpsqLock);
-                         if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
-                             bMoreData = true;
-                         }
-                         A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-                    }
-                }
-            } else {
-                conn = ieee80211_find_conn(ar, datap->dstMac);
-                if (conn) {
-                    if (STA_IS_PWR_SLEEP(conn)) {
-                        /* If this transmit is not because of a PsPoll q it*/
-                        if (!STA_IS_PS_POLLED(conn)) {
-                            bool isPsqEmpty = false;
-                            /* Queue the frames if the STA is sleeping */
-                            A_MUTEX_LOCK(&conn->psqLock);
-                            isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
-                            A_NETBUF_ENQUEUE(&conn->psq, skb);
-                            A_MUTEX_UNLOCK(&conn->psqLock);
-
-                            /* If this is the first pkt getting queued
-                             * for this STA, update the PVB for this STA
-                             */
-                            if (isPsqEmpty) {
-                                wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
-                            }
-
-                            return 0;
-                         } else {
-                         /* This tx is because of a PsPoll. Determine if
-                          * MoreData bit has to be set
-                          */
-                             A_MUTEX_LOCK(&conn->psqLock);
-                             if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
-                                 bMoreData = true;
-                             }
-                             A_MUTEX_UNLOCK(&conn->psqLock);
-                         }
-                    }
-                } else {
-
-                    /* non existent STA. drop the frame */
-                    A_NETBUF_FREE(skb);
-                    return 0;
-                }
-            }
-        }
-
-        if (ar->arWmiEnabled) {
-        u8 csumStart=0;
-        u8 csumDest=0;
-        u8 csum=skb->ip_summed;
-        if(csumOffload && (csum==CHECKSUM_PARTIAL)){
-            csumStart = (skb->head + skb->csum_start - skb_network_header(skb) +
-                        sizeof(ATH_LLC_SNAP_HDR));
-            csumDest=skb->csum_offset+csumStart;
-        }
-            if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
-                struct sk_buff  *newbuf;
-
-                /*
-                 * We really should have gotten enough headroom but sometimes
-                 * we still get packets with not enough headroom.  Copy the packet.
-                 */
-                len = A_NETBUF_LEN(skb);
-                newbuf = A_NETBUF_ALLOC(len);
-                if (newbuf == NULL) {
-                    break;
-                }
-                A_NETBUF_PUT(newbuf, len);
-                memcpy(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
-                A_NETBUF_FREE(skb);
-                skb = newbuf;
-                /* fall through and assemble header */
-            }
-
-            if (dot11Hdr) {
-                if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != 0) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n"));
-                    break;
-                }
-            } else {
-                if (wmi_dix_2_dot3(ar->arWmi, skb) != 0) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n"));
-                    break;
-                }
-            }
-            if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
-                WMI_TX_META_V2  metaV2;
-                metaV2.csumStart =csumStart;
-                metaV2.csumDest = csumDest;
-                metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
-                if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,
-                                        WMI_META_VERSION_2,&metaV2) != 0) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
-                    break;
-                }
-
-            }
-            else
-            {
-                if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
-                    break;
-                }
-            }
-
-
-            if ((ar->arNetworkType == ADHOC_NETWORK) &&
-                ar->arIbssPsEnable && ar->arConnected) {
-                    /* flag to check adhoc mapping once we take the lock below: */
-                checkAdHocPsMapping = true;
-
-            } else {
-                    /* get the stream mapping */
-                ac  =  wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled);
-            }
-
-        } else {
-            EPPING_HEADER    *eppingHdr;
-
-            eppingHdr = A_NETBUF_DATA(skb);
-
-            if (IS_EPPING_PACKET(eppingHdr)) {
-                    /* the stream ID is mapped to an access class */
-                ac = eppingHdr->StreamNo_h;
-                    /* some EPPING packets cannot be dropped no matter what access class it was
-                     * sent on.  We can change the packet tag to guarantee it will not get dropped */
-                if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
-                    htc_tag = AR6K_CONTROL_PKT_TAG;
-                }
-
-                if (ac == HCI_TRANSPORT_STREAM_NUM) {
-                        /* pass this to HCI */
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-                    if (!hci_test_send(ar,skb)) {
-                        return 0;
-                    }
-#endif
-                        /* set AC to discard this skb */
-                    ac = AC_NOT_MAPPED;
-                } else {
-                    /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition
-                     * of the HTC header will mis-align the start of the HTC frame, so we add some
-                     * padding which will be stripped off in the target */
-                    if (EPPING_ALIGNMENT_PAD > 0) {
-                        A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
-                    }
-                }
-
-            } else {
-                    /* not a ping packet, drop it */
-                ac = AC_NOT_MAPPED;
-            }
-        }
-
-    } while (false);
-
-        /* did we succeed ? */
-    if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
-            /* cleanup and exit */
-        A_NETBUF_FREE(skb);
-        AR6000_STAT_INC(ar, tx_dropped);
-        AR6000_STAT_INC(ar, tx_aborted_errors);
-        return 0;
-    }
-
-    cookie = NULL;
-
-        /* take the lock to protect driver data */
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    do {
-
-        if (checkAdHocPsMapping) {
-            eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
-        }else {
-            eid = arAc2EndpointID (ar, ac);
-        }
-            /* validate that the endpoint is connected */
-        if (eid == 0 || eid == ENDPOINT_UNUSED ) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
-            break;
-        }
-            /* allocate resource for this packet */
-        cookie = ar6000_alloc_cookie(ar);
-
-        if (cookie != NULL) {
-                /* update counts while the lock is held */
-            ar->arTxPending[eid]++;
-            ar->arTotalTxDataPending++;
-        }
-
-    } while (false);
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    if (cookie != NULL) {
-        cookie->arc_bp[0] = (unsigned long)skb;
-        cookie->arc_bp[1] = mapNo;
-        SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
-                               cookie,
-                               A_NETBUF_DATA(skb),
-                               A_NETBUF_LEN(skb),
-                               eid,
-                               htc_tag);
-
-#ifdef DEBUG
-        if (debugdriver >= 3) {
-            ar6000_dump_skb(skb);
-        }
-#endif
-#ifdef HTC_TEST_SEND_PKTS
-        DoHTCSendPktsTest(ar,mapNo,eid,skb);
-#endif
-            /* HTC interface is asynchronous, if this fails, cleanup will happen in
-             * the ar6000_tx_complete callback */
-        HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
-    } else {
-            /* no packet to send, cleanup */
-        A_NETBUF_FREE(skb);
-        AR6000_STAT_INC(ar, tx_dropped);
-        AR6000_STAT_INC(ar, tx_aborted_errors);
-    }
-
-    return 0;
-}
-
-int
-ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
-{
-    struct ar6_softc        *ar = (struct ar6_softc *)ar6k_priv(dev);
-    struct ar_cookie *cookie;
-    HTC_ENDPOINT_ID    eid = ENDPOINT_UNUSED;
-
-    cookie = NULL;
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-        /* For now we send ACL on BE endpoint: We can also have a dedicated EP */
-        eid = arAc2EndpointID (ar, 0);
-        /* allocate resource for this packet */
-        cookie = ar6000_alloc_cookie(ar);
-
-        if (cookie != NULL) {
-            /* update counts while the lock is held */
-            ar->arTxPending[eid]++;
-            ar->arTotalTxDataPending++;
-        }
-
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-        if (cookie != NULL) {
-            cookie->arc_bp[0] = (unsigned long)skb;
-            cookie->arc_bp[1] = 0;
-            SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
-                            cookie,
-                            A_NETBUF_DATA(skb),
-                            A_NETBUF_LEN(skb),
-                            eid,
-                            AR6K_DATA_PKT_TAG);
-
-            /* HTC interface is asynchronous, if this fails, cleanup will happen in
-             * the ar6000_tx_complete callback */
-            HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
-        } else {
-            /* no packet to send, cleanup */
-            A_NETBUF_FREE(skb);
-            AR6000_STAT_INC(ar, tx_dropped);
-            AR6000_STAT_INC(ar, tx_aborted_errors);
-        }
-    return 0;
-}
-
-
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-static void
-tvsub(register struct timeval *out, register struct timeval *in)
-{
-    if((out->tv_usec -= in->tv_usec) < 0) {
-        out->tv_sec--;
-        out->tv_usec += 1000000;
-    }
-    out->tv_sec -= in->tv_sec;
-}
-
-void
-applyAPTCHeuristics(struct ar6_softc *ar)
-{
-    u32 duration;
-    u32 numbytes;
-    u32 throughput;
-    struct timeval ts;
-    int status;
-
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
-        do_gettimeofday(&ts);
-        tvsub(&ts, &aptcTR.samplingTS);
-        duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
-        numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
-
-        if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
-            /* Initialize the time stamp and byte count */
-            aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
-            do_gettimeofday(&aptcTR.samplingTS);
-
-            /* Calculate and decide based on throughput thresholds */
-            throughput = ((numbytes * 8) / duration);
-            if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
-                /* Disable Sleep and schedule a timer */
-                A_ASSERT(ar->arWmiReady == true);
-                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-                status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
-                AR6000_SPIN_LOCK(&ar->arLock, 0);
-                A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
-                aptcTR.timerScheduled = true;
-            }
-        }
-    }
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-}
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6_softc     *ar = (struct ar6_softc *)Context;
-    HTC_SEND_FULL_ACTION    action = HTC_SEND_FULL_KEEP;
-    bool                  stopNet = false;
-    HTC_ENDPOINT_ID         Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
-
-    do {
-
-        if (bypasswmi) {
-            int accessClass;
-
-            if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
-                    /* don't drop special control packets */
-                break;
-            }
-
-            accessClass = arEndpoint2Ac(ar,Endpoint);
-                /* for endpoint ping testing drop Best Effort and Background */
-            if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
-                action = HTC_SEND_FULL_DROP;
-                stopNet = false;
-            } else {
-                    /* keep but stop the netqueues */
-                stopNet = true;
-            }
-            break;
-        }
-
-        if (Endpoint == ar->arControlEp) {
-                /* under normal WMI if this is getting full, then something is running rampant
-                 * the host should not be exhausting the WMI queue with too many commands
-                 * the only exception to this is during testing using endpointping */
-            AR6000_SPIN_LOCK(&ar->arLock, 0);
-                /* set flag to handle subsequent messages */
-            ar->arWMIControlEpFull = true;
-            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n"));
-                /* no need to stop the network */
-            stopNet = false;
-            break;
-        }
-
-        /* if we get here, we are dealing with data endpoints getting full */
-
-        if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
-            /* don't drop control packets issued on ANY data endpoint */
-            break;
-        }
-
-        if (ar->arNetworkType == ADHOC_NETWORK) {
-            /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to
-             * continue, however we should stop the network */
-            stopNet = true;
-            break;
-        }
-        /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest
-         * active stream */
-        if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri &&
-            ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
-                /* this stream's priority is less than the highest active priority, we
-                 * give preference to the highest priority stream by directing
-                 * HTC to drop the packet that overflowed */
-            action = HTC_SEND_FULL_DROP;
-                /* since we are dropping packets, no need to stop the network */
-            stopNet = false;
-            break;
-        }
-
-    } while (false);
-
-    if (stopNet) {
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-        ar->arNetQueueStopped = true;
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        /* one of the data endpoints queues is getting full..need to stop network stack
-         * the queue will resume in ar6000_tx_complete() */
-        netif_stop_queue(ar->arNetDev);
-    }
-
-    return action;
-}
-
-
-static void
-ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue)
-{
-    struct ar6_softc     *ar = (struct ar6_softc *)Context;
-    u32 mapNo = 0;
-    int        status;
-    struct ar_cookie * ar_cookie;
-    HTC_ENDPOINT_ID   eid;
-    bool          wakeEvent = false;
-    struct sk_buff_head  skb_queue;
-    struct htc_packet      *pPacket;
-    struct sk_buff  *pktSkb;
-    bool          flushing = false;
-
-    skb_queue_head_init(&skb_queue);
-
-        /* lock the driver as we update internal state */
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-        /* reap completed packets */
-    while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
-
-        pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
-
-        ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
-        A_ASSERT(ar_cookie);
-
-        status = pPacket->Status;
-        pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
-        eid = pPacket->Endpoint;
-        mapNo = ar_cookie->arc_bp[1];
-
-        A_ASSERT(pktSkb);
-        A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
-
-            /* add this to the list, use faster non-lock API */
-        __skb_queue_tail(&skb_queue,pktSkb);
-
-        if (!status) {
-            A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ",
-                         (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer,
-                         pPacket->ActualLength,
-                         eid));
-
-        ar->arTxPending[eid]--;
-
-        if ((eid  != ar->arControlEp) || bypasswmi) {
-            ar->arTotalTxDataPending--;
-        }
-
-        if (eid == ar->arControlEp)
-        {
-            if (ar->arWMIControlEpFull) {
-                    /* since this packet completed, the WMI EP is no longer full */
-                ar->arWMIControlEpFull = false;
-            }
-
-            if (ar->arTxPending[eid] == 0) {
-                wakeEvent = true;
-            }
-        }
-
-        if (status) {
-            if (status == A_ECANCELED) {
-                    /* a packet was flushed  */
-                flushing = true;
-            }
-            AR6000_STAT_INC(ar, tx_errors);
-            if (status != A_NO_RESOURCE) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
-                            status));
-            }
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
-            flushing = false;
-            AR6000_STAT_INC(ar, tx_packets);
-            ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-            aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
-            applyAPTCHeuristics(ar);
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-        }
-
-        // TODO this needs to be looked at
-        if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
-            && (eid != ar->arControlEp) && mapNo)
-        {
-            mapNo --;
-            ar->arNodeMap[mapNo].txPending --;
-
-            if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
-                u32 i;
-                for (i = ar->arNodeNum; i > 0; i --) {
-                    if (!ar->arNodeMap[i - 1].txPending) {
-                        A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
-                        ar->arNodeNum --;
-                    } else {
-                        break;
-                    }
-                }
-            }
-        }
-
-        ar6000_free_cookie(ar, ar_cookie);
-
-        if (ar->arNetQueueStopped) {
-            ar->arNetQueueStopped = false;
-        }
-    }
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    /* lock is released, we can freely call other kernel APIs */
-
-        /* free all skbs in our local list */
-    while (!skb_queue_empty(&skb_queue)) {
-            /* use non-lock version */
-        pktSkb = __skb_dequeue(&skb_queue);
-        A_NETBUF_FREE(pktSkb);
-    }
-
-    if ((ar->arConnected == true) || bypasswmi) {
-        if (!flushing) {
-                /* don't wake the queue if we are flushing, other wise it will just
-                 * keep queueing packets, which will keep failing */
-            netif_wake_queue(ar->arNetDev);
-        }
-    }
-
-    if (wakeEvent) {
-        wake_up(&arEvent);
-    }
-
-}
-
-sta_t *
-ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr)
-{
-    sta_t *conn = NULL;
-    u8 i, max_conn;
-
-    switch(ar->arNetworkType) {
-        case AP_NETWORK:
-            max_conn = AP_MAX_NUM_STA;
-            break;
-        default:
-            max_conn=0;
-            break;
-    }
-
-    for (i = 0; i < max_conn; i++) {
-        if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
-            conn = &ar->sta_list[i];
-            break;
-        }
-    }
-
-    return conn;
-}
-
-sta_t *ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid)
-{
-    sta_t *conn = NULL;
-    u8 ctr;
-
-    for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
-        if (ar->sta_list[ctr].aid == aid) {
-            conn = &ar->sta_list[ctr];
-            break;
-        }
-    }
-    return conn;
-}
-
-/*
- * Receive event handler.  This is called by HTC when a packet is received
- */
-int pktcount;
-static void
-ar6000_rx(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)Context;
-    struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
-    int minHdrLen;
-    u8 containsDot11Hdr = 0;
-    int        status = pPacket->Status;
-    HTC_ENDPOINT_ID   ept = pPacket->Endpoint;
-
-    A_ASSERT((status) ||
-             (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d",
-                    (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer,
-                    pPacket->ActualLength, status));
-    if (status) {
-        if (status != A_ECANCELED) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
-        }
-    }
-
-        /* take lock to protect buffer counts
-         * and adaptive power throughput state */
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    if (!status) {
-        AR6000_STAT_INC(ar, rx_packets);
-        ar->arNetStats.rx_bytes += pPacket->ActualLength;
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
-        aptcTR.bytesReceived += a_netbuf_to_len(skb);
-        applyAPTCHeuristics(ar);
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
-
-        A_NETBUF_PUT(skb, pPacket->ActualLength +  HTC_HEADER_LEN);
-        A_NETBUF_PULL(skb, HTC_HEADER_LEN);
-
-#ifdef DEBUG
-        if (debugdriver >= 2) {
-            ar6000_dump_skb(skb);
-        }
-#endif /* DEBUG */
-    }
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    skb->dev = ar->arNetDev;
-    if (status) {
-        AR6000_STAT_INC(ar, rx_errors);
-        A_NETBUF_FREE(skb);
-    } else if (ar->arWmiEnabled == true) {
-        if (ept == ar->arControlEp) {
-           /*
-            * this is a wmi control msg
-            */
-#ifdef CONFIG_PM 
-            ar6000_check_wow_status(ar, skb, true);
-#endif /* CONFIG_PM */
-            wmi_control_rx(ar->arWmi, skb);
-        } else {
-                WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
-                bool is_amsdu;
-                u8 tid;
-
-               /*
-                * This check can be removed if after a while we do not
-                * see the warning. For now we leave it to ensure
-                * we drop these frames accordingly in case the
-                * target generates them for some reason. These
-                * were used for an internal PAL but that's not
-                * used or supported anymore. These frames should
-                * not come up from the target.
-                */
-                if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) ==
-                           WMI_DATA_HDR_DATA_TYPE_ACL)) {
-                       AR6000_STAT_INC(ar, rx_errors);
-                       A_NETBUF_FREE(skb);
-                       return;
-               }
-
-#ifdef CONFIG_PM 
-                ar6000_check_wow_status(ar, NULL, false);
-#endif /* CONFIG_PM */
-                /*
-                 * this is a wmi data packet
-                 */
-                 // NWF
-
-                if (processDot11Hdr) {
-                    minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR);
-                } else {
-                    minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
-                          sizeof(ATH_LLC_SNAP_HDR);
-                }
-
-                /* In the case of AP mode we may receive NULL data frames
-                 * that do not have LLC hdr. They are 16 bytes in size.
-                 * Allow these frames in the AP mode.
-                 * ACL data frames don't follow ethernet frame bounds for
-                 * min length
-                 */
-                if (ar->arNetworkType != AP_NETWORK &&
-                    ((pPacket->ActualLength < minHdrLen) ||
-                    (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
-                {
-                    /*
-                     * packet is too short or too long
-                     */
-                    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
-                    AR6000_STAT_INC(ar, rx_errors);
-                    AR6000_STAT_INC(ar, rx_length_errors);
-                    A_NETBUF_FREE(skb);
-                } else {
-                    u16 seq_no;
-                    u8 meta_type;
-
-#if 0
-                    /* Access RSSI values here */
-                    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
-                        ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
-#endif
-                    /* Get the Power save state of the STA */
-                    if (ar->arNetworkType == AP_NETWORK) {
-                        sta_t *conn = NULL;
-                        u8 psState=0,prevPsState;
-                        ATH_MAC_HDR *datap=NULL;
-                        u16 offset;
-
-                        meta_type = WMI_DATA_HDR_GET_META(dhdr);
-
-                        psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
-                                     >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK;
-
-                        offset = sizeof(WMI_DATA_HDR);
-
-                        switch (meta_type) {
-                            case 0:
-                                break;
-                            case WMI_META_VERSION_1:
-                                offset += sizeof(WMI_RX_META_V1);
-                                break;
-                            case WMI_META_VERSION_2:
-                                offset += sizeof(WMI_RX_META_V2);
-                                break;
-                            default:
-                                break;
-                        }
-
-                        datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
-                        conn = ieee80211_find_conn(ar, datap->srcMac);
-
-                        if (conn) {
-                            /* if there is a change in PS state of the STA,
-                             * take appropriate steps.
-                             * 1. If Sleep-->Awake, flush the psq for the STA
-                             *    Clear the PVB for the STA.
-                             * 2. If Awake-->Sleep, Starting queueing frames
-                             * the STA.
-                             */
-                            prevPsState = STA_IS_PWR_SLEEP(conn);
-                            if (psState) {
-                                STA_SET_PWR_SLEEP(conn);
-                            } else {
-                                STA_CLR_PWR_SLEEP(conn);
-                            }
-
-                            if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
-
-                                if (!STA_IS_PWR_SLEEP(conn)) {
-
-                                    A_MUTEX_LOCK(&conn->psqLock);
-                                    while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
-                                        struct sk_buff *skb=NULL;
-
-                                        skb = A_NETBUF_DEQUEUE(&conn->psq);
-                                        A_MUTEX_UNLOCK(&conn->psqLock);
-                                        ar6000_data_tx(skb,ar->arNetDev);
-                                        A_MUTEX_LOCK(&conn->psqLock);
-                                    }
-                                    A_MUTEX_UNLOCK(&conn->psqLock);
-                                    /* Clear the PVB for this STA */
-                                    wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
-                                }
-                            }
-                        } else {
-                            /* This frame is from a STA that is not associated*/
-                            A_ASSERT(false);
-                        }
-
-                        /* Drop NULL data frames here */
-                        if((pPacket->ActualLength < minHdrLen) ||
-                                (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) {
-                            A_NETBUF_FREE(skb);
-                            goto rx_done;
-                        }
-                    }
-
-                    is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? true : false;
-                    tid = WMI_DATA_HDR_GET_UP(dhdr);
-                    seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
-                    meta_type = WMI_DATA_HDR_GET_META(dhdr);
-                    containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
-
-                    wmi_data_hdr_remove(ar->arWmi, skb);
-
-                    switch (meta_type) {
-                        case WMI_META_VERSION_1:
-                            {
-                                WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb);
-                                A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
-                                A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
-                                break;
-                            }
-                        case WMI_META_VERSION_2:
-                            {
-                                WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
-                                if(pMeta->csumFlags & 0x1){
-                                    skb->ip_summed=CHECKSUM_COMPLETE;
-                                    skb->csum=(pMeta->csum);
-                                }
-                                A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
-                                break;
-                            }
-                        default:
-                            break;
-                    }
-
-                    A_ASSERT(status == 0);
-
-                    /* NWF: print the 802.11 hdr bytes */
-                    if(containsDot11Hdr) {
-                        status = wmi_dot11_hdr_remove(ar->arWmi,skb);
-                    } else if(!is_amsdu) {
-                        status = wmi_dot3_2_dix(skb);
-                    }
-
-                    if (status) {
-                        /* Drop frames that could not be processed (lack of memory, etc.) */
-                        A_NETBUF_FREE(skb);
-                        goto rx_done;
-                    }
-
-                    if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
-                        if (ar->arNetworkType == AP_NETWORK) {
-                            struct sk_buff *skb1 = NULL;
-                            ATH_MAC_HDR *datap;
-
-                            datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
-                            if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
-                                /* Bcast/Mcast frames should be sent to the OS
-                                 * stack as well as on the air.
-                                 */
-                                skb1 = skb_copy(skb,GFP_ATOMIC);
-                            } else {
-                                /* Search for a connected STA with dstMac as
-                                 * the Mac address. If found send the frame to
-                                 * it on the air else send the frame up the
-                                 * stack
-                                 */
-                                sta_t *conn = NULL;
-                                conn = ieee80211_find_conn(ar, datap->dstMac);
-
-                                if (conn && ar->intra_bss) {
-                                    skb1 = skb;
-                                    skb = NULL;
-                                } else if(conn && !ar->intra_bss) {
-                                    A_NETBUF_FREE(skb);
-                                    skb = NULL;
-                                }
-                            }
-                            if (skb1) {
-                                ar6000_data_tx(skb1, ar->arNetDev);
-                            }
-                        }
-                    }
-                    aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
-                    ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
-                }
-            }
-    } else {
-        if (EPPING_ALIGNMENT_PAD > 0) {
-            A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD);
-        }
-        ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
-    }
-
-rx_done:
-
-    return;
-}
-
-static void
-ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
-{
-    struct sk_buff *skb = (struct sk_buff *)osbuf;
-
-    if(skb) {
-        skb->dev = dev;
-        if ((skb->dev->flags & IFF_UP) == IFF_UP) {
-#ifdef CONFIG_PM 
-            ar6000_check_wow_status((struct ar6_softc *)ar6k_priv(dev), skb, false);
-#endif /* CONFIG_PM */
-            skb->protocol = eth_type_trans(skb, skb->dev);
-        /*
-         * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ)
-         * or tasklet use the netif_rx to deliver the packet to the stack
-         * netif_rx will queue the packet onto the receive queue and mark
-         * the softirq thread has a pending action to complete. Kernel will 
-         * schedule the softIrq kernel thread after processing the DSR.
-         *
-         * If this routine is called on a process context, use netif_rx_ni
-         * which will schedle the softIrq kernel thread after queuing the packet.
-         */
-            if (in_interrupt()) {
-                netif_rx(skb);
-            } else {
-                netif_rx_ni(skb);
-            }
-        } else {
-            A_NETBUF_FREE(skb);
-        }
-    }
-}
-
-#if 0
-static void
-ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
-{
-    struct sk_buff *skb = (struct sk_buff *)osbuf;
-
-    if(skb) {
-        skb->dev = dev;
-        if ((skb->dev->flags & IFF_UP) == IFF_UP) {
-            skb->protocol = htons(ETH_P_CONTROL);
-            netif_rx(skb);
-        } else {
-            A_NETBUF_FREE(skb);
-        }
-    }
-}
-#endif
-
-static void
-ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
-{
-    struct ar6_softc  *ar = (struct ar6_softc *)Context;
-    void        *osBuf;
-    int         RxBuffers;
-    int         buffersToRefill;
-    struct htc_packet  *pPacket;
-    struct htc_packet_queue queue;
-
-    buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
-                                    HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint);
-
-    if (buffersToRefill <= 0) {
-            /* fast return, nothing to fill */
-        return;
-    }
-
-    INIT_HTC_PACKET_QUEUE(&queue);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
-                    buffersToRefill, Endpoint));
-
-    for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
-        osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
-        if (NULL == osBuf) {
-            break;
-        }
-            /* the HTC packet wrapper is at the head of the reserved area
-             * in the skb */
-        pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
-            /* set re-fill info */
-        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
-            /* add to queue */
-        HTC_PACKET_ENQUEUE(&queue,pPacket);
-    }
-
-    if (!HTC_QUEUE_EMPTY(&queue)) {
-            /* add packets */
-        HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
-    }
-
-}
-
-  /* clean up our amsdu buffer list */
-static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar)
-{
-    struct htc_packet  *pPacket;
-    void        *osBuf;
-
-        /* empty AMSDU buffer queue and free OS bufs */
-    while (true) {
-
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-        pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-        if (NULL == pPacket) {
-            break;
-        }
-
-        osBuf = pPacket->pPktContext;
-        if (NULL == osBuf) {
-            A_ASSERT(false);
-            break;
-        }
-
-        A_NETBUF_FREE(osBuf);
-    }
-
-}
-
-
-    /* refill the amsdu buffer list */
-static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count)
-{
-    struct htc_packet  *pPacket;
-    void        *osBuf;
-
-    while (Count > 0) {
-        osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
-        if (NULL == osBuf) {
-            break;
-        }
-            /* the HTC packet wrapper is at the head of the reserved area
-             * in the skb */
-        pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf));
-            /* set re-fill info */
-        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0);
-
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-            /* put it in the list */
-        HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        Count--;
-    }
-
-}
-
-    /* callback to allocate a large receive buffer for a pending packet.  This function is called when
-     * an HTC packet arrives whose length exceeds a threshold value
-     *
-     * We use a pre-allocated list of buffers of maximum AMSDU size (4K).  Under linux it is more optimal to
-     * keep the allocation size the same to optimize cached-slab allocations.
-     *
-     * */
-static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length)
-{
-    struct htc_packet  *pPacket = NULL;
-    struct ar6_softc  *ar = (struct ar6_softc *)Context;
-    int         refillCount = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length));
-
-    do {
-
-        if (Length <= AR6000_BUFFER_SIZE) {
-                /* shouldn't be getting called on normal sized packets */
-            A_ASSERT(false);
-            break;
-        }
-
-        if (Length > AR6000_AMSDU_BUFFER_SIZE) {
-            A_ASSERT(false);
-            break;
-        }
-
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-            /* allocate a packet from the list */
-        pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
-            /* see if we need to refill again */
-        refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue);
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-        if (NULL == pPacket) {
-            break;
-        }
-            /* set actual endpoint ID */
-        pPacket->Endpoint = Endpoint;
-
-    } while (false);
-
-    if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
-        ar6000_refill_amsdu_rxbufs(ar,refillCount);
-    }
-
-    return pPacket;
-}
-
-static void    
-ar6000_set_multicast_list(struct net_device *dev)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n"));
-}
-
-static struct net_device_stats *
-ar6000_get_stats(struct net_device *dev)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    return &ar->arNetStats;
-}
-
-void
-ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-    struct net_device *dev = ar->arNetDev;
-
-    memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
-        dev->dev_addr[0], dev->dev_addr[1],
-        dev->dev_addr[2], dev->dev_addr[3],
-        dev->dev_addr[4], dev->dev_addr[5]));
-
-    ar->arPhyCapability = phyCap;
-    ar->arVersion.wlan_ver = sw_ver;
-    ar->arVersion.abi_ver = abi_ver;
-
-    snprintf(ar->wdev->wiphy->fw_version, sizeof(ar->wdev->wiphy->fw_version),
-            "%u:%u:%u:%u",
-            (ar->arVersion.wlan_ver & 0xf0000000) >> 28,
-            (ar->arVersion.wlan_ver & 0x0f000000) >> 24,
-            (ar->arVersion.wlan_ver & 0x00ff0000) >> 16,
-            (ar->arVersion.wlan_ver & 0x0000ffff));
-
-    /* Indicate to the waiting thread that the ready event was received */
-    ar->arWmiReady = true;
-    wake_up(&arEvent);
-}
-
-void ar6000_install_static_wep_keys(struct ar6_softc *ar)
-{
-    u8 index;
-    u8 keyUsage;
-
-    for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
-        if (ar->arWepKeyList[index].arKeyLen) {
-            keyUsage = GROUP_USAGE;
-            if (index == ar->arDefTxKeyIndex) {
-                keyUsage |= TX_USAGE;
-            }
-            wmi_addKey_cmd(ar->arWmi,
-                           index,
-                           WEP_CRYPT,
-                           keyUsage,
-                           ar->arWepKeyList[index].arKeyLen,
-                           NULL,
-                           ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
-                           NO_SYNC_WMIFLAG);
-        }
-    }
-}
-
-void
-add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie,
-            u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
-{
-    u8 free_slot=aid-1;
-
-        memcpy(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
-        memcpy(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
-        ar->sta_list[free_slot].aid = aid;
-        ar->sta_list[free_slot].keymgmt = keymgmt;
-        ar->sta_list[free_slot].ucipher = ucipher;
-        ar->sta_list[free_slot].auth = auth;
-        ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
-    ar->arAPStats.sta[free_slot].aid = aid;
-}
-
-void
-ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid,
-                     u16 listenInterval, u16 beaconInterval,
-                     NETWORK_TYPE networkType, u8 beaconIeLen,
-                     u8 assocReqLen, u8 assocRespLen,
-                     u8 *assocInfo)
-{
-    union iwreq_data wrqu;
-    int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
-    static const char *tag1 = "ASSOCINFO(ReqIEs=";
-    static const char *tag2 = "ASSOCRESPIE=";
-    static const char *beaconIetag = "BEACONIE=";
-    char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
-    char *pos;
-    u8 key_op_ctrl;
-    unsigned long flags;
-    struct ieee80211req_key *ik;
-    CRYPTO_TYPE keyType = NONE_CRYPT;
-
-    if(ar->arNetworkType & AP_NETWORK) {
-        struct net_device *dev = ar->arNetDev;
-        if(memcmp(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
-            ar->arACS = channel;
-            ik = &ar->ap_mode_bkey;
-
-            switch(ar->arAuthMode) {
-            case NONE_AUTH:
-                if(ar->arPairwiseCrypto == WEP_CRYPT) {
-                    ar6000_install_static_wep_keys(ar);
-                }
-#ifdef WAPI_ENABLE
-                else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
-                    ap_set_wapi_key(ar, ik);
-                }
-#endif
-                break;
-            case WPA_PSK_AUTH:
-            case WPA2_PSK_AUTH:
-            case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
-                switch (ik->ik_type) {
-                    case IEEE80211_CIPHER_TKIP:
-                        keyType = TKIP_CRYPT;
-                        break;
-                    case IEEE80211_CIPHER_AES_CCM:
-                        keyType = AES_CRYPT;
-                        break;
-                    default:
-                       goto skip_key;
-                }
-                wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
-                                ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
-                                ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
-                                SYNC_BOTH_WMIFLAG);
-
-                break;
-            }
-skip_key:
-            ar->arConnected  = true;
-            return;
-        }
-
-        A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
-            " AID=%d \n", bssid[0], bssid[1], bssid[2],
-             bssid[3], bssid[4], bssid[5], channel);
-        switch ((listenInterval>>8)&0xFF) {
-            case OPEN_AUTH:
-                A_PRINTF("AUTH: OPEN\n");
-                break;
-            case SHARED_AUTH:
-                A_PRINTF("AUTH: SHARED\n");
-                break;
-            default:
-                A_PRINTF("AUTH: Unknown\n");
-                break;
-        }
-        switch (listenInterval&0xFF) {
-            case WPA_PSK_AUTH:
-                A_PRINTF("KeyMgmt: WPA-PSK\n");
-                break;
-            case WPA2_PSK_AUTH:
-                A_PRINTF("KeyMgmt: WPA2-PSK\n");
-                break;
-            default:
-                A_PRINTF("KeyMgmt: NONE\n");
-                break;
-        }
-        switch (beaconInterval) {
-            case AES_CRYPT:
-                A_PRINTF("Cipher: AES\n");
-                break;
-            case TKIP_CRYPT:
-                A_PRINTF("Cipher: TKIP\n");
-                break;
-            case WEP_CRYPT:
-                A_PRINTF("Cipher: WEP\n");
-                break;
-#ifdef WAPI_ENABLE
-            case WAPI_CRYPT:
-                A_PRINTF("Cipher: WAPI\n");
-                break;
-#endif
-            default:
-                A_PRINTF("Cipher: NONE\n");
-                break;
-        }
-
-        add_new_sta(ar, bssid, channel /*aid*/,
-            assocInfo /* WPA IE */, assocRespLen /* IE len */,
-            listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
-            (listenInterval>>8)&0xFF /* auth alg */);
-
-        /* Send event to application */
-        A_MEMZERO(&wrqu, sizeof(wrqu));
-        memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
-        wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
-        /* In case the queue is stopped when we switch modes, this will
-         * wake it up
-         */
-        netif_wake_queue(ar->arNetDev);
-        return;
-    }
-
-    ar6k_cfg80211_connect_event(ar, channel, bssid,
-                                listenInterval, beaconInterval,
-                                networkType, beaconIeLen,
-                                assocReqLen, assocRespLen,
-                                assocInfo);
-
-    memcpy(ar->arBssid, bssid, sizeof(ar->arBssid));
-    ar->arBssChannel = channel;
-
-    A_PRINTF("AR6000 connected event on freq %d ", channel);
-    A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
-            " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
-            " assocRespLen =%d\n",
-             bssid[0], bssid[1], bssid[2],
-             bssid[3], bssid[4], bssid[5],
-             listenInterval, beaconInterval,
-             beaconIeLen, assocReqLen, assocRespLen);
-    if (networkType & ADHOC_NETWORK) {
-        if (networkType & ADHOC_CREATOR) {
-            A_PRINTF("Network: Adhoc (Creator)\n");
-        } else {
-            A_PRINTF("Network: Adhoc (Joiner)\n");
-        }
-    } else {
-        A_PRINTF("Network: Infrastructure\n");
-    }
-
-    if ((ar->arNetworkType == INFRA_NETWORK)) {
-        wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
-    }
-
-    if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
-
-        beacon_ie_pos = 0;
-        A_MEMZERO(buf, sizeof(buf));
-        sprintf(buf, "%s", beaconIetag);
-        pos = buf + 9;
-        for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
-            sprintf(pos, "%2.2x", assocInfo[i]);
-            pos += 2;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
-
-        A_MEMZERO(&wrqu, sizeof(wrqu));
-        wrqu.data.length = strlen(buf);
-        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-    }
-
-    if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
-    {
-        assoc_resp_ie_pos = beaconIeLen + assocReqLen +
-                            sizeof(u16)  +  /* capinfo*/
-                            sizeof(u16)  +  /* status Code */
-                            sizeof(u16)  ;  /* associd */
-        A_MEMZERO(buf, sizeof(buf));
-        sprintf(buf, "%s", tag2);
-        pos = buf + 12;
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
-        /*
-         * The Association Response Frame w.o. the WLAN header is delivered to
-         * the host, so skip over to the IEs
-         */
-        for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
-            sprintf(pos, "%2.2x", assocInfo[i]);
-            pos += 2;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
-
-        A_MEMZERO(&wrqu, sizeof(wrqu));
-        wrqu.data.length = strlen(buf);
-        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-    }
-
-    if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
-        /*
-         * assoc Request includes capability and listen interval. Skip these.
-         */
-        assoc_req_ie_pos =  beaconIeLen +
-                            sizeof(u16)  +  /* capinfo*/
-                            sizeof(u16);    /* listen interval */
-
-        A_MEMZERO(buf, sizeof(buf));
-        sprintf(buf, "%s", tag1);
-        pos = buf + 17;
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
-        for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
-            sprintf(pos, "%2.2x", assocInfo[i]);
-            pos += 2;
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
-
-        A_MEMZERO(&wrqu, sizeof(wrqu));
-        wrqu.data.length = strlen(buf);
-        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-    }
-
-    if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
-        ar->user_saved_keys.keyOk == true)
-    {
-        key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
-
-        if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
-            key_op_ctrl &= ~KEY_OP_INIT_RSC;
-        } else {
-            key_op_ctrl |= KEY_OP_INIT_RSC;
-        }
-        ar6000_reinstall_keys(ar, key_op_ctrl);
-    }
-
-    netif_wake_queue(ar->arNetDev);
-
-    /* Update connect & link status atomically */
-    spin_lock_irqsave(&ar->arLock, flags);
-    ar->arConnected  = true;
-    ar->arConnectPending = false;
-    netif_carrier_on(ar->arNetDev);
-    spin_unlock_irqrestore(&ar->arLock, flags);
-    /* reset the rx aggr state */
-    aggr_reset_state(ar->aggr_cntxt);
-    reconnect_flag = 0;
-
-    A_MEMZERO(&wrqu, sizeof(wrqu));
-    memcpy(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
-    wrqu.addr.sa_family = ARPHRD_ETHER;
-    wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
-    if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
-        A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
-        ar->arNodeNum = 0;
-        ar->arNexEpId = ENDPOINT_2;
-    }
-   if (!ar->arUserBssFilter) {
-        wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
-   }
-
-}
-
-void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num)
-{
-    A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
-    ar->arNumDataEndPts = num;
-}
-
-void
-sta_cleanup(struct ar6_softc *ar, u8 i)
-{
-    struct sk_buff *skb;
-
-    /* empty the queued pkts in the PS queue if any */
-    A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
-    while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
-        skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
-        A_NETBUF_FREE(skb);
-    }
-    A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
-
-    /* Zero out the state fields */
-    A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT));
-    A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
-    A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
-    ar->sta_list[i].aid = 0;
-    ar->sta_list[i].flags = 0;
-
-    ar->sta_list_index = ar->sta_list_index & ~(1 << i);
-
-}
-
-u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason)
-{
-    u8 i, removed=0;
-
-    if(IS_MAC_NULL(mac)) {
-        return removed;
-    }
-
-    if(IS_MAC_BCAST(mac)) {
-        A_PRINTF("DEL ALL STA\n");
-        for(i=0; i < AP_MAX_NUM_STA; i++) {
-            if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
-                sta_cleanup(ar, i);
-                removed = 1;
-            }
-        }
-    } else {
-        for(i=0; i < AP_MAX_NUM_STA; i++) {
-            if(memcmp(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
-                A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
-                " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
-                 mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
-
-                sta_cleanup(ar, i);
-                removed = 1;
-                break;
-            }
-        }
-    }
-    return removed;
-}
-
-void
-ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid,
-                        u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus)
-{
-    u8 i;
-    unsigned long flags;
-    union iwreq_data wrqu;
-
-    if(ar->arNetworkType & AP_NETWORK) {
-        union iwreq_data wrqu;
-        struct sk_buff *skb;
-
-        if(!remove_sta(ar, bssid, protocolReasonStatus)) {
-            return;
-        }
-
-        /* If there are no more associated STAs, empty the mcast PS q */
-        if (ar->sta_list_index == 0) {
-            A_MUTEX_LOCK(&ar->mcastpsqLock);
-            while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
-                skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
-                A_NETBUF_FREE(skb);
-            }
-            A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-
-            /* Clear the LSB of the BitMapCtl field of the TIM IE */
-            if (ar->arWmiReady) {
-                wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
-            }
-        }
-
-        if(!IS_MAC_BCAST(bssid)) {
-            /* Send event to application */
-            A_MEMZERO(&wrqu, sizeof(wrqu));
-            memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
-            wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
-        }
-
-        ar->arConnected = false;
-        return;
-    }
-
-    ar6k_cfg80211_disconnect_event(ar, reason, bssid,
-                                   assocRespLen, assocInfo,
-                                   protocolReasonStatus);
-
-    /* Send disconnect event to supplicant */
-    A_MEMZERO(&wrqu, sizeof(wrqu));
-    wrqu.addr.sa_family = ARPHRD_ETHER;
-    wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
-
-    /* it is necessary to clear the host-side rx aggregation state */
-    aggr_reset_state(ar->aggr_cntxt);
-
-    A_UNTIMEOUT(&ar->disconnect_timer);
-
-    A_PRINTF("AR6000 disconnected");
-    if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
-        A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
-                 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason));
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus));
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
-                    assocRespLen ? " " : "NULL"));
-    for (i = 0; i < assocRespLen; i++) {
-        if (!(i % 0x10)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
-    /*
-     * If the event is due to disconnect cmd from the host, only they the target
-     * would stop trying to connect. Under any other condition, target would
-     * keep trying to connect.
-     *
-     */
-    if( reason == DISCONNECT_CMD)
-    {
-        if ((!ar->arUserBssFilter) && (ar->arWmiReady)) {
-            wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
-        }
-    } else {
-        ar->arConnectPending = true;
-        if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
-            ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
-            ar->arConnected = true;
-            return;
-        }
-    }
-
-    if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady)) 
-    {
-        bss_t *pWmiSsidnode = NULL;
-
-        /* remove the current associated bssid node */
-        wmi_free_node (ar->arWmi, bssid);
-
-        /*
-         * In case any other same SSID nodes are present
-         * remove it, since those nodes also not available now
-         */
-        do
-        {
-            /*
-             * Find the nodes based on SSID and remove it
-             * NOTE :: This case will not work out for Hidden-SSID
-             */
-            pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, false, true);
-
-            if (pWmiSsidnode)
-            {
-                wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
-            }
-
-        } while (pWmiSsidnode);
-    }
-
-    /* Update connect & link status atomically */
-    spin_lock_irqsave(&ar->arLock, flags);
-    ar->arConnected = false;
-    netif_carrier_off(ar->arNetDev);
-    spin_unlock_irqrestore(&ar->arLock, flags);
-
-    if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
-        reconnect_flag = 0;
-    }
-
-    if (reason != CSERV_DISCONNECT)
-    {
-        ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
-        ar->user_key_ctrl      = 0;
-    }
-
-    netif_stop_queue(ar->arNetDev);
-    A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
-    ar->arBssChannel = 0;
-    ar->arBeaconInterval = 0;
-
-    ar6000_TxDataCleanup(ar);
-}
-
-void
-ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode)
-{
-    A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
-    ar->arRegCode = regCode;
-}
-
-void
-ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt)
-{
-    if(evt->status == 0) {
-        aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz);
-    }
-}
-
-void
-ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *evt)
-{
-    A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz);
-    if(evt->status == 0) {
-    }
-}
-
-void
-ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt)
-{
-    aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
-}
-
-void register_pal_cb(ar6k_pal_config_t *palConfig_p)
-{
-  ar6k_pal_config_g = *palConfig_p;
-}
-
-void
-ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
-{
-    void *osbuf = NULL;
-    s8 i;
-    u8 size, *buf;
-    int ret = 0;
-
-    size = cmd->evt_buf_sz + 4;
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-       ret = A_NO_MEMORY;
-       A_PRINTF("Error in allocating netbuf \n");
-       return;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-    buf = (u8 *)A_NETBUF_DATA(osbuf);
-    /* First 2-bytes carry HCI event/ACL data type
-     * the next 2 are free
-     */
-    *((short *)buf) = WMI_HCI_EVENT_EVENTID;
-    buf += sizeof(int);
-    memcpy(buf, cmd->buf, cmd->evt_buf_sz);
-
-    ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
-    if(loghci) {
-        A_PRINTF_LOG("HCI Event From PAL <-- \n");
-        for(i = 0; i < cmd->evt_buf_sz; i++) {
-           A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
-           if((i % 10) == 0) {
-               A_PRINTF_LOG("\n");
-           }
-        }
-        A_PRINTF_LOG("\n");
-        A_PRINTF_LOG("==================================\n");
-    }
-}
-
-void
-ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info)
-{
-#if WIRELESS_EXT >= 18
-    struct iw_pmkid_cand *pmkcand;
-#else /* WIRELESS_EXT >= 18 */
-    static const char *tag = "PRE-AUTH";
-    char buf[128];
-#endif /* WIRELESS_EXT >= 18 */
-
-    union iwreq_data wrqu;
-    int i;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
-    for (i=0; i < numAps; info++, i++) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
-            info->bssid[0], info->bssid[1], info->bssid[2],
-            info->bssid[3], info->bssid[4], info->bssid[5]));
-        if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
-        }
-        if (info->bssFlags & WMI_PMKID_VALID_BSS) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
-            continue;           /* we skip bss if the pmkid is already valid */
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
-        A_MEMZERO(&wrqu, sizeof(wrqu));
-#if WIRELESS_EXT >= 18
-        pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
-        A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
-        pmkcand->index = i;
-        pmkcand->flags = info->bssFlags;
-        memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
-        wrqu.data.length = sizeof(struct iw_pmkid_cand);
-        wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
-        kfree(pmkcand);
-#else /* WIRELESS_EXT >= 18 */
-        snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
-                 tag,
-                 info->bssid[0], info->bssid[1], info->bssid[2],
-                 info->bssid[3], info->bssid[4], info->bssid[5],
-                 i, info->bssFlags);
-        wrqu.data.length = strlen(buf);
-        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-#endif /* WIRELESS_EXT >= 18 */
-    }
-}
-
-void
-ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
-{
-    static const char *tag = "MLME-MICHAELMICFAILURE.indication";
-    char buf[128];
-    union iwreq_data wrqu;
-
-    /*
-     * For AP case, keyid will have aid of STA which sent pkt with
-     * MIC error. Use this aid to get MAC & send it to hostapd.
-     */
-    if (ar->arNetworkType == AP_NETWORK) {
-        sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2));
-        if(!s){
-            A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid);
-            return;
-        }
-        A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
-        snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
-            tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
-    } else {
-
-    ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
-
-        A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
-             keyid & 0x3, ismcast ? "multi": "uni");
-        snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3,
-             ismcast ? "mult" : "un");
-    }
-
-    memset(&wrqu, 0, sizeof(wrqu));
-    wrqu.data.length = strlen(buf);
-    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-}
-
-void
-ar6000_scanComplete_event(struct ar6_softc *ar, int status)
-{
-
-    ar6k_cfg80211_scanComplete_event(ar, status);
-
-    if (!ar->arUserBssFilter) {
-        wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
-    }
-    if (ar->scan_triggered) {
-        if (status== 0) {
-            union iwreq_data wrqu;
-            A_MEMZERO(&wrqu, sizeof(wrqu));
-            wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL);
-        }
-        ar->scan_triggered = 0;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status));
-}
-
-void
-ar6000_targetStats_event(struct ar6_softc *ar,  u8 *ptr, u32 len)
-{
-    u8 ac;
-
-    if(ar->arNetworkType == AP_NETWORK) {
-        WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
-        WMI_AP_MODE_STAT *ap = &ar->arAPStats;
-
-        if (len < sizeof(*p)) {
-            return;
-        }
-
-        for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
-            ap->sta[ac].tx_bytes   += p->sta[ac].tx_bytes;
-            ap->sta[ac].tx_pkts    += p->sta[ac].tx_pkts;
-            ap->sta[ac].tx_error   += p->sta[ac].tx_error;
-            ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
-            ap->sta[ac].rx_bytes   += p->sta[ac].rx_bytes;
-            ap->sta[ac].rx_pkts    += p->sta[ac].rx_pkts;
-            ap->sta[ac].rx_error   += p->sta[ac].rx_error;
-            ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
-        }
-
-    } else {
-        WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
-         TARGET_STATS *pStats = &ar->arTargetStats;
-
-        if (len < sizeof(*pTarget)) {
-            return;
-        }
-
-        // Update the RSSI of the connected bss.
-        if (ar->arConnected) {
-            bss_t *pConnBss = NULL;
-
-            pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
-            if (pConnBss)
-            {
-                pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
-                pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
-                wmi_node_return(ar->arWmi, pConnBss);
-            }
-        }
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
-        pStats->tx_packets          += pTarget->txrxStats.tx_stats.tx_packets;
-        pStats->tx_bytes            += pTarget->txrxStats.tx_stats.tx_bytes;
-        pStats->tx_unicast_pkts     += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
-        pStats->tx_unicast_bytes    += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
-        pStats->tx_multicast_pkts   += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
-        pStats->tx_multicast_bytes  += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
-        pStats->tx_broadcast_pkts   += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
-        pStats->tx_broadcast_bytes  += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
-        pStats->tx_rts_success_cnt  += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
-        for(ac = 0; ac < WMM_NUM_AC; ac++)
-            pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
-        pStats->tx_errors           += pTarget->txrxStats.tx_stats.tx_errors;
-        pStats->tx_failed_cnt       += pTarget->txrxStats.tx_stats.tx_failed_cnt;
-        pStats->tx_retry_cnt        += pTarget->txrxStats.tx_stats.tx_retry_cnt;
-        pStats->tx_mult_retry_cnt   += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt;
-        pStats->tx_rts_fail_cnt     += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
-        pStats->tx_unicast_rate      = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
-
-        pStats->rx_packets          += pTarget->txrxStats.rx_stats.rx_packets;
-        pStats->rx_bytes            += pTarget->txrxStats.rx_stats.rx_bytes;
-        pStats->rx_unicast_pkts     += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
-        pStats->rx_unicast_bytes    += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
-        pStats->rx_multicast_pkts   += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
-        pStats->rx_multicast_bytes  += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
-        pStats->rx_broadcast_pkts   += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
-        pStats->rx_broadcast_bytes  += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
-        pStats->rx_fragment_pkt     += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
-        pStats->rx_errors           += pTarget->txrxStats.rx_stats.rx_errors;
-        pStats->rx_crcerr           += pTarget->txrxStats.rx_stats.rx_crcerr;
-        pStats->rx_key_cache_miss   += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
-        pStats->rx_decrypt_err      += pTarget->txrxStats.rx_stats.rx_decrypt_err;
-        pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
-        pStats->rx_unicast_rate      = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
-
-
-        pStats->tkip_local_mic_failure
-                                += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
-        pStats->tkip_counter_measures_invoked
-                                += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
-        pStats->tkip_replays        += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
-        pStats->tkip_format_errors  += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
-        pStats->ccmp_format_errors  += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
-        pStats->ccmp_replays        += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
-
-        pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
-        pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
-
-        pStats->cs_bmiss_cnt        += pTarget->cservStats.cs_bmiss_cnt;
-        pStats->cs_lowRssi_cnt      += pTarget->cservStats.cs_lowRssi_cnt;
-        pStats->cs_connect_cnt      += pTarget->cservStats.cs_connect_cnt;
-        pStats->cs_disconnect_cnt   += pTarget->cservStats.cs_disconnect_cnt;
-        pStats->cs_aveBeacon_snr    = pTarget->cservStats.cs_aveBeacon_snr;
-        pStats->cs_aveBeacon_rssi   = pTarget->cservStats.cs_aveBeacon_rssi;
-
-        if (enablerssicompensation) {
-            pStats->cs_aveBeacon_rssi =
-                    rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
-        }
-        pStats->cs_lastRoam_msec    = pTarget->cservStats.cs_lastRoam_msec;
-        pStats->cs_snr              = pTarget->cservStats.cs_snr;
-        pStats->cs_rssi             = pTarget->cservStats.cs_rssi;
-
-        pStats->lq_val              = pTarget->lqVal;
-
-        pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
-        pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
-        pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
-        pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
-        pStats->arp_received += pTarget->arpStats.arp_received;
-        pStats->arp_matched  += pTarget->arpStats.arp_matched;
-        pStats->arp_replied  += pTarget->arpStats.arp_replied;
-
-        if (ar->statsUpdatePending) {
-            ar->statsUpdatePending = false;
-            wake_up(&arEvent);
-        }
-    }
-}
-
-void
-ar6000_rssiThreshold_event(struct ar6_softc *ar,  WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi)
-{
-    USER_RSSI_THOLD userRssiThold;
-
-    rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
-
-    if (enablerssicompensation) {
-        rssi = rssi_compensation_calc(ar, rssi);
-    }
-
-    /* Send an event to the app */
-    userRssiThold.tag = ar->rssi_map[newThreshold].tag;
-    userRssiThold.rssi = rssi;
-    A_PRINTF("rssi Threshold range = %d tag = %d  rssi = %d\n", newThreshold,
-             userRssiThold.tag, userRssiThold.rssi);
-}
-
-
-void
-ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source)
-{
-    if (source != APP_HB_CHALLENGE) {
-        /* This would ignore the replys that come in after their due time */
-        if (cookie == ar->arHBChallengeResp.seqNum) {
-            ar->arHBChallengeResp.outstanding = false;
-        }
-    }
-}
-
-
-void
-ar6000_reportError_event(struct ar6_softc *ar, WMI_TARGET_ERROR_VAL errorVal)
-{
-       static const char * const errString[] = {
-               [WMI_TARGET_PM_ERR_FAIL]    "WMI_TARGET_PM_ERR_FAIL",
-               [WMI_TARGET_KEY_NOT_FOUND]  "WMI_TARGET_KEY_NOT_FOUND",
-               [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
-               [WMI_TARGET_BMISS]          "WMI_TARGET_BMISS",
-               [WMI_PSDISABLE_NODE_JOIN]   "WMI_PSDISABLE_NODE_JOIN"
-       };
-
-    A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
-
-    /* One error is reported at a time, and errorval is a bitmask */
-    if(errorVal & (errorVal - 1))
-       return;
-
-    A_PRINTF("AR6000 Error type = ");
-    switch(errorVal)
-    {
-        case WMI_TARGET_PM_ERR_FAIL:
-        case WMI_TARGET_KEY_NOT_FOUND:
-        case WMI_TARGET_DECRYPTION_ERR:
-        case WMI_TARGET_BMISS:
-        case WMI_PSDISABLE_NODE_JOIN:
-            A_PRINTF("%s\n", errString[errorVal]);
-            break;
-        default:
-            A_PRINTF("INVALID\n");
-            break;
-    }
-
-}
-
-
-void
-ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cacIndication,
-                 u8 statusCode, u8 *tspecSuggestion)
-{
-    WMM_TSPEC_IE    *tspecIe;
-
-    /*
-     * This is the TSPEC IE suggestion from AP.
-     * Suggestion provided by AP under some error
-     * cases, could be helpful for the host app.
-     * Check documentation.
-     */
-    tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
-
-    /*
-     * What do we do, if we get TSPEC rejection? One thought
-     * that comes to mind is implictly delete the pstream...
-     */
-    A_PRINTF("AR6000 CAC notification. "
-                "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
-                 ac, cacIndication, statusCode);
-}
-
-void
-ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel,
-                            u16 newChannel)
-{
-    A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
-             oldChannel, newChannel);
-}
-
-#define AR6000_PRINT_BSSID(_pBss)  do {     \
-        A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
-                 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
-                 (_pBss)[4],(_pBss)[5]);  \
-} while(0)
-
-void
-ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl)
-{
-    u8 i;
-
-    A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
-              pTbl->numEntries, pTbl->roamMode);
-    for (i= 0; i < pTbl->numEntries; i++) {
-        A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
-            pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
-            pTbl->bssRoamInfo[i].bssid[2],
-            pTbl->bssRoamInfo[i].bssid[3],
-            pTbl->bssRoamInfo[i].bssid[4],
-            pTbl->bssRoamInfo[i].bssid[5]);
-        A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
-                 " BIAS %d\n",
-            pTbl->bssRoamInfo[i].rssi,
-            pTbl->bssRoamInfo[i].rssidt,
-            pTbl->bssRoamInfo[i].last_rssi,
-            pTbl->bssRoamInfo[i].util,
-            pTbl->bssRoamInfo[i].roam_util,
-            pTbl->bssRoamInfo[i].bias);
-    }
-}
-
-void
-ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
-{
-    u8 i,j;
-
-    /*Each event now contains exactly one filter, see bug 26613*/
-    A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num,                 wow_reply->num_filters);
-    A_PRINTF("wow mode = %s host mode = %s\n",
-            (wow_reply->wow_mode == 0? "disabled":"enabled"),
-            (wow_reply->host_mode == 1 ? "awake":"asleep"));
-
-
-    /*If there are no patterns, the reply will only contain generic
-      WoW information. Pattern information will exist only if there are
-      patterns present. Bug 26716*/
-
-   /* If this event contains pattern information, display it*/
-    if (wow_reply->this_filter_num) {
-        i=0;
-        A_PRINTF("id=%d size=%d offset=%d\n",
-                    wow_reply->wow_filters[i].wow_filter_id,
-                    wow_reply->wow_filters[i].wow_filter_size,
-                    wow_reply->wow_filters[i].wow_filter_offset);
-       A_PRINTF("wow pattern = ");
-       for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
-             A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
-        }
-
-        A_PRINTF("\nwow mask = ");
-        for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
-            A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
-        }
-        A_PRINTF("\n");
-    }
-}
-
-/*
- * Report the Roaming related data collected on the target
- */
-void
-ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
-{
-    A_PRINTF("Disconnect Data : BSSID: ");
-    AR6000_PRINT_BSSID(p->disassoc_bssid);
-    A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
-             p->disassoc_bss_rssi,p->disassoc_time,
-             p->no_txrx_time);
-    A_PRINTF("Connect Data: BSSID: ");
-    AR6000_PRINT_BSSID(p->assoc_bssid);
-    A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
-             p->assoc_bss_rssi,p->assoc_time,
-             p->allow_txrx_time);
-}
-
-void
-ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p)
-{
-    switch (p->roamDataType) {
-        case ROAM_DATA_TIME:
-            ar6000_display_roam_time(&p->u.roamTime);
-            break;
-        default:
-            break;
-    }
-}
-
-void
-ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *datap, int len)
-{
-    struct sk_buff *skb;
-    WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
-
-
-    if (!ar->arMgmtFilter) {
-        return;
-    }
-    if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
-        (bih->frameType != BEACON_FTYPE))  ||
-        ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
-        (bih->frameType != PROBERESP_FTYPE)))
-    {
-        return;
-    }
-
-    if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
-
-        A_NETBUF_PUT(skb, len);
-        memcpy(A_NETBUF_DATA(skb), datap, len);
-        skb->dev = ar->arNetDev;
-        memcpy(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
-        skb->ip_summed = CHECKSUM_NONE;
-        skb->pkt_type = PACKET_OTHERHOST;
-        skb->protocol = __constant_htons(0x0019);
-        netif_rx(skb);
-    }
-}
-
-u32 wmiSendCmdNum;
-
-int
-ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
-{
-    struct ar6_softc       *ar = (struct ar6_softc *)devt;
-    int         status = 0;
-    struct ar_cookie *cookie = NULL;
-    int i;
-#ifdef CONFIG_PM
-    if (ar->arWowState != WLAN_WOW_STATE_NONE) {
-        A_NETBUF_FREE(osbuf);
-        return A_EACCES;
-    }
-#endif /* CONFIG_PM */
-        /* take lock to protect ar6000_alloc_cookie() */
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-    do {
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n",
-                         (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid));
-
-        if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
-                /* control endpoint is full, don't allocate resources, we
-                 * are just going to drop this packet */
-            cookie = NULL;
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n",
-                    (unsigned long)osbuf, A_NETBUF_LEN(osbuf)));
-        } else {
-            cookie = ar6000_alloc_cookie(ar);
-        }
-
-        if (cookie == NULL) {
-            status = A_NO_MEMORY;
-            break;
-        }
-
-        if(logWmiRawMsgs) {
-            A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
-            for(i = 0; i < a_netbuf_to_len(osbuf); i++)
-                A_PRINTF("%x ", ((u8 *)a_netbuf_to_data(osbuf))[i]);
-            A_PRINTF("\n");
-        }
-
-        wmiSendCmdNum++;
-
-    } while (false);
-
-    if (cookie != NULL) {
-            /* got a structure to send it out on */
-        ar->arTxPending[eid]++;
-
-        if (eid != ar->arControlEp) {
-            ar->arTotalTxDataPending++;
-        }
-    }
-
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    if (cookie != NULL) {
-        cookie->arc_bp[0] = (unsigned long)osbuf;
-        cookie->arc_bp[1] = 0;
-        SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
-                               cookie,
-                               A_NETBUF_DATA(osbuf),
-                               A_NETBUF_LEN(osbuf),
-                               eid,
-                               AR6K_CONTROL_PKT_TAG);
-            /* this interface is asynchronous, if there is an error, cleanup will happen in the
-             * TX completion callback */
-        HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
-        status = 0;
-    }
-
-    if (status) {
-        A_NETBUF_FREE(osbuf);
-    }
-    return status;
-}
-
-/* indicate tx activity or inactivity on a WMI stream */
-void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active)
-{
-    struct ar6_softc  *ar = (struct ar6_softc *)devt;
-    HTC_ENDPOINT_ID eid ;
-    int i;
-
-    if (ar->arWmiEnabled) {
-        eid = arAc2EndpointID(ar, TrafficClass);
-
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-
-        ar->arAcStreamActive[TrafficClass] = Active;
-
-        if (Active) {
-            /* when a stream goes active, keep track of the active stream with the highest priority */
-
-            if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
-                    /* set the new highest active priority */
-                ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
-            }
-
-        } else {
-            /* when a stream goes inactive, we may have to search for the next active stream
-             * that is the highest priority */
-
-            if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
-
-                /* the highest priority stream just went inactive */
-
-                    /* reset and search for the "next" highest "active" priority stream */
-                ar->arHiAcStreamActivePri = 0;
-                for (i = 0; i < WMM_NUM_AC; i++) {
-                    if (ar->arAcStreamActive[i]) {
-                        if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
-                            /* set the new highest active priority */
-                            ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
-                        }
-                    }
-                }
-            }
-        }
-
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-    } else {
-            /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
-             * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c
-             * convert the stream ID to a endpoint */
-        eid = arAc2EndpointID(ar, TrafficClass);
-    }
-
-        /* notify HTC, this may cause credit distribution changes */
-
-    HTCIndicateActivityChange(ar->arHtcTarget,
-                              eid,
-                              Active);
-
-}
-
-void
-ar6000_btcoex_config_event(struct ar6_softc *ar,  u8 *ptr, u32 len)
-{
-
-    WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
-    WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
-
-    A_PRINTF("received config event\n");
-    pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
-    pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
-
-    switch (pBtcoexConfig->btProfileType) {
-        case WMI_BTCOEX_BT_PROFILE_SCO:
-            memcpy(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd,
-                                        sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
-            break;
-        case WMI_BTCOEX_BT_PROFILE_A2DP:
-            memcpy(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd,
-                                        sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
-            break;
-        case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
-            memcpy(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig,
-                                        sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
-            break;
-        case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
-           memcpy(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd,
-                                        sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
-            break;
-    }
-    if (ar->statsUpdatePending) {
-         ar->statsUpdatePending = false;
-          wake_up(&arEvent);
-    }
-}
-
-void
-ar6000_btcoex_stats_event(struct ar6_softc *ar,  u8 *ptr, u32 len)
-{
-    WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
-
-    memcpy(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT));
-
-    if (ar->statsUpdatePending) {
-         ar->statsUpdatePending = false;
-        wake_up(&arEvent);
-    }
-
-}
-module_init(ar6000_init_module);
-module_exit(ar6000_cleanup_module);
-
-/* Init cookie queue */
-static void
-ar6000_cookie_init(struct ar6_softc *ar)
-{
-    u32 i;
-
-    ar->arCookieList = NULL;
-    ar->arCookieCount = 0;
-
-    A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
-
-    for (i = 0; i < MAX_COOKIE_NUM; i++) {
-        ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
-    }
-}
-
-/* cleanup cookie queue */
-static void
-ar6000_cookie_cleanup(struct ar6_softc *ar)
-{
-    /* It is gone .... */
-    ar->arCookieList = NULL;
-    ar->arCookieCount = 0;
-}
-
-/* Init cookie queue */
-static void
-ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie)
-{
-    /* Insert first */
-    A_ASSERT(ar != NULL);
-    A_ASSERT(cookie != NULL);
-
-    cookie->arc_list_next = ar->arCookieList;
-    ar->arCookieList = cookie;
-    ar->arCookieCount++;
-}
-
-/* cleanup cookie queue */
-static struct ar_cookie *
-ar6000_alloc_cookie(struct ar6_softc  *ar)
-{
-    struct ar_cookie   *cookie;
-
-    cookie = ar->arCookieList;
-    if(cookie != NULL)
-    {
-        ar->arCookieList = cookie->arc_list_next;
-        ar->arCookieCount--;
-    }
-
-    return cookie;
-}
-
-void
-ar6000_tx_retry_err_event(void *devt)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
-}
-
-void
-ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr)
-{
-    WMI_SNR_THRESHOLD_EVENT event;
-
-    event.range = newThreshold;
-    event.snr = snr;
-}
-
-void
-ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq));
-}
-
-
-
-u32 a_copy_to_user(void *to, const void *from, u32 n)
-{
-    return(copy_to_user(to, from, n));
-}
-
-u32 a_copy_from_user(void *to, const void *from, u32 n)
-{
-    return(copy_from_user(to, from, n));
-}
-
-
-int
-ar6000_get_driver_cfg(struct net_device *dev,
-                        u16 cfgParam,
-                        void *result)
-{
-
-    int    ret = 0;
-
-    switch(cfgParam)
-    {
-        case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
-           *((u32 *)result) = wlanNodeCaching;
-           break;
-        case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
-           *((u32 *)result) = logWmiRawMsgs;
-            break;
-        default:
-           ret = EINVAL;
-           break;
-    }
-
-    return ret;
-}
-
-void
-ar6000_keepalive_rx(void *devt, u8 configured)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-
-    ar->arKeepaliveConfigured = configured;
-    wake_up(&arEvent);
-}
-
-void
-ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList,
-                        u8 *bssidList)
-{
-    u8 i, j;
-
-    A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
-
-    for (i = 0; i < numPMKID; i++) {
-        A_PRINTF("\nBSSID %d ", i);
-            for (j = 0; j < ATH_MAC_LEN; j++) {
-                A_PRINTF("%2.2x", bssidList[j]);
-            }
-        bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
-        A_PRINTF("\nPMKID %d ", i);
-            for (j = 0; j < WMI_PMKID_LEN; j++) {
-                A_PRINTF("%2.2x", pmkidList->pmkid[j]);
-            }
-        pmkidList = (WMI_PMKID *)((u8 *)pmkidList + ATH_MAC_LEN +
-                                  WMI_PMKID_LEN);
-    }
-}
-
-void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid)
-{
-    sta_t *conn=NULL;
-    bool isPsqEmpty = false;
-
-    conn = ieee80211_find_conn_for_aid(ar, aid);
-
-    /* If the PS q for this STA is not empty, dequeue and send a pkt from
-     * the head of the q. Also update the More data bit in the WMI_DATA_HDR
-     * if there are more pkts for this STA in the PS q. If there are no more
-     * pkts for this STA, update the PVB for this STA.
-     */
-    A_MUTEX_LOCK(&conn->psqLock);
-    isPsqEmpty  = A_NETBUF_QUEUE_EMPTY(&conn->psq);
-    A_MUTEX_UNLOCK(&conn->psqLock);
-
-    if (isPsqEmpty) {
-        /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
-    } else {
-        struct sk_buff *skb = NULL;
-
-        A_MUTEX_LOCK(&conn->psqLock);
-        skb = A_NETBUF_DEQUEUE(&conn->psq);
-        A_MUTEX_UNLOCK(&conn->psqLock);
-        /* Set the STA flag to PSPolled, so that the frame will go out */
-        STA_SET_PS_POLLED(conn);
-        ar6000_data_tx(skb, ar->arNetDev);
-        STA_CLR_PS_POLLED(conn);
-
-        /* Clear the PVB for this STA if the queue has become empty */
-        A_MUTEX_LOCK(&conn->psqLock);
-        isPsqEmpty  = A_NETBUF_QUEUE_EMPTY(&conn->psq);
-        A_MUTEX_UNLOCK(&conn->psqLock);
-
-        if (isPsqEmpty) {
-            wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
-        }
-    }
-}
-
-void ar6000_dtimexpiry_event(struct ar6_softc *ar)
-{
-    bool isMcastQueued = false;
-    struct sk_buff *skb = NULL;
-
-    /* If there are no associated STAs, ignore the DTIM expiry event.
-     * There can be potential race conditions where the last associated
-     * STA may disconnect & before the host could clear the 'Indicate DTIM'
-     * request to the firmware, the firmware would have just indicated a DTIM
-     * expiry event. The race is between 'clear DTIM expiry cmd' going
-     * from the host to the firmware & the DTIM expiry event happening from
-     * the firmware to the host.
-     */
-    if (ar->sta_list_index == 0) {
-        return;
-    }
-
-    A_MUTEX_LOCK(&ar->mcastpsqLock);
-    isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
-    A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-
-    A_ASSERT(isMcastQueued == false);
-
-    /* Flush the mcast psq to the target */
-    /* Set the STA flag to DTIMExpired, so that the frame will go out */
-    ar->DTIMExpired = true;
-
-    A_MUTEX_LOCK(&ar->mcastpsqLock);
-    while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
-        skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
-        A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-
-        ar6000_data_tx(skb, ar->arNetDev);
-
-        A_MUTEX_LOCK(&ar->mcastpsqLock);
-    }
-    A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-
-    /* Reset the DTIMExpired flag back to 0 */
-    ar->DTIMExpired = false;
-
-    /* Clear the LSB of the BitMapCtl field of the TIM IE */
-    wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
-}
-
-void
-read_rssi_compensation_param(struct ar6_softc *ar)
-{
-    u8 *cust_data_ptr;
-
-//#define RSSICOMPENSATION_PRINT
-
-#ifdef RSSICOMPENSATION_PRINT
-    s16 i;
-    cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
-    for (i=0; i<16; i++) {
-        A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr);
-        cust_data_ptr += 1;
-    }
-#endif
-
-    cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
-
-    rssi_compensation_param.customerID = *(u16 *)cust_data_ptr & 0xffff;
-    rssi_compensation_param.enable = *(u16 *)(cust_data_ptr+2) & 0xffff;
-    rssi_compensation_param.bg_param_a = *(u16 *)(cust_data_ptr+4) & 0xffff;
-    rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff;
-    rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff;
-    rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff;
-    rssi_compensation_param.reserved = *(u32 *)(cust_data_ptr+12);
-
-#ifdef RSSICOMPENSATION_PRINT
-    A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID);
-    A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable);
-    A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a);
-    A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b);
-    A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a);
-    A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b);
-    A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved);
-#endif
-
-    if (rssi_compensation_param.enable != 0x1) {
-        rssi_compensation_param.enable = 0;
-    }
-
-   return;
-}
-
-s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt)
-{
-
-    if (freq > 5000)
-    {
-        if (rssi_compensation_param.enable)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d, totalPkt = %d\n", rssi,totalPkt));
-            rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b;
-            rssi = (rssi-50) /100;
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
-        }
-    }
-    else
-    {
-        if (rssi_compensation_param.enable)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d, totalPkt = %d\n", rssi,totalPkt));
-            rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b;
-            rssi = (rssi-50) /100;
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
-        }
-    }
-
-    return rssi;
-}
-
-s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi)
-{
-    if (ar->arBssChannel > 5000)
-    {
-        if (rssi_compensation_param.enable)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d\n", rssi));
-            rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b;
-            rssi = (rssi-50) /100;
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
-        }
-    }
-    else
-    {
-        if (rssi_compensation_param.enable)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation  = %d\n", rssi));
-            rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b;
-            rssi = (rssi-50) /100;
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
-        }
-    }
-
-    return rssi;
-}
-
-s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above)
-{
-    s16 i;
-
-    if (ar->arBssChannel > 5000)
-    {
-        if (rssi_compensation_param.enable)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation  = %d\n", rssi));
-            rssi = rssi * 100;
-            rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a;
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
-        }
-    }
-    else
-    {
-        if (rssi_compensation_param.enable)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation  = %d\n", rssi));
-
-            if (Above) {
-                for (i=95; i>=0; i--) {
-                    if (rssi <=  rssi_compensation_table[i]) {
-                        rssi = 0 - i;
-                        break;
-                    }
-                }
-            } else {
-                for (i=0; i<=95; i++) {
-                    if (rssi >=  rssi_compensation_table[i]) {
-                        rssi = 0 - i;
-                        break;
-                    }
-                }
-            }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
-        }
-    }
-
-    return rssi;
-}
-
-#ifdef WAPI_ENABLE
-void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac)
-{
-    union iwreq_data wrqu;
-    char buf[20];
-
-    A_MEMZERO(buf, sizeof(buf));
-
-    strcpy(buf, "WAPI_REKEY");
-    buf[10] = type;
-    memcpy(&buf[11], mac, ATH_MAC_LEN);
-
-    A_MEMZERO(&wrqu, sizeof(wrqu));
-    wrqu.data.length = 10+1+ATH_MAC_LEN;
-    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-
-    A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
-}
-#endif
-
-static int
-ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl)
-{
-    int status = 0;
-    struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
-    struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
-    CRYPTO_TYPE  keyType = ar->user_saved_keys.keyType;
-
-    if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
-        if (NONE_CRYPT == keyType) {
-            goto _reinstall_keys_out;
-        }
-
-        if (uik->ik_keylen) {
-            status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
-                    ar->user_saved_keys.keyType, PAIRWISE_USAGE,
-                    uik->ik_keylen, (u8 *)&uik->ik_keyrsc,
-                    uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG);
-        }
-
-    } else {
-        status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
-    }
-
-    if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
-        if (NONE_CRYPT == keyType) {
-            goto _reinstall_keys_out;
-        }
-
-        if (bik->ik_keylen) {
-            status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
-                    ar->user_saved_keys.keyType, GROUP_USAGE,
-                    bik->ik_keylen, (u8 *)&bik->ik_keyrsc,
-                    bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG);
-        }
-    } else {
-        status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
-    }
-
-_reinstall_keys_out:
-    ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
-    ar->user_key_ctrl      = 0;
-
-    return status;
-}
-
-
-void
-ar6000_dset_open_req(
-    void *context,
-    u32 id,
-    u32 targHandle,
-    u32 targReplyFn,
-    u32 targReplyArg)
-{
-}
-
-void
-ar6000_dset_close(
-    void *context,
-    u32 access_cookie)
-{
-    return;
-}
-
-void
-ar6000_dset_data_req(
-   void *context,
-   u32 accessCookie,
-   u32 offset,
-   u32 length,
-   u32 targBuf,
-   u32 targReplyFn,
-   u32 targReplyArg)
-{
-}
-
-int
-ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
-{
-    WMI_CONNECT_CMD p;
-    unsigned long  flags;
-
-    /* No change in AP's profile configuration */
-    if(ar->ap_profile_flag==0) {
-        A_PRINTF("COMMIT: No change in profile!!!\n");
-        return -ENODATA;
-    }
-
-    if(!ar->arSsidLen) {
-        A_PRINTF("SSID not set!!!\n");
-        return -ECHRNG;
-    }
-
-    switch(ar->arAuthMode) {
-    case NONE_AUTH:
-        if((ar->arPairwiseCrypto != NONE_CRYPT) &&
-#ifdef WAPI_ENABLE
-           (ar->arPairwiseCrypto != WAPI_CRYPT) &&
-#endif
-           (ar->arPairwiseCrypto != WEP_CRYPT)) {
-            A_PRINTF("Cipher not supported in AP mode Open auth\n");
-            return -EOPNOTSUPP;
-        }
-        break;
-    case WPA_PSK_AUTH:
-    case WPA2_PSK_AUTH:
-    case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
-        break;
-    default:
-        A_PRINTF("This key mgmt type not supported in AP mode\n");
-        return -EOPNOTSUPP;
-    }
-
-    /* Update the arNetworkType */
-    ar->arNetworkType = ar->arNextMode;
-
-    A_MEMZERO(&p,sizeof(p));
-    p.ssidLength = ar->arSsidLen;
-    memcpy(p.ssid,ar->arSsid,p.ssidLength);
-    p.channel = ar->arChannelHint;
-    p.networkType = ar->arNetworkType;
-
-    p.dot11AuthMode = ar->arDot11AuthMode;
-    p.authMode = ar->arAuthMode;
-    p.pairwiseCryptoType = ar->arPairwiseCrypto;
-    p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
-    p.groupCryptoType = ar->arGroupCrypto;
-    p.groupCryptoLen = ar->arGroupCryptoLen;
-    p.ctrl_flags = ar->arConnectCtrlFlags;
-
-    wmi_ap_profile_commit(ar->arWmi, &p);
-    spin_lock_irqsave(&ar->arLock, flags);
-    ar->arConnected  = true;
-    netif_carrier_on(ar->arNetDev);
-    spin_unlock_irqrestore(&ar->arLock, flags);
-    ar->ap_profile_flag = 0;
-    return 0;
-}
-
-int
-ar6000_connect_to_ap(struct ar6_softc *ar)
-{
-    /* The ssid length check prevents second "essid off" from the user,
-       to be treated as a connect cmd. The second "essid off" is ignored.
-    */
-    if((ar->arWmiReady == true) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK)
-    {
-        int status;
-        if((ADHOC_NETWORK != ar->arNetworkType) &&
-           (NONE_AUTH==ar->arAuthMode)          &&
-           (WEP_CRYPT==ar->arPairwiseCrypto)) {
-                ar6000_install_static_wep_keys(ar);
-        }
-
-        if (!ar->arUserBssFilter) {
-            if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
-                return -EIO;
-            }
-        }
-#ifdef WAPI_ENABLE
-        if (ar->arWapiEnable)  {
-            ar->arPairwiseCrypto = WAPI_CRYPT;
-            ar->arPairwiseCryptoLen = 0;
-            ar->arGroupCrypto = WAPI_CRYPT;
-            ar->arGroupCryptoLen = 0;
-            ar->arAuthMode = NONE_AUTH;
-            ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER;
-        }
-#endif
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\
-                        " PW crypto %d PW crypto Len %d GRP crypto %d"\
-                        " GRP crypto Len %d\n",
-                        ar->arAuthMode, ar->arDot11AuthMode,
-                        ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
-                        ar->arGroupCrypto, ar->arGroupCryptoLen));
-        reconnect_flag = 0;
-        /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn.
-           later set it back locally at the STA to 100/1000 TUs depending on the power mode */
-        if ((ar->arNetworkType == INFRA_NETWORK)) {
-            wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (u16)A_MAX_WOW_LISTEN_INTERVAL), 0);
-        }
-        status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
-                                 ar->arDot11AuthMode, ar->arAuthMode,
-                                 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
-                                 ar->arGroupCrypto,ar->arGroupCryptoLen,
-                                 ar->arSsidLen, ar->arSsid,
-                                 ar->arReqBssid, ar->arChannelHint,
-                                 ar->arConnectCtrlFlags);
-        if (status) {
-            wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
-            if (!ar->arUserBssFilter) {
-                wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
-            }
-            return status;
-        }
-
-        if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
-            ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
-        {
-            A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
-        }
-
-        ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
-        
-        ar->arConnectPending = true;
-        return status;    
-    }
-    return A_ERROR;
-}
-
-int
-ar6000_disconnect(struct ar6_softc *ar)
-{
-    if ((ar->arConnected == true) || (ar->arConnectPending == true)) {
-        wmi_disconnect_cmd(ar->arWmi);
-        /* 
-         * Disconnect cmd is issued, clear connectPending.
-         * arConnected will be cleard in disconnect_event notification.
-         */
-        ar->arConnectPending = false;
-    }
-
-    return 0;
-}
-
-int
-ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie)
-{
-    sta_t *conn = NULL;
-    conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
-
-    A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
-    A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
-
-    if(conn) {
-        memcpy(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
-    }
-
-    return 0;
-}
-
-int
-is_iwioctl_allowed(u8 mode, u16 cmd)
-{
-    if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
-        cmd -= SIOCSIWCOMMIT;
-        if(sioctl_filter[cmd] == 0xFF) return 0;
-        if(sioctl_filter[cmd] & mode) return 0;
-    } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
-        cmd -= SIOCIWFIRSTPRIV;
-        if(pioctl_filter[cmd] == 0xFF) return 0;
-        if(pioctl_filter[cmd] & mode) return 0;
-    } else {
-        return A_ERROR;
-    }
-    return A_ENOTSUP;
-}
-
-int
-is_xioctl_allowed(u8 mode, int cmd)
-{
-    if(sizeof(xioctl_filter)-1 < cmd) {
-        A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
-        return 0;
-    }
-    if(xioctl_filter[cmd] == 0xFF) return 0;
-    if(xioctl_filter[cmd] & mode) return 0;
-    return A_ERROR;
-}
-
-#ifdef WAPI_ENABLE
-int
-ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
-{
-    struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
-    KEY_USAGE   keyUsage = 0;
-    int    status;
-
-    if (memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
-        keyUsage = GROUP_USAGE;
-    } else {
-        keyUsage = PAIRWISE_USAGE;
-    }
-    A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
-        keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
-        ik->ik_keylen);
-
-    status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
-                            ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
-                            ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
-                            SYNC_BOTH_WMIFLAG);
-
-    if (0 != status) {
-        return -EIO;
-    }
-    return 0;
-}
-#endif
-
-void ar6000_peer_event(
-    void *context,
-    u8 eventCode,
-    u8 *macAddr)
-{
-    u8 pos;
-
-    for (pos=0;pos<6;pos++)
-        printk("%02x: ",*(macAddr+pos));
-    printk("\n");
-}
-
-#ifdef HTC_TEST_SEND_PKTS
-#define HTC_TEST_DUPLICATE 8
-static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb)
-{
-    struct ar_cookie *cookie;
-    struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
-    struct sk_buff   *new_skb;
-    int    i;
-    int    pkts = 0;
-    struct htc_packet_queue pktQueue;
-    EPPING_HEADER    *eppingHdr;
-
-    eppingHdr = A_NETBUF_DATA(dupskb);
-
-    if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
-        /* skip test if this is already a tx perf test */
-        return;
-    }
-
-    for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-        cookie = ar6000_alloc_cookie(ar);
-        if (cookie != NULL) {
-            ar->arTxPending[eid]++;
-            ar->arTotalTxDataPending++;
-        }
-
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-
-        if (NULL == cookie) {
-            break;
-        }
-
-        new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
-
-        if (new_skb == NULL) {
-            AR6000_SPIN_LOCK(&ar->arLock, 0);
-            ar6000_free_cookie(ar,cookie);
-            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-            break;
-        }
-
-        A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
-        cookie->arc_bp[0] = (unsigned long)new_skb;
-        cookie->arc_bp[1] = MapNo;
-        SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
-                               cookie,
-                               A_NETBUF_DATA(new_skb),
-                               A_NETBUF_LEN(new_skb),
-                               eid,
-                               AR6K_DATA_PKT_TAG);
-
-        cookieArray[i] = cookie;
-
-        {
-            EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
-            pHdr->Cmd_h = EPPING_CMD_NO_ECHO;  /* do not echo the packet */
-        }
-    }
-
-    if (pkts == 0) {
-        return;
-    }
-
-    INIT_HTC_PACKET_QUEUE(&pktQueue);
-
-    for (i = 0; i < pkts; i++) {
-        HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
-    }
-
-    HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
-
-}
-#endif
-
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-/*
- * Add support for adding and removing a virtual adapter for soft AP.
- * Some OS requires different adapters names for station and soft AP mode.
- * To support these requirement, create and destroy a netdevice  instance
- * when the AP mode is operational. A full fledged support for virual device
- * is not implemented. Rather a virtual interface is created and is linked
- * with the existing physical device instance during the operation of the 
- * AP mode.
- */
-
-int ar6000_start_ap_interface(struct ar6_softc *ar)
-{
-    struct ar_virtual_interface *arApDev;
-
-    /* Change net_device to point to AP instance */
-    arApDev = (struct ar_virtual_interface *)ar->arApDev;
-    ar->arNetDev = arApDev->arNetDev;
-
-    return 0;
-}
-
-int ar6000_stop_ap_interface(struct ar6_softc *ar)
-{
-    struct ar_virtual_interface *arApDev;
-
-    /* Change net_device to point to sta instance */
-    arApDev = (struct ar_virtual_interface *)ar->arApDev;
-    if (arApDev) {
-        ar->arNetDev = arApDev->arStaNetDev;
-    }
-
-    return 0;
-}
-
-
-int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname)
-{
-    struct net_device *dev;
-    struct ar_virtual_interface *arApDev;
-
-    dev = alloc_etherdev(sizeof(struct ar_virtual_interface));
-    if (dev == NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n"));
-        return A_ERROR;
-    } 
-    
-    ether_setup(dev);
-    init_netdev(dev, ap_ifname);
-    dev->priv_flags &= ~IFF_TX_SKB_SHARING;
-
-    if (register_netdev(dev)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
-        return A_ERROR;
-    }
-
-    arApDev = netdev_priv(dev);
-    arApDev->arDev = ar;
-    arApDev->arNetDev = dev;
-    arApDev->arStaNetDev = ar->arNetDev;
-
-    ar->arApDev = arApDev;
-    arApNetDev = dev;
-
-    /* Copy the MAC address */
-    memcpy(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN);
-
-    return 0;
-}
-
-int ar6000_add_ap_interface(struct ar6_softc *ar, char *ap_ifname)
-{
-    /* Interface already added, need not proceed further */
-    if (ar->arApDev != NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n"));
-        return 0;
-    }
-
-    if (ar6000_create_ap_interface(ar, ap_ifname) != 0) {
-        return A_ERROR;
-    }
-
-    A_PRINTF("Add AP interface %s \n",ap_ifname);
-
-    return ar6000_start_ap_interface(ar);
-}
-
-int ar6000_remove_ap_interface(struct ar6_softc *ar)
-{
-    if (arApNetDev) {
-        ar6000_stop_ap_interface(ar);
-
-        unregister_netdev(arApNetDev);
-        free_netdev(apApNetDev);
-
-        A_PRINTF("Remove AP interface\n");
-    }
-    ar->arApDev = NULL;
-    arApNetDev = NULL;
-
-    
-    return 0;
-}
-#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-EXPORT_SYMBOL(setupbtdev);
-#endif
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
deleted file mode 100644 (file)
index 1e0ace8..0000000
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- *
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * 
-//
-// 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.
-//
-//
- *
- */
-
-/*
- * Implementation of system power management
- */
-
-#include "ar6000_drv.h"
-#include <linux/inetdevice.h>
-#include <linux/platform_device.h>
-#include "wlan_config.h"
-
-#define WOW_ENABLE_MAX_INTERVAL 0
-#define WOW_SET_SCAN_PARAMS     0
-
-extern unsigned int wmitimeout;
-extern wait_queue_head_t arEvent;
-
-#undef ATH_MODULE_NAME
-#define ATH_MODULE_NAME pm
-#define  ATH_DEBUG_PM       ATH_DEBUG_MAKE_MODULE_MASK(0)
-
-#ifdef DEBUG
-static struct ath_debug_mask_description pm_debug_desc[] = {
-    { ATH_DEBUG_PM     , "System power management"},
-};
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm,
-                                 "pm",
-                                 "System Power Management",
-                                 ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM,
-                                 ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc),
-                                 pm_debug_desc);
-
-#endif /* DEBUG */
-
-int ar6000_exit_cut_power_state(struct ar6_softc *ar);
-
-#ifdef CONFIG_PM
-static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep)
-{
-    char buf[128];
-    union iwreq_data wrqu;
-
-    snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake");
-    A_MEMZERO(&wrqu, sizeof(wrqu));
-    wrqu.data.length = strlen(buf);
-    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-}
-
-static void ar6000_wow_resume(struct ar6_softc *ar)
-{
-    if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
-        u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
-        u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
-        WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false};
-        ar->arWowState = WLAN_WOW_STATE_NONE;
-        if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
-        }
-#if WOW_SET_SCAN_PARAMS
-        wmi_scanparams_cmd(ar->arWmi, fg_start_period,
-                                   ar->scParams.fg_end_period,
-                                   bg_period,
-                                   ar->scParams.minact_chdwell_time,
-                                   ar->scParams.maxact_chdwell_time,
-                                   ar->scParams.pas_chdwell_time,
-                                   ar->scParams.shortScanRatio,
-                                   ar->scParams.scanCtrlFlags,
-                                   ar->scParams.max_dfsch_act_time,
-                                   ar->scParams.maxact_scan_per_ssid);
-#else
-       (void)fg_start_period;
-       (void)bg_period;
-#endif
-
-
-#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
-        if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) {
-        }
-#endif
-        ar6k_send_asleep_event_to_app(ar, false);
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
-    }
-    ar->arWlanPowerState = WLAN_POWER_STATE_ON;
-}
-
-static void ar6000_wow_suspend(struct ar6_softc *ar)
-{
-#define WOW_LIST_ID 1
-    if (ar->arNetworkType != AP_NETWORK) {
-        /* Setup WoW for unicast & Arp request for our own IP
-        disable background scan. Set listen interval into 1000 TUs
-        Enable keepliave for 110 seconds
-        */
-        struct in_ifaddr **ifap = NULL;
-        struct in_ifaddr *ifa = NULL;
-        struct in_device *in_dev;
-        u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-        int status;
-        WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
-        WMI_DEL_WOW_PATTERN_CMD delWowCmd;
-        WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true};
-        WMI_SET_WOW_MODE_CMD wowMode = {    .enable_wow = true,
-                                            .hostReqDelay = 500 };/*500 ms delay*/
-
-        if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
-            return;
-        }
-
-        ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/
-
-#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
-        if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) {
-        }
-#endif
-
-#if WOW_SET_SCAN_PARAMS
-        status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
-#endif
-        /* clear up our WoW pattern first */
-        delWowCmd.filter_list_id = WOW_LIST_ID;
-        delWowCmd.filter_id = 0;
-        wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);
-
-        /* setup unicast packet pattern for WoW */
-        if (ar->arNetDev->dev_addr[1]) {
-            addWowCmd.filter_list_id = WOW_LIST_ID;
-            addWowCmd.filter_size = 6; /* MAC address */
-            addWowCmd.filter_offset = 0;
-            status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
-            }
-        }
-        /* setup ARP request for our own IP */
-        if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
-            for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
-                if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
-                    break; /* found */
-                }
-            }
-        }
-        if (ifa && ifa->ifa_local) {
-            WMI_SET_IP_CMD ipCmd;
-            memset(&ipCmd, 0, sizeof(ipCmd));
-            ipCmd.ips[0] = ifa->ifa_local;
-            status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
-            }
-        }
-
-#ifndef ATH6K_CONFIG_OTA_MODE
-        wmi_powermode_cmd(ar->arWmi, REC_POWER);
-#endif
-
-        status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
-        }
-        ar6k_send_asleep_event_to_app(ar, true);
-
-        status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
-        }
-
-        ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
-        if (ar->arTxPending[ar->arControlEp]) {
-            u32 timeleft = wait_event_interruptible_timeout(arEvent,
-            ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
-            if (!timeleft || signal_pending(current)) {
-               /* what can I do? wow resume at once */
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
-            }
-        }
-
-        status = hifWaitForPendingRecv(ar->arHifDevice);
-
-        ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
-        ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
-    }
-}
-
-int ar6000_suspend_ev(void *context)
-{
-    int status = 0;
-    struct ar6_softc *ar = (struct ar6_softc *)context;
-    s16 pmmode = ar->arSuspendConfig;
-wow_not_connected:
-    switch (pmmode) {
-    case WLAN_SUSPEND_WOW:
-        if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) {
-            ar6000_wow_suspend(ar);
-            AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState));
-        } else {
-            pmmode = ar->arWow2Config;
-            goto wow_not_connected;
-        }
-        break;
-    case WLAN_SUSPEND_CUT_PWR:
-        /* fall through */
-    case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF:
-        /* fall through */
-    case WLAN_SUSPEND_DEEP_SLEEP:
-        /* fall through */
-    default:
-        status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true);
-        if (ar->arWlanPowerState==WLAN_POWER_STATE_ON ||
-            ar->arWlanPowerState==WLAN_POWER_STATE_WOW) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState));
-        }
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status));
-        status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY;
-        break;
-    }
-
-    ar->scan_triggered = 0;
-    return status;
-}
-
-int ar6000_resume_ev(void *context)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)context;
-    u16 powerState = ar->arWlanPowerState;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState));
-    switch (powerState) {
-    case WLAN_POWER_STATE_WOW:
-        ar6000_wow_resume(ar);
-        break;
-    case WLAN_POWER_STATE_CUT_PWR:
-        /* fall through */
-    case WLAN_POWER_STATE_DEEP_SLEEP:
-        ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true);
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState));
-        break;
-    case WLAN_POWER_STATE_ON:
-        break;
-    default:
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n"));
-        break;
-    }
-    return 0;
-}
-
-void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent)
-{
-    if (ar->arWowState!=WLAN_WOW_STATE_NONE) {
-        if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__));
-            return;
-        }
-        /* Wow resume from irq interrupt */
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
-        ar6000_wow_resume(ar);
-    }
-}
-
-int ar6000_power_change_ev(void *context, u32 config)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)context;
-    int status = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config));
-    switch (config) {
-       case HIF_DEVICE_POWER_UP:
-            ar6000_restart_endpoint(ar->arNetDev);
-            status = 0;
-            break;
-       case HIF_DEVICE_POWER_DOWN:
-       case HIF_DEVICE_POWER_CUT:
-            status = 0;
-            break;
-    }
-    return status;
-}
-
-#endif /* CONFIG_PM */
-
-int
-ar6000_setup_cut_power_state(struct ar6_softc *ar,  AR6000_WLAN_STATE state)
-{
-    int                      status = 0;
-    HIF_DEVICE_POWER_CHANGE_TYPE  config;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState));
-#ifdef CONFIG_PM
-    AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
-#endif
-    do {
-        if (state == WLAN_ENABLED) {
-            /* Not in cut power state.. exit */
-            if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
-                break;
-            }
-
-            /* Change the state to ON */
-            ar->arWlanPowerState = WLAN_POWER_STATE_ON;
-
-
-            /* Indicate POWER_UP to HIF */
-            config = HIF_DEVICE_POWER_UP;
-            status = HIFConfigureDevice(ar->arHifDevice,
-                                HIF_DEVICE_POWER_STATE_CHANGE,
-                                &config,
-                                sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
-
-            if (status == A_PENDING) {
-            } else if (status == 0) {
-                ar6000_restart_endpoint(ar->arNetDev);
-                status = 0;
-            }
-        } else if (state == WLAN_DISABLED) {
-
-
-            /* Already in cut power state.. exit */
-            if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
-                break;
-            }
-            ar6000_stop_endpoint(ar->arNetDev, true, false);
-
-            config = HIF_DEVICE_POWER_CUT;
-            status = HIFConfigureDevice(ar->arHifDevice,
-                                HIF_DEVICE_POWER_STATE_CHANGE,
-                                &config,
-                                sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
-
-            ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
-        }
-    } while (0);
-
-    return status;
-}
-
-int
-ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
-{
-    int status = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState));
-#ifdef CONFIG_PM
-    AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
-#endif
-    do {
-        WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode;
-
-        if (state == WLAN_ENABLED) {
-            u16 fg_start_period;
-
-            /* Not in deep sleep state.. exit */
-            if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
-                if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState));
-                }
-                break;
-            }
-
-            fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
-            hostSleepMode.awake = true;
-            hostSleepMode.asleep = false;
-
-            if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) {
-                break;
-            }
-
-            /* Change the state to ON */
-            ar->arWlanPowerState = WLAN_POWER_STATE_ON;
-
-                /* Enable foreground scanning */
-                if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period,
-                                        ar->scParams.fg_end_period,
-                                        ar->scParams.bg_period,
-                                        ar->scParams.minact_chdwell_time,
-                                        ar->scParams.maxact_chdwell_time,
-                                        ar->scParams.pas_chdwell_time,
-                                        ar->scParams.shortScanRatio,
-                                        ar->scParams.scanCtrlFlags,
-                                        ar->scParams.max_dfsch_act_time,
-                                        ar->scParams.maxact_scan_per_ssid)) != 0)
-                {
-                    break;
-                }
-
-            if (ar->arNetworkType != AP_NETWORK)
-            {
-                if (ar->arSsidLen) {
-                    if (ar6000_connect_to_ap(ar) != 0) {
-                        /* no need to report error if connection failed */
-                        break;
-                    }
-                }
-            }
-        } else if (state == WLAN_DISABLED){
-            WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false };
-
-            /* Already in deep sleep state.. exit */
-            if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
-                if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState));
-                }
-                break;
-            }
-
-            if (ar->arNetworkType != AP_NETWORK)
-            {
-                /* Disconnect from the AP and disable foreground scanning */
-                AR6000_SPIN_LOCK(&ar->arLock, 0);
-                if (ar->arConnected == true || ar->arConnectPending == true) {
-                    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-                    wmi_disconnect_cmd(ar->arWmi);
-                } else {
-                    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-                }
-            }
-
-            ar->scan_triggered = 0;
-
-            if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) {
-                break;
-            }
-
-            /* make sure we disable wow for deep sleep */
-            if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0)
-            {
-                break;
-            }
-
-            ar6000_TxDataCleanup(ar);
-#ifndef ATH6K_CONFIG_OTA_MODE
-            wmi_powermode_cmd(ar->arWmi, REC_POWER);
-#endif
-
-            hostSleepMode.awake = false;
-            hostSleepMode.asleep = true;
-            if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) {
-                break;
-            }
-            if (ar->arTxPending[ar->arControlEp]) {
-                u32 timeleft = wait_event_interruptible_timeout(arEvent,
-                                ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
-                if (!timeleft || signal_pending(current)) {
-                    status = A_ERROR;
-                    break;
-                }
-            }
-            status = hifWaitForPendingRecv(ar->arHifDevice);
-
-            ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP;
-        }
-    } while (0);
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state));
-    }
-
-    return status;
-}
-
-int
-ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent)
-{
-    int status = 0;
-    u16 powerState, oldPowerState;
-    AR6000_WLAN_STATE oldstate = ar->arWlanState;
-    bool wlanOff = ar->arWlanOff;
-#ifdef CONFIG_PM
-    bool btOff = ar->arBTOff;
-#endif /* CONFIG_PM */
-
-    if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) {
-        return A_ERROR;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        return A_EBUSY;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return A_ERROR;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        up(&ar->arSem);
-        return A_EBUSY;
-    }
-
-    ar->arWlanState = wlanOff ? WLAN_DISABLED : state;
-    oldPowerState = ar->arWlanPowerState;
-    if (state == WLAN_ENABLED) {
-        powerState = ar->arWlanPowerState;
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n"));
-        if (!wlanOff) {
-            if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
-                status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED);
-            } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
-                status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
-            }
-        }
-#ifdef CONFIG_PM
-        else if (pmEvent && wlanOff) {
-            bool allowCutPwr = ((!ar->arBTSharing) || btOff);
-            if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) {
-                /* Come out of cut power */
-                ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
-                status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
-            }
-        }
-#endif /* CONFIG_PM */
-    } else if (state == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n"));
-        powerState = WLAN_POWER_STATE_DEEP_SLEEP;
-#ifdef CONFIG_PM
-        if (pmEvent) {  /* disable due to suspend */
-            bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR ||
-                                    (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
-                                        ar->arWow2Config==WLAN_SUSPEND_CUT_PWR));
-            bool suspendCutIfBtOff = ((ar->arSuspendConfig ==
-                                            WLAN_SUSPEND_CUT_PWR_IF_BT_OFF ||
-                                        (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
-                                         ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) &&
-                                        (!ar->arBTSharing || btOff));
-            if ((suspendCutPwr) ||
-                (suspendCutIfBtOff) ||
-                (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR))
-            {
-                powerState = WLAN_POWER_STATE_CUT_PWR;
-            }
-        } else {
-            if ((wlanOff) &&
-                (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) &&
-                (!ar->arBTSharing || btOff))
-            {
-                /* For BT clock sharing designs, CUT_POWER depend on BT state */
-                powerState = WLAN_POWER_STATE_CUT_PWR;
-            }
-        }
-#endif /* CONFIG_PM */
-
-        if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
-            if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n"));
-                ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
-            }
-            status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
-        } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
-            status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED);
-        }
-
-    }
-
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState));
-        ar->arWlanState = oldstate;
-    } else if (status == 0) {
-        WMI_REPORT_SLEEP_STATE_EVENT  wmiSleepEvent, *pSleepEvent = NULL;
-        if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) {
-            wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
-            pSleepEvent = &wmiSleepEvent;
-        } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) {
-            wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
-            pSleepEvent = &wmiSleepEvent;
-        }
-        if (pSleepEvent) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
-        }
-    }
-    up(&ar->arSem);
-    return status;
-}
-
-int
-ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable)
-{
-#ifdef CONFIG_PM
-    bool off = (enable == 0);
-    int status;
-    if (ar->arBTOff == off) {
-        return 0;
-    }
-    ar->arBTOff = off;
-    status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false);
-    return status;
-#else
-    return 0;
-#endif
-}
-
-int
-ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
-{
-    int status;
-    bool off = (state == WLAN_DISABLED);
-    if (ar->arWlanOff == off) {
-        return 0;
-    }
-    ar->arWlanOff = off;
-    status = ar6000_update_wlan_pwr_state(ar, state, false);
-    return status;
-}
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
deleted file mode 100644 (file)
index ae7c1dd..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#include "ar6000_drv.h"
-
-#ifdef HTC_RAW_INTERFACE
-
-static void
-ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6_softc        *ar = (struct ar6_softc *)Context;
-    raw_htc_buffer    *busy;
-    HTC_RAW_STREAM_ID streamID; 
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-
-    busy = (raw_htc_buffer *)pPacket->pPktContext;
-    A_ASSERT(busy != NULL);
-
-    if (pPacket->Status == A_ECANCELED) {
-        /*
-         * HTC provides A_ECANCELED status when it doesn't want to be refilled
-         * (probably due to a shutdown)
-         */
-        return;
-    }
-
-    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
-    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
-    
-#ifdef CF
-   if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
-#else
-    if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
-#endif /* CF */
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
-    }
-
-    A_ASSERT((pPacket->Status != 0) ||
-             (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
-
-    busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
-    busy->currPtr = HTC_HEADER_LEN;
-    arRaw->read_buffer_available[streamID] = true;
-    //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb:  0x%X 0x%X \n", busy->currPtr,busy->length);
-    up(&arRaw->raw_htc_read_sem[streamID]);
-
-    /* Signal the waiting process */
-    AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
-    wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
-}
-
-static void
-ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket)
-{
-    struct ar6_softc          *ar = (struct ar6_softc  *)Context;
-    raw_htc_buffer      *free;
-    HTC_RAW_STREAM_ID   streamID;
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-    
-    free = (raw_htc_buffer *)pPacket->pPktContext;
-    A_ASSERT(free != NULL);
-
-    if (pPacket->Status == A_ECANCELED) {
-        /*
-         * HTC provides A_ECANCELED status when it doesn't want to be refilled
-         * (probably due to a shutdown)
-         */
-        return;
-    }
-
-    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
-    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
-    
-#ifdef CF
-    if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
-#else
-    if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
-#endif
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
-    }
-
-    A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
-
-    free->length = 0;
-    arRaw->write_buffer_available[streamID] = true;
-    up(&arRaw->raw_htc_write_sem[streamID]);
-
-    /* Signal the waiting process */
-    AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
-    wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
-}
-
-/* connect to a service */
-static int ar6000_connect_raw_service(struct ar6_softc        *ar,
-                                           HTC_RAW_STREAM_ID StreamID)
-{
-    int                 status;
-    struct htc_service_connect_resp response;
-    u8 streamNo;
-    struct htc_service_connect_req  connect;
-    
-    do {      
-        
-        A_MEMZERO(&connect,sizeof(connect));
-            /* pass the stream ID as meta data to the RAW streams service */
-        streamNo = (u8)StreamID;
-        connect.pMetaData = &streamNo;
-        connect.MetaDataLength = sizeof(u8);
-            /* these fields are the same for all endpoints */
-        connect.EpCallbacks.pContext = ar;
-        connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;   
-        connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;   
-            /* simple interface, we don't need these optional callbacks */      
-        connect.EpCallbacks.EpRecvRefill = NULL;
-        connect.EpCallbacks.EpSendFull = NULL;
-        connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;  
-        
-            /* connect to the raw streams service, we may be able to get 1 or more
-             * connections, depending on WHAT is running on the target */
-        connect.ServiceID = HTC_RAW_STREAMS_SVC;
-        
-        A_MEMZERO(&response,sizeof(response));
-        
-            /* try to connect to the raw stream, it is okay if this fails with 
-             * status HTC_SERVICE_NO_MORE_EP */
-        status = HTCConnectService(ar->arHtcTarget, 
-                                   &connect,
-                                   &response);
-        
-        if (status) {
-            if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
-                status = 0;
-            }
-            break;    
-        }
-
-            /* set endpoint mapping for the RAW HTC streams */
-        arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
-
-        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n", 
-                        StreamID, arRawStream2EndpointID(ar,StreamID)));
-        
-    } while (false);
-    
-    return status;
-}
-
-int ar6000_htc_raw_open(struct ar6_softc *ar)
-{
-    int status;
-    int streamID, endPt, count2;
-    raw_htc_buffer *buffer;
-    HTC_SERVICE_ID servicepriority;
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-    if (!arRaw) {
-        arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
-        if (arRaw) {
-            A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
-        }
-    }
-    A_ASSERT(ar->arHtcTarget != NULL);
-    if (!arRaw) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
-        return -ENOMEM;
-    }
-    /* wait for target */
-    status = HTCWaitTarget(ar->arHtcTarget);
-        
-    if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
-        return -ENODEV;  
-    }
-    
-    for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
-        arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
-    }
-        
-    for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
-        /* Initialize the data structures */
-       sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
-       sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
-        init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
-        init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
-
-            /* try to connect to the raw service */
-        status = ar6000_connect_raw_service(ar,streamID);
-        
-        if (status) {
-            break;    
-        }
-        
-        if (arRawStream2EndpointID(ar,streamID) == 0) {
-            break;    
-        }
-        
-        for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
-            /* Initialize the receive buffers */
-            buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
-            memset(buffer, 0, sizeof(raw_htc_buffer));
-            buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
-            memset(buffer, 0, sizeof(raw_htc_buffer));
-            
-            SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
-                                          buffer,
-                                          buffer->data,
-                                          HTC_RAW_BUFFER_SIZE,
-                                          arRawStream2EndpointID(ar,streamID));
-            
-            /* Queue buffers to HTC for receive */
-            if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0)
-            {
-                BMIInit();
-                return -EIO;
-            }
-        }
-
-        for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
-            /* Initialize the receive buffers */
-            buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
-            memset(buffer, 0, sizeof(raw_htc_buffer));
-        }
-
-        arRaw->read_buffer_available[streamID] = false;
-        arRaw->write_buffer_available[streamID] = true;
-    }
-    
-    if (status) {
-        return -EIO;    
-    }
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));
-            
-    servicepriority = HTC_RAW_STREAMS_SVC;  /* only 1 */
-    
-        /* set callbacks and priority list */
-    HTCSetCreditDistribution(ar->arHtcTarget,
-                             ar,
-                             NULL,  /* use default */
-                             NULL,  /* use default */
-                             &servicepriority,
-                             1);
-
-    /* Start the HTC component */
-    if ((status = HTCStart(ar->arHtcTarget)) != 0) {
-        BMIInit();
-        return -EIO;
-    }
-
-    (ar)->arRawIfInit = true;
-    
-    return 0;
-}
-
-int ar6000_htc_raw_close(struct ar6_softc *ar)
-{
-    A_PRINTF("ar6000_htc_raw_close called \n");
-    HTCStop(ar->arHtcTarget);
-    
-        /* reset the device */
-    ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false);
-    /* Initialize the BMI component */
-    BMIInit();
-
-    return 0;
-}
-
-raw_htc_buffer *
-get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID)
-{
-    int count;
-    raw_htc_buffer *busy;
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-
-    /* Check for data */
-    for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
-        busy = &arRaw->raw_htc_read_buffer[StreamID][count];
-        if (busy->length) {
-            break;
-        }
-    }
-    if (busy->length) {
-        arRaw->read_buffer_available[StreamID] = true;
-    } else {
-        arRaw->read_buffer_available[StreamID] = false;
-    }
-
-    return busy;
-}
-
-ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, 
-                            char __user *buffer, size_t length)
-{
-    int readPtr;
-    raw_htc_buffer *busy;
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-
-    if (arRawStream2EndpointID(ar,StreamID) == 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
-        return -EFAULT;    
-    }
-    
-    if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
-        return -ERESTARTSYS;
-    }
-
-    busy = get_filled_buffer(ar,StreamID);
-    while (!arRaw->read_buffer_available[StreamID]) {
-        up(&arRaw->raw_htc_read_sem[StreamID]);
-
-        /* Wait for the data */
-        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
-        if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
-                                     arRaw->read_buffer_available[StreamID]))
-        {
-            return -EINTR;
-        }
-        if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
-            return -ERESTARTSYS;
-        }
-        busy = get_filled_buffer(ar,StreamID);
-    }
-
-    /* Read the data */
-    readPtr = busy->currPtr;
-    if (length > busy->length - HTC_HEADER_LEN) {
-        length = busy->length - HTC_HEADER_LEN;
-    }
-    if (copy_to_user(buffer, &busy->data[readPtr], length)) {
-        up(&arRaw->raw_htc_read_sem[StreamID]);
-        return -EFAULT;
-    }
-
-    busy->currPtr += length;
-        
-    if (busy->currPtr == busy->length)
-    {    
-        busy->currPtr = 0;
-        busy->length = 0;        
-        HTC_PACKET_RESET_RX(&busy->HTCPacket);                                          
-        //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl:  ep for packet:%d \n", busy->HTCPacket.Endpoint));
-        HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
-    }
-    arRaw->read_buffer_available[StreamID] = false;
-    up(&arRaw->raw_htc_read_sem[StreamID]);
-
-    return length;
-}
-
-static raw_htc_buffer *
-get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID)
-{
-    int count;
-    raw_htc_buffer *free;
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-
-    free = NULL;
-    for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
-        free = &arRaw->raw_htc_write_buffer[StreamID][count];
-        if (free->length == 0) {
-            break;
-        }
-    }
-    if (!free->length) {
-        arRaw->write_buffer_available[StreamID] = true;
-    } else {
-        arRaw->write_buffer_available[StreamID] = false;
-    }
-
-    return free;
-}
-
-ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
-                     char __user *buffer, size_t length)
-{
-    int writePtr;
-    raw_htc_buffer *free;
-    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
-    if (arRawStream2EndpointID(ar,StreamID) == 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
-        return -EFAULT;    
-    }
-    
-    if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
-        return -ERESTARTSYS;
-    }
-
-    /* Search for a free buffer */
-    free = get_free_buffer(ar,StreamID);
-
-    /* Check if there is space to write else wait */
-    while (!arRaw->write_buffer_available[StreamID]) {
-        up(&arRaw->raw_htc_write_sem[StreamID]);
-
-        /* Wait for buffer to become free */
-        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
-        if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
-                                     arRaw->write_buffer_available[StreamID]))
-        {
-            return -EINTR;
-        }
-        if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
-            return -ERESTARTSYS;
-        }
-        free = get_free_buffer(ar,StreamID);
-    }
-
-    /* Send the data */
-    writePtr = HTC_HEADER_LEN;
-    if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
-        length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
-    }
-
-    if (copy_from_user(&free->data[writePtr], buffer, length)) {
-        up(&arRaw->raw_htc_read_sem[StreamID]);
-        return -EFAULT;
-    }
-
-    free->length = length;
-        
-    SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
-                           free,
-                           &free->data[writePtr],
-                           length,
-                           arRawStream2EndpointID(ar,StreamID),
-                           AR6K_DATA_PKT_TAG);
-    
-    HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
-    
-    arRaw->write_buffer_available[StreamID] = false;
-    up(&arRaw->raw_htc_write_sem[StreamID]);
-
-    return length;
-}
-#endif /* HTC_RAW_INTERFACE */
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c
deleted file mode 100644 (file)
index 5fdda4a..0000000
+++ /dev/null
@@ -1,1892 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <net/cfg80211.h>
-#include <net/netlink.h>
-
-#include "ar6000_drv.h"
-
-
-extern A_WAITQUEUE_HEAD arEvent;
-extern unsigned int wmitimeout;
-extern int reconnect_flag;
-
-
-#define RATETAB_ENT(_rate, _rateid, _flags) {   \
-    .bitrate    = (_rate),                  \
-    .flags      = (_flags),                 \
-    .hw_value   = (_rateid),                \
-}
-
-#define CHAN2G(_channel, _freq, _flags) {   \
-    .band           = IEEE80211_BAND_2GHZ,  \
-    .hw_value       = (_channel),           \
-    .center_freq    = (_freq),              \
-    .flags          = (_flags),             \
-    .max_antenna_gain   = 0,                \
-    .max_power      = 30,                   \
-}
-
-#define CHAN5G(_channel, _flags) {              \
-    .band           = IEEE80211_BAND_5GHZ,      \
-    .hw_value       = (_channel),               \
-    .center_freq    = 5000 + (5 * (_channel)),  \
-    .flags          = (_flags),                 \
-    .max_antenna_gain   = 0,                    \
-    .max_power      = 30,                       \
-}
-
-static struct
-ieee80211_rate ar6k_rates[] = {
-    RATETAB_ENT(10,  0x1,   0),
-    RATETAB_ENT(20,  0x2,   0),
-    RATETAB_ENT(55,  0x4,   0),
-    RATETAB_ENT(110, 0x8,   0),
-    RATETAB_ENT(60,  0x10,  0),
-    RATETAB_ENT(90,  0x20,  0),
-    RATETAB_ENT(120, 0x40,  0),
-    RATETAB_ENT(180, 0x80,  0),
-    RATETAB_ENT(240, 0x100, 0),
-    RATETAB_ENT(360, 0x200, 0),
-    RATETAB_ENT(480, 0x400, 0),
-    RATETAB_ENT(540, 0x800, 0),
-};
-
-#define ar6k_a_rates     (ar6k_rates + 4)
-#define ar6k_a_rates_size    8
-#define ar6k_g_rates     (ar6k_rates + 0)
-#define ar6k_g_rates_size    12
-
-static struct
-ieee80211_channel ar6k_2ghz_channels[] = {
-    CHAN2G(1, 2412, 0),
-    CHAN2G(2, 2417, 0),
-    CHAN2G(3, 2422, 0),
-    CHAN2G(4, 2427, 0),
-    CHAN2G(5, 2432, 0),
-    CHAN2G(6, 2437, 0),
-    CHAN2G(7, 2442, 0),
-    CHAN2G(8, 2447, 0),
-    CHAN2G(9, 2452, 0),
-    CHAN2G(10, 2457, 0),
-    CHAN2G(11, 2462, 0),
-    CHAN2G(12, 2467, 0),
-    CHAN2G(13, 2472, 0),
-    CHAN2G(14, 2484, 0),
-};
-
-static struct
-ieee80211_channel ar6k_5ghz_a_channels[] = {
-    CHAN5G(34, 0),      CHAN5G(36, 0),
-    CHAN5G(38, 0),      CHAN5G(40, 0),
-    CHAN5G(42, 0),      CHAN5G(44, 0),
-    CHAN5G(46, 0),      CHAN5G(48, 0),
-    CHAN5G(52, 0),      CHAN5G(56, 0),
-    CHAN5G(60, 0),      CHAN5G(64, 0),
-    CHAN5G(100, 0),     CHAN5G(104, 0),
-    CHAN5G(108, 0),     CHAN5G(112, 0),
-    CHAN5G(116, 0),     CHAN5G(120, 0),
-    CHAN5G(124, 0),     CHAN5G(128, 0),
-    CHAN5G(132, 0),     CHAN5G(136, 0),
-    CHAN5G(140, 0),     CHAN5G(149, 0),
-    CHAN5G(153, 0),     CHAN5G(157, 0),
-    CHAN5G(161, 0),     CHAN5G(165, 0),
-    CHAN5G(184, 0),     CHAN5G(188, 0),
-    CHAN5G(192, 0),     CHAN5G(196, 0),
-    CHAN5G(200, 0),     CHAN5G(204, 0),
-    CHAN5G(208, 0),     CHAN5G(212, 0),
-    CHAN5G(216, 0),
-};
-
-static struct
-ieee80211_supported_band ar6k_band_2ghz = {
-    .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
-    .channels = ar6k_2ghz_channels,
-    .n_bitrates = ar6k_g_rates_size,
-    .bitrates = ar6k_g_rates,
-};
-
-static struct
-ieee80211_supported_band ar6k_band_5ghz = {
-    .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
-    .channels = ar6k_5ghz_a_channels,
-    .n_bitrates = ar6k_a_rates_size,
-    .bitrates = ar6k_a_rates,
-};
-
-static int
-ar6k_set_wpa_version(struct ar6_softc *ar, enum nl80211_wpa_versions wpa_version)
-{
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
-
-    if (!wpa_version) {
-        ar->arAuthMode = NONE_AUTH;
-    } else if (wpa_version & NL80211_WPA_VERSION_1) {
-        ar->arAuthMode = WPA_AUTH;
-    } else if (wpa_version & NL80211_WPA_VERSION_2) {
-        ar->arAuthMode = WPA2_AUTH;
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("%s: %u not spported\n", __func__, wpa_version));
-        return -ENOTSUPP;
-    }
-
-    return 0;
-}
-
-static int
-ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type)
-{
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
-
-    switch (auth_type) {
-    case NL80211_AUTHTYPE_OPEN_SYSTEM:
-        ar->arDot11AuthMode = OPEN_AUTH;
-        break;
-    case NL80211_AUTHTYPE_SHARED_KEY:
-        ar->arDot11AuthMode = SHARED_AUTH;
-        break;
-    case NL80211_AUTHTYPE_NETWORK_EAP:
-        ar->arDot11AuthMode = LEAP_AUTH;
-        break;
-
-    case NL80211_AUTHTYPE_AUTOMATIC:
-        ar->arDot11AuthMode = OPEN_AUTH;
-        ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
-        break;
-
-    default:
-        ar->arDot11AuthMode = OPEN_AUTH;
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                        ("%s: 0x%x not spported\n", __func__, auth_type));
-        return -ENOTSUPP;
-    }
-
-    return 0;
-}
-
-static int
-ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast)
-{
-    u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
-                                &ar->arGroupCrypto;
-    u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
-                                    &ar->arGroupCryptoLen;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                    ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
-
-    switch (cipher) {
-    case 0:
-    case IW_AUTH_CIPHER_NONE:
-        *ar_cipher = NONE_CRYPT;
-        *ar_cipher_len = 0;
-        break;
-    case WLAN_CIPHER_SUITE_WEP40:
-        *ar_cipher = WEP_CRYPT;
-        *ar_cipher_len = 5;
-        break;
-    case WLAN_CIPHER_SUITE_WEP104:
-        *ar_cipher = WEP_CRYPT;
-        *ar_cipher_len = 13;
-        break;
-    case WLAN_CIPHER_SUITE_TKIP:
-        *ar_cipher = TKIP_CRYPT;
-        *ar_cipher_len = 0;
-        break;
-    case WLAN_CIPHER_SUITE_CCMP:
-        *ar_cipher = AES_CRYPT;
-        *ar_cipher_len = 0;
-        break;
-    default:
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("%s: cipher 0x%x not supported\n", __func__, cipher));
-        return -ENOTSUPP;
-    }
-
-    return 0;
-}
-
-static void
-ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
-
-    if (WLAN_AKM_SUITE_PSK == key_mgmt) {
-        if (WPA_AUTH == ar->arAuthMode) {
-            ar->arAuthMode = WPA_PSK_AUTH;
-        } else if (WPA2_AUTH == ar->arAuthMode) {
-            ar->arAuthMode = WPA2_PSK_AUTH;
-        }
-    } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
-        ar->arAuthMode = NONE_AUTH;
-    }
-}
-
-static int
-ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
-                      struct cfg80211_connect_params *sme)
-{
-    struct ar6_softc *ar = ar6k_priv(dev);
-    int status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-    ar->smeState = SME_CONNECTING;
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->bIsDestroyProgress) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
-        return -EBUSY;
-    }
-
-    if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
-        return -EINVAL;
-    }
-
-    if(ar->arSkipScan == true &&
-       ((sme->channel && sme->channel->center_freq == 0) ||
-        (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
-         !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
-        return -EINVAL;
-    }
-
-    if(down_interruptible(&ar->arSem)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
-        return -ERESTARTSYS;
-    }
-
-    if(ar->bIsDestroyProgress) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
-        /*
-        * sleep until the command queue drains
-        */
-        wait_event_interruptible_timeout(arEvent,
-        ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
-        if (signal_pending(current)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
-            up(&ar->arSem);
-            return -EINTR;
-        }
-    }
-
-    if(ar->arConnected == true &&
-       ar->arSsidLen == sme->ssid_len &&
-       !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
-        reconnect_flag = true;
-        status = wmi_reconnect_cmd(ar->arWmi,
-                                   ar->arReqBssid,
-                                   ar->arChannelHint);
-
-        up(&ar->arSem);
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
-            return -EIO;
-        }
-        return 0;
-    } else if(ar->arSsidLen == sme->ssid_len &&
-              !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
-           ar6000_disconnect(ar);
-    }
-
-    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-    ar->arSsidLen = sme->ssid_len;
-    memcpy(ar->arSsid, sme->ssid, sme->ssid_len);
-
-    if(sme->channel){
-        ar->arChannelHint = sme->channel->center_freq;
-    }
-
-    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-    if(sme->bssid){
-        if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
-            memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
-        }
-    }
-
-    ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
-    ar6k_set_auth_type(ar, sme->auth_type);
-
-    if(sme->crypto.n_ciphers_pairwise) {
-        ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
-    } else {
-        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
-    }
-    ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
-
-    if(sme->crypto.n_akm_suites) {
-        ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
-    }
-
-    if((sme->key_len) &&
-       (NONE_AUTH == ar->arAuthMode) &&
-        (WEP_CRYPT == ar->arPairwiseCrypto)) {
-        struct ar_key *key = NULL;
-
-        if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                            ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
-            up(&ar->arSem);
-            return -ENOENT;
-        }
-
-        key = &ar->keys[sme->key_idx];
-        key->key_len = sme->key_len;
-        memcpy(key->key, sme->key, key->key_len);
-        key->cipher = ar->arPairwiseCrypto;
-        ar->arDefTxKeyIndex = sme->key_idx;
-
-        wmi_addKey_cmd(ar->arWmi, sme->key_idx,
-                    ar->arPairwiseCrypto,
-                    GROUP_USAGE | TX_USAGE,
-                    key->key_len,
-                    NULL,
-                    key->key, KEY_OP_INIT_VAL, NULL,
-                    NO_SYNC_WMIFLAG);
-    }
-
-    if (!ar->arUserBssFilter) {
-        if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
-            up(&ar->arSem);
-            return -EIO;
-        }
-    }
-
-    ar->arNetworkType = ar->arNextMode;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
-                    " PW crypto %d PW crypto Len %d GRP crypto %d"\
-                    " GRP crypto Len %d channel hint %u\n",
-                    __func__, ar->arAuthMode, ar->arDot11AuthMode,
-                    ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
-                    ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
-
-    reconnect_flag = 0;
-    status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
-                            ar->arDot11AuthMode, ar->arAuthMode,
-                            ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
-                            ar->arGroupCrypto,ar->arGroupCryptoLen,
-                            ar->arSsidLen, ar->arSsid,
-                            ar->arReqBssid, ar->arChannelHint,
-                            ar->arConnectCtrlFlags);
-
-    up(&ar->arSem);
-
-    if (A_EINVAL == status) {
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-        ar->arSsidLen = 0;
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
-        return -ENOENT;
-    } else if (status) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
-        return -EIO;
-    }
-
-    if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
-        ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
-    {
-        A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
-    }
-
-    ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
-    ar->arConnectPending = true;
-
-    return 0;
-}
-
-void
-ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
-                u8 *bssid, u16 listenInterval,
-                u16 beaconInterval,NETWORK_TYPE networkType,
-                u8 beaconIeLen, u8 assocReqLen,
-                u8 assocRespLen, u8 *assocInfo)
-{
-    u16 size = 0;
-    u16 capability = 0;
-    struct cfg80211_bss *bss = NULL;
-    struct ieee80211_mgmt *mgmt = NULL;
-    struct ieee80211_channel *ibss_channel = NULL;
-    s32 signal = 50 * 100;
-    u8 ie_buf_len = 0;
-    unsigned char ie_buf[256];
-    unsigned char *ptr_ie_buf = ie_buf;
-    unsigned char *ieeemgmtbuf = NULL;
-    u8 source_mac[ATH_MAC_LEN];
-
-    u8 assocReqIeOffset = sizeof(u16)  +  /* capinfo*/
-                               sizeof(u16);    /* listen interval */
-    u8 assocRespIeOffset = sizeof(u16) +  /* capinfo*/
-                                sizeof(u16) +  /* status Code */
-                                sizeof(u16);   /* associd */
-    u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
-    u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    assocReqLen -= assocReqIeOffset;
-    assocRespLen -= assocRespIeOffset;
-
-    ar->arAutoAuthStage = AUTH_IDLE;
-
-    if((ADHOC_NETWORK & networkType)) {
-        if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                            ("%s: ath6k not in ibss mode\n", __func__));
-            return;
-        }
-    }
-
-    if((INFRA_NETWORK & networkType)) {
-        if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                            ("%s: ath6k not in station mode\n", __func__));
-            return;
-        }
-    }
-
-    /* Before informing the join/connect event, make sure that
-     * bss entry is present in scan list, if it not present
-     * construct and insert into scan list, otherwise that
-     * event will be dropped on the way by cfg80211, due to
-     * this keys will not be plumbed in case of WEP and
-     * application will not be aware of join/connect status. */
-    bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
-                           ar->wdev->ssid, ar->wdev->ssid_len,
-                           ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
-                           ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
-
-    /*
-     * Earlier we were updating the cfg about bss by making a beacon frame
-     * only if the entry for bss is not there. This can have some issue if
-     * ROAM event is generated and a heavy traffic is ongoing. The ROAM
-     * event is handled through a work queue and by the time it really gets
-     * handled, BSS would have been aged out. So it is better to update the
-     * cfg about BSS irrespective of its entry being present right now or
-     * not.
-     */
-
-    if (ADHOC_NETWORK & networkType) {
-            /* construct 802.11 mgmt beacon */
-            if(ptr_ie_buf) {
-                   *ptr_ie_buf++ = WLAN_EID_SSID;
-                   *ptr_ie_buf++ = ar->arSsidLen;
-                   memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
-                   ptr_ie_buf +=ar->arSsidLen;
-
-                   *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
-                   *ptr_ie_buf++ = 2; /* length */
-                   *ptr_ie_buf++ = 0; /* ATIM window */
-                   *ptr_ie_buf++ = 0; /* ATIM window */
-
-                   /* TODO: update ibss params and include supported rates,
-                    * DS param set, extened support rates, wmm. */
-
-                   ie_buf_len = ptr_ie_buf - ie_buf;
-            }
-
-            capability |= IEEE80211_CAPINFO_IBSS;
-            if(WEP_CRYPT == ar->arPairwiseCrypto) {
-                   capability |= IEEE80211_CAPINFO_PRIVACY;
-            }
-            memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
-            ptr_ie_buf = ie_buf;
-    } else {
-            capability = *(u16 *)(&assocInfo[beaconIeLen]);
-            memcpy(source_mac, bssid, ATH_MAC_LEN);
-            ptr_ie_buf = assocReqIe;
-            ie_buf_len = assocReqLen;
-    }
-
-    size = offsetof(struct ieee80211_mgmt, u)
-           + sizeof(mgmt->u.beacon)
-           + ie_buf_len;
-
-    ieeemgmtbuf = A_MALLOC_NOWAIT(size);
-    if(!ieeemgmtbuf) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                            ("%s: ieeeMgmtbuf alloc error\n", __func__));
-           cfg80211_put_bss(bss);
-            return;
-    }
-
-    A_MEMZERO(ieeemgmtbuf, size);
-    mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
-    mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
-    memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
-    memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
-    memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
-    mgmt->u.beacon.beacon_int = beaconInterval;
-    mgmt->u.beacon.capab_info = capability;
-    memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
-
-    ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                   ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
-                    "capability 0x%x\n", __func__, mgmt->bssid,
-                    ibss_channel->hw_value, beaconInterval, capability));
-
-    bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
-                                   ibss_channel, mgmt,
-                                   le16_to_cpu(size),
-                                   signal, GFP_KERNEL);
-    kfree(ieeemgmtbuf);
-    cfg80211_put_bss(bss);
-
-    if((ADHOC_NETWORK & networkType)) {
-        cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
-        return;
-    }
-
-    if (false == ar->arConnected) {
-        /* inform connect result to cfg80211 */
-        ar->smeState = SME_DISCONNECTED;
-        cfg80211_connect_result(ar->arNetDev, bssid,
-                                assocReqIe, assocReqLen,
-                                assocRespIe, assocRespLen,
-                                WLAN_STATUS_SUCCESS, GFP_KERNEL);
-    } else {
-        /* inform roam event to cfg80211 */
-       cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
-                        assocReqIe, assocReqLen,
-                        assocRespIe, assocRespLen,
-                        GFP_KERNEL);
-    }
-}
-
-static int
-ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
-                        u16 reason_code)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->bIsDestroyProgress) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
-        return -EBUSY;
-    }
-
-    if(down_interruptible(&ar->arSem)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
-        return -ERESTARTSYS;
-    }
-
-    reconnect_flag = 0;
-    ar6000_disconnect(ar);
-    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-    ar->arSsidLen = 0;
-
-    if (ar->arSkipScan == false) {
-        A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-    }
-
-    up(&ar->arSem);
-
-    return 0;
-}
-
-void
-ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
-                               u8 *bssid, u8 assocRespLen,
-                               u8 *assocInfo, u16 protocolReasonStatus)
-{
-
-    u16 status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
-
-    if (ar->scan_request) {
-       cfg80211_scan_done(ar->scan_request, true);
-        ar->scan_request = NULL;
-    }
-    if((ADHOC_NETWORK & ar->arNetworkType)) {
-        if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                            ("%s: ath6k not in ibss mode\n", __func__));
-            return;
-        }
-        A_MEMZERO(bssid, ETH_ALEN);
-        cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
-        return;
-    }
-
-    if((INFRA_NETWORK & ar->arNetworkType)) {
-        if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                            ("%s: ath6k not in station mode\n", __func__));
-            return;
-        }
-    }
-
-    if(true == ar->arConnectPending) {
-        if(NO_NETWORK_AVAIL == reason) {
-            /* connect cmd failed */
-            wmi_disconnect_cmd(ar->arWmi);
-        } else if (reason == DISCONNECT_CMD) {
-               if (ar->arAutoAuthStage) {
-                       /*
-                        * If the current auth algorithm is open try shared
-                        * and make autoAuthStage idle. We do not make it
-                        * leap for now being.
-                        */
-                       if (ar->arDot11AuthMode == OPEN_AUTH) {
-                               struct ar_key *key = NULL;
-                               key = &ar->keys[ar->arDefTxKeyIndex];
-                               if (down_interruptible(&ar->arSem)) {
-                                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
-                                       return;
-                               }
-
-
-                               ar->arDot11AuthMode = SHARED_AUTH;
-                               ar->arAutoAuthStage = AUTH_IDLE;
-
-                               wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
-                                               ar->arPairwiseCrypto,
-                                               GROUP_USAGE | TX_USAGE,
-                                               key->key_len,
-                                               NULL,
-                                               key->key, KEY_OP_INIT_VAL, NULL,
-                                               NO_SYNC_WMIFLAG);
-
-                               status = wmi_connect_cmd(ar->arWmi,
-                                                        ar->arNetworkType,
-                                                        ar->arDot11AuthMode,
-                                                        ar->arAuthMode,
-                                                        ar->arPairwiseCrypto,
-                                                        ar->arPairwiseCryptoLen,
-                                                        ar->arGroupCrypto,
-                                                        ar->arGroupCryptoLen,
-                                                        ar->arSsidLen,
-                                                        ar->arSsid,
-                                                        ar->arReqBssid,
-                                                        ar->arChannelHint,
-                                                        ar->arConnectCtrlFlags);
-                               up(&ar->arSem);
-
-                       } else if (ar->arDot11AuthMode == SHARED_AUTH) {
-                               /* should not reach here */
-                       }
-               } else {
-                       ar->arConnectPending = false;
-                       if (ar->smeState == SME_CONNECTING) {
-                               cfg80211_connect_result(ar->arNetDev, bssid,
-                                                       NULL, 0,
-                                                       NULL, 0,
-                                                       WLAN_STATUS_UNSPECIFIED_FAILURE,
-                                                       GFP_KERNEL);
-                       } else {
-                               cfg80211_disconnected(ar->arNetDev,
-                                                     reason,
-                                                     NULL, 0,
-                                                     GFP_KERNEL);
-                       }
-                       ar->smeState = SME_DISCONNECTED;
-               }
-       }
-    } else {
-           if (reason != DISCONNECT_CMD)
-                   wmi_disconnect_cmd(ar->arWmi);
-    }
-}
-
-void
-ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
-{
-    struct wiphy *wiphy = (struct wiphy *)arg;
-    u16 size;
-    unsigned char *ieeemgmtbuf = NULL;
-    struct ieee80211_mgmt *mgmt;
-    struct ieee80211_channel *channel;
-    struct ieee80211_supported_band *band;
-    struct ieee80211_common_ie  *cie;
-    s32 signal;
-    int freq;
-
-    cie = &ni->ni_cie;
-
-#define CHAN_IS_11A(x)  (!((x >= 2412) && (x <= 2484)))
-    if(CHAN_IS_11A(cie->ie_chan)) {
-        /* 11a */
-        band = wiphy->bands[IEEE80211_BAND_5GHZ];
-    } else if((cie->ie_erp) || (cie->ie_xrates)) {
-        /* 11g */
-        band = wiphy->bands[IEEE80211_BAND_2GHZ];
-    } else {
-        /* 11b */
-        band = wiphy->bands[IEEE80211_BAND_2GHZ];
-    }
-
-    size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
-    ieeemgmtbuf = A_MALLOC_NOWAIT(size);
-    if(!ieeemgmtbuf)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
-        return;
-    }
-
-    /* Note:
-       TODO: Update target to include 802.11 mac header while sending bss info.
-       Target removes 802.11 mac header while sending the bss info to host,
-       cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
-    */
-    mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
-    memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
-    memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
-    memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
-    memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
-             ni->ni_buf, ni->ni_framelen);
-
-    freq    = cie->ie_chan;
-    channel = ieee80211_get_channel(wiphy, freq);
-    signal  = ni->ni_snr * 100;
-
-       AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-               ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
-                       mgmt->bssid, channel->hw_value, freq, size));
-    cfg80211_inform_bss_frame(wiphy, channel, mgmt,
-                              le16_to_cpu(size),
-                              signal, GFP_KERNEL);
-
-    kfree (ieeemgmtbuf);
-}
-
-static int
-ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
-                   struct cfg80211_scan_request *request)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
-    int ret = 0;
-    u32 forceFgScan = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if (!ar->arUserBssFilter) {
-        if (wmi_bssfilter_cmd(ar->arWmi,
-                             (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
-                             0) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
-            return -EIO;
-        }
-    }
-
-    if(request->n_ssids &&
-       request->ssids[0].ssid_len) {
-        u8 i;
-
-        if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
-            request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
-        }
-
-        for (i = 0; i < request->n_ssids; i++) {
-            wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
-                               request->ssids[i].ssid_len,
-                               request->ssids[i].ssid);
-        }
-    }
-
-    if(ar->arConnected) {
-        forceFgScan = 1;
-    }
-
-    if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
-                         0, 0, 0, NULL) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
-        ret = -EIO;
-    }
-
-    ar->scan_request = request;
-
-    return ret;
-}
-
-void
-ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
-{
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
-
-    if (!ar->scan_request)
-           return;
-
-    if ((status == A_ECANCELED) || (status == A_EBUSY)) {
-           cfg80211_scan_done(ar->scan_request, true);
-           goto out;
-    }
-
-    /* Translate data to cfg80211 mgmt format */
-    wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
-
-    cfg80211_scan_done(ar->scan_request, false);
-
-    if(ar->scan_request->n_ssids &&
-       ar->scan_request->ssids[0].ssid_len) {
-            u8 i;
-
-            for (i = 0; i < ar->scan_request->n_ssids; i++) {
-                   wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
-                                      0, NULL);
-            }
-    }
-
-out:
-    ar->scan_request = NULL;
-}
-
-static int
-ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
-                      u8 key_index, bool pairwise, const u8 *mac_addr,
-                      struct key_params *params)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
-    struct ar_key *key = NULL;
-    u8 key_usage;
-    u8 key_type;
-    int status = 0;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                        ("%s: key index %d out of bounds\n", __func__, key_index));
-        return -ENOENT;
-    }
-
-    key = &ar->keys[key_index];
-    A_MEMZERO(key, sizeof(struct ar_key));
-
-    if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
-        key_usage = GROUP_USAGE;
-    } else {
-        key_usage = PAIRWISE_USAGE;
-    }
-
-    if(params) {
-        if(params->key_len > WLAN_MAX_KEY_LEN ||
-            params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
-            return -EINVAL;
-
-        key->key_len = params->key_len;
-        memcpy(key->key, params->key, key->key_len);
-        key->seq_len = params->seq_len;
-        memcpy(key->seq, params->seq, key->seq_len);
-        key->cipher = params->cipher;
-    }
-
-    switch (key->cipher) {
-    case WLAN_CIPHER_SUITE_WEP40:
-    case WLAN_CIPHER_SUITE_WEP104:
-        key_type = WEP_CRYPT;
-        break;
-
-    case WLAN_CIPHER_SUITE_TKIP:
-        key_type = TKIP_CRYPT;
-        break;
-
-    case WLAN_CIPHER_SUITE_CCMP:
-        key_type = AES_CRYPT;
-        break;
-
-    default:
-        return -ENOTSUPP;
-    }
-
-    if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
-        (GROUP_USAGE & key_usage))
-    {
-        A_UNTIMEOUT(&ar->disconnect_timer);
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                    ("%s: index %d, key_len %d, key_type 0x%x,"\
-                    " key_usage 0x%x, seq_len %d\n",
-                    __func__, key_index, key->key_len, key_type,
-                    key_usage, key->seq_len));
-
-    ar->arDefTxKeyIndex = key_index;
-    status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
-                    key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
-                    (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
-
-
-    if (status) {
-        return -EIO;
-    }
-
-    return 0;
-}
-
-static int
-ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
-                      u8 key_index, bool pairwise, const u8 *mac_addr)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                        ("%s: key index %d out of bounds\n", __func__, key_index));
-        return -ENOENT;
-    }
-
-    if(!ar->keys[key_index].key_len) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
-        return 0;
-    }
-
-    ar->keys[key_index].key_len = 0;
-
-    return wmi_deleteKey_cmd(ar->arWmi, key_index);
-}
-
-
-static int
-ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
-                      u8 key_index, bool pairwise, const u8 *mac_addr,
-                      void *cookie,
-                      void (*callback)(void *cookie, struct key_params*))
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
-    struct ar_key *key = NULL;
-    struct key_params params;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                        ("%s: key index %d out of bounds\n", __func__, key_index));
-        return -ENOENT;
-    }
-
-    key = &ar->keys[key_index];
-    A_MEMZERO(&params, sizeof(params));
-    params.cipher = key->cipher;
-    params.key_len = key->key_len;
-    params.seq_len = key->seq_len;
-    params.seq = key->seq;
-    params.key = key->key;
-
-    callback(cookie, &params);
-
-    return key->key_len ? 0 : -ENOENT;
-}
-
-
-static int
-ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
-                              u8 key_index, bool unicast, bool multicast)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
-    struct ar_key *key = NULL;
-    int status = 0;
-    u8 key_usage;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                        ("%s: key index %d out of bounds\n",
-                        __func__, key_index));
-        return -ENOENT;
-    }
-
-    if(!ar->keys[key_index].key_len) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
-                        __func__, key_index));
-        return -EINVAL;
-    }
-
-    ar->arDefTxKeyIndex = key_index;
-    key = &ar->keys[ar->arDefTxKeyIndex];
-    key_usage = GROUP_USAGE;
-    if (WEP_CRYPT == ar->arPairwiseCrypto) {
-        key_usage |= TX_USAGE;
-    }
-
-    status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
-                            ar->arPairwiseCrypto, key_usage,
-                            key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
-                            NULL, SYNC_BOTH_WMIFLAG);
-    if (status) {
-        return -EIO;
-    }
-
-    return 0;
-}
-
-static int
-ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
-                                   u8 key_index)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
-    return -ENOTSUPP;
-}
-
-void
-ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-                    ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
-
-    cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
-                                 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
-                                 keyid, NULL, GFP_KERNEL);
-}
-
-static int
-ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
-        if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
-            return -EIO;
-        }
-    }
-
-    return 0;
-}
-
-static int
-ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
-                               const u8 *peer,
-                               const struct cfg80211_bitrate_mask *mask)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
-    return -EIO;
-}
-
-/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
-static int
-ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
-    u8 ar_dbm;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    ar->arTxPwrSet = false;
-    switch(type) {
-    case NL80211_TX_POWER_AUTOMATIC:
-        return 0;
-    case NL80211_TX_POWER_LIMITED:
-        ar->arTxPwr = ar_dbm = dbm;
-        ar->arTxPwrSet = true;
-        break;
-    default:
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
-        return -EOPNOTSUPP;
-    }
-
-    wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
-
-    return 0;
-}
-
-static int
-ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if((ar->arConnected == true)) {
-        ar->arTxPwr = 0;
-
-        if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
-            return -EIO;
-        }
-
-        wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
-
-        if(signal_pending(current)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
-            return -EINTR;
-        }
-    }
-
-    *dbm = ar->arTxPwr;
-    return 0;
-}
-
-static int
-ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
-                             struct net_device *dev,
-                             bool pmgmt, int timeout)
-{
-    struct ar6_softc *ar = ar6k_priv(dev);
-    WMI_POWER_MODE_CMD pwrMode;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(pmgmt) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
-        pwrMode.powerMode = REC_POWER;
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
-        pwrMode.powerMode = MAX_PERF_POWER;
-    }
-
-    if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
-        return -EIO;
-    }
-
-    return 0;
-}
-
-static struct net_device *
-ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
-                                           enum nl80211_iftype type, u32 *flags,
-                                           struct vif_params *params)
-{
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
-
-    /* Multiple virtual interface is not supported.
-     * The default interface supports STA and IBSS type
-     */
-    return ERR_PTR(-EOPNOTSUPP);
-}
-
-static int
-ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
-{
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
-
-    /* Multiple virtual interface is not supported.
-     * The default interface supports STA and IBSS type
-     */
-    return -EOPNOTSUPP;
-}
-
-static int
-ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
-                           enum nl80211_iftype type, u32 *flags,
-                           struct vif_params *params)
-{
-    struct ar6_softc *ar = ar6k_priv(ndev);
-    struct wireless_dev *wdev = ar->wdev;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    switch (type) {
-    case NL80211_IFTYPE_STATION:
-        ar->arNextMode = INFRA_NETWORK;
-        break;
-    case NL80211_IFTYPE_ADHOC:
-        ar->arNextMode = ADHOC_NETWORK;
-        break;
-    default:
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
-        return -EOPNOTSUPP;
-    }
-
-    wdev->iftype = type;
-
-    return 0;
-}
-
-static int
-ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
-                        struct cfg80211_ibss_params *ibss_param)
-{
-    struct ar6_softc *ar = ar6k_priv(dev);
-    int status;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
-        return -EINVAL;
-    }
-
-    ar->arSsidLen = ibss_param->ssid_len;
-    memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
-
-    if(ibss_param->channel) {
-        ar->arChannelHint = ibss_param->channel->center_freq;
-    }
-
-    if(ibss_param->channel_fixed) {
-        /* TODO: channel_fixed: The channel should be fixed, do not search for
-         * IBSSs to join on other channels. Target firmware does not support this
-         * feature, needs to be updated.*/
-    }
-
-    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-    if(ibss_param->bssid) {
-        if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
-            memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
-        }
-    }
-
-    ar6k_set_wpa_version(ar, 0);
-    ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
-
-    if(ibss_param->privacy) {
-        ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
-        ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
-    } else {
-        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
-        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
-    }
-
-    ar->arNetworkType = ar->arNextMode;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
-                    " PW crypto %d PW crypto Len %d GRP crypto %d"\
-                    " GRP crypto Len %d channel hint %u\n",
-                    __func__, ar->arAuthMode, ar->arDot11AuthMode,
-                    ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
-                    ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
-
-    status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
-                            ar->arDot11AuthMode, ar->arAuthMode,
-                            ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
-                            ar->arGroupCrypto,ar->arGroupCryptoLen,
-                            ar->arSsidLen, ar->arSsid,
-                            ar->arReqBssid, ar->arChannelHint,
-                            ar->arConnectCtrlFlags);
-    ar->arConnectPending = true;
-
-    return 0;
-}
-
-static int
-ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    if(ar->arWmiReady == false) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
-        return -EIO;
-    }
-
-    if(ar->arWlanState == WLAN_DISABLED) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
-        return -EIO;
-    }
-
-    ar6000_disconnect(ar);
-    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-    ar->arSsidLen = 0;
-
-    return 0;
-}
-
-#ifdef CONFIG_NL80211_TESTMODE
-enum ar6k_testmode_attr {
-       __AR6K_TM_ATTR_INVALID  = 0,
-       AR6K_TM_ATTR_CMD        = 1,
-       AR6K_TM_ATTR_DATA       = 2,
-
-       /* keep last */
-       __AR6K_TM_ATTR_AFTER_LAST,
-       AR6K_TM_ATTR_MAX        = __AR6K_TM_ATTR_AFTER_LAST - 1
-};
-
-enum ar6k_testmode_cmd {
-       AR6K_TM_CMD_TCMD                = 0,
-       AR6K_TM_CMD_RX_REPORT           = 1,
-};
-
-#define AR6K_TM_DATA_MAX_LEN 5000
-
-static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = {
-       [AR6K_TM_ATTR_CMD] = { .type = NLA_U32 },
-       [AR6K_TM_ATTR_DATA] = { .type = NLA_BINARY,
-                               .len = AR6K_TM_DATA_MAX_LEN },
-};
-
-void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
-                                    int buf_len)
-{
-       if (down_interruptible(&ar->arSem))
-               return;
-
-       kfree(ar->tcmd_rx_report);
-
-       ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
-       ar->tcmd_rx_report_len = buf_len;
-
-       up(&ar->arSem);
-
-       wake_up(&arEvent);
-}
-
-static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf,
-                                    int buf_len, struct sk_buff *skb)
-{
-       int ret = 0;
-       long left;
-
-       if (down_interruptible(&ar->arSem))
-               return -ERESTARTSYS;
-
-       if (ar->arWmiReady == false) {
-               ret = -EIO;
-               goto out;
-       }
-
-       if (ar->bIsDestroyProgress) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       WARN_ON(ar->tcmd_rx_report != NULL);
-       WARN_ON(ar->tcmd_rx_report_len > 0);
-
-       if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) {
-               up(&ar->arSem);
-               return -EIO;
-       }
-
-       left = wait_event_interruptible_timeout(arEvent,
-                                              ar->tcmd_rx_report != NULL,
-                                              wmitimeout * HZ);
-
-       if (left == 0) {
-               ret = -ETIMEDOUT;
-               goto out;
-       } else if (left < 0) {
-               ret = left;
-               goto out;
-       }
-
-       if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len,
-               ar->tcmd_rx_report);
-
-       kfree(ar->tcmd_rx_report);
-       ar->tcmd_rx_report = NULL;
-
-out:
-       up(&ar->arSem);
-
-       return ret;
-
-nla_put_failure:
-       ret = -ENOBUFS;
-       goto out;
-}
-
-static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len)
-{
-       struct ar6_softc *ar = wiphy_priv(wiphy);
-       struct nlattr *tb[AR6K_TM_ATTR_MAX + 1];
-       int err, buf_len, reply_len;
-       struct sk_buff *skb;
-       void *buf;
-
-       err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len,
-                       ar6k_testmode_policy);
-       if (err)
-               return err;
-
-       if (!tb[AR6K_TM_ATTR_CMD])
-               return -EINVAL;
-
-       switch (nla_get_u32(tb[AR6K_TM_ATTR_CMD])) {
-       case AR6K_TM_CMD_TCMD:
-               if (!tb[AR6K_TM_ATTR_DATA])
-                       return -EINVAL;
-
-               buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
-               buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
-
-               wmi_test_cmd(ar->arWmi, buf, buf_len);
-
-               return 0;
-
-               break;
-       case AR6K_TM_CMD_RX_REPORT:
-               if (!tb[AR6K_TM_ATTR_DATA])
-                       return -EINVAL;
-
-               buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
-               buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
-
-               reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN);
-               skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
-               if (!skb)
-                       return -ENOMEM;
-
-               err = ar6000_testmode_rx_report(ar, buf, buf_len, skb);
-               if (err < 0) {
-                       kfree_skb(skb);
-                       return err;
-               }
-
-               return cfg80211_testmode_reply(skb);
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-#endif
-
-static const
-u32 cipher_suites[] = {
-    WLAN_CIPHER_SUITE_WEP40,
-    WLAN_CIPHER_SUITE_WEP104,
-    WLAN_CIPHER_SUITE_TKIP,
-    WLAN_CIPHER_SUITE_CCMP,
-};
-
-bool is_rate_legacy(s32 rate)
-{
-       static const s32 legacy[] = { 1000, 2000, 5500, 11000,
-                                     6000, 9000, 12000, 18000, 24000,
-                                     36000, 48000, 54000 };
-       u8 i;
-
-       for (i = 0; i < ARRAY_SIZE(legacy); i++) {
-               if (rate == legacy[i])
-                       return true;
-       }
-
-       return false;
-}
-
-bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
-{
-       static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
-                                   52000, 58500, 65000, 72200 };
-       u8 i;
-
-       for (i = 0; i < ARRAY_SIZE(ht20); i++) {
-               if (rate == ht20[i]) {
-                       if (i == ARRAY_SIZE(ht20) - 1)
-                               /* last rate uses sgi */
-                               *sgi = true;
-                       else
-                               *sgi = false;
-
-                       *mcs = i;
-                       return true;
-               }
-       }
-       return false;
-}
-
-bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
-{
-       static const s32 ht40[] = { 13500, 27000, 40500, 54000,
-                                   81000, 108000, 121500, 135000,
-                                   150000 };
-       u8 i;
-
-       for (i = 0; i < ARRAY_SIZE(ht40); i++) {
-               if (rate == ht40[i]) {
-                       if (i == ARRAY_SIZE(ht40) - 1)
-                               /* last rate uses sgi */
-                               *sgi = true;
-                       else
-                               *sgi = false;
-
-                       *mcs = i;
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
-                           u8 *mac, struct station_info *sinfo)
-{
-       struct ar6_softc *ar = ar6k_priv(dev);
-       long left;
-       bool sgi;
-       s32 rate;
-       int ret;
-       u8 mcs;
-
-       if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0)
-               return -ENOENT;
-
-       if (down_interruptible(&ar->arSem))
-               return -EBUSY;
-
-       ar->statsUpdatePending = true;
-
-       ret = wmi_get_stats_cmd(ar->arWmi);
-
-       if (ret != 0) {
-               up(&ar->arSem);
-               return -EIO;
-       }
-
-       left = wait_event_interruptible_timeout(arEvent,
-                                               ar->statsUpdatePending == false,
-                                               wmitimeout * HZ);
-
-       up(&ar->arSem);
-
-       if (left == 0)
-               return -ETIMEDOUT;
-       else if (left < 0)
-               return left;
-
-       if (ar->arTargetStats.rx_bytes) {
-               sinfo->rx_bytes = ar->arTargetStats.rx_bytes;
-               sinfo->filled |= STATION_INFO_RX_BYTES;
-               sinfo->rx_packets = ar->arTargetStats.rx_packets;
-               sinfo->filled |= STATION_INFO_RX_PACKETS;
-       }
-
-       if (ar->arTargetStats.tx_bytes) {
-               sinfo->tx_bytes = ar->arTargetStats.tx_bytes;
-               sinfo->filled |= STATION_INFO_TX_BYTES;
-               sinfo->tx_packets = ar->arTargetStats.tx_packets;
-               sinfo->filled |= STATION_INFO_TX_PACKETS;
-       }
-
-       sinfo->signal = ar->arTargetStats.cs_rssi;
-       sinfo->filled |= STATION_INFO_SIGNAL;
-
-       rate = ar->arTargetStats.tx_unicast_rate;
-
-       if (is_rate_legacy(rate)) {
-               sinfo->txrate.legacy = rate / 100;
-       } else if (is_rate_ht20(rate, &mcs, &sgi)) {
-               if (sgi) {
-                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-                       sinfo->txrate.mcs = mcs - 1;
-               } else {
-                       sinfo->txrate.mcs = mcs;
-               }
-
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
-       } else if (is_rate_ht40(rate, &mcs, &sgi)) {
-               if (sgi) {
-                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-                       sinfo->txrate.mcs = mcs - 1;
-               } else {
-                       sinfo->txrate.mcs = mcs;
-               }
-
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
-       } else {
-               WARN(1, "invalid rate: %d", rate);
-               return 0;
-       }
-
-       sinfo->filled |= STATION_INFO_TX_BITRATE;
-
-       return 0;
-}
-
-static int ar6k_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
-                         struct cfg80211_pmksa *pmksa)
-{
-       struct ar6_softc *ar = ar6k_priv(netdev);
-       return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, true);
-}
-
-static int ar6k_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
-                         struct cfg80211_pmksa *pmksa)
-{
-       struct ar6_softc *ar = ar6k_priv(netdev);
-       return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, false);
-}
-
-static int ar6k_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
-{
-       struct ar6_softc *ar = ar6k_priv(netdev);
-       if (ar->arConnected)
-               return wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, false);
-       return 0;
-}
-
-static struct
-cfg80211_ops ar6k_cfg80211_ops = {
-    .change_virtual_intf = ar6k_cfg80211_change_iface,
-    .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
-    .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
-    .scan = ar6k_cfg80211_scan,
-    .connect = ar6k_cfg80211_connect,
-    .disconnect = ar6k_cfg80211_disconnect,
-    .add_key = ar6k_cfg80211_add_key,
-    .get_key = ar6k_cfg80211_get_key,
-    .del_key = ar6k_cfg80211_del_key,
-    .set_default_key = ar6k_cfg80211_set_default_key,
-    .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
-    .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
-    .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
-    .set_tx_power = ar6k_cfg80211_set_txpower,
-    .get_tx_power = ar6k_cfg80211_get_txpower,
-    .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
-    .join_ibss = ar6k_cfg80211_join_ibss,
-    .leave_ibss = ar6k_cfg80211_leave_ibss,
-    .get_station = ar6k_get_station,
-    .set_pmksa = ar6k_set_pmksa,
-    .del_pmksa = ar6k_del_pmksa,
-    .flush_pmksa = ar6k_flush_pmksa,
-    CFG80211_TESTMODE_CMD(ar6k_testmode_cmd)
-};
-
-struct wireless_dev *
-ar6k_cfg80211_init(struct device *dev)
-{
-    int ret = 0;
-    struct wireless_dev *wdev;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
-    if(!wdev) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("%s: Couldn't allocate wireless device\n", __func__));
-        return ERR_PTR(-ENOMEM);
-    }
-
-    /* create a new wiphy for use with cfg80211 */
-    wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
-    if(!wdev->wiphy) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("%s: Couldn't allocate wiphy device\n", __func__));
-        kfree(wdev);
-        return ERR_PTR(-ENOMEM);
-    }
-
-    /* set device pointer for wiphy */
-    set_wiphy_dev(wdev->wiphy, dev);
-
-    wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                                   BIT(NL80211_IFTYPE_ADHOC);
-    /* max num of ssids that can be probed during scanning */
-    wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
-    wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
-    wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
-    wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
-    wdev->wiphy->cipher_suites = cipher_suites;
-    wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-
-    ret = wiphy_register(wdev->wiphy);
-    if(ret < 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                        ("%s: Couldn't register wiphy device\n", __func__));
-        wiphy_free(wdev->wiphy);
-        return ERR_PTR(ret);
-    }
-
-    return wdev;
-}
-
-void
-ar6k_cfg80211_deinit(struct ar6_softc *ar)
-{
-    struct wireless_dev *wdev = ar->wdev;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
-
-    if(ar->scan_request) {
-        cfg80211_scan_done(ar->scan_request, true);
-        ar->scan_request = NULL;
-    }
-
-    if(!wdev)
-        return;
-
-    wiphy_unregister(wdev->wiphy);
-    wiphy_free(wdev->wiphy);
-    kfree(wdev);
-}
-
-
-
-
-
-
-
diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
deleted file mode 100644 (file)
index 430998e..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// HCI bridge implementation
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#include <a_config.h>
-#include <athdefs.h>
-#include "a_osapi.h"
-#include "htc_api.h"
-#include "a_drv.h"
-#include "hif.h"
-#include "common_drv.h"
-#include "a_debug.h"
-#include "hci_transport_api.h"
-
-#include "AR6002/hw4.0/hw/apb_athr_wlan_map.h"
-#include "AR6002/hw4.0/hw/uart_reg.h"
-#include "AR6002/hw4.0/hw/rtc_wlan_reg.h"
-
-HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
-void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
-int    (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
-int    (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
-void        (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
-int    (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
-int    (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
-int    (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
-                                          struct htc_packet           *pPacket,
-                                          int                  MaxPollMS);
-int    (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
-int    (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
-
-extern struct hci_transport_callbacks ar6kHciTransCallbacks;
-
-int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks)
-{
-    ar6kHciTransCallbacks = *hciTransCallbacks;
-
-    _HCI_TransportAttach = HCI_TransportAttach;
-    _HCI_TransportDetach = HCI_TransportDetach;
-    _HCI_TransportAddReceivePkts = HCI_TransportAddReceivePkts;
-    _HCI_TransportSendPkt = HCI_TransportSendPkt;
-    _HCI_TransportStop = HCI_TransportStop;
-    _HCI_TransportStart = HCI_TransportStart;
-    _HCI_TransportEnableDisableAsyncRecv = HCI_TransportEnableDisableAsyncRecv;
-    _HCI_TransportRecvHCIEventSync = HCI_TransportRecvHCIEventSync;
-    _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate;
-    _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt;
-
-    return 0;
-}
-
-int
-ar6000_get_hif_dev(struct hif_device *device, void *config)
-{
-    int status;
-
-    status = HIFConfigureDevice(device,
-                                HIF_DEVICE_GET_OS_DEVICE,
-                                (struct hif_device_os_device_info *)config, 
-                                sizeof(struct hif_device_os_device_info));
-    return status;
-}
-
-int ar6000_set_uart_config(struct hif_device *hifDevice,
-                                u32 scale,
-                                u32 step)
-{
-    u32 regAddress;
-    u32 regVal;
-    int status;
-
-    regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
-    regVal = ((u32)scale << 16) | step;
-    /* change the HCI UART scale/step values through the diagnostic window */
-    status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);                     
-
-    return status;
-}
-
-int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data)
-{
-    u32 regAddress;
-    int status;
-
-    regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS;
-    /* read CPU clock settings*/
-    status = ar6000_ReadRegDiag(hifDevice, &regAddress, data);
-
-    return status;
-}
-
-EXPORT_SYMBOL(ar6000_register_hci_transport);
-EXPORT_SYMBOL(ar6000_get_hif_dev);
-EXPORT_SYMBOL(ar6000_set_uart_config);
-EXPORT_SYMBOL(ar6000_get_core_clock_config);
-EXPORT_SYMBOL(_HCI_TransportAttach);
-EXPORT_SYMBOL(_HCI_TransportDetach);
-EXPORT_SYMBOL(_HCI_TransportAddReceivePkts);
-EXPORT_SYMBOL(_HCI_TransportSendPkt);
-EXPORT_SYMBOL(_HCI_TransportStop);
-EXPORT_SYMBOL(_HCI_TransportStart);
-EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv);
-EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync);
-EXPORT_SYMBOL(_HCI_TransportSetBaudRate);
-EXPORT_SYMBOL(_HCI_TransportEnablePowerMgmt);
diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c
deleted file mode 100644 (file)
index 6087edc..0000000
+++ /dev/null
@@ -1,1141 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// HCI bridge implementation
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-#include <linux/etherdevice.h>
-#include <a_config.h>
-#include <athdefs.h>
-#include "a_osapi.h"
-#include "htc_api.h"
-#include "wmi.h"
-#include "a_drv.h"
-#include "hif.h"
-#include "common_drv.h"
-#include "a_debug.h"
-#define  ATH_DEBUG_HCI_BRIDGE    ATH_DEBUG_MAKE_MODULE_MASK(6)
-#define  ATH_DEBUG_HCI_RECV      ATH_DEBUG_MAKE_MODULE_MASK(7)
-#define  ATH_DEBUG_HCI_SEND      ATH_DEBUG_MAKE_MODULE_MASK(8)
-#define  ATH_DEBUG_HCI_DUMP      ATH_DEBUG_MAKE_MODULE_MASK(9)
-#else
-#include "ar6000_drv.h"
-#endif  /* EXPORT_HCI_BRIDGE_INTERFACE */
-
-#ifdef ATH_AR6K_ENABLE_GMBOX
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-#include "export_hci_transport.h"
-#else
-#include "hci_transport_api.h"
-#endif
-#include "epping_test.h"
-#include "gmboxif.h"
-#include "ar3kconfig.h"
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-    /* only build on newer kernels which have BT configured */
-#if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
-#define CONFIG_BLUEZ_HCI_BRIDGE  
-#endif
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-unsigned int ar3khcibaud = 0;
-unsigned int hciuartscale = 0;
-unsigned int hciuartstep = 0;
-
-module_param(ar3khcibaud, int, 0644);
-module_param(hciuartscale, int, 0644);
-module_param(hciuartstep, int, 0644);
-#else
-extern unsigned int ar3khcibaud;
-extern unsigned int hciuartscale;
-extern unsigned int hciuartstep;
-#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
-
-struct ar6k_hci_bridge_info {
-    void                    *pHCIDev;          /* HCI bridge device */
-    struct hci_transport_properties HCIProps;         /* HCI bridge props */
-    struct hci_dev          *pBtStackHCIDev;   /* BT Stack HCI dev */
-    bool                  HciNormalMode;     /* Actual HCI mode enabled (non-TEST)*/
-    bool                  HciRegistered;     /* HCI device registered with stack */
-    struct htc_packet_queue        HTCPacketStructHead;
-    u8 *pHTCStructAlloc;
-    spinlock_t              BridgeLock;
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-    struct hci_transport_misc_handles    HCITransHdl; 
-#else
-    struct ar6_softc              *ar;
-#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
-};
-
-#define MAX_ACL_RECV_BUFS           16
-#define MAX_EVT_RECV_BUFS           8
-#define MAX_HCI_WRITE_QUEUE_DEPTH   32
-#define MAX_ACL_RECV_LENGTH         1200
-#define MAX_EVT_RECV_LENGTH         257
-#define TX_PACKET_RSV_OFFSET        32
-#define NUM_HTC_PACKET_STRUCTS     ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2)
-
-#define HCI_GET_OP_CODE(p)          (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
-
-extern unsigned int setupbtdev;
-struct ar3k_config_info      ar3kconfig;
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-struct ar6k_hci_bridge_info *g_pHcidevInfo;
-#endif
-
-static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
-static void     bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
-static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo);
-static bool   bt_indicate_recv(struct ar6k_hci_bridge_info      *pHcidevInfo,
-                                 HCI_TRANSPORT_PACKET_TYPE Type, 
-                                 struct sk_buff            *skb);
-static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length);
-static void     bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb);   
-                               
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-int ar6000_setup_hci(void *ar);
-void     ar6000_cleanup_hci(void *ar);
-int hci_test_send(void *ar, struct sk_buff *skb);
-#else
-int ar6000_setup_hci(struct ar6_softc *ar);
-void     ar6000_cleanup_hci(struct ar6_softc *ar);
-/* HCI bridge testing */
-int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
-#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
-
-#define LOCK_BRIDGE(dev)   spin_lock_bh(&(dev)->BridgeLock)
-#define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
-
-static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *osbuf)
-{    
-    if (pHcidevInfo->HciNormalMode) {
-        bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
-    } else {
-            /* in test mode, these are just ordinary netbuf allocations */
-        A_NETBUF_FREE(osbuf);
-    }
-}
-
-static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, struct htc_packet *pPacket)
-{
-    LOCK_BRIDGE(pHcidevInfo);
-    HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
-    UNLOCK_BRIDGE(pHcidevInfo);  
-}
-
-static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo)
-{
-    struct htc_packet  *pPacket = NULL;
-    LOCK_BRIDGE(pHcidevInfo);
-    pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
-    UNLOCK_BRIDGE(pHcidevInfo);  
-    return pPacket;
-}
-
-#define BLOCK_ROUND_UP_PWR2(x, align)    (((int) (x) + ((align)-1)) & ~((align)-1))
-
-static void RefillRecvBuffers(struct ar6k_hci_bridge_info      *pHcidevInfo, 
-                              HCI_TRANSPORT_PACKET_TYPE Type, 
-                              int                       NumBuffers)
-{
-    int                 length, i;
-    void                *osBuf = NULL;
-    struct htc_packet_queue    queue;
-    struct htc_packet          *pPacket;
-
-    INIT_HTC_PACKET_QUEUE(&queue);
-    
-    if (Type == HCI_ACL_TYPE) {     
-        if (pHcidevInfo->HciNormalMode) {  
-            length = HCI_MAX_FRAME_SIZE;
-        } else {
-            length = MAX_ACL_RECV_LENGTH;    
-        }
-    } else {
-        length = MAX_EVT_RECV_LENGTH;
-    }
-    
-        /* add on transport head and tail room */ 
-    length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
-        /* round up to the required I/O padding */      
-    length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
-             
-    for (i = 0; i < NumBuffers; i++) {   
-           
-        if (pHcidevInfo->HciNormalMode) {   
-            osBuf = bt_alloc_buffer(pHcidevInfo,length);       
-        } else {
-            osBuf = A_NETBUF_ALLOC(length);  
-        }
-          
-        if (NULL == osBuf) {
-            break;    
-        }            
-         
-        pPacket = AllocHTCStruct(pHcidevInfo);
-        if (NULL == pPacket) {
-            FreeBtOsBuf(pHcidevInfo,osBuf);
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
-            break;    
-        }     
-        
-        SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
-            /* add to queue */
-        HTC_PACKET_ENQUEUE(&queue,pPacket);
-    }
-    
-    if (i > 0) {
-        HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);    
-    }
-}
-
-#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
-        (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
-        (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
-static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE     HCIHandle,
-                                           struct hci_transport_properties *pProps, 
-                                           void                     *pContext)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    int              status;
-    u32 address, hci_uart_pwr_mgmt_params;
-//    struct ar3k_config_info      ar3kconfig;
-    
-    pHcidevInfo->pHCIDev = HCIHandle;
-    
-    memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", 
-            (unsigned long)HCIHandle, 
-            pHcidevInfo->HCIProps.HeadRoom, 
-            pHcidevInfo->HCIProps.TailRoom,
-            pHcidevInfo->HCIProps.IOBlockPad));
-    
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
-#else
-    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
-#endif
-                             
-        /* provide buffers */
-    RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
-    RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
-   
-    do {
-            /* start transport */
-        status = HCI_TransportStart(pHcidevInfo->pHCIDev);
-         
-        if (status) {
-            break;    
-        }
-        
-        if (!pHcidevInfo->HciNormalMode) {
-                /* in test mode, no need to go any further */
-            break;    
-        }
-
-        // The delay is required when AR6K is driving the BT reset line
-        // where time is needed after the BT chip is out of reset (HCI_TransportStart)
-        // and before the first HCI command is issued (AR3KConfigure)
-        // FIXME
-        // The delay should be configurable and be only applied when AR6K driving the BT
-        // reset line. This could be done by some module parameter or based on some HW config
-        // info. For now apply 100ms delay blindly
-        A_MDELAY(100);
-        
-        A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
-        ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
-        ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice);
-#else
-        ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
-#endif
-        ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
-        
-        if (ar3khcibaud != 0) {
-                /* user wants ar3k baud rate change */
-            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
-            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
-            ar3kconfig.AR3KBaudRate = ar3khcibaud;    
-        }
-        
-        if ((hciuartscale != 0) || (hciuartstep != 0)) {   
-                /* user wants to tune HCI bridge UART scale/step values */
-            ar3kconfig.AR6KScale = (u16)hciuartscale;
-            ar3kconfig.AR6KStep = (u16)hciuartstep;
-            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
-        }
-        
-        /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
-        address = TARG_VTOP(pHcidevInfo->ar->arTargetType, 
-                            HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params));
-        status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
-        if (0 == status) {
-            ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1);
-            ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16;
-            ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8;
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
-        }
-        /* configure the AR3K device */         
-               memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
-        status = AR3KConfigure(&ar3kconfig);
-        if (status) {
-            break; 
-        }
-
-        /* Make sure both AR6K and AR3K have power management enabled */
-        if (ar3kconfig.PwrMgmtEnabled) {
-            status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
-            if (status) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
-            }
-        }
-        
-        status = bt_register_hci(pHcidevInfo);
-        
-    } while (false);
-
-    return status; 
-}
-
-static void ar6000_hci_transport_failure(void *pContext, int Status)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
-    
-    if (pHcidevInfo->HciNormalMode) {
-        /* TODO .. */    
-    }
-}
-
-static void ar6000_hci_transport_removed(void *pContext)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n"));
-    
-    A_ASSERT(pHcidevInfo->pHCIDev != NULL);
-        
-    HCI_TransportDetach(pHcidevInfo->pHCIDev);
-    bt_cleanup_hci(pHcidevInfo);
-    pHcidevInfo->pHCIDev = NULL;
-}
-
-static void ar6000_hci_send_complete(void *pContext, struct htc_packet *pPacket)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    void                 *osbuf = pPacket->pPktContext;
-    A_ASSERT(osbuf != NULL);
-    A_ASSERT(pHcidevInfo != NULL);
-    
-    if (pPacket->Status) {
-        if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status)); 
-        }   
-    }
-            
-    FreeHTCStruct(pHcidevInfo,pPacket);    
-    FreeBtOsBuf(pHcidevInfo,osbuf);
-    
-}
-
-static void ar6000_hci_pkt_recv(void *pContext, struct htc_packet *pPacket)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    struct sk_buff       *skb;
-    
-    A_ASSERT(pHcidevInfo != NULL);
-    skb = (struct sk_buff *)pPacket->pPktContext;
-    A_ASSERT(skb != NULL);
-          
-    do {
-        
-        if (pPacket->Status) {
-            break;
-        }
-  
-        AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, 
-                        ("HCI Bridge, packet received type : %d len:%d \n",
-                        HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength));
-    
-            /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
-             * to fill the front of the buffer */
-        A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom);
-        A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom);
-        
-        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n",
-                        (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVENT" : "ACL",
-                        skb->len));
-            AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
-        }
-        
-        if (pHcidevInfo->HciNormalMode) {
-                /* indicate the packet */         
-            if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) {
-                    /* bt stack accepted the packet */
-                skb = NULL;
-            }  
-            break;
-        }
-        
-            /* for testing, indicate packet to the network stack */ 
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice);        
-        if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) {
-            skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice));
-#else
-        skb->dev = pHcidevInfo->ar->arNetDev;        
-        if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) {
-            skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev);
-#endif
-            netif_rx(skb);
-            skb = NULL;
-        } 
-        
-    } while (false);
-    
-    FreeHTCStruct(pHcidevInfo,pPacket);
-    
-    if (skb != NULL) {
-            /* packet was not accepted, free it */
-        FreeBtOsBuf(pHcidevInfo,skb);       
-    }
-    
-}
-
-static void  ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    int                  refillCount;
-
-    if (Type == HCI_ACL_TYPE) {
-        refillCount =  MAX_ACL_RECV_BUFS - BuffersAvailable;   
-    } else {
-        refillCount =  MAX_EVT_RECV_BUFS - BuffersAvailable;     
-    }
-    
-    if (refillCount > 0) {
-        RefillRecvBuffers(pHcidevInfo,Type,refillCount);
-    }
-    
-}
-
-static HCI_SEND_FULL_ACTION  ar6000_hci_pkt_send_full(void *pContext, struct htc_packet *pPacket)
-{
-    struct ar6k_hci_bridge_info    *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
-    HCI_SEND_FULL_ACTION    action = HCI_SEND_FULL_KEEP;
-    
-    if (!pHcidevInfo->HciNormalMode) {
-            /* for epping testing, check packet tag, some epping packets are
-             * special and cannot be dropped */
-        if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) {
-            action = HCI_SEND_FULL_DROP;     
-        }
-    }
-    
-    return action;
-}
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-int ar6000_setup_hci(void *ar)
-#else
-int ar6000_setup_hci(struct ar6_softc *ar)
-#endif
-{
-    struct hci_transport_config_info config;
-    int                  status = 0;
-    int                       i;
-    struct htc_packet                *pPacket;
-    struct ar6k_hci_bridge_info      *pHcidevInfo;
-        
-       
-    do {
-        
-        pHcidevInfo = (struct ar6k_hci_bridge_info *)A_MALLOC(sizeof(struct ar6k_hci_bridge_info));
-        
-        if (NULL == pHcidevInfo) {
-            status = A_NO_MEMORY;
-            break;    
-        }
-        
-        A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info));
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        g_pHcidevInfo = pHcidevInfo;
-        pHcidevInfo->HCITransHdl = *(struct hci_transport_misc_handles *)ar;
-#else
-        ar->hcidev_info = pHcidevInfo;
-        pHcidevInfo->ar = ar;
-#endif
-        spin_lock_init(&pHcidevInfo->BridgeLock);
-        INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
-
-        ar->exitCallback = AR3KConfigureExit;
-    
-        status = bt_setup_hci(pHcidevInfo);
-        if (status) {
-            break;    
-        }
-        
-        if (pHcidevInfo->HciNormalMode) {      
-            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));    
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));     
-        }
-        
-        pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(struct htc_packet)) * NUM_HTC_PACKET_STRUCTS);
-        
-        if (NULL == pHcidevInfo->pHTCStructAlloc) {
-            status = A_NO_MEMORY;
-            break;    
-        }
-        
-        pPacket = (struct htc_packet *)pHcidevInfo->pHTCStructAlloc;
-        for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
-            FreeHTCStruct(pHcidevInfo,pPacket);                
-        }
-        
-        A_MEMZERO(&config,sizeof(struct hci_transport_config_info));        
-        config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
-        config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
-        config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
-        config.pContext = pHcidevInfo;    
-        config.TransportFailure = ar6000_hci_transport_failure;
-        config.TransportReady = ar6000_hci_transport_ready;
-        config.TransportRemoved = ar6000_hci_transport_removed;
-        config.pHCISendComplete = ar6000_hci_send_complete;
-        config.pHCIPktRecv = ar6000_hci_pkt_recv;
-        config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
-        config.pHCISendFull = ar6000_hci_pkt_send_full;
-       
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
-#else
-        pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
-#endif
-
-        if (NULL == pHcidevInfo->pHCIDev) {
-            status = A_ERROR;      
-        }
-    
-    } while (false);
-    
-    if (status) {
-        if (pHcidevInfo != NULL) {
-            if (NULL == pHcidevInfo->pHCIDev) {
-                /* GMBOX may not be present in older chips */
-                /* just return success */ 
-                status = 0;
-            }
-        }
-        ar6000_cleanup_hci(ar);    
-    }
-    
-    return status;
-}
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-void  ar6000_cleanup_hci(void *ar)
-#else
-void  ar6000_cleanup_hci(struct ar6_softc *ar)
-#endif
-{
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-    struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
-#else
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
-#endif
-    
-    if (pHcidevInfo != NULL) {
-        bt_cleanup_hci(pHcidevInfo);   
-        
-        if (pHcidevInfo->pHCIDev != NULL) {
-            HCI_TransportStop(pHcidevInfo->pHCIDev);
-            HCI_TransportDetach(pHcidevInfo->pHCIDev);
-            pHcidevInfo->pHCIDev = NULL;
-        } 
-        
-        if (pHcidevInfo->pHTCStructAlloc != NULL) {
-            kfree(pHcidevInfo->pHTCStructAlloc);
-            pHcidevInfo->pHTCStructAlloc = NULL;    
-        }
-        
-        kfree(pHcidevInfo);
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-        ar->hcidev_info = NULL;
-#endif
-    }
-    
-    
-}
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-int hci_test_send(void *ar, struct sk_buff *skb)
-#else
-int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
-#endif
-{
-    int              status = 0;
-    int              length;
-    EPPING_HEADER    *pHeader;
-    struct htc_packet       *pPacket;   
-    HTC_TX_TAG       htc_tag = AR6K_DATA_PKT_TAG;
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-    struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo;
-#else
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
-#endif
-            
-    do {
-        
-        if (NULL == pHcidevInfo) {
-            status = A_ERROR;
-            break;    
-        }
-        
-        if (NULL == pHcidevInfo->pHCIDev) {
-            status = A_ERROR;
-            break;    
-        }
-        
-        if (pHcidevInfo->HciNormalMode) {
-                /* this interface cannot run when normal WMI is running */
-            status = A_ERROR;
-            break;    
-        }
-        
-        pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
-        
-        if (!IS_EPPING_PACKET(pHeader)) {
-            status = A_EINVAL;
-            break;
-        }
-                       
-        if (IS_EPING_PACKET_NO_DROP(pHeader)) {
-            htc_tag = AR6K_CONTROL_PKT_TAG;   
-        }
-        
-        length = sizeof(EPPING_HEADER) + pHeader->DataLength;
-                
-        pPacket = AllocHTCStruct(pHcidevInfo);
-        if (NULL == pPacket) {        
-            status = A_NO_MEMORY;
-            break;
-        } 
-     
-        SET_HTC_PACKET_INFO_TX(pPacket,
-                               skb,
-                               A_NETBUF_DATA(skb),
-                               length,
-                               HCI_ACL_TYPE,  /* send every thing out as ACL */
-                               htc_tag);
-             
-        HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
-        pPacket = NULL;
-            
-    } while (false);
-            
-    return status;
-}
-
-void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
-{
-    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info;
-    struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig;
-
-    config->pHCIDev = pHcidevInfo->pHCIDev;
-    config->pHCIProps = &pHcidevInfo->HCIProps;
-    config->pHIFDevice = ar->arHifDevice;
-    config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
-    config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
-    config->AR3KBaudRate = 115200;    
-}
-
-#ifdef CONFIG_BLUEZ_HCI_BRIDGE   
-/*** BT Stack Entrypoints *******/
-
-/*
- * bt_open - open a handle to the device
-*/
-static int bt_open(struct hci_dev *hdev)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n"));
-    set_bit(HCI_RUNNING, &hdev->flags);
-    set_bit(HCI_UP, &hdev->flags);
-    set_bit(HCI_INIT, &hdev->flags);         
-    return 0;
-}
-
-/*
- * bt_close - close handle to the device
-*/
-static int bt_close(struct hci_dev *hdev)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
-    clear_bit(HCI_RUNNING, &hdev->flags);
-    return 0;
-}
-
-/*
- * bt_send_frame - send data frames
-*/
-static int bt_send_frame(struct sk_buff *skb)
-{
-    struct hci_dev             *hdev = (struct hci_dev *)skb->dev;
-    HCI_TRANSPORT_PACKET_TYPE  type;
-    struct ar6k_hci_bridge_info       *pHcidevInfo;
-    struct htc_packet                 *pPacket;
-    int                   status = 0;
-    struct sk_buff             *txSkb = NULL;
-    
-    if (!hdev) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
-        return -ENODEV;
-    }
-      
-    if (!test_bit(HCI_RUNNING, &hdev->flags)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
-        return -EBUSY;
-    }
-  
-    pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;   
-    A_ASSERT(pHcidevInfo != NULL);
-      
-    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
-    type = HCI_COMMAND_TYPE;
-    
-    switch (bt_cb(skb)->pkt_type) {
-        case HCI_COMMAND_PKT:
-            type = HCI_COMMAND_TYPE;
-            hdev->stat.cmd_tx++;
-            break;
-        case HCI_ACLDATA_PKT:
-            type = HCI_ACL_TYPE;
-            hdev->stat.acl_tx++;
-            break;
-
-        case HCI_SCODATA_PKT:
-            /* we don't support SCO over the bridge */
-            kfree_skb(skb);
-            return 0;
-        default:
-            A_ASSERT(false);
-            kfree_skb(skb);
-            return 0;
-    } 
-
-    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
-                        (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
-                        skb->len));
-        if (type == HCI_COMMAND_TYPE) {
-            u16 opcode = HCI_GET_OP_CODE(skb->data);
-            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("    HCI Command: OGF:0x%X OCF:0x%X \r\n", 
-                  opcode >> 10, opcode & 0x3FF));
-        }
-        AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
-    }
-    
-    do {
-        
-        txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom + 
-                             pHcidevInfo->HCIProps.TailRoom + skb->len, 
-                             GFP_ATOMIC);
-
-        if (txSkb == NULL) {
-            status = A_NO_MEMORY;
-            break;    
-        }
-        
-        bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
-        txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
-        skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom);
-        memcpy(txSkb->data, skb->data, skb->len);
-        skb_put(txSkb,skb->len);
-        
-        pPacket = AllocHTCStruct(pHcidevInfo);        
-        if (NULL == pPacket) {
-            status = A_NO_MEMORY;
-            break;    
-        }       
-              
-        /* HCI packet length here doesn't include the 1-byte transport header which
-         * will be handled by the HCI transport layer. Enough headroom has already
-         * been reserved above for the transport header
-         */
-        SET_HTC_PACKET_INFO_TX(pPacket,
-                               txSkb,
-                               txSkb->data,
-                               txSkb->len,
-                               type, 
-                               AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */
-        
-        AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb));
-        AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n",
-                                      type, txSkb->len));
-                                      
-        status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
-        pPacket = NULL;
-        txSkb = NULL;
-        
-    } while (false);
-   
-    if (txSkb != NULL) {
-        kfree_skb(txSkb);    
-    }
-    
-    kfree_skb(skb);        
-       
-    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame  \n"));
-    return 0;
-}
-
-/*
- * bt_ioctl - ioctl processing
-*/
-static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
-    return -ENOIOCTLCMD;
-}
-
-/*
- * bt_flush - flush outstandingbpackets
-*/
-static int bt_flush(struct hci_dev *hdev)
-{
-    struct ar6k_hci_bridge_info    *pHcidevInfo; 
-    
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
-    
-    pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data;   
-    
-    /* TODO??? */   
-    
-    return 0;
-}
-
-
-/*
- * bt_destruct - 
-*/
-static void bt_destruct(struct hci_dev *hdev)
-{
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
-    /* nothing to do here */
-}
-
-static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
-{
-    int                    status = 0;
-    struct hci_dev              *pHciDev = NULL;
-    struct hif_device_os_device_info   osDevInfo;
-    
-    if (!setupbtdev) {
-        return 0;
-    } 
-        
-    do {
-            
-        A_MEMZERO(&osDevInfo,sizeof(osDevInfo));
-            /* get the underlying OS device */
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-        status = ar6000_get_hif_dev((struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice), 
-                                    &osDevInfo);
-#else
-        status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice, 
-                                    HIF_DEVICE_GET_OS_DEVICE,
-                                    &osDevInfo, 
-                                    sizeof(osDevInfo));
-#endif
-                                    
-        if (status) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n"));
-            break;
-        }
-        
-            /* allocate a BT HCI struct for this device */
-        pHciDev = hci_alloc_dev();
-        if (NULL == pHciDev) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n"));
-            status = A_NO_MEMORY;
-            break;
-        }    
-            /* save the device, we'll register this later */
-        pHcidevInfo->pBtStackHCIDev = pHciDev;       
-        SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice);          
-        SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_BREDR);
-        pHciDev->driver_data = pHcidevInfo;
-        pHciDev->open     = bt_open;
-        pHciDev->close    = bt_close;
-        pHciDev->send     = bt_send_frame;
-        pHciDev->ioctl    = bt_ioctl;
-        pHciDev->flush    = bt_flush;
-        pHciDev->destruct = bt_destruct;
-        pHciDev->owner = THIS_MODULE; 
-            /* driver is running in normal BT mode */
-        pHcidevInfo->HciNormalMode = true;
-        
-    } while (false);
-    
-    if (status) {
-        bt_cleanup_hci(pHcidevInfo);    
-    }
-    
-    return status;
-}
-
-static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
-{   
-    int   err;      
-        
-    if (pHcidevInfo->HciRegistered) {
-        pHcidevInfo->HciRegistered = false;
-        clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags);
-        clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags);
-        clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags);   
-        A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
-            /* unregister */
-        if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister with bluetooth %d\n",err));
-        }          
-    }   
-    
-    kfree(pHcidevInfo->pBtStackHCIDev);
-    pHcidevInfo->pBtStackHCIDev = NULL;  
-}
-
-static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
-{
-    int       err;
-    int  status = 0;
-    
-    do {          
-        AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n"));
-        A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
-             /* mark that we are registered */
-        pHcidevInfo->HciRegistered = true;
-        if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err));
-            pHcidevInfo->HciRegistered = false;
-            status = A_ERROR;
-            break;
-        }
-    
-        AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n"));
-        
-    } while (false);
-    
-    return status;
-}
-
-static bool bt_indicate_recv(struct ar6k_hci_bridge_info      *pHcidevInfo,
-                               HCI_TRANSPORT_PACKET_TYPE Type, 
-                               struct                    sk_buff *skb)
-{
-    u8 btType;
-    int                   len;
-    bool                success = false;
-    BT_HCI_EVENT_HEADER   *pEvent;
-    
-    do {
-             
-        if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
-            break;
-        }
-    
-        switch (Type) {
-            case HCI_ACL_TYPE:
-                btType = HCI_ACLDATA_PKT;
-                break;
-            case HCI_EVENT_TYPE:  
-                btType = HCI_EVENT_PKT;  
-                break;
-            default:
-                btType = 0;
-                A_ASSERT(false);
-                break;
-        } 
-        
-        if (0 == btType) {
-            break;    
-        }
-        
-            /* set the final type */
-        bt_cb(skb)->pkt_type = btType;
-            /* set dev */
-        skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
-        len = skb->len;
-        
-        if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) {
-            if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {                
-                pEvent = (BT_HCI_EVENT_HEADER *)skb->data; 
-                AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len:%d \n", 
-                        pEvent->EventCode, pEvent->ParamLength));
-            } 
-        }
-        
-            /* pass receive packet up the stack */    
-        if (hci_recv_frame(skb) != 0) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \n"));
-            break;
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, 
-                    ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len));
-        }
-            
-        success = true;
-    
-    } while (false);
-    
-    return success;
-}
-
-static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) 
-{ 
-    struct sk_buff *skb;         
-        /* in normal HCI mode we need to alloc from the bt core APIs */
-    skb = bt_skb_alloc(Length, GFP_ATOMIC);
-    if (NULL == skb) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
-    }
-    return skb;
-}
-
-static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
-{
-    kfree_skb(skb);    
-}
-
-#else // { CONFIG_BLUEZ_HCI_BRIDGE
-
-    /* stubs when we only want to test the HCI bridging Interface without the HT stack */
-static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
-{
-    return 0;
-}
-static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
-{   
-     
-}
-static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo)
-{
-    A_ASSERT(false);
-    return A_ERROR;    
-}
-
-static bool bt_indicate_recv(struct ar6k_hci_bridge_info      *pHcidevInfo,
-                               HCI_TRANSPORT_PACKET_TYPE Type, 
-                               struct                    sk_buff *skb)
-{
-    A_ASSERT(false);
-    return false;
-}
-
-static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) 
-{
-    A_ASSERT(false);
-    return NULL;
-}
-static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb)
-{
-    A_ASSERT(false);
-}
-
-#endif // } CONFIG_BLUEZ_HCI_BRIDGE
-
-#else  // { ATH_AR6K_ENABLE_GMBOX
-
-    /* stubs when GMBOX support is not needed */
-    
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-int ar6000_setup_hci(void *ar)
-#else
-int ar6000_setup_hci(struct ar6_softc *ar)
-#endif
-{
-    return 0;
-}
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-void ar6000_cleanup_hci(void *ar)
-#else
-void ar6000_cleanup_hci(struct ar6_softc *ar)
-#endif
-{
-    return;    
-}
-
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig)
-{
-    return;
-}
-#endif
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-int hci_test_send(void *ar, struct sk_buff *skb)
-#else
-int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb)
-#endif
-{
-    return -EOPNOTSUPP;
-}
-
-#endif // } ATH_AR6K_ENABLE_GMBOX
-
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-static int __init
-hcibridge_init_module(void)
-{
-    int status;
-    struct hci_transport_callbacks hciTransCallbacks;
-
-    hciTransCallbacks.setupTransport = ar6000_setup_hci;
-    hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
-
-    status = ar6000_register_hci_transport(&hciTransCallbacks);
-    if (status)
-        return -ENODEV;
-
-    return 0;
-}
-
-static void __exit
-hcibridge_cleanup_module(void)
-{
-}
-
-module_init(hcibridge_init_module);
-module_exit(hcibridge_cleanup_module);
-MODULE_LICENSE("Dual BSD/GPL");
-#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
deleted file mode 100644 (file)
index 80cef77..0000000
+++ /dev/null
@@ -1,776 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _AR6000_H_
-#define _AR6000_H_
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/if_ether.h>
-#include <linux/etherdevice.h>
-#include <net/iw_handler.h>
-#include <linux/if_arp.h>
-#include <linux/ip.h>
-#include <linux/wireless.h>
-#include <net/cfg80211.h>
-#include <linux/module.h>
-#include <asm/io.h>
-
-#include <a_config.h>
-#include <athdefs.h>
-#include "a_osapi.h"
-#include "htc_api.h"
-#include "wmi.h"
-#include "a_drv.h"
-#include "bmi.h"
-#include <ieee80211.h>
-#include <ieee80211_ioctl.h>
-#include <wlan_api.h>
-#include <wmi_api.h>
-#include "pkt_log.h"
-#include "aggr_recv_api.h"
-#include <host_version.h>
-#include <linux/rtnetlink.h>
-#include <linux/moduleparam.h>
-#include "ar6000_api.h"
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-#include <testcmd.h>
-#endif
-#include <linux/firmware.h>
-
-#include "targaddrs.h"
-#include "dbglog_api.h"
-#include "ar6000_diag.h"
-#include "common_drv.h"
-#include "roaming.h"
-#include "hci_transport_api.h"
-#define ATH_MODULE_NAME driver
-#include "a_debug.h"
-#include "hw/apb_map.h"
-#include "hw/rtc_reg.h"
-#include "hw/mbox_reg.h"
-#include "gpio_reg.h"
-
-#define  ATH_DEBUG_DBG_LOG       ATH_DEBUG_MAKE_MODULE_MASK(0)
-#define  ATH_DEBUG_WLAN_CONNECT  ATH_DEBUG_MAKE_MODULE_MASK(1)
-#define  ATH_DEBUG_WLAN_SCAN     ATH_DEBUG_MAKE_MODULE_MASK(2)
-#define  ATH_DEBUG_WLAN_TX       ATH_DEBUG_MAKE_MODULE_MASK(3)
-#define  ATH_DEBUG_WLAN_RX       ATH_DEBUG_MAKE_MODULE_MASK(4)
-#define  ATH_DEBUG_HTC_RAW       ATH_DEBUG_MAKE_MODULE_MASK(5)
-#define  ATH_DEBUG_HCI_BRIDGE    ATH_DEBUG_MAKE_MODULE_MASK(6)
-#define  ATH_DEBUG_HCI_RECV      ATH_DEBUG_MAKE_MODULE_MASK(7)
-#define  ATH_DEBUG_HCI_SEND      ATH_DEBUG_MAKE_MODULE_MASK(8)
-#define  ATH_DEBUG_HCI_DUMP      ATH_DEBUG_MAKE_MODULE_MASK(9)
-
-#ifndef  __dev_put
-#define  __dev_put(dev) dev_put(dev)
-#endif
-
-
-#define USER_SAVEDKEYS_STAT_INIT     0
-#define USER_SAVEDKEYS_STAT_RUN      1
-
-// TODO this needs to move into the AR_SOFTC struct
-struct USER_SAVEDKEYS {
-    struct ieee80211req_key   ucast_ik;
-    struct ieee80211req_key   bcast_ik;
-    CRYPTO_TYPE               keyType;
-    bool                    keyOk;
-};
-
-#define DBG_INFO        0x00000001
-#define DBG_ERROR       0x00000002
-#define DBG_WARNING     0x00000004
-#define DBG_SDIO        0x00000008
-#define DBG_HIF         0x00000010
-#define DBG_HTC         0x00000020
-#define DBG_WMI         0x00000040
-#define DBG_WMI2        0x00000080
-#define DBG_DRIVER      0x00000100
-
-#define DBG_DEFAULTS    (DBG_ERROR|DBG_WARNING)
-
-
-int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
-int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data);
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_AR6000                        1
-#define AR6000_MAX_RX_BUFFERS             16
-#define AR6000_BUFFER_SIZE                1664
-#define AR6000_MAX_AMSDU_RX_BUFFERS       4
-#define AR6000_AMSDU_REFILL_THRESHOLD     3
-#define AR6000_AMSDU_BUFFER_SIZE          (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
-#define AR6000_MAX_RX_MESSAGE_SIZE        (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH,WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))
-
-#define AR6000_TX_TIMEOUT                 10
-#define AR6000_ETH_ADDR_LEN               6
-#define AR6000_MAX_ENDPOINTS              4
-#define MAX_NODE_NUM                      15
-/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
-#define MAX_DEF_COOKIE_NUM                180
-#define MAX_HI_COOKIE_NUM                 18 /* 10% of MAX_COOKIE_NUM */
-#define MAX_COOKIE_NUM                    (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
-
-/* MAX_DEFAULT_SEND_QUEUE_DEPTH is used to set the default queue depth for the
- * WMM send queues.  If a queue exceeds this depth htc will query back to the
- * OS specific layer by calling EpSendFull().  This gives the OS layer the
- * opportunity to drop the packet if desired.  Therefore changing
- * MAX_DEFAULT_SEND_QUEUE_DEPTH does not affect resource utilization but
- * does impact the threshold used to identify if a packet should be
- * dropped. */
-#define MAX_DEFAULT_SEND_QUEUE_DEPTH      (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
-
-#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT        1
-#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT  1
-#define A_DISCONNECT_TIMER_INTERVAL       10 * 1000
-#define A_DEFAULT_LISTEN_INTERVAL         100
-#define A_MAX_WOW_LISTEN_INTERVAL         1000
-
-enum {
-    DRV_HB_CHALLENGE = 0,
-    APP_HB_CHALLENGE
-};
-
-enum {
-    WLAN_INIT_MODE_NONE = 0,
-    WLAN_INIT_MODE_USR,
-    WLAN_INIT_MODE_UDEV,
-    WLAN_INIT_MODE_DRV
-};
-
-/* Suspend - configuration */
-enum {
-    WLAN_SUSPEND_CUT_PWR = 0,
-    WLAN_SUSPEND_DEEP_SLEEP,
-    WLAN_SUSPEND_WOW,
-    WLAN_SUSPEND_CUT_PWR_IF_BT_OFF
-};
-
-/* WiFi OFF - configuration */
-enum {
-    WLAN_OFF_CUT_PWR = 0,
-    WLAN_OFF_DEEP_SLEEP,
-};
-
-/* WLAN low power state */
-enum {
-    WLAN_POWER_STATE_ON = 0,
-    WLAN_POWER_STATE_CUT_PWR = 1,
-    WLAN_POWER_STATE_DEEP_SLEEP,
-    WLAN_POWER_STATE_WOW
-};
-
-/* WLAN WoW State */
-enum {
-    WLAN_WOW_STATE_NONE = 0,
-    WLAN_WOW_STATE_SUSPENDED,
-    WLAN_WOW_STATE_SUSPENDING
-};
-
-
-typedef enum _AR6K_BIN_FILE {
-    AR6K_OTP_FILE,
-    AR6K_FIRMWARE_FILE,
-    AR6K_PATCH_FILE,
-    AR6K_BOARD_DATA_FILE,
-} AR6K_BIN_FILE;
-
-#ifdef SETUPHCI_ENABLED
-#define SETUPHCI_DEFAULT           1
-#else
-#define SETUPHCI_DEFAULT           0
-#endif /* SETUPHCI_ENABLED */
-
-#ifdef SETUPBTDEV_ENABLED
-#define SETUPBTDEV_DEFAULT         1
-#else
-#define SETUPBTDEV_DEFAULT         0
-#endif /* SETUPBTDEV_ENABLED */
-
-#ifdef ENABLEUARTPRINT_SET
-#define ENABLEUARTPRINT_DEFAULT    1
-#else
-#define ENABLEUARTPRINT_DEFAULT    0
-#endif /* ENABLEARTPRINT_SET */
-
-#ifdef ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
-#define NOHIFSCATTERSUPPORT_DEFAULT    1
-#else /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
-#define NOHIFSCATTERSUPPORT_DEFAULT    0
-#endif /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
-
-
-#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
-
-#ifdef CONFIG_AR600x_BT_QCOM
-#define ATH6KL_BT_DEV 1
-#elif defined(CONFIG_AR600x_BT_CSR)
-#define ATH6KL_BT_DEV 2
-#else
-#define ATH6KL_BT_DEV 3
-#endif
-
-#ifdef CONFIG_AR600x_DUAL_ANTENNA
-#define ATH6KL_BT_ANTENNA 2
-#else
-#define ATH6KL_BT_ANTENNA 1
-#endif
-
-#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
-
-#ifdef AR600x_BT_AR3001
-#define AR3KHCIBAUD_DEFAULT        3000000
-#define HCIUARTSCALE_DEFAULT       1
-#define HCIUARTSTEP_DEFAULT        8937
-#else
-#define AR3KHCIBAUD_DEFAULT        0
-#define HCIUARTSCALE_DEFAULT       0
-#define HCIUARTSTEP_DEFAULT        0
-#endif /* AR600x_BT_AR3001 */
-
-#define WLAN_INIT_MODE_DEFAULT     WLAN_INIT_MODE_DRV
-
-#define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \
-    if ((_ver) == AR6003_REV1_VERSION) { \
-        (_param) = AR6003_REV1_PATCH_DOWNLOAD_ADDRESS; \
-    } else if ((_ver) == AR6003_REV2_VERSION) { \
-        (_param) = AR6003_REV2_PATCH_DOWNLOAD_ADDRESS; \
-    } else { \
-       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
-       A_ASSERT(0); \
-    } \
-} while (0)
-
-#define AR6K_DATA_DOWNLOAD_ADDRESS(_param, _ver) do { \
-    if ((_ver) == AR6003_REV1_VERSION) { \
-        (_param) = AR6003_REV1_DATA_DOWNLOAD_ADDRESS; \
-    } else if ((_ver) == AR6003_REV2_VERSION) { \
-        (_param) = AR6003_REV2_DATA_DOWNLOAD_ADDRESS; \
-    } else { \
-       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
-       A_ASSERT(0); \
-    } \
-} while (0)
-
-#define AR6K_DATASET_PATCH_ADDRESS(_param, _ver) do { \
-        if ((_ver) == AR6003_REV2_VERSION) { \
-                (_param) = AR6003_REV2_DATASET_PATCH_ADDRESS; \
-        } else if ((_ver) == AR6003_REV3_VERSION) { \
-                (_param) = AR6003_REV3_DATASET_PATCH_ADDRESS; \
-        } else { \
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
-        A_ASSERT(0); \
-        } \
-} while (0)
-
-#define AR6K_APP_LOAD_ADDRESS(_param, _ver) do { \
-        if ((_ver) == AR6003_REV2_VERSION) { \
-                (_param) = AR6003_REV2_APP_LOAD_ADDRESS; \
-        } else if ((_ver) == AR6003_REV3_VERSION) { \
-                (_param) = AR6003_REV3_APP_LOAD_ADDRESS; \
-        } else { \
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
-        A_ASSERT(0); \
-        } \
-} while (0)
-
-#define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \
-        if ((_ver) == AR6003_REV2_VERSION) { \
-                (_param) = AR6003_REV2_APP_START_OVERRIDE; \
-        } else if ((_ver) == AR6003_REV3_VERSION) { \
-                (_param) = AR6003_REV3_APP_START_OVERRIDE; \
-        } else { \
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
-        A_ASSERT(0); \
-        } \
-} while (0)
-
-/* AR6003 1.0 definitions */
-#define AR6003_REV1_VERSION                 0x300002ba
-#define AR6003_REV1_DATA_DOWNLOAD_ADDRESS   AR6003_REV1_OTP_DATA_ADDRESS
-#define AR6003_REV1_PATCH_DOWNLOAD_ADDRESS  0x57ea6c
-#define AR6003_REV1_OTP_FILE                "ath6k/AR6003/hw1.0/otp.bin.z77"
-#define AR6003_REV1_FIRMWARE_FILE           "ath6k/AR6003/hw1.0/athwlan.bin.z77"
-#define AR6003_REV1_TCMD_FIRMWARE_FILE      "ath6k/AR6003/hw1.0/athtcmd_ram.bin"
-#define AR6003_REV1_ART_FIRMWARE_FILE       "ath6k/AR6003/hw1.0/device.bin"
-#define AR6003_REV1_PATCH_FILE              "ath6k/AR6003/hw1.0/data.patch.bin"
-#define AR6003_REV1_EPPING_FIRMWARE_FILE    "ath6k/AR6003/hw1.0/endpointping.bin"
-#ifdef CONFIG_AR600x_SD31_XXX
-#define AR6003_REV1_BOARD_DATA_FILE         "ath6k/AR6003/hw1.0/bdata.SD31.bin"
-#elif defined(CONFIG_AR600x_SD32_XXX)
-#define AR6003_REV1_BOARD_DATA_FILE         "ath6k/AR6003/hw1.0/bdata.SD32.bin"
-#elif defined(CONFIG_AR600x_WB31_XXX)
-#define AR6003_REV1_BOARD_DATA_FILE         "ath6k/AR6003/hw1.0/bdata.WB31.bin"
-#else
-#define AR6003_REV1_BOARD_DATA_FILE         "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin"
-#endif /* Board Data File */
-
-/* AR6003 2.0 definitions */
-#define AR6003_REV2_VERSION                 0x30000384 
-#define AR6003_REV2_DATA_DOWNLOAD_ADDRESS   AR6003_REV2_OTP_DATA_ADDRESS
-#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS  0x57e910
-#define AR6003_REV2_OTP_FILE                "ath6k/AR6003/hw2.0/otp.bin.z77"
-#define AR6003_REV2_FIRMWARE_FILE           "ath6k/AR6003/hw2.0/athwlan.bin.z77"
-#define AR6003_REV2_TCMD_FIRMWARE_FILE      "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
-#define AR6003_REV2_ART_FIRMWARE_FILE       "ath6k/AR6003/hw2.0/device.bin"
-#define AR6003_REV2_PATCH_FILE              "ath6k/AR6003/hw2.0/data.patch.bin"
-#define AR6003_REV2_EPPING_FIRMWARE_FILE    "ath6k/AR6003/hw2.0/endpointping.bin"
-#ifdef CONFIG_AR600x_SD31_XXX
-#define AR6003_REV2_BOARD_DATA_FILE         "ath6k/AR6003/hw2.0/bdata.SD31.bin"
-#elif defined(CONFIG_AR600x_SD32_XXX)
-#define AR6003_REV2_BOARD_DATA_FILE         "ath6k/AR6003/hw2.0/bdata.SD32.bin"
-#elif defined(CONFIG_AR600x_WB31_XXX)
-#define AR6003_REV2_BOARD_DATA_FILE         "ath6k/AR6003/hw2.0/bdata.WB31.bin"
-#else
-#define AR6003_REV2_BOARD_DATA_FILE         "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin"
-#endif /* Board Data File */
-
-/* AR6003 3.0 definitions */
-#define AR6003_REV3_VERSION                 0x30000582
-#define AR6003_REV3_OTP_FILE                "ath6k/AR6003/hw2.1.1/otp.bin"
-#define AR6003_REV3_FIRMWARE_FILE           "ath6k/AR6003/hw2.1.1/athwlan.bin"
-#define AR6003_REV3_TCMD_FIRMWARE_FILE    "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
-#define AR6003_REV3_ART_FIRMWARE_FILE       "ath6k/AR6003/hw2.1.1/device.bin"
-#define AR6003_REV3_PATCH_FILE            "ath6k/AR6003/hw2.1.1/data.patch.bin"
-#define AR6003_REV3_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/endpointping.bin"
-#ifdef CONFIG_AR600x_SD31_XXX
-#define AR6003_REV3_BOARD_DATA_FILE       "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
-#elif defined(CONFIG_AR600x_SD32_XXX)
-#define AR6003_REV3_BOARD_DATA_FILE        "ath6k/AR6003/hw2.1.1/bdata.SD32.bin"
-#elif defined(CONFIG_AR600x_WB31_XXX)
-#define AR6003_REV3_BOARD_DATA_FILE        "ath6k/AR6003/hw2.1.1/bdata.WB31.bin"
-#else
-#define AR6003_REV3_BOARD_DATA_FILE      "ath6k/AR6003/hw2.1.1/bdata.CUSTOM.bin"
-#endif /* Board Data File */
-
-
-/* Power states */
-enum {
-    WLAN_PWR_CTRL_UP = 0,
-    WLAN_PWR_CTRL_CUT_PWR,
-    WLAN_PWR_CTRL_DEEP_SLEEP,
-    WLAN_PWR_CTRL_WOW,
-    WLAN_PWR_CTRL_DEEP_SLEEP_DISABLED
-};
-
-/* HTC RAW streams */
-typedef enum _HTC_RAW_STREAM_ID {
-    HTC_RAW_STREAM_NOT_MAPPED = -1,
-    HTC_RAW_STREAM_0 = 0,
-    HTC_RAW_STREAM_1 = 1,
-    HTC_RAW_STREAM_2 = 2,
-    HTC_RAW_STREAM_3 = 3,
-    HTC_RAW_STREAM_NUM_MAX
-} HTC_RAW_STREAM_ID;
-
-#define RAW_HTC_READ_BUFFERS_NUM    4
-#define RAW_HTC_WRITE_BUFFERS_NUM   4
-
-#define HTC_RAW_BUFFER_SIZE  1664
-
-typedef struct {
-    int currPtr;
-    int length;
-    unsigned char data[HTC_RAW_BUFFER_SIZE];
-    struct htc_packet    HTCPacket;
-} raw_htc_buffer;
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-/*
- *  add TCMD_MODE besides wmi and bypasswmi
- *  in TCMD_MODE, only few TCMD releated wmi commands
- *  counld be hanlder
- */
-enum {
-    AR6000_WMI_MODE = 0,
-    AR6000_BYPASS_MODE,
-    AR6000_TCMD_MODE,
-    AR6000_WLAN_MODE
-};
-#endif /* CONFIG_HOST_TCMD_SUPPORT */
-
-struct ar_wep_key {
-    u8 arKeyIndex;
-    u8 arKeyLen;
-    u8 arKey[64];
-} ;
-
-struct ar_key {
-    u8 key[WLAN_MAX_KEY_LEN];
-    u8 key_len;
-    u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
-    u8 seq_len;
-    u32 cipher;
-};
-
-enum {
-    SME_DISCONNECTED,
-    SME_CONNECTING,
-    SME_CONNECTED
-};
-
-struct ar_node_mapping {
-    u8 macAddress[6];
-    u8 epId;
-    u8 txPending;
-};
-
-struct ar_cookie {
-    unsigned long          arc_bp[2];    /* Must be first field */
-    struct htc_packet             HtcPkt;       /* HTC packet wrapper */
-    struct ar_cookie *arc_list_next;
-};
-
-struct ar_hb_chlng_resp {
-    A_TIMER                 timer;
-    u32 frequency;
-    u32 seqNum;
-    bool                  outstanding;
-    u8 missCnt;
-    u8 missThres;
-};
-
-/* Per STA data, used in AP mode */
-/*TODO: All this should move to OS independent dir */
-
-#define STA_PWR_MGMT_MASK 0x1
-#define STA_PWR_MGMT_SHIFT 0x0
-#define STA_PWR_MGMT_AWAKE 0x0
-#define STA_PWR_MGMT_SLEEP 0x1
-
-#define STA_SET_PWR_SLEEP(sta) (sta->flags |= (STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
-#define STA_CLR_PWR_SLEEP(sta) (sta->flags &= ~(STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
-#define STA_IS_PWR_SLEEP(sta) ((sta->flags >> STA_PWR_MGMT_SHIFT) & STA_PWR_MGMT_MASK)
-
-#define STA_PS_POLLED_MASK 0x1
-#define STA_PS_POLLED_SHIFT 0x1
-#define STA_SET_PS_POLLED(sta) (sta->flags |= (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
-#define STA_CLR_PS_POLLED(sta) (sta->flags &= ~(STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
-#define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
-
-typedef struct {
-    u16 flags;
-    u8 mac[ATH_MAC_LEN];
-    u8 aid;
-    u8 keymgmt;
-    u8 ucipher;
-    u8 auth;
-    u8 wpa_ie[IEEE80211_MAX_IE];
-    A_NETBUF_QUEUE_T        psq;    /* power save q */
-    A_MUTEX_T               psqLock;
-} sta_t;
-
-typedef struct ar6_raw_htc {
-    HTC_ENDPOINT_ID         arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX];
-    HTC_RAW_STREAM_ID       arEp2RawMapping[ENDPOINT_MAX];
-    struct semaphore        raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX];
-    struct semaphore        raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX];
-    wait_queue_head_t       raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX];
-    wait_queue_head_t       raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX];
-    raw_htc_buffer          raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];
-    raw_htc_buffer          raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];
-    bool                  write_buffer_available[HTC_RAW_STREAM_NUM_MAX];
-    bool                  read_buffer_available[HTC_RAW_STREAM_NUM_MAX];
-} AR_RAW_HTC_T;
-
-struct ar6_softc {
-    struct net_device       *arNetDev;    /* net_device pointer */
-    void                    *arWmi;
-    int                     arTxPending[ENDPOINT_MAX];
-    int                     arTotalTxDataPending;
-    u8 arNumDataEndPts;
-    bool                  arWmiEnabled;
-    bool                  arWmiReady;
-    bool                  arConnected;
-    HTC_HANDLE              arHtcTarget;
-    void                    *arHifDevice;
-    spinlock_t              arLock;
-    struct semaphore        arSem;
-    int                     arSsidLen;
-    u_char                  arSsid[32];
-    u8 arNextMode;
-    u8 arNetworkType;
-    u8 arDot11AuthMode;
-    u8 arAuthMode;
-    u8 arPairwiseCrypto;
-    u8 arPairwiseCryptoLen;
-    u8 arGroupCrypto;
-    u8 arGroupCryptoLen;
-    u8 arDefTxKeyIndex;
-    struct ar_wep_key       arWepKeyList[WMI_MAX_KEY_INDEX + 1];
-    u8 arBssid[6];
-    u8 arReqBssid[6];
-    u16 arChannelHint;
-    u16 arBssChannel;
-    u16 arListenIntervalB;
-    u16 arListenIntervalT;
-    struct ar6000_version   arVersion;
-    u32 arTargetType;
-    s8 arRssi;
-    u8 arTxPwr;
-    bool                  arTxPwrSet;
-    s32 arBitRate;
-    struct net_device_stats arNetStats;
-    struct iw_statistics    arIwStats;
-    s8 arNumChannels;
-    u16 arChannelList[32];
-    u32 arRegCode;
-    bool                  statsUpdatePending;
-    TARGET_STATS            arTargetStats;
-    s8 arMaxRetries;
-    u8 arPhyCapability;
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-    u32 arTargetMode;
-    void *tcmd_rx_report;
-    int tcmd_rx_report_len;
-#endif
-    AR6000_WLAN_STATE       arWlanState;
-    struct ar_node_mapping  arNodeMap[MAX_NODE_NUM];
-    u8 arIbssPsEnable;
-    u8 arNodeNum;
-    u8 arNexEpId;
-    struct ar_cookie        *arCookieList;
-    u32 arCookieCount;
-    u32 arRateMask;
-    u8 arSkipScan;
-    u16 arBeaconInterval;
-    bool                  arConnectPending;
-    bool                  arWmmEnabled;
-    struct ar_hb_chlng_resp arHBChallengeResp;
-    u8 arKeepaliveConfigured;
-    u32 arMgmtFilter;
-    HTC_ENDPOINT_ID         arAc2EpMapping[WMM_NUM_AC];
-    bool                  arAcStreamActive[WMM_NUM_AC];
-    u8 arAcStreamPriMap[WMM_NUM_AC];
-    u8 arHiAcStreamActivePri;
-    u8 arEp2AcMapping[ENDPOINT_MAX];
-    HTC_ENDPOINT_ID         arControlEp;
-#ifdef HTC_RAW_INTERFACE
-    AR_RAW_HTC_T            *arRawHtc;
-#endif
-    bool                  arNetQueueStopped;
-    bool                  arRawIfInit;
-    int                     arDeviceIndex;
-    struct common_credit_state_info arCreditStateInfo;
-    bool                  arWMIControlEpFull;
-    bool                  dbgLogFetchInProgress;
-    u8                 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE];
-    u32 log_cnt;
-    u32 dbglog_init_done;
-    u32 arConnectCtrlFlags;
-    s32 user_savedkeys_stat;
-    u32 user_key_ctrl;
-    struct USER_SAVEDKEYS   user_saved_keys;
-    USER_RSSI_THOLD rssi_map[12];
-    u8 arUserBssFilter;
-    u16 ap_profile_flag;    /* AP mode */
-    WMI_AP_ACL              g_acl;              /* AP mode */
-    sta_t                   sta_list[AP_MAX_NUM_STA]; /* AP mode */
-    u8 sta_list_index;     /* AP mode */
-    struct ieee80211req_key ap_mode_bkey;           /* AP mode */
-    A_NETBUF_QUEUE_T        mcastpsq;    /* power save q for Mcast frames */
-    A_MUTEX_T               mcastpsqLock;
-    bool                  DTIMExpired; /* flag to indicate DTIM expired */
-    u8 intra_bss;   /* enable/disable intra bss data forward */
-    void                    *aggr_cntxt;
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-    void                    *hcidev_info;
-#endif
-    WMI_AP_MODE_STAT        arAPStats;
-    u8 ap_hidden_ssid;
-    u8 ap_country_code[3];
-    u8 ap_wmode;
-    u8 ap_dtim_period;
-    u16 ap_beacon_interval;
-    u16 arRTS;
-    u16 arACS; /* AP mode - Auto Channel Selection */
-    struct htc_packet_queue        amsdu_rx_buffer_queue;
-    bool                  bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */
-    A_TIMER                 disconnect_timer;
-    u8 rxMetaVersion;
-#ifdef WAPI_ENABLE
-    u8 arWapiEnable;
-#endif
-       WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig;
-       WMI_BTCOEX_STATS_EVENT  arBtcoexStats;
-    s32 (*exitCallback)(void *config);  /* generic callback at AR6K exit */
-    struct hif_device_os_device_info   osDevInfo;
-    struct wireless_dev *wdev;
-    struct cfg80211_scan_request    *scan_request;
-    struct ar_key   keys[WMI_MAX_KEY_INDEX + 1];
-    u32 smeState;
-    u16 arWlanPowerState;
-    bool                  arWlanOff;
-#ifdef CONFIG_PM
-    u16 arWowState;
-    bool                  arBTOff;
-    bool                  arBTSharing;
-    u16 arSuspendConfig;
-    u16 arWlanOffConfig;
-    u16 arWow2Config;
-#endif
-    u8 scan_triggered;
-    WMI_SCAN_PARAMS_CMD     scParams;
-#define AR_MCAST_FILTER_MAC_ADDR_SIZE  4
-    u8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE];
-    u8 bdaddr[6];
-    bool                  scanSpecificSsid;
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-    void                    *arApDev;
-#endif
-    u8 arAutoAuthStage;
-
-       u8 *fw_otp;
-       size_t fw_otp_len;
-       u8 *fw;
-       size_t fw_len;
-       u8 *fw_patch;
-       size_t fw_patch_len;
-       u8 *fw_data;
-       size_t fw_data_len;
-};
-
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-struct ar_virtual_interface {
-    struct net_device       *arNetDev;    /* net_device pointer */
-    struct ar6_softc              *arDev;       /* ar device pointer */
-    struct net_device       *arStaNetDev; /* net_device pointer */
-};
-#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-
-static inline void *ar6k_priv(struct net_device *dev)
-{
-    return (wdev_priv(dev->ieee80211_ptr));
-}
-
-#define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \
-    (pHciDev)->bus = (__bus); \
-    (pHciDev)->dev_type = (__type); \
-} while(0)
-
-#define GET_INODE_FROM_FILEP(filp) \
-    (filp)->f_path.dentry->d_inode
-
-#define arAc2EndpointID(ar,ac)          (ar)->arAc2EpMapping[(ac)]
-#define arSetAc2EndpointIDMap(ar,ac,ep)  \
-{  (ar)->arAc2EpMapping[(ac)] = (ep); \
-   (ar)->arEp2AcMapping[(ep)] = (ac); }
-#define arEndpoint2Ac(ar,ep)           (ar)->arEp2AcMapping[(ep)]
-
-#define arRawIfEnabled(ar) (ar)->arRawIfInit
-#define arRawStream2EndpointID(ar,raw)          (ar)->arRawHtc->arRaw2EpMapping[(raw)]
-#define arSetRawStream2EndpointIDMap(ar,raw,ep)  \
-{  (ar)->arRawHtc->arRaw2EpMapping[(raw)] = (ep); \
-   (ar)->arRawHtc->arEp2RawMapping[(ep)] = (raw); }
-#define arEndpoint2RawStreamID(ar,ep)           (ar)->arRawHtc->arEp2RawMapping[(ep)]
-
-struct ar_giwscan_param {
-    char *current_ev;
-    char *end_buf;
-    u32 bytes_needed;
-    struct iw_request_info *info;
-};
-
-#define AR6000_STAT_INC(ar, stat)       (ar->arNetStats.stat++)
-
-#define AR6000_SPIN_LOCK(lock, param)   do {                            \
-    if (irqs_disabled()) {                                              \
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled:AR6000_LOCK\n"));                 \
-    }                                                                   \
-    spin_lock_bh(lock);                                                 \
-} while (0)
-
-#define AR6000_SPIN_UNLOCK(lock, param) do {                            \
-    if (irqs_disabled()) {                                              \
-        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled: AR6000_UNLOCK\n"));              \
-    }                                                                   \
-    spin_unlock_bh(lock);                                               \
-} while (0)
-
-void ar6000_init_profile_info(struct ar6_softc *ar);
-void ar6000_install_static_wep_keys(struct ar6_softc *ar);
-int ar6000_init(struct net_device *dev);
-int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
-void ar6000_TxDataCleanup(struct ar6_softc *ar);
-int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev);
-void ar6000_restart_endpoint(struct net_device *dev);
-void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs);
-
-#ifdef HTC_RAW_INTERFACE
-
-#ifndef __user
-#define __user
-#endif
-
-int ar6000_htc_raw_open(struct ar6_softc *ar);
-int ar6000_htc_raw_close(struct ar6_softc *ar);
-ssize_t ar6000_htc_raw_read(struct ar6_softc *ar,
-                            HTC_RAW_STREAM_ID StreamID,
-                            char __user *buffer, size_t count);
-ssize_t ar6000_htc_raw_write(struct ar6_softc *ar,
-                             HTC_RAW_STREAM_ID StreamID,
-                             char __user *buffer, size_t count);
-
-#endif /* HTC_RAW_INTERFACE */
-
-/* AP mode */
-/*TODO: These routines should be moved to a file that is common across OS */
-sta_t *
-ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr);
-
-sta_t *
-ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid);
-
-u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason);
-
-/* HCI support */
-
-#ifndef EXPORT_HCI_BRIDGE_INTERFACE
-int ar6000_setup_hci(struct ar6_softc *ar);
-void     ar6000_cleanup_hci(struct ar6_softc *ar);
-void     ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig);
-
-/* HCI bridge testing */
-int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb);
-#endif
-
-ATH_DEBUG_DECLARE_EXTERN(htc);
-ATH_DEBUG_DECLARE_EXTERN(wmi);
-ATH_DEBUG_DECLARE_EXTERN(bmi);
-ATH_DEBUG_DECLARE_EXTERN(hif);
-ATH_DEBUG_DECLARE_EXTERN(wlan);
-ATH_DEBUG_DECLARE_EXTERN(misc);
-
-extern u8 bcast_mac[];
-extern u8 null_mac[];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _AR6000_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
deleted file mode 100644 (file)
index 39e0873..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-// The software source and binaries included in this development package are
-// licensed, not sold. You, or your company, received the package under one
-// or more license agreements. The rights granted to you are specifically
-// listed in these license agreement(s). All other rights remain with Atheros
-// Communications, Inc., its subsidiaries, or the respective owner including
-// those listed on the included copyright notices.  Distribution of any
-// portion of this package must be in strict compliance with the license
-// agreement(s) terms.
-// </copyright>
-// 
-// <summary>
-//     PAL driver for AR6003
-// </summary>
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _AR6K_PAL_H_
-#define _AR6K_PAL_H_
-#define HCI_GET_OP_CODE(p)          (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
-
-/* transmit packet reserve offset */
-#define TX_PACKET_RSV_OFFSET        32
-/* pal specific config structure */
-typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb);
-typedef struct ar6k_pal_config_s
-{
-       ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt;
-}ar6k_pal_config_t;
-
-void register_pal_cb(ar6k_pal_config_t *palConfig_p);
-#endif /* _AR6K_PAL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
deleted file mode 100644 (file)
index 184dbdb..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _AR6XAPI_LINUX_H
-#define _AR6XAPI_LINUX_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ar6_softc;
-
-void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap,
-                        u32 sw_ver, u32 abi_ver);
-int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid);
-void ar6000_connect_event(struct ar6_softc *ar, u16 channel,
-                          u8 *bssid, u16 listenInterval,
-                          u16 beaconInterval, NETWORK_TYPE networkType,
-                          u8 beaconIeLen, u8 assocReqLen,
-                          u8 assocRespLen,u8 *assocInfo);
-void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason,
-                             u8 *bssid, u8 assocRespLen,
-                             u8 *assocInfo, u16 protocolReasonStatus);
-void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid,
-                              bool ismcast);
-void ar6000_bitrate_rx(void *devt, s32 rateKbps);
-void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList);
-void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode);
-void ar6000_txPwr_rx(void *devt, u8 txPwr);
-void ar6000_keepalive_rx(void *devt, u8 configured);
-void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps,
-                                 WMI_NEIGHBOR_INFO *info);
-void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num);
-void ar6000_scanComplete_event(struct ar6_softc *ar, int status);
-void ar6000_targetStats_event(struct ar6_softc *ar,  u8 *ptr, u32 len);
-void ar6000_rssiThreshold_event(struct ar6_softc *ar,
-                                WMI_RSSI_THRESHOLD_VAL newThreshold,
-                                s16 rssi);
-void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal);
-void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication,
-                                u8 statusCode, u8 *tspecSuggestion);
-void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel);
-void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source);
-void
-ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl);
-
-void
-ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p);
-
-void
-ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters,
-                      WMI_GET_WOW_LIST_REPLY *wow_reply);
-
-void ar6000_pmkid_list_event(void *devt, u8 numPMKID,
-                             WMI_PMKID *pmkidList, u8 *bssidList);
-
-void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values);
-void ar6000_gpio_data_rx(u32 reg_id, u32 value);
-void ar6000_gpio_ack_rx(void);
-
-s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt);
-s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi);
-s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above);
-
-void ar6000_dbglog_init_done(struct ar6_softc *ar);
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len);
-#endif
-
-void ar6000_tx_retry_err_event(void *devt);
-
-void ar6000_snrThresholdEvent_rx(void *devt,
-                                 WMI_SNR_THRESHOLD_VAL newThreshold,
-                                 u8 snr);
-
-void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal);
-
-
-void ar6000_ratemask_rx(void *devt, u32 ratemask);
-
-int ar6000_get_driver_cfg(struct net_device *dev,
-                                u16 cfgParam,
-                                void *result);
-void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len);
-
-void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped,
-                         s8 *buffer, u32 length);
-
-int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
-
-void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid);
-
-void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active);
-HTC_ENDPOINT_ID  ar6000_ac2_endpoint_id ( void * devt, u8 ac);
-u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep );
-
-void ar6000_btcoex_config_event(struct ar6_softc *ar,  u8 *ptr, u32 len);
-
-void ar6000_btcoex_stats_event(struct ar6_softc *ar,  u8 *ptr, u32 len) ;
-
-void ar6000_dset_open_req(void *devt,
-                          u32 id,
-                          u32 targ_handle,
-                          u32 targ_reply_fn,
-                          u32 targ_reply_arg);
-void ar6000_dset_close(void *devt, u32 access_cookie);
-void ar6000_dset_data_req(void *devt,
-                          u32 access_cookie,
-                          u32 offset,
-                          u32 length,
-                          u32 targ_buf,
-                          u32 targ_reply_fn,
-                          u32 targ_reply_arg);
-
-
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-void prof_count_rx(unsigned int addr, unsigned int count);
-#endif
-
-u32 ar6000_getnodeAge (void);
-
-u32 ar6000_getclkfreq (void);
-
-int ar6000_ap_mode_profile_commit(struct ar6_softc *ar);
-
-struct ieee80211req_wpaie;
-int
-ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie);
-
-int is_iwioctl_allowed(u8 mode, u16 cmd);
-
-int is_xioctl_allowed(u8 mode, int cmd);
-
-void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid);
-
-void ar6000_dtimexpiry_event(struct ar6_softc *ar);
-
-void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd);
-void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd);
-void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd);
-void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd);
-
-#ifdef WAPI_ENABLE
-int ap_set_wapi_key(struct ar6_softc *ar, void *ik);
-void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac);
-#endif
-
-int ar6000_connect_to_ap(struct ar6_softc *ar);
-int ar6000_disconnect(struct ar6_softc *ar);
-int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending);
-int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state);
-int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state);
-
-#ifdef CONFIG_PM
-int ar6000_suspend_ev(void *context);
-int ar6000_resume_ev(void *context);
-int ar6000_power_change_ev(void *context, u32 config);
-void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent);
-#endif
-
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname);
-int ar6000_remove_ap_interface(struct ar6_softc *ar);
-#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
deleted file mode 100644 (file)
index 3d5f01d..0000000
+++ /dev/null
@@ -1,1217 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _ATHDRV_LINUX_H
-#define _ATHDRV_LINUX_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * There are two types of ioctl's here: Standard ioctls and
- * eXtended ioctls.  All extended ioctls (XIOCTL) are multiplexed
- * off of the single ioctl command, AR6000_IOCTL_EXTENDED.  The
- * arguments for every XIOCTL starts with a 32-bit command word
- * that is used to select which extended ioctl is in use.  After
- * the command word are command-specific arguments.
- */
-
-/* Linux standard Wireless Extensions, private ioctl interfaces */
-#define IEEE80211_IOCTL_SETPARAM             (SIOCIWFIRSTPRIV+0)
-#define IEEE80211_IOCTL_SETKEY               (SIOCIWFIRSTPRIV+1)
-#define IEEE80211_IOCTL_DELKEY               (SIOCIWFIRSTPRIV+2)
-#define IEEE80211_IOCTL_SETMLME              (SIOCIWFIRSTPRIV+3)
-#define IEEE80211_IOCTL_ADDPMKID             (SIOCIWFIRSTPRIV+4)
-#define IEEE80211_IOCTL_SETOPTIE             (SIOCIWFIRSTPRIV+5)
-//#define IEEE80211_IOCTL_GETPARAM             (SIOCIWFIRSTPRIV+6)
-//#define IEEE80211_IOCTL_SETWMMPARAMS         (SIOCIWFIRSTPRIV+7)
-//#define IEEE80211_IOCTL_GETWMMPARAMS         (SIOCIWFIRSTPRIV+8)
-//#define IEEE80211_IOCTL_GETOPTIE             (SIOCIWFIRSTPRIV+9)
-//#define IEEE80211_IOCTL_SETAUTHALG           (SIOCIWFIRSTPRIV+10)
-#define IEEE80211_IOCTL_LASTONE              (SIOCIWFIRSTPRIV+10)
-
-
-
-/*                      ====WMI Ioctls====                                    */
-/*
- *
- * Many ioctls simply provide WMI services to application code:
- * an application makes such an ioctl call with a set of arguments
- * that are packaged into the corresponding WMI message, and sent
- * to the Target.
- */
-
-#define AR6000_IOCTL_WMI_GETREV              (SIOCIWFIRSTPRIV+11)
-/*
- * arguments:
- *   ar6000_version *revision
- */
-
-#define AR6000_IOCTL_WMI_SETPWR              (SIOCIWFIRSTPRIV+12)
-/*
- * arguments:
- *   WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h)
- * uses: WMI_SET_POWER_MODE_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SETSCAN             (SIOCIWFIRSTPRIV+13)
-/*
- * arguments:
- *   WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h)
- * uses: WMI_SET_SCAN_PARAMS_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SETLISTENINT        (SIOCIWFIRSTPRIV+14)
-/*
- * arguments:
- *   UINT32 listenInterval
- * uses: WMI_SET_LISTEN_INT_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SETBSSFILTER        (SIOCIWFIRSTPRIV+15)
-/*
- * arguments:
- *   WMI_BSS_FILTER filter (see include/wmi.h)
- * uses: WMI_SET_BSS_FILTER_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS   (SIOCIWFIRSTPRIV+16)
-/*
- * arguments:
- *   WMI_CHANNEL_PARAMS_CMD chParams
- * uses: WMI_SET_CHANNEL_PARAMS_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_PROBEDSSID      (SIOCIWFIRSTPRIV+17)
-/*
- * arguments:
- *   WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h)
- * uses: WMI_SETPROBED_SSID_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_PMPARAMS        (SIOCIWFIRSTPRIV+18)
-/*
- * arguments:
- *   WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h)
- * uses: WMI_SET_POWER_PARAMS_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_BADAP           (SIOCIWFIRSTPRIV+19)
-/*
- * arguments:
- *   WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h)
- * uses: WMI_ADD_BAD_AP_CMDID
- */
-
-#define AR6000_IOCTL_WMI_GET_QOS_QUEUE       (SIOCIWFIRSTPRIV+20)
-/*
- * arguments:
- *   ar6000_queuereq queueRequest (see below)
- */
-
-#define AR6000_IOCTL_WMI_CREATE_QOS          (SIOCIWFIRSTPRIV+21)
-/*
- * arguments:
- *   WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h)
- * uses: WMI_CREATE_PSTREAM_CMDID
- */
-
-#define AR6000_IOCTL_WMI_DELETE_QOS          (SIOCIWFIRSTPRIV+22)
-/*
- * arguments:
- *   WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h)
- * uses: WMI_DELETE_PSTREAM_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD   (SIOCIWFIRSTPRIV+23)
-/*
- * arguments:
- *   WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
- * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)
-/*
- * arguments:
- *   WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h)
- * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
- */
-
-#define AR6000_IOCTL_WMI_GET_TARGET_STATS    (SIOCIWFIRSTPRIV+25)
-/*
- * arguments:
- *   TARGET_STATS *targetStats (see below)
- * uses: WMI_GET_STATISTICS_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_ASSOC_INFO      (SIOCIWFIRSTPRIV+26)
-/*
- * arguments:
- *   WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd
- * uses: WMI_SET_ASSOC_INFO_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS   (SIOCIWFIRSTPRIV+27)
-/*
- * arguments:
- *   WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h)
- * uses: WMI_SET_ACCESS_PARAMS_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_BMISS_TIME      (SIOCIWFIRSTPRIV+28)
-/*
- * arguments:
- *   UINT32 beaconMissTime
- * uses: WMI_SET_BMISS_TIME_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT    (SIOCIWFIRSTPRIV+29)
-/*
- * arguments:
- *   WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h)
- * uses: WMI_SET_DISC_TIMEOUT_CMDID
- */
-
-#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS    (SIOCIWFIRSTPRIV+30)
-/*
- * arguments:
- *   WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd
- * uses: WMI_SET_IBSS_PM_CAPS_CMDID
- */
-
-/*
- * There is a very small space available for driver-private
- * wireless ioctls.  In order to circumvent this limitation,
- * we multiplex a bunch of ioctls (XIOCTLs) on top of a
- * single AR6000_IOCTL_EXTENDED ioctl.
- */
-#define AR6000_IOCTL_EXTENDED                (SIOCIWFIRSTPRIV+31)
-
-
-/*                         ====BMI Extended Ioctls====                        */
-
-#define AR6000_XIOCTL_BMI_DONE                                  1
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_DONE)
- * uses: BMI_DONE
- */
-
-#define AR6000_XIOCTL_BMI_READ_MEMORY                           2
-/*
- * arguments:
- *   union {
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY)
- *       UINT32 address
- *       UINT32 length
- *     }
- *     char results[length]
- *   }
- * uses: BMI_READ_MEMORY
- */
-
-#define AR6000_XIOCTL_BMI_WRITE_MEMORY                          3
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY)
- *   UINT32 address
- *   UINT32 length
- *   char data[length]
- * uses: BMI_WRITE_MEMORY
- */
-
-#define AR6000_XIOCTL_BMI_EXECUTE                               4
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE)
- *   UINT32 TargetAddress
- *   UINT32 parameter
- * uses: BMI_EXECUTE
- */
-
-#define AR6000_XIOCTL_BMI_SET_APP_START                         5
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START)
- *   UINT32 TargetAddress
- * uses: BMI_SET_APP_START
- */
-
-#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER                     6
-/*
- * arguments:
- *   union {
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER)
- *       UINT32 TargetAddress, 32-bit aligned
- *     }
- *     UINT32 result
- *   }
- * uses: BMI_READ_SOC_REGISTER
- */
-
-#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER                    7
-/*
- * arguments:
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER)
- *       UINT32 TargetAddress, 32-bit aligned
- *       UINT32 newValue
- *     }
- * uses: BMI_WRITE_SOC_REGISTER
- */
-
-#define AR6000_XIOCTL_BMI_TEST                                  8
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_TEST)
- *   UINT32 address
- *   UINT32 length
- *   UINT32 count
- */
-
-
-
-/* Historical Host-side DataSet support */
-#define AR6000_XIOCTL_UNUSED9                                   9
-#define AR6000_XIOCTL_UNUSED10                                  10
-#define AR6000_XIOCTL_UNUSED11                                  11
-
-/*                      ====Misc Extended Ioctls====                          */
-
-#define AR6000_XIOCTL_FORCE_TARGET_RESET                        12
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET)
- */
-
-
-#ifdef HTC_RAW_INTERFACE
-/* HTC Raw Interface Ioctls */
-#define AR6000_XIOCTL_HTC_RAW_OPEN                              13
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN)
- */
-
-#define AR6000_XIOCTL_HTC_RAW_CLOSE                             14
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE)
- */
-
-#define AR6000_XIOCTL_HTC_RAW_READ                              15
-/*
- * arguments:
- *   union {
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ)
- *       UINT32 mailboxID
- *       UINT32 length
- *     }
- *     results[length]
- *   }
- */
-
-#define AR6000_XIOCTL_HTC_RAW_WRITE                             16
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE)
- *   UINT32 mailboxID
- *   UINT32 length
- *   char buffer[length]
- */
-#endif /* HTC_RAW_INTERFACE */
-
-#define AR6000_XIOCTL_CHECK_TARGET_READY                        17
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY)
- */
-
-
-
-/*                ====GPIO (General Purpose I/O) Extended Ioctls====          */
-
-#define AR6000_XIOCTL_GPIO_OUTPUT_SET                           18
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET)
- *   ar6000_gpio_output_set_cmd_s (see below)
- * uses: WMIX_GPIO_OUTPUT_SET_CMDID
- */
-
-#define AR6000_XIOCTL_GPIO_INPUT_GET                            19
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET)
- * uses: WMIX_GPIO_INPUT_GET_CMDID
- */
-
-#define AR6000_XIOCTL_GPIO_REGISTER_SET                         20
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET)
- *   ar6000_gpio_register_cmd_s (see below)
- * uses: WMIX_GPIO_REGISTER_SET_CMDID
- */
-
-#define AR6000_XIOCTL_GPIO_REGISTER_GET                         21
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET)
- *   ar6000_gpio_register_cmd_s (see below)
- * uses: WMIX_GPIO_REGISTER_GET_CMDID
- */
-
-#define AR6000_XIOCTL_GPIO_INTR_ACK                             22
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK)
- *   ar6000_cpio_intr_ack_cmd_s (see below)
- * uses: WMIX_GPIO_INTR_ACK_CMDID
- */
-
-#define AR6000_XIOCTL_GPIO_INTR_WAIT                            23
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT)
- */
-
-
-
-/*                    ====more wireless commands====                          */
-
-#define AR6000_XIOCTL_SET_ADHOC_BSSID                           24
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID)
- *   WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h)
- */
-
-#define AR6000_XIOCTL_SET_OPT_MODE                              25
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE)
- *   WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h)
- * uses: WMI_SET_OPT_MODE_CMDID
- */
-
-#define AR6000_XIOCTL_OPT_SEND_FRAME                            26
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME)
- *   WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h)
- * uses: WMI_OPT_TX_FRAME_CMDID
- */
-
-#define AR6000_XIOCTL_SET_BEACON_INTVAL                         27
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_SET_BEACON_INTVAL)
- *   WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h)
- * uses: WMI_SET_BEACON_INT_CMDID
- */
-
-
-#define IEEE80211_IOCTL_SETAUTHALG                              28
-
-
-#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE                        29
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE)
- *   WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h)
- * uses: WMI_SET_VOICE_PKT_SIZE_CMDID
- */
-
-
-#define AR6000_XIOCTL_SET_MAX_SP                                30
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP)
- *   WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h)
- * uses: WMI_SET_MAX_SP_LEN_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_GET_ROAM_TBL                          31
-
-#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL                         32
-
-#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS                 33
-
-
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS)
- *   WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h)
- *   WMI_SET_POWERSAVE_TIMERS_CMDID
- */
-
-#define AR6000_XIOCTRL_WMI_GET_POWER_MODE                        34
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE)
- */
-
-#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE                       35
-typedef enum {
-    WLAN_DISABLED,
-    WLAN_ENABLED
-} AR6000_WLAN_STATE;
-/*
- * arguments:
- * enable/disable
- */
-
-#define AR6000_XIOCTL_WMI_GET_ROAM_DATA                         36
-
-#define AR6000_XIOCTL_WMI_SETRETRYLIMITS                37
-/*
- * arguments:
- *   WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd
- * uses: WMI_SET_RETRY_LIMITS_CMDID
- */
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-/*       ====extended commands for radio test ====                          */
-
-#define AR6000_XIOCTL_TCMD_CONT_TX                      38
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX)
- *   WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h)
- * uses: WMI_TCMD_CONT_TX_CMDID
- */
-
-#define AR6000_XIOCTL_TCMD_CONT_RX                      39
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX)
- *   WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h)
- * uses: WMI_TCMD_CONT_RX_CMDID
- */
-
-#define AR6000_XIOCTL_TCMD_PM                           40
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_TCMD_PM)
- *   WMI_TCMD_PM_CMD pmCmd (see include/wmi.h)
- * uses: WMI_TCMD_PM_CMDID
- */
-
-#endif /* CONFIG_HOST_TCMD_SUPPORT */
-
-#define AR6000_XIOCTL_WMI_STARTSCAN                     41
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN)
- *   UINT8  scanType
- *   UINT8  scanConnected
- *   u32 forceFgScan
- * uses: WMI_START_SCAN_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_SETFIXRATES                   42
-
-#define AR6000_XIOCTL_WMI_GETFIXRATES                   43
-
-
-#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD             44
-/*
- * arguments:
- *   WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
- * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_CLR_RSSISNR                   45
-/*
- * arguments:
- *   WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h)
- * uses: WMI_CLR_RSSISNR_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD               46
-/*
- * arguments:
- *   WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
- * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_SET_RTS                        47
-/*
- * arguments:
- *   WMI_SET_RTS_MODE_CMD (see include/wmi.h)
- * uses: WMI_SET_RTS_MODE_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_SET_LPREAMBLE                 48
-
-#define AR6000_XIOCTL_WMI_SET_AUTHMODE                  49
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE)
- *   UINT8  mode
- * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_SET_REASSOCMODE               50
-
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM)
- *   UINT8  mode
- * uses: WMI_SET_WMM_CMDID
- */
-#define AR6000_XIOCTL_WMI_SET_WMM                       51
-
-/*
- * arguments:
- * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS)
- * UINT32 frequency
- * UINT8  threshold
- */
-#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS  52
-
-/*
- * arguments:
- * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP)
- * UINT32 cookie
- */
-#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP         53
-
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD)
- *   UINT32 regDomain
- */
-#define AR6000_XIOCTL_WMI_GET_RD                        54
-
-#define AR6000_XIOCTL_DIAG_READ                         55
-
-#define AR6000_XIOCTL_DIAG_WRITE                        56
-
-/*
- * arguments cmd (AR6000_XIOCTL_SET_TXOP)
- * WMI_TXOP_CFG  txopEnable
- */
-#define AR6000_XIOCTL_WMI_SET_TXOP                      57
-
-/*
- * arguments:
- * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS)
- * UINT32 keyOpCtrl
- * uses struct ar6000_user_setkeys_info
- */
-#define AR6000_XIOCTL_USER_SETKEYS                      58
-
-#define AR6000_XIOCTL_WMI_SET_KEEPALIVE                 59
-/*
- * arguments:
- *   UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE)
- *   UINT8 keepaliveInterval
- * uses: WMI_SET_KEEPALIVE_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_GET_KEEPALIVE                 60
-/*
- * arguments:
- *   UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE)
- *   UINT8 keepaliveInterval
- *   u32 configured
- * uses: WMI_GET_KEEPALIVE_CMDID
- */
-
-/*               ====ROM Patching Extended Ioctls====                       */
-
-#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL              61
-/*
- * arguments:
- *     union {
- *       struct {
- *         UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL)
- *         UINT32 ROM Address
- *         UINT32 RAM Address
- *         UINT32 number of bytes
- *         UINT32 activate? (0 or 1)
- *       }
- *       u32 resulting rompatch ID
- *     }
- * uses: BMI_ROMPATCH_INSTALL
- */
-
-#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL            62
-/*
- * arguments:
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL)
- *       UINT32 rompatch ID
- *     }
- * uses: BMI_ROMPATCH_UNINSTALL
- */
-
-#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE             63
-/*
- * arguments:
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE)
- *       UINT32 rompatch count
- *       UINT32 rompatch IDs[rompatch count]
- *     }
- * uses: BMI_ROMPATCH_ACTIVATE
- */
-
-#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE           64
-/*
- * arguments:
- *     struct {
- *       UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE)
- *       UINT32 rompatch count
- *       UINT32 rompatch IDs[rompatch count]
- *     }
- * uses: BMI_ROMPATCH_DEACTIVATE
- */
-
-#define AR6000_XIOCTL_WMI_SET_APPIE             65
-/*
- * arguments:
- *      struct {
- *          UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE)
- *          UINT32  app_frmtype;
- *          UINT32  app_buflen;
- *          UINT8   app_buf[];
- *      }
- */
-#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER    66
-/*
- * arguments:
- *      u32 filter_type;
- */
-
-#define AR6000_XIOCTL_DBGLOG_CFG_MODULE             67
-
-#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS         68
-
-#define AR6000_XIOCTL_WMI_SET_WSC_STATUS            70
-/*
- * arguments:
- *      u32 wsc_status;
- *            (WSC_REG_INACTIVE or WSC_REG_ACTIVE)
- */
-
-/*
- * arguments:
- *      struct {
- *          u8 streamType;
- *          u8 status;
- *      }
- * uses: WMI_SET_BT_STATUS_CMDID
- */
-#define AR6000_XIOCTL_WMI_SET_BT_STATUS             71
-
-/*
- * arguments:
- *      struct {
- *           u8 paramType;
- *           union {
- *               u8 noSCOPkts;
- *               BT_PARAMS_A2DP a2dpParams;
- *               BT_COEX_REGS regs;
- *           };
- *      }
- * uses: WMI_SET_BT_PARAM_CMDID
- */
-#define AR6000_XIOCTL_WMI_SET_BT_PARAMS             72
-
-#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE       73
-#define AR6000_XIOCTL_WMI_SET_WOW_MODE              74
-#define AR6000_XIOCTL_WMI_GET_WOW_LIST              75
-#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN           76
-#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN           77
-
-
-
-#define AR6000_XIOCTL_TARGET_INFO                   78
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_TARGET_INFO)
- *   u32 TargetVersion (returned)
- *   u32 TargetType    (returned)
- * (See also bmi_msg.h target_ver and target_type)
- */
-
-#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE         79
-/*
- * arguments:
- *      none
- */
-
-#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE       80
-/*
- * This ioctl is used to emulate traffic activity
- * timeouts.  Activity/inactivity will trigger the driver
- * to re-balance credits.
- *
- * arguments:
- *      ar6000_traffic_activity_change
- */
-
-#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS    81
-/*
- * This ioctl is used to set the connect control flags
- *
- * arguments:
- *      u32 connectCtrlFlags
- */
-
-#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS              82
-/*
- * This IOCTL sets any Authentication,Key Management and Protection
- * related parameters. This is used along with the information set in
- * Connect Command.
- * Currently this enables Multiple PMKIDs to an AP.
- *
- * arguments:
- *      struct {
- *          u32 akmpInfo;
- *      }
- * uses: WMI_SET_AKMP_PARAMS_CMD
- */
-
-#define AR6000_XIOCTL_WMI_GET_PMKID_LIST            83
-
-#define AR6000_XIOCTL_WMI_SET_PMKID_LIST            84
-/*
- * This IOCTL is used to set a list of PMKIDs. This list of
- * PMKIDs is used in the [Re]AssocReq Frame. This list is used
- * only if the MultiPMKID option is enabled via the
- * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS  IOCTL.
- *
- * arguments:
- *      struct {
- *          u32 numPMKID;
- *          WMI_PMKID   pmkidList[WMI_MAX_PMKID_CACHE];
- *      }
- * uses: WMI_SET_PMKIDLIST_CMD
- */
-
-#define AR6000_XIOCTL_WMI_SET_PARAMS                85
-#define AR6000_XIOCTL_WMI_SET_MCAST_FILTER     86
-#define AR6000_XIOCTL_WMI_DEL_MCAST_FILTER     87
-
-
-/* Historical DSETPATCH support for INI patches */
-#define AR6000_XIOCTL_UNUSED90                      90
-
-
-/* Support LZ-compressed firmware download */
-#define AR6000_XIOCTL_BMI_LZ_STREAM_START           91
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_LZ_STREAM_START)
- *   UINT32 address
- * uses: BMI_LZ_STREAM_START
- */
-
-#define AR6000_XIOCTL_BMI_LZ_DATA                   92
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_BMI_LZ_DATA)
- *   UINT32 length
- *   char data[length]
- * uses: BMI_LZ_DATA
- */
-
-#define AR6000_XIOCTL_PROF_CFG                      93
-/*
- * arguments:
- *   u32 period
- *   u32 nbins
- */
-
-#define AR6000_XIOCTL_PROF_ADDR_SET                 94
-/*
- * arguments:
- *   u32 Target address
- */
-
-#define AR6000_XIOCTL_PROF_START                    95
-
-#define AR6000_XIOCTL_PROF_STOP                     96
-
-#define AR6000_XIOCTL_PROF_COUNT_GET                97
-
-#define AR6000_XIOCTL_WMI_ABORT_SCAN                98
-
-/*
- * AP mode
- */
-#define AR6000_XIOCTL_AP_GET_STA_LIST               99
-
-#define AR6000_XIOCTL_AP_HIDDEN_SSID                100
-
-#define AR6000_XIOCTL_AP_SET_NUM_STA                101
-
-#define AR6000_XIOCTL_AP_SET_ACL_MAC                102
-
-#define AR6000_XIOCTL_AP_GET_ACL_LIST               103
-
-#define AR6000_XIOCTL_AP_COMMIT_CONFIG              104
-
-#define IEEE80211_IOCTL_GETWPAIE                    105
-
-#define AR6000_XIOCTL_AP_CONN_INACT_TIME            106
-
-#define AR6000_XIOCTL_AP_PROT_SCAN_TIME             107
-
-#define AR6000_XIOCTL_AP_SET_COUNTRY                108
-
-#define AR6000_XIOCTL_AP_SET_DTIM                   109
-
-
-
-
-#define AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT       110
-
-#define AR6000_XIOCTL_SET_IP                        111
-
-#define AR6000_XIOCTL_AP_SET_ACL_POLICY             112
-
-#define AR6000_XIOCTL_AP_INTRA_BSS_COMM             113
-
-#define AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO        114
-
-#define AR6000_XIOCTL_MODULE_DEBUG_SET_MASK         115
-
-#define AR6000_XIOCTL_MODULE_DEBUG_GET_MASK         116
-
-#define AR6000_XIOCTL_DUMP_RCV_AGGR_STATS           117
-
-#define AR6000_XIOCTL_SET_HT_CAP                    118
-
-#define AR6000_XIOCTL_SET_HT_OP                     119
-
-#define AR6000_XIOCTL_AP_GET_STAT                   120
-
-#define AR6000_XIOCTL_SET_TX_SELECT_RATES           121
-
-#define AR6000_XIOCTL_SETUP_AGGR                    122
-
-#define AR6000_XIOCTL_ALLOW_AGGR                    123
-
-#define AR6000_XIOCTL_AP_GET_HIDDEN_SSID            124
-
-#define AR6000_XIOCTL_AP_GET_COUNTRY                125
-
-#define AR6000_XIOCTL_AP_GET_WMODE                  126
-
-#define AR6000_XIOCTL_AP_GET_DTIM                   127
-
-#define AR6000_XIOCTL_AP_GET_BINTVL                 128
-
-#define AR6000_XIOCTL_AP_GET_RTS                    129
-
-#define AR6000_XIOCTL_DELE_AGGR                     130
-
-#define AR6000_XIOCTL_FETCH_TARGET_REGS             131
-
-#define AR6000_XIOCTL_HCI_CMD                       132
-
-#define AR6000_XIOCTL_ACL_DATA                      133 /* used to be used for PAL */
-
-#define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE          134
-
-#define AR6000_XIOCTL_AP_SET_11BG_RATESET           135
-
-/*
- * arguments:
- *   WMI_AP_PS_CMD apPsCmd
- * uses: WMI_AP_PS_CMDID
- */
-
-#define AR6000_XIOCTL_WMI_SET_AP_PS                 136
-
-#define AR6000_XIOCTL_WMI_MCAST_FILTER              137
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT                                    138
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV                  139
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG     140
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG                                141
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG                               142
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG                    143
-
-#define AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG                                             144
-
-#define AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS                      145
-
-#define AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG                                    146
-
-#define AR6000_XIOCTL_WMI_GET_BTCOEX_STATS                                             147
-/*
- * arguments:
- *   UINT32 cmd (AR6000_XIOCTL_WMI_SET_QOS_SUPP)
- *   UINT8  mode
- * uses: WMI_SET_QOS_SUPP_CMDID
- */
-#define AR6000_XIOCTL_WMI_SET_QOS_SUPP                  148 
-
-#define AR6000_XIOCTL_GET_WLAN_SLEEP_STATE              149
-
-#define AR6000_XIOCTL_SET_BT_HW_POWER_STATE             150 
-
-#define AR6000_XIOCTL_GET_BT_HW_POWER_STATE             151
-
-#define AR6000_XIOCTL_ADD_AP_INTERFACE                  152
-
-#define AR6000_XIOCTL_REMOVE_AP_INTERFACE               153
-
-#define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM              154
-
-#define AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES     161
-
-/* used by AR6000_IOCTL_WMI_GETREV */
-struct ar6000_version {
-    u32 host_ver;
-    u32 target_ver;
-    u32 wlan_ver;
-    u32 abi_ver;
-};
-
-/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */
-struct ar6000_queuereq {
-    u8 trafficClass;
-    u16 activeTsids;
-};
-
-/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */
-typedef struct targetStats_t {
-    u64 tx_packets;
-    u64 tx_bytes;
-    u64 tx_unicast_pkts;
-    u64 tx_unicast_bytes;
-    u64 tx_multicast_pkts;
-    u64 tx_multicast_bytes;
-    u64 tx_broadcast_pkts;
-    u64 tx_broadcast_bytes;
-    u64 tx_rts_success_cnt;
-    u64 tx_packet_per_ac[4];
-
-    u64 tx_errors;
-    u64 tx_failed_cnt;
-    u64 tx_retry_cnt;
-    u64 tx_mult_retry_cnt;
-    u64 tx_rts_fail_cnt;
-
-    u64 rx_packets;
-    u64 rx_bytes;
-    u64 rx_unicast_pkts;
-    u64 rx_unicast_bytes;
-    u64 rx_multicast_pkts;
-    u64 rx_multicast_bytes;
-    u64 rx_broadcast_pkts;
-    u64 rx_broadcast_bytes;
-    u64 rx_fragment_pkt;
-
-    u64 rx_errors;
-    u64 rx_crcerr;
-    u64 rx_key_cache_miss;
-    u64 rx_decrypt_err;
-    u64 rx_duplicate_frames;
-
-    u64 tkip_local_mic_failure;
-    u64 tkip_counter_measures_invoked;
-    u64 tkip_replays;
-    u64 tkip_format_errors;
-    u64 ccmp_format_errors;
-    u64 ccmp_replays;
-
-    u64 power_save_failure_cnt;
-
-    u64 cs_bmiss_cnt;
-    u64 cs_lowRssi_cnt;
-    u64 cs_connect_cnt;
-    u64 cs_disconnect_cnt;
-
-    s32 tx_unicast_rate;
-    s32 rx_unicast_rate;
-
-    u32 lq_val;
-
-    u32 wow_num_pkts_dropped;
-    u16 wow_num_events_discarded;
-
-    s16 noise_floor_calibation;
-    s16 cs_rssi;
-    s16 cs_aveBeacon_rssi;
-    u8 cs_aveBeacon_snr;
-    u8 cs_lastRoam_msec;
-    u8 cs_snr;
-
-    u8 wow_num_host_pkt_wakeups;
-    u8 wow_num_host_event_wakeups;
-
-    u32 arp_received;
-    u32 arp_matched;
-    u32 arp_replied;
-}TARGET_STATS;
-
-typedef struct targetStats_cmd_t {
-    TARGET_STATS targetStats;
-    int clearStats;
-} TARGET_STATS_CMD;
-
-/* used by AR6000_XIOCTL_USER_SETKEYS */
-
-/*
- * Setting this bit to 1 doesnot initialize the RSC on the firmware
- */
-#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL    1
-#define AR6000_USER_SETKEYS_RSC_UNCHANGED     0x00000002
-
-struct ar6000_user_setkeys_info {
-    u32 keyOpCtrl;  /* Bit Map of Key Mgmt Ctrl Flags */
-}; /* XXX: unused !? */
-
-/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */
-struct ar6000_gpio_output_set_cmd_s {
-    u32 set_mask;
-    u32 clear_mask;
-    u32 enable_mask;
-    u32 disable_mask;
-};
-
-/*
- * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET
- */
-struct ar6000_gpio_register_cmd_s {
-    u32 gpioreg_id;
-    u32 value;
-};
-
-/* used by AR6000_XIOCTL_GPIO_INTR_ACK */
-struct ar6000_gpio_intr_ack_cmd_s {
-    u32 ack_mask;
-};
-
-/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */
-struct ar6000_gpio_intr_wait_cmd_s {
-    u32 intr_mask;
-    u32 input_values;
-};
-
-/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */
-typedef struct ar6000_dbglog_module_config_s {
-    u32 valid;
-    u16 mmask;
-    u16 tsr;
-    u32   rep;
-    u16 size;
-} DBGLOG_MODULE_CONFIG;
-
-typedef struct user_rssi_thold_t {
-    s16 tag;
-    s16 rssi;
-} USER_RSSI_THOLD;
-
-typedef struct user_rssi_params_t {
-    u8 weight;
-    u32 pollTime;
-    USER_RSSI_THOLD    tholds[12];
-} USER_RSSI_PARAMS;
-
-typedef struct ar6000_get_btcoex_config_cmd_t{
-       u32 btProfileType;
-       u32 linkId;
- }AR6000_GET_BTCOEX_CONFIG_CMD;
-
-typedef struct ar6000_btcoex_config_t {
-    AR6000_GET_BTCOEX_CONFIG_CMD  configCmd;
-    u32 *configEvent;
-} AR6000_BTCOEX_CONFIG;
-
-typedef struct ar6000_btcoex_stats_t {
-    u32 *statsEvent;
- }AR6000_BTCOEX_STATS;
-/*
- * Host driver may have some config parameters. Typically, these
- * config params are one time config parameters. These could
- * correspond to any of the underlying modules. Host driver exposes
- * an api for the underlying modules to get this config.
- */
-#define AR6000_DRIVER_CFG_BASE                  0x8000
-
-/* Should driver perform wlan node caching? */
-#define AR6000_DRIVER_CFG_GET_WLANNODECACHING   0x8001
-/*Should we log raw WMI msgs */
-#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS      0x8002
-
-/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */
-struct ar6000_diag_window_cmd_s {
-    unsigned int addr;
-    unsigned int value;
-};
-
-
-struct ar6000_traffic_activity_change {
-    u32 StreamID;   /* stream ID to indicate activity change */
-    u32 Active;     /* active (1) or inactive (0) */
-};
-
-/* Used with AR6000_XIOCTL_PROF_COUNT_GET */
-struct prof_count_s {
-    u32 addr;       /* bin start address */
-    u32 count;      /* hit count */
-};
-
-
-/* used by AR6000_XIOCTL_MODULE_DEBUG_SET_MASK */
-/*         AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */
-/*         AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */
-struct drv_debug_module_s {
-    char modulename[128];   /* name of module */
-    u32 mask;              /* new mask to set .. or .. current mask */
-};
-
-
-/* All HCI related rx events are sent up to the host app
- * via a wmi event id. It can contain ACL data or HCI event, 
- * based on which it will be de-multiplexed.
- */
-typedef enum {
-    PAL_HCI_EVENT = 0,
-    PAL_HCI_RX_DATA,
-} WMI_PAL_EVENT_INFO;
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
deleted file mode 100644 (file)
index d525320..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _AR6K_CFG80211_H_
-#define _AR6K_CFG80211_H_
-
-struct wireless_dev *ar6k_cfg80211_init(struct device *dev);
-void ar6k_cfg80211_deinit(struct ar6_softc *ar);
-
-void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status);
-
-void ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
-                                u8 *bssid, u16 listenInterval,
-                                u16 beaconInterval,NETWORK_TYPE networkType,
-                                u8 beaconIeLen, u8 assocReqLen,
-                                u8 assocRespLen, u8 *assocInfo);
-
-void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
-                                    u8 *bssid, u8 assocRespLen,
-                                    u8 *assocInfo, u16 protocolReasonStatus);
-
-void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast);
-
-#ifdef CONFIG_NL80211_TESTMODE
-void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
-                                    int buf_len);
-#else
-static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar,
-                                                  void *buf, int buf_len) 
-{
-}
-#endif
-
-
-#endif /* _AR6K_CFG80211_H_ */
-
-
-
-
-
-
diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h
deleted file mode 100644 (file)
index dbbe1a0..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _CONFIG_LINUX_H_
-#define _CONFIG_LINUX_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Host side Test Command support
- */
-#define CONFIG_HOST_TCMD_SUPPORT
-
-#define USE_4BYTE_REGISTER_ACCESS
-
-/* Host-side support for Target-side profiling */
-#undef CONFIG_TARGET_PROFILE_SUPPORT
-
-/* IP/TCP checksum offload */
-/* Checksum offload is currently not supported for 64 bit platforms */
-#ifndef __LP64__
-#define CONFIG_CHECKSUM_OFFLOAD
-#endif /* __LP64__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/debug_linux.h b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
deleted file mode 100644 (file)
index b8dba52..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _DEBUG_LINUX_H_
-#define _DEBUG_LINUX_H_
-
-    /* macro to remove parens */
-#define ATH_PRINTX_ARG(arg...) arg
-
-#ifdef DEBUG
-    /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros
-     * which may be compiler dependent. */
-#define AR_DEBUG_PRINTF(mask, args) do {        \
-    if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) {                    \
-        A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args);    \
-    }                                            \
-} while (0)
-#else
-    /* on non-debug builds, keep in error and warning messages in the driver, all other
-     * message tracing will get compiled out */
-#define AR_DEBUG_PRINTF(mask, args) \
-    if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); }
-
-#endif
-
-    /* compile specific macro to get the function name string */
-#define _A_FUNCNAME_  __func__
-
-
-#endif /* _DEBUG_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
deleted file mode 100644 (file)
index 74f9861..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// HCI bridge implementation
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "hci_transport_api.h"
-#include "common_drv.h"
-
-extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo);
-extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
-extern int    (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue);
-extern int    (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous);
-extern void        (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
-extern int    (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
-extern int    (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
-extern int    (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
-                                          struct htc_packet           *pPacket,
-                                          int                  MaxPollMS);
-extern int    (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud);
-extern int    (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable);
-
-
-#define HCI_TransportAttach(HTCHandle, pInfo)   \
-            _HCI_TransportAttach((HTCHandle), (pInfo))
-#define HCI_TransportDetach(HciTrans)    \
-            _HCI_TransportDetach(HciTrans)
-#define HCI_TransportAddReceivePkts(HciTrans, pQueue)   \
-            _HCI_TransportAddReceivePkts((HciTrans), (pQueue))
-#define HCI_TransportSendPkt(HciTrans, pPacket, Synchronous)  \
-            _HCI_TransportSendPkt((HciTrans), (pPacket), (Synchronous))
-#define HCI_TransportStop(HciTrans)  \
-            _HCI_TransportStop((HciTrans))
-#define HCI_TransportStart(HciTrans)  \
-            _HCI_TransportStart((HciTrans))
-#define HCI_TransportEnableDisableAsyncRecv(HciTrans, Enable)   \
-            _HCI_TransportEnableDisableAsyncRecv((HciTrans), (Enable))
-#define HCI_TransportRecvHCIEventSync(HciTrans, pPacket, MaxPollMS)   \
-            _HCI_TransportRecvHCIEventSync((HciTrans), (pPacket), (MaxPollMS))
-#define HCI_TransportSetBaudRate(HciTrans, Baud)    \
-            _HCI_TransportSetBaudRate((HciTrans), (Baud))
-#define HCI_TransportEnablePowerMgmt(HciTrans, Enable)    \
-            _HCI_TransportEnablePowerMgmt((HciTrans), (Enable))
-
-
-extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks);
-
-extern int ar6000_get_hif_dev(struct hif_device *device, void *config);
-
-extern int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step);
-
-/* get core clock register settings
- * data: 0 - 40/44MHz
- *       1 - 80/88MHz
- *       where (5G band/2.4G band)
- * assume 2.4G band for now
- */
-extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data);
diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
deleted file mode 100644 (file)
index e6e96de..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _IEEE80211_IOCTL_H_
-#define _IEEE80211_IOCTL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Extracted from the MADWIFI net80211/ieee80211_ioctl.h
- */
-
-/*
- * WPA/RSN get/set key request.  Specify the key/cipher
- * type and whether the key is to be used for sending and/or
- * receiving.  The key index should be set only when working
- * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
- * Otherwise a unicast/pairwise key is specified by the bssid
- * (on a station) or mac address (on an ap).  They key length
- * must include any MIC key data; otherwise it should be no
- more than IEEE80211_KEYBUF_SIZE.
- */
-struct ieee80211req_key {
-    u_int8_t    ik_type;    /* key/cipher type */
-    u_int8_t    ik_pad;
-    u_int16_t   ik_keyix;   /* key index */
-    u_int8_t    ik_keylen;  /* key length in bytes */
-    u_int8_t    ik_flags;
-#define IEEE80211_KEY_XMIT  0x01
-#define IEEE80211_KEY_RECV  0x02
-#define IEEE80211_KEY_DEFAULT   0x80    /* default xmit key */
-    u_int8_t    ik_macaddr[IEEE80211_ADDR_LEN];
-    u_int64_t   ik_keyrsc;  /* key receive sequence counter */
-    u_int64_t   ik_keytsc;  /* key transmit sequence counter */
-    u_int8_t    ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
-};
-/*
- * Delete a key either by index or address.  Set the index
- * to IEEE80211_KEYIX_NONE when deleting a unicast key.
- */
-struct ieee80211req_del_key {
-    u_int8_t    idk_keyix;  /* key index */
-    u_int8_t    idk_macaddr[IEEE80211_ADDR_LEN];
-};
-/*
- * MLME state manipulation request.  IEEE80211_MLME_ASSOC
- * only makes sense when operating as a station.  The other
- * requests can be used when operating as a station or an
- * ap (to effect a station).
- */
-struct ieee80211req_mlme {
-    u_int8_t    im_op;      /* operation to perform */
-#define IEEE80211_MLME_ASSOC        1   /* associate station */
-#define IEEE80211_MLME_DISASSOC     2   /* disassociate station */
-#define IEEE80211_MLME_DEAUTH       3   /* deauthenticate station */
-#define IEEE80211_MLME_AUTHORIZE    4   /* authorize station */
-#define IEEE80211_MLME_UNAUTHORIZE  5   /* unauthorize station */
-    u_int16_t   im_reason;  /* 802.11 reason code */
-    u_int8_t    im_macaddr[IEEE80211_ADDR_LEN];
-};
-
-struct ieee80211req_addpmkid {
-    u_int8_t    pi_bssid[IEEE80211_ADDR_LEN];
-    u_int8_t    pi_enable;
-    u_int8_t    pi_pmkid[16];
-};
-
-#define AUTH_ALG_OPEN_SYSTEM    0x01
-#define AUTH_ALG_SHARED_KEY 0x02
-#define AUTH_ALG_LEAP       0x04
-
-struct ieee80211req_authalg {
-   u_int8_t auth_alg;
-};  
-
-/* 
- * Request to add an IE to a Management Frame
- */
-enum{
-    IEEE80211_APPIE_FRAME_BEACON     = 0,
-    IEEE80211_APPIE_FRAME_PROBE_REQ  = 1,
-    IEEE80211_APPIE_FRAME_PROBE_RESP = 2,
-    IEEE80211_APPIE_FRAME_ASSOC_REQ  = 3,
-    IEEE80211_APPIE_FRAME_ASSOC_RESP = 4,
-    IEEE80211_APPIE_NUM_OF_FRAME     = 5
-};
-
-/*
- * The Maximum length of the IE that can be added to a Management frame
- */
-#define IEEE80211_APPIE_FRAME_MAX_LEN  200
-
-struct ieee80211req_getset_appiebuf {
-    u_int32_t app_frmtype; /* management frame type for which buffer is added */
-    u_int32_t app_buflen;  /*application supplied buffer length */
-    u_int8_t  app_buf[];
-};
-
-/* 
- * The following definitions are used by an application to set filter
- * for receiving management frames 
- */
-enum {
-     IEEE80211_FILTER_TYPE_BEACON      =   0x1,
-     IEEE80211_FILTER_TYPE_PROBE_REQ   =   0x2,
-     IEEE80211_FILTER_TYPE_PROBE_RESP  =   0x4,
-     IEEE80211_FILTER_TYPE_ASSOC_REQ   =   0x8,
-     IEEE80211_FILTER_TYPE_ASSOC_RESP  =   0x10,
-     IEEE80211_FILTER_TYPE_AUTH        =   0x20,
-     IEEE80211_FILTER_TYPE_DEAUTH      =   0x40,
-     IEEE80211_FILTER_TYPE_DISASSOC    =   0x80,
-     IEEE80211_FILTER_TYPE_ALL         =   0xFF  /* used to check the valid filter bits */
-};
-
-struct ieee80211req_set_filter {
-      u_int32_t app_filterype; /* management frame filter type */
-};
-
-enum {
-    IEEE80211_PARAM_AUTHMODE = 3,   /* Authentication Mode */
-    IEEE80211_PARAM_MCASTCIPHER = 5,
-    IEEE80211_PARAM_MCASTKEYLEN = 6,    /* multicast key length */
-    IEEE80211_PARAM_UCASTCIPHER = 8,
-    IEEE80211_PARAM_UCASTKEYLEN = 9,    /* unicast key length */
-    IEEE80211_PARAM_WPA     = 10,   /* WPA mode (0,1,2) */
-    IEEE80211_PARAM_ROAMING     = 12,   /* roaming mode */
-    IEEE80211_PARAM_PRIVACY     = 13,   /* privacy invoked */
-    IEEE80211_PARAM_COUNTERMEASURES = 14,   /* WPA/TKIP countermeasures */
-    IEEE80211_PARAM_DROPUNENCRYPTED = 15,   /* discard unencrypted frames */
-    IEEE80211_PARAM_WAPI = 16,   /* WAPI policy from wapid */        
-};
-
-/*
- * Values for IEEE80211_PARAM_WPA
- */
-#define WPA_MODE_WPA1   1
-#define WPA_MODE_WPA2   2
-#define WPA_MODE_AUTO   3
-#define WPA_MODE_NONE   4
-
-struct ieee80211req_wpaie {
-    u_int8_t    wpa_macaddr[IEEE80211_ADDR_LEN];
-    u_int8_t    wpa_ie[IEEE80211_MAX_IE];
-    u_int8_t    rsn_ie[IEEE80211_MAX_IE];
-};
-
-#ifndef IW_ENCODE_ALG_PMK
-#define IW_ENCODE_ALG_PMK       4
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _IEEE80211_IOCTL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
deleted file mode 100644 (file)
index 41f4373..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-//------------------------------------------------------------------------------
-// This file contains the definitions of the basic atheros data types.
-// It is used to map the data types in atheros files to a platform specific
-// type.
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _OSAPI_LINUX_H_
-#define _OSAPI_LINUX_H_
-
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/semaphore.h>
-#include <linux/cache.h>
-
-#ifdef __GNUC__
-#define __ATTRIB_PACK           __attribute__ ((packed))
-#define __ATTRIB_PRINTF         __attribute__ ((format (printf, 1, 2)))
-#define __ATTRIB_NORETURN       __attribute__ ((noreturn))
-#ifndef INLINE
-#define INLINE                  __inline__
-#endif
-#else /* Not GCC */
-#define __ATTRIB_PACK
-#define __ATTRIB_PRINTF
-#define __ATTRIB_NORETURN
-#ifndef INLINE
-#define INLINE                  __inline
-#endif
-#endif /* End __GNUC__ */
-
-#define PREPACK
-#define POSTPACK                __ATTRIB_PACK
-
-/*
- * Endianes macros
- */
-#define A_BE2CPU8(x)       ntohb(x)
-#define A_BE2CPU16(x)      ntohs(x)
-#define A_BE2CPU32(x)      ntohl(x)
-
-#define A_LE2CPU8(x)       (x)
-#define A_LE2CPU16(x)      (x)
-#define A_LE2CPU32(x)      (x)
-
-#define A_CPU2BE8(x)       htonb(x)
-#define A_CPU2BE16(x)      htons(x)
-#define A_CPU2BE32(x)      htonl(x)
-
-#define A_MEMZERO(addr, len)            memset(addr, 0, len)
-#define A_MALLOC(size)                  kmalloc((size), GFP_KERNEL)
-#define A_MALLOC_NOWAIT(size)           kmalloc((size), GFP_ATOMIC)
-
-#define A_LOGGER(mask, mod, args...)    printk(KERN_ALERT args)
-#define A_PRINTF(args...)               printk(KERN_ALERT args)
-
-#define A_PRINTF_LOG(args...)           printk(args)
-#define A_SPRINTF(buf, args...)                        sprintf (buf, args)
-
-/* Mutual Exclusion */
-typedef spinlock_t                      A_MUTEX_T;
-#define A_MUTEX_INIT(mutex)             spin_lock_init(mutex)
-#define A_MUTEX_LOCK(mutex)             spin_lock_bh(mutex)
-#define A_MUTEX_UNLOCK(mutex)           spin_unlock_bh(mutex)
-#define A_IS_MUTEX_VALID(mutex)         true  /* okay to return true, since A_MUTEX_DELETE does nothing */
-#define A_MUTEX_DELETE(mutex)           /* spin locks are not kernel resources so nothing to free.. */
-
-/* Get current time in ms adding a constant offset (in ms) */
-#define A_GET_MS(offset)    \
-       (((jiffies / HZ) * 1000) + (offset))
-
-/*
- * Timer Functions
- */
-#define A_MDELAY(msecs)                 mdelay(msecs)
-typedef struct timer_list               A_TIMER;
-
-#define A_INIT_TIMER(pTimer, pFunction, pArg) do {              \
-    init_timer(pTimer);                                         \
-    (pTimer)->function = (pFunction);                           \
-    (pTimer)->data   = (unsigned long)(pArg);                   \
-} while (0)
-
-/*
- * Start a Timer that elapses after 'periodMSec' milli-seconds
- * Support is provided for a one-shot timer. The 'repeatFlag' is
- * ignored.
- */
-#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do {                   \
-    if (repeatFlag) {                                                       \
-        printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__);     \
-        panic("Timer Repeat");                                              \
-    }                                                                       \
-    mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000);                \
-} while (0)
-
-/*
- * Cancel the Timer. 
- */
-#define A_UNTIMEOUT(pTimer) do {                                \
-    del_timer((pTimer));                                        \
-} while (0)
-
-#define A_DELETE_TIMER(pTimer) do {                             \
-} while (0)
-
-/*
- * Wait Queue related functions
- */
-typedef wait_queue_head_t               A_WAITQUEUE_HEAD;
-#define A_INIT_WAITQUEUE_HEAD(head)     init_waitqueue_head(head)
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret)          \
-do {                                                                    \
-        wait_queue_t __wait;                                            \
-        init_waitqueue_entry(&__wait, current);                         \
-                                                                        \
-        add_wait_queue(&wq, &__wait);                                   \
-        for (;;) {                                                      \
-                set_current_state(TASK_INTERRUPTIBLE);                  \
-                if (condition)                                          \
-                        break;                                          \
-                if (!signal_pending(current)) {                         \
-                        ret = schedule_timeout(ret);                    \
-                        if (!ret)                                       \
-                                break;                                  \
-                        continue;                                       \
-                }                                                       \
-                ret = -ERESTARTSYS;                                     \
-                break;                                                  \
-        }                                                               \
-        current->state = TASK_RUNNING;                                  \
-        remove_wait_queue(&wq, &__wait);                                \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout)        \
-({                                                                      \
-        long __ret = timeout;                                           \
-        if (!(condition))                                               \
-                __wait_event_interruptible_timeout(wq, condition, __ret); \
-        __ret;                                                          \
-})
-#endif /* wait_event_interruptible_timeout */
-
-#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
-    wait_event_interruptible_timeout(head, condition, timeout); \
-} while (0)
-
-#define A_WAKE_UP(head)                 wake_up(head)
-
-#ifdef DEBUG
-extern unsigned int panic_on_assert;
-#define A_ASSERT(expr)  \
-    if (!(expr)) {   \
-        printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \
-        if (panic_on_assert) panic(#expr);                                                               \
-    }
-#else
-#define A_ASSERT(expr)
-#endif /* DEBUG */
-
-#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev)
-#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
-
-/*
- * Initialization of the network buffer subsystem
- */
-#define A_NETBUF_INIT()
-
-/*
- * Network buffer queue support
- */
-typedef struct sk_buff_head A_NETBUF_QUEUE_T;
-
-#define A_NETBUF_QUEUE_INIT(q)  \
-    a_netbuf_queue_init(q)
-
-#define A_NETBUF_ENQUEUE(q, pkt) \
-    a_netbuf_enqueue((q), (pkt))
-#define A_NETBUF_PREQUEUE(q, pkt) \
-    a_netbuf_prequeue((q), (pkt))
-#define A_NETBUF_DEQUEUE(q) \
-    (a_netbuf_dequeue(q))
-#define A_NETBUF_QUEUE_SIZE(q)  \
-    a_netbuf_queue_size(q)
-#define A_NETBUF_QUEUE_EMPTY(q) \
-    (a_netbuf_queue_empty(q) ? true : false)
-
-/*
- * Network buffer support
- */
-#define A_NETBUF_ALLOC(size) \
-    a_netbuf_alloc(size)
-#define A_NETBUF_ALLOC_RAW(size) \
-    a_netbuf_alloc_raw(size)
-#define A_NETBUF_FREE(bufPtr) \
-    a_netbuf_free(bufPtr)
-#define A_NETBUF_DATA(bufPtr) \
-    a_netbuf_to_data(bufPtr)
-#define A_NETBUF_LEN(bufPtr) \
-    a_netbuf_to_len(bufPtr)
-#define A_NETBUF_PUSH(bufPtr, len) \
-    a_netbuf_push(bufPtr, len)
-#define A_NETBUF_PUT(bufPtr, len) \
-    a_netbuf_put(bufPtr, len)
-#define A_NETBUF_TRIM(bufPtr,len) \
-    a_netbuf_trim(bufPtr, len)
-#define A_NETBUF_PULL(bufPtr, len) \
-    a_netbuf_pull(bufPtr, len)
-#define A_NETBUF_HEADROOM(bufPtr)\
-    a_netbuf_headroom(bufPtr)
-#define A_NETBUF_SETLEN(bufPtr,len) \
-    a_netbuf_setlen(bufPtr, len)
-
-/* Add data to end of a buffer  */
-#define A_NETBUF_PUT_DATA(bufPtr, srcPtr,  len) \
-    a_netbuf_put_data(bufPtr, srcPtr, len) 
-
-/* Add data to start of the  buffer */
-#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr,  len) \
-    a_netbuf_push_data(bufPtr, srcPtr, len) 
-
-/* Remove data at start of the buffer */
-#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \
-    a_netbuf_pull_data(bufPtr, dstPtr, len) 
-
-/* Remove data from the end of the buffer */
-#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \
-    a_netbuf_trim_data(bufPtr, dstPtr, len) 
-
-/* View data as "size" contiguous bytes of type "t" */
-#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \
-    (t )( ((struct skbuf *)(bufPtr))->data)
-
-/* return the beginning of the headroom for the buffer */
-#define A_NETBUF_HEAD(bufPtr) \
-        ((((struct sk_buff *)(bufPtr))->head))
-    
-/*
- * OS specific network buffer access routines
- */
-void *a_netbuf_alloc(int size);
-void *a_netbuf_alloc_raw(int size);
-void a_netbuf_free(void *bufPtr);
-void *a_netbuf_to_data(void *bufPtr);
-u32 a_netbuf_to_len(void *bufPtr);
-int a_netbuf_push(void *bufPtr, s32 len);
-int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len);
-int a_netbuf_put(void *bufPtr, s32 len);
-int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len);
-int a_netbuf_pull(void *bufPtr, s32 len);
-int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len);
-int a_netbuf_trim(void *bufPtr, s32 len);
-int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len);
-int a_netbuf_setlen(void *bufPtr, s32 len);
-s32 a_netbuf_headroom(void *bufPtr);
-void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt);
-void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt);
-void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q);
-int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q);
-int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
-int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
-void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
-
-/*
- * Kernel v.s User space functions
- */
-u32 a_copy_to_user(void *to, const void *from, u32 n);
-u32 a_copy_from_user(void *to, const void *from, u32 n);
-
-/* In linux, WLAN Rx and Tx run in different contexts, so no need to check
- * for any commands/data queued for WLAN */
-#define A_CHECK_DRV_TX()   
-             
-#define A_GET_CACHE_LINE_BYTES()    L1_CACHE_BYTES
-
-#define A_CACHE_LINE_PAD            128
-
-static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) {   
-    return (void *)L1_CACHE_ALIGN((unsigned long)ptr);
-}
-   
-#else /* __KERNEL__ */
-
-#ifdef __GNUC__
-#define __ATTRIB_PACK           __attribute__ ((packed))
-#define __ATTRIB_PRINTF         __attribute__ ((format (printf, 1, 2)))
-#define __ATTRIB_NORETURN       __attribute__ ((noreturn))
-#ifndef INLINE
-#define INLINE                  __inline__
-#endif
-#else /* Not GCC */
-#define __ATTRIB_PACK
-#define __ATTRIB_PRINTF
-#define __ATTRIB_NORETURN
-#ifndef INLINE
-#define INLINE                  __inline
-#endif
-#endif /* End __GNUC__ */
-
-#define PREPACK
-#define POSTPACK                __ATTRIB_PACK
-
-#define A_MEMZERO(addr, len)            memset((addr), 0, (len))
-#define A_MALLOC(size)                  malloc(size)
-
-#include <err.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* _OSAPI_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
deleted file mode 100644 (file)
index c1fe0c6..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 tunable configuration items for the WLAN module
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _HOST_WLAN_CONFIG_H_
-#define _HOST_WLAN_CONFIG_H_
-
-/* Include definitions here that can be used to tune the WLAN module behavior.
- * Different customers can tune the behavior as per their needs, here. 
- */
-
-/* This configuration item when defined will consider the barker preamble 
- * mentioned in the ERP IE of the beacons from the AP to determine the short 
- * preamble support sent in the (Re)Assoc request frames.
- */
-#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0
-
-/* This config item when defined will not send the power module state transition
- * failure events that happen during scan, to the host. 
- */
-#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0
-
-/*
- * This configuration item enable/disable keepalive support.
- * Keepalive support: In the absence of any data traffic to AP, null 
- * frames will be sent to the AP at periodic interval, to keep the association
- * active. This configuration item defines the periodic interval.
- * Use value of zero to disable keepalive support
- * Default: 60 seconds
- */
-#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60 
-
-/*
- * This configuration item sets the value of disconnect timeout
- * Firmware delays sending the disconnec event to the host for this
- * timeout after is gets disconnected from the current AP.
- * If the firmware successly roams within the disconnect timeout
- * it sends a new connect event
- */
-#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
-
-/*
- * This configuration item disables 11n support. 
- * 0 - Enable
- * 1 - Disable
- */
-#define WLAN_CONFIG_DISABLE_11N         0
-
-/*
- * This configuration item enable BT clock sharing support
- * 1 - Enable
- * 0 - Disable (Default)
- */
-#define WLAN_CONFIG_BT_SHARING          0
-
-/*
- * This configuration item sets WIFI OFF policy
- * 0 - CUT_POWER
- * 1 - DEEP_SLEEP (Default)
- */
-#define WLAN_CONFIG_WLAN_OFF                1
-
-/*
- * This configuration item sets suspend policy
- * 0 - CUT_POWER (Default)
- * 1 - DEEP_SLEEP
- * 2 - WoW
- * 3 - CUT_POWER if BT OFF (clock sharing designs only)
- */
-#define WLAN_CONFIG_PM_SUSPEND              0
-
-/*
- * This configuration item sets suspend policy to use if PM_SUSPEND is
- * set to WoW and device is not connected at the time of suspend
- * 0 - CUT_POWER (Default)
- * 1 - DEEP_SLEEP
- * 2 - WoW
- * 3 - CUT_POWER if BT OFF (clock sharing designs only)
- */
-#define WLAN_CONFIG_PM_WOW2                 0
-
-/*
- * This configuration item enables/disables transmit bursting 
- * 0 - Enable tx Bursting (default)
- * 1 - Disable tx bursting 
- */
-#define WLAN_CONFIG_DISABLE_TX_BURSTING     0
-
-#endif /* _HOST_WLAN_CONFIG_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
deleted file mode 100644 (file)
index 1eb6f82..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _WMI_FILTER_LINUX_H_
-#define  _WMI_FILTER_LINUX_H_
-
-/*
- * sioctl_filter - Standard ioctl
- * pioctl_filter - Priv ioctl
- * xioctl_filter - eXtended ioctl
- *
- * ---- Possible values for the WMI filter ---------------
- * (0) - Block this cmd always (or) not implemented
- * (INFRA_NETWORK) - Allow this cmd only in STA mode
- * (ADHOC_NETWORK) - Allow this cmd only in IBSS mode
- * (AP_NETWORK) -    Allow this cmd only in AP mode
- * (INFRA_NETWORK | ADHOC_NETWORK) - Block this cmd in AP mode
- * (ADHOC_NETWORK | AP_NETWORK) -    Block this cmd in STA mode
- * (INFRA_NETWORK | AP_NETWORK) -    Block this cmd in IBSS mode
- * (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK)- allow only when mode is set
- * (0xFF) - Allow this cmd always irrespective of mode
- */
-
-u8 sioctl_filter[] = {
-(AP_NETWORK),                                   /* SIOCSIWCOMMIT   0x8B00   */
-(0xFF),                                         /* SIOCGIWNAME     0x8B01   */
-(0),                                            /* SIOCSIWNWID     0x8B02   */
-(0),                                            /* SIOCGIWNWID     0x8B03   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWFREQ     0x8B04   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWFREQ     0x8B05   */
-(0xFF),                                         /* SIOCSIWMODE     0x8B06   */
-(0xFF),                                         /* SIOCGIWMODE     0x8B07   */
-(0),                                            /* SIOCSIWSENS     0x8B08   */
-(0),                                            /* SIOCGIWSENS     0x8B09   */
-(0),                                            /* SIOCSIWRANGE    0x8B0A   */
-(0xFF),                                         /* SIOCGIWRANGE    0x8B0B   */
-(0),                                            /* SIOCSIWPRIV     0x8B0C   */
-(0),                                            /* SIOCGIWPRIV     0x8B0D   */
-(0),                                            /* SIOCSIWSTATS    0x8B0E   */
-(0),                                            /* SIOCGIWSTATS    0x8B0F   */
-(0),                                            /* SIOCSIWSPY      0x8B10   */
-(0),                                            /* SIOCGIWSPY      0x8B11   */
-(0),                                            /* SIOCSIWTHRSPY   0x8B12   */
-(0),                                            /* SIOCGIWTHRSPY   0x8B13   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWAP       0x8B14   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWAP       0x8B15   */
-#if (WIRELESS_EXT >= 18)
-(INFRA_NETWORK | ADHOC_NETWORK),                /* SIOCSIWMLME     0X8B16   */
-#else
-(0),                                            /* Dummy           0        */
-#endif /* WIRELESS_EXT */
-(0),                                            /* SIOCGIWAPLIST   0x8B17   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* SIOCSIWSCAN     0x8B18   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* SIOCGIWSCAN     0x8B19   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWESSID    0x8B1A   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWESSID    0x8B1B   */
-(0),                                            /* SIOCSIWNICKN    0x8B1C   */
-(0),                                            /* SIOCGIWNICKN    0x8B1D   */
-(0),                                            /* Dummy           0        */
-(0),                                            /* Dummy           0        */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWRATE     0x8B20   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWRATE     0x8B21   */
-(0),                                            /* SIOCSIWRTS      0x8B22   */
-(0),                                            /* SIOCGIWRTS      0x8B23   */
-(0),                                            /* SIOCSIWFRAG     0x8B24   */
-(0),                                            /* SIOCGIWFRAG     0x8B25   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWTXPOW    0x8B26   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWTXPOW    0x8B27   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* SIOCSIWRETRY    0x8B28   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* SIOCGIWRETRY    0x8B29   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWENCODE   0x8B2A   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWENCODE   0x8B2B   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCSIWPOWER    0x8B2C   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* SIOCGIWPOWER    0x8B2D   */
-};
-
-
-
-u8 pioctl_filter[] = {
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* IEEE80211_IOCTL_SETPARAM             (SIOCIWFIRSTPRIV+0)     */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* IEEE80211_IOCTL_SETKEY               (SIOCIWFIRSTPRIV+1)     */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* IEEE80211_IOCTL_DELKEY               (SIOCIWFIRSTPRIV+2)     */
-(AP_NETWORK),                                   /* IEEE80211_IOCTL_SETMLME              (SIOCIWFIRSTPRIV+3)     */
-(INFRA_NETWORK),                                /* IEEE80211_IOCTL_ADDPMKID             (SIOCIWFIRSTPRIV+4)     */
-(0),                                            /* IEEE80211_IOCTL_SETOPTIE             (SIOCIWFIRSTPRIV+5)     */
-(0),                                            /*                                      (SIOCIWFIRSTPRIV+6)     */
-(0),                                            /*                                      (SIOCIWFIRSTPRIV+7)     */
-(0),                                            /*                                      (SIOCIWFIRSTPRIV+8)     */
-(0),                                            /*                                      (SIOCIWFIRSTPRIV+9)     */
-(0),                                            /* IEEE80211_IOCTL_LASTONE              (SIOCIWFIRSTPRIV+10)    */
-(0xFF),                                         /* AR6000_IOCTL_WMI_GETREV              (SIOCIWFIRSTPRIV+11)    */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_IOCTL_WMI_SETPWR              (SIOCIWFIRSTPRIV+12)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SETSCAN             (SIOCIWFIRSTPRIV+13)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SETLISTENINT        (SIOCIWFIRSTPRIV+14)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SETBSSFILTER        (SIOCIWFIRSTPRIV+15)    */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_IOCTL_WMI_SET_CHANNELPARAMS   (SIOCIWFIRSTPRIV+16)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_PROBEDSSID      (SIOCIWFIRSTPRIV+17)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_PMPARAMS        (SIOCIWFIRSTPRIV+18)    */
-(INFRA_NETWORK),                                /* AR6000_IOCTL_WMI_SET_BADAP           (SIOCIWFIRSTPRIV+19)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_GET_QOS_QUEUE       (SIOCIWFIRSTPRIV+20)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_CREATE_QOS          (SIOCIWFIRSTPRIV+21)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_DELETE_QOS          (SIOCIWFIRSTPRIV+22)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_SNRTHRESHOLD    (SIOCIWFIRSTPRIV+23)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)*/
-(0xFF),                                         /* AR6000_IOCTL_WMI_GET_TARGET_STATS    (SIOCIWFIRSTPRIV+25)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_ASSOC_INFO      (SIOCIWFIRSTPRIV+26)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_ACCESS_PARAMS   (SIOCIWFIRSTPRIV+27)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_BMISS_TIME      (SIOCIWFIRSTPRIV+28)    */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_IOCTL_WMI_SET_DISC_TIMEOUT    (SIOCIWFIRSTPRIV+29)    */
-(ADHOC_NETWORK),                                /* AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS    (SIOCIWFIRSTPRIV+30)    */
-};
-
-
-
-u8 xioctl_filter[] = {
-(0xFF),                                         /* Dummy                                           0    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_DONE                          1    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_READ_MEMORY                   2    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_WRITE_MEMORY                  3    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_EXECUTE                       4    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_SET_APP_START                 5    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_READ_SOC_REGISTER             6    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER            7    */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_TEST                          8    */
-(0xFF),                                         /* AR6000_XIOCTL_UNUSED9                           9    */
-(0xFF),                                         /* AR6000_XIOCTL_UNUSED10                          10   */
-(0xFF),                                         /* AR6000_XIOCTL_UNUSED11                          11   */
-(0xFF),                                         /* AR6000_XIOCTL_FORCE_TARGET_RESET                12   */
-(0xFF),                                         /* AR6000_XIOCTL_HTC_RAW_OPEN                      13   */
-(0xFF),                                         /* AR6000_XIOCTL_HTC_RAW_CLOSE                     14   */
-(0xFF),                                         /* AR6000_XIOCTL_HTC_RAW_READ                      15   */
-(0xFF),                                         /* AR6000_XIOCTL_HTC_RAW_WRITE                     16   */
-(0xFF),                                         /* AR6000_XIOCTL_CHECK_TARGET_READY                17   */
-(0xFF),                                         /* AR6000_XIOCTL_GPIO_OUTPUT_SET                   18   */
-(0xFF),                                         /* AR6000_XIOCTL_GPIO_INPUT_GET                    19   */
-(0xFF),                                         /* AR6000_XIOCTL_GPIO_REGISTER_SET                 20   */
-(0xFF),                                         /* AR6000_XIOCTL_GPIO_REGISTER_GET                 21   */
-(0xFF),                                         /* AR6000_XIOCTL_GPIO_INTR_ACK                     22   */
-(0xFF),                                         /* AR6000_XIOCTL_GPIO_INTR_WAIT                    23   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_SET_ADHOC_BSSID                   24   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_SET_OPT_MODE                      25   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_OPT_SEND_FRAME                    26   */
-(ADHOC_NETWORK | AP_NETWORK),                   /* AR6000_XIOCTL_SET_BEACON_INTVAL                 27   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* IEEE80211_IOCTL_SETAUTHALG                      28   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_SET_VOICE_PKT_SIZE                29   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_SET_MAX_SP                        30   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_ROAM_TBL                  31   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_ROAM_CTRL                 32   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS         33   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTRL_WMI_GET_POWER_MODE               34   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTRL_WMI_SET_WLAN_STATE               35   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_ROAM_DATA                 36   */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_SETRETRYLIMITS                37   */
-(0xFF),                                         /* AR6000_XIOCTL_TCMD_CONT_TX                      38   */
-(0xFF),                                         /* AR6000_XIOCTL_TCMD_CONT_RX                      39   */
-(0xFF),                                         /* AR6000_XIOCTL_TCMD_PM                           40   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_STARTSCAN                     41   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTL_WMI_SETFIXRATES                   42   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTL_WMI_GETFIXRATES                   43   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD             44   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_CLR_RSSISNR                   45   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_LQTHRESHOLD               46   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTL_WMI_SET_RTS                       47   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTL_WMI_SET_LPREAMBLE                 48   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTL_WMI_SET_AUTHMODE                  49   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_REASSOCMODE               50   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_WMM                       51   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS  52   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP         53   */
-(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK),   /* AR6000_XIOCTL_WMI_GET_RD                        54   */
-(0xFF),                                         /* AR6000_XIOCTL_DIAG_READ                         55   */
-(0xFF),                                         /* AR6000_XIOCTL_DIAG_WRITE                        56   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_TXOP                      57   */
-(INFRA_NETWORK),                                /* AR6000_XIOCTL_USER_SETKEYS                      58   */
-(INFRA_NETWORK),                                /* AR6000_XIOCTL_WMI_SET_KEEPALIVE                 59   */
-(INFRA_NETWORK),                                /* AR6000_XIOCTL_WMI_GET_KEEPALIVE                 60   */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_ROMPATCH_INSTALL              61   */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL            62   */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE             63   */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE           64   */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_SET_APPIE                     65   */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER        66   */
-(0xFF),                                         /* AR6000_XIOCTL_DBGLOG_CFG_MODULE                 67   */
-(0xFF),                                         /* AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS             68   */
-(0xFF),                                         /* Dummy                                           69   */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_SET_WSC_STATUS                70   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BT_STATUS                 71   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BT_PARAMS                 72   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE           73   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_WOW_MODE                  74   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_WOW_LIST                  75   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_ADD_WOW_PATTERN               76   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_DEL_WOW_PATTERN               77   */
-(0xFF),                                         /* AR6000_XIOCTL_TARGET_INFO                       78   */
-(0xFF),                                         /* AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE             79   */
-(0xFF),                                         /* AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE           80   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS        81   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_AKMP_PARAMS               82   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_PMKID_LIST                83   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_PMKID_LIST                84   */
-(0xFF),                                         /* Dummy                                           85   */
-(0xFF),                                         /* Dummy                                           86   */
-(0xFF),                                         /* Dummy                                           87   */
-(0xFF),                                         /* Dummy                                           88   */
-(0xFF),                                         /* Dummy                                           89   */
-(0xFF),                                         /* AR6000_XIOCTL_UNUSED90                          90   */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_LZ_STREAM_START               91   */
-(0xFF),                                         /* AR6000_XIOCTL_BMI_LZ_DATA                       92   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_PROF_CFG                          93   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_PROF_ADDR_SET                     94   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_PROF_START                        95   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_PROF_STOP                         96   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_PROF_COUNT_GET                    97   */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_ABORT_SCAN                    98   */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_STA_LIST                   99   */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_HIDDEN_SSID                    100  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_SET_NUM_STA                    101  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_SET_ACL_MAC                    102  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_ACL_LIST                   103  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_COMMIT_CONFIG                  104  */
-(AP_NETWORK),                                   /* IEEE80211_IOCTL_GETWPAIE                        105  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_CONN_INACT_TIME                106  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_PROT_SCAN_TIME                 107  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_WMI_SET_COUNTRY                   108  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_SET_DTIM                       109  */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT           110  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_SET_IP                            111  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_SET_ACL_POLICY                 112  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_INTRA_BSS_COMM                 113  */
-(0xFF),                                         /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO            114  */
-(0xFF),                                         /* AR6000_XIOCTL_MODULE_DEBUG_SET_MASK             115  */
-(0xFF),                                         /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK             116  */
-(0xFF),                                         /* AR6000_XIOCTL_DUMP_RCV_AGGR_STATS               117  */
-(0xFF),                                         /* AR6000_XIOCTL_SET_HT_CAP                        118  */
-(0xFF),                                         /* AR6000_XIOCTL_SET_HT_OP                         119  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_STAT                       120  */
-(0xFF),                                         /* AR6000_XIOCTL_SET_TX_SELECT_RATES               121  */
-(0xFF),                                         /* AR6000_XIOCTL_SETUP_AGGR                        122  */
-(0xFF),                                         /* AR6000_XIOCTL_ALLOW_AGGR                        123  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_HIDDEN_SSID                124  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_COUNTRY                    125  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_WMODE                      126  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_GET_DTIM                       127  */
-(AP_NETWORK | ADHOC_NETWORK),                   /* AR6000_XIOCTL_AP_GET_BINTVL                     128  */
-(0xFF),                                         /* AR6000_XIOCTL_AP_GET_RTS                        129  */
-(0xFF),                                         /* AR6000_XIOCTL_DELE_AGGR                         130  */
-(0xFF),                                         /* AR6000_XIOCTL_FETCH_TARGET_REGS                 131  */
-(0xFF),                                         /* AR6000_XIOCTL_HCI_CMD                           132  */
-(0xFF),                                         /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133  */
-(0xFF),                                         /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE              134  */
-(AP_NETWORK),                                   /* AR6000_XIOCTL_AP_SET_11BG_RATESET               135  */
-(0xFF),
-(0xFF),
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT             138  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV   139  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG  140  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG         141  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG        142  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG     143  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG              144  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS       145  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG             146  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_GET_BTCOEX_GET_STATS          147  */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_SET_QOS_SUPP                  148  */
-(0xFF),                                         /* AR6000_XIOCTL_GET_WLAN_SLEEP_STATE              149  */
-(0xFF),                                         /* AR6000_XIOCTL_SET_BT_HW_POWER_STATE             150  */
-(0xFF),                                         /* AR6000_XIOCTL_GET_BT_HW_POWER_STATE             151  */
-(0xFF),                                         /* AR6000_XIOCTL_ADD_AP_INTERFACE                  152  */
-(0xFF),                                         /* AR6000_XIOCTL_REMOVE_AP_INTERFACE               153  */
-(0xFF),                                         /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM              154  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_WPA_OFFLOAD_STATE         155  */
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_PASSPHRASE                156  */
-(0xFF),
-(0xFF),
-(0xFF),
-(0xFF),
-(INFRA_NETWORK | ADHOC_NETWORK),                /* AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES     161  */
-};
-
-#endif /*_WMI_FILTER_LINUX_H_*/
diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c
deleted file mode 100644 (file)
index 963a2fb..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-#include <a_config.h>
-#include "athdefs.h"
-#include "a_osapi.h"
-#include "htc_packet.h"
-
-#define AR6000_DATA_OFFSET    64
-
-void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt)
-{
-    skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt);
-}
-
-void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt)
-{
-    skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt);
-}
-
-void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q)
-{
-    return((void *) skb_dequeue((struct sk_buff_head *) q));
-}
-
-int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q)
-{
-    return(skb_queue_len((struct sk_buff_head *) q));
-}
-
-int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q)
-{
-    return(skb_queue_empty((struct sk_buff_head *) q));
-}
-
-void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q)
-{
-    skb_queue_head_init((struct sk_buff_head *) q);
-}
-
-void *
-a_netbuf_alloc(int size)
-{
-    struct sk_buff *skb;
-    size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */
-    skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(struct htc_packet) + size);
-    skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(struct htc_packet) + A_GET_CACHE_LINE_BYTES());    
-    return ((void *)skb);
-}
-
-/*
- * Allocate an SKB w.o. any encapsulation requirement.
- */
-void *
-a_netbuf_alloc_raw(int size)
-{
-    struct sk_buff *skb;
-
-    skb = dev_alloc_skb(size);
-
-    return ((void *)skb);
-}
-
-void
-a_netbuf_free(void *bufPtr)
-{
-    struct sk_buff *skb = (struct sk_buff *)bufPtr;
-
-    dev_kfree_skb(skb);
-}
-
-u32 a_netbuf_to_len(void *bufPtr)
-{
-    return (((struct sk_buff *)bufPtr)->len);
-}
-
-void *
-a_netbuf_to_data(void *bufPtr)
-{
-    return (((struct sk_buff *)bufPtr)->data);
-}
-
-/*
- * Add len # of bytes to the beginning of the network buffer
- * pointed to by bufPtr
- */
-int
-a_netbuf_push(void *bufPtr, s32 len)
-{
-    skb_push((struct sk_buff *)bufPtr, len);
-
-    return 0;
-}
-
-/*
- * Add len # of bytes to the beginning of the network buffer
- * pointed to by bufPtr and also fill with data
- */
-int
-a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len)
-{
-    skb_push((struct sk_buff *) bufPtr, len);
-    memcpy(((struct sk_buff *)bufPtr)->data, srcPtr, len);
-
-    return 0;
-}
-
-/*
- * Add len # of bytes to the end of the network buffer
- * pointed to by bufPtr
- */
-int
-a_netbuf_put(void *bufPtr, s32 len)
-{
-    skb_put((struct sk_buff *)bufPtr, len);
-
-    return 0;
-}
-
-/*
- * Add len # of bytes to the end of the network buffer
- * pointed to by bufPtr and also fill with data
- */
-int
-a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len)
-{
-    char *start = (char*)(((struct sk_buff *)bufPtr)->data +
-        ((struct sk_buff *)bufPtr)->len);
-    skb_put((struct sk_buff *)bufPtr, len);
-    memcpy(start, srcPtr, len);
-
-    return 0;
-}
-
-
-/*
- * Trim the network buffer pointed to by bufPtr to len # of bytes 
- */
-int
-a_netbuf_setlen(void *bufPtr, s32 len)
-{
-    skb_trim((struct sk_buff *)bufPtr, len);
-
-    return 0;
-}
-
-/*
- * Chop of len # of bytes from the end of the buffer.
- */
-int
-a_netbuf_trim(void *bufPtr, s32 len)
-{
-    skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
-
-    return 0;
-}
-
-/*
- * Chop of len # of bytes from the end of the buffer and return the data.
- */
-int
-a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len)
-{
-    char *start = (char*)(((struct sk_buff *)bufPtr)->data +
-        (((struct sk_buff *)bufPtr)->len - len));
-    
-    memcpy(dstPtr, start, len);
-    skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
-
-    return 0;
-}
-
-
-/*
- * Returns the number of bytes available to a a_netbuf_push()
- */
-s32 a_netbuf_headroom(void *bufPtr)
-{
-    return (skb_headroom((struct sk_buff *)bufPtr));
-}
-
-/*
- * Removes specified number of bytes from the beginning of the buffer
- */
-int
-a_netbuf_pull(void *bufPtr, s32 len)
-{
-    skb_pull((struct sk_buff *)bufPtr, len);
-
-    return 0;
-}
-
-/*
- * Removes specified number of bytes from the beginning of the buffer
- * and return the data
- */
-int
-a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len)
-{
-    memcpy(dstPtr, ((struct sk_buff *)bufPtr)->data, len);
-    skb_pull((struct sk_buff *)bufPtr, len);
-
-    return 0;
-}
-
-#ifdef EXPORT_HCI_BRIDGE_INTERFACE
-EXPORT_SYMBOL(a_netbuf_to_data);
-EXPORT_SYMBOL(a_netbuf_put);
-EXPORT_SYMBOL(a_netbuf_pull);
-EXPORT_SYMBOL(a_netbuf_alloc);
-EXPORT_SYMBOL(a_netbuf_free);
-#endif
diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
deleted file mode 100644 (file)
index 1112596..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * 
-//
-// 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 __AGGR_RX_INTERNAL_H__
-#define __AGGR_RX_INTERNAL_H__
-
-#include "a_osapi.h"
-#include "aggr_recv_api.h"
-
-#define AGGR_WIN_IDX(x, y)          ((x) % (y))
-#define AGGR_INCR_IDX(x, y)         AGGR_WIN_IDX(((x)+1), (y))
-#define AGGR_DCRM_IDX(x, y)         AGGR_WIN_IDX(((x)-1), (y))
-#define IEEE80211_MAX_SEQ_NO        0xFFF
-#define IEEE80211_NEXT_SEQ_NO(x)    (((x) + 1) & IEEE80211_MAX_SEQ_NO)
-
-
-#define NUM_OF_TIDS         8
-#define AGGR_SZ_DEFAULT     8
-
-#define AGGR_WIN_SZ_MIN     2
-#define AGGR_WIN_SZ_MAX     8
-/* TID Window sz is double of what is negotiated. Derive TID_WINDOW_SZ from win_sz, per tid */
-#define TID_WINDOW_SZ(_x)   ((_x) << 1)
-
-#define AGGR_NUM_OF_FREE_NETBUFS    16
-
-#define AGGR_GET_RXTID_STATS(_p, _x)    (&(_p->stat[(_x)]))
-#define AGGR_GET_RXTID(_p, _x)    (&(_p->RxTid[(_x)]))
-
-/* Hold q is a function of win_sz, which is negotiated per tid */
-#define HOLD_Q_SZ(_x)   (TID_WINDOW_SZ((_x))*sizeof(struct osbuf_hold_q))
-/* AGGR_RX_TIMEOUT value is important as a (too) small value can cause frames to be 
- * delivered out of order and a (too) large value can cause undesirable latency in
- * certain situations. */
-#define AGGR_RX_TIMEOUT     400  /* Timeout(in ms) for delivery of frames, if they are stuck */
-
-typedef enum {
-    ALL_SEQNO = 0,
-    CONTIGUOUS_SEQNO = 1,
-}DELIVERY_ORDER;
-
-struct osbuf_hold_q {
-    void        *osbuf;
-    bool      is_amsdu;
-    u16 seq_no;
-};
-
-
-#if 0
-/* XXX: unused ? */
-struct window_snapshot {
-    u16 seqno_st;
-    u16 seqno_end;
-};
-#endif
-
-struct rxtid {
-    bool              aggr;       /* is it ON or OFF */
-    bool              progress;   /* true when frames have arrived after a timer start */
-    bool              timerMon;   /* true if the timer started for the sake of this TID */
-    u16 win_sz;     /* negotiated window size */
-    u16 seq_next;   /* Next seq no, in current window */
-    u32 hold_q_sz;  /* Num of frames that can be held in hold q */
-    struct osbuf_hold_q        *hold_q;    /* Hold q for re-order */
-#if 0    
-    struct window_snapshot     old_win;    /* Sliding window snapshot - for timeout */
-#endif    
-    A_NETBUF_QUEUE_T    q;          /* q head for enqueuing frames for dispatch */
-    A_MUTEX_T           lock;
-};
-
-struct rxtid_stats {
-    u32 num_into_aggr;      /* hitting at the input of this module */
-    u32 num_dups;           /* duplicate */
-    u32 num_oow;            /* out of window */
-    u32 num_mpdu;           /* single payload 802.3/802.11 frame */
-    u32 num_amsdu;          /* AMSDU */
-    u32 num_delivered;      /* frames delivered to IP stack */
-    u32 num_timeouts;       /* num of timeouts, during which frames delivered */
-    u32 num_hole;           /* frame not present, when window moved over */
-    u32 num_bar;            /* num of resets of seq_num, via BAR */
-};
-
-struct aggr_info {
-    u8 aggr_sz;            /* config value of aggregation size */
-    u8 timerScheduled;
-    A_TIMER             timer;              /* timer for returning held up pkts in re-order que */    
-    void                *dev;               /* dev handle */
-    RX_CALLBACK         rx_fn;              /* callback function to return frames; to upper layer */
-    struct rxtid               RxTid[NUM_OF_TIDS]; /* Per tid window */
-    ALLOC_NETBUFS       netbuf_allocator;   /* OS netbuf alloc fn */
-    A_NETBUF_QUEUE_T    freeQ;              /* pre-allocated buffers - for A_MSDU slicing */
-    struct rxtid_stats         stat[NUM_OF_TIDS];  /* Tid based statistics */
-    PACKET_LOG          pkt_log;            /* Log info of the packets */
-};
-
-#endif /* __AGGR_RX_INTERNAL_H__ */
diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c
deleted file mode 100644 (file)
index 9b1509e..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- *
- * Copyright (c) 2010 Atheros Communications Inc.
- * All rights reserved.
- *
- * 
-//
-// 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 <a_config.h>
-#include <athdefs.h>
-#include <a_osapi.h>
-#include <a_debug.h>
-#include "pkt_log.h"
-#include "aggr_recv_api.h"
-#include "aggr_rx_internal.h"
-#include "wmi.h"
-
-extern int
-wmi_dot3_2_dix(void *osbuf);
-
-static void
-aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf);
-
-static void
-aggr_timeout(unsigned long arg);
-
-static void
-aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order);
-
-static void
-aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q);
-
-static void *
-aggr_get_osbuf(struct aggr_info *p_aggr);
-
-void *
-aggr_init(ALLOC_NETBUFS netbuf_allocator)
-{
-    struct aggr_info   *p_aggr = NULL;
-    struct rxtid *rxtid;
-    u8 i;
-    int status = 0;
-
-    A_PRINTF("In aggr_init..\n");
-
-    do {
-        p_aggr = A_MALLOC(sizeof(struct aggr_info));
-        if(!p_aggr) {
-            A_PRINTF("Failed to allocate memory for aggr_node\n");
-            status = A_ERROR;
-            break;
-        }
-
-        /* Init timer and data structures */
-        A_MEMZERO(p_aggr, sizeof(struct aggr_info));
-        p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
-        A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
-        p_aggr->timerScheduled = false;
-        A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);
-
-        p_aggr->netbuf_allocator = netbuf_allocator;
-        p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
-
-        for(i = 0; i < NUM_OF_TIDS; i++) {
-            rxtid = AGGR_GET_RXTID(p_aggr, i);
-            rxtid->aggr = false;
-            rxtid->progress = false;
-            rxtid->timerMon = false;
-            A_NETBUF_QUEUE_INIT(&rxtid->q);
-            A_MUTEX_INIT(&rxtid->lock);
-        }
-    }while(false);
-
-    A_PRINTF("going out of aggr_init..status %s\n",
-                    (status == 0) ? "OK":"Error");
-
-    if (status) {
-        /* Cleanup */
-        aggr_module_destroy(p_aggr);
-    }
-    return ((status == 0) ? p_aggr : NULL);
-}
-
-/* utility function to clear rx hold_q for a tid */
-static void
-aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
-{
-    struct rxtid *rxtid;
-    struct rxtid_stats *stats;
-
-    A_ASSERT(tid < NUM_OF_TIDS && p_aggr);
-
-    rxtid = AGGR_GET_RXTID(p_aggr, tid);
-    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
-
-    if(rxtid->aggr) {
-        aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
-    }
-
-    rxtid->aggr = false;
-    rxtid->progress = false;
-    rxtid->timerMon = false;
-    rxtid->win_sz = 0;
-    rxtid->seq_next = 0;
-    rxtid->hold_q_sz = 0;
-
-    if(rxtid->hold_q) {
-        kfree(rxtid->hold_q);
-        rxtid->hold_q = NULL;
-    }
-
-    A_MEMZERO(stats, sizeof(struct rxtid_stats));
-}
-
-void
-aggr_module_destroy(void *cntxt)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-    struct rxtid *rxtid;
-    u8 i, k;
-    A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr);
-    A_ASSERT(p_aggr);
-
-    if(p_aggr) {
-        if(p_aggr->timerScheduled) {
-            A_UNTIMEOUT(&p_aggr->timer);
-            p_aggr->timerScheduled = false;
-        }
-
-        for(i = 0; i < NUM_OF_TIDS; i++) {
-            rxtid = AGGR_GET_RXTID(p_aggr, i);
-            /* Free the hold q contents and hold_q*/
-            if(rxtid->hold_q) {
-                for(k = 0; k< rxtid->hold_q_sz; k++) {
-                    if(rxtid->hold_q[k].osbuf) {
-                        A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
-                    }
-                }
-                kfree(rxtid->hold_q);
-            }
-            /* Free the dispatch q contents*/
-            while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
-                A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q));
-            }
-            if (A_IS_MUTEX_VALID(&rxtid->lock)) {
-                A_MUTEX_DELETE(&rxtid->lock);
-            }
-        }
-        /* free the freeQ and its contents*/
-        while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
-            A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
-        }
-        kfree(p_aggr);
-    }
-    A_PRINTF("out aggr_module_destroy\n");
-}
-
-
-void
-aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-
-    A_ASSERT(p_aggr && fn && dev);
-
-    p_aggr->rx_fn = fn;
-    p_aggr->dev = dev;
-}
-
-
-void
-aggr_process_bar(void *cntxt, u8 tid, u16 seq_no)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-    struct rxtid_stats *stats;
-
-    A_ASSERT(p_aggr);
-    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
-    stats->num_bar++;
-
-    aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO);
-}
-
-
-void
-aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-    struct rxtid *rxtid;
-    struct rxtid_stats *stats;
-
-    A_ASSERT(p_aggr);
-    rxtid = AGGR_GET_RXTID(p_aggr, tid);
-    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
-
-    A_PRINTF("%s(): win_sz = %d aggr %d\n", _A_FUNCNAME_, win_sz, rxtid->aggr);
-    if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
-        A_PRINTF("win_sz %d, tid %d\n", win_sz, tid);
-    }
-
-    if(rxtid->aggr) {
-        /* Just go and  deliver all the frames up from this
-         * queue, as if we got DELBA and re-initialize the queue
-         */
-        aggr_delete_tid_state(p_aggr, tid);
-    }
-
-    rxtid->seq_next = seq_no;
-    /* create these queues, only upon receiving of ADDBA for a
-     * tid, reducing memory requirement
-     */
-    rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz));
-    if((rxtid->hold_q == NULL)) {
-        A_PRINTF("Failed to allocate memory, tid = %d\n", tid);
-        A_ASSERT(0);
-    }
-    A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz));
-
-    /* Update rxtid for the window sz */
-    rxtid->win_sz = win_sz;
-    /* hold_q_sz inicates the depth of holding q - which  is
-     * a factor of win_sz. Compute once, as it will be used often
-     */
-    rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
-    /* There should be no frames on q - even when second ADDBA comes in.
-     * If aggr was previously ON on this tid, we would have cleaned up
-     * the q
-     */
-    if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) {
-        A_PRINTF("ERROR: Frames still on queue ?\n");
-        A_ASSERT(0);
-    }
-
-    rxtid->aggr = true;
-}
-
-void
-aggr_recv_delba_req_evt(void *cntxt, u8 tid)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-    struct rxtid *rxtid;
-
-    A_ASSERT(p_aggr);
-    A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid);
-
-    rxtid = AGGR_GET_RXTID(p_aggr, tid);
-
-    if(rxtid->aggr) {
-        aggr_delete_tid_state(p_aggr, tid);
-    }
-}
-
-static void
-aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order)
-{
-    struct rxtid *rxtid;
-    struct osbuf_hold_q *node;
-    u16 idx, idx_end, seq_end;
-    struct rxtid_stats *stats;
-
-    A_ASSERT(p_aggr);
-    rxtid = AGGR_GET_RXTID(p_aggr, tid);
-    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
-
-    /* idx is absolute location for first frame */
-    idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
-
-    /* idx_end is typically the last possible frame in the window,
-     * but changes to 'the' seq_no, when BAR comes. If seq_no
-     * is non-zero, we will go up to that and stop.
-     * Note: last seq no in current window will occupy the same
-     * index position as index that is just previous to start.
-     * An imp point : if win_sz is 7, for seq_no space of 4095,
-     * then, there would be holes when sequence wrap around occurs.
-     * Target should judiciously choose the win_sz, based on
-     * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
-     * 2, 4, 8, 16 win_sz works fine).
-     * We must deque from "idx" to "idx_end", including both.
-     */
-    seq_end = (seq_no) ? seq_no : rxtid->seq_next;
-    idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
-
-    /* Critical section begins */
-    A_MUTEX_LOCK(&rxtid->lock);
-    do {
-
-        node = &rxtid->hold_q[idx];
-
-        if((order == CONTIGUOUS_SEQNO) && (!node->osbuf))
-            break;
-
-        /* chain frames and deliver frames bcos:
-         *  1. either the frames are in order and window is contiguous, OR
-         *  2. we need to deque frames, irrespective of holes
-         */
-        if(node->osbuf) {
-            if(node->is_amsdu) {
-                aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf);
-            } else {
-                A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf);
-            }
-            node->osbuf = NULL;
-        } else {
-            stats->num_hole++;
-        }
-
-        /* window is moving */
-        rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next);
-        idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
-    } while(idx != idx_end);
-    /* Critical section ends */
-    A_MUTEX_UNLOCK(&rxtid->lock);
-
-    stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q);
-    aggr_dispatch_frames(p_aggr, &rxtid->q);
-}
-
-static void *
-aggr_get_osbuf(struct aggr_info *p_aggr)
-{
-    void *buf = NULL;
-
-    /* Starving for buffers?  get more from OS
-     *  check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) :
-     *      re-allocate bufs if so
-     * allocate a free buf from freeQ
-     */
-    if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) {
-        p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
-    }
-
-    if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
-        buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ);
-    }
-
-    return buf;
-}
-
-
-static void
-aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf)
-{
-    void *new_buf;
-    u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
-    u8 *framep;
-
-    /* Frame format at this point:
-     *  [DIX hdr | 802.3 | 802.3 | ... | 802.3]
-     *
-     * Strip the DIX header.
-     * Iterate through the osbuf and do:
-     *  grab a free netbuf from freeQ
-     *  find the start and end of a frame
-     *  copy it to netbuf(Vista can do better here)
-     *  convert all msdu's(802.3) frames to upper layer format - os routine
-     *      -for now lets convert from 802.3 to dix
-     *  enque this to dispatch q of tid
-     * repeat
-     * free the osbuf - to OS. It's been sliced.
-     */
-
-    mac_hdr_len = sizeof(ATH_MAC_HDR);
-    framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len;
-    amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len;
-
-    while(amsdu_len > mac_hdr_len) {
-        /* Begin of a 802.3 frame */
-        payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen);
-#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
-#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
-        if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
-            A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8023_len);
-            break;
-        }
-        frame_8023_len = payload_8023_len + mac_hdr_len;
-        new_buf = aggr_get_osbuf(p_aggr);
-        if(new_buf == NULL) {
-            A_PRINTF("No buffer available \n");
-            break;
-        }
-
-        memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
-        A_NETBUF_PUT(new_buf, frame_8023_len);
-        if (wmi_dot3_2_dix(new_buf) != 0) {
-            A_PRINTF("dot3_2_dix err..\n");
-            A_NETBUF_FREE(new_buf);
-            break;
-        }
-
-        A_NETBUF_ENQUEUE(&rxtid->q, new_buf);
-
-        /* Is this the last subframe within this aggregate ? */
-        if ((amsdu_len - frame_8023_len) == 0) {
-            break;
-        }
-
-        /* Add the length of A-MSDU subframe padding bytes -
-         * Round to nearest word.
-         */
-        frame_8023_len = ((frame_8023_len + 3) & ~3);
-
-        framep += frame_8023_len;
-        amsdu_len -= frame_8023_len;
-    }
-
-    A_NETBUF_FREE(*osbuf);
-    *osbuf = NULL;
-}
-
-void
-aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-    struct rxtid *rxtid;
-    struct rxtid_stats *stats;
-    u16 idx, st, cur, end;
-    u16 *log_idx;
-    struct osbuf_hold_q *node;
-    PACKET_LOG *log;
-
-    A_ASSERT(p_aggr);
-    A_ASSERT(tid < NUM_OF_TIDS);
-
-    rxtid = AGGR_GET_RXTID(p_aggr, tid);
-    stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
-
-    stats->num_into_aggr++;
-
-    if(!rxtid->aggr) {
-        if(is_amsdu) {
-            aggr_slice_amsdu(p_aggr, rxtid, osbuf);
-            stats->num_amsdu++;
-            aggr_dispatch_frames(p_aggr, &rxtid->q);
-        }
-        return;
-    }
-
-    /* Check the incoming sequence no, if it's in the window */
-    st = rxtid->seq_next;
-    cur = seq_no;
-    end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
-    /* Log the pkt info for future analysis */
-    log = &p_aggr->pkt_log;
-    log_idx = &log->last_idx;
-    log->info[*log_idx].cur = cur;
-    log->info[*log_idx].st = st;
-    log->info[*log_idx].end = end;
-    *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx);
-
-    if(((st < end) && (cur < st || cur > end)) ||
-      ((st > end) && (cur > end) && (cur < st))) {
-        /* the cur frame is outside the window. Since we know
-         * our target would not do this without reason it must
-         * be assumed that the window has moved for some valid reason.
-         * Therefore, we dequeue all frames and start fresh.
-         */
-        u16 extended_end;
-
-        extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
-
-        if(((end < extended_end) && (cur < end || cur > extended_end)) ||
-           ((end > extended_end) && (cur > extended_end) && (cur < end))) {
-            // dequeue all frames in queue and shift window to new frame
-            aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
-            //set window start so that new frame is last frame in window
-            if(cur >= rxtid->hold_q_sz-1) {
-                rxtid->seq_next = cur - (rxtid->hold_q_sz-1);
-            }else{
-                rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
-            }
-        } else {
-            // dequeue only those frames that are outside the new shifted window
-            if(cur >= rxtid->hold_q_sz-1) {
-                st = cur - (rxtid->hold_q_sz-1);
-            }else{
-                st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
-            }
-
-            aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO);
-        }
-
-        stats->num_oow++;
-    }
-
-    idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
-
-    /*enque the frame, in hold_q */
-    node = &rxtid->hold_q[idx];
-
-    A_MUTEX_LOCK(&rxtid->lock);
-    if(node->osbuf) {
-        /* Is the cur frame duplicate or something beyond our
-         * window(hold_q -> which is 2x, already)?
-         * 1. Duplicate is easy - drop incoming frame.
-         * 2. Not falling in current sliding window.
-         *  2a. is the frame_seq_no preceding current tid_seq_no?
-         *      -> drop the frame. perhaps sender did not get our ACK.
-         *         this is taken care of above.
-         *  2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
-         *      -> Taken care of it above, by moving window forward.
-         *
-         */
-        A_NETBUF_FREE(node->osbuf);
-        stats->num_dups++;
-    }
-
-    node->osbuf = *osbuf;
-    node->is_amsdu = is_amsdu;
-    node->seq_no = seq_no;
-    if(node->is_amsdu) {
-        stats->num_amsdu++;
-    } else {
-        stats->num_mpdu++;
-    }
-    A_MUTEX_UNLOCK(&rxtid->lock);
-
-    *osbuf = NULL;
-    aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);
-
-    if(p_aggr->timerScheduled) {
-        rxtid->progress = true;
-    }else{
-        for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
-            if(rxtid->hold_q[idx].osbuf) {
-                /* there is a frame in the queue and no timer so
-                 * start a timer to ensure that the frame doesn't remain
-                 * stuck forever. */
-                p_aggr->timerScheduled = true;
-                A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
-                rxtid->progress = false;
-                rxtid->timerMon = true;
-                break;
-            }
-        }
-    }
-}
-
-/*
- * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
- *  hold Q state.  Examples include when a Connect event or disconnect event is
- *  received.
- */
-void
-aggr_reset_state(void *cntxt)
-{
-    u8 tid;
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-
-    A_ASSERT(p_aggr);
-
-    for(tid=0 ; tid<NUM_OF_TIDS ; tid++) {
-        aggr_delete_tid_state(p_aggr, tid);
-    }
-}
-
-
-static void
-aggr_timeout(unsigned long arg)
-{
-    u8 i,j;
-    struct aggr_info *p_aggr = (struct aggr_info *)arg;
-    struct rxtid   *rxtid;
-    struct rxtid_stats *stats;
-    /*
-     * If the q for which the timer was originally started has
-     * not progressed then it is necessary to dequeue all the
-     * contained frames so that they are not held forever.
-     */
-    for(i = 0; i < NUM_OF_TIDS; i++) {
-        rxtid = AGGR_GET_RXTID(p_aggr, i);
-        stats = AGGR_GET_RXTID_STATS(p_aggr, i);
-
-        if(rxtid->aggr == false ||
-           rxtid->timerMon == false ||
-           rxtid->progress == true) {
-            continue;
-        }
-        // dequeue all frames in for this tid
-        stats->num_timeouts++;
-        A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO));
-        aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
-    }
-
-    p_aggr->timerScheduled = false;
-    // determine whether a new timer should be started.
-    for(i = 0; i < NUM_OF_TIDS; i++) {
-        rxtid = AGGR_GET_RXTID(p_aggr, i);
-
-        if(rxtid->aggr == true && rxtid->hold_q) {
-            for(j = 0 ; j < rxtid->hold_q_sz ; j++)
-            {
-                if(rxtid->hold_q[j].osbuf)
-                {
-                    p_aggr->timerScheduled = true;
-                    rxtid->timerMon = true;
-                    rxtid->progress = false;
-                    break;
-                }
-            }
-
-            if(j >= rxtid->hold_q_sz) {
-                rxtid->timerMon = false;
-            }
-        }
-    }
-
-    if(p_aggr->timerScheduled) {
-        /* Rearm the timer*/
-        A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
-    }
-
-}
-
-static void
-aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q)
-{
-    void *osbuf;
-
-    while((osbuf = A_NETBUF_DEQUEUE(q))) {
-        p_aggr->rx_fn(p_aggr->dev, osbuf);
-    }
-}
-
-void
-aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
-{
-    struct aggr_info *p_aggr = (struct aggr_info *)cntxt;
-    struct rxtid   *rxtid;
-    struct rxtid_stats *stats;
-    u8 i;
-
-    *log_buf = &p_aggr->pkt_log;
-    A_PRINTF("\n\n================================================\n");
-    A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, holes, bar, seq_next\n");
-    for(i = 0; i < NUM_OF_TIDS; i++) {
-        stats = AGGR_GET_RXTID_STATS(p_aggr, i);
-        rxtid = AGGR_GET_RXTID(p_aggr, i);
-        A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_aggr, stats->num_dups,
-                    stats->num_oow, stats->num_mpdu,
-                    stats->num_amsdu, stats->num_delivered, stats->num_timeouts,
-                    stats->num_hole, stats->num_bar,
-                    rxtid->seq_next);
-    }
-    A_PRINTF("================================================\n\n");
-
-}
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h
deleted file mode 100644 (file)
index cf47d06..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ieee80211.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _NET80211_IEEE80211_H_
-#define _NET80211_IEEE80211_H_
-
-/*
- * 802.11 protocol definitions.
- */
-#define IEEE80211_WEP_KEYLEN        5   /* 40bit */
-#define IEEE80211_WEP_IVLEN         3   /* 24bit */
-#define IEEE80211_WEP_KIDLEN        1   /* 1 octet */
-#define IEEE80211_WEP_CRCLEN        4   /* CRC-32 */
-#define IEEE80211_WEP_NKID          4   /* number of key ids */
-
-/*
- * 802.11i defines an extended IV for use with non-WEP ciphers.
- * When the EXTIV bit is set in the key id byte an additional
- * 4 bytes immediately follow the IV for TKIP.  For CCMP the
- * EXTIV bit is likewise set but the 8 bytes represent the
- * CCMP header rather than IV+extended-IV.
- */
-#define IEEE80211_WEP_EXTIV         0x20
-#define IEEE80211_WEP_EXTIVLEN      4   /* extended IV length */
-#define IEEE80211_WEP_MICLEN        8   /* trailing MIC */
-
-#define IEEE80211_CRC_LEN           4
-
-#ifdef WAPI_ENABLE
-#define IEEE80211_WAPI_EXTIVLEN      10   /* extended IV length */
-#endif /* WAPI ENABLE */
-
-
-#define IEEE80211_ADDR_LEN  6       /* size of 802.11 address */
-/* is 802.11 address multicast/broadcast? */
-#define IEEE80211_IS_MULTICAST(_a)  (*(_a) & 0x01)
-#define IEEE80211_IS_BROADCAST(_a)  (*(_a) == 0xFF)
-#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
-#define WEP_TRAILER IEEE80211_WEP_CRCLEN
-#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
-                    IEEE80211_WEP_EXTIVLEN)
-#define CCMP_TRAILER IEEE80211_WEP_MICLEN
-#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
-                    IEEE80211_WEP_EXTIVLEN)
-#define TKIP_TRAILER IEEE80211_WEP_CRCLEN
-#define TKIP_MICLEN  IEEE80211_WEP_MICLEN
-
-
-#define IEEE80211_ADDR_EQ(addr1, addr2)     \
-    (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) == 0)
-
-#define IEEE80211_ADDR_COPY(dst,src)    memcpy(dst,src,IEEE80211_ADDR_LEN)
-
-#define IEEE80211_KEYBUF_SIZE 16
-#define IEEE80211_MICBUF_SIZE (8+8)  /* space for both tx and rx */
-
-/*
- * NB: these values are ordered carefully; there are lots of
- * of implications in any reordering.  In particular beware
- * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
- */
-#define IEEE80211_CIPHER_WEP            0
-#define IEEE80211_CIPHER_TKIP           1
-#define IEEE80211_CIPHER_AES_OCB        2
-#define IEEE80211_CIPHER_AES_CCM        3
-#define IEEE80211_CIPHER_CKIP           5
-#define IEEE80211_CIPHER_CCKM_KRK       6
-#define IEEE80211_CIPHER_NONE           7       /* pseudo value */
-
-#define IEEE80211_CIPHER_MAX            (IEEE80211_CIPHER_NONE+1)
-
-#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \
-        (((len) == 5) || ((len) == 13) || ((len) == 16))
-
-
-
-/*
- * generic definitions for IEEE 802.11 frames
- */
-PREPACK struct ieee80211_frame {
-    u8 i_fc[2];
-    u8 i_dur[2];
-    u8 i_addr1[IEEE80211_ADDR_LEN];
-    u8 i_addr2[IEEE80211_ADDR_LEN];
-    u8 i_addr3[IEEE80211_ADDR_LEN];
-    u8 i_seq[2];
-    /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
-    /* see below */
-} POSTPACK;
-
-PREPACK struct ieee80211_qosframe {
-    u8 i_fc[2];
-    u8 i_dur[2];
-    u8 i_addr1[IEEE80211_ADDR_LEN];
-    u8 i_addr2[IEEE80211_ADDR_LEN];
-    u8 i_addr3[IEEE80211_ADDR_LEN];
-    u8 i_seq[2];
-    u8 i_qos[2];
-} POSTPACK;
-
-#define IEEE80211_FC0_VERSION_MASK          0x03
-#define IEEE80211_FC0_VERSION_SHIFT         0
-#define IEEE80211_FC0_VERSION_0             0x00
-#define IEEE80211_FC0_TYPE_MASK             0x0c
-#define IEEE80211_FC0_TYPE_SHIFT            2
-#define IEEE80211_FC0_TYPE_MGT              0x00
-#define IEEE80211_FC0_TYPE_CTL              0x04
-#define IEEE80211_FC0_TYPE_DATA             0x08
-
-#define IEEE80211_FC0_SUBTYPE_MASK          0xf0
-#define IEEE80211_FC0_SUBTYPE_SHIFT         4
-/* for TYPE_MGT */
-#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ     0x00
-#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP    0x10
-#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ   0x20
-#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP  0x30
-#define IEEE80211_FC0_SUBTYPE_PROBE_REQ     0x40
-#define IEEE80211_FC0_SUBTYPE_PROBE_RESP    0x50
-#define IEEE80211_FC0_SUBTYPE_BEACON        0x80
-#define IEEE80211_FC0_SUBTYPE_ATIM          0x90
-#define IEEE80211_FC0_SUBTYPE_DISASSOC      0xa0
-#define IEEE80211_FC0_SUBTYPE_AUTH          0xb0
-#define IEEE80211_FC0_SUBTYPE_DEAUTH        0xc0
-/* for TYPE_CTL */
-#define IEEE80211_FC0_SUBTYPE_PS_POLL       0xa0
-#define IEEE80211_FC0_SUBTYPE_RTS           0xb0
-#define IEEE80211_FC0_SUBTYPE_CTS           0xc0
-#define IEEE80211_FC0_SUBTYPE_ACK           0xd0
-#define IEEE80211_FC0_SUBTYPE_CF_END        0xe0
-#define IEEE80211_FC0_SUBTYPE_CF_END_ACK    0xf0
-/* for TYPE_DATA (bit combination) */
-#define IEEE80211_FC0_SUBTYPE_DATA          0x00
-#define IEEE80211_FC0_SUBTYPE_CF_ACK        0x10
-#define IEEE80211_FC0_SUBTYPE_CF_POLL       0x20
-#define IEEE80211_FC0_SUBTYPE_CF_ACPL       0x30
-#define IEEE80211_FC0_SUBTYPE_NODATA        0x40
-#define IEEE80211_FC0_SUBTYPE_CFACK         0x50
-#define IEEE80211_FC0_SUBTYPE_CFPOLL        0x60
-#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
-#define IEEE80211_FC0_SUBTYPE_QOS           0x80
-#define IEEE80211_FC0_SUBTYPE_QOS_NULL      0xc0
-
-#define IEEE80211_FC1_DIR_MASK              0x03
-#define IEEE80211_FC1_DIR_NODS              0x00    /* STA->STA */
-#define IEEE80211_FC1_DIR_TODS              0x01    /* STA->AP  */
-#define IEEE80211_FC1_DIR_FROMDS            0x02    /* AP ->STA */
-#define IEEE80211_FC1_DIR_DSTODS            0x03    /* AP ->AP  */
-
-#define IEEE80211_FC1_MORE_FRAG             0x04
-#define IEEE80211_FC1_RETRY                 0x08
-#define IEEE80211_FC1_PWR_MGT               0x10
-#define IEEE80211_FC1_MORE_DATA             0x20
-#define IEEE80211_FC1_WEP                   0x40
-#define IEEE80211_FC1_ORDER                 0x80
-
-#define IEEE80211_SEQ_FRAG_MASK             0x000f
-#define IEEE80211_SEQ_FRAG_SHIFT            0
-#define IEEE80211_SEQ_SEQ_MASK              0xfff0
-#define IEEE80211_SEQ_SEQ_SHIFT             4
-
-#define IEEE80211_NWID_LEN                  32
-
-/*
- * 802.11 rate set.
- */
-#define IEEE80211_RATE_SIZE     8       /* 802.11 standard */
-#define IEEE80211_RATE_MAXSIZE  15      /* max rates we'll handle */
-
-#define WMM_NUM_AC                  4   /* 4 AC categories */
-
-#define WMM_PARAM_ACI_M         0x60    /* Mask for ACI field */
-#define WMM_PARAM_ACI_S         5   /* Shift for ACI field */
-#define WMM_PARAM_ACM_M         0x10    /* Mask for ACM bit */
-#define WMM_PARAM_ACM_S         4       /* Shift for ACM bit */
-#define WMM_PARAM_AIFSN_M       0x0f    /* Mask for aifsn field */
-#define WMM_PARAM_LOGCWMIN_M    0x0f    /* Mask for CwMin field (in log) */
-#define WMM_PARAM_LOGCWMAX_M    0xf0    /* Mask for CwMax field (in log) */
-#define WMM_PARAM_LOGCWMAX_S    4   /* Shift for CwMax field */
-
-#define WMM_AC_TO_TID(_ac) (       \
-    ((_ac) == WMM_AC_VO) ? 6 : \
-    ((_ac) == WMM_AC_VI) ? 5 : \
-    ((_ac) == WMM_AC_BK) ? 1 : \
-    0)
-
-#define TID_TO_WMM_AC(_tid) (      \
-    ((_tid) < 1) ? WMM_AC_BE : \
-    ((_tid) < 3) ? WMM_AC_BK : \
-    ((_tid) < 6) ? WMM_AC_VI : \
-    WMM_AC_VO)
-/*
- * Management information element payloads.
- */
-
-enum {
-    IEEE80211_ELEMID_SSID       = 0,
-    IEEE80211_ELEMID_RATES      = 1,
-    IEEE80211_ELEMID_FHPARMS    = 2,
-    IEEE80211_ELEMID_DSPARMS    = 3,
-    IEEE80211_ELEMID_CFPARMS    = 4,
-    IEEE80211_ELEMID_TIM        = 5,
-    IEEE80211_ELEMID_IBSSPARMS  = 6,
-    IEEE80211_ELEMID_COUNTRY    = 7,
-    IEEE80211_ELEMID_CHALLENGE  = 16,
-    /* 17-31 reserved for challenge text extension */
-    IEEE80211_ELEMID_PWRCNSTR   = 32,
-    IEEE80211_ELEMID_PWRCAP     = 33,
-    IEEE80211_ELEMID_TPCREQ     = 34,
-    IEEE80211_ELEMID_TPCREP     = 35,
-    IEEE80211_ELEMID_SUPPCHAN   = 36,
-    IEEE80211_ELEMID_CHANSWITCH = 37,
-    IEEE80211_ELEMID_MEASREQ    = 38,
-    IEEE80211_ELEMID_MEASREP    = 39,
-    IEEE80211_ELEMID_QUIET      = 40,
-    IEEE80211_ELEMID_IBSSDFS    = 41,
-    IEEE80211_ELEMID_ERP        = 42,
-    IEEE80211_ELEMID_HTCAP_ANA  = 45,   /* Address ANA, and non-ANA story, for interop. CL#171733 */
-    IEEE80211_ELEMID_RSN        = 48,
-    IEEE80211_ELEMID_XRATES     = 50,
-    IEEE80211_ELEMID_HTINFO_ANA = 61,
-#ifdef WAPI_ENABLE
-    IEEE80211_ELEMID_WAPI       = 68,
-#endif
-    IEEE80211_ELEMID_TPC        = 150,
-    IEEE80211_ELEMID_CCKM       = 156,
-    IEEE80211_ELEMID_VENDOR     = 221,  /* vendor private */
-};
-
-#define ATH_OUI             0x7f0300        /* Atheros OUI */
-#define ATH_OUI_TYPE        0x01
-#define ATH_OUI_SUBTYPE     0x01
-#define ATH_OUI_VERSION     0x00
-
-#define WPA_OUI             0xf25000
-#define WPA_OUI_TYPE        0x01
-#define WPA_VERSION         1          /* current supported version */
-
-#define WPA_CSE_NULL        0x00
-#define WPA_CSE_WEP40       0x01
-#define WPA_CSE_TKIP        0x02
-#define WPA_CSE_CCMP        0x04
-#define WPA_CSE_WEP104      0x05
-
-#define WPA_ASE_NONE        0x00
-#define WPA_ASE_8021X_UNSPEC    0x01
-#define WPA_ASE_8021X_PSK   0x02
-
-#define RSN_OUI         0xac0f00
-#define RSN_VERSION     1       /* current supported version */
-
-#define RSN_CSE_NULL        0x00
-#define RSN_CSE_WEP40       0x01
-#define RSN_CSE_TKIP        0x02
-#define RSN_CSE_WRAP        0x03
-#define RSN_CSE_CCMP        0x04
-#define RSN_CSE_WEP104      0x05
-
-#define RSN_ASE_NONE            0x00
-#define RSN_ASE_8021X_UNSPEC    0x01
-#define RSN_ASE_8021X_PSK       0x02
-
-#define RSN_CAP_PREAUTH         0x01
-
-#define WMM_OUI                 0xf25000
-#define WMM_OUI_TYPE            0x02
-#define WMM_INFO_OUI_SUBTYPE    0x00
-#define WMM_PARAM_OUI_SUBTYPE   0x01
-#define WMM_VERSION             1
-
-/* WMM stream classes */
-#define WMM_NUM_AC  4
-#define WMM_AC_BE   0       /* best effort */
-#define WMM_AC_BK   1       /* background */
-#define WMM_AC_VI   2       /* video */
-#define WMM_AC_VO   3       /* voice */
-
-/* TSPEC related */
-#define ACTION_CATEGORY_CODE_TSPEC                 17
-#define ACTION_CODE_TSPEC_ADDTS                    0
-#define ACTION_CODE_TSPEC_ADDTS_RESP               1
-#define ACTION_CODE_TSPEC_DELTS                    2
-
-typedef enum {
-    TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0,
-    TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1,
-    TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3,
-    TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8,
-    TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9,
-    TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA,
-    TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB,
-    TSPEC_STATUS_CODE_DELTS_SENT    = 0x30,
-    TSPEC_STATUS_CODE_DELTS_RECV    = 0x31,
-} TSPEC_STATUS_CODE;
-
-#define TSPEC_TSID_MASK             0xF
-#define TSPEC_TSID_S                1
-
-/*
- * WMM/802.11e Tspec Element
- */
-typedef PREPACK struct wmm_tspec_ie_t {
-    u8 elementId;
-    u8 len;
-    u8 oui[3];
-    u8 ouiType;
-    u8 ouiSubType;
-    u8 version;
-    u16 tsInfo_info;
-    u8 tsInfo_reserved;
-    u16 nominalMSDU;
-    u16 maxMSDU;
-    u32 minServiceInt;
-    u32 maxServiceInt;
-    u32 inactivityInt;
-    u32 suspensionInt;
-    u32 serviceStartTime;
-    u32 minDataRate;
-    u32 meanDataRate;
-    u32 peakDataRate;
-    u32 maxBurstSize;
-    u32 delayBound;
-    u32 minPhyRate;
-    u16 sba;
-    u16 mediumTime;
-} POSTPACK WMM_TSPEC_IE;
-
-
-/*
- * BEACON management packets
- *
- *  octet timestamp[8]
- *  octet beacon interval[2]
- *  octet capability information[2]
- *  information element
- *      octet elemid
- *      octet length
- *      octet information[length]
- */
-
-#define IEEE80211_BEACON_INTERVAL(beacon) \
-    ((beacon)[8] | ((beacon)[9] << 8))
-#define IEEE80211_BEACON_CAPABILITY(beacon) \
-    ((beacon)[10] | ((beacon)[11] << 8))
-
-#define IEEE80211_CAPINFO_ESS               0x0001
-#define IEEE80211_CAPINFO_IBSS              0x0002
-#define IEEE80211_CAPINFO_CF_POLLABLE       0x0004
-#define IEEE80211_CAPINFO_CF_POLLREQ        0x0008
-#define IEEE80211_CAPINFO_PRIVACY           0x0010
-#define IEEE80211_CAPINFO_SHORT_PREAMBLE    0x0020
-#define IEEE80211_CAPINFO_PBCC              0x0040
-#define IEEE80211_CAPINFO_CHNL_AGILITY      0x0080
-/* bits 8-9 are reserved */
-#define IEEE80211_CAPINFO_SHORT_SLOTTIME    0x0400
-#define IEEE80211_CAPINFO_APSD              0x0800
-/* bit 12 is reserved */
-#define IEEE80211_CAPINFO_DSSSOFDM          0x2000
-/* bits 14-15 are reserved */
-
-/*
- * Authentication Modes
- */
-
-enum ieee80211_authmode {
-    IEEE80211_AUTH_NONE     = 0,
-    IEEE80211_AUTH_OPEN     = 1,
-    IEEE80211_AUTH_SHARED   = 2,
-    IEEE80211_AUTH_8021X    = 3,
-    IEEE80211_AUTH_AUTO     = 4,   /* auto-select/accept */
-    /* NB: these are used only for ioctls */
-    IEEE80211_AUTH_WPA      = 5,  /* WPA/RSN  w/ 802.1x */
-    IEEE80211_AUTH_WPA_PSK  = 6,  /* WPA/RSN  w/ PSK */
-    IEEE80211_AUTH_WPA_CCKM = 7,  /* WPA/RSN IE  w/ CCKM */
-};
-
-#define IEEE80211_PS_MAX_QUEUE    50 /*Maximum no of buffers that can be queues for PS*/
-
-#endif /* _NET80211_IEEE80211_H_ */
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
deleted file mode 100644 (file)
index 1cb0167..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="ieee80211_node.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _IEEE80211_NODE_H_
-#define _IEEE80211_NODE_H_
-
-/*
- * Node locking definitions.
- */
-#define IEEE80211_NODE_LOCK_INIT(_nt)   A_MUTEX_INIT(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_LOCK_DESTROY(_nt) if (A_IS_MUTEX_VALID(&(_nt)->nt_nodelock)) { \
-                                               A_MUTEX_DELETE(&(_nt)->nt_nodelock); }
-       
-#define IEEE80211_NODE_LOCK(_nt)        A_MUTEX_LOCK(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_UNLOCK(_nt)      A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_LOCK_BH(_nt)     A_MUTEX_LOCK(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_UNLOCK_BH(_nt)   A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
-#define IEEE80211_NODE_LOCK_ASSERT(_nt)
-
-/*
- * Node reference counting definitions.
- *
- * ieee80211_node_initref   initialize the reference count to 1
- * ieee80211_node_incref    add a reference
- * ieee80211_node_decref    remove a reference
- * ieee80211_node_dectestref    remove a reference and return 1 if this
- *              is the last reference, otherwise 0
- * ieee80211_node_refcnt    reference count for printing (only)
- */
-#define ieee80211_node_initref(_ni)     ((_ni)->ni_refcnt = 1)
-#define ieee80211_node_incref(_ni)      ((_ni)->ni_refcnt++)
-#define ieee80211_node_decref(_ni)      ((_ni)->ni_refcnt--)
-#define ieee80211_node_dectestref(_ni)  (((_ni)->ni_refcnt--) == 1)
-#define ieee80211_node_refcnt(_ni)      ((_ni)->ni_refcnt)
-
-#define IEEE80211_NODE_HASHSIZE 32
-/* simple hash is enough for variation of macaddr */
-#define IEEE80211_NODE_HASH(addr)   \
-    (((const u8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \
-        IEEE80211_NODE_HASHSIZE)
-
-/*
- * Table of ieee80211_node instances.  Each ieee80211com
- * has at least one for holding the scan candidates.
- * When operating as an access point or in ibss mode there
- * is a second table for associated stations or neighbors.
- */
-struct ieee80211_node_table {
-    void                   *nt_wmip;       /* back reference */
-    A_MUTEX_T               nt_nodelock;    /* on node table */
-    struct bss              *nt_node_first; /* information of all nodes */
-    struct bss              *nt_node_last;  /* information of all nodes */
-    struct bss              *nt_hash[IEEE80211_NODE_HASHSIZE];
-    const char              *nt_name;   /* for debugging */
-    u32 nt_scangen; /* gen# for timeout scan */
-#ifdef THREAD_X
-    A_TIMER                 nt_inact_timer;
-    u8 isTimerArmed;   /* is the node timer armed */
-#endif
-    u32 nt_nodeAge; /* node aging time */
-#ifdef OS_ROAM_MANAGEMENT
-    u32 nt_si_gen; /* gen# for scan indication*/
-#endif
-};
-
-#ifdef THREAD_X
-#define WLAN_NODE_INACT_TIMEOUT_MSEC            20000
-#else
-#define WLAN_NODE_INACT_TIMEOUT_MSEC            120000
-#endif
-   
-#define WLAN_NODE_INACT_CNT            4
-
-#endif /* _IEEE80211_NODE_H_ */
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c
deleted file mode 100644 (file)
index 0fe5f4b..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wlan_node.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// IEEE 802.11 node handling support.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#include <a_config.h>
-#include <athdefs.h>
-#include <a_osapi.h>
-#define ATH_MODULE_NAME wlan
-#include <a_debug.h>
-#include "htc.h"
-#include "htc_api.h"
-#include <wmi.h>
-#include <ieee80211.h>
-#include <wlan_api.h>
-#include <wmi_api.h>
-#include <ieee80211_node.h>
-
-#define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0)
-
-#ifdef ATH_DEBUG_MODULE
-
-static struct ath_debug_mask_description wlan_debug_desc[] = {
-    { ATH_DEBUG_WLAN , "General WLAN Node Tracing"},
-};
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan,
-                                 "wlan",
-                                 "WLAN Node Management",
-                                 ATH_DEBUG_MASK_DEFAULTS,
-                                 ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc),
-                                 wlan_debug_desc);
-                                 
-#endif
-
-#ifdef THREAD_X
-static void wlan_node_timeout(unsigned long arg);
-#endif
-
-static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
-                                     const u8 *macaddr);
-
-bss_t *
-wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
-{
-    bss_t *ni;
-
-    ni = A_MALLOC_NOWAIT(sizeof(bss_t));
-
-    if (ni != NULL) {
-        if (wh_size)
-        {
-        ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
-        if (ni->ni_buf == NULL) {
-            kfree(ni);
-            ni = NULL;
-            return ni;
-        }
-        }
-    } else {
-        return ni;
-    }
-
-    /* Make sure our lists are clean */
-    ni->ni_list_next = NULL;
-    ni->ni_list_prev = NULL;
-    ni->ni_hash_next = NULL;
-    ni->ni_hash_prev = NULL;
-
-    //
-    // ni_scangen never initialized before and during suspend/resume of winmobile,
-    // that some junk has been stored in this, due to this scan list didn't properly updated
-    //
-    ni->ni_scangen   = 0;
-
-#ifdef OS_ROAM_MANAGEMENT
-    ni->ni_si_gen    = 0;
-#endif
-
-    return ni;
-}
-
-void
-wlan_node_free(bss_t *ni)
-{
-    if (ni->ni_buf != NULL) {
-        kfree(ni->ni_buf);
-    }
-    kfree(ni);
-}
-
-void
-wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
-                const u8 *macaddr)
-{
-    int hash;
-    u32 timeoutValue = 0;
-
-    memcpy(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
-    hash = IEEE80211_NODE_HASH (macaddr);
-    ieee80211_node_initref (ni);     /* mark referenced */
-
-    timeoutValue = nt->nt_nodeAge;
-
-    ni->ni_tstamp = A_GET_MS (0);
-    ni->ni_actcnt = WLAN_NODE_INACT_CNT;
-
-    IEEE80211_NODE_LOCK_BH(nt);
-
-    /* Insert at the end of the node list */
-    ni->ni_list_next = NULL;
-    ni->ni_list_prev = nt->nt_node_last;
-    if(nt->nt_node_last != NULL)
-    {
-        nt->nt_node_last->ni_list_next = ni;
-    }
-    nt->nt_node_last = ni;
-    if(nt->nt_node_first == NULL)
-    {
-        nt->nt_node_first = ni;
-    }
-
-    /* Insert into the hash list i.e. the bucket */
-    if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
-    {
-        nt->nt_hash[hash]->ni_hash_prev = ni;
-    }
-    ni->ni_hash_prev = NULL;
-    nt->nt_hash[hash] = ni;
-
-#ifdef THREAD_X
-    if (!nt->isTimerArmed) {
-        A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0);
-        nt->isTimerArmed = true;
-    }
-#endif
-
-    IEEE80211_NODE_UNLOCK_BH(nt);
-}
-
-static bss_t *
-_ieee80211_find_node(struct ieee80211_node_table *nt,
-    const u8 *macaddr)
-{
-    bss_t *ni;
-    int hash;
-
-    IEEE80211_NODE_LOCK_ASSERT(nt);
-
-    hash = IEEE80211_NODE_HASH(macaddr);
-    for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
-        if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
-            ieee80211_node_incref(ni);  /* mark referenced */
-            return ni;
-        }
-    }
-    return NULL;
-}
-
-bss_t *
-wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr)
-{
-    bss_t *ni;
-
-    IEEE80211_NODE_LOCK(nt);
-    ni = _ieee80211_find_node(nt, macaddr);
-    IEEE80211_NODE_UNLOCK(nt);
-    return ni;
-}
-
-/*
- * Reclaim a node.  If this is the last reference count then
- * do the normal free work.  Otherwise remove it from the node
- * table and mark it gone by clearing the back-reference.
- */
-void
-wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
-{
-    IEEE80211_NODE_LOCK(nt);
-
-    if(ni->ni_list_prev == NULL)
-    {
-        /* First in list so fix the list head */
-        nt->nt_node_first = ni->ni_list_next;
-    }
-    else
-    {
-        ni->ni_list_prev->ni_list_next = ni->ni_list_next;
-    }
-
-    if(ni->ni_list_next == NULL)
-    {
-        /* Last in list so fix list tail */
-        nt->nt_node_last = ni->ni_list_prev;
-    }
-    else
-    {
-        ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
-    }
-
-    if(ni->ni_hash_prev == NULL)
-    {
-        /* First in list so fix the list head */
-        int hash;
-        hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
-        nt->nt_hash[hash] = ni->ni_hash_next;
-    }
-    else
-    {
-        ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
-    }
-
-    if(ni->ni_hash_next != NULL)
-    {
-        ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
-    }
-    wlan_node_free(ni);
-
-    IEEE80211_NODE_UNLOCK(nt);
-}
-
-static void
-wlan_node_dec_free(bss_t *ni)
-{
-    if (ieee80211_node_dectestref(ni)) {
-        wlan_node_free(ni);
-    }
-}
-
-void
-wlan_free_allnodes(struct ieee80211_node_table *nt)
-{
-    bss_t *ni;
-
-    while ((ni = nt->nt_node_first) != NULL) {
-        wlan_node_reclaim(nt, ni);
-    }
-}
-
-void
-wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
-                   void *arg)
-{
-    bss_t *ni;
-    u32 gen;
-
-    gen = ++nt->nt_scangen;
-
-    IEEE80211_NODE_LOCK(nt);
-    for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
-        if (ni->ni_scangen != gen) {
-            ni->ni_scangen = gen;
-            (void) ieee80211_node_incref(ni);
-            (*f)(arg, ni);
-            wlan_node_dec_free(ni);
-        }
-    }
-    IEEE80211_NODE_UNLOCK(nt);
-}
-
-/*
- * Node table support.
- */
-void
-wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
-{
-    int i;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%lx\n", (unsigned long)nt));
-    IEEE80211_NODE_LOCK_INIT(nt);
-
-    A_REGISTER_MODULE_DEBUG_INFO(wlan);
-    
-    nt->nt_node_first = nt->nt_node_last = NULL;
-    for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
-    {
-        nt->nt_hash[i] = NULL;
-    }
-
-#ifdef THREAD_X
-    A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
-    nt->isTimerArmed = false;
-#endif
-    nt->nt_wmip = wmip;
-    nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC;
-
-    //
-    // nt_scangen never initialized before and during suspend/resume of winmobile, 
-    // that some junk has been stored in this, due to this scan list didn't properly updated
-    //
-    nt->nt_scangen   = 0;
-
-#ifdef OS_ROAM_MANAGEMENT
-    nt->nt_si_gen    = 0;
-#endif
-}
-
-void
-wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge)
-{
-    nt->nt_nodeAge = nodeAge;
-    return;
-}
-void
-wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt)
-{
-#ifdef THREAD_X
-    bss_t *bss, *nextBss;
-    u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
-
-    wmi_get_current_bssid(nt->nt_wmip, myBssid);
-
-    bss = nt->nt_node_first;
-    while (bss != NULL)
-    {
-        nextBss = bss->ni_list_next;
-        if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
-        {
-               /*
-                * free up all but the current bss - if set
-                */
-                wlan_node_reclaim(nt, bss);
-
-        }
-        bss = nextBss;
-    }
-#else
-    bss_t *bss, *nextBss;
-    u8 myBssid[IEEE80211_ADDR_LEN];
-    u32 timeoutValue = 0;
-    u32 now = A_GET_MS(0);
-    timeoutValue = nt->nt_nodeAge;
-
-    wmi_get_current_bssid(nt->nt_wmip, myBssid);
-
-    bss = nt->nt_node_first;
-    while (bss != NULL)
-    {
-        nextBss = bss->ni_list_next;
-        if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
-        {
-
-            if (((now - bss->ni_tstamp) > timeoutValue)  || --bss->ni_actcnt == 0)
-            {
-               /*
-                * free up all but the current bss - if set
-                */
-                wlan_node_reclaim(nt, bss);
-            }
-        }
-        bss = nextBss;
-    }
-#endif
-}
-
-#ifdef THREAD_X
-static void
-wlan_node_timeout (unsigned long arg)
-{
-    struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
-    bss_t *bss, *nextBss;
-    u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false;
-    u32 timeoutValue = 0;
-    u32 now = A_GET_MS(0);
-
-    timeoutValue = nt->nt_nodeAge;
-
-    wmi_get_current_bssid(nt->nt_wmip, myBssid);
-
-    bss = nt->nt_node_first;
-    while (bss != NULL)
-    {
-        nextBss = bss->ni_list_next;
-        if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
-        {
-
-            if ((now - bss->ni_tstamp) > timeoutValue)
-            {
-               /*
-                * free up all but the current bss - if set
-                */
-                wlan_node_reclaim(nt, bss);
-            }
-            else
-            {
-                /*
-                 * Re-arm timer, only when we have a bss other than
-                 * current bss AND it is not aged-out.
-                 */
-                reArmTimer = true;
-            }
-        }
-        bss = nextBss;
-    }
-
-    if (reArmTimer)
-        A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0);
-
-    nt->isTimerArmed = reArmTimer;
-}
-#endif
-
-void
-wlan_node_table_cleanup(struct ieee80211_node_table *nt)
-{
-#ifdef THREAD_X
-    A_UNTIMEOUT(&nt->nt_inact_timer);
-    A_DELETE_TIMER(&nt->nt_inact_timer);
-#endif
-    wlan_free_allnodes(nt);
-    IEEE80211_NODE_LOCK_DESTROY(nt);
-}
-
-bss_t *
-wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
-                    u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
-{
-    bss_t   *ni = NULL;
-    u8 *pIESsid = NULL;
-
-    IEEE80211_NODE_LOCK (nt);
-
-    for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
-        pIESsid = ni->ni_cie.ie_ssid;
-        if (pIESsid[1] <= 32) {
-
-            // Step 1 : Check SSID
-            if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
-
-                //
-                // Step 2.1 : Check MatchSSID is true, if so, return Matched SSID
-                // Profile, otherwise check whether WPA2 or WPA
-                //
-                if (true == bMatchSSID) {
-                    ieee80211_node_incref (ni);  /* mark referenced */
-                    IEEE80211_NODE_UNLOCK (nt);
-                    return ni;
-                }
-
-                // Step 2 : if SSID matches, check WPA or WPA2
-                if (true == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) {
-                    ieee80211_node_incref (ni);  /* mark referenced */
-                    IEEE80211_NODE_UNLOCK (nt);
-                    return ni;
-                }
-                if (false == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) {
-                    ieee80211_node_incref(ni);  /* mark referenced */
-                    IEEE80211_NODE_UNLOCK (nt);
-                    return ni;
-                }
-            }
-        }
-    }
-
-    IEEE80211_NODE_UNLOCK (nt);
-
-    return NULL;
-}
-
-void
-wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni)
-{
-    IEEE80211_NODE_LOCK (nt);
-    wlan_node_dec_free (ni);
-    IEEE80211_NODE_UNLOCK (nt);
-}
-
-void
-wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni)
-{
-    if(ni->ni_list_prev == NULL)
-    {
-        /* First in list so fix the list head */
-        nt->nt_node_first = ni->ni_list_next;
-    }
-    else
-    {
-        ni->ni_list_prev->ni_list_next = ni->ni_list_next;
-    }
-
-    if(ni->ni_list_next == NULL)
-    {
-        /* Last in list so fix list tail */
-        nt->nt_node_last = ni->ni_list_prev;
-    }
-    else
-    {
-        ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
-    }
-
-    if(ni->ni_hash_prev == NULL)
-    {
-        /* First in list so fix the list head */
-        int hash;
-        hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
-        nt->nt_hash[hash] = ni->ni_hash_next;
-    }
-    else
-    {
-        ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
-    }
-
-    if(ni->ni_hash_next != NULL)
-    {
-        ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
-    }
-}
-
-bss_t *
-wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid)
-{
-    bss_t *bss, *nextBss;
-
-    IEEE80211_NODE_LOCK(nt);
-
-    bss = nt->nt_node_first;
-
-    while (bss != NULL)
-    {
-        nextBss = bss->ni_list_next;
-
-        if (memcmp(bssid, bss->ni_macaddr, 6) == 0)
-        {
-            wlan_node_remove_core (nt, bss);
-            IEEE80211_NODE_UNLOCK(nt);
-            return bss;
-        }
-
-        bss = nextBss;
-    }
-
-    IEEE80211_NODE_UNLOCK(nt);
-    return NULL;
-}
-
-bss_t *
-wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid,
-                    u32 ssidLength, u32 dot11AuthMode, u32 authMode,
-                   u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
-{
-    bss_t   *ni = NULL;
-    bss_t   *best_ni = NULL;
-    u8 *pIESsid = NULL;
-
-    IEEE80211_NODE_LOCK (nt);
-
-    for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
-        pIESsid = ni->ni_cie.ie_ssid;
-        if (pIESsid[1] <= 32) {
-
-            // Step 1 : Check SSID
-            if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
-
-                if (ni->ni_cie.ie_capInfo & 0x10)
-                {
-
-                    if ((NULL != ni->ni_cie.ie_rsn) && (WPA2_PSK_AUTH == authMode))
-                    {
-                        /* WPA2 */
-                        if (NULL == best_ni)
-                        {
-                            best_ni = ni;
-                        }
-                        else if (ni->ni_rssi > best_ni->ni_rssi)
-                        {
-                            best_ni = ni;
-                        }
-                    }
-                    else if ((NULL != ni->ni_cie.ie_wpa) && (WPA_PSK_AUTH == authMode))
-                    {
-                        /* WPA */
-                        if (NULL == best_ni)
-                        {
-                            best_ni = ni;
-                        }
-                        else if (ni->ni_rssi > best_ni->ni_rssi)
-                        {
-                            best_ni = ni;
-                        }
-                    }
-                    else if (WEP_CRYPT == pairwiseCryptoType)
-                    {
-                        /* WEP */
-                        if (NULL == best_ni)
-                        {
-                            best_ni = ni;
-                        }
-                        else if (ni->ni_rssi > best_ni->ni_rssi)
-                        {
-                            best_ni = ni;
-                        }
-                    }
-                }
-                else
-                {
-                    /* open AP */
-                    if ((OPEN_AUTH == authMode) && (NONE_CRYPT == pairwiseCryptoType))
-                    {
-                        if (NULL == best_ni)
-                        {
-                            best_ni = ni;
-                        }
-                        else if (ni->ni_rssi > best_ni->ni_rssi)
-                        {
-                            best_ni = ni;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    IEEE80211_NODE_UNLOCK (nt);
-
-    return best_ni;
-}
-
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
deleted file mode 100644 (file)
index 07b8313..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wlan_recv_beacon.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// IEEE 802.11 input handling.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include "a_config.h"
-#include "athdefs.h"
-#include "a_osapi.h"
-#include <wmi.h>
-#include <ieee80211.h>
-#include <wlan_api.h>
-
-#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do {         \
-    if ((_len) < (_minlen)) {                   \
-        return A_EINVAL;                         \
-    }                               \
-} while (0)
-
-#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do {         \
-    if ((__elem) == NULL) {                     \
-        return A_EINVAL;                         \
-    }                               \
-    if ((__elem)[1] > (__maxlen)) {                 \
-        return A_EINVAL;                         \
-    }                               \
-} while (0)
-
-
-/* unaligned little endian access */
-#define LE_READ_2(p)                            \
-    ((u16)                            \
-     ((((u8 *)(p))[0]      ) | (((u8 *)(p))[1] <<  8)))
-
-#define LE_READ_4(p)                            \
-    ((u32)                            \
-     ((((u8 *)(p))[0]      ) | (((u8 *)(p))[1] <<  8) | \
-      (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
-
-
-static int __inline
-iswpaoui(const u8 *frm)
-{
-    return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
-}
-
-static int __inline
-iswmmoui(const u8 *frm)
-{
-    return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
-}
-
-/* unused functions for now */
-#if 0
-static int __inline
-iswmmparam(const u8 *frm)
-{
-    return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
-}
-
-static int __inline
-iswmminfo(const u8 *frm)
-{
-    return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE;
-}
-#endif
-
-static int __inline
-isatherosoui(const u8 *frm)
-{
-    return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
-}
-
-static int __inline
-iswscoui(const u8 *frm)
-{
-    return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI);
-}
-
-int
-wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie)
-{
-    u8 *frm, *efrm;
-    u8 elemid_ssid = false;
-
-    frm = buf;
-    efrm = (u8 *) (frm + framelen);
-
-    /*
-     * beacon/probe response frame format
-     *  [8] time stamp
-     *  [2] beacon interval
-     *  [2] capability information
-     *  [tlv] ssid
-     *  [tlv] supported rates
-     *  [tlv] country information
-     *  [tlv] parameter set (FH/DS)
-     *  [tlv] erp information
-     *  [tlv] extended supported rates
-     *  [tlv] WMM
-     *  [tlv] WPA or RSN
-     *  [tlv] Atheros Advanced Capabilities
-     */
-    IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
-    A_MEMZERO(cie, sizeof(*cie));
-
-    cie->ie_tstamp = frm; frm += 8;
-    cie->ie_beaconInt = A_LE2CPU16(*(u16 *)frm);  frm += 2;
-    cie->ie_capInfo = A_LE2CPU16(*(u16 *)frm);  frm += 2;
-    cie->ie_chan = 0;
-
-    while (frm < efrm) {
-        switch (*frm) {
-        case IEEE80211_ELEMID_SSID:
-            if (!elemid_ssid) {
-                cie->ie_ssid = frm;
-                elemid_ssid = true;
-            }
-            break;
-        case IEEE80211_ELEMID_RATES:
-            cie->ie_rates = frm;
-            break;
-        case IEEE80211_ELEMID_COUNTRY:
-            cie->ie_country = frm;
-            break;
-        case IEEE80211_ELEMID_FHPARMS:
-            break;
-        case IEEE80211_ELEMID_DSPARMS:
-            cie->ie_chan = frm[2];
-            break;
-        case IEEE80211_ELEMID_TIM:
-            cie->ie_tim = frm;
-            break;
-        case IEEE80211_ELEMID_IBSSPARMS:
-            break;
-        case IEEE80211_ELEMID_XRATES:
-            cie->ie_xrates = frm;
-            break;
-        case IEEE80211_ELEMID_ERP:
-            if (frm[1] != 1) {
-                //A_PRINTF("Discarding ERP Element - Bad Len\n");
-                return A_EINVAL;
-            }
-            cie->ie_erp = frm[2];
-            break;
-        case IEEE80211_ELEMID_RSN:
-            cie->ie_rsn = frm;
-            break;
-        case IEEE80211_ELEMID_HTCAP_ANA:
-            cie->ie_htcap = frm;
-            break;
-        case IEEE80211_ELEMID_HTINFO_ANA:
-            cie->ie_htop = frm;
-            break;
-#ifdef WAPI_ENABLE
-               case IEEE80211_ELEMID_WAPI:
-            cie->ie_wapi = frm;
-            break;
-#endif
-        case IEEE80211_ELEMID_VENDOR:
-            if (iswpaoui(frm)) {
-                cie->ie_wpa = frm;
-            } else if (iswmmoui(frm)) {
-                cie->ie_wmm = frm;
-            } else if (isatherosoui(frm)) {
-                cie->ie_ath = frm;
-            } else if(iswscoui(frm)) {
-                cie->ie_wsc = frm;
-            }
-            break;
-        default:
-            break;
-        }
-        frm += frm[1] + 2;
-    }
-    IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
-    IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);
-
-    return 0;
-}
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
deleted file mode 100644 (file)
index bc91599..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wlan_utils.c" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 module implements frequently used wlan utilies
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#include <a_config.h>
-#include <athdefs.h>
-#include <a_osapi.h>
-
-/*
- * converts ieee channel number to frequency
- */
-u16 wlan_ieee2freq(int chan)
-{
-    if (chan == 14) {
-        return 2484;
-    }
-    if (chan < 14) {    /* 0-13 */
-        return (2407 + (chan*5));
-    }
-    if (chan < 27) {    /* 15-26 */
-        return (2512 + ((chan-15)*20));
-    }
-    return (5000 + (chan*5));
-}
-
-/*
- * Converts MHz frequency to IEEE channel number.
- */
-u32 wlan_freq2ieee(u16 freq)
-{
-    if (freq == 2484)
-        return 14;
-    if (freq < 2484)
-        return (freq - 2407) / 5;
-    if (freq < 5000)
-        return 15 + ((freq - 2512) / 20);
-    return (freq - 5000) / 5;
-}
diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c
deleted file mode 100644 (file)
index c7b5e5c..0000000
+++ /dev/null
@@ -1,6444 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 module implements the hardware independent layer of the
-// Wireless Module Interface (WMI) protocol.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#include <a_config.h>
-#include <athdefs.h>
-#include <a_osapi.h>
-#include "htc.h"
-#include "htc_api.h"
-#include "wmi.h"
-#include <wlan_api.h>
-#include <wmi_api.h>
-#include <ieee80211.h>
-#include <ieee80211_node.h>
-#include "dset_api.h"
-#include "wmi_host.h"
-#include "a_drv.h"
-#include "a_drv_api.h"
-#define ATH_MODULE_NAME wmi
-#include "a_debug.h"
-#include "dbglog_api.h"
-#include "roaming.h"
-#include "cfg80211.h"
-
-#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
-
-#ifdef ATH_DEBUG_MODULE
-
-static struct ath_debug_mask_description wmi_debug_desc[] = {
-    { ATH_DEBUG_WMI , "General WMI Tracing"},
-};
-
-ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
-                                 "wmi",
-                                 "Wireless Module Interface",
-                                 ATH_DEBUG_MASK_DEFAULTS,
-                                 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
-                                 wmi_debug_desc);
-
-#endif
-
-#ifndef REXOS
-#define DBGARG      _A_FUNCNAME_
-#define DBGFMT      "%s() : "
-#define DBG_WMI     ATH_DEBUG_WMI
-#define DBG_ERROR   ATH_DEBUG_ERR
-#define DBG_WMI2    ATH_DEBUG_WMI
-#define A_DPRINTF   AR_DEBUG_PRINTF
-#endif
-
-static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap,
-                                        int len);
-
-static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap,
-                                        int len);
-static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap,
-                                       int len);
-static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_sync_point(struct wmi_t *wmip);
-
-static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap,
-                                         int len);
-static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap,
-                                       int len);
-static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap,
-                                             int len);
-
-static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-#ifdef CONFIG_HOST_DSET_SUPPORT
-static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-#endif /* CONFIG_HOST_DSET_SUPPORT */
-
-
-static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap,
-                                      int len);
-static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap,
-                                      int len);
-static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap,
-                                      int len);
-static int
-wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
-
-static int
-wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
-
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-static int
-wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len);
-#endif
-
-static int
-wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-static int
-wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-static int
-wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-static bool
-wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex);
-
-static int
-wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-static int
-wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
-
-int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
-                  WMI_SYNC_FLAG syncflag);
-
-u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
-u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
-
-void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
-void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
-static int wmi_send_rssi_threshold_params(struct wmi_t *wmip,
-                              WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
-static int wmi_send_snr_threshold_params(struct wmi_t *wmip,
-                             WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-static int
-wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len);
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-
-static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-
-static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
-                                        int len);
-static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
-static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
-static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
-static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
-
-#ifdef WAPI_ENABLE
-static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,
-                                     int len);
-#endif
-
-#if defined(UNDER_CE)
-#if defined(NDIS51_MINIPORT)
-unsigned int processDot11Hdr = 0;
-#else
-unsigned int processDot11Hdr = 1;
-#endif
-#else
-extern unsigned int processDot11Hdr;
-#endif
-
-int wps_enable;
-static const s32 wmi_rateTable[][2] = {
-  //{W/O SGI, with SGI}
-    {1000, 1000},
-    {2000, 2000},
-    {5500, 5500},
-    {11000, 11000},
-    {6000, 6000},
-    {9000, 9000},
-    {12000, 12000},
-    {18000, 18000},
-    {24000, 24000},
-    {36000, 36000},
-    {48000, 48000},
-    {54000, 54000},
-    {6500, 7200},
-    {13000, 14400},
-    {19500, 21700},
-    {26000, 28900},
-    {39000, 43300},
-    {52000, 57800},
-    {58500, 65000},
-    {65000, 72200},
-    {13500, 15000},
-    {27000, 30000},
-    {40500, 45000},
-    {54000, 60000},
-    {81000, 90000},
-    {108000, 120000},
-    {121500, 135000},
-    {135000, 150000},
-    {0, 0}};
-
-#define MODE_A_SUPPORT_RATE_START       ((s32) 4)
-#define MODE_A_SUPPORT_RATE_STOP        ((s32) 11)
-
-#define MODE_GONLY_SUPPORT_RATE_START   MODE_A_SUPPORT_RATE_START
-#define MODE_GONLY_SUPPORT_RATE_STOP    MODE_A_SUPPORT_RATE_STOP
-
-#define MODE_B_SUPPORT_RATE_START       ((s32) 0)
-#define MODE_B_SUPPORT_RATE_STOP        ((s32) 3)
-
-#define MODE_G_SUPPORT_RATE_START       ((s32) 0)
-#define MODE_G_SUPPORT_RATE_STOP        ((s32) 11)
-
-#define MODE_GHT20_SUPPORT_RATE_START   ((s32) 0)
-#define MODE_GHT20_SUPPORT_RATE_STOP    ((s32) 19)
-
-#define MAX_NUMBER_OF_SUPPORT_RATES     (MODE_GHT20_SUPPORT_RATE_STOP + 1)
-
-/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
-const u8 up_to_ac[]= {
-                WMM_AC_BE,
-                WMM_AC_BK,
-                WMM_AC_BK,
-                WMM_AC_BE,
-                WMM_AC_VI,
-                WMM_AC_VI,
-                WMM_AC_VO,
-                WMM_AC_VO,
-            };
-
-/* This stuff is used when we want a simple layer-3 visibility */
-typedef PREPACK struct _iphdr {
-    u8 ip_ver_hdrlen;          /* version and hdr length */
-    u8 ip_tos;                 /* type of service */
-    u16 ip_len;                 /* total length */
-    u16 ip_id;                  /* identification */
-    s16 ip_off;                 /* fragment offset field */
-#define IP_DF 0x4000                    /* dont fragment flag */
-#define IP_MF 0x2000                    /* more fragments flag */
-#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
-    u8 ip_ttl;                 /* time to live */
-    u8 ip_p;                   /* protocol */
-    u16 ip_sum;                 /* checksum */
-    u8 ip_src[4];              /* source and dest address */
-    u8 ip_dst[4];
-} POSTPACK iphdr;
-
-static s16 rssi_event_value = 0;
-static s16 snr_event_value = 0;
-
-bool is_probe_ssid = false;
-
-void *
-wmi_init(void *devt)
-{
-    struct wmi_t *wmip;
-
-    A_REGISTER_MODULE_DEBUG_INFO(wmi);
-
-    wmip = A_MALLOC (sizeof(struct wmi_t));
-    if (wmip == NULL) {
-        return (NULL);
-    }
-    A_MEMZERO(wmip, sizeof(struct wmi_t ));
-#ifdef THREAD_X
-    INIT_WMI_LOCK(wmip);
-#else
-       A_MUTEX_INIT(&wmip->wmi_lock);
-#endif
-    wmip->wmi_devt = devt;
-    wlan_node_table_init(wmip, &wmip->wmi_scan_table);
-    wmi_qos_state_init(wmip);
-
-    wmip->wmi_powerMode = REC_POWER;
-    wmip->wmi_phyMode = WMI_11G_MODE;
-
-    wmip->wmi_pair_crypto_type  = NONE_CRYPT;
-    wmip->wmi_grp_crypto_type   = NONE_CRYPT;
-
-    wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
-    wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
-
-    return (wmip);
-}
-
-void
-wmi_qos_state_init(struct wmi_t *wmip)
-{
-    u8 i;
-
-    if (wmip == NULL) {
-        return;
-    }
-    LOCK_WMI(wmip);
-
-    /* Initialize QoS States */
-    wmip->wmi_numQoSStream = 0;
-
-    wmip->wmi_fatPipeExists = 0;
-
-    for (i=0; i < WMM_NUM_AC; i++) {
-        wmip->wmi_streamExistsForAC[i]=0;
-    }
-
-    UNLOCK_WMI(wmip);
-
-    A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
-}
-
-void
-wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
-{
-    A_ASSERT( eid != ENDPOINT_UNUSED);
-    wmip->wmi_endpoint_id = eid;
-}
-
-HTC_ENDPOINT_ID
-wmi_get_control_ep(struct wmi_t * wmip)
-{
-    return(wmip->wmi_endpoint_id);
-}
-
-void
-wmi_shutdown(struct wmi_t *wmip)
-{
-    if (wmip != NULL) {
-        wlan_node_table_cleanup(&wmip->wmi_scan_table);
-        if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
-#ifdef THREAD_X
-            DELETE_WMI_LOCK(&wmip);
-#else
-            A_MUTEX_DELETE(&wmip->wmi_lock);
-#endif
-        }
-        kfree(wmip);
-    }
-}
-
-/*
- *  performs DIX to 802.3 encapsulation for transmit packets.
- *  uses passed in buffer.  Returns buffer or NULL if failed.
- *  Assumes the entire DIX header is contigous and that there is
- *  enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
- */
-int
-wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
-{
-    u8 *datap;
-    u16 typeorlen;
-    ATH_MAC_HDR      macHdr;
-    ATH_LLC_SNAP_HDR *llcHdr;
-
-    A_ASSERT(osbuf != NULL);
-
-    if (A_NETBUF_HEADROOM(osbuf) <
-        (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
-    {
-        return A_NO_MEMORY;
-    }
-
-    datap = A_NETBUF_DATA(osbuf);
-
-    typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
-
-    if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
-        /*
-         * packet is already in 802.3 format - return success
-         */
-        A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
-        return (0);
-    }
-
-    /*
-     * Save mac fields and length to be inserted later
-     */
-    memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
-    memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
-    macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
-                                  sizeof(ATH_LLC_SNAP_HDR));
-
-    /*
-     * Make room for LLC+SNAP headers
-     */
-    if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
-        return A_NO_MEMORY;
-    }
-    datap = A_NETBUF_DATA(osbuf);
-
-    memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
-
-    llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
-    llcHdr->dsap      = 0xAA;
-    llcHdr->ssap      = 0xAA;
-    llcHdr->cntl      = 0x03;
-    llcHdr->orgCode[0] = 0x0;
-    llcHdr->orgCode[1] = 0x0;
-    llcHdr->orgCode[2] = 0x0;
-    llcHdr->etherType = typeorlen;
-
-    return (0);
-}
-
-int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS)
-{
-    switch(*pVersion){
-       case 0:
-               return (0);
-       case WMI_META_VERSION_1:
-               {
-               WMI_TX_META_V1     *pV1= NULL;
-               A_ASSERT(osbuf != NULL);
-               if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
-                       return A_NO_MEMORY;
-               }
-
-               pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
-               /* the pktID is used in conjunction with txComplete messages
-               * allowing the target to notify which tx requests have been
-               * completed and how. */
-               pV1->pktID = 0;
-               /* the ratePolicyID allows the host to specify which rate policy
-               * to use for transmitting this packet. 0 means use default behavior. */
-               pV1->ratePolicyID = 0;
-               A_ASSERT(pVersion != NULL);
-               /* the version must be used to populate the meta field of the WMI_DATA_HDR */
-               *pVersion = WMI_META_VERSION_1;
-               return (0);
-               }
-       case WMI_META_VERSION_2:
-               {
-               WMI_TX_META_V2 *pV2 ;
-               A_ASSERT(osbuf != NULL);
-               if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
-                       return A_NO_MEMORY;
-               }
-               pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
-               memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
-               return (0);
-               }
-       default:
-               return (0);
-    }
-}
-
-/* Adds a WMI data header */
-int
-wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData,
-                    WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS)
-{
-    WMI_DATA_HDR     *dtHdr;
-//    u8 metaVersion = 0;
-    int status;
-
-    A_ASSERT(osbuf != NULL);
-
-    /* adds the meta data field after the wmi data hdr. If metaVersion
-     * is returns 0 then no meta field was added. */
-    if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) {
-        return status;
-    }
-
-    if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
-        return A_NO_MEMORY;
-    }
-
-    dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
-    A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
-
-    WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
-    WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
-
-    if (bMoreData) {
-        WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
-    }
-
-    WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
-
-    dtHdr->info3 = 0;
-
-    return (0);
-}
-
-
-u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled)
-{
-    u8 *datap;
-    u8 trafficClass = WMM_AC_BE;
-    u16 ipType = IP_ETHERTYPE;
-    WMI_DATA_HDR    *dtHdr;
-    u8 streamExists = 0;
-    u8 userPriority;
-    u32 hdrsize, metasize;
-    ATH_LLC_SNAP_HDR    *llcHdr;
-
-    WMI_CREATE_PSTREAM_CMD  cmd;
-
-    A_ASSERT(osbuf != NULL);
-
-    //
-    // Initialize header size
-    //
-    hdrsize = 0;
-
-    datap = A_NETBUF_DATA(osbuf);
-    dtHdr = (WMI_DATA_HDR *)datap;
-    metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
-
-    if (!wmmEnabled)
-    {
-            /* If WMM is disabled all traffic goes as BE traffic */
-        userPriority = 0;
-    }
-    else
-    {
-        if (processDot11Hdr)
-        {
-             hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
-             llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
-                          hdrsize);
-
-
-        }
-        else
-        {
-            llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
-                          sizeof(ATH_MAC_HDR));
-        }
-
-        if (llcHdr->etherType == A_CPU2BE16(ipType))
-        {
-            /* Extract the endpoint info from the TOS field in the IP header */
-
-            userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
-        }
-        else
-        {
-            userPriority = layer2Priority & 0x7;
-        }
-    }
-
-
-    /* workaround for WMM S5 */
-    if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
-    {
-        userPriority = 1;
-    }
-
-    trafficClass = convert_userPriority_to_trafficClass(userPriority);
-
-    WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
-    /* lower 3-bits are 802.1d priority */
-    //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
-
-    LOCK_WMI(wmip);
-    streamExists = wmip->wmi_fatPipeExists;
-    UNLOCK_WMI(wmip);
-
-    if (!(streamExists & (1 << trafficClass)))
-    {
-
-        A_MEMZERO(&cmd, sizeof(cmd));
-        cmd.trafficClass = trafficClass;
-        cmd.userPriority = userPriority;
-        cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
-            /* Implicit streams are created with TSID 0xFF */
-
-        cmd.tsid = WMI_IMPLICIT_PSTREAM;
-        wmi_create_pstream_cmd(wmip, &cmd);
-    }
-
-    return trafficClass;
-}
-
-int
-wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
-{
-    u8 *datap;
-    u16 typeorlen;
-    ATH_MAC_HDR      macHdr;
-    ATH_LLC_SNAP_HDR *llcHdr;
-    struct           ieee80211_frame *wh;
-    u32 hdrsize;
-
-    A_ASSERT(osbuf != NULL);
-
-    if (A_NETBUF_HEADROOM(osbuf) <
-        (sizeof(struct ieee80211_qosframe) +  sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
-    {
-        return A_NO_MEMORY;
-    }
-
-    datap = A_NETBUF_DATA(osbuf);
-
-    typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
-
-    if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
-/*
-         * packet is already in 802.3 format - return success
-         */
-        A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
-        goto AddDot11Hdr;
-    }
-
-    /*
-     * Save mac fields and length to be inserted later
-     */
-    memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
-    memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
-    macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
-                                  sizeof(ATH_LLC_SNAP_HDR));
-
-    // Remove the Ethernet hdr
-    A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
-    /*
-     * Make room for LLC+SNAP headers
-     */
-    if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
-        return A_NO_MEMORY;
-    }
-    datap = A_NETBUF_DATA(osbuf);
-
-    llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
-    llcHdr->dsap       = 0xAA;
-    llcHdr->ssap       = 0xAA;
-    llcHdr->cntl       = 0x03;
-    llcHdr->orgCode[0] = 0x0;
-    llcHdr->orgCode[1] = 0x0;
-    llcHdr->orgCode[2] = 0x0;
-    llcHdr->etherType  = typeorlen;
-
-AddDot11Hdr:
-    /* Make room for 802.11 hdr */
-    if (wmip->wmi_is_wmm_enabled)
-    {
-        hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
-        if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
-        {
-            return A_NO_MEMORY;
-        }
-        wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
-        wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
-    }
-    else
-    {
-        hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32));
-        if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
-        {
-            return A_NO_MEMORY;
-        }
-        wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
-        wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
-    }
-    /* Setup the SA & DA */
-    IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
-
-    if (mode == INFRA_NETWORK) {
-        IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
-    }
-    else if (mode == ADHOC_NETWORK) {
-        IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
-    }
-
-    return (0);
-}
-
-int
-wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
-{
-    u8 *datap;
-    struct           ieee80211_frame *pwh,wh;
-    u8 type,subtype;
-    ATH_LLC_SNAP_HDR *llcHdr;
-    ATH_MAC_HDR      macHdr;
-    u32 hdrsize;
-
-    A_ASSERT(osbuf != NULL);
-    datap = A_NETBUF_DATA(osbuf);
-
-    pwh = (struct ieee80211_frame *)datap;
-    type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
-    subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
-
-    memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame));
-
-    /* strip off the 802.11 hdr*/
-    if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
-        hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
-        A_NETBUF_PULL(osbuf, hdrsize);
-    } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
-        A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
-    }
-
-    datap = A_NETBUF_DATA(osbuf);
-    llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
-
-    macHdr.typeOrLen = llcHdr->etherType;
-    A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
-    A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
-
-    switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
-    case IEEE80211_FC1_DIR_NODS:
-        IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
-        IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
-        break;
-    case IEEE80211_FC1_DIR_TODS:
-        IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
-        IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
-        break;
-    case IEEE80211_FC1_DIR_FROMDS:
-        IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
-        IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
-        break;
-    case IEEE80211_FC1_DIR_DSTODS:
-        break;
-    }
-
-    // Remove the LLC Hdr.
-    A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
-
-    // Insert the ATH MAC hdr.
-
-    A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
-    datap = A_NETBUF_DATA(osbuf);
-
-    memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR));
-
-    return 0;
-}
-
-/*
- *  performs 802.3 to DIX encapsulation for received packets.
- *  Assumes the entire 802.3 header is contigous.
- */
-int
-wmi_dot3_2_dix(void *osbuf)
-{
-    u8 *datap;
-    ATH_MAC_HDR      macHdr;
-    ATH_LLC_SNAP_HDR *llcHdr;
-
-    A_ASSERT(osbuf != NULL);
-    datap = A_NETBUF_DATA(osbuf);
-
-    memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR));
-    llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
-    macHdr.typeOrLen = llcHdr->etherType;
-
-    if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
-        return A_NO_MEMORY;
-    }
-
-    datap = A_NETBUF_DATA(osbuf);
-
-    memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
-
-    return (0);
-}
-
-/*
- * Removes a WMI data header
- */
-int
-wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
-{
-    A_ASSERT(osbuf != NULL);
-
-    return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
-}
-
-void
-wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
-{
-    wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
-}
-
-/*
- * WMI Extended Event received from Target.
- */
-int
-wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
-{
-    WMIX_CMD_HDR *cmd;
-    u16 id;
-    u8 *datap;
-    u32 len;
-    int status = 0;
-
-    if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
-        A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
-        wmip->wmi_stats.cmd_len_err++;
-        return A_ERROR;
-    }
-
-    cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
-    id = cmd->commandId;
-
-    if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
-        A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
-        wmip->wmi_stats.cmd_len_err++;
-        return A_ERROR;
-    }
-
-    datap = A_NETBUF_DATA(osbuf);
-    len = A_NETBUF_LEN(osbuf);
-
-    switch (id) {
-    case (WMIX_DSETOPENREQ_EVENTID):
-        status = wmi_dset_open_req_rx(wmip, datap, len);
-        break;
-#ifdef CONFIG_HOST_DSET_SUPPORT
-    case (WMIX_DSETCLOSE_EVENTID):
-        status = wmi_dset_close_rx(wmip, datap, len);
-        break;
-    case (WMIX_DSETDATAREQ_EVENTID):
-        status = wmi_dset_data_req_rx(wmip, datap, len);
-        break;
-#endif /* CONFIG_HOST_DSET_SUPPORT */
-    case (WMIX_HB_CHALLENGE_RESP_EVENTID):
-        wmi_hbChallengeResp_rx(wmip, datap, len);
-        break;
-    case (WMIX_DBGLOG_EVENTID):
-        wmi_dbglog_event_rx(wmip, datap, len);
-        break;
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-    case (WMIX_PROF_COUNT_EVENTID):
-        wmi_prof_count_rx(wmip, datap, len);
-        break;
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-    default:
-        A_DPRINTF(DBG_WMI|DBG_ERROR,
-            (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
-        wmip->wmi_stats.cmd_id_err++;
-        status = A_ERROR;
-        break;
-    }
-
-    return status;
-}
-
-/*
- * Control Path
- */
-u32 cmdRecvNum;
-
-int
-wmi_control_rx(struct wmi_t *wmip, void *osbuf)
-{
-    WMI_CMD_HDR *cmd;
-    u16 id;
-    u8 *datap;
-    u32 len, i, loggingReq;
-    int status = 0;
-
-    A_ASSERT(osbuf != NULL);
-    if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
-        A_NETBUF_FREE(osbuf);
-        A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
-        wmip->wmi_stats.cmd_len_err++;
-        return A_ERROR;
-    }
-
-    cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
-    id = cmd->commandId;
-
-    if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
-        A_NETBUF_FREE(osbuf);
-        A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
-        wmip->wmi_stats.cmd_len_err++;
-        return A_ERROR;
-    }
-
-    datap = A_NETBUF_DATA(osbuf);
-    len = A_NETBUF_LEN(osbuf);
-
-    loggingReq = 0;
-
-    ar6000_get_driver_cfg(wmip->wmi_devt,
-                    AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
-                    &loggingReq);
-
-    if(loggingReq) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
-        for(i = 0; i < len; i++)
-            AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
-    }
-
-    LOCK_WMI(wmip);
-    cmdRecvNum++;
-    UNLOCK_WMI(wmip);
-
-    switch (id) {
-    case (WMI_GET_BITRATE_CMDID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
-        status = wmi_bitrate_reply_rx(wmip, datap, len);
-        break;
-    case (WMI_GET_CHANNEL_LIST_CMDID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
-        status = wmi_channelList_reply_rx(wmip, datap, len);
-        break;
-    case (WMI_GET_TX_PWR_CMDID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
-        status = wmi_txPwr_reply_rx(wmip, datap, len);
-        break;
-    case (WMI_READY_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
-        status = wmi_ready_event_rx(wmip, datap, len);
-        A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
-        break;
-    case (WMI_CONNECT_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
-        status = wmi_connect_event_rx(wmip, datap, len);
-        break;
-    case (WMI_DISCONNECT_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
-        status = wmi_disconnect_event_rx(wmip, datap, len);
-        break;
-    case (WMI_PEER_NODE_EVENTID):
-        A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
-        status = wmi_peer_node_event_rx(wmip, datap, len);
-        break;
-    case (WMI_TKIP_MICERR_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
-        status = wmi_tkip_micerr_event_rx(wmip, datap, len);
-        break;
-    case (WMI_BSSINFO_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
-        {
-            /*
-             * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
-             * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
-             * and reconstruct the WMI_BSS_INFO_HDR in its place
-            */
-            WMI_BSS_INFO_HDR2 bih2;
-            WMI_BSS_INFO_HDR *bih;
-            memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
-
-            A_NETBUF_PUSH(osbuf, 4);
-            datap = A_NETBUF_DATA(osbuf);
-            len = A_NETBUF_LEN(osbuf);
-            bih = (WMI_BSS_INFO_HDR *)datap;
-
-            bih->channel = bih2.channel;
-            bih->frameType = bih2.frameType;
-            bih->snr = bih2.snr;
-            bih->rssi = bih2.snr - 95;
-            bih->ieMask = bih2.ieMask;
-            memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
-
-            status = wmi_bssInfo_event_rx(wmip, datap, len);
-        }
-        break;
-    case (WMI_REGDOMAIN_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
-        status = wmi_regDomain_event_rx(wmip, datap, len);
-        break;
-    case (WMI_PSTREAM_TIMEOUT_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
-        status = wmi_pstream_timeout_event_rx(wmip, datap, len);
-        break;
-    case (WMI_NEIGHBOR_REPORT_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
-        status = wmi_neighborReport_event_rx(wmip, datap, len);
-        break;
-    case (WMI_SCAN_COMPLETE_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
-        status = wmi_scanComplete_rx(wmip, datap, len);
-        break;
-    case (WMI_CMDERROR_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
-        status = wmi_errorEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_REPORT_STATISTICS_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
-        status = wmi_statsEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_RSSI_THRESHOLD_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
-        status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_ERROR_REPORT_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
-        status = wmi_reportErrorEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_OPT_RX_FRAME_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
-        status = wmi_opt_frame_event_rx(wmip, datap, len);
-        break;
-    case (WMI_REPORT_ROAM_TBL_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
-        status = wmi_roam_tbl_event_rx(wmip, datap, len);
-        break;
-    case (WMI_EXTENSION_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
-        status = wmi_control_rx_xtnd(wmip, osbuf);
-        break;
-    case (WMI_CAC_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
-        status = wmi_cac_event_rx(wmip, datap, len);
-        break;
-    case (WMI_CHANNEL_CHANGE_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
-        status = wmi_channel_change_event_rx(wmip, datap, len);
-        break;
-    case (WMI_REPORT_ROAM_DATA_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
-        status = wmi_roam_data_event_rx(wmip, datap, len);
-        break;
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-    case (WMI_TEST_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
-        status = wmi_tcmd_test_report_rx(wmip, datap, len);
-        break;
-#endif
-    case (WMI_GET_FIXRATES_CMDID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
-        status = wmi_ratemask_reply_rx(wmip, datap, len);
-        break;
-    case (WMI_TX_RETRY_ERR_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
-        status = wmi_txRetryErrEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_SNR_THRESHOLD_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
-        status = wmi_snrThresholdEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_LQ_THRESHOLD_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
-        status = wmi_lqThresholdEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_APLIST_EVENTID):
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
-        status = wmi_aplistEvent_rx(wmip, datap, len);
-        break;
-    case (WMI_GET_KEEPALIVE_CMDID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
-        status = wmi_keepalive_reply_rx(wmip, datap, len);
-        break;
-    case (WMI_GET_WOW_LIST_EVENTID):
-        status = wmi_get_wow_list_event_rx(wmip, datap, len);
-        break;
-    case (WMI_GET_PMKID_LIST_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
-        status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
-        break;
-    case (WMI_PSPOLL_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
-        status = wmi_pspoll_event_rx(wmip, datap, len);
-        break;
-    case (WMI_DTIMEXPIRY_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
-        status = wmi_dtimexpiry_event_rx(wmip, datap, len);
-        break;
-    case (WMI_SET_PARAMS_REPLY_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
-        status = wmi_set_params_event_rx(wmip, datap, len);
-        break;
-    case (WMI_ADDBA_REQ_EVENTID):
-        status = wmi_addba_req_event_rx(wmip, datap, len);
-        break;
-    case (WMI_ADDBA_RESP_EVENTID):
-        status = wmi_addba_resp_event_rx(wmip, datap, len);
-        break;
-    case (WMI_DELBA_REQ_EVENTID):
-        status = wmi_delba_req_event_rx(wmip, datap, len);
-        break;
-       case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
-           A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
-       status = wmi_btcoex_config_event_rx(wmip, datap, len);
-           break;
-       case (WMI_REPORT_BTCOEX_STATS_EVENTID):
-           A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
-       status = wmi_btcoex_stats_event_rx(wmip, datap, len);
-           break;
-    case (WMI_TX_COMPLETE_EVENTID):
-        {
-            int index;
-            TX_COMPLETE_MSG_V1 *pV1;
-            WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
-            A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
-
-            for(index = 0 ; index < pEv->numMessages ; index++) {
-                pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
-                A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
-            }
-        }
-        break;
-    case (WMI_HCI_EVENT_EVENTID):
-        status = wmi_hci_event_rx(wmip, datap, len);
-        break;
-#ifdef WAPI_ENABLE
-    case (WMI_WAPI_REKEY_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
-        status = wmi_wapi_rekey_event_rx(wmip, datap, len);
-        break;
-#endif
-    default:
-        A_DPRINTF(DBG_WMI|DBG_ERROR,
-            (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
-        wmip->wmi_stats.cmd_id_err++;
-        status = A_ERROR;
-        break;
-    }
-
-    A_NETBUF_FREE(osbuf);
-
-    return status;
-}
-
-/* Send a "simple" wmi command -- one with no arguments */
-static int
-wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
-{
-    void *osbuf;
-
-    osbuf = A_NETBUF_ALLOC(0);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
-}
-
-/* Send a "simple" extended wmi command -- one with no arguments.
-   Enabling this command only if GPIO or profiling support is enabled.
-   This is to suppress warnings on some platforms */
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-static int
-wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
-{
-    void *osbuf;
-
-    osbuf = A_NETBUF_ALLOC(0);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
-}
-#endif
-
-static int
-wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
-
-    if (len < sizeof(WMI_READY_EVENT)) {
-        return A_EINVAL;
-    }
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-    wmip->wmi_ready = true;
-    A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
-                      ev->sw_version, ev->abi_version);
-
-    return 0;
-}
-
-#define LE_READ_4(p)                            \
-    ((u32)                            \
-     ((((u8 *)(p))[0]      ) | (((u8 *)(p))[1] <<  8) | \
-      (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
-
-static int __inline
-iswmmoui(const u8 *frm)
-{
-    return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
-}
-
-static int __inline
-iswmmparam(const u8 *frm)
-{
-    return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
-}
-
-
-static int
-wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_CONNECT_EVENT *ev;
-    u8 *pie,*peie;
-
-    if (len < sizeof(WMI_CONNECT_EVENT))
-    {
-        return A_EINVAL;
-    }
-    ev = (WMI_CONNECT_EVENT *)datap;
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
-        DBGARG, ev->channel,
-        ev->bssid[0], ev->bssid[1], ev->bssid[2],
-        ev->bssid[3], ev->bssid[4], ev->bssid[5]));
-
-    memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
-
-    /* initialize pointer to start of assoc rsp IEs */
-    pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
-                            sizeof(u16)  +  /* capinfo*/
-                            sizeof(u16)  +  /* status Code */
-                            sizeof(u16)  ;  /* associd */
-
-    /* initialize pointer to end of assoc rsp IEs */
-    peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
-
-    while (pie < peie)
-    {
-        switch (*pie)
-        {
-            case IEEE80211_ELEMID_VENDOR:
-                if (iswmmoui(pie))
-                {
-                    if(iswmmparam (pie))
-                    {
-                        wmip->wmi_is_wmm_enabled = true;
-                    }
-                }
-            break;
-        }
-
-        if (wmip->wmi_is_wmm_enabled)
-        {
-            break;
-        }
-        pie += pie[1] + 2;
-    }
-
-    A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
-                         ev->listenInterval, ev->beaconInterval,
-                         (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
-                         ev->assocReqLen, ev->assocRespLen,
-                         ev->assocInfo);
-
-    return 0;
-}
-
-static int
-wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_REG_DOMAIN_EVENT *ev;
-
-    if (len < sizeof(*ev)) {
-        return A_EINVAL;
-    }
-    ev = (WMI_REG_DOMAIN_EVENT *)datap;
-
-    A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
-
-    return 0;
-}
-
-static int
-wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_NEIGHBOR_REPORT_EVENT *ev;
-    int numAps;
-
-    if (len < sizeof(*ev)) {
-        return A_EINVAL;
-    }
-    ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
-    numAps = ev->numberOfAps;
-
-    if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
-        return A_EINVAL;
-    }
-
-    A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
-
-    return 0;
-}
-
-static int
-wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_DISCONNECT_EVENT *ev;
-    wmip->wmi_traffic_class = 100;
-
-    if (len < sizeof(WMI_DISCONNECT_EVENT)) {
-        return A_EINVAL;
-    }
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    ev = (WMI_DISCONNECT_EVENT *)datap;
-
-    A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
-
-    wmip->wmi_is_wmm_enabled = false;
-    wmip->wmi_pair_crypto_type = NONE_CRYPT;
-    wmip->wmi_grp_crypto_type = NONE_CRYPT;
-
-    A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
-                            ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
-
-    return 0;
-}
-
-static int
-wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_PEER_NODE_EVENT *ev;
-
-    if (len < sizeof(WMI_PEER_NODE_EVENT)) {
-        return A_EINVAL;
-    }
-    ev = (WMI_PEER_NODE_EVENT *)datap;
-    if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
-        A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
-    } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
-        A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
-    }
-
-    A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
-
-    return 0;
-}
-
-static int
-wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_TKIP_MICERR_EVENT *ev;
-
-    if (len < sizeof(*ev)) {
-        return A_EINVAL;
-    }
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    ev = (WMI_TKIP_MICERR_EVENT *)datap;
-    A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
-
-    return 0;
-}
-
-static int
-wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    bss_t *bss = NULL;
-    WMI_BSS_INFO_HDR *bih;
-    u8 *buf;
-    u32 nodeCachingAllowed = 1;
-    u8 cached_ssid_len = 0;
-    u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
-    u8 beacon_ssid_len = 0;
-
-    if (len <= sizeof(WMI_BSS_INFO_HDR)) {
-        return A_EINVAL;
-    }
-
-    bih = (WMI_BSS_INFO_HDR *)datap;
-    bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
-
-    if (bih->rssi > 0) {
-        if (NULL == bss)
-            return 0;  //no node found in the table, just drop the node with incorrect RSSI
-        else
-            bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
-    }
-
-    A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
-    /* What is driver config for wlan node caching? */
-    if(ar6000_get_driver_cfg(wmip->wmi_devt,
-                    AR6000_DRIVER_CFG_GET_WLANNODECACHING,
-                    &nodeCachingAllowed) != 0) {
-        wmi_node_return(wmip, bss);
-        return A_EINVAL;
-    }
-
-    if(!nodeCachingAllowed) {
-        wmi_node_return(wmip, bss);
-        return 0;
-    }
-
-    buf = datap + sizeof(WMI_BSS_INFO_HDR);
-    len -= sizeof(WMI_BSS_INFO_HDR);
-
-       A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
-               "bssid \"%pM\"\n", DBGARG, bih->channel,
-               (unsigned char) bih->rssi, bih->bssid));
-
-    if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
-        wmi_node_return(wmip, bss);
-        return 0;
-    }
-
-    if (bss != NULL) {
-        /*
-         * Free up the node.  Not the most efficient process given
-         * we are about to allocate a new node but it is simple and should be
-         * adequate.
-         */
-
-        /* In case of hidden AP, beacon will not have ssid,
-         * but a directed probe response will have it,
-         * so cache the probe-resp-ssid if already present. */
-        if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
-        {
-            u8 *ie_ssid;
-
-            ie_ssid = bss->ni_cie.ie_ssid;
-            if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
-            {
-                cached_ssid_len = ie_ssid[1];
-                memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
-            }
-        }
-
-        /*
-         * Use the current average rssi of associated AP base on assumpiton
-         * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
-         * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
-         * The average value of RSSI give end-user better feeling for instance value of scan result
-         * It also sync up RSSI info in GUI between scan result and RSSI signal icon
-         */
-        if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
-            bih->rssi = bss->ni_rssi;
-            bih->snr  = bss->ni_snr;
-        }
-
-        wlan_node_reclaim(&wmip->wmi_scan_table, bss);
-    }
-
-    /*  beacon/probe response frame format
-     *  [8] time stamp
-     *  [2] beacon interval
-     *  [2] capability information
-     *  [tlv] ssid */
-    beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
-
-    /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
-    if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
-        (0 != cached_ssid_len) &&
-        (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
-    {
-        len += (cached_ssid_len - beacon_ssid_len);
-    }
-
-    bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
-    if (bss == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    bss->ni_snr        = bih->snr;
-    bss->ni_rssi       = bih->rssi;
-    A_ASSERT(bss->ni_buf != NULL);
-
-    /* In case of hidden AP, beacon will not have ssid,
-     * but a directed probe response will have it,
-     * so place the cached-ssid(probe-resp) in the bssinfo. */
-    if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
-         (0 != cached_ssid_len) &&
-         (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
-    {
-        u8 *ni_buf = bss->ni_buf;
-        int buf_len = len;
-
-        /* copy the first 14 bytes such as
-         * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
-        memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
-
-        ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
-        ni_buf += (SSID_IE_LEN_INDEX + 1);
-
-        buf += (SSID_IE_LEN_INDEX + 1);
-        buf_len -= (SSID_IE_LEN_INDEX + 1);
-
-        /* copy the cached ssid */
-        memcpy(ni_buf, cached_ssid_buf, cached_ssid_len);
-        ni_buf += cached_ssid_len;
-
-        buf += beacon_ssid_len;
-        buf_len -= beacon_ssid_len;
-
-        if (cached_ssid_len > beacon_ssid_len)
-            buf_len -= (cached_ssid_len - beacon_ssid_len);
-
-        /* now copy the rest of bytes */
-        memcpy(ni_buf, buf, buf_len);
-    }
-    else
-        memcpy(bss->ni_buf, buf, len);
-
-    bss->ni_framelen = len;
-    if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) {
-        wlan_node_free(bss);
-        return A_EINVAL;
-    }
-
-    /*
-     * Update the frequency in ie_chan, overwriting of channel number
-     * which is done in wlan_parse_beacon
-     */
-    bss->ni_cie.ie_chan = bih->channel;
-    wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
-
-    return 0;
-}
-
-static int
-wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    bss_t *bss;
-    WMI_OPT_RX_INFO_HDR *bih;
-    u8 *buf;
-
-    if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
-        return A_EINVAL;
-    }
-
-    bih = (WMI_OPT_RX_INFO_HDR *)datap;
-    buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
-    len -= sizeof(WMI_OPT_RX_INFO_HDR);
-
-    A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
-        bih->bssid[4], bih->bssid[5]));
-
-    bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
-    if (bss != NULL) {
-        /*
-         * Free up the node.  Not the most efficient process given
-         * we are about to allocate a new node but it is simple and should be
-         * adequate.
-         */
-        wlan_node_reclaim(&wmip->wmi_scan_table, bss);
-    }
-
-    bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
-    if (bss == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    bss->ni_snr        = bih->snr;
-    bss->ni_cie.ie_chan = bih->channel;
-    A_ASSERT(bss->ni_buf != NULL);
-    memcpy(bss->ni_buf, buf, len);
-    wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
-
-    return 0;
-}
-
-    /* This event indicates inactivity timeout of a fatpipe(pstream)
-     * at the target
-     */
-static int
-wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_PSTREAM_TIMEOUT_EVENT *ev;
-
-    if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
-        return A_EINVAL;
-    }
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
-
-    ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
-
-        /* When the pstream (fat pipe == AC) timesout, it means there were no
-         * thinStreams within this pstream & it got implicitly created due to
-         * data flow on this AC. We start the inactivity timer only for
-         * implicitly created pstream. Just reset the host state.
-     */
-        /* Set the activeTsids for this AC to 0 */
-    LOCK_WMI(wmip);
-    wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
-    wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
-    UNLOCK_WMI(wmip);
-
-        /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
-    A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
-
-    return 0;
-}
-
-static int
-wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_BIT_RATE_REPLY *reply;
-    s32 rate;
-    u32 sgi,index;
-    /* 54149:
-     * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
-     * since there is difference in the length and to avoid returning
-     * error value.
-     */
-    if (len < sizeof(WMI_BIT_RATE_REPLY)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_BIT_RATE_REPLY *)datap;
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
-
-    if (reply->rateIndex == (s8) RATE_AUTO) {
-        rate = RATE_AUTO;
-    } else {
-        // the SGI state is stored as the MSb of the rateIndex
-        index = reply->rateIndex & 0x7f;
-        sgi = (reply->rateIndex & 0x80)? 1:0;
-        rate = wmi_rateTable[index][sgi];
-    }
-
-    A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
-    return 0;
-}
-
-static int
-wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_FIX_RATES_REPLY *reply;
-
-    if (len < sizeof(WMI_FIX_RATES_REPLY)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_FIX_RATES_REPLY *)datap;
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
-
-    A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
-
-    return 0;
-}
-
-static int
-wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_CHANNEL_LIST_REPLY *reply;
-
-    if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_CHANNEL_LIST_REPLY *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
-                          reply->channelList);
-
-    return 0;
-}
-
-static int
-wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_TX_PWR_REPLY *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_TX_PWR_REPLY *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
-
-    return 0;
-}
-static int
-wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_GET_KEEPALIVE_CMD *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_GET_KEEPALIVE_CMD *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
-
-    return 0;
-}
-
-
-static int
-wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_DSETOPENREQ_EVENT *dsetopenreq;
-
-    if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
-        return A_EINVAL;
-    }
-    dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
-    A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
-                        dsetopenreq->dset_id,
-                        dsetopenreq->targ_dset_handle,
-                        dsetopenreq->targ_reply_fn,
-                        dsetopenreq->targ_reply_arg);
-
-    return 0;
-}
-
-#ifdef CONFIG_HOST_DSET_SUPPORT
-static int
-wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_DSETCLOSE_EVENT *dsetclose;
-
-    if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
-        return A_EINVAL;
-    }
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
-    A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
-
-    return 0;
-}
-
-static int
-wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_DSETDATAREQ_EVENT *dsetdatareq;
-
-    if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
-        return A_EINVAL;
-    }
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
-    A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
-                         dsetdatareq->access_cookie,
-                         dsetdatareq->offset,
-                         dsetdatareq->length,
-                         dsetdatareq->targ_buf,
-                         dsetdatareq->targ_reply_fn,
-                         dsetdatareq->targ_reply_arg);
-
-    return 0;
-}
-#endif /* CONFIG_HOST_DSET_SUPPORT */
-
-static int
-wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_SCAN_COMPLETE_EVENT *ev;
-
-    ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
-    if ((int)ev->status == 0) {
-        wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
-    }
-    A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status);
-    is_probe_ssid = false;
-
-    return 0;
-}
-
-/*
- * Target is reporting a programming error.  This is for
- * developer aid only.  Target only checks a few common violations
- * and it is responsibility of host to do all error checking.
- * Behavior of target after wmi error event is undefined.
- * A reset is recommended.
- */
-static int
-wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_CMD_ERROR_EVENT *ev;
-
-    ev = (WMI_CMD_ERROR_EVENT *)datap;
-    AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
-    switch (ev->errorCode) {
-    case (INVALID_PARAM):
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
-        break;
-    case (ILLEGAL_STATE):
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
-        break;
-    case (INTERNAL_ERROR):
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
-        break;
-    }
-
-    return 0;
-}
-
-
-static int
-wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
-
-    return 0;
-}
-
-static int
-wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_RSSI_THRESHOLD_EVENT *reply;
-    WMI_RSSI_THRESHOLD_VAL newThreshold;
-    WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
-    SQ_THRESHOLD_PARAMS *sq_thresh =
-           &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
-    u8 upper_rssi_threshold, lower_rssi_threshold;
-    s16 rssi;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-    newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
-    rssi = reply->rssi;
-
-    /*
-     * Identify the threshold breached and communicate that to the app. After
-     * that install a new set of thresholds based on the signal quality
-     * reported by the target
-     */
-    if (newThreshold) {
-        /* Upper threshold breached */
-        if (rssi < sq_thresh->upper_threshold[0]) {
-            A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
-                      " %d\n", DBGARG, rssi));
-        } else if ((rssi < sq_thresh->upper_threshold[1]) &&
-                   (rssi >= sq_thresh->upper_threshold[0]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
-        } else if ((rssi < sq_thresh->upper_threshold[2]) &&
-                   (rssi >= sq_thresh->upper_threshold[1]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
-        } else if ((rssi < sq_thresh->upper_threshold[3]) &&
-                   (rssi >= sq_thresh->upper_threshold[2]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
-        } else if ((rssi < sq_thresh->upper_threshold[4]) &&
-                   (rssi >= sq_thresh->upper_threshold[3]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
-        } else if ((rssi < sq_thresh->upper_threshold[5]) &&
-                   (rssi >= sq_thresh->upper_threshold[4]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
-        } else if (rssi >= sq_thresh->upper_threshold[5]) {
-            newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
-        }
-    } else {
-        /* Lower threshold breached */
-        if (rssi > sq_thresh->lower_threshold[0]) {
-            A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
-                      "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
-        } else if ((rssi > sq_thresh->lower_threshold[1]) &&
-                   (rssi <= sq_thresh->lower_threshold[0]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
-        } else if ((rssi > sq_thresh->lower_threshold[2]) &&
-                   (rssi <= sq_thresh->lower_threshold[1]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
-        } else if ((rssi > sq_thresh->lower_threshold[3]) &&
-                   (rssi <= sq_thresh->lower_threshold[2]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
-        } else if ((rssi > sq_thresh->lower_threshold[4]) &&
-                   (rssi <= sq_thresh->lower_threshold[3]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
-        } else if ((rssi > sq_thresh->lower_threshold[5]) &&
-                   (rssi <= sq_thresh->lower_threshold[4]))
-        {
-            newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
-        } else if (rssi <= sq_thresh->lower_threshold[5]) {
-            newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
-        }
-    }
-    /* Calculate and install the next set of thresholds */
-    lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
-                                      sq_thresh->lower_threshold_valid_count);
-    upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
-                                      sq_thresh->upper_threshold_valid_count);
-    /* Issue a wmi command to install the thresholds */
-    cmd.thresholdAbove1_Val = upper_rssi_threshold;
-    cmd.thresholdBelow1_Val = lower_rssi_threshold;
-    cmd.weight = sq_thresh->weight;
-    cmd.pollTime = sq_thresh->polling_interval;
-
-    rssi_event_value = rssi;
-
-    if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) {
-        A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
-                  DBGARG));
-    }
-
-    A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
-
-    return 0;
-}
-
-
-static int
-wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_TARGET_ERROR_REPORT_EVENT *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
-
-    return 0;
-}
-
-static int
-wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_CAC_EVENT *reply;
-    WMM_TSPEC_IE *tspec_ie;
-    u16 activeTsids;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_CAC_EVENT *)datap;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
-        (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
-        tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
-
-        wmi_delete_pstream_cmd(wmip, reply->ac,
-                (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
-    }
-    else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
-        u8 i;
-
-        /* following assumes that there is only one outstanding ADDTS request
-           when this event is received */
-        LOCK_WMI(wmip);
-        activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
-        UNLOCK_WMI(wmip);
-
-        for (i = 0; i < sizeof(activeTsids) * 8; i++) {
-            if ((activeTsids >> i) & 1) {
-                break;
-            }
-        }
-        if (i < (sizeof(activeTsids) * 8)) {
-            wmi_delete_pstream_cmd(wmip, reply->ac, i);
-        }
-    }
-        /*
-         * Ev#72990: Clear active tsids and Add missing handling
-         * for delete qos stream from AP
-         */
-    else if (reply->cac_indication == CAC_INDICATION_DELETE) {
-        u8 tsid = 0;
-
-        tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
-        tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
-        LOCK_WMI(wmip);
-        wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
-        activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
-        UNLOCK_WMI(wmip);
-
-
-        /* Indicate stream inactivity to driver layer only if all tsids
-         * within this AC are deleted.
-         */
-       if (!activeTsids) {
-           A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
-           wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
-        }
-    }
-
-    A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
-                reply->cac_indication, reply->statusCode,
-                reply->tspecSuggestion);
-
-    return 0;
-}
-
-static int
-wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_CHANNEL_CHANGE_EVENT *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
-                               reply->newChannel);
-
-    return 0;
-}
-
-static int
-wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_HB_CHALLENGE_RESP_EVENT *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
-
-    A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
-
-    return 0;
-}
-
-static int
-wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_TARGET_ROAM_TBL *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_TARGET_ROAM_TBL *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
-
-    return 0;
-}
-
-static int
-wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_TARGET_ROAM_DATA *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_TARGET_ROAM_DATA *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
-
-    return 0;
-}
-
-static int
-wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
-        return A_EINVAL;
-    }
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
-
-    return 0;
-}
-
-static int
-wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_SNR_THRESHOLD_EVENT *reply;
-    SQ_THRESHOLD_PARAMS *sq_thresh =
-           &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
-    WMI_SNR_THRESHOLD_VAL newThreshold;
-    WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
-    u8 upper_snr_threshold, lower_snr_threshold;
-    s16 snr;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
-    snr = reply->snr;
-    /*
-     * Identify the threshold breached and communicate that to the app. After
-     * that install a new set of thresholds based on the signal quality
-     * reported by the target
-     */
-    if (newThreshold) {
-        /* Upper threshold breached */
-        if (snr < sq_thresh->upper_threshold[0]) {
-            A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
-                     "%d\n", DBGARG, snr));
-        } else if ((snr < sq_thresh->upper_threshold[1]) &&
-                   (snr >= sq_thresh->upper_threshold[0]))
-        {
-            newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
-        } else if ((snr < sq_thresh->upper_threshold[2]) &&
-                   (snr >= sq_thresh->upper_threshold[1]))
-        {
-            newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
-        } else if ((snr < sq_thresh->upper_threshold[3]) &&
-                   (snr >= sq_thresh->upper_threshold[2]))
-        {
-            newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
-        } else if (snr >= sq_thresh->upper_threshold[3]) {
-            newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
-        }
-    } else {
-        /* Lower threshold breached */
-        if (snr > sq_thresh->lower_threshold[0]) {
-            A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
-                      "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
-        } else if ((snr > sq_thresh->lower_threshold[1]) &&
-                   (snr <= sq_thresh->lower_threshold[0]))
-        {
-            newThreshold = WMI_SNR_THRESHOLD4_BELOW;
-        } else if ((snr > sq_thresh->lower_threshold[2]) &&
-                   (snr <= sq_thresh->lower_threshold[1]))
-        {
-            newThreshold = WMI_SNR_THRESHOLD3_BELOW;
-        } else if ((snr > sq_thresh->lower_threshold[3]) &&
-                   (snr <= sq_thresh->lower_threshold[2]))
-        {
-            newThreshold = WMI_SNR_THRESHOLD2_BELOW;
-        } else if (snr <= sq_thresh->lower_threshold[3]) {
-            newThreshold = WMI_SNR_THRESHOLD1_BELOW;
-        }
-    }
-
-    /* Calculate and install the next set of thresholds */
-    lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
-                                      sq_thresh->lower_threshold_valid_count);
-    upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
-                                      sq_thresh->upper_threshold_valid_count);
-
-    /* Issue a wmi command to install the thresholds */
-    cmd.thresholdAbove1_Val = upper_snr_threshold;
-    cmd.thresholdBelow1_Val = lower_snr_threshold;
-    cmd.weight = sq_thresh->weight;
-    cmd.pollTime = sq_thresh->polling_interval;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
-              ,DBGARG, snr, newThreshold, lower_snr_threshold,
-              upper_snr_threshold));
-
-    snr_event_value = snr;
-
-    if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) {
-        A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
-                  DBGARG));
-    }
-    A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
-
-    return 0;
-}
-
-static int
-wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_LQ_THRESHOLD_EVENT *reply;
-
-    if (len < sizeof(*reply)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
-                                (WMI_LQ_THRESHOLD_VAL) reply->range,
-                                reply->lq);
-
-    return 0;
-}
-
-static int
-wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    u16 ap_info_entry_size;
-    WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
-    WMI_AP_INFO_V1 *ap_info_v1;
-    u8 i;
-
-    if (len < sizeof(WMI_APLIST_EVENT)) {
-        return A_EINVAL;
-    }
-
-    if (ev->apListVer == APLIST_VER1) {
-        ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
-        ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
-    } else {
-        return A_EINVAL;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
-    if (len < (int)(sizeof(WMI_APLIST_EVENT) +
-              (ev->numAP - 1) * ap_info_entry_size))
-    {
-        return A_EINVAL;
-    }
-
-    /*
-     * AP List Ver1 Contents
-     */
-    for (i = 0; i < ev->numAP; i++) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
-                    "Channel %d\n", i,
-                   ap_info_v1->bssid[0], ap_info_v1->bssid[1],
-                   ap_info_v1->bssid[2], ap_info_v1->bssid[3],
-                   ap_info_v1->bssid[4], ap_info_v1->bssid[5],
-                   ap_info_v1->channel));
-        ap_info_v1++;
-    }
-    return 0;
-}
-
-static int
-wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    u32 dropped;
-
-    dropped = *((u32 *)datap);
-    datap += sizeof(dropped);
-    len -= sizeof(dropped);
-    A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len);
-    return 0;
-}
-
-/*
- * Called to send a wmi command. Command specific data is already built
- * on osbuf and current osbuf->data points to it.
- */
-int
-wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
-               WMI_SYNC_FLAG syncflag)
-{
-    int status;
-#define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
-    WMI_CMD_HDR         *cHdr;
-    HTC_ENDPOINT_ID     eid  = wmip->wmi_endpoint_id;
-
-    A_ASSERT(osbuf != NULL);
-
-    if (syncflag >= END_WMIFLAG) {
-        A_NETBUF_FREE(osbuf);
-        return A_EINVAL;
-    }
-
-    if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
-        /*
-         * We want to make sure all data currently queued is transmitted before
-         * the cmd execution.  Establish a new sync point.
-         */
-        wmi_sync_point(wmip);
-    }
-
-    if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
-        A_NETBUF_FREE(osbuf);
-        return A_NO_MEMORY;
-    }
-
-    cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
-    cHdr->commandId = (u16) cmdId;
-    cHdr->info1 = 0; // added for virtual interface
-
-    /*
-     * Only for OPT_TX_CMD, use BE endpoint.
-     */
-    if (IS_OPT_TX_CMD(cmdId)) {
-        if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) {
-            A_NETBUF_FREE(osbuf);
-            return status;
-        }
-        eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
-    }
-    A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
-
-    if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
-        /*
-         * We want to make sure all new data queued waits for the command to
-         * execute. Establish a new sync point.
-         */
-        wmi_sync_point(wmip);
-    }
-    return (0);
-#undef IS_OPT_TX_CMD
-}
-
-int
-wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
-                  WMI_SYNC_FLAG syncflag)
-{
-    WMIX_CMD_HDR     *cHdr;
-
-    if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
-        A_NETBUF_FREE(osbuf);
-        return A_NO_MEMORY;
-    }
-
-    cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
-    cHdr->commandId = (u32) cmdId;
-
-    return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
-}
-
-int
-wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
-                DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
-                CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen,
-                CRYPTO_TYPE groupCrypto, u8 groupCryptoLen,
-                int ssidLength, u8 *ssid,
-                u8 *bssid, u16 channel, u32 ctrl_flags)
-{
-    void *osbuf;
-    WMI_CONNECT_CMD *cc;
-    wmip->wmi_traffic_class = 100;
-
-    if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
-        return A_EINVAL;
-    }
-    if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
-
-    cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cc, sizeof(*cc));
-
-    if (ssidLength)
-    {
-        memcpy(cc->ssid, ssid, ssidLength);
-    }
-
-    cc->ssidLength          = ssidLength;
-    cc->networkType         = netType;
-    cc->dot11AuthMode       = dot11AuthMode;
-    cc->authMode            = authMode;
-    cc->pairwiseCryptoType  = pairwiseCrypto;
-    cc->pairwiseCryptoLen   = pairwiseCryptoLen;
-    cc->groupCryptoType     = groupCrypto;
-    cc->groupCryptoLen      = groupCryptoLen;
-    cc->channel             = channel;
-    cc->ctrl_flags          = ctrl_flags;
-
-    if (bssid != NULL) {
-        memcpy(cc->bssid, bssid, ATH_MAC_LEN);
-    }
-
-    wmip->wmi_pair_crypto_type  = pairwiseCrypto;
-    wmip->wmi_grp_crypto_type   = groupCrypto;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel)
-{
-    void *osbuf;
-    WMI_RECONNECT_CMD *cc;
-    wmip->wmi_traffic_class = 100;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
-
-    cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cc, sizeof(*cc));
-
-    cc->channel = channel;
-
-    if (bssid != NULL) {
-        memcpy(cc->bssid, bssid, ATH_MAC_LEN);
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_disconnect_cmd(struct wmi_t *wmip)
-{
-    int status;
-    wmip->wmi_traffic_class = 100;
-
-    /* Bug fix for 24817(elevator bug) - the disconnect command does not
-       need to do a SYNC before.*/
-    status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
-
-    return status;
-}
-
-int
-wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
-                  u32 forceFgScan, u32 isLegacy,
-                  u32 homeDwellTime, u32 forceScanInterval,
-                  s8 numChan, u16 *channelList)
-{
-    void *osbuf;
-    WMI_START_SCAN_CMD *sc;
-    s8 size;
-
-    size = sizeof (*sc);
-
-    if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
-        return A_EINVAL;
-    }
-
-    if (numChan) {
-        if (numChan > WMI_MAX_CHANNELS) {
-            return A_EINVAL;
-        }
-        size += sizeof(u16) * (numChan - 1);
-    }
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
-    sc->scanType = scanType;
-    sc->forceFgScan = forceFgScan;
-    sc->isLegacy = isLegacy;
-    sc->homeDwellTime = homeDwellTime;
-    sc->forceScanInterval = forceScanInterval;
-    sc->numChannels = numChan;
-    if (numChan) {
-        memcpy(sc->channelList, channelList, numChan * sizeof(u16));
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
-                   u16 fg_end_sec, u16 bg_sec,
-                   u16 minact_chdw_msec, u16 maxact_chdw_msec,
-                   u16 pas_chdw_msec,
-                   u8 shScanRatio, u8 scanCtrlFlags,
-                   u32 max_dfsch_act_time, u16 maxact_scan_per_ssid)
-{
-    void *osbuf;
-    WMI_SCAN_PARAMS_CMD *sc;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*sc));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*sc));
-
-    sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(sc, sizeof(*sc));
-    sc->fg_start_period  = fg_start_sec;
-    sc->fg_end_period    = fg_end_sec;
-    sc->bg_period        = bg_sec;
-    sc->minact_chdwell_time = minact_chdw_msec;
-    sc->maxact_chdwell_time = maxact_chdw_msec;
-    sc->pas_chdwell_time = pas_chdw_msec;
-    sc->shortScanRatio   = shScanRatio;
-    sc->scanCtrlFlags    = scanCtrlFlags;
-    sc->max_dfsch_act_time = max_dfsch_act_time;
-    sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask)
-{
-    void *osbuf;
-    WMI_BSS_FILTER_CMD *cmd;
-
-    if (filter >= LAST_BSS_FILTER) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->bssFilter = filter;
-    cmd->ieMask = ieMask;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
-                   u8 ssidLength, u8 *ssid)
-{
-    void *osbuf;
-    WMI_PROBED_SSID_CMD *cmd;
-
-    if (index > MAX_PROBED_SSID_INDEX) {
-        return A_EINVAL;
-    }
-    if (ssidLength > sizeof(cmd->ssid)) {
-        return A_EINVAL;
-    }
-    if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
-        return A_EINVAL;
-    }
-    if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
-        return A_EINVAL;
-    }
-
-    if (flag & SPECIFIC_SSID_FLAG) {
-        is_probe_ssid = true;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->entryIndex = index;
-    cmd->flag       = flag;
-    cmd->ssidLength = ssidLength;
-    memcpy(cmd->ssid, ssid, ssidLength);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons)
-{
-    void *osbuf;
-    WMI_LISTEN_INT_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->listenInterval = listenInterval;
-    cmd->numBeacons = listenBeacons;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons)
-{
-    void *osbuf;
-    WMI_BMISS_TIME_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->bmissTime = bmissTime;
-    cmd->numBeacons =  bmissBeacons;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
-                     u8 ieLen, u8 *ieInfo)
-{
-    void *osbuf;
-    WMI_SET_ASSOC_INFO_CMD *cmd;
-    u16 cmdLen;
-
-    cmdLen = sizeof(*cmd) + ieLen - 1;
-    osbuf = A_NETBUF_ALLOC(cmdLen);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, cmdLen);
-
-    cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, cmdLen);
-    cmd->ieType = ieType;
-    cmd->bufferSize = ieLen;
-    memcpy(cmd->assocInfo, ieInfo, ieLen);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode)
-{
-    void *osbuf;
-    WMI_POWER_MODE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->powerMode = powerMode;
-    wmip->wmi_powerMode = powerMode;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
-                   u16 atim_windows, u16 timeout_value)
-{
-    void *osbuf;
-    WMI_IBSS_PM_CAPS_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->power_saving = pmEnable;
-    cmd->ttl = ttl;
-    cmd->atim_windows = atim_windows;
-    cmd->timeout_value = timeout_value;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
-                   u32 ps_period, u8 sleep_period)
-{
-    void *osbuf;
-    WMI_AP_PS_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->psType = psType;
-    cmd->idle_time = idle_time;
-    cmd->ps_period = ps_period;
-    cmd->sleep_period = sleep_period;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
-                 u16 psPollNum, u16 dtimPolicy,
-                 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
-                 u16 ps_fail_event_policy)
-{
-    void *osbuf;
-    WMI_POWER_PARAMS_CMD *pm;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*pm));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*pm));
-
-    pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(pm, sizeof(*pm));
-    pm->idle_period   = idlePeriod;
-    pm->pspoll_number = psPollNum;
-    pm->dtim_policy   = dtimPolicy;
-    pm->tx_wakeup_policy = tx_wakeup_policy;
-    pm->num_tx_to_wakeup = num_tx_to_wakeup;
-    pm->ps_fail_event_policy = ps_fail_event_policy;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout)
-{
-    void *osbuf;
-    WMI_DISC_TIMEOUT_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->disconnectTimeout = timeout;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType,
-               u8 keyUsage, u8 keyLength, u8 *keyRSC,
-               u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr,
-               WMI_SYNC_FLAG sync_flag)
-{
-    void *osbuf;
-    WMI_ADD_CIPHER_KEY_CMD *cmd;
-
-    if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
-        (keyMaterial == NULL))
-    {
-        return A_EINVAL;
-    }
-
-    if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->keyIndex = keyIndex;
-    cmd->keyType  = keyType;
-    cmd->keyUsage = keyUsage;
-    cmd->keyLength = keyLength;
-    memcpy(cmd->key, keyMaterial, keyLength);
-#ifdef WAPI_ENABLE
-    if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
-#else
-    if (NULL != keyRSC) {
-#endif // WAPI_ENABLE
-        memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
-    }
-    cmd->key_op_ctrl = key_op_ctrl;
-
-    if(macAddr) {
-        memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
-}
-
-int
-wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk)
-{
-    void *osbuf;
-    WMI_ADD_KRK_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    memcpy(cmd->krk, krk, WMI_KRK_LEN);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_delete_krk_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
-}
-
-int
-wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex)
-{
-    void *osbuf;
-    WMI_DELETE_CIPHER_KEY_CMD *cmd;
-
-    if (keyIndex > WMI_MAX_KEY_INDEX) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->keyIndex = keyIndex;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
-                 bool set)
-{
-    void *osbuf;
-    WMI_SET_PMKID_CMD *cmd;
-
-    if (bssid == NULL) {
-        return A_EINVAL;
-    }
-
-    if ((set == true) && (pmkId == NULL)) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
-    memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
-    if (set == true) {
-        memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
-        cmd->enable = PMKID_ENABLE;
-    } else {
-        A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
-        cmd->enable = PMKID_DISABLE;
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en)
-{
-    void *osbuf;
-    WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_akmp_params_cmd(struct wmi_t *wmip,
-                        WMI_SET_AKMP_PARAMS_CMD *akmpParams)
-{
-    void *osbuf;
-    WMI_SET_AKMP_PARAMS_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->akmpInfo = akmpParams->akmpInfo;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
-                       WMI_SET_PMKID_LIST_CMD *pmkInfo)
-{
-    void *osbuf;
-    WMI_SET_PMKID_LIST_CMD *cmd;
-    u16 cmdLen;
-    u8 i;
-
-    cmdLen = sizeof(pmkInfo->numPMKID) +
-             pmkInfo->numPMKID * sizeof(WMI_PMKID);
-
-    osbuf = A_NETBUF_ALLOC(cmdLen);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, cmdLen);
-    cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->numPMKID = pmkInfo->numPMKID;
-
-    for (i = 0; i < cmd->numPMKID; i++) {
-        memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
-                 WMI_PMKID_LEN);
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
-}
-
-int
-wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
-{
-    WMI_DATA_HDR     *dtHdr;
-
-    A_ASSERT( eid != wmip->wmi_endpoint_id);
-    A_ASSERT(osbuf != NULL);
-
-    if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
-        return A_NO_MEMORY;
-    }
-
-    dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
-    dtHdr->info =
-      (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
-
-    dtHdr->info3 = 0;
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
-
-    return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
-}
-
-typedef struct _WMI_DATA_SYNC_BUFS {
-    u8 trafficClass;
-    void               *osbuf;
-}WMI_DATA_SYNC_BUFS;
-
-static int
-wmi_sync_point(struct wmi_t *wmip)
-{
-    void *cmd_osbuf;
-    WMI_SYNC_CMD *cmd;
-    WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
-    u8 i,numPriStreams=0;
-    int status = 0;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    memset(dataSyncBufs,0,sizeof(dataSyncBufs));
-
-    /* lock out while we walk through the priority list and assemble our local array */
-    LOCK_WMI(wmip);
-
-    for (i=0; i < WMM_NUM_AC ; i++) {
-        if (wmip->wmi_fatPipeExists & (1 << i)) {
-            numPriStreams++;
-            dataSyncBufs[numPriStreams-1].trafficClass = i;
-        }
-    }
-
-    UNLOCK_WMI(wmip);
-
-    /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
-
-    do {
-        /*
-         * We allocate all network buffers needed so we will be able to
-         * send all required frames.
-         */
-        cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-        if (cmd_osbuf == NULL) {
-            status = A_NO_MEMORY;
-            break;
-    }
-
-        A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
-
-        cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
-        A_MEMZERO(cmd, sizeof(*cmd));
-
-        /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
-         * eps on which the Data Sync will be sent
-         */
-        cmd->dataSyncMap = wmip->wmi_fatPipeExists;
-
-        for (i=0; i < numPriStreams ; i++) {
-            dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
-            if (dataSyncBufs[i].osbuf == NULL) {
-                status = A_NO_MEMORY;
-                break;
-            }
-        } //end for
-
-        /* if Buffer allocation for any of the dataSync fails, then do not
-         * send the Synchronize cmd on the control ep
-         */
-        if (status) {
-            break;
-        }
-
-    /*
-     * Send sync cmd followed by sync data messages on all endpoints being
-     * used
-     */
-    status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
-                          NO_SYNC_WMIFLAG);
-
-        if (status) {
-            break;
-    }
-            /* cmd buffer sent, we no longer own it */
-        cmd_osbuf = NULL;
-
-        for(i=0; i < numPriStreams; i++) {
-            A_ASSERT(dataSyncBufs[i].osbuf != NULL);
-            status = wmi_dataSync_send(wmip,
-                                       dataSyncBufs[i].osbuf,
-                                       A_WMI_Ac2EndpointID(wmip->wmi_devt,
-                                                            dataSyncBufs[i].
-                                                            trafficClass)
-                                      );
-
-            if (status) {
-                break;
-            }
-            /* we don't own this buffer anymore, NULL it out of the array so it
-             * won't get cleaned up */
-            dataSyncBufs[i].osbuf = NULL;
-        } //end for
-
-    } while(false);
-
-    /* free up any resources left over (possibly due to an error) */
-
-    if (cmd_osbuf != NULL) {
-        A_NETBUF_FREE(cmd_osbuf);
-            }
-
-    for (i = 0; i < numPriStreams; i++) {
-        if (dataSyncBufs[i].osbuf != NULL) {
-            A_NETBUF_FREE(dataSyncBufs[i].osbuf);
-        }
-    }
-
-    return (status);
-}
-
-int
-wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
-{
-    void *osbuf;
-    WMI_CREATE_PSTREAM_CMD *cmd;
-    u8 fatPipeExistsForAC=0;
-    s32 minimalPHY = 0;
-    s32 nominalPHY = 0;
-
-    /* Validate all the parameters. */
-    if( !((params->userPriority < 8) &&
-         (params->userPriority <= 0x7) &&
-         (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass)  &&
-         (params->trafficDirection == UPLINK_TRAFFIC ||
-            params->trafficDirection == DNLINK_TRAFFIC ||
-            params->trafficDirection == BIDIR_TRAFFIC) &&
-         (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
-            params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
-         (params->voicePSCapability == DISABLE_FOR_THIS_AC  ||
-            params->voicePSCapability == ENABLE_FOR_THIS_AC ||
-            params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
-         (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
-    {
-        return  A_EINVAL;
-    }
-
-    //
-    // check nominal PHY rate is >= minimalPHY, so that DUT
-    // can allow TSRS IE
-    //
-
-    // get the physical rate
-    minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
-
-    // check minimal phy < nominal phy rate
-    //
-    if (params->nominalPHY >= minimalPHY)
-    {
-        nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
-        A_DPRINTF(DBG_WMI,
-                  (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
-                  minimalPHY, nominalPHY));
-
-        params->nominalPHY = nominalPHY;
-    }
-    else
-    {
-        params->nominalPHY = 0;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Sending create_pstream_cmd: ac=%d    tsid:%d\n", DBGARG,
-        params->trafficClass, params->tsid));
-
-    cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    memcpy(cmd, params, sizeof(*cmd));
-
-        /* this is an implicitly created Fat pipe */
-    if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) {
-        LOCK_WMI(wmip);
-        fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
-        wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
-        UNLOCK_WMI(wmip);
-    } else {
-            /* this is an explicitly created thin stream within a fat pipe */
-    LOCK_WMI(wmip);
-        fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
-    wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
-            /* if a thinstream becomes active, the fat pipe automatically
-            * becomes active
-            */
-        wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
-    UNLOCK_WMI(wmip);
-    }
-
-        /* Indicate activty change to driver layer only if this is the
-         * first TSID to get created in this AC explicitly or an implicit
-         * fat pipe is getting created.
-         */
-    if (!fatPipeExistsForAC) {
-        A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
-    }
-
-    /* mike: should be SYNC_BEFORE_WMIFLAG */
-    return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid)
-{
-    void *osbuf;
-    WMI_DELETE_PSTREAM_CMD *cmd;
-    int status;
-    u16 activeTsids=0;
-
-    /* validate the parameters */
-    if (trafficClass > 3) {
-        A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->trafficClass = trafficClass;
-    cmd->tsid = tsid;
-
-    LOCK_WMI(wmip);
-    activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
-    UNLOCK_WMI(wmip);
-
-        /* Check if the tsid was created & exists */
-    if (!(activeTsids & (1<<tsid))) {
-
-        A_NETBUF_FREE(osbuf);
-        A_DPRINTF(DBG_WMI,
-        (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
-            /* TODO: return a more appropriate err code */
-        return A_ERROR;
-    }
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
-
-    status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
-                         SYNC_BEFORE_WMIFLAG));
-
-    LOCK_WMI(wmip);
-    wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
-    activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
-    UNLOCK_WMI(wmip);
-
-
-        /* Indicate stream inactivity to driver layer only if all tsids
-         * within this AC are deleted.
-         */
-    if(!activeTsids) {
-        A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
-        wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
-    }
-
-    return status;
-}
-
-int
-wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask)
-{
-    void *osbuf;
-    WMI_FRAME_RATES_CMD *cmd;
-    u8 frameType;
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
-
-    if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
-        (subType > 15)){
-
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    frameType = (u8)((subType << 4) | type);
-
-    cmd->bEnableMask = bEnable;
-    cmd->frameType = frameType;
-    cmd->frameRateMask = rateMask;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
-}
-
-/*
- * used to set the bit rate.  rate is in Kbps.  If rate == -1
- * then auto selection is used.
- */
-int
-wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate)
-{
-    void *osbuf;
-    WMI_BIT_RATE_CMD *cmd;
-    s8 drix, mrix, crix, ret_val;
-
-    if (dataRate != -1) {
-        ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
-        if(ret_val == A_EINVAL){
-            return A_EINVAL;
-        }
-    } else {
-        drix = -1;
-    }
-
-    if (mgmtRate != -1) {
-        ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
-        if(ret_val == A_EINVAL){
-            return A_EINVAL;
-        }
-    } else {
-        mrix = -1;
-    }
-    if (ctlRate != -1) {
-        ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
-        if(ret_val == A_EINVAL){
-            return A_EINVAL;
-        }
-    } else {
-        crix = -1;
-    }
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->rateIndex = drix;
-    cmd->mgmtRateIndex = mrix;
-    cmd->ctlRateIndex  = crix;
-
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_get_bitrate_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
-}
-
-/*
- * Returns true iff the given rate index is legal in the current PHY mode.
- */
-bool
-wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex)
-{
-    WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
-    bool isValid = true;
-    switch(phyMode) {
-        case WMI_11A_MODE:
-            if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
-                if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
-                    isValid = false;
-                }
-            } else {
-                if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
-                    isValid = false;
-                }
-            }
-            break;
-
-        case WMI_11B_MODE:
-            if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
-                isValid = false;
-            }
-            break;
-
-        case WMI_11GONLY_MODE:
-            if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
-                if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
-                    isValid = false;
-                }
-            } else {
-                if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
-                    isValid = false;
-                }
-            }
-            break;
-
-        case WMI_11G_MODE:
-        case WMI_11AG_MODE:
-            if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
-                if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
-                    isValid = false;
-                }
-            } else {
-                if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
-                    isValid = false;
-                }
-            }
-            break;
-        default:
-            A_ASSERT(false);
-            break;
-    }
-
-    return isValid;
-}
-
-s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx)
-{
-    s8 i;
-
-    for (i=0;;i++)
-    {
-        if (wmi_rateTable[(u32) i][0] == 0) {
-            return A_EINVAL;
-        }
-        if (wmi_rateTable[(u32) i][0] == rate) {
-            break;
-        }
-    }
-
-    if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) {
-        return A_EINVAL;
-    }
-
-    *rate_idx = i;
-    return 0;
-}
-
-int
-wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask)
-{
-    void *osbuf;
-    WMI_FIX_RATES_CMD *cmd;
-#if 0
-    s32 rateIndex;
-/* This check does not work for AR6003 as the HT modes are enabled only when
- * the STA is connected to a HT_BSS and is not based only on channel. It is
- * safe to skip this check however because rate control will only use rates
- * that are permitted by the valid rate mask and the fix rate mask. Meaning
- * the fix rate mask is not sufficient by itself to cause an invalid rate
- * to be used. */
-    /* Make sure all rates in the mask are valid in the current PHY mode */
-    for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
-       if((1 << rateIndex) & (u32)fixRatesMask) {
-            if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) {
-                A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
-                return A_EINVAL;
-            }
-       }
-    }
-#endif
-
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->fixRateMask = fixRatesMask;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_get_ratemask_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
-}
-
-int
-wmi_get_channelList_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
-}
-
-/*
- * used to generate a wmi sey channel Parameters cmd.
- * mode should always be specified and corresponds to the phy mode of the
- * wlan.
- * numChan should alway sbe specified. If zero indicates that all available
- * channels should be used.
- * channelList is an array of channel frequencies (in Mhz) which the radio
- * should limit its operation to.  It should be NULL if numChan == 0.  Size of
- * array should correspond to numChan entries.
- */
-int
-wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
-                          WMI_PHY_MODE mode, s8 numChan,
-                          u16 *channelList)
-{
-    void *osbuf;
-    WMI_CHANNEL_PARAMS_CMD *cmd;
-    s8 size;
-
-    size = sizeof (*cmd);
-
-    if (numChan) {
-        if (numChan > WMI_MAX_CHANNELS) {
-            return A_EINVAL;
-        }
-        size += sizeof(u16) * (numChan - 1);
-    }
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-
-    wmip->wmi_phyMode = mode;
-    cmd->scanParam   = scanParam;
-    cmd->phyMode     = mode;
-    cmd->numChannels = numChan;
-    memcpy(cmd->channelList, channelList, numChan * sizeof(u16));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-void
-wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
-{
-    SQ_THRESHOLD_PARAMS *sq_thresh =
-           &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
-    /*
-     * Parse the command and store the threshold values here. The checks
-     * for valid values can be put here
-     */
-    sq_thresh->weight = rssiCmd->weight;
-    sq_thresh->polling_interval = rssiCmd->pollTime;
-
-    sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->upper_threshold_valid_count = 6;
-
-    /* List sorted in descending order */
-    sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
-    sq_thresh->lower_threshold_valid_count = 6;
-
-    if (!rssi_event_value) {
-    /*
-     * Configuring the thresholds to their extremes allows the host to get an
-     * event from the target which is used for the configuring the correct
-     * thresholds
-     */
-    rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
-    rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
-    } else {
-        /*
-         * In case the user issues multiple times of rssi_threshold_setting,
-         * we should not use the extreames anymore, the target does not expect that.
-         */
-        rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
-                                              sq_thresh->upper_threshold_valid_count);
-        rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
-                                              sq_thresh->lower_threshold_valid_count);
-}
-}
-
-int
-wmi_set_rssi_threshold_params(struct wmi_t *wmip,
-                              WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
-{
-
-     /* Check these values are in ascending order */
-    if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
-        rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
-        rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
-        rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
-        rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
-        rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
-        rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
-        rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
-        rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
-        rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
-    {
-        return A_EINVAL;
-    }
-
-    wmi_cache_configure_rssithreshold(wmip, rssiCmd);
-
-    return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
-}
-
-int
-wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
-{
-    void    *osbuf;
-    WMI_SET_IP_CMD *cmd;
-
-    /* Multicast address are not valid */
-    if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) ||
-       (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
-    cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
-    memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
-                              WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
-    u16 activeTsids=0;
-    u8 streamExists=0;
-    u8 i;
-
-    if( hostModeCmd->awake == hostModeCmd->asleep) {
-        return A_EINVAL;
-    }
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
-
-    if(hostModeCmd->asleep) {
-        /*
-         * Relinquish credits from all implicitly created pstreams since when we
-         * go to sleep. If user created explicit thinstreams exists with in a
-         * fatpipe leave them intact for the user to delete
-         */
-        LOCK_WMI(wmip);
-        streamExists = wmip->wmi_fatPipeExists;
-        UNLOCK_WMI(wmip);
-
-        for(i=0;i< WMM_NUM_AC;i++) {
-            if (streamExists & (1<<i)) {
-                LOCK_WMI(wmip);
-                activeTsids = wmip->wmi_streamExistsForAC[i];
-                UNLOCK_WMI(wmip);
-                /* If there are no user created thin streams delete the fatpipe */
-                if(!activeTsids) {
-                    streamExists &= ~(1<<i);
-                    /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
-                    A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
-                }
-            }
-        }
-
-        /* Update the fatpipes that exists*/
-        LOCK_WMI(wmip);
-        wmip->wmi_fatPipeExists = streamExists;
-        UNLOCK_WMI(wmip);
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_wow_mode_cmd(struct wmi_t *wmip,
-                              WMI_SET_WOW_MODE_CMD *wowModeCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_SET_WOW_MODE_CMD *cmd;
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
-                            NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_get_wow_list_cmd(struct wmi_t *wmip,
-                              WMI_GET_WOW_LIST_CMD *wowListCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_GET_WOW_LIST_CMD *cmd;
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
-                            NO_SYNC_WMIFLAG));
-
-}
-
-static int
-wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_GET_WOW_LIST_REPLY *reply;
-
-    if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_GET_WOW_LIST_REPLY *)datap;
-
-    A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
-                          reply);
-
-    return 0;
-}
-
-int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
-                                 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
-                                 u8 *pattern, u8 *mask,
-                                 u8 pattern_size)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_ADD_WOW_PATTERN_CMD *cmd;
-    u8 *filter_mask = NULL;
-
-    size = sizeof (*cmd);
-
-    size += ((2 * addWowCmd->filter_size)* sizeof(u8));
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->filter_list_id = addWowCmd->filter_list_id;
-    cmd->filter_offset = addWowCmd->filter_offset;
-    cmd->filter_size = addWowCmd->filter_size;
-
-    memcpy(cmd->filter, pattern, addWowCmd->filter_size);
-
-    filter_mask = (u8 *)(cmd->filter + cmd->filter_size);
-    memcpy(filter_mask, mask, addWowCmd->filter_size);
-
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
-                              WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_DEL_WOW_PATTERN_CMD *cmd;
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
-                            NO_SYNC_WMIFLAG));
-
-}
-
-void
-wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
-{
-    SQ_THRESHOLD_PARAMS *sq_thresh =
-           &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
-    /*
-     * Parse the command and store the threshold values here. The checks
-     * for valid values can be put here
-     */
-    sq_thresh->weight = snrCmd->weight;
-    sq_thresh->polling_interval = snrCmd->pollTime;
-
-    sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
-    sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
-    sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
-    sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
-    sq_thresh->upper_threshold_valid_count = 4;
-
-    /* List sorted in descending order */
-    sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
-    sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
-    sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
-    sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
-    sq_thresh->lower_threshold_valid_count = 4;
-
-    if (!snr_event_value) {
-    /*
-     * Configuring the thresholds to their extremes allows the host to get an
-     * event from the target which is used for the configuring the correct
-     * thresholds
-     */
-    snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0];
-    snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0];
-    } else {
-        /*
-         * In case the user issues multiple times of snr_threshold_setting,
-         * we should not use the extreames anymore, the target does not expect that.
-         */
-        snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
-                                              sq_thresh->upper_threshold_valid_count);
-        snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
-                                              sq_thresh->lower_threshold_valid_count);
-    }
-
-}
-int
-wmi_set_snr_threshold_params(struct wmi_t *wmip,
-                             WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
-{
-    if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
-        snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
-        snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
-        snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
-        snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
-        snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
-    {
-        return A_EINVAL;
-    }
-    wmi_cache_configure_snrthreshold(wmip, snrCmd);
-    return (wmi_send_snr_threshold_params(wmip, snrCmd));
-}
-
-int
-wmi_clr_rssi_snr(struct wmi_t *wmip)
-{
-    void    *osbuf;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(int));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_lq_threshold_params(struct wmi_t *wmip,
-                             WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
-    /* These values are in ascending order */
-    if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
-        lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
-        lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
-        lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
-        lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
-        lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
-
-        return A_EINVAL;
-    }
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-
-    cmd->bitmask = mask;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source)
-{
-    void *osbuf;
-    WMIX_HB_CHALLENGE_RESP_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->cookie = cookie;
-    cmd->source = source;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
-                              NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
-                            u16 tsr, bool rep, u16 size,
-                            u32 valid)
-{
-    void *osbuf;
-    WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->config.cfgmmask = mmask;
-    cmd->config.cfgtsr = tsr;
-    cmd->config.cfgrep = rep;
-    cmd->config.cfgsize = size;
-    cmd->config.cfgvalid = valid;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
-                              NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_get_stats_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
-}
-
-int
-wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid)
-{
-    void *osbuf;
-    WMI_ADD_BAD_AP_CMD *cmd;
-
-    if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->badApIndex = apIndex;
-    memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
-}
-
-int
-wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex)
-{
-    void *osbuf;
-    WMI_DELETE_BAD_AP_CMD *cmd;
-
-    if (apIndex > WMI_MAX_BAD_AP_INDEX) {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->badApIndex = apIndex;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_abort_scan_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
-}
-
-int
-wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM)
-{
-    void *osbuf;
-    WMI_SET_TX_PWR_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->dbM = dbM;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_get_txPwr_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
-}
-
-u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass)
-{
-    u16 activeTsids=0;
-
-    LOCK_WMI(wmip);
-    activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
-    UNLOCK_WMI(wmip);
-
-    return activeTsids;
-}
-
-int
-wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
-}
-
-int
-wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType)
-{
-    void *osbuf;
-    u32 size = sizeof(u8);
-    WMI_TARGET_ROAM_DATA *cmd;
-
-    osbuf = A_NETBUF_ALLOC(size);      /* no payload */
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
-    cmd->roamDataType = roamDataType;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
-                      u8 size)
-{
-    void *osbuf;
-    WMI_SET_ROAM_CTRL_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-
-    memcpy(cmd, p, size);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
-                            WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
-                            u8 size)
-{
-    void *osbuf;
-    WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
-
-    /* These timers can't be zero */
-    if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
-       !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
-         pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
-       !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
-         pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
-        return A_EINVAL;
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-
-    memcpy(cmd, pCmd, size);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac,  u16 txop, u8 eCWmin,
-                          u8 eCWmax, u8 aifsn)
-{
-    void *osbuf;
-    WMI_SET_ACCESS_PARAMS_CMD *cmd;
-
-    if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
-        (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
-    {
-        return A_EINVAL;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->txop   = txop;
-    cmd->eCWmin = eCWmin;
-    cmd->eCWmax = eCWmax;
-    cmd->aifsn  = aifsn;
-    cmd->ac = ac;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
-                         u8 trafficClass, u8 maxRetries,
-                         u8 enableNotify)
-{
-    void *osbuf;
-    WMI_SET_RETRY_LIMITS_CMD *cmd;
-
-    if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
-        (frameType != DATA_FRAMETYPE))
-    {
-        return A_EINVAL;
-    }
-
-    if (maxRetries > WMI_MAX_RETRIES) {
-        return A_EINVAL;
-    }
-
-    if (frameType != DATA_FRAMETYPE) {
-        trafficClass = 0;
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->frameType    = frameType;
-    cmd->trafficClass = trafficClass;
-    cmd->maxRetries   = maxRetries;
-    cmd->enableNotify = enableNotify;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-void
-wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid)
-{
-    if (bssid != NULL) {
-        memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
-    }
-}
-
-int
-wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode)
-{
-    void *osbuf;
-    WMI_SET_OPT_MODE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->optMode = optMode;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
-                         SYNC_BOTH_WMIFLAG));
-}
-
-int
-wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
-                      u8 frmType,
-                      u8 *dstMacAddr,
-                      u8 *bssid,
-                      u16 optIEDataLen,
-                      u8 *optIEData)
-{
-    void *osbuf;
-    WMI_OPT_TX_FRAME_CMD *cmd;
-    osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
-
-    cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
-
-    cmd->frmType    = frmType;
-    cmd->optIEDataLen   = optIEDataLen;
-    //cmd->optIEData     = (u8 *)((int)cmd + sizeof(*cmd));
-    memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
-    memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
-    memcpy(&cmd->optIEData[0], optIEData, optIEDataLen);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl)
-{
-    void *osbuf;
-    WMI_BEACON_INT_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->beaconInterval = intvl;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize)
-{
-    void *osbuf;
-    WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->voicePktSize = voicePktSize;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen)
-{
-    void *osbuf;
-    WMI_SET_MAX_SP_LEN_CMD *cmd;
-
-    /* maxSPLen is a two-bit value. If user trys to set anything
-     * other than this, then its invalid
-     */
-    if(maxSPLen & ~0x03)
-        return  A_EINVAL;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->maxSPLen = maxSPLen;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-u8 wmi_determine_userPriority(
-    u8 *pkt,
-    u32 layer2Pri)
-{
-    u8 ipPri;
-    iphdr *ipHdr = (iphdr *)pkt;
-
-    /* Determine IPTOS priority */
-    /*
-     * IP Tos format :
-     *      (Refer Pg 57 WMM-test-plan-v1.2)
-     * IP-TOS - 8bits
-     *          : DSCP(6-bits) ECN(2-bits)
-     *          : DSCP - P2 P1 P0 X X X
-     *              where (P2 P1 P0) form 802.1D
-     */
-    ipPri = ipHdr->ip_tos >> 5;
-    ipPri &= 0x7;
-
-    if ((layer2Pri & 0x7) > ipPri)
-        return ((u8)layer2Pri & 0x7);
-    else
-        return ipPri;
-}
-
-u8 convert_userPriority_to_trafficClass(u8 userPriority)
-{
-    return  (up_to_ac[userPriority & 0x7]);
-}
-
-u8 wmi_get_power_mode_cmd(struct wmi_t *wmip)
-{
-    return wmip->wmi_powerMode;
-}
-
-int
-wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
-{
-    int ret = 0;
-
-#define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
-#define TSPEC_SERVICE_START_TIME_ATHEROS_DEF  0
-#define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF      0
-#define TSPEC_DELAY_BOUND_ATHEROS_DEF         0
-#define TSPEC_MEDIUM_TIME_ATHEROS_DEF         0
-#define TSPEC_SBA_ATHEROS_DEF                 0x2000  /* factor is 1 */
-
-    /* Verify TSPEC params for ATHEROS compliance */
-    if(tspecCompliance == ATHEROS_COMPLIANCE) {
-        if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
-            (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
-            (pCmd->minDataRate != pCmd->meanDataRate) ||
-            (pCmd->minDataRate != pCmd->peakDataRate) ||
-            (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
-            (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
-            (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
-            (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
-
-            A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
-            //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
-            ret = A_EINVAL;
-        }
-    }
-
-    return ret;
-}
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-static int
-wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-       ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len);
-
-       return 0;
-}
-
-#endif /* CONFIG_HOST_TCMD_SUPPORT*/
-
-int
-wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode)
-{
-    void *osbuf;
-    WMI_SET_AUTH_MODE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->mode = mode;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode)
-{
-    void *osbuf;
-    WMI_SET_REASSOC_MODE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->mode = mode;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy)
-{
-    void *osbuf;
-    WMI_SET_LPREAMBLE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->status = status;
-    cmd->preamblePolicy = preamblePolicy;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold)
-{
-    void *osbuf;
-    WMI_SET_RTS_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->threshold = threshold;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
-{
-    void *osbuf;
-    WMI_SET_WMM_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->status = status;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
-            NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status)
-{
-    void *osbuf;
-    WMI_SET_QOS_SUPP_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->status = status;
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
-{
-    void *osbuf;
-    WMI_SET_WMM_TXOP_CMD *cmd;
-
-    if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
-        return A_EINVAL;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->txopEnable = cfg;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
-            NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_country(struct wmi_t *wmip, u8 *countryCode)
-{
-    void *osbuf;
-    WMI_AP_SET_COUNTRY_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    memcpy(cmd->countryCode,countryCode,3);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-/* WMI  layer doesn't need to know the data type of the test cmd.
-   This would be beneficial for customers like Qualcomm, who might
-   have different test command requirements from different manufacturers
- */
-int
-wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len)
-{
-    void *osbuf;
-    char *data;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    osbuf= A_NETBUF_ALLOC(len);
-    if(osbuf == NULL)
-    {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, len);
-    data = A_NETBUF_DATA(osbuf);
-    memcpy(data, buf, len);
-
-    return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
-         NO_SYNC_WMIFLAG));
-}
-
-#endif
-
-int
-wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status)
-{
-    void *osbuf;
-    WMI_SET_BT_STATUS_CMD *cmd;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->streamType = streamType;
-    cmd->status = status;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
-{
-    void *osbuf;
-    WMI_SET_BT_PARAMS_CMD* alloc_cmd;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
-
-    if (cmd->paramType == BT_PARAM_SCO) {
-      AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
-        cmd->info.scoParams.dataResponseTimeout,
-        cmd->info.scoParams.stompScoRules,
-        cmd->info.scoParams.scoOptFlags,
-        cmd->info.scoParams.stompDutyCyleVal,
-        cmd->info.scoParams.stompDutyCyleMaxVal,
-        cmd->info.scoParams.psPollLatencyFraction,
-        cmd->info.scoParams.noSCOSlots,
-        cmd->info.scoParams.noIdleSlots,
-        cmd->info.scoParams.scoOptOffRssi,
-        cmd->info.scoParams.scoOptOnRssi,
-        cmd->info.scoParams.scoOptRtsCount));
-    }
-    else if (cmd->paramType == BT_PARAM_A2DP) {
-      AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
-        cmd->info.a2dpParams.a2dpBurstCntMin,
-        cmd->info.a2dpParams.a2dpDataRespTimeout,
-        cmd->info.a2dpParams.a2dpOptFlags,
-        cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
-        cmd->info.a2dpParams.a2dpOptOffRssi,
-        cmd->info.a2dpParams.a2dpOptOnRssi,
-        cmd->info.a2dpParams.a2dpOptRtsCount));
-    }
-    else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
-      AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
-    }
-    else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
-      AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
-    }
-    else if (cmd->paramType == BT_PARAM_ACLCOEX) {
-      AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
-        cmd->info.aclCoexParams.aclBtMediumUsageTime,
-        cmd->info.aclCoexParams.aclDataRespTimeout));
-    }
-    else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
-      A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
-    }
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-    memcpy(alloc_cmd, cmd, sizeof(*cmd));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
-{
-       void *osbuf;
-    WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
-                         NO_SYNC_WMIFLAG));
-
-}
-
-
-int
-wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
-                                               WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
-{
-       void *osbuf;
-    WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-    memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
-    A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
-                         NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
-                                               WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
-{
-       void *osbuf;
-    WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
-                         NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
-                                               WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
-{
-       void *osbuf;
-    WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
-                         NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
-                                               WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
-{
-       void *osbuf;
-    WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
-                         NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
-                                               WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
-{
-       void *osbuf;
-    WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
-                         NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
-{
-       void *osbuf;
-       WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
-
-       osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-       if (osbuf == NULL) {
-                       return A_NO_MEMORY;
-       }
-       A_NETBUF_PUT(osbuf, sizeof(*cmd));
-       alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
-       A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
-       return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
-                                                        NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
-                                       WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
-{
-       void *osbuf;
-       WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
-
-       osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-       if (osbuf == NULL) {
-                       return A_NO_MEMORY;
-       }
-       A_NETBUF_PUT(osbuf, sizeof(*cmd));
-       alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
-       A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
-       return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
-                                                                NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
-{
-       void *osbuf;
-       WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
-
-       osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-       if (osbuf == NULL) {
-                       return A_NO_MEMORY;
-       }
-       A_NETBUF_PUT(osbuf, sizeof(*cmd));
-       alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
-       A_MEMZERO(alloc_cmd, sizeof(*cmd));
-       memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
-       return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
-                                                        NO_SYNC_WMIFLAG));
-
-}
-
-int
-wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
-{
-
-    return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
-
-}
-
-int
-wmi_get_keepalive_configured(struct wmi_t *wmip)
-{
-    void *osbuf;
-    WMI_GET_KEEPALIVE_CMD *cmd;
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-    cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-u8 wmi_get_keepalive_cmd(struct wmi_t *wmip)
-{
-    return wmip->wmi_keepaliveInterval;
-}
-
-int
-wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval)
-{
-    void *osbuf;
-    WMI_SET_KEEPALIVE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->keepaliveInterval = keepaliveInterval;
-    wmip->wmi_keepaliveInterval = keepaliveInterval;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer)
-{
-    void *osbuf;
-    WMI_SET_PARAMS_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
-
-    cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->opcode = opcode;
-    cmd->length = length;
-    memcpy(cmd->buffer, buffer, length);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
-{
-    void *osbuf;
-    WMI_SET_MCAST_FILTER_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->multicast_mac[0] = 0x01;
-    cmd->multicast_mac[1] = 0x00;
-    cmd->multicast_mac[2] = 0x5e;
-    cmd->multicast_mac[3] = dot2&0x7F;
-    cmd->multicast_mac[4] = dot3;
-    cmd->multicast_mac[5] = dot4;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
-{
-    void *osbuf;
-    WMI_SET_MCAST_FILTER_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->multicast_mac[0] = 0x01;
-    cmd->multicast_mac[1] = 0x00;
-    cmd->multicast_mac[2] = 0x5e;
-    cmd->multicast_mac[3] = dot2&0x7F;
-    cmd->multicast_mac[4] = dot3;
-    cmd->multicast_mac[5] = dot4;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable)
-{
-    void *osbuf;
-    WMI_MCAST_FILTER_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->enable = enable;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,
-                  u8 *ieInfo)
-{
-    void *osbuf;
-    WMI_SET_APPIE_CMD *cmd;
-    u16 cmdLen;
-
-    cmdLen = sizeof(*cmd) + ieLen - 1;
-    osbuf = A_NETBUF_ALLOC(cmdLen);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, cmdLen);
-
-    cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, cmdLen);
-
-    cmd->mgmtFrmType = mgmtFrmType;
-    cmd->ieLen = ieLen;
-    memcpy(cmd->ieInfo, ieInfo, ieLen);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen)
-{
-    void *osbuf;
-    u8 *data;
-
-    osbuf = A_NETBUF_ALLOC(dataLen);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, dataLen);
-
-    data = A_NETBUF_DATA(osbuf);
-
-    memcpy(data, cmd, dataLen);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
-}
-
-s32 wmi_get_rate(s8 rateindex)
-{
-    if (rateindex == RATE_AUTO) {
-        return 0;
-    } else {
-        return(wmi_rateTable[(u32) rateindex][0]);
-    }
-}
-
-void
-wmi_node_return (struct wmi_t *wmip, bss_t *bss)
-{
-    if (NULL != bss)
-    {
-        wlan_node_return (&wmip->wmi_scan_table, bss);
-    }
-}
-
-void
-wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge)
-{
-    wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
-}
-
-bss_t *
-wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
-                   u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
-{
-    bss_t *node = NULL;
-    node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
-                               ssidLength, bIsWPA2, bMatchSSID);
-    return node;
-}
-
-
-#ifdef THREAD_X
-void
-wmi_refresh_scan_table (struct wmi_t *wmip)
-{
-       wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
-}
-#endif
-
-void
-wmi_free_allnodes(struct wmi_t *wmip)
-{
-    wlan_free_allnodes(&wmip->wmi_scan_table);
-}
-
-bss_t *
-wmi_find_node(struct wmi_t *wmip, const u8 *macaddr)
-{
-    bss_t *ni=NULL;
-    ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
-    return ni;
-}
-
-void
-wmi_free_node(struct wmi_t *wmip, const u8 *macaddr)
-{
-    bss_t *ni=NULL;
-
-    ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
-    if (ni != NULL) {
-        wlan_node_reclaim(&wmip->wmi_scan_table, ni);
-    }
-
-    return;
-}
-
-int
-wmi_dset_open_reply(struct wmi_t *wmip,
-                    u32 status,
-                    u32 access_cookie,
-                    u32 dset_size,
-                    u32 dset_version,
-                    u32 targ_handle,
-                    u32 targ_reply_fn,
-                    u32 targ_reply_arg)
-{
-    void *osbuf;
-    WMIX_DSETOPEN_REPLY_CMD *open_reply;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*open_reply));
-    open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
-
-    open_reply->status                   = status;
-    open_reply->targ_dset_handle         = targ_handle;
-    open_reply->targ_reply_fn            = targ_reply_fn;
-    open_reply->targ_reply_arg           = targ_reply_arg;
-    open_reply->access_cookie            = access_cookie;
-    open_reply->size                     = dset_size;
-    open_reply->version                  = dset_version;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
-                             NO_SYNC_WMIFLAG));
-}
-
-static int
-wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
-{
-    WMI_PMKID_LIST_REPLY *reply;
-    u32 expected_len;
-
-    if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_PMKID_LIST_REPLY *)datap;
-    expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
-
-    if (len < expected_len) {
-        return A_EINVAL;
-    }
-
-    A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
-                           reply->pmkidList, reply->bssidList[0]);
-
-    return 0;
-}
-
-
-static int
-wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
-{
-    WMI_SET_PARAMS_REPLY *reply;
-
-    if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
-        return A_EINVAL;
-    }
-    reply = (WMI_SET_PARAMS_REPLY *)datap;
-
-    if (0 == reply->status)
-    {
-
-    }
-    else
-    {
-
-    }
-
-    return 0;
-}
-
-
-#ifdef CONFIG_HOST_DSET_SUPPORT
-int
-wmi_dset_data_reply(struct wmi_t *wmip,
-                    u32 status,
-                    u8 *user_buf,
-                    u32 length,
-                    u32 targ_buf,
-                    u32 targ_reply_fn,
-                    u32 targ_reply_arg)
-{
-    void *osbuf;
-    WMIX_DSETDATA_REPLY_CMD *data_reply;
-    u32 size;
-
-    size = sizeof(*data_reply) + length;
-
-    if (size <= length) {
-        return A_ERROR;
-    }
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, size);
-    data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
-
-    data_reply->status                     = status;
-    data_reply->targ_buf                   = targ_buf;
-    data_reply->targ_reply_fn              = targ_reply_fn;
-    data_reply->targ_reply_arg             = targ_reply_arg;
-    data_reply->length                     = length;
-
-    if (status == 0) {
-        if (a_copy_from_user(data_reply->buf, user_buf, length)) {
-            A_NETBUF_FREE(osbuf);
-            return A_ERROR;
-        }
-    }
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
-                             NO_SYNC_WMIFLAG));
-}
-#endif /* CONFIG_HOST_DSET_SUPPORT */
-
-int
-wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status)
-{
-    void *osbuf;
-    char *cmd;
-
-    wps_enable = status;
-
-    osbuf = a_netbuf_alloc(sizeof(1));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    a_netbuf_put(osbuf, sizeof(1));
-
-    cmd = (char *)(a_netbuf_to_data(osbuf));
-
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd[0] = (status?1:0);
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-int
-wmi_prof_cfg_cmd(struct wmi_t *wmip,
-                 u32 period,
-                 u32 nbins)
-{
-    void *osbuf;
-    WMIX_PROF_CFG_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->period = period;
-    cmd->nbins  = nbins;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr)
-{
-    void *osbuf;
-    WMIX_PROF_ADDR_SET_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->addr = addr;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_prof_start_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
-}
-
-int
-wmi_prof_stop_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
-}
-
-int
-wmi_prof_count_get_cmd(struct wmi_t *wmip)
-{
-    return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
-}
-
-/* Called to handle WMIX_PROF_CONT_EVENTID */
-static int
-wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
-        prof_data->addr, prof_data->count));
-
-    A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
-
-    return 0;
-}
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-
-#ifdef OS_ROAM_MANAGEMENT
-
-#define ETHERNET_MAC_ADDRESS_LENGTH    6
-
-void
-wmi_scan_indication (struct wmi_t *wmip)
-{
-    struct ieee80211_node_table *nt;
-    u32 gen;
-    u32 size;
-    u32 bsssize;
-    bss_t *bss;
-    u32 numbss;
-    PNDIS_802_11_BSSID_SCAN_INFO psi;
-    PBYTE  pie;
-    NDIS_802_11_FIXED_IEs *pFixed;
-    NDIS_802_11_VARIABLE_IEs *pVar;
-    u32 RateSize;
-
-    struct ar6kScanIndication
-    {
-        NDIS_802_11_STATUS_INDICATION     ind;
-        NDIS_802_11_BSSID_SCAN_INFO_LIST  slist;
-    } *pAr6kScanIndEvent;
-
-    nt = &wmip->wmi_scan_table;
-
-    ++nt->nt_si_gen;
-
-
-    gen = nt->nt_si_gen;
-
-    size = offsetof(struct ar6kScanIndication, slist) +
-           offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
-
-    numbss = 0;
-
-    IEEE80211_NODE_LOCK(nt);
-
-    //calc size
-    for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
-        if (bss->ni_si_gen != gen) {
-            bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
-            bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
-
-#ifdef SUPPORT_WPA2
-            if (bss->ni_cie.ie_rsn) {
-                bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
-            }
-#endif
-            if (bss->ni_cie.ie_wpa) {
-                bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
-            }
-
-            // bsssize must be a multiple of 4 to maintain alignment.
-            bsssize = (bsssize + 3) & ~3;
-
-            size += bsssize;
-
-            numbss++;
-        }
-    }
-
-    if (0 == numbss)
-    {
-//        RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
-        ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
-        IEEE80211_NODE_UNLOCK (nt);
-        return;
-    }
-
-    pAr6kScanIndEvent = A_MALLOC(size);
-
-    if (NULL == pAr6kScanIndEvent)
-    {
-        IEEE80211_NODE_UNLOCK(nt);
-        return;
-    }
-
-    A_MEMZERO(pAr6kScanIndEvent, size);
-
-    //copy data
-    pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
-    pAr6kScanIndEvent->slist.Version = 1;
-    pAr6kScanIndEvent->slist.NumItems = numbss;
-
-    psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
-
-    for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
-        if (bss->ni_si_gen != gen) {
-
-            bss->ni_si_gen = gen;
-
-            //Set scan time
-            psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
-
-            // Copy data to bssid_ex
-            bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
-            bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
-
-#ifdef SUPPORT_WPA2
-            if (bss->ni_cie.ie_rsn) {
-                bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
-            }
-#endif
-            if (bss->ni_cie.ie_wpa) {
-                bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
-            }
-
-            // bsssize must be a multiple of 4 to maintain alignment.
-            bsssize = (bsssize + 3) & ~3;
-
-            psi->Bssid.Length = bsssize;
-
-            memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
-
-
-//if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
-//  ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
-//            RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
-
-            psi->Bssid.Ssid.SsidLength = 0;
-            pie = bss->ni_cie.ie_ssid;
-
-            if (pie) {
-                // Format of SSID IE is:
-                //  Type   (1 octet)
-                //  Length (1 octet)
-                //  SSID (Length octets)
-                //
-                //  Validation of the IE should have occurred within WMI.
-                //
-                if (pie[1] <= 32) {
-                    psi->Bssid.Ssid.SsidLength = pie[1];
-                    memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
-                }
-            }
-            psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
-
-            //Post the RSSI value relative to the Standard Noise floor value.
-            psi->Bssid.Rssi = bss->ni_rssi;
-
-            if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
-
-                if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
-                    psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
-                }
-                else {
-                    psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
-                }
-            }
-            else {
-                psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
-            }
-
-            psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
-            psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
-            psi->Bssid.Configuration.ATIMWindow =  0;
-            psi->Bssid.Configuration.DSConfig =  bss->ni_cie.ie_chan * 1000;
-            psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
-
-            RateSize = 0;
-            pie = bss->ni_cie.ie_rates;
-            if (pie) {
-                RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
-                memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
-            }
-            pie = bss->ni_cie.ie_xrates;
-            if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
-                memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
-                       (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
-            }
-
-            // Copy the fixed IEs
-            psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
-
-            pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
-            memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
-            pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
-            pFixed->Capabilities = bss->ni_cie.ie_capInfo;
-
-            // Copy selected variable IEs
-
-            pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
-
-#ifdef SUPPORT_WPA2
-            // Copy the WPAv2 IE
-            if (bss->ni_cie.ie_rsn) {
-                pie = bss->ni_cie.ie_rsn;
-                psi->Bssid.IELength += pie[1] + 2;
-                memcpy(pVar, pie, pie[1] + 2);
-                pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
-            }
-#endif
-            // Copy the WPAv1 IE
-            if (bss->ni_cie.ie_wpa) {
-                pie = bss->ni_cie.ie_wpa;
-                psi->Bssid.IELength += pie[1] + 2;
-                memcpy(pVar, pie, pie[1] + 2);
-                pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
-            }
-
-            // Advance buffer pointer
-            psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
-        }
-    }
-
-    IEEE80211_NODE_UNLOCK(nt);
-
-//    wmi_free_allnodes(wmip);
-
-//    RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
-
-    ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
-
-    kfree(pAr6kScanIndEvent);
-}
-#endif
-
-u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
-                           u32 size)
-{
-    u32 index;
-    u8 threshold = (u8)sq_thresh->upper_threshold[size - 1];
-
-    /* The list is already in sorted order. Get the next lower value */
-    for (index = 0; index < size; index ++) {
-        if (rssi < sq_thresh->upper_threshold[index]) {
-            threshold = (u8)sq_thresh->upper_threshold[index];
-            break;
-        }
-    }
-
-    return threshold;
-}
-
-u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
-                           u32 size)
-{
-    u32 index;
-    u8 threshold = (u8)sq_thresh->lower_threshold[size - 1];
-
-    /* The list is already in sorted order. Get the next lower value */
-    for (index = 0; index < size; index ++) {
-        if (rssi > sq_thresh->lower_threshold[index]) {
-            threshold = (u8)sq_thresh->lower_threshold[index];
-            break;
-        }
-    }
-
-    return threshold;
-}
-static int
-wmi_send_rssi_threshold_params(struct wmi_t *wmip,
-                              WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-
-    cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-static int
-wmi_send_snr_threshold_params(struct wmi_t *wmip,
-                             WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
-{
-    void    *osbuf;
-    s8 size;
-    WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
-
-    size = sizeof (*cmd);
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, size);
-    cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, size);
-    memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
-                            NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
-{
-    void *osbuf;
-    WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(alloc_cmd, sizeof(*cmd));
-    memcpy(alloc_cmd, cmd, sizeof(*cmd));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
-            NO_SYNC_WMIFLAG));
-}
-
-bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id)
-{
-    wmi_get_current_bssid (wmip, id);
-    return wlan_node_remove (&wmip->wmi_scan_table, id);
-}
-
-int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss)
-{
-    wlan_setup_node (&wmip->wmi_scan_table, bss, id);
-    return 0;
-}
-
-static int
-wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
-
-    A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
-
-    return 0;
-}
-
-
-static int
-wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
-
-    A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
-
-    return 0;
-}
-
-static int
-wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
-
-    A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
-
-    return 0;
-}
-
-int
-wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-       A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
-
-     return 0;
-}
-
-
-int
-wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len)
-{
-       A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
-
-     return 0;
-
-}
-
-static int
-wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
-    A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
-
-    return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////                                                                        ////
-////                AP mode functions                                       ////
-////                                                                        ////
-////////////////////////////////////////////////////////////////////////////////
-/*
- * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
- *
- * When AR6K in AP mode, This command will be called after
- * changing ssid, channel etc. It will pass the profile to
- * target with a flag which will indicate which parameter changed,
- * also if this flag is 0, there was no change in parametes, so
- * commit cmd will not be sent to target. Without calling this IOCTL
- * the changes will not take effect.
- */
-int
-wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
-{
-    void *osbuf;
-    WMI_CONNECT_CMD *cm;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cm));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cm));
-    cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cm, sizeof(*cm));
-
-    memcpy(cm,p,sizeof(*cm));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
-}
-
-/*
- * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
- *
- * This command will be used to enable/disable hidden ssid functioanlity of
- * beacon. If it is enabled, ssid will be NULL in beacon.
- */
-int
-wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid)
-{
-    void *osbuf;
-    WMI_AP_HIDDEN_SSID_CMD *hs;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
-    hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(hs, sizeof(*hs));
-
-    hs->hidden_ssid          = hidden_ssid;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
-}
-
-/*
- * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
- *
- * This command is used to limit max num of STA that can connect
- * with this AP. This value should not exceed AP_MAX_NUM_STA (this
- * is max num of STA supported by AP). Value was already validated
- * in ioctl.c
- */
-int
-wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta)
-{
-    void *osbuf;
-    WMI_AP_SET_NUM_STA_CMD *ns;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
-    ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(ns, sizeof(*ns));
-
-    ns->num_sta          = num_sta;
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
-}
-
-/*
- * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
- *
- * This command is used to send list of mac of STAs which will
- * be allowed to connect with this AP. When this list is empty
- * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
- */
-int
-wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
-{
-    void *osbuf;
-    WMI_AP_ACL_MAC_CMD *a;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
-    a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(a, sizeof(*a));
-    memcpy(a,acl,sizeof(*acl));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
-}
-
-/*
- * IOCTL: AR6000_XIOCTL_AP_SET_MLME
- *
- * This command is used to send list of mac of STAs which will
- * be allowed to connect with this AP. When this list is empty
- * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
- */
-int
-wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason)
-{
-    void *osbuf;
-    WMI_AP_SET_MLME_CMD *mlme;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
-    mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(mlme, sizeof(*mlme));
-
-    mlme->cmd = cmd;
-    memcpy(mlme->mac, mac, ATH_MAC_LEN);
-    mlme->reason = reason;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
-}
-
-static int
-wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMI_PSPOLL_EVENT *ev;
-
-    if (len < sizeof(WMI_PSPOLL_EVENT)) {
-        return A_EINVAL;
-    }
-    ev = (WMI_PSPOLL_EVENT *)datap;
-
-    A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
-    return 0;
-}
-
-static int
-wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len)
-{
-    A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
-    return 0;
-}
-
-#ifdef WAPI_ENABLE
-static int
-wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len)
-{
-    u8 *ev;
-
-    if (len < 7) {
-        return A_EINVAL;
-    }
-    ev = (u8 *)datap;
-
-    A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
-    return 0;
-}
-#endif
-
-int
-wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag)
-{
-    WMI_AP_SET_PVB_CMD *cmd;
-    void *osbuf = NULL;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
-    cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->aid = aid;
-    cmd->flag = flag;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period)
-{
-    WMI_AP_CONN_INACT_CMD *cmd;
-    void *osbuf = NULL;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
-    cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->period = period;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell)
-{
-    WMI_AP_PROT_SCAN_TIME_CMD *cmd;
-    void *osbuf = NULL;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
-    cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->period_min = period;
-    cmd->dwell_ms   = dwell;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim)
-{
-    WMI_AP_SET_DTIM_CMD *cmd;
-    void *osbuf = NULL;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
-    cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-
-    cmd->dtim = dtim;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
-}
-
-/*
- * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
- *
- * This command is used to set ACL policay. While changing policy, if you
- * want to retain the existing MAC addresses in the ACL list, policy should be
- * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
- * If there is no chage in policy, the list will be intact.
- */
-int
-wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy)
-{
-    void *osbuf;
-    WMI_AP_ACL_POLICY_CMD *po;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-}
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
-    po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(po, sizeof(*po));
-
-    po->policy = policy;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset)
-{
-    void *osbuf;
-    WMI_AP_SET_11BG_RATESET_CMD *rs;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
-    rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(rs, sizeof(*rs));
-
-    rs->rateset = rateset;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
-{
-    void *osbuf;
-    WMI_SET_HT_CAP_CMD *htCap;
-    u8 band;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*htCap));
-
-    band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
-    wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
-
-    htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(htCap, sizeof(*htCap));
-    memcpy(htCap, cmd, sizeof(*htCap));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width)
-{
-    void *osbuf;
-    WMI_SET_HT_OP_CMD *htInfo;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*htInfo));
-
-    htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(htInfo, sizeof(*htInfo));
-    htInfo->sta_chan_width = sta_chan_width;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
-{
-    void *osbuf;
-    WMI_SET_TX_SELECT_RATES_CMD *pData;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*pData));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*pData));
-
-    pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
-    memcpy(pData, pMaskArray, sizeof(*pData));
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz)
-{
-    void *osbuf;
-    WMI_HCI_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
-    cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
-
-    cmd->cmd_buf_sz = sz;
-    memcpy(cmd->buf, buf, sz);
-    return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask)
-{
-    void *osbuf;
-    WMI_ALLOW_AGGR_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->tx_allow_aggr = tx_tidmask;
-    cmd->rx_allow_aggr = rx_tidmask;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid)
-{
-    void *osbuf;
-    WMI_ADDBA_REQ_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->tid = tid;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink)
-{
-    void *osbuf;
-    WMI_DELBA_REQ_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->tid = tid;
-    cmd->is_sender_initiator = uplink;  /* uplink =1 - uplink direction, 0=downlink direction */
-
-    /* Delete the local aggr state, on host */
-    return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion,
-                            bool rxDot11Hdr, bool defragOnHost)
-{
-    void *osbuf;
-    WMI_RX_FRAME_FORMAT_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0;
-    cmd->defragOnHost = (defragOnHost==true)? 1:0;
-    cmd->metaVersion = rxMetaVersion;  /*  */
-
-    /* Delete the local aggr state, on host */
-    return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode)
-{
-    void *osbuf;
-    WMI_SET_THIN_MODE_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
-    cmd->enable = (bThinMode==true)? 1:0;
-
-    /* Delete the local aggr state, on host */
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
-}
-
-
-int
-wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
-{
-    void *osbuf;
-    WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->precedence = precedence;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk)
-{
-    void *osbuf;
-    WMI_SET_PMK_CMD *p;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
-
-    p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(p, sizeof(*p));
-
-    memcpy(p->pmk, pmk, WMI_PMK_LEN);
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd)
-{
-    void *osbuf;
-    WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
-
-    p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf));
-    memset(p, 0, sizeof(*p));
-
-    p->threshold = cmd->threshold;
-
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG));
-}
-
-int
-wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold)
-{
-    void *osbuf;
-    WMI_SET_TX_SGI_PARAM_CMD *cmd;
-
-    osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
-    if (osbuf == NULL) {
-        return A_NO_MEMORY ;
-    }
-
-    A_NETBUF_PUT(osbuf, sizeof(*cmd));
-
-    cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
-    A_MEMZERO(cmd, sizeof(*cmd));
-    cmd->sgiMask = sgiMask;
-    cmd->sgiPERThreshold = sgiPERThreshold;
-    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
-                         NO_SYNC_WMIFLAG));
-}
-
-bss_t *
-wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
-                   u32 ssidLength,
-                   u32 dot11AuthMode, u32 authMode,
-                   u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
-{
-    bss_t *node = NULL;
-    node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
-                               ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
-
-    return node;
-}
-
-u16 wmi_ieee2freq (int chan)
-{
-    u16 freq = 0;
-    freq = wlan_ieee2freq (chan);
-    return freq;
-
-}
-
-u32 wmi_freq2ieee (u16 freq)
-{
-    u16 chan = 0;
-    chan = wlan_freq2ieee (freq);
-    return chan;
-}
diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h
deleted file mode 100644 (file)
index 53e4f08..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wmi_host.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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 local definitios for the wmi host module.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _WMI_HOST_H_
-#define _WMI_HOST_H_
-
-#include "roaming.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct wmi_stats {
-    u32 cmd_len_err;
-    u32 cmd_id_err;
-};
-
-#define SSID_IE_LEN_INDEX 13
-
-/* Host side link management data structures */
-#define SIGNAL_QUALITY_THRESHOLD_LEVELS 6
-#define SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
-#define SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
-typedef struct sq_threshold_params_s {
-    s16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS];
-    s16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS];
-    u32 upper_threshold_valid_count;
-    u32 lower_threshold_valid_count;
-    u32 polling_interval;
-    u8 weight;
-    u8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target.
-    u8 last_rssi_poll_event; //Not sure if it belongs to host or target
-} SQ_THRESHOLD_PARAMS;
-
-/*
- * These constants are used with A_WLAN_BAND_SET.
- */ 
-#define A_BAND_24GHZ           0
-#define A_BAND_5GHZ            1
-#define A_NUM_BANDS            2
-
-struct wmi_t {
-    bool                          wmi_ready;
-    bool                          wmi_numQoSStream;
-    u16 wmi_streamExistsForAC[WMM_NUM_AC];
-    u8 wmi_fatPipeExists;
-    void                           *wmi_devt;
-    struct wmi_stats                wmi_stats;
-    struct ieee80211_node_table     wmi_scan_table;
-    u8 wmi_bssid[ATH_MAC_LEN];
-    u8 wmi_powerMode;
-    u8 wmi_phyMode;
-    u8 wmi_keepaliveInterval;
-#ifdef THREAD_X
-    A_CSECT_T                       wmi_lock;
-#else 
-    A_MUTEX_T                       wmi_lock;
-#endif
-    HTC_ENDPOINT_ID                 wmi_endpoint_id;
-    SQ_THRESHOLD_PARAMS             wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_NUM_MAX];
-    CRYPTO_TYPE                     wmi_pair_crypto_type;
-    CRYPTO_TYPE                     wmi_grp_crypto_type;
-    bool                          wmi_is_wmm_enabled;
-    u8 wmi_ht_allowed[A_NUM_BANDS];
-    u8 wmi_traffic_class;
-};
-
-#ifdef THREAD_X
-#define INIT_WMI_LOCK(w)    A_CSECT_INIT(&(w)->wmi_lock)
-#define LOCK_WMI(w)         A_CSECT_ENTER(&(w)->wmi_lock);
-#define UNLOCK_WMI(w)       A_CSECT_LEAVE(&(w)->wmi_lock);
-#define DELETE_WMI_LOCK(w)  A_CSECT_DELETE(&(w)->wmi_lock);
-#else
-#define LOCK_WMI(w)     A_MUTEX_LOCK(&(w)->wmi_lock);
-#define UNLOCK_WMI(w)   A_MUTEX_UNLOCK(&(w)->wmi_lock);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _WMI_HOST_H_ */
index 05dada98eb6bfb6bbacc0a6d8c5cf41834d39ffd..b1294017dd7b75777faee870b624aea95011f026 100644 (file)
@@ -1437,7 +1437,7 @@ static struct net_device_ops brcmf_netdev_ops_pri = {
        .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
        .ndo_start_xmit = brcmf_netdev_start_xmit,
        .ndo_set_mac_address = brcmf_netdev_set_mac_address,
-       .ndo_set_multicast_list = brcmf_netdev_set_multicast_list
+       .ndo_set_rx_mode = brcmf_netdev_set_multicast_list,
 };
 
 int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
index 34253cf37812a60c190dbc2f5143623f6ba9f354..4a70180eba5d71060358edb08c18bce98e9b9b18 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/io.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 
 #include <brcm_hw_ids.h>
 #include <chipcommon.h>
index bbf21897ae0e32137c7f38bbabf5159a31b4cda7..823b5e4672e29fbae23e7bab1175e94154c1b9d6 100644 (file)
@@ -18,6 +18,7 @@
 #define _BRCM_TYPES_H_
 
 #include <linux/types.h>
+#include <linux/io.h>
 
 /* Bus types */
 #define        SI_BUS                  0       /* SOC Interconnect */
index 5f25bbad36b6c05d4af2cbd7398b45f35e18d0f3..4406630b0c6f110e5781d17c7cc3423f00fad54d 100644 (file)
@@ -638,7 +638,7 @@ static const struct net_device_ops et131x_netdev_ops = {
        .ndo_open               = et131x_open,
        .ndo_stop               = et131x_close,
        .ndo_start_xmit         = et131x_tx,
-       .ndo_set_multicast_list = et131x_multicast,
+       .ndo_set_rx_mode        = et131x_multicast,
        .ndo_tx_timeout         = et131x_tx_timeout,
        .ndo_change_mtu         = et131x_change_mtu,
        .ndo_set_mac_address    = et131x_set_mac_addr,
index 61989f0d9f0d34faf68d25d637aea35b0392fef9..bfd4c81c410f3774636f545b19ba09682df998d6 100644 (file)
@@ -307,7 +307,7 @@ static const struct net_device_ops device_ops = {
        .ndo_open =                     netvsc_open,
        .ndo_stop =                     netvsc_close,
        .ndo_start_xmit =               netvsc_start_xmit,
-       .ndo_set_multicast_list =       netvsc_set_multicast_list,
+       .ndo_set_rx_mode =              netvsc_set_multicast_list,
        .ndo_change_mtu =               eth_change_mtu,
        .ndo_validate_addr =            eth_validate_addr,
        .ndo_set_mac_address =          eth_mac_addr,
index 9c0d2936e4862e2d3c8888fa8618e12416966212..c3d73f8431ae88f3cc7604ac603aabd36ae26a29 100644 (file)
@@ -26,6 +26,7 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/interrupt.h>
 #include <linux/phy.h>
 #include <linux/ratelimit.h>
 #include <net/dst.h>
index 970825421884d44526385d7782d4faa40207501c..d0e2d514968a6f864f5fbda312a854e2a1cc414c 100644 (file)
@@ -26,6 +26,7 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/interrupt.h>
 #include <net/dst.h>
 
 #include <asm/octeon/octeon.h>
index a8f780e95e0a5c735c5e6560e4c44ca4d48f30fb..076f86675ce68878d61acae0271ff76f0c380186 100644 (file)
@@ -512,7 +512,7 @@ static const struct net_device_ops cvm_oct_npi_netdev_ops = {
        .ndo_init               = cvm_oct_common_init,
        .ndo_uninit             = cvm_oct_common_uninit,
        .ndo_start_xmit         = cvm_oct_xmit,
-       .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
+       .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
        .ndo_do_ioctl           = cvm_oct_ioctl,
        .ndo_change_mtu         = cvm_oct_common_change_mtu,
@@ -527,7 +527,7 @@ static const struct net_device_ops cvm_oct_xaui_netdev_ops = {
        .ndo_open               = cvm_oct_xaui_open,
        .ndo_stop               = cvm_oct_xaui_stop,
        .ndo_start_xmit         = cvm_oct_xmit,
-       .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
+       .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
        .ndo_do_ioctl           = cvm_oct_ioctl,
        .ndo_change_mtu         = cvm_oct_common_change_mtu,
@@ -542,7 +542,7 @@ static const struct net_device_ops cvm_oct_sgmii_netdev_ops = {
        .ndo_open               = cvm_oct_sgmii_open,
        .ndo_stop               = cvm_oct_sgmii_stop,
        .ndo_start_xmit         = cvm_oct_xmit,
-       .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
+       .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
        .ndo_do_ioctl           = cvm_oct_ioctl,
        .ndo_change_mtu         = cvm_oct_common_change_mtu,
@@ -555,7 +555,7 @@ static const struct net_device_ops cvm_oct_spi_netdev_ops = {
        .ndo_init               = cvm_oct_spi_init,
        .ndo_uninit             = cvm_oct_spi_uninit,
        .ndo_start_xmit         = cvm_oct_xmit,
-       .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
+       .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
        .ndo_do_ioctl           = cvm_oct_ioctl,
        .ndo_change_mtu         = cvm_oct_common_change_mtu,
@@ -570,7 +570,7 @@ static const struct net_device_ops cvm_oct_rgmii_netdev_ops = {
        .ndo_open               = cvm_oct_rgmii_open,
        .ndo_stop               = cvm_oct_rgmii_stop,
        .ndo_start_xmit         = cvm_oct_xmit,
-       .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
+       .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
        .ndo_do_ioctl           = cvm_oct_ioctl,
        .ndo_change_mtu         = cvm_oct_common_change_mtu,
@@ -582,7 +582,7 @@ static const struct net_device_ops cvm_oct_rgmii_netdev_ops = {
 static const struct net_device_ops cvm_oct_pow_netdev_ops = {
        .ndo_init               = cvm_oct_common_init,
        .ndo_start_xmit         = cvm_oct_xmit_pow,
-       .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
+       .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
        .ndo_do_ioctl           = cvm_oct_ioctl,
        .ndo_change_mtu         = cvm_oct_common_change_mtu,
index 4c6651aac30793ffab9ade20bd167acd3303de7d..04c23919f4d661d36ab9758401d03d9a55e5a57c 100644 (file)
@@ -3534,7 +3534,7 @@ static const struct net_device_ops rtl8180_netdev_ops = {
        .ndo_get_stats          = rtl8180_stats,
        .ndo_tx_timeout         = rtl8180_restart,
        .ndo_do_ioctl           = rtl8180_ioctl,
-       .ndo_set_multicast_list = r8180_set_multicast,
+       .ndo_set_rx_mode        = r8180_set_multicast,
        .ndo_set_mac_address    = r8180_set_mac_adr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
index 94d9c8d5d0907b6519ef65727946337097f99084..b418fed703c699e80f5b5193dcec252827e61237 100644 (file)
@@ -4519,7 +4519,7 @@ static const struct net_device_ops rtl8192_netdev_ops = {
        .ndo_stop =                     rtl8192_close,
        .ndo_tx_timeout =               tx_timeout,
        .ndo_do_ioctl =                 rtl8192_ioctl,
-       .ndo_set_multicast_list =       r8192_set_multicast,
+       .ndo_set_rx_mode =              r8192_set_multicast,
        .ndo_set_mac_address =          r8192_set_mac_adr,
        .ndo_start_xmit =               ieee80211_rtl_xmit,
 };
index ee86fe8509ed58513f87e21e7bd299c42b6d13ef..c09be0a6646752a8cb25d369529a8488f01ad1a5 100644 (file)
@@ -5739,7 +5739,7 @@ static const struct net_device_ops rtl8192_netdev_ops = {
        .ndo_get_stats          = rtl8192_stats,
        .ndo_tx_timeout         = tx_timeout,
        .ndo_do_ioctl           = rtl8192_ioctl,
-       .ndo_set_multicast_list = r8192_set_multicast,
+       .ndo_set_rx_mode        = r8192_set_multicast,
        .ndo_set_mac_address    = r8192_set_mac_adr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
index 16c73fbff51fe52d9bd3b11d5e91a39a1654c573..a1b909345020fd80e55faba7ab9d409d02acadeb 100644 (file)
@@ -466,8 +466,6 @@ static int rtsx_control_thread(void *__dev)
        struct rtsx_chip *chip = dev->chip;
        struct Scsi_Host *host = rtsx_to_host(dev);
 
-       current->flags |= PF_NOFREEZE;
-
        for (;;) {
                if (wait_for_completion_interruptible(&dev->cmnd_ready))
                        break;
index 18f11039bb5f368a45bc4937b934aeab161eb5d4..77a0751a31ad8cc8b251ff267eeb497be0e707c2 100644 (file)
@@ -3724,7 +3724,7 @@ static const struct net_device_ops slic_netdev_ops = {
        .ndo_do_ioctl           = slic_ioctl,
        .ndo_set_mac_address    = slic_mac_set_address,
        .ndo_get_stats          = slic_get_stats,
-       .ndo_set_multicast_list = slic_mcast_set_list,
+       .ndo_set_rx_mode        = slic_mcast_set_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
 };
index 3d2a9ba16b15cdcfb3c37ceb866373f096b72886..8cb9116c44f8a7b94fac7f0665c7960c48d3f409 100644 (file)
@@ -911,7 +911,7 @@ static const struct net_device_ops device_netdev_ops = {
     .ndo_do_ioctl           = device_ioctl,
     .ndo_get_stats          = device_get_stats,
     .ndo_start_xmit         = device_xmit,
-    .ndo_set_multicast_list = device_set_multi,
+    .ndo_set_rx_mode       = device_set_multi,
 };
 
 
index e18efd43e3e0235ba8d6111b8c7bd42a975ceb71..1ff394074cba398ba39e8b370c2a923f0d540b83 100644 (file)
@@ -753,7 +753,7 @@ static const struct net_device_ops device_netdev_ops = {
     .ndo_do_ioctl           = device_ioctl,
     .ndo_get_stats          = device_get_stats,
     .ndo_start_xmit         = device_xmit,
-    .ndo_set_multicast_list = device_set_multi,
+    .ndo_set_rx_mode       = device_set_multi,
 };
 
 static int __devinit
index cf917e613f22a087888168195749d4abf14ac9ad..b21515ff678a4b1e508e6dd8df108f5d2850404b 100644 (file)
@@ -1179,7 +1179,7 @@ static const struct net_device_ops wl_netdev_ops =
 
     .ndo_set_config         = &wl_config,
     .ndo_get_stats          = &wl_stats,
-    .ndo_set_multicast_list = &wl_multicast,
+    .ndo_set_rx_mode        = &wl_multicast,
 
     .ndo_init               = &wl_insert,
     .ndo_open               = &wl_adapter_open,
index b0af292bc7e33c0ae3413603b647a231a93819e9..14bfeb2e704cbb8bf83b7b450d529e182dde9dbf 100644 (file)
@@ -715,7 +715,7 @@ static const struct net_device_ops p80211_netdev_ops = {
        .ndo_stop = p80211knetdev_stop,
        .ndo_get_stats = p80211knetdev_get_stats,
        .ndo_start_xmit = p80211knetdev_hard_start_xmit,
-       .ndo_set_multicast_list = p80211knetdev_set_multicast_list,
+       .ndo_set_rx_mode = p80211knetdev_set_multicast_list,
        .ndo_do_ioctl = p80211knetdev_do_ioctl,
        .ndo_set_mac_address = p80211knetdev_set_mac_address,
        .ndo_tx_timeout = p80211knetdev_tx_timeout,
index 4403e5f8059713d5062a8be65a574513c030c8f6..f8b88add9520dab5c4cfe6a934711f85a26be5ec 100644 (file)
@@ -1364,26 +1364,16 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 }
 
 #ifdef XGIFB_PAN
-static int XGIfb_pan_var(struct fb_var_screeninfo *var)
+static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        unsigned int base;
 
        /* printk("Inside pan_var"); */
 
-       if (var->xoffset > (var->xres_virtual - var->xres)) {
-               /* printk("Pan: xo: %d xv %d xr %d\n",
-                       var->xoffset, var->xres_virtual, var->xres); */
-               return -EINVAL;
-       }
-       if (var->yoffset > (var->yres_virtual - var->yres)) {
-               /* printk("Pan: yo: %d yv %d yr %d\n",
-                       var->yoffset, var->yres_virtual, var->yres); */
-               return -EINVAL;
-       }
-       base = var->yoffset * var->xres_virtual + var->xoffset;
+       base = var->yoffset * info->var.xres_virtual + var->xoffset;
 
        /* calculate base bpp dep. */
-       switch (var->bits_per_pixel) {
+       switch (info->var.bits_per_pixel) {
        case 16:
                base >>= 1;
                break;
@@ -1681,9 +1671,9 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
 
        /* printk("\nInside pan_display:\n"); */
 
-       if (var->xoffset > (var->xres_virtual - var->xres))
+       if (var->xoffset > (info->var.xres_virtual - info->var.xres))
                return -EINVAL;
-       if (var->yoffset > (var->yres_virtual - var->yres))
+       if (var->yoffset > (info->var.yres_virtual - info->var.yres))
                return -EINVAL;
 
        if (var->vmode & FB_VMODE_YWRAP) {
@@ -1696,7 +1686,7 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var,
                                                > info->var.yres_virtual)
                        return -EINVAL;
        }
-       err = XGIfb_pan_var(var);
+       err = XGIfb_pan_var(var, info);
        if (err < 0)
                return err;
 
index 975e34bcd722aecf4ed753a9b86ad25e90c5d19c..1ca66ea9b28123825a4db9b08d8621da909c8c66 100644 (file)
@@ -604,7 +604,7 @@ int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index,
        struct tmem_obj *obj;
        void *pampd;
        bool ephemeral = is_ephemeral(pool);
-       uint32_t ret = -1;
+       int ret = -1;
        struct tmem_hashbucket *hb;
        bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral);
        bool lock_held = false;
index 855a5bb56a47d8e591873b05e6be15ec6f4f6ee0..a3f5162bfedcf5fb6f58f42405f3323e18880ed1 100644 (file)
@@ -1158,7 +1158,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
        size_t clen;
        int ret;
        unsigned long count;
-       struct page *page = virt_to_page(data);
+       struct page *page = (struct page *)(data);
        struct zcache_client *cli = pool->client;
        uint16_t client_id = get_client_id_from_client(cli);
        unsigned long zv_mean_zsize;
@@ -1227,7 +1227,7 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw,
        int ret = 0;
 
        BUG_ON(is_ephemeral(pool));
-       zv_decompress(virt_to_page(data), pampd);
+       zv_decompress((struct page *)(data), pampd);
        return ret;
 }
 
@@ -1539,7 +1539,7 @@ static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp,
                goto out;
        if (!zcache_freeze && zcache_do_preload(pool) == 0) {
                /* preload does preempt_disable on success */
-               ret = tmem_put(pool, oidp, index, page_address(page),
+               ret = tmem_put(pool, oidp, index, (char *)(page),
                                PAGE_SIZE, 0, is_ephemeral(pool));
                if (ret < 0) {
                        if (is_ephemeral(pool))
@@ -1572,7 +1572,7 @@ static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp,
        pool = zcache_get_pool_by_id(cli_id, pool_id);
        if (likely(pool != NULL)) {
                if (atomic_read(&pool->obj_count) > 0)
-                       ret = tmem_get(pool, oidp, index, page_address(page),
+                       ret = tmem_get(pool, oidp, index, (char *)(page),
                                        &size, 0, is_ephemeral(pool));
                zcache_put_pool(pool);
        }
index 98b6e3bdb000bda730a69a05680d76b8584f1715..e809e9d4683c6d82197cbd569c12b1375df8be99 100644 (file)
@@ -446,8 +446,19 @@ static inline void legacy_pty_init(void) { }
 int pty_limit = NR_UNIX98_PTY_DEFAULT;
 static int pty_limit_min;
 static int pty_limit_max = NR_UNIX98_PTY_MAX;
+static int tty_count;
 static int pty_count;
 
+static inline void pty_inc_count(void)
+{
+       pty_count = (++tty_count) / 2;
+}
+
+static inline void pty_dec_count(void)
+{
+       pty_count = (--tty_count) / 2;
+}
+
 static struct cdev ptmx_cdev;
 
 static struct ctl_table pty_table[] = {
@@ -542,6 +553,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
 
 static void pty_unix98_shutdown(struct tty_struct *tty)
 {
+       tty_driver_remove_tty(tty->driver, tty);
        /* We have our own method as we don't use the tty index */
        kfree(tty->termios);
 }
@@ -588,7 +600,8 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
         */
        tty_driver_kref_get(driver);
        tty->count++;
-       pty_count++;
+       pty_inc_count(); /* tty */
+       pty_inc_count(); /* tty->link */
        return 0;
 err_free_mem:
        deinitialize_tty_struct(o_tty);
@@ -602,7 +615,7 @@ err_free_tty:
 
 static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 {
-       pty_count--;
+       pty_dec_count();
 }
 
 static const struct tty_operations ptm_unix98_ops = {
index f2dfec82faf85d19f78d3ea4d755ae730b336911..7f50999eebc22f00fb482d2fda62d62f11262be5 100644 (file)
@@ -1819,6 +1819,8 @@ static void serial8250_backup_timeout(unsigned long data)
        unsigned int iir, ier = 0, lsr;
        unsigned long flags;
 
+       spin_lock_irqsave(&up->port.lock, flags);
+
        /*
         * Must disable interrupts or else we risk racing with the interrupt
         * based handler.
@@ -1836,10 +1838,8 @@ static void serial8250_backup_timeout(unsigned long data)
         * the "Diva" UART used on the management processor on many HP
         * ia64 and parisc boxes.
         */
-       spin_lock_irqsave(&up->port.lock, flags);
        lsr = serial_in(up, UART_LSR);
        up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-       spin_unlock_irqrestore(&up->port.lock, flags);
        if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
            (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
            (lsr & UART_LSR_THRE)) {
@@ -1848,11 +1848,13 @@ static void serial8250_backup_timeout(unsigned long data)
        }
 
        if (!(iir & UART_IIR_NO_INT))
-               serial8250_handle_port(up);
+               transmit_chars(up);
 
        if (is_real_interrupt(up->port.irq))
                serial_out(up, UART_IER, ier);
 
+       spin_unlock_irqrestore(&up->port.lock, flags);
+
        /* Standard timer interval plus 0.2s to keep the port running */
        mod_timer(&up->timer,
                jiffies + uart_poll_timeout(&up->port) + HZ / 5);
index 6b887d90a20554683975d921c7ca492bba3ccf68..3abeca2a2a1bb08a85c8e5d76fe37afc22da5f4e 100644 (file)
@@ -1599,11 +1599,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .device         = 0x800D,
                .init           = pci_eg20t_init,
        },
-       {
-               .vendor         = 0x10DB,
-               .device         = 0x800D,
-               .init           = pci_eg20t_init,
-       },
        /*
         * Cronyx Omega PCI (PLX-chip based)
         */
@@ -4021,13 +4016,17 @@ static struct pci_device_id serial_pci_tbl[] = {
                0, 0, pbn_NETMOS9900_2s_115200 },
 
        /*
-        * Best Connectivity PCI Multi I/O cards
+        * Best Connectivity and Rosewill PCI Multi I/O cards
         */
 
        {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
                0xA000, 0x1000,
                0, 0, pbn_b0_1_115200 },
 
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
+               0xA000, 0x3002,
+               0, 0, pbn_b0_bt_2_115200 },
+
        {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
                0xA000, 0x3004,
                0, 0, pbn_b0_bt_4_115200 },
index fc301f6722e1bf4d2e9788f01e702cee6e711ddd..a2f236510ff1cd3f7fc92524f6096dc8678946f0 100644 (file)
@@ -109,6 +109,9 @@ static const struct pnp_device_id pnp_dev_table[] = {
        /* IBM */
        /* IBM Thinkpad 701 Internal Modem Voice */
        {       "IBM0033",              0       },
+       /* Intermec */
+       /* Intermec CV60 touchscreen port */
+       {       "PNP4972",              0       },
        /* Intertex */
        /* Intertex 28k8 33k6 Voice EXT PnP */
        {       "IXDC801",              0       },
index af9b7814965a461921d337047c068aed9bb5d051..caba6730a9434b33054260d3aee794cf788a5b6c 100644 (file)
@@ -46,7 +46,7 @@
 
 #ifdef CONFIG_ARM
 #include <mach/cpu.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #endif
 
 #define PDC_BUFFER_SIZE                512
@@ -1609,9 +1609,11 @@ static struct console atmel_console = {
 static int __init atmel_console_init(void)
 {
        if (atmel_default_console_device) {
-               add_preferred_console(ATMEL_DEVICENAME,
-                                     atmel_default_console_device->id, NULL);
-               atmel_init_port(&atmel_ports[atmel_default_console_device->id],
+               struct atmel_uart_data *pdata =
+                       atmel_default_console_device->dev.platform_data;
+
+               add_preferred_console(ATMEL_DEVICENAME, pdata->num, NULL);
+               atmel_init_port(&atmel_ports[pdata->num],
                                atmel_default_console_device);
                register_console(&atmel_console);
        }
index a1fe304f2f5204adf43c2a26171886198719ac91..d73aadd7a9ad6614385b62f92582c5c7b87c7b61 100644 (file)
@@ -340,5 +340,5 @@ module_exit(max3107_exit);
 
 MODULE_DESCRIPTION("MAX3107 driver");
 MODULE_AUTHOR("Aavamobile");
-MODULE_ALIAS("aava-max3107-spi");
+MODULE_ALIAS("spi:aava-max3107");
 MODULE_LICENSE("GPL v2");
index 750b4f627315e465e7c9eed0f7d9fd172f869c13..a8164601c0ead50c841f4a3a662f90df315e18ca 100644 (file)
@@ -1209,5 +1209,5 @@ module_exit(max3107_exit);
 
 MODULE_DESCRIPTION("MAX3107 driver");
 MODULE_AUTHOR("Aavamobile");
-MODULE_ALIAS("max3107-spi");
+MODULE_ALIAS("spi:max3107");
 MODULE_LICENSE("GPL v2");
index a764bf99743b0b5c6be4d46fed2952cbca278d94..23bc743f2a22f864674750fb2ea4d4f442ca174f 100644 (file)
@@ -917,4 +917,4 @@ module_init(serial_m3110_init);
 module_exit(serial_m3110_exit);
 
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("max3110-uart");
+MODULE_ALIAS("spi:max3110-uart");
index c37df8d0fa2819261dffccc5bc4d0180b9531f49..5e713d3ef1f47c49eaa93f8d4ced09ce87b89c1e 100644 (file)
@@ -806,8 +806,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 
        serial_omap_set_mctrl(&up->port, up->port.mctrl);
        /* Software Flow Control Configuration */
-       if (termios->c_iflag & (IXON | IXOFF))
-               serial_omap_configure_xonxoff(up, termios);
+       serial_omap_configure_xonxoff(up, termios);
 
        spin_unlock_irqrestore(&up->port.lock, flags);
        dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id);
index 846dfcd3ce0d28a6ee882278a90779c3c6427e21..b46218d679e21e4561657b8cf5508e7138d5e03e 100644 (file)
@@ -598,7 +598,8 @@ static void pch_request_dma(struct uart_port *port)
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(0xa, 0)); /* Get DMA's dev
+       dma_dev = pci_get_bus_and_slot(priv->pdev->bus->number,
+                                      PCI_DEVFN(0xa, 0)); /* Get DMA's dev
                                                                information */
        /* Set Tx DMA */
        param = &priv->param_tx;
index afc629423152bfa606b27bb11094713dd7936988..6edafb5ace183bfb0c30eff6f00f7f673ea022c9 100644 (file)
@@ -1225,15 +1225,19 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
        .suspend = s3c24xx_serial_suspend,
        .resume = s3c24xx_serial_resume,
 };
+#define SERIAL_SAMSUNG_PM_OPS  (&s3c24xx_serial_pm_ops)
+
 #else /* !CONFIG_PM_SLEEP */
-#define s3c24xx_serial_pm_ops  NULL
+
+#define SERIAL_SAMSUNG_PM_OPS  NULL
 #endif /* CONFIG_PM_SLEEP */
 
 int s3c24xx_serial_init(struct platform_driver *drv,
                        struct s3c24xx_uart_info *info)
 {
        dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
-       drv->driver.pm = &s3c24xx_serial_pm_ops;
+
+       drv->driver.pm = SERIAL_SAMSUNG_PM_OPS;
 
        return platform_driver_register(drv);
 }
index db7912cb7ae041a71a901437d3c835ee242530a9..a3efbea5dbba6b88f0068470c4e0ad019fa3cd5d 100644 (file)
@@ -200,6 +200,11 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in
                clear_bit(TTY_IO_ERROR, &tty->flags);
        }
 
+       /*
+        * This is to allow setserial on this port. People may want to set
+        * port/irq/type and then reconfigure the port properly if it failed
+        * now.
+        */
        if (retval && capable(CAP_SYS_ADMIN))
                retval = 0;
 
index 2ec57b2fb2783a232df5aad9df1a276a6f2edd1e..18e6342af07379e71f966c67656cca803925f76c 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 
@@ -95,6 +96,12 @@ struct sci_port {
 #endif
 
        struct notifier_block           freq_transition;
+
+#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
+       unsigned short saved_smr;
+       unsigned short saved_fcr;
+       unsigned char saved_brr;
+#endif
 };
 
 /* Function prototypes */
@@ -1633,11 +1640,25 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
        return ((freq + 16 * bps) / (32 * bps) - 1);
 }
 
+static void sci_reset(struct uart_port *port)
+{
+       unsigned int status;
+
+       do {
+               status = sci_in(port, SCxSR);
+       } while (!(status & SCxSR_TEND(port)));
+
+       sci_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
+
+       if (port->type != PORT_SCI)
+               sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+}
+
 static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
                            struct ktermios *old)
 {
        struct sci_port *s = to_sci_port(port);
-       unsigned int status, baud, smr_val, max_baud;
+       unsigned int baud, smr_val, max_baud;
        int t = -1;
        u16 scfcr = 0;
 
@@ -1657,14 +1678,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
        sci_port_enable(s);
 
-       do {
-               status = sci_in(port, SCxSR);
-       } while (!(status & SCxSR_TEND(port)));
-
-       sci_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
-
-       if (port->type != PORT_SCI)
-               sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST);
+       sci_reset(port);
 
        smr_val = sci_in(port, SCSMR) & 3;
 
@@ -2036,7 +2050,8 @@ static int __devinit serial_console_setup(struct console *co, char *options)
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
 
-       /* TODO: disable clock */
+       sci_port_disable(sci_port);
+
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
@@ -2079,6 +2094,36 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
        return 0;
 }
 
+#define uart_console(port)     ((port)->cons->index == (port)->line)
+
+static int sci_runtime_suspend(struct device *dev)
+{
+       struct sci_port *sci_port = dev_get_drvdata(dev);
+       struct uart_port *port = &sci_port->port;
+
+       if (uart_console(port)) {
+               sci_port->saved_smr = sci_in(port, SCSMR);
+               sci_port->saved_brr = sci_in(port, SCBRR);
+               sci_port->saved_fcr = sci_in(port, SCFCR);
+       }
+       return 0;
+}
+
+static int sci_runtime_resume(struct device *dev)
+{
+       struct sci_port *sci_port = dev_get_drvdata(dev);
+       struct uart_port *port = &sci_port->port;
+
+       if (uart_console(port)) {
+               sci_reset(port);
+               sci_out(port, SCSMR, sci_port->saved_smr);
+               sci_out(port, SCBRR, sci_port->saved_brr);
+               sci_out(port, SCFCR, sci_port->saved_fcr);
+               sci_out(port, SCSCR, sci_port->cfg->scscr);
+       }
+       return 0;
+}
+
 #define SCI_CONSOLE    (&serial_console)
 
 #else
@@ -2088,6 +2133,8 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
 }
 
 #define SCI_CONSOLE    NULL
+#define sci_runtime_suspend    NULL
+#define sci_runtime_resume     NULL
 
 #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
 
@@ -2203,6 +2250,8 @@ static int sci_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops sci_dev_pm_ops = {
+       .runtime_suspend = sci_runtime_suspend,
+       .runtime_resume = sci_runtime_resume,
        .suspend        = sci_suspend,
        .resume         = sci_resume,
 };
index c327218cad44c91ab680cf0dc46fcd4933cc8347..9af9f0879a24542860ab8f934d025acf705174ca 100644 (file)
@@ -235,7 +235,7 @@ static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port)
                return qe_port->bd_virt + (addr - qe_port->bd_dma_addr);
 
        /* something nasty happened */
-       printk(KERN_ERR "%s: addr=%x\n", __func__, addr);
+       printk(KERN_ERR "%s: addr=%llx\n", __func__, (u64)addr);
        BUG();
        return NULL;
 }
index 150e4f747c7dc4bc822a706a76d06afefb80424d..4f1fc81112e6b5ae6521e39cf19295e1f3a0c6b5 100644 (file)
@@ -1295,8 +1295,7 @@ static int tty_driver_install_tty(struct tty_driver *driver,
  *
  *     Locking: tty_mutex for now
  */
-static void tty_driver_remove_tty(struct tty_driver *driver,
-                                               struct tty_struct *tty)
+void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty)
 {
        if (driver->ops->remove)
                driver->ops->remove(driver, tty);
index d2efe823c20dd7fc317a1ffc0e12c283138e531d..c89f12a8b1166b576a5fecb8c823894a1942cd47 100644 (file)
@@ -750,14 +750,13 @@ static int uio_major_init(void)
 
        uio_major = MAJOR(uio_dev);
        uio_cdev = cdev;
-       result = 0;
-out:
-       return result;
+       return 0;
 out_put:
        kobject_put(&cdev->kobj);
 out_unregister:
        unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
-       goto out;
+out:
+       return result;
 }
 
 static void uio_major_cleanup(void)
index fc22e1e6f215cf9148b0ccc7b7a20b3333a24fe9..02bd47bdee1c504727d29903ccb8d19bf6867829 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/uio_driver.h>
-#include <linux/spinlock.h>
 
 #define DRIVER_VERSION "0.01.0"
 #define DRIVER_AUTHOR  "Michael S. Tsirkin <mst@redhat.com>"
@@ -33,7 +32,6 @@
 struct uio_pci_generic_dev {
        struct uio_info info;
        struct pci_dev *pdev;
-       spinlock_t lock; /* guards command register accesses */
 };
 
 static inline struct uio_pci_generic_dev *
@@ -57,7 +55,6 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
        BUILD_BUG_ON(PCI_COMMAND % 4);
        BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
 
-       spin_lock_irq(&gdev->lock);
        pci_block_user_cfg_access(pdev);
 
        /* Read both command and status registers in a single 32-bit operation.
@@ -83,7 +80,6 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info)
 done:
 
        pci_unblock_user_cfg_access(pdev);
-       spin_unlock_irq(&gdev->lock);
        return ret;
 }
 
@@ -158,7 +154,6 @@ static int __devinit probe(struct pci_dev *pdev,
        gdev->info.irq_flags = IRQF_SHARED;
        gdev->info.handler = irqhandler;
        gdev->pdev = pdev;
-       spin_lock_init(&gdev->lock);
 
        if (uio_register_device(&pdev->dev, &gdev->info))
                goto err_register;
index bae96d246760c2298f96be53e9449313c8747612..0b2ed71e3bfa22c31de8eb9a03743d53808b989f 100644 (file)
@@ -253,7 +253,7 @@ static const struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
 };
 
 #ifdef CONFIG_OF
-static const struct of_device_id __devinitconst uio_of_genirq_match[] = {
+static const struct of_device_id uio_of_genirq_match[] = {
        { /* empty for now */ },
 };
 MODULE_DEVICE_TABLE(of, uio_of_genirq_match);
index dac7676ce21bb6d9121d8fa4d178ea5cc0708438..94e6c5c09dd8c80cd842db2e2fbf952bd029c634 100644 (file)
@@ -1305,7 +1305,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
        struct acm *acm = usb_get_intfdata(intf);
        int cnt;
 
-       if (message.event & PM_EVENT_AUTO) {
+       if (PMSG_IS_AUTO(message)) {
                int b;
 
                spin_lock_irq(&acm->write_lock);
index 2b9ff518b509c3ca45fa7e064aa5be56fbae36ae..42f180aca3fbe1dd7a7761174bd8db3caed7f724 100644 (file)
@@ -798,11 +798,11 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
        dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
 
        /* if this is an autosuspend the caller does the locking */
-       if (!(message.event & PM_EVENT_AUTO))
+       if (!PMSG_IS_AUTO(message))
                mutex_lock(&desc->lock);
        spin_lock_irq(&desc->iuspin);
 
-       if ((message.event & PM_EVENT_AUTO) &&
+       if (PMSG_IS_AUTO(message) &&
                        (test_bit(WDM_IN_USE, &desc->flags)
                        || test_bit(WDM_RESPONDING, &desc->flags))) {
                spin_unlock_irq(&desc->iuspin);
@@ -815,7 +815,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
                kill_urbs(desc);
                cancel_work_sync(&desc->rxwork);
        }
-       if (!(message.event & PM_EVENT_AUTO))
+       if (!PMSG_IS_AUTO(message))
                mutex_unlock(&desc->lock);
 
        return rv;
index 34e3da5aa72a2463863b04e3b3befb4aba02505d..e03042883c68c7476d823f317993814699f1e35c 100644 (file)
@@ -1046,8 +1046,7 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg)
        /* Non-root devices on a full/low-speed bus must wait for their
         * companion high-speed root hub, in case a handoff is needed.
         */
-       if (!(msg.event & PM_EVENT_AUTO) && udev->parent &&
-                       udev->bus->hs_companion)
+       if (!PMSG_IS_AUTO(msg) && udev->parent && udev->bus->hs_companion)
                device_pm_wait_for_dev(&udev->dev,
                                &udev->bus->hs_companion->root_hub->dev);
 
@@ -1075,7 +1074,7 @@ static int usb_suspend_interface(struct usb_device *udev,
 
        if (driver->suspend) {
                status = driver->suspend(intf, msg);
-               if (status && !(msg.event & PM_EVENT_AUTO))
+               if (status && !PMSG_IS_AUTO(msg))
                        dev_err(&intf->dev, "%s error %d\n",
                                        "suspend", status);
        } else {
@@ -1189,7 +1188,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                        status = usb_suspend_interface(udev, intf, msg);
 
                        /* Ignore errors during system sleep transitions */
-                       if (!(msg.event & PM_EVENT_AUTO))
+                       if (!PMSG_IS_AUTO(msg))
                                status = 0;
                        if (status != 0)
                                break;
@@ -1199,7 +1198,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
                status = usb_suspend_device(udev, msg);
 
                /* Again, ignore errors during system sleep transitions */
-               if (!(msg.event & PM_EVENT_AUTO))
+               if (!PMSG_IS_AUTO(msg))
                        status = 0;
        }
 
index 8669ba3fe79486ffe487e6b6b266ff4767afe670..c1dabf0798b1569ae2697543bb03c407967603eb 100644 (file)
@@ -1775,6 +1775,8 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
                struct usb_interface *iface = usb_ifnum_to_if(udev,
                                cur_alt->desc.bInterfaceNumber);
 
+               if (!iface)
+                       return -EINVAL;
                if (iface->resetting_device) {
                        /*
                         * The USB core just reset the device, so the xHCI host
@@ -1960,7 +1962,7 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
        int             old_state = hcd->state;
 
        dev_dbg(&rhdev->dev, "bus %s%s\n",
-                       (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend");
+                       (PMSG_IS_AUTO(msg) ? "auto-" : ""), "suspend");
        if (HCD_DEAD(hcd)) {
                dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend");
                return 0;
@@ -1996,7 +1998,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
        int             old_state = hcd->state;
 
        dev_dbg(&rhdev->dev, "usb %s%s\n",
-                       (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume");
+                       (PMSG_IS_AUTO(msg) ? "auto-" : ""), "resume");
        if (HCD_DEAD(hcd)) {
                dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume");
                return 0;
index 99fff6be36419edf1d54914c33c1aea1529c05b4..b7eb94c3ae69db3782530a64a816bafe076e2919 100644 (file)
@@ -2337,7 +2337,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
                        dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
                                        status);
                        /* bail if autosuspend is requested */
-                       if (msg.event & PM_EVENT_AUTO)
+                       if (PMSG_IS_AUTO(msg))
                                return status;
                }
        }
@@ -2362,12 +2362,12 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
                                USB_CTRL_SET_TIMEOUT);
 
                /* System sleep transitions should never fail */
-               if (!(msg.event & PM_EVENT_AUTO))
+               if (!PMSG_IS_AUTO(msg))
                        status = 0;
        } else {
                /* device has up to 10 msec to fully suspend */
                dev_dbg(&udev->dev, "usb %ssuspend\n",
-                               (msg.event & PM_EVENT_AUTO ? "auto-" : ""));
+                               (PMSG_IS_AUTO(msg) ? "auto-" : ""));
                usb_set_device_state(udev, USB_STATE_SUSPENDED);
                msleep(10);
        }
@@ -2518,7 +2518,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
        } else {
                /* drive resume for at least 20 msec */
                dev_dbg(&udev->dev, "usb %sresume\n",
-                               (msg.event & PM_EVENT_AUTO ? "auto-" : ""));
+                               (PMSG_IS_AUTO(msg) ? "auto-" : ""));
                msleep(25);
 
                /* Virtual root hubs can trigger on GET_PORT_STATUS to
@@ -2620,7 +2620,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
                udev = hdev->children [port1-1];
                if (udev && udev->can_submit) {
                        dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
-                       if (msg.event & PM_EVENT_AUTO)
+                       if (PMSG_IS_AUTO(msg))
                                return -EBUSY;
                }
        }
index 257859564f914c0c1a5d1d17a6d688dce6fcbede..e3b77d2dc03487a0bbb2c51ee2beb54d9cefd2de 100644 (file)
@@ -38,6 +38,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
index 8f8d3f6cd89edf22fb9d96a67f89bc3fb56b0d5f..8f3eab1af885847fa69ec343b0039a0df4faae39 100644 (file)
@@ -434,6 +434,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
                            config_ep_by_speed(gadget, f, fp->out_ep)) {
                                fp->in_ep->desc = NULL;
                                fp->out_ep->desc = NULL;
+                               spin_unlock(&port->lock);
                                return -EINVAL;
                        }
                        usb_ep_enable(fp->out_ep);
index c6104c4f1f38b0a1b6e297b134b4784429703e3b..77bbb2357e478a5e021118076bbe2a7f84811af4 100644 (file)
@@ -341,7 +341,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        u32                     temp;
        u32                     power_okay;
        int                     i;
-       u8                      resume_needed = 0;
+       unsigned long           resume_needed = 0;
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
@@ -415,7 +415,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
                if (test_bit(i, &ehci->bus_suspended) &&
                                (temp & PORT_SUSPEND)) {
                        temp |= PORT_RESUME;
-                       resume_needed = 1;
+                       set_bit(i, &resume_needed);
                }
                ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
        }
@@ -430,8 +430,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        i = HCS_N_PORTS (ehci->hcs_params);
        while (i--) {
                temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
-               if (test_bit(i, &ehci->bus_suspended) &&
-                               (temp & PORT_SUSPEND)) {
+               if (test_bit(i, &resume_needed)) {
                        temp &= ~(PORT_RWC_BITS | PORT_RESUME);
                        ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
                        ehci_vdbg (ehci, "resumed port %d\n", i + 1);
index 318e0c6d0ab1e3594fcdc7d32063c3e51d33a7b0..64bcf66d304027ce387aca459d8a1fbc799eb9d5 100644 (file)
@@ -86,6 +86,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)
                goto fail_hcd;
        }
 
+       s5p_ehci->hcd = hcd;
        s5p_ehci->clk = clk_get(&pdev->dev, "usbhost");
 
        if (IS_ERR(s5p_ehci->clk)) {
index 653d6a60edb54e9e748b9e11e18a22192c8e3900..d1b41933199ec0aeaecd19cc67fd26083efbfdc6 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <mach/platform.h>
 #include <mach/irqs.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #define USB_CTRL       IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
 
index 0be788cc2fdbe6e40920e5f77efa7590475bffa8..1e96d1f1fe6befacfc2a37bb84e1f48b734b2724 100644 (file)
@@ -463,11 +463,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                        && (temp & PORT_POWER))
                                status |= USB_PORT_STAT_SUSPEND;
                }
-               if ((temp & PORT_PLS_MASK) == XDEV_RESUME) {
+               if ((temp & PORT_PLS_MASK) == XDEV_RESUME &&
+                               !DEV_SUPERSPEED(temp)) {
                        if ((temp & PORT_RESET) || !(temp & PORT_PE))
                                goto error;
-                       if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies,
-                                               bus_state->resume_done[wIndex])) {
+                       if (time_after_eq(jiffies,
+                                       bus_state->resume_done[wIndex])) {
                                xhci_dbg(xhci, "Resume USB2 port %d\n",
                                        wIndex + 1);
                                bus_state->resume_done[wIndex] = 0;
@@ -487,6 +488,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                xhci_ring_device(xhci, slot_id);
                                bus_state->port_c_suspend |= 1 << wIndex;
                                bus_state->suspended_ports &= ~(1 << wIndex);
+                       } else {
+                               /*
+                                * The resume has been signaling for less than
+                                * 20ms. Report the port status as SUSPEND,
+                                * let the usbcore check port status again
+                                * and clear resume signaling later.
+                                */
+                               status |= USB_PORT_STAT_SUSPEND;
                        }
                }
                if ((temp & PORT_PLS_MASK) == XDEV_U0
@@ -664,7 +673,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        xhci_dbg(xhci, "PORTSC %04x\n", temp);
                        if (temp & PORT_RESET)
                                goto error;
-                       if (temp & XDEV_U3) {
+                       if ((temp & PORT_PLS_MASK) == XDEV_U3) {
                                if ((temp & PORT_PE) == 0)
                                        goto error;
 
index 7113d16e2d3a40f1febae01cedd8bf2dd2308980..54139a2f06ce9700933f96255fc0a680c07b9a80 100644 (file)
@@ -514,8 +514,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
                        (unsigned long long) addr);
 }
 
+/* flip_cycle means flip the cycle bit of all but the first and last TRB.
+ * (The last TRB actually points to the ring enqueue pointer, which is not part
+ * of this TD.)  This is used to remove partially enqueued isoc TDs from a ring.
+ */
 static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
-               struct xhci_td *cur_td)
+               struct xhci_td *cur_td, bool flip_cycle)
 {
        struct xhci_segment *cur_seg;
        union xhci_trb *cur_trb;
@@ -528,6 +532,12 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
                         * leave the pointers intact.
                         */
                        cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN);
+                       /* Flip the cycle bit (link TRBs can't be the first
+                        * or last TRB).
+                        */
+                       if (flip_cycle)
+                               cur_trb->generic.field[3] ^=
+                                       cpu_to_le32(TRB_CYCLE);
                        xhci_dbg(xhci, "Cancel (unchain) link TRB\n");
                        xhci_dbg(xhci, "Address = %p (0x%llx dma); "
                                        "in seg %p (0x%llx dma)\n",
@@ -541,6 +551,11 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
                        cur_trb->generic.field[2] = 0;
                        /* Preserve only the cycle bit of this TRB */
                        cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE);
+                       /* Flip the cycle bit except on the first or last TRB */
+                       if (flip_cycle && cur_trb != cur_td->first_trb &&
+                                       cur_trb != cur_td->last_trb)
+                               cur_trb->generic.field[3] ^=
+                                       cpu_to_le32(TRB_CYCLE);
                        cur_trb->generic.field[3] |= cpu_to_le32(
                                TRB_TYPE(TRB_TR_NOOP));
                        xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) "
@@ -719,14 +734,14 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
                                        cur_td->urb->stream_id,
                                        cur_td, &deq_state);
                else
-                       td_to_noop(xhci, ep_ring, cur_td);
+                       td_to_noop(xhci, ep_ring, cur_td, false);
 remove_finished_td:
                /*
                 * The event handler won't see a completion for this TD anymore,
                 * so remove it from the endpoint ring's TD list.  Keep it in
                 * the cancelled TD list for URB completion later.
                 */
-               list_del(&cur_td->td_list);
+               list_del_init(&cur_td->td_list);
        }
        last_unlinked_td = cur_td;
        xhci_stop_watchdog_timer_in_irq(xhci, ep);
@@ -754,7 +769,7 @@ remove_finished_td:
        do {
                cur_td = list_entry(ep->cancelled_td_list.next,
                                struct xhci_td, cancelled_td_list);
-               list_del(&cur_td->cancelled_td_list);
+               list_del_init(&cur_td->cancelled_td_list);
 
                /* Clean up the cancelled URB */
                /* Doesn't matter what we pass for status, since the core will
@@ -862,9 +877,9 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
                                cur_td = list_first_entry(&ring->td_list,
                                                struct xhci_td,
                                                td_list);
-                               list_del(&cur_td->td_list);
+                               list_del_init(&cur_td->td_list);
                                if (!list_empty(&cur_td->cancelled_td_list))
-                                       list_del(&cur_td->cancelled_td_list);
+                                       list_del_init(&cur_td->cancelled_td_list);
                                xhci_giveback_urb_in_irq(xhci, cur_td,
                                                -ESHUTDOWN, "killed");
                        }
@@ -873,7 +888,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
                                                &temp_ep->cancelled_td_list,
                                                struct xhci_td,
                                                cancelled_td_list);
-                               list_del(&cur_td->cancelled_td_list);
+                               list_del_init(&cur_td->cancelled_td_list);
                                xhci_giveback_urb_in_irq(xhci, cur_td,
                                                -ESHUTDOWN, "killed");
                        }
@@ -1565,10 +1580,10 @@ td_cleanup:
                        else
                                *status = 0;
                }
-               list_del(&td->td_list);
+               list_del_init(&td->td_list);
                /* Was this TD slated to be cancelled but completed anyway? */
                if (!list_empty(&td->cancelled_td_list))
-                       list_del(&td->cancelled_td_list);
+                       list_del_init(&td->cancelled_td_list);
 
                urb_priv->td_cnt++;
                /* Giveback the urb when all the tds are completed */
@@ -2500,11 +2515,8 @@ static int prepare_transfer(struct xhci_hcd *xhci,
 
        if (td_index == 0) {
                ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb);
-               if (unlikely(ret)) {
-                       xhci_urb_free_priv(xhci, urb_priv);
-                       urb->hcpriv = NULL;
+               if (unlikely(ret))
                        return ret;
-               }
        }
 
        td->urb = urb;
@@ -2672,6 +2684,10 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
 {
        int packets_transferred;
 
+       /* One TRB with a zero-length data packet. */
+       if (running_total == 0 && trb_buff_len == 0)
+               return 0;
+
        /* All the TRB queueing functions don't count the current TRB in
         * running_total.
         */
@@ -3113,20 +3129,15 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci,
                struct urb *urb, int i)
 {
        int num_trbs = 0;
-       u64 addr, td_len, running_total;
+       u64 addr, td_len;
 
        addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
        td_len = urb->iso_frame_desc[i].length;
 
-       running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1));
-       running_total &= TRB_MAX_BUFF_SIZE - 1;
-       if (running_total != 0)
-               num_trbs++;
-
-       while (running_total < td_len) {
+       num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
+                       TRB_MAX_BUFF_SIZE);
+       if (num_trbs == 0)
                num_trbs++;
-               running_total += TRB_MAX_BUFF_SIZE;
-       }
 
        return num_trbs;
 }
@@ -3226,6 +3237,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        start_trb = &ep_ring->enqueue->generic;
        start_cycle = ep_ring->cycle_state;
 
+       urb_priv = urb->hcpriv;
        /* Queue the first TRB, even if it's zero-length */
        for (i = 0; i < num_tds; i++) {
                unsigned int total_packet_count;
@@ -3237,9 +3249,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                addr = start_addr + urb->iso_frame_desc[i].offset;
                td_len = urb->iso_frame_desc[i].length;
                td_remain_len = td_len;
-               /* FIXME: Ignoring zero-length packets, can those happen? */
                total_packet_count = roundup(td_len,
                                le16_to_cpu(urb->ep->desc.wMaxPacketSize));
+               /* A zero-length transfer still involves at least one packet. */
+               if (total_packet_count == 0)
+                       total_packet_count++;
                burst_count = xhci_get_burst_count(xhci, urb->dev, urb,
                                total_packet_count);
                residue = xhci_get_last_burst_packet_count(xhci,
@@ -3249,12 +3263,13 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
                ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index,
                                urb->stream_id, trbs_per_td, urb, i, mem_flags);
-               if (ret < 0)
-                       return ret;
+               if (ret < 0) {
+                       if (i == 0)
+                               return ret;
+                       goto cleanup;
+               }
 
-               urb_priv = urb->hcpriv;
                td = urb_priv->td[i];
-
                for (j = 0; j < trbs_per_td; j++) {
                        u32 remainder = 0;
                        field = TRB_TBC(burst_count) | TRB_TLBPC(residue);
@@ -3344,6 +3359,27 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
                        start_cycle, start_trb);
        return 0;
+cleanup:
+       /* Clean up a partially enqueued isoc transfer. */
+
+       for (i--; i >= 0; i--)
+               list_del_init(&urb_priv->td[i]->td_list);
+
+       /* Use the first TD as a temporary variable to turn the TDs we've queued
+        * into No-ops with a software-owned cycle bit. That way the hardware
+        * won't accidentally start executing bogus TDs when we partially
+        * overwrite them.  td->first_trb and td->start_seg are already set.
+        */
+       urb_priv->td[0]->last_trb = ep_ring->enqueue;
+       /* Every TRB except the first & last will have its cycle bit flipped. */
+       td_to_noop(xhci, ep_ring, urb_priv->td[0], true);
+
+       /* Reset the ring enqueue back to the first TRB and its cycle bit. */
+       ep_ring->enqueue = urb_priv->td[0]->first_trb;
+       ep_ring->enq_seg = urb_priv->td[0]->start_seg;
+       ep_ring->cycle_state = start_cycle;
+       usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
+       return ret;
 }
 
 /*
index 1c4432d8fc1048f2e3bb838b63a0be84201f2a82..3a0f695138f4195d4caf988c2fb0266ca7678e5f 100644 (file)
@@ -1085,8 +1085,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
                if (urb->dev->speed == USB_SPEED_FULL) {
                        ret = xhci_check_maxpacket(xhci, slot_id,
                                        ep_index, urb);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               xhci_urb_free_priv(xhci, urb_priv);
+                               urb->hcpriv = NULL;
                                return ret;
+                       }
                }
 
                /* We have a spinlock and interrupts disabled, so we must pass
@@ -1097,6 +1100,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
                        goto dying;
                ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
                                slot_id, ep_index);
+               if (ret)
+                       goto free_priv;
                spin_unlock_irqrestore(&xhci->lock, flags);
        } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
                spin_lock_irqsave(&xhci->lock, flags);
@@ -1117,6 +1122,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
                        ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
                                        slot_id, ep_index);
                }
+               if (ret)
+                       goto free_priv;
                spin_unlock_irqrestore(&xhci->lock, flags);
        } else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
                spin_lock_irqsave(&xhci->lock, flags);
@@ -1124,6 +1131,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
                        goto dying;
                ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
                                slot_id, ep_index);
+               if (ret)
+                       goto free_priv;
                spin_unlock_irqrestore(&xhci->lock, flags);
        } else {
                spin_lock_irqsave(&xhci->lock, flags);
@@ -1131,18 +1140,22 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
                        goto dying;
                ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb,
                                slot_id, ep_index);
+               if (ret)
+                       goto free_priv;
                spin_unlock_irqrestore(&xhci->lock, flags);
        }
 exit:
        return ret;
 dying:
-       xhci_urb_free_priv(xhci, urb_priv);
-       urb->hcpriv = NULL;
        xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
                        "non-responsive xHCI host.\n",
                        urb->ep->desc.bEndpointAddress, urb);
+       ret = -ESHUTDOWN;
+free_priv:
+       xhci_urb_free_priv(xhci, urb_priv);
+       urb->hcpriv = NULL;
        spin_unlock_irqrestore(&xhci->lock, flags);
-       return -ESHUTDOWN;
+       return ret;
 }
 
 /* Get the right ring for the given URB.
@@ -1239,6 +1252,13 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
                xhci_dbg(xhci, "HW died, freeing TD.\n");
                urb_priv = urb->hcpriv;
+               for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
+                       td = urb_priv->td[i];
+                       if (!list_empty(&td->td_list))
+                               list_del_init(&td->td_list);
+                       if (!list_empty(&td->cancelled_td_list))
+                               list_del_init(&td->cancelled_td_list);
+               }
 
                usb_hcd_unlink_urb_from_ep(hcd, urb);
                spin_unlock_irqrestore(&xhci->lock, flags);
index ae8c396177434a7cb6ea10e67893cee00a8ff5a3..5e7cfba5b079b02d781710c106cfbbe38f37a358 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/prefetch.h>
 
 #include <asm/cacheflush.h>
 
index 149f3f310a0a1f9903793ca5f56daaf1038a4024..318fb4e8a8850cb21789a4d9f9d89d23bd2fbd12 100644 (file)
@@ -226,8 +226,10 @@ static int cppi_controller_stop(struct dma_controller *c)
        struct cppi             *controller;
        void __iomem            *tibase;
        int                     i;
+       struct musb             *musb;
 
        controller = container_of(c, struct cppi, controller);
+       musb = controller->musb;
 
        tibase = controller->tibase;
        /* DISABLE INDIVIDUAL CHANNEL Interrupts */
@@ -289,9 +291,11 @@ cppi_channel_allocate(struct dma_controller *c,
        u8                      index;
        struct cppi_channel     *cppi_ch;
        void __iomem            *tibase;
+       struct musb             *musb;
 
        controller = container_of(c, struct cppi, controller);
        tibase = controller->tibase;
+       musb = controller->musb;
 
        /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */
        index = ep->epnum - 1;
@@ -339,7 +343,8 @@ static void cppi_channel_release(struct dma_channel *channel)
        c = container_of(channel, struct cppi_channel, channel);
        tibase = c->controller->tibase;
        if (!c->hw_ep)
-               dev_dbg(musb->controller, "releasing idle DMA channel %p\n", c);
+               dev_dbg(c->controller->musb->controller,
+                       "releasing idle DMA channel %p\n", c);
        else if (!c->transmit)
                core_rxirq_enable(tibase, c->index + 1);
 
@@ -357,10 +362,11 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag)
 
        musb_ep_select(base, c->index + 1);
 
-       DBG(level, "RX DMA%d%s: %d left, csr %04x, "
-                       "%08x H%08x S%08x C%08x, "
-                       "B%08x L%08x %08x .. %08x"
-                       "\n",
+       dev_dbg(c->controller->musb->controller,
+               "RX DMA%d%s: %d left, csr %04x, "
+               "%08x H%08x S%08x C%08x, "
+               "B%08x L%08x %08x .. %08x"
+               "\n",
                c->index, tag,
                musb_readl(c->controller->tibase,
                        DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index),
@@ -387,10 +393,11 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag)
 
        musb_ep_select(base, c->index + 1);
 
-       DBG(level, "TX DMA%d%s: csr %04x, "
-                       "H%08x S%08x C%08x %08x, "
-                       "F%08x L%08x .. %08x"
-                       "\n",
+       dev_dbg(c->controller->musb->controller,
+               "TX DMA%d%s: csr %04x, "
+               "H%08x S%08x C%08x %08x, "
+               "F%08x L%08x .. %08x"
+               "\n",
                c->index, tag,
                musb_readw(c->hw_ep->regs, MUSB_TXCSR),
 
@@ -1022,6 +1029,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
        int                             i;
        dma_addr_t                      safe2ack;
        void __iomem                    *regs = rx->hw_ep->regs;
+       struct musb                     *musb = cppi->musb;
 
        cppi_dump_rx(6, rx, "/K");
 
index 8bdf25a8b023645ec839361cdc18f86dc624c7bb..f9a3f62a83b51d82d9192a4d9325eb0318df689e 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <mach/hardware.h>
 #include <mach/memory.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <mach/cputype.h>
 
 #include <asm/mach-types.h>
index 668eeef601ae94f093fa925706afcbcc2b1f5e37..b3c065ab9dbc2f9aace5b36939390761fa0c5218 100644 (file)
@@ -172,7 +172,8 @@ enum musb_g_ep0_state {
 #endif
 
 /* TUSB mapping: "flat" plus ep0 special cases */
-#if    defined(CONFIG_USB_MUSB_TUSB6010)
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
 #define musb_ep_select(_mbase, _epnum) \
        musb_writeb((_mbase), MUSB_INDEX, (_epnum))
 #define        MUSB_EP_OFFSET                  MUSB_TUSB_OFFSET
@@ -241,7 +242,8 @@ struct musb_hw_ep {
        void __iomem            *fifo;
        void __iomem            *regs;
 
-#ifdef CONFIG_USB_MUSB_TUSB6010
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
        void __iomem            *conf;
 #endif
 
@@ -258,7 +260,8 @@ struct musb_hw_ep {
        struct dma_channel      *tx_channel;
        struct dma_channel      *rx_channel;
 
-#ifdef CONFIG_USB_MUSB_TUSB6010
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
        /* TUSB has "asynchronous" and "synchronous" dma modes */
        dma_addr_t              fifo_async;
        dma_addr_t              fifo_sync;
@@ -356,7 +359,8 @@ struct musb {
        void __iomem            *ctrl_base;
        void __iomem            *mregs;
 
-#ifdef CONFIG_USB_MUSB_TUSB6010
+#if defined(CONFIG_USB_MUSB_TUSB6010) || \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
        dma_addr_t              async;
        dma_addr_t              sync;
        void __iomem            *sync_va;
index 8c41a2e6ea7702e8906771d3bf5e7810ad412937..e81820370d6f9cab155d1fac9ef83d4c8653c723 100644 (file)
@@ -1856,6 +1856,7 @@ int __init musb_gadget_setup(struct musb *musb)
 
        return 0;
 err:
+       musb->g.dev.parent = NULL;
        device_unregister(&musb->g.dev);
        return status;
 }
@@ -1863,7 +1864,8 @@ err:
 void musb_gadget_cleanup(struct musb *musb)
 {
        usb_del_gadget_udc(&musb->g);
-       device_unregister(&musb->g.dev);
+       if (musb->g.dev.parent)
+               device_unregister(&musb->g.dev);
 }
 
 /*
index 82410703dcd3c1d87e688007c52cd737675d03d6..03f2655af290758cb708a67f832abd6257df2894 100644 (file)
 #define MUSB_TESTMODE          0x0F    /* 8 bit */
 
 /* Get offset for a given FIFO from musb->mregs */
-#ifdef CONFIG_USB_MUSB_TUSB6010
+#if defined(CONFIG_USB_MUSB_TUSB6010) ||       \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
 #define MUSB_FIFO_OFFSET(epnum)        (0x200 + ((epnum) * 0x20))
 #else
 #define MUSB_FIFO_OFFSET(epnum)        (0x20 + ((epnum) * 4))
 #define MUSB_FLAT_OFFSET(_epnum, _offset)      \
        (0x100 + (0x10*(_epnum)) + (_offset))
 
-#ifdef CONFIG_USB_MUSB_TUSB6010
+#if defined(CONFIG_USB_MUSB_TUSB6010) ||       \
+       defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
 /* TUSB6010 EP0 configuration register is special */
 #define MUSB_TUSB_OFFSET(_epnum, _offset)      \
        (0x10 + _offset)
index 9eec41fbf3a433e0ac250035a997df4440bef1ef..ec1480191f78752a1ff16b09566f3f4d2d6512b1 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/prefetch.h>
 #include <linux/usb.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
index 07c8a73dfe41c4d565f8f36b2134bdc373e7b5bb..b67b4bc596c18953b5c9abf997fb3f25605be1fe 100644 (file)
@@ -20,6 +20,7 @@
 #include <plat/mux.h>
 
 #include "musb_core.h"
+#include "tusb6010.h"
 
 #define to_chdat(c)            ((struct tusb_omap_dma_ch *)(c)->private_data)
 
index cecace4118327c8a148ab976d1c8dfb234e7bf57..ef4333f4bbe021178501d14ae4edbcd5562c9dbe 100644 (file)
@@ -65,7 +65,8 @@ static void ux500_tx_work(struct work_struct *data)
        struct musb *musb = hw_ep->musb;
        unsigned long flags;
 
-       DBG(4, "DMA tx transfer done on hw_ep=%d\n", hw_ep->epnum);
+       dev_dbg(musb->controller, "DMA tx transfer done on hw_ep=%d\n",
+               hw_ep->epnum);
 
        spin_lock_irqsave(&musb->lock, flags);
        ux500_channel->channel.actual_len = ux500_channel->cur_len;
@@ -84,7 +85,8 @@ static void ux500_rx_work(struct work_struct *data)
        struct musb *musb = hw_ep->musb;
        unsigned long flags;
 
-       DBG(4, "DMA rx transfer done on hw_ep=%d\n", hw_ep->epnum);
+       dev_dbg(musb->controller, "DMA rx transfer done on hw_ep=%d\n",
+               hw_ep->epnum);
 
        spin_lock_irqsave(&musb->lock, flags);
        ux500_channel->channel.actual_len = ux500_channel->cur_len;
@@ -116,9 +118,11 @@ static bool ux500_configure_channel(struct dma_channel *channel,
        enum dma_slave_buswidth addr_width;
        dma_addr_t usb_fifo_addr = (MUSB_FIFO_OFFSET(hw_ep->epnum) +
                                        ux500_channel->controller->phy_base);
+       struct musb *musb = ux500_channel->controller->private_data;
 
-       DBG(4, "packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n",
-                       packet_sz, mode, dma_addr, len, ux500_channel->is_tx);
+       dev_dbg(musb->controller,
+               "packet_sz=%d, mode=%d, dma_addr=0x%x, len=%d is_tx=%d\n",
+               packet_sz, mode, dma_addr, len, ux500_channel->is_tx);
 
        ux500_channel->cur_len = len;
 
@@ -133,15 +137,13 @@ static bool ux500_configure_channel(struct dma_channel *channel,
                                        DMA_SLAVE_BUSWIDTH_4_BYTES;
 
        slave_conf.direction = direction;
-       if (direction == DMA_FROM_DEVICE) {
-               slave_conf.src_addr = usb_fifo_addr;
-               slave_conf.src_addr_width = addr_width;
-               slave_conf.src_maxburst = 16;
-       } else {
-               slave_conf.dst_addr = usb_fifo_addr;
-               slave_conf.dst_addr_width = addr_width;
-               slave_conf.dst_maxburst = 16;
-       }
+       slave_conf.src_addr = usb_fifo_addr;
+       slave_conf.src_addr_width = addr_width;
+       slave_conf.src_maxburst = 16;
+       slave_conf.dst_addr = usb_fifo_addr;
+       slave_conf.dst_addr_width = addr_width;
+       slave_conf.dst_maxburst = 16;
+
        dma_chan->device->device_control(dma_chan, DMA_SLAVE_CONFIG,
                                             (unsigned long) &slave_conf);
 
@@ -166,6 +168,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
        struct ux500_dma_controller *controller = container_of(c,
                        struct ux500_dma_controller, controller);
        struct ux500_dma_channel *ux500_channel = NULL;
+       struct musb *musb = controller->private_data;
        u8 ch_num = hw_ep->epnum - 1;
        u32 max_ch;
 
@@ -192,7 +195,7 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
        ux500_channel->hw_ep = hw_ep;
        ux500_channel->is_allocated = 1;
 
-       DBG(7, "hw_ep=%d, is_tx=0x%x, channel=%d\n",
+       dev_dbg(musb->controller, "hw_ep=%d, is_tx=0x%x, channel=%d\n",
                hw_ep->epnum, is_tx, ch_num);
 
        return &(ux500_channel->channel);
@@ -201,8 +204,9 @@ static struct dma_channel *ux500_dma_channel_allocate(struct dma_controller *c,
 static void ux500_dma_channel_release(struct dma_channel *channel)
 {
        struct ux500_dma_channel *ux500_channel = channel->private_data;
+       struct musb *musb = ux500_channel->controller->private_data;
 
-       DBG(7, "channel=%d\n", ux500_channel->ch_num);
+       dev_dbg(musb->controller, "channel=%d\n", ux500_channel->ch_num);
 
        if (ux500_channel->is_allocated) {
                ux500_channel->is_allocated = 0;
@@ -252,8 +256,8 @@ static int ux500_dma_channel_abort(struct dma_channel *channel)
        void __iomem *epio = musb->endpoints[ux500_channel->hw_ep->epnum].regs;
        u16 csr;
 
-       DBG(4, "channel=%d, is_tx=%d\n", ux500_channel->ch_num,
-                                               ux500_channel->is_tx);
+       dev_dbg(musb->controller, "channel=%d, is_tx=%d\n",
+               ux500_channel->ch_num, ux500_channel->is_tx);
 
        if (channel->status == MUSB_DMA_STATUS_BUSY) {
                if (ux500_channel->is_tx) {
index 40abedbc5943a26359a60087fdb54cc948cd2e7f..3524a105d042f110a2ec6ce1aa90527c0e71b8ba 100644 (file)
@@ -2006,7 +2006,6 @@ static int mos7720_ioctl(struct tty_struct *tty,
                dbg("%s (%d) TIOCSERGETLSR", __func__,  port->number);
                return get_lsr_info(tty, mos7720_port,
                                        (unsigned int __user *)arg);
-               return 0;
 
        /* FIXME: These should be using the mode methods */
        case TIOCMBIS:
index 7b50aa12275277fb4e9da7e874551d1fbb3380e6..c72abd52498324e061bc2b3256aff77048bf70f1 100644 (file)
@@ -2263,7 +2263,6 @@ static int mos7840_ioctl(struct tty_struct *tty,
        case TIOCSERGETLSR:
                dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
                return mos7840_get_lsr_info(tty, argp);
-               return 0;
 
        case TIOCGSERIAL:
                dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
index 815656198914ddee0a4e5ca51fc5b2786ba5a94a..fe22e90bc879551a912ebcbcbf974a83c4ae0cb9 100644 (file)
@@ -148,6 +148,8 @@ static void option_instat_callback(struct urb *urb);
 #define HUAWEI_PRODUCT_K4505                   0x1464
 #define HUAWEI_PRODUCT_K3765                   0x1465
 #define HUAWEI_PRODUCT_E14AC                   0x14AC
+#define HUAWEI_PRODUCT_K3806                   0x14AE
+#define HUAWEI_PRODUCT_K4605                   0x14C6
 #define HUAWEI_PRODUCT_K3770                   0x14C9
 #define HUAWEI_PRODUCT_K3771                   0x14CA
 #define HUAWEI_PRODUCT_K4510                   0x14CB
@@ -416,6 +418,56 @@ static void option_instat_callback(struct urb *urb);
 #define SAMSUNG_VENDOR_ID                       0x04e8
 #define SAMSUNG_PRODUCT_GT_B3730                0x6889
 
+/* YUGA products  www.yuga-info.com*/
+#define YUGA_VENDOR_ID                         0x257A
+#define YUGA_PRODUCT_CEM600                    0x1601
+#define YUGA_PRODUCT_CEM610                    0x1602
+#define YUGA_PRODUCT_CEM500                    0x1603
+#define YUGA_PRODUCT_CEM510                    0x1604
+#define YUGA_PRODUCT_CEM800                    0x1605
+#define YUGA_PRODUCT_CEM900                    0x1606
+
+#define YUGA_PRODUCT_CEU818                    0x1607
+#define YUGA_PRODUCT_CEU816                    0x1608
+#define YUGA_PRODUCT_CEU828                    0x1609
+#define YUGA_PRODUCT_CEU826                    0x160A
+#define YUGA_PRODUCT_CEU518                    0x160B
+#define YUGA_PRODUCT_CEU516                    0x160C
+#define YUGA_PRODUCT_CEU528                    0x160D
+#define YUGA_PRODUCT_CEU526                    0x160F
+
+#define YUGA_PRODUCT_CWM600                    0x2601
+#define YUGA_PRODUCT_CWM610                    0x2602
+#define YUGA_PRODUCT_CWM500                    0x2603
+#define YUGA_PRODUCT_CWM510                    0x2604
+#define YUGA_PRODUCT_CWM800                    0x2605
+#define YUGA_PRODUCT_CWM900                    0x2606
+
+#define YUGA_PRODUCT_CWU718                    0x2607
+#define YUGA_PRODUCT_CWU716                    0x2608
+#define YUGA_PRODUCT_CWU728                    0x2609
+#define YUGA_PRODUCT_CWU726                    0x260A
+#define YUGA_PRODUCT_CWU518                    0x260B
+#define YUGA_PRODUCT_CWU516                    0x260C
+#define YUGA_PRODUCT_CWU528                    0x260D
+#define YUGA_PRODUCT_CWU526                    0x260F
+
+#define YUGA_PRODUCT_CLM600                    0x2601
+#define YUGA_PRODUCT_CLM610                    0x2602
+#define YUGA_PRODUCT_CLM500                    0x2603
+#define YUGA_PRODUCT_CLM510                    0x2604
+#define YUGA_PRODUCT_CLM800                    0x2605
+#define YUGA_PRODUCT_CLM900                    0x2606
+
+#define YUGA_PRODUCT_CLU718                    0x2607
+#define YUGA_PRODUCT_CLU716                    0x2608
+#define YUGA_PRODUCT_CLU728                    0x2609
+#define YUGA_PRODUCT_CLU726                    0x260A
+#define YUGA_PRODUCT_CLU518                    0x260B
+#define YUGA_PRODUCT_CLU516                    0x260C
+#define YUGA_PRODUCT_CLU528                    0x260D
+#define YUGA_PRODUCT_CLU526                    0x260F
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -551,6 +603,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
@@ -1005,6 +1059,48 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
        { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
@@ -1134,11 +1230,13 @@ static int option_probe(struct usb_serial *serial,
                serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
                return -ENODEV;
 
-       /* Don't bind network interfaces on Huawei K3765 & K4505 */
+       /* Don't bind network interfaces on Huawei K3765, K4505 & K4605 */
        if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID &&
                (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 ||
-                       serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) &&
-               serial->interface->cur_altsetting->desc.bInterfaceNumber == 1)
+                       serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505 ||
+                       serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4605) &&
+               (serial->interface->cur_altsetting->desc.bInterfaceNumber == 1 ||
+                       serial->interface->cur_altsetting->desc.bInterfaceNumber == 2))
                return -ENODEV;
 
        /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
index d5d136a53b61a52ca50cb2dd33fa983009b53b37..b18179bda0d8a0f7cd46b436e282ad08096e90d4 100644 (file)
@@ -1009,7 +1009,7 @@ static int sierra_suspend(struct usb_serial *serial, pm_message_t message)
        struct sierra_intf_private *intfdata;
        int b;
 
-       if (message.event & PM_EVENT_AUTO) {
+       if (PMSG_IS_AUTO(message)) {
                intfdata = serial->private;
                spin_lock_irq(&intfdata->susp_lock);
                b = intfdata->in_flight;
index e4fad5e643d74d6ab01995b0e84b9b53ea47fff7..d555ca9567b8507baa292f0087d1b20f9881783a 100644 (file)
@@ -651,7 +651,7 @@ int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
 
        dbg("%s entered", __func__);
 
-       if (message.event & PM_EVENT_AUTO) {
+       if (PMSG_IS_AUTO(message)) {
                spin_lock_irq(&intfdata->susp_lock);
                b = intfdata->in_flight;
                spin_unlock_irq(&intfdata->susp_lock);
index 75a39eab70c38e291363473074ff8373dcf30135..a425d65d5ba2d5d2e66f513f5dfcfa29b62de186 100644 (file)
@@ -378,8 +378,8 @@ static int mc68x328fb_pan_display(struct fb_var_screeninfo *var,
                    || var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual ||
-                   var->yoffset + var->yres > info->var.yres_virtual)
+               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+                   var->yoffset + info->var.yres > info->var.yres_virtual)
                        return -EINVAL;
        }
        info->var.xoffset = var->xoffset;
index 549b960667c81b5bcbff1145550a28630038c374..e087fc2207e7b9f6cbe9a868a8fee620bec366d8 100644 (file)
@@ -259,6 +259,15 @@ config FB_TILEBLITTING
 comment "Frame buffer hardware drivers"
        depends on FB
 
+config FB_GRVGA
+       tristate "Aeroflex Gaisler framebuffer support"
+       depends on FB && SPARC
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       ---help---
+       This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
 config FB_CIRRUS
        tristate "Cirrus Logic support"
        depends on FB && (ZORRO || PCI)
@@ -1756,9 +1765,10 @@ config FB_AU1100
 config FB_AU1200
        bool "Au1200 LCD Driver"
        depends on (FB = y) && MIPS && SOC_AU1200
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_SYS_FOPS
        help
          This is the framebuffer driver for the AMD Au1200 SOC.  It can drive
          various panels and CRTs by passing in kernel cmd line option
index 8b83129e209ca0f943a3d624e29930a679aec110..43079108bb16695d02052b6452e123f84a8beab7 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
+obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)             += pm3fb.o
 
index 6183a57eb69d8b913abcde29af3bbdb24714e725..b303f17150654a8a4d0237f41977421a29cd715b 100644 (file)
@@ -850,9 +850,10 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        u_int y_bottom = var->yoffset;
 
        if (!(var->vmode & FB_VMODE_YWRAP))
-               y_bottom += var->yres;
+               y_bottom += info->var.yres;
 
-       BUG_ON(y_bottom > var->yres_virtual);
+       if (y_bottom > info->var.yres_virtual)
+               return -EINVAL;
 
        acornfb_update_dma(info, var);
 
index 8686429cbdf07b57af8564849ad64b7a8624ff16..555dd4c64f5be24a1a13986f84fe19360f1d9102 100644 (file)
@@ -908,13 +908,14 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
        unsigned int offset;
 
        /* Calculate the offset */
-       if (var->bits_per_pixel == 0) {
-               offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
+       if (info->var.bits_per_pixel == 0) {
+               offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
+                      + (var->xoffset / 2);
                offset = offset >> 2;
        } else {
                offset = (var->yoffset * info->fix.line_length) +
-                        (var->xoffset * var->bits_per_pixel / 8);
-               offset = offset >> ((var->bits_per_pixel == 4) ? 2 : 3);
+                        (var->xoffset * info->var.bits_per_pixel / 8);
+               offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 3);
        }
 
        /* Set the offset */
index 817ab60f7537266d5f63e2e3ef9bbeb1b108bac5..82ad48002347807b70762fef658a0c266d182d70 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <mach/board.h>
 #include <mach/cpu.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -39,7 +39,8 @@
                                         | FBINFO_HWACCEL_YPAN)
 
 static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
-                                       struct fb_var_screeninfo *var)
+                                       struct fb_var_screeninfo *var,
+                                       struct fb_info *info)
 {
 
 }
@@ -50,14 +51,16 @@ static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
                                        | FBINFO_HWACCEL_YPAN)
 
 static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
-                                    struct fb_var_screeninfo *var)
+                                    struct fb_var_screeninfo *var,
+                                    struct fb_info *info)
 {
        u32 dma2dcfg;
        u32 pixeloff;
 
-       pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
+       pixeloff = (var->xoffset * info->var.bits_per_pixel) & 0x1f;
 
-       dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
+       dma2dcfg = (info-var.xres_virtual - info->var.xres)
+                * info->var.bits_per_pixel / 8;
        dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
        lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
 
@@ -249,14 +252,14 @@ static void atmel_lcdfb_update_dma(struct fb_info *info,
        unsigned long dma_addr;
 
        dma_addr = (fix->smem_start + var->yoffset * fix->line_length
-                   + var->xoffset * var->bits_per_pixel / 8);
+                   + var->xoffset * info->var.bits_per_pixel / 8);
 
        dma_addr &= ~3UL;
 
        /* Set framebuffer DMA base address and pixel offset */
        lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
 
-       atmel_lcdfb_update_dma2d(sinfo, var);
+       atmel_lcdfb_update_dma2d(sinfo, var, info);
 }
 
 static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
index 32f8cf6200a7533ce7bce35a4896fcdb4ff7946b..150684882ef74fce86d33ea2ed14bad9afa5df5b 100644 (file)
@@ -845,16 +845,16 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
 {
         struct radeonfb_info *rinfo = info->par;
 
-        if ((var->xoffset + var->xres > var->xres_virtual)
-           || (var->yoffset + var->yres > var->yres_virtual))
-               return -EINVAL;
+       if ((var->xoffset + info->var.xres > info->var.xres_virtual)
+           || (var->yoffset + info->var.yres > info->var.yres_virtual))
+               return -EINVAL;
                 
         if (rinfo->asleep)
                return 0;
 
        radeon_fifo_wait(2);
-        OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
-                            * var->bits_per_pixel / 8) & ~7);
+       OUTREG(CRTC_OFFSET, (var->yoffset * info->fix.line_length +
+                            var->xoffset * info->var.bits_per_pixel / 8) & ~7);
         return 0;
 }
 
index 5dff32ac8044be8de287c7e4c156dd0c577eb3c8..ed5dcdb29cf7ba232571a868a7fdb506c7ba9be1 100644 (file)
 #include <asm/mach-au1x00/au1000.h>
 #include "au1200fb.h"
 
-#ifdef CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
-#ifndef CONFIG_FB_AU1200_DEVS
-#define CONFIG_FB_AU1200_DEVS 4
-#endif
-
 #define DRIVER_NAME "au1200fb"
 #define DRIVER_DESC "LCD controller driver for AU1200 processors"
 
@@ -150,7 +142,7 @@ struct au1200_lcd_iodata_t {
 
 /* Private, per-framebuffer management information (independent of the panel itself) */
 struct au1200fb_device {
-       struct fb_info fb_info;                 /* FB driver info record */
+       struct fb_info *fb_info;                /* FB driver info record */
 
        int                                     plane;
        unsigned char*          fb_mem;         /* FrameBuffer memory map */
@@ -158,7 +150,6 @@ struct au1200fb_device {
        dma_addr_t              fb_phys;
 };
 
-static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
 /********************************************************************/
 
 /* LCD controller restrictions */
@@ -171,10 +162,18 @@ static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
 /* Default number of visible screen buffer to allocate */
 #define AU1200FB_NBR_VIDEO_BUFFERS 1
 
+/* Default maximum number of fb devices to create */
+#define MAX_DEVICE_COUNT       4
+
+/* Default window configuration entry to use (see windows[]) */
+#define DEFAULT_WINDOW_INDEX   2
+
 /********************************************************************/
 
+static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
 static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
-static int window_index = 2; /* default is zero */
+static int device_count = MAX_DEVICE_COUNT;
+static int window_index = DEFAULT_WINDOW_INDEX;        /* default is zero */
 static int panel_index = 2; /* default is zero */
 static struct window_settings *win;
 static struct panel_settings *panel;
@@ -205,12 +204,6 @@ struct window_settings {
 extern int board_au1200fb_panel_init (void);
 extern int board_au1200fb_panel_shutdown (void);
 
-#ifdef CONFIG_PM
-int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
-               au1xxx_request_t request, void *data);
-au1xxx_power_dev_t *LCD_pm_dev;
-#endif
-
 /*
  * Default window configurations
  */
@@ -652,25 +645,6 @@ static struct panel_settings known_lcd_panels[] =
 
 /********************************************************************/
 
-#ifdef CONFIG_PM
-static int set_brightness(unsigned int brightness)
-{
-       unsigned int hi1, divider;
-
-       /* limit brightness pwm duty to >= 30/1600 */
-       if (brightness < 30) {
-               brightness = 30;
-       }
-       divider = (lcd->pwmdiv & 0x3FFFF) + 1;
-       hi1 = (lcd->pwmhi >> 16) + 1;
-       hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
-       lcd->pwmhi &= 0xFFFF;
-       lcd->pwmhi |= (hi1 << 16);
-
-       return brightness;
-}
-#endif /* CONFIG_PM */
-
 static int winbpp (unsigned int winctrl1)
 {
        int bits = 0;
@@ -712,8 +686,8 @@ static int fbinfo2index (struct fb_info *fb_info)
 {
        int i;
 
-       for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
-               if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
+       for (i = 0; i < device_count; ++i) {
+               if (fb_info == _au1200fb_infos[i])
                        return i;
        }
        printk("au1200fb: ERROR: fbinfo2index failed!\n");
@@ -962,7 +936,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev)
        lcd->window[plane].winctrl2 = ( 0
                | LCD_WINCTRL2_CKMODE_00
                | LCD_WINCTRL2_DBM
-               | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
+               | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
                | LCD_WINCTRL2_SCX_1
                | LCD_WINCTRL2_SCY_1
                ) ;
@@ -1050,7 +1024,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi)
 static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
        struct fb_info *fbi)
 {
-       struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
+       struct au1200fb_device *fbdev = fbi->par;
        u32 pixclock;
        int screen_size, plane;
 
@@ -1142,7 +1116,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
  */
 static int au1200fb_fb_set_par(struct fb_info *fbi)
 {
-       struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
+       struct au1200fb_device *fbdev = fbi->par;
 
        au1200fb_update_fbinfo(fbi);
        au1200_setmode(fbdev);
@@ -1246,11 +1220,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        unsigned int len;
        unsigned long start=0, off;
-       struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
-
-#ifdef CONFIG_PM
-       au1xxx_pm_access(LCD_pm_dev);
-#endif
+       struct au1200fb_device *fbdev = info->par;
 
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
                return -EINVAL;
@@ -1461,10 +1431,6 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
        int plane;
        int val;
 
-#ifdef CONFIG_PM
-       au1xxx_pm_access(LCD_pm_dev);
-#endif
-
        plane = fbinfo2index(info);
        print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
 
@@ -1536,9 +1502,11 @@ static struct fb_ops au1200fb_fb_ops = {
        .fb_set_par     = au1200fb_fb_set_par,
        .fb_setcolreg   = au1200fb_fb_setcolreg,
        .fb_blank       = au1200fb_fb_blank,
-       .fb_fillrect    = cfb_fillrect,
-       .fb_copyarea    = cfb_copyarea,
-       .fb_imageblit   = cfb_imageblit,
+       .fb_fillrect    = sys_fillrect,
+       .fb_copyarea    = sys_copyarea,
+       .fb_imageblit   = sys_imageblit,
+       .fb_read        = fb_sys_read,
+       .fb_write       = fb_sys_write,
        .fb_sync        = NULL,
        .fb_ioctl       = au1200fb_ioctl,
        .fb_mmap        = au1200fb_fb_mmap,
@@ -1561,10 +1529,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
 
 static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
 {
-       struct fb_info *fbi = &fbdev->fb_info;
+       struct fb_info *fbi = fbdev->fb_info;
        int bpp;
 
-       memset(fbi, 0, sizeof(struct fb_info));
        fbi->fbops = &au1200fb_fb_ops;
 
        bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
@@ -1623,24 +1590,36 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
 
 /* AU1200 LCD controller device driver */
 
-static int au1200fb_drv_probe(struct platform_device *dev)
+static int __devinit au1200fb_drv_probe(struct platform_device *dev)
 {
        struct au1200fb_device *fbdev;
+       struct fb_info *fbi = NULL;
        unsigned long page;
-       int bpp, plane, ret;
+       int bpp, plane, ret, irq;
 
-       if (!dev)
-               return -EINVAL;
+       /* shut gcc up */
+       ret = 0;
+       fbdev = NULL;
+
+       /* Kickstart the panel */
+       au1200_setpanel(panel);
 
-       for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
+       for (plane = 0; plane < device_count; ++plane) {
                bpp = winbpp(win->w[plane].mode_winctrl1);
                if (win->w[plane].xres == 0)
                        win->w[plane].xres = panel->Xres;
                if (win->w[plane].yres == 0)
                        win->w[plane].yres = panel->Yres;
 
-               fbdev = &_au1200fb_devices[plane];
-               memset(fbdev, 0, sizeof(struct au1200fb_device));
+               fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
+                                       &dev->dev);
+               if (!fbi)
+                       goto failed;
+
+               _au1200fb_infos[plane] = fbi;
+               fbdev = fbi->par;
+               fbdev->fb_info = fbi;
+
                fbdev->plane = plane;
 
                /* Allocate the framebuffer to the maximum screen size */
@@ -1673,30 +1652,31 @@ static int au1200fb_drv_probe(struct platform_device *dev)
                        goto failed;
 
                /* Register new framebuffer */
-               if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
+               ret = register_framebuffer(fbi);
+               if (ret < 0) {
                        print_err("cannot register new framebuffer");
                        goto failed;
                }
 
-               au1200fb_fb_set_par(&fbdev->fb_info);
+               au1200fb_fb_set_par(fbi);
 
 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
                if (plane == 0)
-                       if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
+                       if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
                                /* Start display and show logo on boot */
-                               fb_set_cmap(&fbdev->fb_info.cmap,
-                                               &fbdev->fb_info);
-
-                               fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
+                               fb_set_cmap(&fbi->cmap, fbi);
+                               fb_show_logo(fbi, FB_ROTATE_UR);
                        }
 #endif
        }
 
        /* Now hook interrupt too */
-       if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
-                         IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) {
+       irq = platform_get_irq(dev, 0);
+       ret = request_irq(irq, au1200fb_handle_irq,
+                         IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev);
+       if (ret) {
                print_err("fail to request interrupt line %d (err: %d)",
-                         AU1200_LCD_INT, ret);
+                         irq, ret);
                goto failed;
        }
 
@@ -1705,84 +1685,108 @@ static int au1200fb_drv_probe(struct platform_device *dev)
 failed:
        /* NOTE: This only does the current plane/window that failed; others are still active */
        if (fbdev->fb_mem)
-               dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
+               dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
                                fbdev->fb_mem, fbdev->fb_phys);
-       if (fbdev->fb_info.cmap.len != 0)
-               fb_dealloc_cmap(&fbdev->fb_info.cmap);
-       if (fbdev->fb_info.pseudo_palette)
-               kfree(fbdev->fb_info.pseudo_palette);
+       if (fbi) {
+               if (fbi->cmap.len != 0)
+                       fb_dealloc_cmap(&fbi->cmap);
+               kfree(fbi->pseudo_palette);
+       }
        if (plane == 0)
                free_irq(AU1200_LCD_INT, (void*)dev);
        return ret;
 }
 
-static int au1200fb_drv_remove(struct platform_device *dev)
+static int __devexit au1200fb_drv_remove(struct platform_device *dev)
 {
        struct au1200fb_device *fbdev;
+       struct fb_info *fbi;
        int plane;
 
-       if (!dev)
-               return -ENODEV;
-
        /* Turn off the panel */
        au1200_setpanel(NULL);
 
-       for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
-       {
-               fbdev = &_au1200fb_devices[plane];
+       for (plane = 0; plane < device_count; ++plane)  {
+               fbi = _au1200fb_infos[plane];
+               fbdev = fbi->par;
 
                /* Clean up all probe data */
-               unregister_framebuffer(&fbdev->fb_info);
+               unregister_framebuffer(fbi);
                if (fbdev->fb_mem)
                        dma_free_noncoherent(&dev->dev,
                                        PAGE_ALIGN(fbdev->fb_len),
                                        fbdev->fb_mem, fbdev->fb_phys);
-               if (fbdev->fb_info.cmap.len != 0)
-                       fb_dealloc_cmap(&fbdev->fb_info.cmap);
-               if (fbdev->fb_info.pseudo_palette)
-                       kfree(fbdev->fb_info.pseudo_palette);
+               if (fbi->cmap.len != 0)
+                       fb_dealloc_cmap(&fbi->cmap);
+               kfree(fbi->pseudo_palette);
+
+               framebuffer_release(fbi);
+               _au1200fb_infos[plane] = NULL;
        }
 
-       free_irq(AU1200_LCD_INT, (void *)dev);
+       free_irq(platform_get_irq(dev, 0), (void *)dev);
 
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
+static int au1200fb_drv_suspend(struct device *dev)
 {
-       /* TODO */
+       au1200_setpanel(NULL);
+
+       lcd->outmask = 0;
+       au_sync();
+
        return 0;
 }
 
-static int au1200fb_drv_resume(struct platform_device *dev)
+static int au1200fb_drv_resume(struct device *dev)
 {
-       /* TODO */
+       struct fb_info *fbi;
+       int i;
+
+       /* Kickstart the panel */
+       au1200_setpanel(panel);
+
+       for (i = 0; i < device_count; i++) {
+               fbi = _au1200fb_infos[i];
+               au1200fb_fb_set_par(fbi);
+       }
+
        return 0;
 }
+
+static const struct dev_pm_ops au1200fb_pmops = {
+       .suspend        = au1200fb_drv_suspend,
+       .resume         = au1200fb_drv_resume,
+       .freeze         = au1200fb_drv_suspend,
+       .thaw           = au1200fb_drv_resume,
+};
+
+#define AU1200FB_PMOPS (&au1200fb_pmops)
+
+#else
+#define AU1200FB_PMOPS NULL
 #endif /* CONFIG_PM */
 
 static struct platform_driver au1200fb_driver = {
        .driver = {
-               .name           = "au1200-lcd",
-               .owner          = THIS_MODULE,
+               .name   = "au1200-lcd",
+               .owner  = THIS_MODULE,
+               .pm     = AU1200FB_PMOPS,
        },
        .probe          = au1200fb_drv_probe,
-       .remove         = au1200fb_drv_remove,
-#ifdef CONFIG_PM
-       .suspend        = au1200fb_drv_suspend,
-       .resume         = au1200fb_drv_resume,
-#endif
+       .remove         = __devexit_p(au1200fb_drv_remove),
 };
 
 /*-------------------------------------------------------------------------*/
 
 /* Kernel driver */
 
-static void au1200fb_setup(void)
+static int au1200fb_setup(void)
 {
-       charoptions = NULL;
-       char* this_opt;
+       char *options = NULL;
+       char *this_opt, *endptr;
        int num_panels = ARRAY_SIZE(known_lcd_panels);
        int panel_idx = -1;
 
@@ -1827,70 +1831,42 @@ static void au1200fb_setup(void)
                                nohwcursor = 1;
                        }
 
-                       /* Unsupported option */
-                       else {
-                               print_warn("Unsupported option \"%s\"", this_opt);
+                       else if (strncmp(this_opt, "devices:", 8) == 0) {
+                               this_opt += 8;
+                               device_count = simple_strtol(this_opt,
+                                                            &endptr, 0);
+                               if ((device_count < 0) ||
+                                   (device_count > MAX_DEVICE_COUNT))
+                                       device_count = MAX_DEVICE_COUNT;
                        }
-               }
-       }
-}
 
-#ifdef CONFIG_PM
-static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
-               au1xxx_request_t request, void *data) {
-       int retval = -1;
-       unsigned int d = 0;
-       unsigned int brightness = 0;
-
-       if (request == AU1XXX_PM_SLEEP) {
-               board_au1200fb_panel_shutdown();
-       }
-       else if (request == AU1XXX_PM_WAKEUP) {
-               if(dev->prev_state == SLEEP_STATE)
-               {
-                       int plane;
-                       au1200_setpanel(panel);
-                       for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)         {
-                               struct au1200fb_device *fbdev;
-                               fbdev = &_au1200fb_devices[plane];
-                               au1200fb_fb_set_par(&fbdev->fb_info);
+                       else if (strncmp(this_opt, "wincfg:", 7) == 0) {
+                               this_opt += 7;
+                               window_index = simple_strtol(this_opt,
+                                                            &endptr, 0);
+                               if ((window_index < 0) ||
+                                   (window_index >= ARRAY_SIZE(windows)))
+                                       window_index = DEFAULT_WINDOW_INDEX;
                        }
-               }
 
-               d = *((unsigned int*)data);
-               if(d <=10) brightness = 26;
-               else if(d<=20) brightness = 51;
-               else if(d<=30) brightness = 77;
-               else if(d<=40) brightness = 102;
-               else if(d<=50) brightness = 128;
-               else if(d<=60) brightness = 153;
-               else if(d<=70) brightness = 179;
-               else if(d<=80) brightness = 204;
-               else if(d<=90) brightness = 230;
-               else brightness = 255;
-               set_brightness(brightness);
-       } else if (request == AU1XXX_PM_GETSTATUS) {
-               return dev->cur_state;
-       } else if (request == AU1XXX_PM_ACCESS) {
-               if (dev->cur_state != SLEEP_STATE)
-                       return retval;
-               else {
-                       au1200_setpanel(panel);
+                       else if (strncmp(this_opt, "off", 3) == 0)
+                               return 1;
+                       /* Unsupported option */
+                       else {
+                               print_warn("Unsupported option \"%s\"", this_opt);
+                       }
                }
-       } else if (request == AU1XXX_PM_IDLE) {
-       } else if (request == AU1XXX_PM_CLEANUP) {
        }
-
-       return retval;
+       return 0;
 }
-#endif
 
 static int __init au1200fb_init(void)
 {
        print_info("" DRIVER_DESC "");
 
        /* Setup driver with options */
-       au1200fb_setup();
+       if (au1200fb_setup())
+               return -ENODEV;
 
        /* Point to the panel selected */
        panel = &known_lcd_panels[panel_index];
@@ -1899,17 +1875,6 @@ static int __init au1200fb_init(void)
        printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
        printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
 
-       /* Kickstart the panel, the framebuffers/windows come soon enough */
-       au1200_setpanel(panel);
-
-       #ifdef CONFIG_PM
-       LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
-       if ( LCD_pm_dev == NULL)
-               printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
-       else
-               printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
-       #endif
-
        return platform_driver_register(&au1200fb_driver);
 }
 
index 183b6f6398523d86fbb14a45f5fa08025ac71c3e..66bc74d9ce2af30889d026835d00442923cbc822 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pm.h>
index 05a8832bb3eb360d2d835e5281323d978d078500..383c4c364b5fd3d92c9469852b0cf156f4b9a5b6 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pm.h>
index caaa27d4a46a95c76da928a4353cd7d8087d1a95..cb09aa1fa138618c13278de877d5ecfb9b845582 100644 (file)
 #define CARMINEFB_DEFAULT_VIDEO_MODE   1
 
 static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
-module_param(fb_mode, uint, 444);
+module_param(fb_mode, uint, 0444);
 MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
 
 static char *fb_mode_str;
-module_param(fb_mode_str, charp, 444);
+module_param(fb_mode_str, charp, 0444);
 MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
 
 /*
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
  * 0b010 Display 1
  */
 static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
-module_param(fb_displays, int, 444);
+module_param(fb_displays, int, 0444);
 MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
 
 struct carmine_hw {
index 9075bea55879fc9c3eb507dc9e7e2a4c707111e1..7b2c40abae15b21e5ba26f460d809c216fb8e30a 100644 (file)
@@ -550,7 +550,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
 
 
 /*
- * Parse user speficied options (`video=controlfb:')
+ * Parse user specified options (`video=controlfb:')
  */
 static void __init control_setup(char *options)
 {
index fcdac872522d66702e0035bfda682ae189547eec..217c05f745416a81442702cb5857851dcbb58e2d 100644 (file)
@@ -35,6 +35,9 @@
 
 #define DRIVER_NAME "da8xx_lcdc"
 
+#define LCD_VERSION_1  1
+#define LCD_VERSION_2  2
+
 /* LCD Status Register */
 #define LCD_END_OF_FRAME1              BIT(9)
 #define LCD_END_OF_FRAME0              BIT(8)
@@ -49,7 +52,9 @@
 #define LCD_DMA_BURST_4                        0x2
 #define LCD_DMA_BURST_8                        0x3
 #define LCD_DMA_BURST_16               0x4
-#define LCD_END_OF_FRAME_INT_ENA       BIT(2)
+#define LCD_V1_END_OF_FRAME_INT_ENA    BIT(2)
+#define LCD_V2_END_OF_FRAME0_INT_ENA   BIT(8)
+#define LCD_V2_END_OF_FRAME1_INT_ENA   BIT(9)
 #define LCD_DUAL_FRAME_BUFFER_ENABLE   BIT(0)
 
 /* LCD Control Register */
 #define LCD_MONO_8BIT_MODE             BIT(9)
 #define LCD_RASTER_ORDER               BIT(8)
 #define LCD_TFT_MODE                   BIT(7)
-#define LCD_UNDERFLOW_INT_ENA          BIT(6)
-#define LCD_PL_ENABLE                  BIT(4)
+#define LCD_V1_UNDERFLOW_INT_ENA       BIT(6)
+#define LCD_V2_UNDERFLOW_INT_ENA       BIT(5)
+#define LCD_V1_PL_INT_ENA              BIT(4)
+#define LCD_V2_PL_INT_ENA              BIT(6)
 #define LCD_MONOCHROME_MODE            BIT(1)
 #define LCD_RASTER_ENABLE              BIT(0)
 #define LCD_TFT_ALT_ENABLE             BIT(23)
 #define LCD_STN_565_ENABLE             BIT(24)
+#define LCD_V2_DMA_CLK_EN              BIT(2)
+#define LCD_V2_LIDD_CLK_EN             BIT(1)
+#define LCD_V2_CORE_CLK_EN             BIT(0)
+#define LCD_V2_LPP_B10                 26
 
 /* LCD Raster Timing 2 Register */
 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)     ((x) << 16)
@@ -82,6 +93,7 @@
 #define LCD_INVERT_FRAME_CLOCK                 BIT(20)
 
 /* LCD Block */
+#define  LCD_PID_REG                           0x0
 #define  LCD_CTRL_REG                          0x4
 #define  LCD_STAT_REG                          0x8
 #define  LCD_RASTER_CTRL_REG                   0x28
 #define  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG       0x4C
 #define  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG    0x50
 
+/* Interrupt Registers available only in Version 2 */
+#define  LCD_RAW_STAT_REG                      0x58
+#define  LCD_MASKED_STAT_REG                   0x5c
+#define  LCD_INT_ENABLE_SET_REG                        0x60
+#define  LCD_INT_ENABLE_CLR_REG                        0x64
+#define  LCD_END_OF_INT_IND_REG                        0x68
+
+/* Clock registers available only on Version 2 */
+#define  LCD_CLK_ENABLE_REG                    0x6c
+#define  LCD_CLK_RESET_REG                     0x70
+
 #define LCD_NUM_BUFFERS        2
 
 #define WSI_TIMEOUT    50
 
 static resource_size_t da8xx_fb_reg_base;
 static struct resource *lcdc_regs;
+static unsigned int lcd_revision;
+static irq_handler_t lcdc_irq_handler;
 
 static inline unsigned int lcdc_read(unsigned int addr)
 {
@@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
        u32 end;
        u32 reg_ras;
        u32 reg_dma;
+       u32 reg_int;
 
        /* init reg to clear PLM (loading mode) fields */
        reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
@@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
                end      = par->dma_end;
 
                reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
-               reg_dma |= LCD_END_OF_FRAME_INT_ENA;
+               if (lcd_revision == LCD_VERSION_1) {
+                       reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
+               } else {
+                       reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+                               LCD_V2_END_OF_FRAME0_INT_ENA |
+                               LCD_V2_END_OF_FRAME1_INT_ENA;
+                       lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+               }
                reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
 
                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
@@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
                end      = start + par->palette_sz - 1;
 
                reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
-               reg_ras |= LCD_PL_ENABLE;
+
+               if (lcd_revision == LCD_VERSION_1) {
+                       reg_ras |= LCD_V1_PL_INT_ENA;
+               } else {
+                       reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+                               LCD_V2_PL_INT_ENA;
+                       lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+               }
 
                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
                lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
@@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
 static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 {
        u32 reg;
+       u32 reg_int;
 
        reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
                                                LCD_MONO_8BIT_MODE |
@@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
        }
 
        /* enable additional interrupts here */
-       reg |= LCD_UNDERFLOW_INT_ENA;
+       if (lcd_revision == LCD_VERSION_1) {
+               reg |= LCD_V1_UNDERFLOW_INT_ENA;
+       } else {
+               reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
+                       LCD_V2_UNDERFLOW_INT_ENA;
+               lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
+       }
 
        lcdc_write(reg, LCD_RASTER_CTRL_REG);
 
@@ -511,6 +558,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
        /* DMA has to be disabled */
        lcdc_write(0, LCD_DMA_CTRL_REG);
        lcdc_write(0, LCD_RASTER_CTRL_REG);
+
+       if (lcd_revision == LCD_VERSION_2)
+               lcdc_write(0, LCD_INT_ENABLE_SET_REG);
 }
 
 static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
@@ -523,6 +573,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
        /* Configure the LCD clock divisor. */
        lcdc_write(LCD_CLK_DIVISOR(div) |
                        (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
+
+       if (lcd_revision == LCD_VERSION_2)
+               lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
+                               LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+
 }
 
 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -583,7 +638,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
        return 0;
 }
 
-static irqreturn_t lcdc_irq_handler(int irq, void *arg)
+/* IRQ handler for version 2 of LCDC */
+static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
+{
+       struct da8xx_fb_par *par = arg;
+       u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
+       u32 reg_int;
+
+       if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
+               lcd_disable_raster();
+               lcdc_write(stat, LCD_MASKED_STAT_REG);
+               lcd_enable_raster();
+       } else if (stat & LCD_PL_LOAD_DONE) {
+               /*
+                * Must disable raster before changing state of any control bit.
+                * And also must be disabled before clearing the PL loading
+                * interrupt via the following write to the status register. If
+                * this is done after then one gets multiple PL done interrupts.
+                */
+               lcd_disable_raster();
+
+               lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+               /* Disable PL completion inerrupt */
+               reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
+                      (LCD_V2_PL_INT_ENA);
+               lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
+
+               /* Setup and start data loading mode */
+               lcd_blit(LOAD_DATA, par);
+       } else {
+               lcdc_write(stat, LCD_MASKED_STAT_REG);
+
+               if (stat & LCD_END_OF_FRAME0) {
+                       lcdc_write(par->dma_start,
+                                  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+                       lcdc_write(par->dma_end,
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
+               }
+
+               if (stat & LCD_END_OF_FRAME1) {
+                       lcdc_write(par->dma_start,
+                                  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+                       lcdc_write(par->dma_end,
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
+               }
+       }
+
+       lcdc_write(0, LCD_END_OF_INT_IND_REG);
+       return IRQ_HANDLED;
+}
+
+/* IRQ handler for version 1 LCDC */
+static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
 {
        struct da8xx_fb_par *par = arg;
        u32 stat = lcdc_read(LCD_STAT_REG);
@@ -606,7 +717,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
 
                /* Disable PL completion inerrupt */
                reg_ras  = lcdc_read(LCD_RASTER_CTRL_REG);
-               reg_ras &= ~LCD_PL_ENABLE;
+               reg_ras &= ~LCD_V1_PL_INT_ENA;
                lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
 
                /* Setup and start data loading mode */
@@ -877,8 +988,8 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
 
                        start   = fix->smem_start +
                                new_var.yoffset * fix->line_length +
-                               new_var.xoffset * var->bits_per_pixel / 8;
-                       end     = start + var->yres * fix->line_length - 1;
+                               new_var.xoffset * fbi->var.bits_per_pixel / 8;
+                       end     = start + fbi->var.yres * fix->line_length - 1;
                        par->dma_start  = start;
                        par->dma_end    = end;
                }
@@ -945,6 +1056,22 @@ static int __devinit fb_probe(struct platform_device *device)
        if (ret)
                goto err_clk_put;
 
+       /* Determine LCD IP Version */
+       switch (lcdc_read(LCD_PID_REG)) {
+       case 0x4C100102:
+               lcd_revision = LCD_VERSION_1;
+               break;
+       case 0x4F200800:
+               lcd_revision = LCD_VERSION_2;
+               break;
+       default:
+               dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
+                               "defaulting to LCD revision 1\n",
+                               lcdc_read(LCD_PID_REG));
+               lcd_revision = LCD_VERSION_1;
+               break;
+       }
+
        for (i = 0, lcdc_info = known_lcd_panels;
                i < ARRAY_SIZE(known_lcd_panels);
                i++, lcdc_info++) {
@@ -1085,7 +1212,13 @@ static int __devinit fb_probe(struct platform_device *device)
        }
 #endif
 
-       ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+       if (lcd_revision == LCD_VERSION_1)
+               lcdc_irq_handler = lcdc_irq_handler_rev01;
+       else
+               lcdc_irq_handler = lcdc_irq_handler_rev02;
+
+       ret = request_irq(par->irq, lcdc_irq_handler, 0,
+                       DRIVER_NAME, par);
        if (ret)
                goto irq_freq;
        return 0;
index 27f2c57e06e9f0225f8132f5a93ce7022ba81183..60a787fa32cfe97ddc8cdbb2999492e4da99144d 100644 (file)
@@ -624,8 +624,8 @@ static int unifb_pan_display(struct fb_var_screeninfo *var,
                    || var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual ||
-                   var->yoffset + var->yres > info->var.yres_virtual)
+               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+                   var->yoffset + info->var.yres > info->var.yres_virtual)
                        return -EINVAL;
        }
        info->var.xoffset = var->xoffset;
index 32814e8800e034ccb073024a0959f5764ced7d86..c27e153d8882053e2d28ab72cfc784875752f337 100644 (file)
@@ -223,8 +223,7 @@ void fb_deferred_io_cleanup(struct fb_info *info)
        int i;
 
        BUG_ON(!fbdefio);
-       cancel_delayed_work(&info->deferred_work);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&info->deferred_work);
 
        /* clear out the mapping that we setup */
        for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
index 0acc7d65aeaade67e5ce3d1188d030d5d842d159..0f1933b5459659c98ed56dabc6848954ad557fb5 100644 (file)
@@ -31,8 +31,6 @@
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
 
-#include <linux/of_platform.h>
-
 #include <sysdev/fsl_soc.h>
 #include <linux/fsl-diu-fb.h>
 #include "edid.h"
@@ -183,7 +181,8 @@ static struct fb_videomode __devinitdata fsl_diu_mode_db[] = {
 
 static char *fb_mode = "1024x768-32@60";
 static unsigned long default_bpp = 32;
-static int monitor_port;
+static enum fsl_diu_monitor_port monitor_port;
+static char *monitor_string;
 
 #if defined(CONFIG_NOT_COHERENT_CACHE)
 static u8 *coherence_data;
@@ -201,7 +200,7 @@ struct fsl_diu_data {
        void *dummy_aoi_virt;
        unsigned int irq;
        int fb_enabled;
-       int monitor_port;
+       enum fsl_diu_monitor_port monitor_port;
 };
 
 struct mfb_info {
@@ -281,6 +280,37 @@ static struct diu_hw dr = {
 
 static struct diu_pool pool;
 
+/**
+ * fsl_diu_name_to_port - convert a port name to a monitor port enum
+ *
+ * Takes the name of a monitor port ("dvi", "lvds", or "dlvds") and returns
+ * the enum fsl_diu_monitor_port that corresponds to that string.
+ *
+ * For compatibility with older versions, a number ("0", "1", or "2") is also
+ * supported.
+ *
+ * If the string is unknown, DVI is assumed.
+ *
+ * If the particular port is not supported by the platform, another port
+ * (platform-specific) is chosen instead.
+ */
+static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
+{
+       enum fsl_diu_monitor_port port = FSL_DIU_PORT_DVI;
+       unsigned long val;
+
+       if (s) {
+               if (!strict_strtoul(s, 10, &val) && (val <= 2))
+                       port = (enum fsl_diu_monitor_port) val;
+               else if (strncmp(s, "lvds", 4) == 0)
+                       port = FSL_DIU_PORT_LVDS;
+               else if (strncmp(s, "dlvds", 5) == 0)
+                       port = FSL_DIU_PORT_DLVDS;
+       }
+
+       return diu_ops.valid_monitor_port(port);
+}
+
 /**
  * fsl_diu_alloc - allocate memory for the DIU
  * @size: number of bytes to allocate
@@ -831,9 +861,8 @@ static int fsl_diu_set_par(struct fb_info *info)
                }
        }
 
-       ad->pix_fmt =
-               diu_ops.get_pixel_format(var->bits_per_pixel,
-                                        machine_data->monitor_port);
+       ad->pix_fmt = diu_ops.get_pixel_format(machine_data->monitor_port,
+                                              var->bits_per_pixel);
        ad->addr    = cpu_to_le32(info->fix.smem_start);
        ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
                                var->xres_virtual) | mfbi->g_alpha;
@@ -1439,16 +1468,12 @@ static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
 static ssize_t store_monitor(struct device *device,
        struct device_attribute *attr, const char *buf, size_t count)
 {
-       int old_monitor_port;
-       unsigned long val;
+       enum fsl_diu_monitor_port old_monitor_port;
        struct fsl_diu_data *machine_data =
                container_of(attr, struct fsl_diu_data, dev_attr);
 
-       if (strict_strtoul(buf, 10, &val))
-               return 0;
-
        old_monitor_port = machine_data->monitor_port;
-       machine_data->monitor_port = diu_ops.set_sysfs_monitor_port(val);
+       machine_data->monitor_port = fsl_diu_name_to_port(buf);
 
        if (old_monitor_port != machine_data->monitor_port) {
                /* All AOIs need adjust pixel format
@@ -1468,7 +1493,17 @@ static ssize_t show_monitor(struct device *device,
 {
        struct fsl_diu_data *machine_data =
                container_of(attr, struct fsl_diu_data, dev_attr);
-       return diu_ops.show_monitor_port(machine_data->monitor_port, buf);
+
+       switch (machine_data->monitor_port) {
+       case FSL_DIU_PORT_DVI:
+               return sprintf(buf, "DVI\n");
+       case FSL_DIU_PORT_LVDS:
+               return sprintf(buf, "Single-link LVDS\n");
+       case FSL_DIU_PORT_DLVDS:
+               return sprintf(buf, "Dual-link LVDS\n");
+       }
+
+       return 0;
 }
 
 static int __devinit fsl_diu_probe(struct platform_device *ofdev)
@@ -1692,8 +1727,7 @@ static int __init fsl_diu_setup(char *options)
                if (!*opt)
                        continue;
                if (!strncmp(opt, "monitor=", 8)) {
-                       if (!strict_strtoul(opt + 8, 10, &val) && (val <= 2))
-                               monitor_port = val;
+                       monitor_port = fsl_diu_name_to_port(opt + 8);
                } else if (!strncmp(opt, "bpp=", 4)) {
                        if (!strict_strtoul(opt + 4, 10, &val))
                                default_bpp = val;
@@ -1746,6 +1780,8 @@ static int __init fsl_diu_init(void)
        if (fb_get_options("fslfb", &option))
                return -ENODEV;
        fsl_diu_setup(option);
+#else
+       monitor_port = fsl_diu_name_to_port(monitor_string);
 #endif
        printk(KERN_INFO "Freescale DIU driver\n");
 
@@ -1812,7 +1848,7 @@ MODULE_PARM_DESC(mode,
        "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
 module_param_named(bpp, default_bpp, ulong, 0);
 MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
-module_param_named(monitor, monitor_port, int, 0);
-MODULE_PARM_DESC(monitor,
-       "Specify the monitor port (0, 1 or 2) if supported by the platform");
+module_param_named(monitor, monitor_string, charp, 0);
+MODULE_PARM_DESC(monitor, "Specify the monitor port "
+       "(\"dvi\", \"lvds\", or \"dlvds\") if supported by the platform");
 
index d662317d85e30fb01782b29f0bb681d327b766df..223896cc5f7d66713f98db315ada5ab364fc7d2b 100644 (file)
@@ -149,10 +149,11 @@ int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 static int g364fb_pan_display(struct fb_var_screeninfo *var, 
                              struct fb_info *info)
 {
-       if (var->xoffset || var->yoffset + var->yres > var->yres_virtual)
+       if (var->xoffset ||
+           var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
 
-       *(unsigned int *) TOP_REG = var->yoffset * var->xres;
+       *(unsigned int *) TOP_REG = var->yoffset * info->var.xres;
        return 0;
 }
 
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
new file mode 100644 (file)
index 0000000..f37e025
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+ * Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
+ *
+ * 2011 (c) Aeroflex Gaisler AB
+ *
+ * Full documentation of the core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+
+struct grvga_regs {
+       u32 status;             /* 0x00 */
+       u32 video_length;       /* 0x04 */
+       u32 front_porch;        /* 0x08 */
+       u32 sync_length;        /* 0x0C */
+       u32 line_length;        /* 0x10 */
+       u32 fb_pos;             /* 0x14 */
+       u32 clk_vector[4];      /* 0x18 */
+       u32 clut;               /* 0x20 */
+};
+
+struct grvga_par {
+       struct grvga_regs *regs;
+       u32 color_palette[16];  /* 16 entry pseudo palette used by fbcon in true color mode */
+       int clk_sel;
+       int fb_alloced;         /* = 1 if framebuffer is allocated in main memory */
+};
+
+
+static const struct fb_videomode grvga_modedb[] = {
+    {
+       /* 640x480 @ 60 Hz */
+       NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
+       0, FB_VMODE_NONINTERLACED
+    }, {
+       /* 800x600 @ 60 Hz */
+       NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
+       0, FB_VMODE_NONINTERLACED
+    }, {
+       /* 800x600 @ 72 Hz */
+       NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
+       0, FB_VMODE_NONINTERLACED
+    }, {
+       /* 1024x768 @ 60 Hz */
+       NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
+       0, FB_VMODE_NONINTERLACED
+    }
+ };
+
+static struct fb_fix_screeninfo grvga_fix __initdata = {
+       .id =           "AG SVGACTRL",
+       .type =         FB_TYPE_PACKED_PIXELS,
+       .visual =       FB_VISUAL_PSEUDOCOLOR,
+       .xpanstep =     0,
+       .ypanstep =     1,
+       .ywrapstep =    0,
+       .accel =        FB_ACCEL_NONE,
+};
+
+static int grvga_check_var(struct fb_var_screeninfo *var,
+                          struct fb_info *info)
+{
+       struct grvga_par *par = info->par;
+       int i;
+
+       if (!var->xres)
+               var->xres = 1;
+       if (!var->yres)
+               var->yres = 1;
+       if (var->bits_per_pixel <= 8)
+               var->bits_per_pixel = 8;
+       else if (var->bits_per_pixel <= 16)
+               var->bits_per_pixel = 16;
+       else if (var->bits_per_pixel <= 24)
+               var->bits_per_pixel = 24;
+       else if (var->bits_per_pixel <= 32)
+               var->bits_per_pixel = 32;
+       else
+               return -EINVAL;
+
+       var->xres_virtual = var->xres;
+       var->yres_virtual = 2*var->yres;
+
+       if (info->fix.smem_len) {
+               if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
+                       return -ENOMEM;
+       }
+
+       /* Which clocks that are available can be read out in these registers */
+       for (i = 0; i <= 3 ; i++) {
+               if (var->pixclock == par->regs->clk_vector[i])
+                       break;
+       }
+       if (i <= 3)
+               par->clk_sel = i;
+       else
+               return -EINVAL;
+
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               var->red   = (struct fb_bitfield) {0, 8, 0};      /* offset, length, msb-right */
+               var->green = (struct fb_bitfield) {0, 8, 0};
+               var->blue  = (struct fb_bitfield) {0, 8, 0};
+               var->transp = (struct fb_bitfield) {0, 0, 0};
+               break;
+       case 16:
+               var->red   = (struct fb_bitfield) {11, 5, 0};
+               var->green = (struct fb_bitfield) {5, 6, 0};
+               var->blue  = (struct fb_bitfield) {0, 5, 0};
+               var->transp = (struct fb_bitfield) {0, 0, 0};
+               break;
+       case 24:
+       case 32:
+               var->red   = (struct fb_bitfield) {16, 8, 0};
+               var->green = (struct fb_bitfield) {8, 8, 0};
+               var->blue  = (struct fb_bitfield) {0, 8, 0};
+               var->transp = (struct fb_bitfield) {24, 8, 0};
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int grvga_set_par(struct fb_info *info)
+{
+
+       u32 func = 0;
+       struct grvga_par *par = info->par;
+
+       __raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
+                    &par->regs->video_length);
+
+       __raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
+                    &par->regs->front_porch);
+
+       __raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
+                    &par->regs->sync_length);
+
+       __raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
+                    (info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
+                    &par->regs->line_length);
+
+       switch (info->var.bits_per_pixel) {
+       case 8:
+               info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+               func = 1;
+               break;
+       case 16:
+               info->fix.visual = FB_VISUAL_TRUECOLOR;
+               func = 2;
+               break;
+       case 24:
+       case 32:
+               info->fix.visual = FB_VISUAL_TRUECOLOR;
+               func = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       __raw_writel((par->clk_sel << 6) | (func << 4) | 1,
+                    &par->regs->status);
+
+       info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
+       return 0;
+}
+
+static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
+{
+       struct grvga_par *par;
+       par = info->par;
+
+       if (regno >= 256)       /* Size of CLUT */
+               return -EINVAL;
+
+       if (info->var.grayscale) {
+               /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+               red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+       }
+
+
+
+#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
+
+       red    = CNVT_TOHW(red,   info->var.red.length);
+       green  = CNVT_TOHW(green, info->var.green.length);
+       blue   = CNVT_TOHW(blue,  info->var.blue.length);
+       transp = CNVT_TOHW(transp, info->var.transp.length);
+
+#undef CNVT_TOHW
+
+       /* In PSEUDOCOLOR we use the hardware CLUT */
+       if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
+               __raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
+                            &par->regs->clut);
+
+       /* Truecolor uses the pseudo palette */
+       else if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+               u32 v;
+               if (regno >= 16)
+                       return -EINVAL;
+
+
+               v =     (red    << info->var.red.offset)   |
+                       (green  << info->var.green.offset) |
+                       (blue   << info->var.blue.offset)  |
+                       (transp << info->var.transp.offset);
+
+               ((u32 *) (info->pseudo_palette))[regno] = v;
+       }
+       return 0;
+}
+
+static int grvga_pan_display(struct fb_var_screeninfo *var,
+                            struct fb_info *info)
+{
+       struct grvga_par *par = info->par;
+       struct fb_fix_screeninfo *fix = &info->fix;
+       u32 base_addr;
+
+       if (var->xoffset != 0)
+               return -EINVAL;
+
+       base_addr = fix->smem_start + (var->yoffset * fix->line_length);
+       base_addr &= ~3UL;
+
+       /* Set framebuffer base address  */
+       __raw_writel(base_addr,
+                    &par->regs->fb_pos);
+
+       return 0;
+}
+
+static struct fb_ops grvga_ops = {
+       .owner          = THIS_MODULE,
+       .fb_check_var   = grvga_check_var,
+       .fb_set_par     = grvga_set_par,
+       .fb_setcolreg   = grvga_setcolreg,
+       .fb_pan_display = grvga_pan_display,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit
+};
+
+static int __init grvga_parse_custom(char *options,
+                                    struct fb_var_screeninfo *screendata)
+{
+       char *this_opt;
+       int count = 0;
+       if (!options || !*options)
+               return -1;
+
+       while ((this_opt = strsep(&options, " ")) != NULL) {
+               if (!*this_opt)
+                       continue;
+
+               switch (count) {
+               case 0:
+                       screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 1:
+                       screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 2:
+                       screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 3:
+                       screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 4:
+                       screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 5:
+                       screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 6:
+                       screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 7:
+                       screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 8:
+                       screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               case 9:
+                       screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
+                       count++;
+                       break;
+               default:
+                       return -1;
+               }
+       }
+       screendata->activate  = FB_ACTIVATE_NOW;
+       screendata->vmode     = FB_VMODE_NONINTERLACED;
+       return 0;
+}
+
+static int __devinit grvga_probe(struct platform_device *dev)
+{
+       struct fb_info *info;
+       int retval = -ENOMEM;
+       unsigned long virtual_start;
+       unsigned long grvga_fix_addr = 0;
+       unsigned long physical_start = 0;
+       unsigned long grvga_mem_size = 0;
+       struct grvga_par *par = NULL;
+       char *options = NULL, *mode_opt = NULL;
+
+       info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
+       if (!info) {
+               dev_err(&dev->dev, "framebuffer_alloc failed\n");
+               return -ENOMEM;
+       }
+
+       /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
+        *
+        * If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
+        * If address is left out, we allocate memory,
+        * if size is left out we only allocate enough to support the given mode.
+        */
+       if (fb_get_options("grvga", &options)) {
+               retval = -ENODEV;
+               goto err;
+       }
+
+       if (!options || !*options)
+               options =  "640x480-8@60";
+
+       while (1) {
+               char *this_opt = strsep(&options, ",");
+
+               if (!this_opt)
+                       break;
+
+               if (!strncmp(this_opt, "custom", 6)) {
+                       if (grvga_parse_custom(this_opt, &info->var) < 0) {
+                               dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
+                               retval = -EINVAL;
+                               goto err1;
+                       }
+               } else if (!strncmp(this_opt, "addr", 4))
+                       grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
+               else if (!strncmp(this_opt, "size", 4))
+                       grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
+               else
+                       mode_opt = this_opt;
+       }
+
+       par = info->par;
+       info->fbops = &grvga_ops;
+       info->fix = grvga_fix;
+       info->pseudo_palette = par->color_palette;
+       info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
+       info->fix.smem_len = grvga_mem_size;
+
+       if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
+               dev_err(&dev->dev, "registers already mapped\n");
+               retval = -EBUSY;
+               goto err;
+       }
+
+       par->regs = of_ioremap(&dev->resource[0], 0,
+                              resource_size(&dev->resource[0]),
+                              "grlib-svgactrl regs");
+
+       if (!par->regs) {
+               dev_err(&dev->dev, "failed to map registers\n");
+               retval = -ENOMEM;
+               goto err1;
+       }
+
+       retval = fb_alloc_cmap(&info->cmap, 256, 0);
+       if (retval < 0) {
+               dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
+               retval = -ENOMEM;
+               goto err2;
+       }
+
+       if (mode_opt) {
+               retval = fb_find_mode(&info->var, info, mode_opt,
+                                     grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
+               if (!retval || retval == 4) {
+                       retval = -EINVAL;
+                       goto err3;
+               }
+       }
+
+       if (!grvga_mem_size)
+               grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
+
+       if (grvga_fix_addr) {
+               /* Got framebuffer base address from argument list */
+
+               physical_start = grvga_fix_addr;
+
+               if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
+                       dev_err(&dev->dev, "failed to request memory region\n");
+                       retval = -ENOMEM;
+                       goto err3;
+               }
+
+               virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
+
+               if (!virtual_start) {
+                       dev_err(&dev->dev, "error mapping framebuffer memory\n");
+                       retval = -ENOMEM;
+                       goto err4;
+               }
+       } else {        /* Allocate frambuffer memory */
+
+               unsigned long page;
+
+               virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
+                                                                get_order(grvga_mem_size));
+               if (!virtual_start) {
+                       dev_err(&dev->dev,
+                               "unable to allocate framebuffer memory (%lu bytes)\n",
+                               grvga_mem_size);
+                       retval = -ENOMEM;
+                       goto err3;
+               }
+
+               physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
+
+               /* Set page reserved so that mmap will work. This is necessary
+                * since we'll be remapping normal memory.
+                */
+               for (page = virtual_start;
+                    page < PAGE_ALIGN(virtual_start + grvga_mem_size);
+                    page += PAGE_SIZE) {
+                       SetPageReserved(virt_to_page(page));
+               }
+
+               par->fb_alloced = 1;
+       }
+
+       memset((unsigned long *) virtual_start, 0, grvga_mem_size);
+
+       info->screen_base = (char __iomem *) virtual_start;
+       info->fix.smem_start = physical_start;
+       info->fix.smem_len   = grvga_mem_size;
+
+       dev_set_drvdata(&dev->dev, info);
+
+       dev_info(&dev->dev,
+                "Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
+                info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
+                grvga_mem_size >> 10, info->screen_base);
+
+       retval = register_framebuffer(info);
+       if (retval < 0) {
+               dev_err(&dev->dev, "failed to register framebuffer\n");
+               goto err4;
+       }
+
+       __raw_writel(physical_start, &par->regs->fb_pos);
+       __raw_writel(__raw_readl(&par->regs->status) | 1,  /* Enable framebuffer */
+                    &par->regs->status);
+
+       return 0;
+
+err4:
+       dev_set_drvdata(&dev->dev, NULL);
+       if (grvga_fix_addr) {
+               release_mem_region(physical_start, grvga_mem_size);
+               iounmap((void *)virtual_start);
+       } else
+               kfree((void *)virtual_start);
+err3:
+       fb_dealloc_cmap(&info->cmap);
+err2:
+       of_iounmap(&dev->resource[0], par->regs,
+                  resource_size(&dev->resource[0]));
+err1:
+       release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
+err:
+       framebuffer_release(info);
+
+       return retval;
+}
+
+static int __devexit grvga_remove(struct platform_device *device)
+{
+       struct fb_info *info = dev_get_drvdata(&device->dev);
+       struct grvga_par *par = info->par;
+
+       if (info) {
+               unregister_framebuffer(info);
+               fb_dealloc_cmap(&info->cmap);
+
+               of_iounmap(&device->resource[0], par->regs,
+                          resource_size(&device->resource[0]));
+               release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
+
+               if (!par->fb_alloced) {
+                       release_mem_region(info->fix.smem_start, info->fix.smem_len);
+                       iounmap(info->screen_base);
+               } else
+                       kfree((void *)info->screen_base);
+
+               framebuffer_release(info);
+               dev_set_drvdata(&device->dev, NULL);
+       }
+
+       return 0;
+}
+
+static struct of_device_id svgactrl_of_match[] = {
+       {
+               .name = "GAISLER_SVGACTRL",
+       },
+       {
+               .name = "01_063",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, svgactrl_of_match);
+
+static struct platform_driver grvga_driver = {
+       .driver = {
+               .name = "grlib-svgactrl",
+               .owner = THIS_MODULE,
+               .of_match_table = svgactrl_of_match,
+       },
+       .probe          = grvga_probe,
+       .remove         = __devexit_p(grvga_remove),
+};
+
+
+static int __init grvga_init(void)
+{
+       return platform_driver_register(&grvga_driver);
+}
+
+static void __exit grvga_exit(void)
+{
+       platform_driver_unregister(&grvga_driver);
+}
+
+module_init(grvga_init);
+module_exit(grvga_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Aeroflex Gaisler");
+MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");
index 896e53dea906178a30f951e4460b76b462c51b66..0fad23f810a32035faffd0fcd7e0256426947b58 100644 (file)
@@ -543,8 +543,8 @@ static int gxt4500_pan_display(struct fb_var_screeninfo *var,
 
        if (var->xoffset & 7)
                return -EINVAL;
-       if (var->xoffset + var->xres > var->xres_virtual ||
-           var->yoffset + var->yres > var->yres_virtual)
+       if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+           var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
 
        writereg(par, REFRESH_START, (var->xoffset << 16) | var->yoffset);
index 4052718eefaa09215a8706501eb9e6e47a339857..4394389caf68d8e8ffa40c5d19e2eec3970d76eb 100644 (file)
@@ -422,8 +422,8 @@ static int hgafb_pan_display(struct fb_var_screeninfo *var,
                    var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual
-                || var->yoffset + var->yres > info->var.yres_virtual
+               if (var->xoffset + info->var.xres > info->var.xres_virtual
+                || var->yoffset + info->var.yres > info->var.yres_virtual
                 || var->yoffset % 8)
                        return -EINVAL;
        }
index efb2c10656b0a89aa88d23276d47926805bbb4b2..8149356471e443af26d5a4e2cb97c818bfaf9c7f 100644 (file)
@@ -749,7 +749,7 @@ set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct imstt_par *par = info->par;
        __u32 off = var->yoffset * (info->fix.line_length >> 3)
-                   + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
+                   + ((var->xoffset * (info->var.bits_per_pixel >> 3)) >> 3);
        write_reg_le32(par->dc_regs, SSR, off);
 }
 
index 38065cf94ac4cf5dbaf195233871712af4607ab6..fbad61da359f796b579ae74b1dc01a78d888d4a9 100644 (file)
@@ -390,12 +390,12 @@ int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        xoffset = ROUND_DOWN_TO(var->xoffset, 8);
        yoffset = var->yoffset;
 
-       if ((xoffset + var->xres > var->xres_virtual) ||
-           (yoffset + var->yres > var->yres_virtual))
+       if ((xoffset + info->var.xres > info->var.xres_virtual) ||
+           (yoffset + info->var.yres > info->var.yres_virtual))
                return -EINVAL;
 
        offset = (yoffset * dinfo->pitch) +
-                (xoffset * var->bits_per_pixel) / 8;
+                (xoffset * info->var.bits_per_pixel) / 8;
 
        offset += dinfo->fb.offset << 12;
 
index ee1de3e26dece9a80f152478ffa642cfef00beae..7a1f2773cf38366ac5090bbf1dc37f89496807be 100644 (file)
@@ -278,7 +278,7 @@ static int mb862xxfb_pan(struct fb_var_screeninfo *var,
        reg = pack(var->yoffset, var->xoffset);
        outreg(disp, GC_L0WY_L0WX, reg);
 
-       reg = pack(var->yres_virtual, var->xres_virtual);
+       reg = pack(info->var.yres_virtual, info->var.xres_virtual);
        outreg(disp, GC_L0WH_L0WW, reg);
        return 0;
 }
index 243d16f09b8a2cbbfc6f5604f1775ec97cf91d72..01fa660764b4caea65c69b24e9c51be0a9636318 100644 (file)
@@ -421,7 +421,8 @@ int mdp_probe(struct platform_device *pdev)
        clk = clk_get(&pdev->dev, "mdp_clk");
        if (IS_ERR(clk)) {
                printk(KERN_INFO "mdp: failed to get mdp clk");
-               return PTR_ERR(clk);
+               ret = PTR_ERR(clk);
+               goto error_get_clk;
        }
 
        ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
@@ -495,6 +496,7 @@ int mdp_probe(struct platform_device *pdev)
 error_device_register:
        free_irq(mdp->irq, mdp);
 error_request_irq:
+error_get_clk:
        iounmap(mdp->base);
 error_get_irq:
 error_ioremap:
index 7e3a490e8d76d882555f58a752242360a6ed948b..bd768588cf10c8dca7a77fbf76c7564817bea5b4 100644 (file)
@@ -1062,15 +1062,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
        y_bottom = var->yoffset;
 
        if (!(var->vmode & FB_VMODE_YWRAP))
-               y_bottom += var->yres;
+               y_bottom += fbi->var.yres;
 
        if (y_bottom > fbi->var.yres_virtual)
                return -EINVAL;
 
        mutex_lock(&mx3_fbi->mutex);
 
-       offset = (var->yoffset * var->xres_virtual + var->xoffset) *
-               (var->bits_per_pixel / 8);
+       offset = var->yoffset * fbi->fix.line_length
+              + var->xoffset * (fbi->var.bits_per_pixel / 8);
        base = fbi->fix.smem_start + offset;
 
        dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
index 588527a254c27ead542b906d7f4045aa6aff1955..feea7b1dc3860a3f28965995d9aa24968cb7312d 100644 (file)
@@ -1185,8 +1185,8 @@ static int neofb_pan_display(struct fb_var_screeninfo *var,
 
        DBG("neofb_update_start");
 
-       Base = (var->yoffset * var->xres_virtual + var->xoffset) >> 2;
-       Base *= (var->bits_per_pixel + 7) / 8;
+       Base = (var->yoffset * info->var.xres_virtual + var->xoffset) >> 2;
+       Base *= (info->var.bits_per_pixel + 7) / 8;
 
        neoUnlock();
 
index 10459d8bd9a01268f99321aee171d8be0abf4294..4b24f549f9b92dd70d84b48259bf38fdfebf8319 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #include "omapfb.h"
 
index 8df688748b5a5376b6fd6419484e4bbdf296f0ba..622ad839fd9d46701af954235af4b30536f5c9da 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c/tps65010.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include "omapfb.h"
 
 #define MODULE_NAME    "omapfb-lcd_h3"
index 9fff86f67bde401ff475e2ba977db90897c613b0..12cc52a70f9642ad2c7c568b00ecca24cbb084f5 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include "omapfb.h"
 
 #define MODULE_NAME    "omapfb-lcd_h3"
index 0f5952cae85e6b2ddfd47ffd66ac1c0f7c88a919..062466402c0e67531e4fff8dbe6484973b1f7ced 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/delay.h>
 #include <linux/i2c/twl.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/mux.h>
 #include <asm/mach-types.h>
 
index b87e8b83f29c5fe12f40c5c76f14ff1f071baa32..6f8d13c41202a8addf821111d674a9e7fab8f8b9 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/mux.h>
 #include "omapfb.h"
 
index 564933ffac6ef73fc00b7e36bf81ca155f57d9db..b8fd5b2ec29c58899b976ae8a3a331b1ae3b345f 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c/twl.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include <plat/mux.h>
 #include <asm/mach-types.h>
 
index ff0e6d7ab3a207b118fed6ffa0d189caae46b838..b51b332e5a2bd16d05833996191034143808af52 100644 (file)
@@ -29,7 +29,7 @@ GPIO13 - screen blanking
 #include <linux/module.h>
 #include <linux/io.h>
 
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 #include "omapfb.h"
 
 static int palmtt_panel_init(struct lcd_panel *panel,
index f27ae16ead2ea1671e782821a1f6836140120ee7..66949232f85ce354325858a188a015f6d0864407 100644 (file)
@@ -490,7 +490,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
 
 
 /* 
- * Parse user speficied options (`video=platinumfb:')
+ * Parse user specified options (`video=platinumfb:')
  */
 static int __init platinumfb_setup(char *options)
 {
index 27f93aab6ddc008d3c61e59667993b4004a0a49a..dc7bfa91e57ab1c87bc6b2b0e4d405b050895c9a 100644 (file)
@@ -973,8 +973,8 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
 {
        struct pm2fb_par *p = info->par;
        u32 base;
-       u32 depth = (var->bits_per_pixel + 7) & ~7;
-       u32 xres = (var->xres + 31) & ~31;
+       u32 depth = (info->var.bits_per_pixel + 7) & ~7;
+       u32 xres = (info->var.xres + 31) & ~31;
 
        depth = (depth > 32) ? 32 : depth;
        base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
@@ -1773,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
 
 #ifndef MODULE
 /**
- * Parse user speficied options.
+ * Parse user specified options.
  *
  * This is, comma-separated options following `video=pm2fb:'.
  */
index 6666f45a2f8ce56e03f8ecb962caad73e5b7abdd..6632ee5ecb7e1243d2e6afc177a4a71eb6a5b6ec 100644 (file)
@@ -1147,9 +1147,9 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
                                 struct fb_info *info)
 {
        struct pm3_par *par = info->par;
-       const u32 xres = (var->xres + 31) & ~31;
+       const u32 xres = (info->var.xres + 31) & ~31;
 
-       par->base = pm3fb_shift_bpp(var->bits_per_pixel,
+       par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
                                        (var->yoffset * xres)
                                        + var->xoffset);
        PM3_WAIT(par, 1);
@@ -1525,7 +1525,7 @@ static int __init pm3fb_setup(char *options)
 {
        char *this_opt;
 
-       /* Parse user speficied options (`video=pm3fb:') */
+       /* Parse user specified options (`video=pm3fb:') */
        if (!options || !*options)
                return 0;
 
index 5ec4f2d439c949efd03f8b6d6024ac77cea81e83..50e00395240f67b43eb93f9c7697c5ff12d60a1a 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/clk.h>
 #include <linux/gfp.h>
 #include <asm/uaccess.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
 
 #include "sdum.h"
 #include "fbcommon.h"
index 0283c7021090d05661a3cdf9c0724f986364530f..d8de5577d3cf203d0de12ef461fb53a1c9b47dc9 100644 (file)
@@ -31,8 +31,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
-
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/miscdevice.h>
index 4aecf213c9be46cb1f37ee38d231aabcf9d089d3..fd9f20df912fef09c3be039d666edef150f8295d 100644 (file)
@@ -883,7 +883,7 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
                }
        }
        /* Offset in bytes to the end of the displayed area */
-       end_boff = start_boff + var->yres * info->fix.line_length;
+       end_boff = start_boff + info->var.yres * info->fix.line_length;
 
        /* Temporarily turn off per-vsync update from shadow registers until
         * both start and end addresses are updated to prevent corruption */
index 0aa13761de6ec3168c38569dd2a9ee479689cdfb..798144a4eedd2094fa39c147bdfb108245e7f400 100644 (file)
@@ -767,7 +767,6 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
 static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
                                        unsigned long val, void *data)
 {
-       struct cpufreq_freqs *freqs = data;
        struct s3c2410fb_info *info;
        struct fb_info *fbinfo;
        long delta_f;
index 4ca5d0c8fe84a6501ca6ef4f31898c0babac2725..946a949f4c7d44cba635432f92c7591a54b773ab 100644 (file)
@@ -1019,12 +1019,13 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
        unsigned int offset;
 
        /* Calculate the offset */
-       if (var->bits_per_pixel == 0) {
-               offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
+       if (info->var.bits_per_pixel == 0) {
+               offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
+                      + (var->xoffset / 2);
                offset = offset >> 2;
        } else {
                offset = (var->yoffset * info->fix.line_length) +
-                        (var->xoffset * var->bits_per_pixel / 8);
+                        (var->xoffset * info->var.bits_per_pixel / 8);
                offset = offset >> 2;
        }
 
@@ -1504,7 +1505,7 @@ static struct pci_driver s3fb_pci_driver = {
        .resume         = s3_pci_resume,
 };
 
-/* Parse user speficied options */
+/* Parse user specified options */
 
 #ifndef MODULE
 static int  __init s3fb_setup(char *options)
index 4de541ca9c52c14d38cb95762ba86034e71d59fd..beb495044b240e5b2edc3f98656845756279e80c 100644 (file)
@@ -1477,15 +1477,9 @@ static void savagefb_set_par_int(struct savagefb_par  *par, struct savage_reg *r
        vgaHWProtect(par, 0);
 }
 
-static void savagefb_update_start(struct savagefb_par      *par,
-                                 struct fb_var_screeninfo *var)
+static void savagefb_update_start(struct savagefb_par *par, int base)
 {
-       int base;
-
-       base = ((var->yoffset * var->xres_virtual + (var->xoffset & ~1))
-               * ((var->bits_per_pixel+7) / 8)) >> 2;
-
-       /* now program the start address registers */
+       /* program the start address registers */
        vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
        vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
        vga_out8(0x3d4, 0x69, par);
@@ -1550,8 +1544,12 @@ static int savagefb_pan_display(struct fb_var_screeninfo *var,
                                struct fb_info           *info)
 {
        struct savagefb_par *par = info->par;
+       int base;
+
+       base = (var->yoffset * info->fix.line_length
+            + (var->xoffset & ~1) * ((info->var.bits_per_pixel+7) / 8)) >> 2;
 
-       savagefb_update_start(par, var);
+       savagefb_update_start(par, base);
        return 0;
 }
 
index 75259845933deb53ab030a2067bb52e69259f673..078ca2167d6f9754a3fc9ad26582643b82e34c8a 100644 (file)
@@ -1333,19 +1333,14 @@ sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
 }
 
 static int
-sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+sisfb_pan_var(struct sis_video_info *ivideo, struct fb_info *info,
+             struct fb_var_screeninfo *var)
 {
-       if(var->xoffset > (var->xres_virtual - var->xres)) {
-               return -EINVAL;
-       }
-       if(var->yoffset > (var->yres_virtual - var->yres)) {
-               return -EINVAL;
-       }
-
-       ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;
+       ivideo->current_base = var->yoffset * info->var.xres_virtual
+                            + var->xoffset;
 
        /* calculate base bpp dep. */
-       switch(var->bits_per_pixel) {
+       switch (info->var.bits_per_pixel) {
        case 32:
                break;
        case 16:
@@ -1635,20 +1630,15 @@ sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
        struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
        int err;
 
-       if(var->xoffset > (var->xres_virtual - var->xres))
-               return -EINVAL;
-
-       if(var->yoffset > (var->yres_virtual - var->yres))
-               return -EINVAL;
-
-       if(var->vmode & FB_VMODE_YWRAP)
+       if (var->vmode & FB_VMODE_YWRAP)
                return -EINVAL;
 
-       if(var->xoffset + info->var.xres > info->var.xres_virtual ||
-          var->yoffset + info->var.yres > info->var.yres_virtual)
+       if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+           var->yoffset + info->var.yres > info->var.yres_virtual)
                return -EINVAL;
 
-       if((err = sisfb_pan_var(ivideo, var)) < 0)
+       err = sisfb_pan_var(ivideo, info, var);
+       if (err < 0)
                return err;
 
        info->var.xoffset = var->xoffset;
index 89158bc71da2b3ea982d355c2e6ee0dfeaee7244..30f7a815a62bc0f36813a644ad1819d210958ca5 100644 (file)
@@ -989,7 +989,7 @@ static struct platform_device *xxxfb_device;
  */
 int __init xxxfb_setup(char *options)
 {
-    /* Parse user speficied options (`video=xxxfb:') */
+    /* Parse user specified options (`video=xxxfb:') */
 }
 #endif /* MODULE */
 
index 6294dca955005988f384fbf0bdae104f43c8037d..a78254cf8e83eb971db5bd7f6cb499745a6741f6 100644 (file)
@@ -582,7 +582,7 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
 {
        struct sm501fb_par  *par = info->par;
        struct sm501fb_info *fbi = par->info;
-       unsigned int bytes_pixel = var->bits_per_pixel / 8;
+       unsigned int bytes_pixel = info->var.bits_per_pixel / 8;
        unsigned long reg;
        unsigned long xoffs;
 
@@ -614,10 +614,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
        struct sm501fb_info *fbi = par->info;
        unsigned long reg;
 
-       reg = var->xoffset | (var->xres_virtual << 16);
+       reg = var->xoffset | (info->var.xres_virtual << 16);
        smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
 
-       reg = var->yoffset | (var->yres_virtual << 16);
+       reg = var->yoffset | (info->var.yres_virtual << 16);
        smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
 
        sm501fb_sync_regs(fbi);
index c6c77562839d9663cef133f9b23e0d1607a5d2c8..34cf019bba44b64dc9c5a09ec4683efac8ff262c 100644 (file)
@@ -987,8 +987,8 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var,
        unsigned int offset;
 
        debug("enter\n");
-       offset = (var->xoffset + (var->yoffset * var->xres_virtual))
-               * var->bits_per_pixel / 32;
+       offset = (var->xoffset + (var->yoffset * info->var.xres_virtual))
+               * info->var.bits_per_pixel / 32;
        set_screen_start(par, offset);
        debug("exit\n");
        return 0;
index 087fc9960bb9bbb2d1b60136631f815dd2325685..ab19504a35ba0c26f87a498dd0398cfa725a9b0a 100644 (file)
@@ -48,13 +48,22 @@ static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
                FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR;
 
 /*
- * There are many DisplayLink-based products, all with unique PIDs. We are able
- * to support all volume ones (circa 2009) with a single driver, so we match
- * globally on VID. TODO: Probe() needs to detect when we might be running
- * "future" chips, and bail on those, so a compatible driver can match.
+ * There are many DisplayLink-based graphics products, all with unique PIDs.
+ * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff)
+ * We also require a match on SubClass (0x00) and Protocol (0x00),
+ * which is compatible with all known USB 2.0 era graphics chips and firmware,
+ * but allows DisplayLink to increment those for any future incompatible chips
  */
 static struct usb_device_id id_table[] = {
-       {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
+       {.idVendor = 0x17e9,
+        .bInterfaceClass = 0xff,
+        .bInterfaceSubClass = 0x00,
+        .bInterfaceProtocol = 0x00,
+        .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
+               USB_DEVICE_ID_MATCH_INT_CLASS |
+               USB_DEVICE_ID_MATCH_INT_SUBCLASS |
+               USB_DEVICE_ID_MATCH_INT_PROTOCOL,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -1548,7 +1557,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,
        /* We don't register a new USB class. Our client interface is fbdev */
 
        /* allocates framebuffer driver structure, not framebuffer memory */
-       info = framebuffer_alloc(0, &usbdev->dev);
+       info = framebuffer_alloc(0, &interface->dev);
        if (!info) {
                retval = -ENOMEM;
                pr_err("framebuffer_alloc failed\n");
index 6b52bf65f0b57fc3ddced265a76a8ce5b03b0f6e..3f5a041601dafd77a6088096f6d5dab6331461d1 100644 (file)
@@ -555,7 +555,7 @@ static int __init valkyrie_init_info(struct fb_info *info,
 
 
 /*
- * Parse user speficied options (`video=valkyriefb:')
+ * Parse user specified options (`video=valkyriefb:')
  */
 int __init valkyriefb_setup(char *options)
 {
index bc67251f1a2f1d0e3662d4bec1f46f91bd2884d8..bf2f78065cf97d8d0bcdf492087244946783e99c 100644 (file)
@@ -395,8 +395,8 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
                    || var->xoffset)
                        return -EINVAL;
        } else {
-               if (var->xoffset + var->xres > info->var.xres_virtual ||
-                   var->yoffset + var->yres > info->var.yres_virtual)
+               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+                   var->yoffset + info->var.yres > info->var.yres_virtual)
                        return -EINVAL;
        }
        info->var.xoffset = var->xoffset;
index 305c975b1787ea0628d600d2ac89c89cd0afdee9..0267acd8dc832690e3f02709a9e99361a8979805 100644 (file)
@@ -207,7 +207,7 @@ static void vga16fb_pan_var(struct fb_info *info,
         * granularity if someone supports xoffset in bit resolution */
        vga_io_r(VGA_IS1_RC);           /* reset flip-flop */
        vga_io_w(VGA_ATT_IW, VGA_ATC_PEL);
-       if (var->bits_per_pixel == 8)
+       if (info->var.bits_per_pixel == 8)
                vga_io_w(VGA_ATT_IW, (xoffset & 3) << 1);
        else
                vga_io_w(VGA_ATT_IW, xoffset & 7);
index b1f364745ca007d8774566955d6f0d8bdf28b87b..9138e517267c1e67cfeed4db7ad111dd379eb426 100644 (file)
@@ -172,30 +172,20 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
 }
 
 /* DVI Set Mode */
-void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
-       int set_iga)
+void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
 {
-       struct VideoModeTable *rb_mode;
-       struct crt_mode_table *pDviTiming;
-       unsigned long desirePixelClock, maxPixelClock;
-       pDviTiming = mode->crtc;
-       desirePixelClock = pDviTiming->refresh_rate
-               * pDviTiming->crtc.hor_total * pDviTiming->crtc.ver_total
-               / 1000000;
-       maxPixelClock = (unsigned long)viaparinfo->
-               tmds_setting_info->max_pixel_clock;
-
-       DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
-
-       if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
-               rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
-                       mode->crtc[0].crtc.ver_addr);
-               if (rb_mode) {
-                       mode = rb_mode;
-                       pDviTiming = rb_mode->crtc;
-               }
+       struct fb_var_screeninfo dvi_var = *var;
+       struct crt_mode_table *rb_mode;
+       int maxPixelClock;
+
+       maxPixelClock = viaparinfo->shared->tmds_setting_info.max_pixel_clock;
+       if (maxPixelClock && PICOS2KHZ(var->pixclock) / 1000 > maxPixelClock) {
+               rb_mode = viafb_get_best_rb_mode(var->xres, var->yres, 60);
+               if (rb_mode)
+                       viafb_fill_var_timing_info(&dvi_var, rb_mode);
        }
-       viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
+
+       viafb_fill_crtc_timing(&dvi_var, iga);
 }
 
 /* Sense DVI Connector */
index f473dd010977ba1222da41a8f04878f124317a51..e2116aaf797a23973c91baefaf837dfe14828935 100644 (file)
@@ -59,7 +59,6 @@ void viafb_dvi_enable(void);
 bool __devinit viafb_tmds_trasmitter_identify(void);
 void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
        struct tmds_setting_information *tmds_setting);
-void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp,
-       int set_iga);
+void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga);
 
 #endif /* __DVI_H__ */
index e10d8249534c682543f0a43cfb9398240e357219..3102171c16743200ce3fc8e1462a00ffe1839fff 100644 (file)
@@ -35,6 +35,8 @@ int viafb_LCD_ON ;
 int viafb_LCD2_ON;
 int viafb_SAMM_ON;
 int viafb_dual_fb;
+unsigned int viafb_second_xres = 640;
+unsigned int viafb_second_yres = 480;
 int viafb_hotplug_Xres = 640;
 int viafb_hotplug_Yres = 480;
 int viafb_hotplug_bpp = 32;
index ff969dc3459352bbfea5df7dec88e111576584c3..275dbbbd6b81227ac690028588ac24c7691ffe8a 100644 (file)
@@ -67,6 +67,8 @@ extern int viafb_lcd_dsp_method;
 extern int viafb_lcd_mode;
 
 extern int viafb_CRT_ON;
+extern unsigned int viafb_second_xres;
+extern unsigned int viafb_second_yres;
 extern int viafb_hotplug_Xres;
 extern int viafb_hotplug_Yres;
 extern int viafb_hotplug_bpp;
index 47b13535ed2b6279a568a3f7c0b7ed00edd2a8c3..d5aaca9cfa7e2b7b6a4e5770b5965cbc199e262a 100644 (file)
@@ -191,67 +191,6 @@ static struct fetch_count fetch_count_reg = {
        {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
 };
 
-static struct iga1_crtc_timing iga1_crtc_reg = {
-       /* IGA1 Horizontal Total */
-       {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
-       /* IGA1 Horizontal Addressable Video */
-       {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
-       /* IGA1 Horizontal Blank Start */
-       {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
-       /* IGA1 Horizontal Blank End */
-       {IGA1_HOR_BLANK_END_REG_NUM,
-        {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
-       /* IGA1 Horizontal Sync Start */
-       {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
-       /* IGA1 Horizontal Sync End */
-       {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
-       /* IGA1 Vertical Total */
-       {IGA1_VER_TOTAL_REG_NUM,
-        {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
-       /* IGA1 Vertical Addressable Video */
-       {IGA1_VER_ADDR_REG_NUM,
-        {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
-       /* IGA1 Vertical Blank Start */
-       {IGA1_VER_BLANK_START_REG_NUM,
-        {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
-       /* IGA1 Vertical Blank End */
-       {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
-       /* IGA1 Vertical Sync Start */
-       {IGA1_VER_SYNC_START_REG_NUM,
-        {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
-       /* IGA1 Vertical Sync End */
-       {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
-};
-
-static struct iga2_crtc_timing iga2_crtc_reg = {
-       /* IGA2 Horizontal Total */
-       {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
-       /* IGA2 Horizontal Addressable Video */
-       {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
-       /* IGA2 Horizontal Blank Start */
-       {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
-       /* IGA2 Horizontal Blank End */
-       {IGA2_HOR_BLANK_END_REG_NUM,
-        {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
-       /* IGA2 Horizontal Sync Start */
-       {IGA2_HOR_SYNC_START_REG_NUM,
-        {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
-       /* IGA2 Horizontal Sync End */
-       {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
-       /* IGA2 Vertical Total */
-       {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
-       /* IGA2 Vertical Addressable Video */
-       {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
-       /* IGA2 Vertical Blank Start */
-       {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
-       /* IGA2 Vertical Blank End */
-       {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
-       /* IGA2 Vertical Sync Start */
-       {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
-       /* IGA2 Vertical Sync End */
-       {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
-};
-
 static struct rgbLUT palLUT_table[] = {
        /* {R,G,B} */
        /* Index 0x00~0x03 */
@@ -1528,302 +1467,40 @@ void viafb_set_vclock(u32 clk, int set_iga)
        via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
 }
 
-void viafb_load_crtc_timing(struct display_timing device_timing,
-       int set_iga)
+static struct display_timing var_to_timing(const struct fb_var_screeninfo *var)
 {
-       int i;
-       int viafb_load_reg_num = 0;
-       int reg_value = 0;
-       struct io_register *reg = NULL;
-
-       viafb_unlock_crt();
-
-       for (i = 0; i < 12; i++) {
-               if (set_iga == IGA1) {
-                       switch (i) {
-                       case H_TOTAL_INDEX:
-                               reg_value =
-                                   IGA1_HOR_TOTAL_FORMULA(device_timing.
-                                                          hor_total);
-                               viafb_load_reg_num =
-                                       iga1_crtc_reg.hor_total.reg_num;
-                               reg = iga1_crtc_reg.hor_total.reg;
-                               break;
-                       case H_ADDR_INDEX:
-                               reg_value =
-                                   IGA1_HOR_ADDR_FORMULA(device_timing.
-                                                         hor_addr);
-                               viafb_load_reg_num =
-                                       iga1_crtc_reg.hor_addr.reg_num;
-                               reg = iga1_crtc_reg.hor_addr.reg;
-                               break;
-                       case H_BLANK_START_INDEX:
-                               reg_value =
-                                   IGA1_HOR_BLANK_START_FORMULA
-                                   (device_timing.hor_blank_start);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.hor_blank_start.reg_num;
-                               reg = iga1_crtc_reg.hor_blank_start.reg;
-                               break;
-                       case H_BLANK_END_INDEX:
-                               reg_value =
-                                   IGA1_HOR_BLANK_END_FORMULA
-                                   (device_timing.hor_blank_start,
-                                    device_timing.hor_blank_end);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.hor_blank_end.reg_num;
-                               reg = iga1_crtc_reg.hor_blank_end.reg;
-                               break;
-                       case H_SYNC_START_INDEX:
-                               reg_value =
-                                   IGA1_HOR_SYNC_START_FORMULA
-                                   (device_timing.hor_sync_start);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.hor_sync_start.reg_num;
-                               reg = iga1_crtc_reg.hor_sync_start.reg;
-                               break;
-                       case H_SYNC_END_INDEX:
-                               reg_value =
-                                   IGA1_HOR_SYNC_END_FORMULA
-                                   (device_timing.hor_sync_start,
-                                    device_timing.hor_sync_end);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.hor_sync_end.reg_num;
-                               reg = iga1_crtc_reg.hor_sync_end.reg;
-                               break;
-                       case V_TOTAL_INDEX:
-                               reg_value =
-                                   IGA1_VER_TOTAL_FORMULA(device_timing.
-                                                          ver_total);
-                               viafb_load_reg_num =
-                                       iga1_crtc_reg.ver_total.reg_num;
-                               reg = iga1_crtc_reg.ver_total.reg;
-                               break;
-                       case V_ADDR_INDEX:
-                               reg_value =
-                                   IGA1_VER_ADDR_FORMULA(device_timing.
-                                                         ver_addr);
-                               viafb_load_reg_num =
-                                       iga1_crtc_reg.ver_addr.reg_num;
-                               reg = iga1_crtc_reg.ver_addr.reg;
-                               break;
-                       case V_BLANK_START_INDEX:
-                               reg_value =
-                                   IGA1_VER_BLANK_START_FORMULA
-                                   (device_timing.ver_blank_start);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.ver_blank_start.reg_num;
-                               reg = iga1_crtc_reg.ver_blank_start.reg;
-                               break;
-                       case V_BLANK_END_INDEX:
-                               reg_value =
-                                   IGA1_VER_BLANK_END_FORMULA
-                                   (device_timing.ver_blank_start,
-                                    device_timing.ver_blank_end);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.ver_blank_end.reg_num;
-                               reg = iga1_crtc_reg.ver_blank_end.reg;
-                               break;
-                       case V_SYNC_START_INDEX:
-                               reg_value =
-                                   IGA1_VER_SYNC_START_FORMULA
-                                   (device_timing.ver_sync_start);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.ver_sync_start.reg_num;
-                               reg = iga1_crtc_reg.ver_sync_start.reg;
-                               break;
-                       case V_SYNC_END_INDEX:
-                               reg_value =
-                                   IGA1_VER_SYNC_END_FORMULA
-                                   (device_timing.ver_sync_start,
-                                    device_timing.ver_sync_end);
-                               viafb_load_reg_num =
-                                   iga1_crtc_reg.ver_sync_end.reg_num;
-                               reg = iga1_crtc_reg.ver_sync_end.reg;
-                               break;
-
-                       }
-               }
-
-               if (set_iga == IGA2) {
-                       switch (i) {
-                       case H_TOTAL_INDEX:
-                               reg_value =
-                                   IGA2_HOR_TOTAL_FORMULA(device_timing.
-                                                          hor_total);
-                               viafb_load_reg_num =
-                                       iga2_crtc_reg.hor_total.reg_num;
-                               reg = iga2_crtc_reg.hor_total.reg;
-                               break;
-                       case H_ADDR_INDEX:
-                               reg_value =
-                                   IGA2_HOR_ADDR_FORMULA(device_timing.
-                                                         hor_addr);
-                               viafb_load_reg_num =
-                                       iga2_crtc_reg.hor_addr.reg_num;
-                               reg = iga2_crtc_reg.hor_addr.reg;
-                               break;
-                       case H_BLANK_START_INDEX:
-                               reg_value =
-                                   IGA2_HOR_BLANK_START_FORMULA
-                                   (device_timing.hor_blank_start);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.hor_blank_start.reg_num;
-                               reg = iga2_crtc_reg.hor_blank_start.reg;
-                               break;
-                       case H_BLANK_END_INDEX:
-                               reg_value =
-                                   IGA2_HOR_BLANK_END_FORMULA
-                                   (device_timing.hor_blank_start,
-                                    device_timing.hor_blank_end);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.hor_blank_end.reg_num;
-                               reg = iga2_crtc_reg.hor_blank_end.reg;
-                               break;
-                       case H_SYNC_START_INDEX:
-                               reg_value =
-                                   IGA2_HOR_SYNC_START_FORMULA
-                                   (device_timing.hor_sync_start);
-                               if (UNICHROME_CN700 <=
-                                       viaparinfo->chip_info->gfx_chip_name)
-                                       viafb_load_reg_num =
-                                           iga2_crtc_reg.hor_sync_start.
-                                           reg_num;
-                               else
-                                       viafb_load_reg_num = 3;
-                               reg = iga2_crtc_reg.hor_sync_start.reg;
-                               break;
-                       case H_SYNC_END_INDEX:
-                               reg_value =
-                                   IGA2_HOR_SYNC_END_FORMULA
-                                   (device_timing.hor_sync_start,
-                                    device_timing.hor_sync_end);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.hor_sync_end.reg_num;
-                               reg = iga2_crtc_reg.hor_sync_end.reg;
-                               break;
-                       case V_TOTAL_INDEX:
-                               reg_value =
-                                   IGA2_VER_TOTAL_FORMULA(device_timing.
-                                                          ver_total);
-                               viafb_load_reg_num =
-                                       iga2_crtc_reg.ver_total.reg_num;
-                               reg = iga2_crtc_reg.ver_total.reg;
-                               break;
-                       case V_ADDR_INDEX:
-                               reg_value =
-                                   IGA2_VER_ADDR_FORMULA(device_timing.
-                                                         ver_addr);
-                               viafb_load_reg_num =
-                                       iga2_crtc_reg.ver_addr.reg_num;
-                               reg = iga2_crtc_reg.ver_addr.reg;
-                               break;
-                       case V_BLANK_START_INDEX:
-                               reg_value =
-                                   IGA2_VER_BLANK_START_FORMULA
-                                   (device_timing.ver_blank_start);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.ver_blank_start.reg_num;
-                               reg = iga2_crtc_reg.ver_blank_start.reg;
-                               break;
-                       case V_BLANK_END_INDEX:
-                               reg_value =
-                                   IGA2_VER_BLANK_END_FORMULA
-                                   (device_timing.ver_blank_start,
-                                    device_timing.ver_blank_end);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.ver_blank_end.reg_num;
-                               reg = iga2_crtc_reg.ver_blank_end.reg;
-                               break;
-                       case V_SYNC_START_INDEX:
-                               reg_value =
-                                   IGA2_VER_SYNC_START_FORMULA
-                                   (device_timing.ver_sync_start);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.ver_sync_start.reg_num;
-                               reg = iga2_crtc_reg.ver_sync_start.reg;
-                               break;
-                       case V_SYNC_END_INDEX:
-                               reg_value =
-                                   IGA2_VER_SYNC_END_FORMULA
-                                   (device_timing.ver_sync_start,
-                                    device_timing.ver_sync_end);
-                               viafb_load_reg_num =
-                                   iga2_crtc_reg.ver_sync_end.reg_num;
-                               reg = iga2_crtc_reg.ver_sync_end.reg;
-                               break;
-
-                       }
-               }
-               viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
-       }
-
-       viafb_lock_crt();
+       struct display_timing timing;
+
+       timing.hor_addr = var->xres;
+       timing.hor_sync_start = timing.hor_addr + var->right_margin;
+       timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
+       timing.hor_total = timing.hor_sync_end + var->left_margin;
+       timing.hor_blank_start = timing.hor_addr;
+       timing.hor_blank_end = timing.hor_total;
+       timing.ver_addr = var->yres;
+       timing.ver_sync_start = timing.ver_addr + var->lower_margin;
+       timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
+       timing.ver_total = timing.ver_sync_end + var->upper_margin;
+       timing.ver_blank_start = timing.ver_addr;
+       timing.ver_blank_end = timing.ver_total;
+       return timing;
 }
 
-void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
-       struct VideoModeTable *video_mode, int bpp_byte, int set_iga)
+void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga)
 {
-       struct display_timing crt_reg;
-       int i;
-       int index = 0;
-       int h_addr, v_addr;
-       u32 clock, refresh = viafb_refresh;
-
-       if (viafb_SAMM_ON && set_iga == IGA2)
-               refresh = viafb_refresh1;
-
-       for (i = 0; i < video_mode->mode_array; i++) {
-               index = i;
-
-               if (crt_table[i].refresh_rate == refresh)
-                       break;
-       }
+       struct display_timing crt_reg = var_to_timing(var);
 
-       crt_reg = crt_table[index].crtc;
+       if (iga == IGA1)
+               via_set_primary_timing(&crt_reg);
+       else if (iga == IGA2)
+               via_set_secondary_timing(&crt_reg);
 
-       /* Mode 640x480 has border, but LCD/DFP didn't have border. */
-       /* So we would delete border. */
-       if ((viafb_LCD_ON | viafb_DVI_ON)
-           && video_mode->crtc[0].crtc.hor_addr == 640
-           && video_mode->crtc[0].crtc.ver_addr == 480
-           && refresh == 60) {
-               /* The border is 8 pixels. */
-               crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
-
-               /* Blanking time should add left and right borders. */
-               crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
-       }
-
-       h_addr = crt_reg.hor_addr;
-       v_addr = crt_reg.ver_addr;
-       if (set_iga == IGA1) {
-               viafb_unlock_crt();
-               viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
-       }
-
-       switch (set_iga) {
-       case IGA1:
-               viafb_load_crtc_timing(crt_reg, IGA1);
-               break;
-       case IGA2:
-               viafb_load_crtc_timing(crt_reg, IGA2);
-               break;
-       }
-
-       viafb_lock_crt();
-       viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
-       viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
-
-       /* load FIFO */
-       if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
-           && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
-               viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
-
-       clock = crt_reg.hor_total * crt_reg.ver_total
-               * crt_table[index].refresh_rate;
-       viafb_set_vclock(clock, set_iga);
+       viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);
+       if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266
+               && viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)
+               viafb_load_FIFO_reg(iga, var->xres, var->yres);
 
+       viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
 }
 
 void __devinit viafb_init_chip_info(int chip_type)
@@ -2092,23 +1769,9 @@ static u8 get_sync(struct fb_info *info)
        return polarity;
 }
 
-int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
-       struct VideoModeTable *vmode_tbl1, int video_bpp1)
+static void hw_init(void)
 {
-       int i, j;
-       int port;
-       u32 devices = viaparinfo->shared->iga1_devices
-               | viaparinfo->shared->iga2_devices;
-       u8 value, index, mask;
-       struct crt_mode_table *crt_timing;
-       struct crt_mode_table *crt_timing1 = NULL;
-
-       device_screen_off();
-       crt_timing = vmode_tbl->crtc;
-
-       if (viafb_SAMM_ON == 1) {
-               crt_timing1 = vmode_tbl1->crtc;
-       }
+       int i;
 
        inb(VIAStatus);
        outb(0x00, VIAAR);
@@ -2147,9 +1810,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
                break;
        }
 
+       /* probably this should go to the scaling code one day */
        viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
-       device_off();
-       via_set_state(devices, VIA_STATE_OFF);
 
        /* Fill VPIT Parameters */
        /* Write Misc Register */
@@ -2175,12 +1837,29 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
        inb(VIAStatus);
        outb(0x20, VIAAR);
 
+       load_fix_bit_crtc_reg();
+}
+
+int viafb_setmode(int video_bpp, int video_bpp1)
+{
+       int j;
+       int port;
+       u32 devices = viaparinfo->shared->iga1_devices
+               | viaparinfo->shared->iga2_devices;
+       u8 value, index, mask;
+       struct fb_var_screeninfo var2;
+
+       device_screen_off();
+       device_off();
+       via_set_state(devices, VIA_STATE_OFF);
+
+       hw_init();
+
        /* Update Patch Register */
 
        if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
-           || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
-           && vmode_tbl->crtc[0].crtc.hor_addr == 1024
-           && vmode_tbl->crtc[0].crtc.ver_addr == 768) {
+               || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
+               && viafbinfo->var.xres == 1024 && viafbinfo->var.yres == 768) {
                for (j = 0; j < res_patch_table[0].table_length; j++) {
                        index = res_patch_table[0].io_reg_table[j].index;
                        port = res_patch_table[0].io_reg_table[j].port;
@@ -2190,7 +1869,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
                }
        }
 
-       load_fix_bit_crtc_reg();
        via_set_primary_pitch(viafbinfo->fix.line_length);
        via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
                : viafbinfo->fix.line_length);
@@ -2208,23 +1886,28 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
 
        /* Clear On Screen */
 
+       if (viafb_dual_fb) {
+               var2 = viafbinfo1->var;
+       } else if (viafb_SAMM_ON) {
+               viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
+                       viafb_second_xres, viafb_second_yres, viafb_refresh1));
+               var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
+       }
+
        /* CRT set mode */
        if (viafb_CRT_ON) {
-               if (viafb_SAMM_ON &&
-                       viaparinfo->shared->iga2_devices & VIA_CRT) {
-                       viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
-                               video_bpp1 / 8, IGA2);
-               } else {
-                       viafb_fill_crtc_timing(crt_timing, vmode_tbl,
-                               video_bpp / 8,
+               if (viaparinfo->shared->iga2_devices & VIA_CRT
+                       && viafb_SAMM_ON)
+                       viafb_fill_crtc_timing(&var2, IGA2);
+               else
+                       viafb_fill_crtc_timing(&viafbinfo->var,
                                (viaparinfo->shared->iga1_devices & VIA_CRT)
                                ? IGA1 : IGA2);
-               }
 
                /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
                to 8 alignment (1368),there is several pixels (2 pixels)
                on right side of screen. */
-               if (vmode_tbl->crtc[0].crtc.hor_addr % 8) {
+               if (viafbinfo->var.xres % 8) {
                        viafb_unlock_crt();
                        viafb_write_reg(CR02, VIACR,
                                viafb_read_reg(VIACR, CR02) - 1);
@@ -2233,31 +1916,20 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
        }
 
        if (viafb_DVI_ON) {
-               if (viafb_SAMM_ON &&
-                       (viaparinfo->tmds_setting_info->iga_path == IGA2)) {
-                       viafb_dvi_set_mode(viafb_get_mode
-                                    (viaparinfo->tmds_setting_info->h_active,
-                                     viaparinfo->tmds_setting_info->
-                                     v_active),
-                                    video_bpp1, viaparinfo->
-                                    tmds_setting_info->iga_path);
-               } else {
-                       viafb_dvi_set_mode(viafb_get_mode
-                                    (viaparinfo->tmds_setting_info->h_active,
-                                     viaparinfo->
-                                     tmds_setting_info->v_active),
-                                    video_bpp, viaparinfo->
-                                    tmds_setting_info->iga_path);
-               }
+               if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
+                       && viafb_SAMM_ON)
+                       viafb_dvi_set_mode(&var2, IGA2);
+               else
+                       viafb_dvi_set_mode(&viafbinfo->var,
+                               viaparinfo->tmds_setting_info->iga_path);
        }
 
        if (viafb_LCD_ON) {
                if (viafb_SAMM_ON &&
                        (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
                        viaparinfo->lvds_setting_info->bpp = video_bpp1;
-                       viafb_lcd_set_mode(crt_timing1, viaparinfo->
-                               lvds_setting_info,
-                                    &viaparinfo->chip_info->lvds_chip_info);
+                       viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
+                               &viaparinfo->chip_info->lvds_chip_info);
                } else {
                        /* IGA1 doesn't have LCD scaling, so set it center. */
                        if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
@@ -2265,18 +1937,16 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
                                    LCD_CENTERING;
                        }
                        viaparinfo->lvds_setting_info->bpp = video_bpp;
-                       viafb_lcd_set_mode(crt_timing, viaparinfo->
-                               lvds_setting_info,
-                                    &viaparinfo->chip_info->lvds_chip_info);
+                       viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
+                               &viaparinfo->chip_info->lvds_chip_info);
                }
        }
        if (viafb_LCD2_ON) {
                if (viafb_SAMM_ON &&
                        (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
                        viaparinfo->lvds_setting_info2->bpp = video_bpp1;
-                       viafb_lcd_set_mode(crt_timing1, viaparinfo->
-                               lvds_setting_info2,
-                                    &viaparinfo->chip_info->lvds_chip_info2);
+                       viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
+                               &viaparinfo->chip_info->lvds_chip_info2);
                } else {
                        /* IGA1 doesn't have LCD scaling, so set it center. */
                        if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
@@ -2284,9 +1954,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
                                    LCD_CENTERING;
                        }
                        viaparinfo->lvds_setting_info2->bpp = video_bpp;
-                       viafb_lcd_set_mode(crt_timing, viaparinfo->
-                               lvds_setting_info2,
-                                    &viaparinfo->chip_info->lvds_chip_info2);
+                       viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
+                               &viaparinfo->chip_info->lvds_chip_info2);
                }
        }
 
@@ -2296,8 +1965,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
 
        /* If set mode normally, save resolution information for hot-plug . */
        if (!viafb_hotplug) {
-               viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr;
-               viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr;
+               viafb_hotplug_Xres = viafbinfo->var.xres;
+               viafb_hotplug_Yres = viafbinfo->var.yres;
                viafb_hotplug_bpp = video_bpp;
                viafb_hotplug_refresh = viafb_refresh;
 
@@ -2348,42 +2017,14 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
        return 1;
 }
 
-int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
-{
-       int i;
-       struct crt_mode_table *best;
-       struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
-
-       if (!vmode)
-               return RES_640X480_60HZ_PIXCLOCK;
-
-       best = &vmode->crtc[0];
-       for (i = 1; i < vmode->mode_array; i++) {
-               if (abs(vmode->crtc[i].refresh_rate - vmode_refresh)
-                       < abs(best->refresh_rate - vmode_refresh))
-                       best = &vmode->crtc[i];
-       }
-
-       return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total)
-               * 1000 / best->refresh_rate;
-}
-
 int viafb_get_refresh(int hres, int vres, u32 long_refresh)
 {
-       int i;
        struct crt_mode_table *best;
-       struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
 
-       if (!vmode)
+       best = viafb_get_best_mode(hres, vres, long_refresh);
+       if (!best)
                return 60;
 
-       best = &vmode->crtc[0];
-       for (i = 1; i < vmode->mode_array; i++) {
-               if (abs(vmode->crtc[i].refresh_rate - long_refresh)
-                       < abs(best->refresh_rate - long_refresh))
-                       best = &vmode->crtc[i];
-       }
-
        if (abs(best->refresh_rate - long_refresh) > 3) {
                if (hres == 1200 && vres == 900)
                        return 49; /* OLPC DCON only supports 50 Hz */
@@ -2485,21 +2126,14 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
 }
 
 /*According var's xres, yres fill var's other timing information*/
-void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
-       struct VideoModeTable *vmode_tbl)
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
+       struct crt_mode_table *mode)
 {
-       struct crt_mode_table *crt_timing = NULL;
        struct display_timing crt_reg;
-       int i = 0, index = 0;
-       crt_timing = vmode_tbl->crtc;
-       for (i = 0; i < vmode_tbl->mode_array; i++) {
-               index = i;
-               if (crt_timing[i].refresh_rate == refresh)
-                       break;
-       }
 
-       crt_reg = crt_timing[index].crtc;
-       var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
+       crt_reg = mode->crtc;
+       var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total)
+               * 1000 / mode->refresh_rate;
        var->left_margin =
            crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
        var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
@@ -2509,8 +2143,8 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
        var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
        var->vsync_len = crt_reg.ver_sync_end;
        var->sync = 0;
-       if (crt_timing[index].h_sync_polarity == POSITIVE)
+       if (mode->h_sync_polarity == POSITIVE)
                var->sync |= FB_SYNC_HOR_HIGH_ACT;
-       if (crt_timing[index].v_sync_polarity == POSITIVE)
+       if (mode->v_sync_polarity == POSITIVE)
                var->sync |= FB_SYNC_VERT_HIGH_ACT;
 }
index c7239eb83bae30aaad17e356b7a712d973751d50..4db5b6e8d8d092cfe4ad59f922010552277d40a0 100644 (file)
 #define VIA_HSYNC_NEGATIVE     0x01
 #define VIA_VSYNC_NEGATIVE     0x02
 
-/***************************************************
-* Definition IGA1 Design Method of CRTC Registers *
-****************************************************/
-#define IGA1_HOR_TOTAL_FORMULA(x)           (((x)/8)-5)
-#define IGA1_HOR_ADDR_FORMULA(x)            (((x)/8)-1)
-#define IGA1_HOR_BLANK_START_FORMULA(x)     (((x)/8)-1)
-#define IGA1_HOR_BLANK_END_FORMULA(x, y)     (((x+y)/8)-1)
-#define IGA1_HOR_SYNC_START_FORMULA(x)      ((x)/8)
-#define IGA1_HOR_SYNC_END_FORMULA(x, y)      ((x+y)/8)
-
-#define IGA1_VER_TOTAL_FORMULA(x)           ((x)-2)
-#define IGA1_VER_ADDR_FORMULA(x)            ((x)-1)
-#define IGA1_VER_BLANK_START_FORMULA(x)     ((x)-1)
-#define IGA1_VER_BLANK_END_FORMULA(x, y)     ((x+y)-1)
-#define IGA1_VER_SYNC_START_FORMULA(x)      ((x)-1)
-#define IGA1_VER_SYNC_END_FORMULA(x, y)      ((x+y)-1)
-
-/***************************************************
-** Definition IGA2 Design Method of CRTC Registers *
-****************************************************/
-#define IGA2_HOR_TOTAL_FORMULA(x)           ((x)-1)
-#define IGA2_HOR_ADDR_FORMULA(x)            ((x)-1)
-#define IGA2_HOR_BLANK_START_FORMULA(x)     ((x)-1)
-#define IGA2_HOR_BLANK_END_FORMULA(x, y)     ((x+y)-1)
-#define IGA2_HOR_SYNC_START_FORMULA(x)      ((x)-1)
-#define IGA2_HOR_SYNC_END_FORMULA(x, y)      ((x+y)-1)
-
-#define IGA2_VER_TOTAL_FORMULA(x)           ((x)-1)
-#define IGA2_VER_ADDR_FORMULA(x)            ((x)-1)
-#define IGA2_VER_BLANK_START_FORMULA(x)     ((x)-1)
-#define IGA2_VER_BLANK_END_FORMULA(x, y)     ((x+y)-1)
-#define IGA2_VER_SYNC_START_FORMULA(x)      ((x)-1)
-#define IGA2_VER_SYNC_END_FORMULA(x, y)      ((x+y)-1)
-
 /**********************************************************/
 /* Definition IGA2 Design Method of CRTC Shadow Registers */
 /**********************************************************/
 #define IGA2_VER_SYNC_START_SHADOW_FORMULA(x)      (x)
 #define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y)      (x+y)
 
-/* Define Register Number for IGA1 CRTC Timing */
-
-/* location: {CR00,0,7},{CR36,3,3} */
-#define IGA1_HOR_TOTAL_REG_NUM         2
-/* location: {CR01,0,7} */
-#define IGA1_HOR_ADDR_REG_NUM          1
-/* location: {CR02,0,7} */
-#define IGA1_HOR_BLANK_START_REG_NUM    1
-/* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */
-#define IGA1_HOR_BLANK_END_REG_NUM     3
-/* location: {CR04,0,7},{CR33,4,4} */
-#define IGA1_HOR_SYNC_START_REG_NUM    2
-/* location: {CR05,0,4} */
-#define IGA1_HOR_SYNC_END_REG_NUM       1
-/* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */
-#define IGA1_VER_TOTAL_REG_NUM          4
-/* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */
-#define IGA1_VER_ADDR_REG_NUM           4
-/* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */
-#define IGA1_VER_BLANK_START_REG_NUM    4
-/* location: {CR16,0,7} */
-#define IGA1_VER_BLANK_END_REG_NUM      1
-/* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */
-#define IGA1_VER_SYNC_START_REG_NUM     4
-/* location: {CR11,0,3} */
-#define IGA1_VER_SYNC_END_REG_NUM       1
-
 /* Define Register Number for IGA2 Shadow CRTC Timing */
 
 /* location: {CR6D,0,7},{CR71,3,3} */
 /* location: {CR76,0,3} */
 #define IGA2_SHADOW_VER_SYNC_END_REG_NUM    1
 
-/* Define Register Number for IGA2 CRTC Timing */
-
-/* location: {CR50,0,7},{CR55,0,3} */
-#define IGA2_HOR_TOTAL_REG_NUM          2
-/* location: {CR51,0,7},{CR55,4,6} */
-#define IGA2_HOR_ADDR_REG_NUM           2
-/* location: {CR52,0,7},{CR54,0,2} */
-#define IGA2_HOR_BLANK_START_REG_NUM    2
-/* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6]
-is reserved, so it may have problem to set 1600x1200 on IGA2. */
-/*             Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */
-#define IGA2_HOR_BLANK_END_REG_NUM      3
-/* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */
-/* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */
-#define IGA2_HOR_SYNC_START_REG_NUM     4
-
-/* location: {CR57,0,7},{CR5C,6,6} */
-#define IGA2_HOR_SYNC_END_REG_NUM       2
-/* location: {CR58,0,7},{CR5D,0,2} */
-#define IGA2_VER_TOTAL_REG_NUM          2
-/* location: {CR59,0,7},{CR5D,3,5} */
-#define IGA2_VER_ADDR_REG_NUM           2
-/* location: {CR5A,0,7},{CR5C,0,2} */
-#define IGA2_VER_BLANK_START_REG_NUM    2
-/* location: {CR5E,0,7},{CR5C,3,5} */
-#define IGA2_VER_BLANK_END_REG_NUM      2
-/* location: {CR5E,0,7},{CR5F,5,7} */
-#define IGA2_VER_SYNC_START_REG_NUM     2
-/* location: {CR5F,0,4} */
-#define IGA2_VER_SYNC_END_REG_NUM       1
-
 /* Define Fetch Count Register*/
 
 /* location: {SR1C,0,7},{SR1D,0,1} */
@@ -446,87 +354,12 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */
 /* location: {CR78,0,7},{CR79,6,7} */
 #define LCD_VER_SCALING_FACTOR_REG_NUM_CLE  2
 
-/************************************************
- *****     Define IGA1 Display Timing       *****
- ************************************************/
 struct io_register {
        u8 io_addr;
        u8 start_bit;
        u8 end_bit;
 };
 
-/* IGA1 Horizontal Total */
-struct iga1_hor_total {
-       int reg_num;
-       struct io_register reg[IGA1_HOR_TOTAL_REG_NUM];
-};
-
-/* IGA1 Horizontal Addressable Video */
-struct iga1_hor_addr {
-       int reg_num;
-       struct io_register reg[IGA1_HOR_ADDR_REG_NUM];
-};
-
-/* IGA1 Horizontal Blank Start */
-struct iga1_hor_blank_start {
-       int reg_num;
-       struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM];
-};
-
-/* IGA1 Horizontal Blank End */
-struct iga1_hor_blank_end {
-       int reg_num;
-       struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM];
-};
-
-/* IGA1 Horizontal Sync Start */
-struct iga1_hor_sync_start {
-       int reg_num;
-       struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM];
-};
-
-/* IGA1 Horizontal Sync End */
-struct iga1_hor_sync_end {
-       int reg_num;
-       struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM];
-};
-
-/* IGA1 Vertical Total */
-struct iga1_ver_total {
-       int reg_num;
-       struct io_register reg[IGA1_VER_TOTAL_REG_NUM];
-};
-
-/* IGA1 Vertical Addressable Video */
-struct iga1_ver_addr {
-       int reg_num;
-       struct io_register reg[IGA1_VER_ADDR_REG_NUM];
-};
-
-/* IGA1 Vertical Blank Start */
-struct iga1_ver_blank_start {
-       int reg_num;
-       struct io_register reg[IGA1_VER_BLANK_START_REG_NUM];
-};
-
-/* IGA1 Vertical Blank End */
-struct iga1_ver_blank_end {
-       int reg_num;
-       struct io_register reg[IGA1_VER_BLANK_END_REG_NUM];
-};
-
-/* IGA1 Vertical Sync Start */
-struct iga1_ver_sync_start {
-       int reg_num;
-       struct io_register reg[IGA1_VER_SYNC_START_REG_NUM];
-};
-
-/* IGA1 Vertical Sync End */
-struct iga1_ver_sync_end {
-       int reg_num;
-       struct io_register reg[IGA1_VER_SYNC_END_REG_NUM];
-};
-
 /*****************************************************
 **      Define IGA2 Shadow Display Timing         ****
 *****************************************************/
@@ -579,82 +412,6 @@ struct iga2_shadow_ver_sync_end {
        struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM];
 };
 
-/*****************************************************
-**      Define IGA2 Display Timing                ****
-******************************************************/
-
-/* IGA2 Horizontal Total */
-struct iga2_hor_total {
-       int reg_num;
-       struct io_register reg[IGA2_HOR_TOTAL_REG_NUM];
-};
-
-/* IGA2 Horizontal Addressable Video */
-struct iga2_hor_addr {
-       int reg_num;
-       struct io_register reg[IGA2_HOR_ADDR_REG_NUM];
-};
-
-/* IGA2 Horizontal Blank Start */
-struct iga2_hor_blank_start {
-       int reg_num;
-       struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM];
-};
-
-/* IGA2 Horizontal Blank End */
-struct iga2_hor_blank_end {
-       int reg_num;
-       struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM];
-};
-
-/* IGA2 Horizontal Sync Start */
-struct iga2_hor_sync_start {
-       int reg_num;
-       struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM];
-};
-
-/* IGA2 Horizontal Sync End */
-struct iga2_hor_sync_end {
-       int reg_num;
-       struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM];
-};
-
-/* IGA2 Vertical Total */
-struct iga2_ver_total {
-       int reg_num;
-       struct io_register reg[IGA2_VER_TOTAL_REG_NUM];
-};
-
-/* IGA2 Vertical Addressable Video */
-struct iga2_ver_addr {
-       int reg_num;
-       struct io_register reg[IGA2_VER_ADDR_REG_NUM];
-};
-
-/* IGA2 Vertical Blank Start */
-struct iga2_ver_blank_start {
-       int reg_num;
-       struct io_register reg[IGA2_VER_BLANK_START_REG_NUM];
-};
-
-/* IGA2 Vertical Blank End */
-struct iga2_ver_blank_end {
-       int reg_num;
-       struct io_register reg[IGA2_VER_BLANK_END_REG_NUM];
-};
-
-/* IGA2 Vertical Sync Start */
-struct iga2_ver_sync_start {
-       int reg_num;
-       struct io_register reg[IGA2_VER_SYNC_START_REG_NUM];
-};
-
-/* IGA2 Vertical Sync End */
-struct iga2_ver_sync_end {
-       int reg_num;
-       struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
-};
-
 /* IGA1 Fetch Count Register */
 struct iga1_fetch_count {
        int reg_num;
@@ -817,21 +574,6 @@ struct display_queue_expire_num {
         iga2_display_queue_expire_num_reg;
 };
 
-struct iga1_crtc_timing {
-       struct iga1_hor_total hor_total;
-       struct iga1_hor_addr hor_addr;
-       struct iga1_hor_blank_start hor_blank_start;
-       struct iga1_hor_blank_end hor_blank_end;
-       struct iga1_hor_sync_start hor_sync_start;
-       struct iga1_hor_sync_end hor_sync_end;
-       struct iga1_ver_total ver_total;
-       struct iga1_ver_addr ver_addr;
-       struct iga1_ver_blank_start ver_blank_start;
-       struct iga1_ver_blank_end ver_blank_end;
-       struct iga1_ver_sync_start ver_sync_start;
-       struct iga1_ver_sync_end ver_sync_end;
-};
-
 struct iga2_shadow_crtc_timing {
        struct iga2_shadow_hor_total hor_total_shadow;
        struct iga2_shadow_hor_blank_end hor_blank_end_shadow;
@@ -843,21 +585,6 @@ struct iga2_shadow_crtc_timing {
        struct iga2_shadow_ver_sync_end ver_sync_end_shadow;
 };
 
-struct iga2_crtc_timing {
-       struct iga2_hor_total hor_total;
-       struct iga2_hor_addr hor_addr;
-       struct iga2_hor_blank_start hor_blank_start;
-       struct iga2_hor_blank_end hor_blank_end;
-       struct iga2_hor_sync_start hor_sync_start;
-       struct iga2_hor_sync_end hor_sync_end;
-       struct iga2_ver_total ver_total;
-       struct iga2_ver_addr ver_addr;
-       struct iga2_ver_blank_start ver_blank_start;
-       struct iga2_ver_blank_end ver_blank_end;
-       struct iga2_ver_sync_start ver_sync_start;
-       struct iga2_ver_sync_end ver_sync_end;
-};
-
 /* device ID */
 #define CLE266_FUNCTION3    0x3123
 #define KM400_FUNCTION3     0x3205
@@ -910,9 +637,7 @@ extern int viafb_LCD_ON;
 extern int viafb_DVI_ON;
 extern int viafb_hotplug;
 
-void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
-       struct VideoModeTable *video_mode, int bpp_byte, int set_iga);
-
+void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga);
 void viafb_set_vclock(u32 CLK, int set_iga);
 void viafb_load_reg(int timing_value, int viafb_load_reg_num,
        struct io_register *reg,
@@ -932,13 +657,11 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
 void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
                                        *p_gfx_dpa_setting);
 
-int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
-       struct VideoModeTable *vmode_tbl1, int video_bpp1);
-void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
-       struct VideoModeTable *vmode_tbl);
+int viafb_setmode(int video_bpp, int video_bpp1);
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
+       struct crt_mode_table *mode);
 void __devinit viafb_init_chip_info(int chip_type);
 void __devinit viafb_init_dac(int set_iga);
-int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
 int viafb_get_refresh(int hres, int vres, u32 float_refresh);
 void viafb_update_device_setting(int hres, int vres, int bpp, int flag);
 
index 6e06981d638be99f44c0b5ef9fc5ef2d90cfb883..5f3b4e394e82133c8668bbdaada42d523fed2bc7 100644 (file)
@@ -548,9 +548,8 @@ static void lcd_patch_skew(struct lvds_setting_information
 }
 
 /* LCD Set Mode */
-void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
-                 struct lvds_setting_information *plvds_setting_info,
-                 struct lvds_chip_information *plvds_chip_info)
+void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info)
 {
        int set_iga = plvds_setting_info->iga_path;
        int mode_bpp = plvds_setting_info->bpp;
@@ -559,16 +558,15 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
        int panel_hres = plvds_setting_info->lcd_panel_hres;
        int panel_vres = plvds_setting_info->lcd_panel_vres;
        u32 clock;
-       struct display_timing mode_crt_reg, panel_crt_reg;
-       struct crt_mode_table *panel_crt_table = NULL;
-       struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
-               panel_vres);
+       struct display_timing mode_crt_reg, panel_crt_reg, timing;
+       struct crt_mode_table *mode_crt_table, *panel_crt_table;
 
        DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
        /* Get mode table */
+       mode_crt_table = viafb_get_best_mode(set_hres, set_vres, 60);
        mode_crt_reg = mode_crt_table->crtc;
        /* Get panel table Pointer */
-       panel_crt_table = vmode_tbl->crtc;
+       panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60);
        panel_crt_reg = panel_crt_table->crtc;
        DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
        if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
@@ -576,31 +574,28 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
        clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total
                * panel_crt_table->refresh_rate;
        plvds_setting_info->vclk = clock;
-       if (set_iga == IGA1) {
-               /* IGA1 doesn't have LCD scaling, so set it as centering. */
-               viafb_load_crtc_timing(lcd_centering_timging
-                                (mode_crt_reg, panel_crt_reg), IGA1);
+
+       if (set_iga == IGA2 && (set_hres < panel_hres || set_vres < panel_vres)
+               && plvds_setting_info->display_method == LCD_EXPANDSION) {
+               timing = panel_crt_reg;
+               load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres);
        } else {
-               /* Expansion */
-               if (plvds_setting_info->display_method == LCD_EXPANDSION
-                       && (set_hres < panel_hres || set_vres < panel_vres)) {
-                       /* expansion timing IGA2 loaded panel set timing*/
-                       viafb_load_crtc_timing(panel_crt_reg, IGA2);
-                       DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
-                       load_lcd_scaling(set_hres, set_vres, panel_hres,
-                                        panel_vres);
-                       DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
-               } else {        /* Centering */
-                       /* centering timing IGA2 always loaded panel
-                          and mode releative timing */
-                       viafb_load_crtc_timing(lcd_centering_timging
-                                        (mode_crt_reg, panel_crt_reg), IGA2);
-                       viafb_write_reg_mask(CR79, VIACR, 0x00,
+               timing = lcd_centering_timging(mode_crt_reg, panel_crt_reg);
+               if (set_iga == IGA2)
+                       /* disable scaling */
+                       via_write_reg_mask(VIACR, 0x79, 0x00,
                                BIT0 + BIT1 + BIT2);
-                       /* LCD scaling disabled */
-               }
        }
 
+       timing.hor_blank_end += timing.hor_blank_start;
+       timing.hor_sync_end += timing.hor_sync_start;
+       timing.ver_blank_end += timing.ver_blank_start;
+       timing.ver_sync_end += timing.ver_sync_start;
+       if (set_iga == IGA1)
+               via_set_primary_timing(&timing);
+       else if (set_iga == IGA2)
+               via_set_secondary_timing(&timing);
+
        /* Fetch count for IGA2 only */
        viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
 
index 75f60a655b0e09c334a77d8418a656edefb8c467..77ca7b862e6830b9f7ddaac37551c3c2b73fc3b9 100644 (file)
@@ -76,16 +76,13 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
                                *plvds_chip_info,
                                struct lvds_setting_information
                                *plvds_setting_info);
-void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
-                 struct lvds_setting_information *plvds_setting_info,
-                 struct lvds_chip_information *plvds_chip_info);
+void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
+       struct lvds_chip_information *plvds_chip_info);
 bool __devinit viafb_lvds_trasmitter_identify(void);
 void viafb_init_lvds_output_interface(struct lvds_chip_information
                                *plvds_chip_info,
                                struct lvds_setting_information
                                *plvds_setting_info);
 bool viafb_lcd_get_mobile_state(bool *mobile);
-void viafb_load_crtc_timing(struct display_timing device_timing,
-       int set_iga);
 
 #endif /* __LCD_H__ */
index 61b0bd596b85db28553cbae06bcdeb8f6d4128ca..69d882cbe7095f0acde27c9e61e12ea3236948d8 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef __SHARE_H__
 #define __SHARE_H__
 
+#include "via_modesetting.h"
+
 /* Define Bit Field */
 #define BIT0    0x01
 #define BIT1    0x02
 #define V_SYNC_SATRT_SHADOW_INDEX   18
 #define V_SYNC_END_SHADOW_INDEX     19
 
-/* Definition Video Mode Pixel Clock (picoseconds)
-*/
-#define RES_640X480_60HZ_PIXCLOCK    39722
-
 /* LCD display method
 */
 #define     LCD_EXPANDSION              0x00
 #define     LCD_OPENLDI               0x00
 #define     LCD_SPWG                  0x01
 
-/* Define display timing
-*/
-struct display_timing {
-       u16 hor_total;
-       u16 hor_addr;
-       u16 hor_blank_start;
-       u16 hor_blank_end;
-       u16 hor_sync_start;
-       u16 hor_sync_end;
-       u16 ver_total;
-       u16 ver_addr;
-       u16 ver_blank_start;
-       u16 ver_blank_end;
-       u16 ver_sync_start;
-       u16 ver_sync_end;
-};
-
 struct crt_mode_table {
        int refresh_rate;
        int h_sync_polarity;
index eb112b62173565984c28e68b400b40f798b1877e..dd58b530c0dffde2a1f511a059cb6bc42279f7c9 100644 (file)
@@ -35,7 +35,7 @@ static struct via_port_cfg adap_configs[] = {
  * The OLPC XO-1.5 puts the camera power and reset lines onto
  * GPIO 2C.
  */
-static const struct via_port_cfg olpc_adap_configs[] = {
+static struct via_port_cfg olpc_adap_configs[] = {
        [VIA_PORT_26]   = { VIA_PORT_I2C,  VIA_MODE_I2C, VIASR, 0x26 },
        [VIA_PORT_31]   = { VIA_PORT_I2C,  VIA_MODE_I2C, VIASR, 0x31 },
        [VIA_PORT_25]   = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 },
index 3cddcff88ab90400b8bf4b58cd7f14b7bf9b099f..0e431aee17bbcc83a330ffdda6623d477a84ac8f 100644 (file)
 #include "share.h"
 #include "debug.h"
 
+
+void via_set_primary_timing(const struct display_timing *timing)
+{
+       struct display_timing raw;
+
+       raw.hor_total = timing->hor_total / 8 - 5;
+       raw.hor_addr = timing->hor_addr / 8 - 1;
+       raw.hor_blank_start = timing->hor_blank_start / 8 - 1;
+       raw.hor_blank_end = timing->hor_blank_end / 8 - 1;
+       raw.hor_sync_start = timing->hor_sync_start / 8;
+       raw.hor_sync_end = timing->hor_sync_end / 8;
+       raw.ver_total = timing->ver_total - 2;
+       raw.ver_addr = timing->ver_addr - 1;
+       raw.ver_blank_start = timing->ver_blank_start - 1;
+       raw.ver_blank_end = timing->ver_blank_end - 1;
+       raw.ver_sync_start = timing->ver_sync_start - 1;
+       raw.ver_sync_end = timing->ver_sync_end - 1;
+
+       /* unlock timing registers */
+       via_write_reg_mask(VIACR, 0x11, 0x00, 0x80);
+
+       via_write_reg(VIACR, 0x00, raw.hor_total & 0xFF);
+       via_write_reg(VIACR, 0x01, raw.hor_addr & 0xFF);
+       via_write_reg(VIACR, 0x02, raw.hor_blank_start & 0xFF);
+       via_write_reg_mask(VIACR, 0x03, raw.hor_blank_end & 0x1F, 0x1F);
+       via_write_reg(VIACR, 0x04, raw.hor_sync_start & 0xFF);
+       via_write_reg_mask(VIACR, 0x05, (raw.hor_sync_end & 0x1F)
+               | (raw.hor_blank_end << (7 - 5) & 0x80), 0x9F);
+       via_write_reg(VIACR, 0x06, raw.ver_total & 0xFF);
+       via_write_reg_mask(VIACR, 0x07, (raw.ver_total >> 8 & 0x01)
+               | (raw.ver_addr >> (8 - 1) & 0x02)
+               | (raw.ver_sync_start >> (8 - 2) & 0x04)
+               | (raw.ver_blank_start >> (8 - 3) & 0x08)
+               | (raw.ver_total >> (9 - 5) & 0x20)
+               | (raw.ver_addr >> (9 - 6) & 0x40)
+               | (raw.ver_sync_start >> (9 - 7) & 0x80), 0xEF);
+       via_write_reg_mask(VIACR, 0x09, raw.ver_blank_start >> (9 - 5) & 0x20,
+               0x20);
+       via_write_reg(VIACR, 0x10, raw.ver_sync_start & 0xFF);
+       via_write_reg_mask(VIACR, 0x11, raw.ver_sync_end & 0x0F, 0x0F);
+       via_write_reg(VIACR, 0x12, raw.ver_addr & 0xFF);
+       via_write_reg(VIACR, 0x15, raw.ver_blank_start & 0xFF);
+       via_write_reg(VIACR, 0x16, raw.ver_blank_end & 0xFF);
+       via_write_reg_mask(VIACR, 0x33, (raw.hor_sync_start >> (8 - 4) & 0x10)
+               | (raw.hor_blank_end >> (6 - 5) & 0x20), 0x30);
+       via_write_reg_mask(VIACR, 0x35, (raw.ver_total >> 10 & 0x01)
+               | (raw.ver_sync_start >> (10 - 1) & 0x02)
+               | (raw.ver_addr >> (10 - 2) & 0x04)
+               | (raw.ver_blank_start >> (10 - 3) & 0x08), 0x0F);
+       via_write_reg_mask(VIACR, 0x36, raw.hor_total >> (8 - 3) & 0x08, 0x08);
+
+       /* lock timing registers */
+       via_write_reg_mask(VIACR, 0x11, 0x80, 0x80);
+
+       /* reset timing control */
+       via_write_reg_mask(VIACR, 0x17, 0x00, 0x80);
+       via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
+}
+
+void via_set_secondary_timing(const struct display_timing *timing)
+{
+       struct display_timing raw;
+
+       raw.hor_total = timing->hor_total - 1;
+       raw.hor_addr = timing->hor_addr - 1;
+       raw.hor_blank_start = timing->hor_blank_start - 1;
+       raw.hor_blank_end = timing->hor_blank_end - 1;
+       raw.hor_sync_start = timing->hor_sync_start - 1;
+       raw.hor_sync_end = timing->hor_sync_end - 1;
+       raw.ver_total = timing->ver_total - 1;
+       raw.ver_addr = timing->ver_addr - 1;
+       raw.ver_blank_start = timing->ver_blank_start - 1;
+       raw.ver_blank_end = timing->ver_blank_end - 1;
+       raw.ver_sync_start = timing->ver_sync_start - 1;
+       raw.ver_sync_end = timing->ver_sync_end - 1;
+
+       via_write_reg(VIACR, 0x50, raw.hor_total & 0xFF);
+       via_write_reg(VIACR, 0x51, raw.hor_addr & 0xFF);
+       via_write_reg(VIACR, 0x52, raw.hor_blank_start & 0xFF);
+       via_write_reg(VIACR, 0x53, raw.hor_blank_end & 0xFF);
+       via_write_reg(VIACR, 0x54, (raw.hor_blank_start >> 8 & 0x07)
+               | (raw.hor_blank_end >> (8 - 3) & 0x38)
+               | (raw.hor_sync_start >> (8 - 6) & 0xC0));
+       via_write_reg_mask(VIACR, 0x55, (raw.hor_total >> 8 & 0x0F)
+               | (raw.hor_addr >> (8 - 4) & 0x70), 0x7F);
+       via_write_reg(VIACR, 0x56, raw.hor_sync_start & 0xFF);
+       via_write_reg(VIACR, 0x57, raw.hor_sync_end & 0xFF);
+       via_write_reg(VIACR, 0x58, raw.ver_total & 0xFF);
+       via_write_reg(VIACR, 0x59, raw.ver_addr & 0xFF);
+       via_write_reg(VIACR, 0x5A, raw.ver_blank_start & 0xFF);
+       via_write_reg(VIACR, 0x5B, raw.ver_blank_end & 0xFF);
+       via_write_reg(VIACR, 0x5C, (raw.ver_blank_start >> 8 & 0x07)
+               | (raw.ver_blank_end >> (8 - 3) & 0x38)
+               | (raw.hor_sync_end >> (8 - 6) & 0x40)
+               | (raw.hor_sync_start >> (10 - 7) & 0x80));
+       via_write_reg(VIACR, 0x5D, (raw.ver_total >> 8 & 0x07)
+               | (raw.ver_addr >> (8 - 3) & 0x38)
+               | (raw.hor_blank_end >> (11 - 6) & 0x40)
+               | (raw.hor_sync_start >> (11 - 7) & 0x80));
+       via_write_reg(VIACR, 0x5E, raw.ver_sync_start & 0xFF);
+       via_write_reg(VIACR, 0x5F, (raw.ver_sync_end & 0x1F)
+               | (raw.ver_sync_start >> (8 - 5) & 0xE0));
+}
+
 void via_set_primary_address(u32 addr)
 {
        DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr);
index ae35cfdeb37cd0de853c9f1c82b1fc7614011fed..06e09fe351ae86a209b139e88687d1f8f8f9d7e2 100644 (file)
 
 #include <linux/types.h>
 
+
+#define VIA_PITCH_SIZE (1<<3)
+#define VIA_PITCH_MAX  0x3FF8
+
+
+struct display_timing {
+       u16 hor_total;
+       u16 hor_addr;
+       u16 hor_blank_start;
+       u16 hor_blank_end;
+       u16 hor_sync_start;
+       u16 hor_sync_end;
+       u16 ver_total;
+       u16 ver_addr;
+       u16 ver_blank_start;
+       u16 ver_blank_end;
+       u16 ver_sync_start;
+       u16 ver_sync_end;
+};
+
+
+void via_set_primary_timing(const struct display_timing *timing);
+void via_set_secondary_timing(const struct display_timing *timing);
 void via_set_primary_address(u32 addr);
 void via_set_secondary_address(u32 addr);
 void via_set_primary_pitch(u32 pitch);
index 53aa4430d86ea74cb525a1adc37484ee60c07b07..a13c258bd32f45ed1abe7126fdc3728b1657b5e7 100644 (file)
@@ -38,8 +38,6 @@ static char *viafb_mode1;
 static int viafb_bpp = 32;
 static int viafb_bpp1 = 32;
 
-static unsigned int viafb_second_xres = 640;
-static unsigned int viafb_second_yres = 480;
 static unsigned int viafb_second_offset;
 static int viafb_second_size;
 
@@ -151,7 +149,8 @@ static void viafb_update_fix(struct fb_info *info)
 
        info->fix.visual =
                bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
-       info->fix.line_length = (info->var.xres_virtual * bpp / 8 + 7) & ~7;
+       info->fix.line_length = ALIGN(info->var.xres_virtual * bpp / 8,
+               VIA_PITCH_SIZE);
 }
 
 static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
@@ -200,7 +199,6 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
        struct fb_info *info)
 {
        int depth, refresh;
-       struct VideoModeTable *vmode_entry;
        struct viafb_par *ppar = info->par;
        u32 line;
 
@@ -210,8 +208,10 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
        if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
                return -EINVAL;
 
-       vmode_entry = viafb_get_mode(var->xres, var->yres);
-       if (!vmode_entry) {
+       /* the refresh rate is not important here, as we only want to know
+        * whether the resolution exists
+        */
+       if (!viafb_get_best_mode(var->xres, var->yres, 60)) {
                DEBUG_MSG(KERN_INFO
                          "viafb: Mode %dx%dx%d not supported!!\n",
                          var->xres, var->yres, var->bits_per_pixel);
@@ -238,8 +238,12 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
                depth = 24;
 
        viafb_fill_var_color_info(var, depth);
-       line = (var->xres_virtual * var->bits_per_pixel / 8 + 7) & ~7;
-       if (line * var->yres_virtual > ppar->memsize)
+       if (var->xres_virtual < var->xres)
+               var->xres_virtual = var->xres;
+
+       line = ALIGN(var->xres_virtual * var->bits_per_pixel / 8,
+               VIA_PITCH_SIZE);
+       if (line > VIA_PITCH_MAX || line * var->yres_virtual > ppar->memsize)
                return -EINVAL;
 
        /* Based on var passed in to calculate the refresh,
@@ -249,7 +253,8 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
                get_var_refresh(var));
 
        /* Adjust var according to our driver's own table */
-       viafb_fill_var_timing_info(var, refresh, vmode_entry);
+       viafb_fill_var_timing_info(var,
+               viafb_get_best_mode(var->xres, var->yres, refresh));
        if (var->accel_flags & FB_ACCELF_TEXT &&
                !ppar->shared->vdev->engine_mmio)
                var->accel_flags = 0;
@@ -260,7 +265,6 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
 static int viafb_set_par(struct fb_info *info)
 {
        struct viafb_par *viapar = info->par;
-       struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
        int refresh;
        DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
 
@@ -269,10 +273,7 @@ static int viafb_set_par(struct fb_info *info)
        viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
                viafbinfo->var.bits_per_pixel, 0);
 
-       vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres);
        if (viafb_dual_fb) {
-               vmode_entry1 = viafb_get_mode(viafbinfo1->var.xres,
-                       viafbinfo1->var.yres);
                viafb_update_device_setting(viafbinfo1->var.xres,
                        viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel,
                        1);
@@ -280,8 +281,6 @@ static int viafb_set_par(struct fb_info *info)
                DEBUG_MSG(KERN_INFO
                "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
                          viafb_second_xres, viafb_second_yres, viafb_bpp1);
-               vmode_entry1 = viafb_get_mode(viafb_second_xres,
-                       viafb_second_yres);
 
                viafb_update_device_setting(viafb_second_xres,
                        viafb_second_yres, viafb_bpp1, 1);
@@ -289,7 +288,8 @@ static int viafb_set_par(struct fb_info *info)
 
        refresh = viafb_get_refresh(info->var.xres, info->var.yres,
                get_var_refresh(&info->var));
-       if (vmode_entry) {
+       if (viafb_get_best_mode(viafbinfo->var.xres, viafbinfo->var.yres,
+               refresh)) {
                if (viafb_dual_fb && viapar->iga_path == IGA2) {
                        viafb_bpp1 = info->var.bits_per_pixel;
                        viafb_refresh1 = refresh;
@@ -302,8 +302,7 @@ static int viafb_set_par(struct fb_info *info)
                        info->flags &= ~FBINFO_HWACCEL_DISABLED;
                else
                        info->flags |= FBINFO_HWACCEL_DISABLED;
-               viafb_setmode(vmode_entry, info->var.bits_per_pixel,
-                       vmode_entry1, viafb_bpp1);
+               viafb_setmode(info->var.bits_per_pixel, viafb_bpp1);
                viafb_pan_display(&info->var, info);
        }
 
@@ -348,8 +347,9 @@ static int viafb_pan_display(struct fb_var_screeninfo *var,
        struct fb_info *info)
 {
        struct viafb_par *viapar = info->par;
-       u32 vram_addr = (var->yoffset * var->xres_virtual + var->xoffset)
-               * (var->bits_per_pixel / 8) + viapar->vram_addr;
+       u32 vram_addr = viapar->vram_addr
+               + var->yoffset * info->fix.line_length
+               + var->xoffset * info->var.bits_per_pixel / 8;
 
        DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr);
        if (!viafb_dual_fb) {
@@ -1158,7 +1158,8 @@ static ssize_t viafb_dvp0_proc_write(struct file *file,
        for (i = 0; i < 3; i++) {
                value = strsep(&pbuf, " ");
                if (value != NULL) {
-                       strict_strtoul(value, 0, (unsigned long *)&reg_val);
+                       if (kstrtou8(value, 0, &reg_val) < 0)
+                               return -EINVAL;
                        DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i,
                                  reg_val);
                        switch (i) {
@@ -1228,7 +1229,8 @@ static ssize_t viafb_dvp1_proc_write(struct file *file,
        for (i = 0; i < 3; i++) {
                value = strsep(&pbuf, " ");
                if (value != NULL) {
-                       strict_strtoul(value, 0, (unsigned long *)&reg_val);
+                       if (kstrtou8(value, 0, &reg_val) < 0)
+                               return -EINVAL;
                        switch (i) {
                        case 0:
                                viafb_write_reg_mask(CR9B, VIACR,
@@ -1286,7 +1288,8 @@ static ssize_t viafb_dfph_proc_write(struct file *file,
        if (copy_from_user(&buf[0], buffer, length))
                return -EFAULT;
        buf[length - 1] = '\0'; /*Ensure end string */
-       strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
+       if (kstrtou8(buf, 0, &reg_val) < 0)
+               return -EINVAL;
        viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
        return count;
 }
@@ -1325,7 +1328,8 @@ static ssize_t viafb_dfpl_proc_write(struct file *file,
        if (copy_from_user(&buf[0], buffer, length))
                return -EFAULT;
        buf[length - 1] = '\0'; /*Ensure end string */
-       strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
+       if (kstrtou8(buf, 0, &reg_val) < 0)
+               return -EINVAL;
        viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
        return count;
 }
@@ -1394,8 +1398,8 @@ static ssize_t viafb_vt1636_proc_write(struct file *file,
                for (i = 0; i < 2; i++) {
                        value = strsep(&pbuf, " ");
                        if (value != NULL) {
-                               strict_strtoul(value, 0,
-                                       (unsigned long *)&reg_val.Data);
+                               if (kstrtou8(value, 0, &reg_val.Data) < 0)
+                                       return -EINVAL;
                                switch (i) {
                                case 0:
                                        reg_val.Index = 0x08;
@@ -1431,8 +1435,8 @@ static ssize_t viafb_vt1636_proc_write(struct file *file,
                for (i = 0; i < 2; i++) {
                        value = strsep(&pbuf, " ");
                        if (value != NULL) {
-                               strict_strtoul(value, 0,
-                                       (unsigned long *)&reg_val.Data);
+                               if (kstrtou8(value, 0, &reg_val.Data) < 0)
+                                       return -EINVAL;
                                switch (i) {
                                case 0:
                                        reg_val.Index = 0x08;
@@ -1729,7 +1733,6 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
 int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
 {
        u32 default_xres, default_yres;
-       struct VideoModeTable *vmode_entry;
        struct fb_var_screeninfo default_var;
        int rc;
        u32 viafb_par_length;
@@ -1802,7 +1805,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
        }
 
        parse_mode(viafb_mode, &default_xres, &default_yres);
-       vmode_entry = viafb_get_mode(default_xres, default_yres);
        if (viafb_SAMM_ON == 1)
                parse_mode(viafb_mode1, &viafb_second_xres,
                        &viafb_second_yres);
@@ -1812,9 +1814,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
        default_var.xres_virtual = default_xres;
        default_var.yres_virtual = default_yres;
        default_var.bits_per_pixel = viafb_bpp;
-       viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
-               default_var.xres, default_var.yres, viafb_refresh),
-               viafb_get_mode(default_var.xres, default_var.yres));
+       viafb_fill_var_timing_info(&default_var, viafb_get_best_mode(
+               default_var.xres, default_var.yres, viafb_refresh));
        viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
        viafbinfo->var = default_var;
 
@@ -1853,9 +1854,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
                default_var.xres_virtual = viafb_second_xres;
                default_var.yres_virtual = viafb_second_yres;
                default_var.bits_per_pixel = viafb_bpp1;
-               viafb_fill_var_timing_info(&default_var, viafb_get_refresh(
-                       default_var.xres, default_var.yres, viafb_refresh1),
-                       viafb_get_mode(default_var.xres, default_var.yres));
+               viafb_fill_var_timing_info(&default_var, viafb_get_best_mode(
+                       default_var.xres, default_var.yres, viafb_refresh1));
 
                viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
                viafb_check_var(&default_var, viafbinfo1);
@@ -1950,61 +1950,67 @@ static int __init viafb_setup(void)
                if (!*this_opt)
                        continue;
 
-               if (!strncmp(this_opt, "viafb_mode1=", 12))
+               if (!strncmp(this_opt, "viafb_mode1=", 12)) {
                        viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL);
-               else if (!strncmp(this_opt, "viafb_mode=", 11))
+               } else if (!strncmp(this_opt, "viafb_mode=", 11)) {
                        viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL);
-               else if (!strncmp(this_opt, "viafb_bpp1=", 11))
-                       strict_strtoul(this_opt + 11, 0,
-                               (unsigned long *)&viafb_bpp1);
-               else if (!strncmp(this_opt, "viafb_bpp=", 10))
-                       strict_strtoul(this_opt + 10, 0,
-                               (unsigned long *)&viafb_bpp);
-               else if (!strncmp(this_opt, "viafb_refresh1=", 15))
-                       strict_strtoul(this_opt + 15, 0,
-                               (unsigned long *)&viafb_refresh1);
-               else if (!strncmp(this_opt, "viafb_refresh=", 14))
-                       strict_strtoul(this_opt + 14, 0,
-                               (unsigned long *)&viafb_refresh);
-               else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21))
-                       strict_strtoul(this_opt + 21, 0,
-                               (unsigned long *)&viafb_lcd_dsp_method);
-               else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19))
-                       strict_strtoul(this_opt + 19, 0,
-                               (unsigned long *)&viafb_lcd_panel_id);
-               else if (!strncmp(this_opt, "viafb_accel=", 12))
-                       strict_strtoul(this_opt + 12, 0,
-                               (unsigned long *)&viafb_accel);
-               else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14))
-                       strict_strtoul(this_opt + 14, 0,
-                               (unsigned long *)&viafb_SAMM_ON);
-               else if (!strncmp(this_opt, "viafb_active_dev=", 17))
+               } else if (!strncmp(this_opt, "viafb_bpp1=", 11)) {
+                       if (kstrtouint(this_opt + 11, 0, &viafb_bpp1) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_bpp=", 10)) {
+                       if (kstrtouint(this_opt + 10, 0, &viafb_bpp) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_refresh1=", 15)) {
+                       if (kstrtoint(this_opt + 15, 0, &viafb_refresh1) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_refresh=", 14)) {
+                       if (kstrtoint(this_opt + 14, 0, &viafb_refresh) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21)) {
+                       if (kstrtoint(this_opt + 21, 0,
+                                     &viafb_lcd_dsp_method) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19)) {
+                       if (kstrtoint(this_opt + 19, 0,
+                                     &viafb_lcd_panel_id) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_accel=", 12)) {
+                       if (kstrtoint(this_opt + 12, 0, &viafb_accel) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14)) {
+                       if (kstrtoint(this_opt + 14, 0, &viafb_SAMM_ON) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_active_dev=", 17)) {
                        viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL);
-               else if (!strncmp(this_opt,
-                       "viafb_display_hardware_layout=", 30))
-                       strict_strtoul(this_opt + 30, 0,
-                       (unsigned long *)&viafb_display_hardware_layout);
-               else if (!strncmp(this_opt, "viafb_second_size=", 18))
-                       strict_strtoul(this_opt + 18, 0,
-                               (unsigned long *)&viafb_second_size);
-               else if (!strncmp(this_opt,
-                       "viafb_platform_epia_dvi=", 24))
-                       strict_strtoul(this_opt + 24, 0,
-                               (unsigned long *)&viafb_platform_epia_dvi);
-               else if (!strncmp(this_opt,
-                       "viafb_device_lcd_dualedge=", 26))
-                       strict_strtoul(this_opt + 26, 0,
-                               (unsigned long *)&viafb_device_lcd_dualedge);
-               else if (!strncmp(this_opt, "viafb_bus_width=", 16))
-                       strict_strtoul(this_opt + 16, 0,
-                               (unsigned long *)&viafb_bus_width);
-               else if (!strncmp(this_opt, "viafb_lcd_mode=", 15))
-                       strict_strtoul(this_opt + 15, 0,
-                               (unsigned long *)&viafb_lcd_mode);
-               else if (!strncmp(this_opt, "viafb_lcd_port=", 15))
+               } else if (!strncmp(this_opt,
+                       "viafb_display_hardware_layout=", 30)) {
+                       if (kstrtoint(this_opt + 30, 0,
+                                     &viafb_display_hardware_layout) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_second_size=", 18)) {
+                       if (kstrtoint(this_opt + 18, 0, &viafb_second_size) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt,
+                       "viafb_platform_epia_dvi=", 24)) {
+                       if (kstrtoint(this_opt + 24, 0,
+                                     &viafb_platform_epia_dvi) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt,
+                       "viafb_device_lcd_dualedge=", 26)) {
+                       if (kstrtoint(this_opt + 26, 0,
+                                     &viafb_device_lcd_dualedge) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_bus_width=", 16)) {
+                       if (kstrtoint(this_opt + 16, 0, &viafb_bus_width) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) {
+                       if (kstrtoint(this_opt + 15, 0, &viafb_lcd_mode) < 0)
+                               return -EINVAL;
+               } else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) {
                        viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL);
-               else if (!strncmp(this_opt, "viafb_dvi_port=", 15))
+               } else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) {
                        viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL);
+               }
        }
        return 0;
 }
@@ -2028,9 +2034,9 @@ int __init viafb_init(void)
                return r;
 #endif
        if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
-               || !viafb_get_mode(dummy_x, dummy_y)
+               || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
                || parse_mode(viafb_mode1, &dummy_x, &dummy_y)
-               || !viafb_get_mode(dummy_x, dummy_y)
+               || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
                || viafb_bpp < 0 || viafb_bpp > 32
                || viafb_bpp1 < 0 || viafb_bpp1 > 32
                || parse_active_dev())
index 58df74e1417e0a744ddd2f822accf4647cfd48ba..0911cac1b2ffb9cd3731b0c77f3040f035231f04 100644 (file)
@@ -281,7 +281,7 @@ static struct crt_mode_table CRTM640x480[] = {
        /*r_rate,hsp,vsp */
        /*HT,  HA,  HBS, HBE, HSS, HSE, VT,  VA,  VBS, VBE, VSS, VSE */
        {REFRESH_60, M640X480_R60_HSP, M640X480_R60_VSP,
-        {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} },
+        {800, 640, 640, 160, 656, 96, 525, 480, 480, 45, 490, 2} },
        {REFRESH_75, M640X480_R75_HSP, M640X480_R75_VSP,
         {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} },
        {REFRESH_85, M640X480_R85_HSP, M640X480_R85_VSP,
@@ -863,26 +863,56 @@ int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
 int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
 
 
-struct VideoModeTable *viafb_get_mode(int hres, int vres)
+static struct VideoModeTable *get_modes(struct VideoModeTable *vmt, int n,
+       int hres, int vres)
 {
-       u32 i;
-       for (i = 0; i < ARRAY_SIZE(viafb_modes); i++)
-               if (viafb_modes[i].mode_array &&
-                       viafb_modes[i].crtc[0].crtc.hor_addr == hres &&
-                       viafb_modes[i].crtc[0].crtc.ver_addr == vres)
+       int i;
+
+       for (i = 0; i < n; i++)
+               if (vmt[i].mode_array &&
+                       vmt[i].crtc[0].crtc.hor_addr == hres &&
+                       vmt[i].crtc[0].crtc.ver_addr == vres)
                        return &viafb_modes[i];
 
        return NULL;
 }
 
-struct VideoModeTable *viafb_get_rb_mode(int hres, int vres)
+static struct crt_mode_table *get_best_mode(struct VideoModeTable *vmt,
+       int refresh)
 {
-       u32 i;
-       for (i = 0; i < ARRAY_SIZE(viafb_rb_modes); i++)
-               if (viafb_rb_modes[i].mode_array &&
-                       viafb_rb_modes[i].crtc[0].crtc.hor_addr == hres &&
-                       viafb_rb_modes[i].crtc[0].crtc.ver_addr == vres)
-                       return &viafb_rb_modes[i];
+       struct crt_mode_table *best;
+       int i;
 
-       return NULL;
+       if (!vmt)
+               return NULL;
+
+       best = &vmt->crtc[0];
+       for (i = 1; i < vmt->mode_array; i++) {
+               if (abs(vmt->crtc[i].refresh_rate - refresh)
+                       < abs(best->refresh_rate - refresh))
+                       best = &vmt->crtc[i];
+       }
+
+       return best;
+}
+
+static struct VideoModeTable *viafb_get_mode(int hres, int vres)
+{
+       return get_modes(viafb_modes, ARRAY_SIZE(viafb_modes), hres, vres);
+}
+
+struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh)
+{
+       return get_best_mode(viafb_get_mode(hres, vres), refresh);
+}
+
+static struct VideoModeTable *viafb_get_rb_mode(int hres, int vres)
+{
+       return get_modes(viafb_rb_modes, ARRAY_SIZE(viafb_rb_modes), hres,
+               vres);
+}
+
+struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh)
+{
+       return get_best_mode(viafb_get_rb_mode(hres, vres), refresh);
 }
index 3751289eb4506a1faa2a87a187dd6737ce37c598..5917a2b00e1ba7b69dec0b0d3bcc262bfc4b9e0b 100644 (file)
@@ -60,7 +60,7 @@ extern struct io_reg PM1024x768[];
 extern struct patch_table res_patch_table[];
 extern struct VPITTable VPIT;
 
-struct VideoModeTable *viafb_get_mode(int hres, int vres);
-struct VideoModeTable *viafb_get_rb_mode(int hres, int vres);
+struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh);
+struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh);
 
 #endif /* __VIAMODE_H__ */
index 0e120d67eb65074eb0f337ff9d29e10cdae134a3..c13c246be9a56ddd68b398e00f123937517c80fa 100644 (file)
@@ -210,8 +210,8 @@ static int vt8500lcd_pan_display(struct fb_var_screeninfo *var,
        struct vt8500lcd_info *fbi = to_vt8500lcd_info(info);
 
        writel((1 << 31)
-               | (((var->xres_virtual - var->xres) * pixlen / 4) << 20)
-               | (off >> 2), fbi->regbase + 0x20);
+            | (((info->var.xres_virtual - info->var.xres) * pixlen / 4) << 20)
+            | (off >> 2), fbi->regbase + 0x20);
        return 0;
 }
 
index f9b3e3dc24219fcdabcf9235a95720292c107c12..4e74d262cf3e9f338c1eb0cb46a5835794a532d3 100644 (file)
@@ -620,13 +620,14 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
        unsigned int offset;
 
        /* Calculate the offset */
-       if (var->bits_per_pixel == 0) {
-               offset = (var->yoffset / 16) * var->xres_virtual + var->xoffset;
+       if (info->var.bits_per_pixel == 0) {
+               offset = (var->yoffset / 16) * info->var.xres_virtual
+                      + var->xoffset;
                offset = offset >> 3;
        } else {
                offset = (var->yoffset * info->fix.line_length) +
-                        (var->xoffset * var->bits_per_pixel / 8);
-               offset = offset >> ((var->bits_per_pixel == 4) ? 2 : 1);
+                        (var->xoffset * info->var.bits_per_pixel / 8);
+               offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 1);
        }
 
        /* Set the offset */
index 77dea015ff69a7524261296ea91ed33975b338a9..fcb6cd90f64d8ade134626076a622ac4a2a16118 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
index bd44417c84d40940302fe484373818b84ac70982..5c5f4b14fd05aee17e1e6d1f30743f8a3735a1c9 100644 (file)
@@ -54,12 +54,35 @@ static atomic_t ticks;
 static inline void bcm47xx_wdt_hw_start(void)
 {
        /* this is 2,5s on 100Mhz clock  and 2s on 133 Mhz */
-       ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff);
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
+                                              0xfffffff);
+               break;
+#endif
+       }
 }
 
 static inline int bcm47xx_wdt_hw_stop(void)
 {
-       return ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
+               return 0;
+#endif
+       }
+       return -EINVAL;
 }
 
 static void bcm47xx_timer_tick(unsigned long unused)
index 410fba45378d404f5ce4045faaf6f3c9782a957b..809cbda03d7a24390a62b90775859bb029c6d760 100644 (file)
@@ -494,15 +494,16 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
                asminline_call(&cmn_regs, cru_rom_addr);
        die_nmi_called = 1;
        spin_unlock_irqrestore(&rom_lock, rom_pl);
+
+       if (allow_kdump)
+               hpwdt_stop();
+
        if (!is_icru) {
                if (cmn_regs.u1.ral == 0) {
-                       printk(KERN_WARNING "hpwdt: An NMI occurred, "
+                       panic("An NMI occurred, "
                                "but unable to determine source.\n");
                }
        }
-
-       if (allow_kdump)
-               hpwdt_stop();
        panic("An NMI occurred, please see the Integrated "
                "Management Log for details.\n");
 
index d33520d0b4c96f6485e38c3c8fc29fa90a8a5807..1199da0f98cf2ada1a3a8868c57561f742e723df 100644 (file)
@@ -59,7 +59,7 @@ static struct watchdog_device *wdd;
 
 static int watchdog_ping(struct watchdog_device *wddev)
 {
-       if (test_bit(WDOG_ACTIVE, &wdd->status)) {
+       if (test_bit(WDOG_ACTIVE, &wddev->status)) {
                if (wddev->ops->ping)
                        return wddev->ops->ping(wddev);  /* ping the watchdog */
                else
@@ -81,12 +81,12 @@ static int watchdog_start(struct watchdog_device *wddev)
 {
        int err;
 
-       if (!test_bit(WDOG_ACTIVE, &wdd->status)) {
+       if (!test_bit(WDOG_ACTIVE, &wddev->status)) {
                err = wddev->ops->start(wddev);
                if (err < 0)
                        return err;
 
-               set_bit(WDOG_ACTIVE, &wdd->status);
+               set_bit(WDOG_ACTIVE, &wddev->status);
        }
        return 0;
 }
@@ -105,18 +105,18 @@ static int watchdog_stop(struct watchdog_device *wddev)
 {
        int err = -EBUSY;
 
-       if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) {
+       if (test_bit(WDOG_NO_WAY_OUT, &wddev->status)) {
                pr_info("%s: nowayout prevents watchdog to be stopped!\n",
-                                                       wdd->info->identity);
+                                                       wddev->info->identity);
                return err;
        }
 
-       if (test_bit(WDOG_ACTIVE, &wdd->status)) {
+       if (test_bit(WDOG_ACTIVE, &wddev->status)) {
                err = wddev->ops->stop(wddev);
                if (err < 0)
                        return err;
 
-               clear_bit(WDOG_ACTIVE, &wdd->status);
+               clear_bit(WDOG_ACTIVE, &wddev->status);
        }
        return 0;
 }
index 5dfd8f8ff07f402e9063b608c7e11b1b6571c126..6c93c5766fb622a3b82450ca4533b7d986787f08 100644 (file)
@@ -93,8 +93,8 @@ static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
 #define inc_totalhigh_pages() (totalhigh_pages++)
 #define dec_totalhigh_pages() (totalhigh_pages--)
 #else
-#define inc_totalhigh_pages() do {} while(0)
-#define dec_totalhigh_pages() do {} while(0)
+#define inc_totalhigh_pages() do {} while (0)
+#define dec_totalhigh_pages() do {} while (0)
 #endif
 
 /* List of ballooned pages, threaded through the mem_map array. */
@@ -154,8 +154,7 @@ static struct page *balloon_retrieve(bool prefer_highmem)
        if (PageHighMem(page)) {
                balloon_stats.balloon_high--;
                inc_totalhigh_pages();
-       }
-       else
+       } else
                balloon_stats.balloon_low--;
 
        totalram_pages++;
@@ -422,7 +421,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
                                (unsigned long)__va(pfn << PAGE_SHIFT),
                                __pte_ma(0), 0);
                        BUG_ON(ret);
-                }
+               }
 
        }
 
@@ -503,10 +502,10 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);
  * @pages: pages returned
  * @return 0 on success, error otherwise
  */
-int alloc_xenballooned_pages(int nr_pages, struct page** pages)
+int alloc_xenballooned_pages(int nr_pages, struct page **pages)
 {
        int pgno = 0;
-       struct pagepage;
+       struct page *page;
        mutex_lock(&balloon_mutex);
        while (pgno < nr_pages) {
                page = balloon_retrieve(true);
@@ -536,7 +535,7 @@ EXPORT_SYMBOL(alloc_xenballooned_pages);
  * @nr_pages: Number of pages
  * @pages: pages to return
  */
-void free_xenballooned_pages(int nr_pages, struct page** pages)
+void free_xenballooned_pages(int nr_pages, struct page **pages)
 {
        int i;
 
index da70f5c32eb9875d9d24eade0861d5004d918d14..8876ffd08771baf0790db3643122e16397c93b8b 100644 (file)
@@ -85,8 +85,7 @@ enum xen_irq_type {
  *    IPI - IPI vector
  *    EVTCHN -
  */
-struct irq_info
-{
+struct irq_info {
        struct list_head list;
        enum xen_irq_type type; /* type */
        unsigned irq;
@@ -282,9 +281,9 @@ static inline unsigned long active_evtchns(unsigned int cpu,
                                           struct shared_info *sh,
                                           unsigned int idx)
 {
-       return (sh->evtchn_pending[idx] &
+       return sh->evtchn_pending[idx] &
                per_cpu(cpu_evtchn_mask, cpu)[idx] &
-               ~sh->evtchn_mask[idx]);
+               ~sh->evtchn_mask[idx];
 }
 
 static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
@@ -1152,7 +1151,7 @@ static void __xen_evtchn_do_upcall(void)
        int cpu = get_cpu();
        struct shared_info *s = HYPERVISOR_shared_info;
        struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
-       unsigned count;
+       unsigned count;
 
        do {
                unsigned long pending_words;
index f914b26cf0c2efdfac05b8af9e6d9b8a37124dfc..772a5b8bbf2e8b16a2ca73ce204d3a403261f775 100644 (file)
@@ -188,9 +188,8 @@ static void gntdev_put_map(struct grant_map *map)
 
        atomic_sub(map->count, &pages_mapped);
 
-       if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
+       if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
                notify_remote_via_evtchn(map->notify.event);
-       }
 
        if (map->pages) {
                if (!use_ptemod)
index 4f44b347b24ab2e43a783f20a4c8232561ec120d..e2d2c31ae0d0a2c0ca49b72b63fe6727e692e13d 100644 (file)
@@ -193,7 +193,7 @@ int gnttab_query_foreign_access(grant_ref_t ref)
 
        nflags = shared[ref].flags;
 
-       return (nflags & (GTF_reading|GTF_writing));
+       return nflags & (GTF_reading|GTF_writing);
 }
 EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
 
index cef4bafc07dc61d9eea2fe8f507c895ccef99f7b..c4448ee5595f92ae582168f8c064f42e608d89b4 100644 (file)
@@ -36,7 +36,7 @@ static int xen_add_device(struct device *dev)
                struct physdev_manage_pci_ext manage_pci_ext = {
                        .bus            = pci_dev->bus->number,
                        .devfn          = pci_dev->devfn,
-                       .is_virtfn      = 1,
+                       .is_virtfn      = 1,
                        .physfn.bus     = pci_dev->physfn->bus->number,
                        .physfn.devfn   = pci_dev->physfn->devfn,
                };
@@ -56,7 +56,7 @@ static int xen_add_device(struct device *dev)
                        &manage_pci_ext);
        } else {
                struct physdev_manage_pci manage_pci = {
-                       .bus    = pci_dev->bus->number,
+                       .bus    = pci_dev->bus->number,
                        .devfn  = pci_dev->devfn,
                };
 
index 6e8c15a23201a3a280948cf25142001347a0d6cb..0408f3225722c22d2c082e9812b3427adf9ba96e 100644 (file)
@@ -38,6 +38,7 @@
 #include <xen/swiotlb-xen.h>
 #include <xen/page.h>
 #include <xen/xen-ops.h>
+#include <xen/hvc-console.h>
 /*
  * Used to do a quick range check in swiotlb_tbl_unmap_single and
  * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this
@@ -146,8 +147,10 @@ xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs)
 void __init xen_swiotlb_init(int verbose)
 {
        unsigned long bytes;
-       int rc;
+       int rc = -ENOMEM;
        unsigned long nr_tbl;
+       char *m = NULL;
+       unsigned int repeat = 3;
 
        nr_tbl = swioltb_nr_tbl();
        if (nr_tbl)
@@ -156,16 +159,17 @@ void __init xen_swiotlb_init(int verbose)
                xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
                xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
        }
-
+retry:
        bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT;
 
        /*
         * Get IO TLB memory from any location.
         */
        xen_io_tlb_start = alloc_bootmem(bytes);
-       if (!xen_io_tlb_start)
-               panic("Cannot allocate SWIOTLB buffer");
-
+       if (!xen_io_tlb_start) {
+               m = "Cannot allocate Xen-SWIOTLB buffer!\n";
+               goto error;
+       }
        xen_io_tlb_end = xen_io_tlb_start + bytes;
        /*
         * And replace that memory with pages under 4GB.
@@ -173,17 +177,28 @@ void __init xen_swiotlb_init(int verbose)
        rc = xen_swiotlb_fixup(xen_io_tlb_start,
                               bytes,
                               xen_io_tlb_nslabs);
-       if (rc)
+       if (rc) {
+               free_bootmem(__pa(xen_io_tlb_start), bytes);
+               m = "Failed to get contiguous memory for DMA from Xen!\n"\
+                   "You either: don't have the permissions, do not have"\
+                   " enough free memory under 4GB, or the hypervisor memory"\
+                   "is too fragmented!";
                goto error;
-
+       }
        start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
        swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose);
 
        return;
 error:
-       panic("DMA(%d): Failed to exchange pages allocated for DMA with Xen! "\
-             "We either don't have the permission or you do not have enough"\
-             "free memory under 4GB!\n", rc);
+       if (repeat--) {
+               xen_io_tlb_nslabs = max(1024UL, /* Min is 2MB */
+                                       (xen_io_tlb_nslabs >> 1));
+               printk(KERN_INFO "Xen-SWIOTLB: Lowering to %luMB\n",
+                     (xen_io_tlb_nslabs << IO_TLB_SHIFT) >> 20);
+               goto retry;
+       }
+       xen_raw_printk("%s (rc:%d)", m, rc);
+       panic("%s (rc:%d)", m, rc);
 }
 
 void *
@@ -278,9 +293,10 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
        /*
         * Ensure that the address returned is DMA'ble
         */
-       if (!dma_capable(dev, dev_addr, size))
-               panic("map_single: bounce buffer is not DMA'ble");
-
+       if (!dma_capable(dev, dev_addr, size)) {
+               swiotlb_tbl_unmap_single(dev, map, size, dir);
+               dev_addr = 0;
+       }
        return dev_addr;
 }
 EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
index 5c9dc43c1e94240cf3f25c674a047df4f9f93ea7..9cc2259c9992799dca480245b018ffb971541ed9 100644 (file)
@@ -50,11 +50,6 @@ static struct sys_device balloon_sysdev;
 
 static int register_balloon(struct sys_device *sysdev);
 
-static struct xenbus_watch target_watch =
-{
-       .node = "memory/target"
-};
-
 /* React to a change in the target key */
 static void watch_target(struct xenbus_watch *watch,
                         const char **vec, unsigned int len)
@@ -73,6 +68,11 @@ static void watch_target(struct xenbus_watch *watch,
         */
        balloon_set_new_target(new_target >> (PAGE_SHIFT - 10));
 }
+static struct xenbus_watch target_watch = {
+       .node = "memory/target",
+       .callback = watch_target,
+};
+
 
 static int balloon_init_watcher(struct notifier_block *notifier,
                                unsigned long event,
@@ -87,7 +87,9 @@ static int balloon_init_watcher(struct notifier_block *notifier,
        return NOTIFY_DONE;
 }
 
-static struct notifier_block xenstore_notifier;
+static struct notifier_block xenstore_notifier = {
+       .notifier_call = balloon_init_watcher,
+};
 
 static int __init balloon_init(void)
 {
@@ -100,9 +102,6 @@ static int __init balloon_init(void)
 
        register_xen_selfballooning(&balloon_sysdev);
 
-       target_watch.callback = watch_target;
-       xenstore_notifier.notifier_call = balloon_init_watcher;
-
        register_xenstore_notifier(&xenstore_notifier);
 
        return 0;
index da3cbdfcb5dcd20aabfac8658bc4aba7d73133ac..f14b30f71464b3180780f6b1f988bbc0e6807e14 100644 (file)
@@ -187,7 +187,7 @@ static inline void read_dev_bar(struct pci_dev *dev,
 
        bar_info->val = res[pos].start |
                        (res[pos].flags & PCI_REGION_FLAG_MASK);
-       bar_info->len_val = res[pos].end - res[pos].start + 1;
+       bar_info->len_val = resource_size(&res[pos]);
 }
 
 static void *bar_init(struct pci_dev *dev, int offset)
index bd2f90c9ac8b8131ff12a2e0f9a26be28af745ee..d4c7a9ffbcb93d880614bbbdfebdfcae9fe47dc1 100644 (file)
@@ -309,8 +309,7 @@ void xenbus_unregister_driver(struct xenbus_driver *drv)
 }
 EXPORT_SYMBOL_GPL(xenbus_unregister_driver);
 
-struct xb_find_info
-{
+struct xb_find_info {
        struct xenbus_device *dev;
        const char *nodename;
 };
@@ -639,7 +638,7 @@ int xenbus_dev_cancel(struct device *dev)
 EXPORT_SYMBOL_GPL(xenbus_dev_cancel);
 
 /* A flag to determine if xenstored is 'ready' (i.e. has started) */
-int xenstored_ready = 0;
+int xenstored_ready;
 
 
 int register_xenstore_notifier(struct notifier_block *nb)
@@ -762,7 +761,7 @@ static int __init xenbus_init(void)
 
        return 0;
 
-  out_error:
+out_error:
        if (page != 0)
                free_page(page);
 
index b814935378c7a4739fce949f70961505997381b7..9b1de4e34c64db2eae45798765bf81f45af1a84b 100644 (file)
@@ -36,8 +36,7 @@
 
 #define XEN_BUS_ID_SIZE                        20
 
-struct xen_bus_type
-{
+struct xen_bus_type {
        char *root;
        unsigned int levels;
        int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE], const char *nodename);
index 7ee2b6e7178643af597273a2263f26b962e6db4f..229624f867d3533f09173b276065457955878568 100644 (file)
@@ -37,6 +37,7 @@ zorro_match_device(const struct zorro_device_id *ids,
        }
        return NULL;
 }
+EXPORT_SYMBOL(zorro_match_device);
 
 
 static int zorro_device_probe(struct device *dev)
@@ -91,6 +92,7 @@ int zorro_register_driver(struct zorro_driver *drv)
        /* register with core */
        return driver_register(&drv->driver);
 }
+EXPORT_SYMBOL(zorro_register_driver);
 
 
     /**
@@ -107,6 +109,7 @@ void zorro_unregister_driver(struct zorro_driver *drv)
 {
        driver_unregister(&drv->driver);
 }
+EXPORT_SYMBOL(zorro_unregister_driver);
 
 
     /**
@@ -168,6 +171,7 @@ struct bus_type zorro_bus_type = {
        .probe  = zorro_device_probe,
        .remove = zorro_device_remove,
 };
+EXPORT_SYMBOL(zorro_bus_type);
 
 
 static int __init zorro_driver_init(void)
@@ -177,7 +181,3 @@ static int __init zorro_driver_init(void)
 
 postcore_initcall(zorro_driver_init);
 
-EXPORT_SYMBOL(zorro_match_device);
-EXPORT_SYMBOL(zorro_register_driver);
-EXPORT_SYMBOL(zorro_unregister_driver);
-EXPORT_SYMBOL(zorro_bus_type);
index 46ce357ca1abd46d5bff175aa5518b9e1f7f778f..410ffd6ceb5fb10961d9230e056cd2fe87bef148 100644 (file)
@@ -54,9 +54,9 @@ extern struct kmem_cache *v9fs_inode_cache;
 
 struct inode *v9fs_alloc_inode(struct super_block *sb);
 void v9fs_destroy_inode(struct inode *inode);
-struct inode *v9fs_get_inode(struct super_block *sb, int mode);
+struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t);
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
-                   struct inode *inode, int mode);
+                   struct inode *inode, int mode, dev_t);
 void v9fs_evict_inode(struct inode *inode);
 ino_t v9fs_qid2ino(struct p9_qid *qid);
 void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
@@ -83,4 +83,6 @@ static inline void v9fs_invalidate_inode_attr(struct inode *inode)
        v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
        return;
 }
+
+int v9fs_open_to_dotl_flags(int flags);
 #endif
index 9c2bdda5cd9de6556e6907711a38953041aa1ef5..ce6600f33659fb3742243ebaa2f01f20ab6f01d5 100644 (file)
@@ -231,7 +231,7 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
        while (err == 0) {
                if (rdir->tail == rdir->head) {
                        err = p9_client_readdir(fid, rdir->buf, buflen,
-                                                               filp->f_pos);
+                                               filp->f_pos);
                        if (err <= 0)
                                goto unlock_and_exit;
 
index 3c173fcc2c5a0902be016dd20e6a48411f5d3a55..839d97769e34bf1b3120938d5bf05f3fa52dc1bd 100644 (file)
@@ -65,7 +65,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
        v9inode = V9FS_I(inode);
        v9ses = v9fs_inode2v9ses(inode);
        if (v9fs_proto_dotl(v9ses))
-               omode = file->f_flags;
+               omode = v9fs_open_to_dotl_flags(file->f_flags);
        else
                omode = v9fs_uflags2omode(file->f_flags,
                                        v9fs_proto_dotu(v9ses));
@@ -169,7 +169,18 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
 
        /* convert posix lock to p9 tlock args */
        memset(&flock, 0, sizeof(flock));
-       flock.type = fl->fl_type;
+       /* map the lock type */
+       switch (fl->fl_type) {
+       case F_RDLCK:
+               flock.type = P9_LOCK_TYPE_RDLCK;
+               break;
+       case F_WRLCK:
+               flock.type = P9_LOCK_TYPE_WRLCK;
+               break;
+       case F_UNLCK:
+               flock.type = P9_LOCK_TYPE_UNLCK;
+               break;
+       }
        flock.start = fl->fl_start;
        if (fl->fl_end == OFFSET_MAX)
                flock.length = 0;
@@ -245,7 +256,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
 
        /* convert posix lock to p9 tgetlock args */
        memset(&glock, 0, sizeof(glock));
-       glock.type = fl->fl_type;
+       glock.type  = P9_LOCK_TYPE_UNLCK;
        glock.start = fl->fl_start;
        if (fl->fl_end == OFFSET_MAX)
                glock.length = 0;
@@ -257,7 +268,19 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
        res = p9_client_getlock_dotl(fid, &glock);
        if (res < 0)
                return res;
-       if (glock.type != F_UNLCK) {
+       /* map 9p lock type to os lock type */
+       switch (glock.type) {
+       case P9_LOCK_TYPE_RDLCK:
+               fl->fl_type = F_RDLCK;
+               break;
+       case P9_LOCK_TYPE_WRLCK:
+               fl->fl_type = F_WRLCK;
+               break;
+       case P9_LOCK_TYPE_UNLCK:
+               fl->fl_type = F_UNLCK;
+               break;
+       }
+       if (glock.type != P9_LOCK_TYPE_UNLCK) {
                fl->fl_type = glock.type;
                fl->fl_start = glock.start;
                if (glock.length == 0)
@@ -265,9 +288,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
                else
                        fl->fl_end = glock.start + glock.length - 1;
                fl->fl_pid = glock.proc_id;
-       } else
-               fl->fl_type = F_UNLCK;
-
+       }
        return res;
 }
 
index 8bb5507e822f4151574f564150f48acd4531f002..b2a41e5cee5d75141335e05c2b7851ebaae19f59 100644 (file)
@@ -40,6 +40,7 @@
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
+
 #include "v9fs.h"
 #include "v9fs_vfs.h"
 #include "fid.h"
@@ -95,15 +96,18 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
 /**
  * p9mode2unixmode- convert plan9 mode bits to unix mode bits
  * @v9ses: v9fs session information
- * @mode: mode to convert
+ * @stat: p9_wstat from which mode need to be derived
+ * @rdev: major number, minor number in case of device files.
  *
  */
-
-static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
+static int p9mode2unixmode(struct v9fs_session_info *v9ses,
+                          struct p9_wstat *stat, dev_t *rdev)
 {
        int res;
+       int mode = stat->mode;
 
-       res = mode & 0777;
+       res = mode & S_IALLUGO;
+       *rdev = 0;
 
        if ((mode & P9_DMDIR) == P9_DMDIR)
                res |= S_IFDIR;
@@ -116,9 +120,26 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
                 && (v9ses->nodev == 0))
                res |= S_IFIFO;
        else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
-                && (v9ses->nodev == 0))
-               res |= S_IFBLK;
-       else
+                && (v9ses->nodev == 0)) {
+               char type = 0, ext[32];
+               int major = -1, minor = -1;
+
+               strncpy(ext, stat->extension, sizeof(ext));
+               sscanf(ext, "%c %u %u", &type, &major, &minor);
+               switch (type) {
+               case 'c':
+                       res |= S_IFCHR;
+                       break;
+               case 'b':
+                       res |= S_IFBLK;
+                       break;
+               default:
+                       P9_DPRINTK(P9_DEBUG_ERROR,
+                               "Unknown special type %c %s\n", type,
+                               stat->extension);
+               };
+               *rdev = MKDEV(major, minor);
+       } else
                res |= S_IFREG;
 
        if (v9fs_proto_dotu(v9ses)) {
@@ -131,7 +152,6 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
                if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
                        res |= S_ISVTX;
        }
-
        return res;
 }
 
@@ -242,13 +262,13 @@ void v9fs_destroy_inode(struct inode *inode)
 }
 
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
-                   struct inode *inode, int mode)
+                   struct inode *inode, int mode, dev_t rdev)
 {
        int err = 0;
 
        inode_init_owner(inode, NULL, mode);
        inode->i_blocks = 0;
-       inode->i_rdev = 0;
+       inode->i_rdev = rdev;
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        inode->i_mapping->a_ops = &v9fs_addr_operations;
 
@@ -335,7 +355,7 @@ error:
  *
  */
 
-struct inode *v9fs_get_inode(struct super_block *sb, int mode)
+struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t rdev)
 {
        int err;
        struct inode *inode;
@@ -348,7 +368,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
                P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
                return ERR_PTR(-ENOMEM);
        }
-       err = v9fs_init_inode(v9ses, inode, mode);
+       err = v9fs_init_inode(v9ses, inode, mode, rdev);
        if (err) {
                iput(inode);
                return ERR_PTR(err);
@@ -435,11 +455,12 @@ void v9fs_evict_inode(struct inode *inode)
 static int v9fs_test_inode(struct inode *inode, void *data)
 {
        int umode;
+       dev_t rdev;
        struct v9fs_inode *v9inode = V9FS_I(inode);
        struct p9_wstat *st = (struct p9_wstat *)data;
        struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
 
-       umode = p9mode2unixmode(v9ses, st->mode);
+       umode = p9mode2unixmode(v9ses, st, &rdev);
        /* don't match inode of different type */
        if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
                return 0;
@@ -473,6 +494,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
                                   struct p9_wstat *st,
                                   int new)
 {
+       dev_t rdev;
        int retval, umode;
        unsigned long i_ino;
        struct inode *inode;
@@ -496,8 +518,8 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
         * later.
         */
        inode->i_ino = i_ino;
-       umode = p9mode2unixmode(v9ses, st->mode);
-       retval = v9fs_init_inode(v9ses, inode, umode);
+       umode = p9mode2unixmode(v9ses, st, &rdev);
+       retval = v9fs_init_inode(v9ses, inode, umode, rdev);
        if (retval)
                goto error;
 
@@ -531,6 +553,19 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
        return inode;
 }
 
+/**
+ * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
+ * plan 9 AT flag.
+ * @flags: flags to convert
+ */
+static int v9fs_at_to_dotl_flags(int flags)
+{
+       int rflags = 0;
+       if (flags & AT_REMOVEDIR)
+               rflags |= P9_DOTL_AT_REMOVEDIR;
+       return rflags;
+}
+
 /**
  * v9fs_remove - helper function to remove files and directories
  * @dir: directory inode that is being deleted
@@ -558,7 +593,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
                return retval;
        }
        if (v9fs_proto_dotl(v9ses))
-               retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags);
+               retval = p9_client_unlinkat(dfid, dentry->d_name.name,
+                                           v9fs_at_to_dotl_flags(flags));
        if (retval == -EOPNOTSUPP) {
                /* Try the one based on path */
                v9fid = v9fs_fid_clone(dentry);
@@ -645,13 +681,11 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
                P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
                goto error;
        }
-       d_instantiate(dentry, inode);
        err = v9fs_fid_add(dentry, fid);
        if (err < 0)
                goto error;
-
+       d_instantiate(dentry, inode);
        return ofid;
-
 error:
        if (ofid)
                p9_client_clunk(ofid);
@@ -792,6 +826,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
                                      struct nameidata *nameidata)
 {
+       struct dentry *res;
        struct super_block *sb;
        struct v9fs_session_info *v9ses;
        struct p9_fid *dfid, *fid;
@@ -823,22 +858,35 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
 
                return ERR_PTR(result);
        }
-
-       inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
+       /*
+        * Make sure we don't use a wrong inode due to parallel
+        * unlink. For cached mode create calls request for new
+        * inode. But with cache disabled, lookup should do this.
+        */
+       if (v9ses->cache)
+               inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
+       else
+               inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
        if (IS_ERR(inode)) {
                result = PTR_ERR(inode);
                inode = NULL;
                goto error;
        }
-
        result = v9fs_fid_add(dentry, fid);
        if (result < 0)
                goto error_iput;
-
 inst_out:
-       d_add(dentry, inode);
-       return NULL;
-
+       /*
+        * If we had a rename on the server and a parallel lookup
+        * for the new name, then make sure we instantiate with
+        * the new name. ie look up for a/b, while server somebody
+        * moved b under k and client parallely did a lookup for
+        * k/b.
+        */
+       res = d_materialise_unique(dentry, inode);
+       if (!IS_ERR(res))
+               return res;
+       result = PTR_ERR(res);
 error_iput:
        iput(inode);
 error:
@@ -1002,7 +1050,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
                return PTR_ERR(st);
 
        v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb);
-               generic_fillattr(dentry->d_inode, stat);
+       generic_fillattr(dentry->d_inode, stat);
 
        p9stat_free(st);
        kfree(st);
@@ -1086,6 +1134,7 @@ void
 v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
        struct super_block *sb)
 {
+       mode_t mode;
        char ext[32];
        char tag_name[14];
        unsigned int i_nlink;
@@ -1121,31 +1170,9 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
                                inode->i_nlink = i_nlink;
                }
        }
-       inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
-       if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
-               char type = 0;
-               int major = -1;
-               int minor = -1;
-
-               strncpy(ext, stat->extension, sizeof(ext));
-               sscanf(ext, "%c %u %u", &type, &major, &minor);
-               switch (type) {
-               case 'c':
-                       inode->i_mode &= ~S_IFBLK;
-                       inode->i_mode |= S_IFCHR;
-                       break;
-               case 'b':
-                       break;
-               default:
-                       P9_DPRINTK(P9_DEBUG_ERROR,
-                               "Unknown special type %c %s\n", type,
-                               stat->extension);
-               };
-               inode->i_rdev = MKDEV(major, minor);
-               init_special_inode(inode, inode->i_mode, inode->i_rdev);
-       } else
-               inode->i_rdev = 0;
-
+       mode = stat->mode & S_IALLUGO;
+       mode |= inode->i_mode & ~S_IALLUGO;
+       inode->i_mode = mode;
        i_size_write(inode, stat->length);
 
        /* not real number of blocks, but 512 byte ones ... */
@@ -1411,6 +1438,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 
 int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
 {
+       int umode;
+       dev_t rdev;
        loff_t i_size;
        struct p9_wstat *st;
        struct v9fs_session_info *v9ses;
@@ -1419,6 +1448,12 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
        st = p9_client_stat(fid);
        if (IS_ERR(st))
                return PTR_ERR(st);
+       /*
+        * Don't update inode if the file type is different
+        */
+       umode = p9mode2unixmode(v9ses, st, &rdev);
+       if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
+               goto out;
 
        spin_lock(&inode->i_lock);
        /*
@@ -1430,6 +1465,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
        if (v9ses->cache)
                inode->i_size = i_size;
        spin_unlock(&inode->i_lock);
+out:
        p9stat_free(st);
        kfree(st);
        return 0;
index b6c8ed205192e5ab34f1b8ae15323dcc01fdec34..aded79fcd5cfdadc359929f3b39fad1f92ff2001 100644 (file)
@@ -153,7 +153,8 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
         * later.
         */
        inode->i_ino = i_ino;
-       retval = v9fs_init_inode(v9ses, inode, st->st_mode);
+       retval = v9fs_init_inode(v9ses, inode,
+                                st->st_mode, new_decode_dev(st->st_rdev));
        if (retval)
                goto error;
 
@@ -190,6 +191,58 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
        return inode;
 }
 
+struct dotl_openflag_map {
+       int open_flag;
+       int dotl_flag;
+};
+
+static int v9fs_mapped_dotl_flags(int flags)
+{
+       int i;
+       int rflags = 0;
+       struct dotl_openflag_map dotl_oflag_map[] = {
+               { O_CREAT,      P9_DOTL_CREATE },
+               { O_EXCL,       P9_DOTL_EXCL },
+               { O_NOCTTY,     P9_DOTL_NOCTTY },
+               { O_TRUNC,      P9_DOTL_TRUNC },
+               { O_APPEND,     P9_DOTL_APPEND },
+               { O_NONBLOCK,   P9_DOTL_NONBLOCK },
+               { O_DSYNC,      P9_DOTL_DSYNC },
+               { FASYNC,       P9_DOTL_FASYNC },
+               { O_DIRECT,     P9_DOTL_DIRECT },
+               { O_LARGEFILE,  P9_DOTL_LARGEFILE },
+               { O_DIRECTORY,  P9_DOTL_DIRECTORY },
+               { O_NOFOLLOW,   P9_DOTL_NOFOLLOW },
+               { O_NOATIME,    P9_DOTL_NOATIME },
+               { O_CLOEXEC,    P9_DOTL_CLOEXEC },
+               { O_SYNC,       P9_DOTL_SYNC},
+       };
+       for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
+               if (flags & dotl_oflag_map[i].open_flag)
+                       rflags |= dotl_oflag_map[i].dotl_flag;
+       }
+       return rflags;
+}
+
+/**
+ * v9fs_open_to_dotl_flags- convert Linux specific open flags to
+ * plan 9 open flag.
+ * @flags: flags to convert
+ */
+int v9fs_open_to_dotl_flags(int flags)
+{
+       int rflags = 0;
+
+       /*
+        * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
+        * and P9_DOTL_NOACCESS
+        */
+       rflags |= flags & O_ACCMODE;
+       rflags |= v9fs_mapped_dotl_flags(flags);
+
+       return rflags;
+}
+
 /**
  * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
  * @dir: directory inode that is being created
@@ -258,7 +311,8 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
                           "Failed to get acl values in creat %d\n", err);
                goto error;
        }
-       err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
+       err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
+                                   mode, gid, &qid);
        if (err < 0) {
                P9_DPRINTK(P9_DEBUG_VFS,
                                "p9_client_open_dotl failed in creat %d\n",
@@ -281,10 +335,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
                P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
                goto error;
        }
-       d_instantiate(dentry, inode);
        err = v9fs_fid_add(dentry, fid);
        if (err < 0)
                goto error;
+       d_instantiate(dentry, inode);
 
        /* Now set the ACL based on the default value */
        v9fs_set_create_acl(dentry, &dacl, &pacl);
@@ -403,10 +457,10 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
                                err);
                        goto error;
                }
-               d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        goto error;
+               d_instantiate(dentry, inode);
                fid = NULL;
        } else {
                /*
@@ -414,7 +468,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
                 * inode with stat. We need to get an inode
                 * so that we can set the acl with dentry
                 */
-               inode = v9fs_get_inode(dir->i_sb, mode);
+               inode = v9fs_get_inode(dir->i_sb, mode, 0);
                if (IS_ERR(inode)) {
                        err = PTR_ERR(inode);
                        goto error;
@@ -540,6 +594,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 void
 v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
 {
+       mode_t mode;
        struct v9fs_inode *v9inode = V9FS_I(inode);
 
        if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
@@ -552,11 +607,10 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
                inode->i_uid = stat->st_uid;
                inode->i_gid = stat->st_gid;
                inode->i_nlink = stat->st_nlink;
-               inode->i_mode = stat->st_mode;
-               inode->i_rdev = new_decode_dev(stat->st_rdev);
 
-               if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
-                       init_special_inode(inode, inode->i_mode, inode->i_rdev);
+               mode = stat->st_mode & S_IALLUGO;
+               mode |= inode->i_mode & ~S_IALLUGO;
+               inode->i_mode = mode;
 
                i_size_write(inode, stat->st_size);
                inode->i_blocks = stat->st_blocks;
@@ -657,14 +711,14 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
                                        err);
                        goto error;
                }
-               d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        goto error;
+               d_instantiate(dentry, inode);
                fid = NULL;
        } else {
                /* Not in cached mode. No need to populate inode with stat */
-               inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
+               inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
                if (IS_ERR(inode)) {
                        err = PTR_ERR(inode);
                        goto error;
@@ -810,17 +864,17 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
                                err);
                        goto error;
                }
-               d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        goto error;
+               d_instantiate(dentry, inode);
                fid = NULL;
        } else {
                /*
                 * Not in cached mode. No need to populate inode with stat.
                 * socket syscall returns a fd, so we need instantiate
                 */
-               inode = v9fs_get_inode(dir->i_sb, mode);
+               inode = v9fs_get_inode(dir->i_sb, mode, rdev);
                if (IS_ERR(inode)) {
                        err = PTR_ERR(inode);
                        goto error;
@@ -886,6 +940,11 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
        st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
        if (IS_ERR(st))
                return PTR_ERR(st);
+       /*
+        * Don't update inode if the file type is different
+        */
+       if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
+               goto out;
 
        spin_lock(&inode->i_lock);
        /*
@@ -897,6 +956,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
        if (v9ses->cache)
                inode->i_size = i_size;
        spin_unlock(&inode->i_lock);
+out:
        kfree(st);
        return 0;
 }
index feef6cdc1fd22d23ba45a8f98f2f21ec0a0dc95a..c70251d47ed196c65594365091c1125f4e86d987 100644 (file)
@@ -149,7 +149,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
        else
                sb->s_d_op = &v9fs_dentry_operations;
 
-       inode = v9fs_get_inode(sb, S_IFDIR | mode);
+       inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);
        if (IS_ERR(inode)) {
                retval = PTR_ERR(inode);
                goto release_sb;
index 538e27959d3f7fec79a8a0647723830b2bb4a5b4..7ee7ba48831358f7bf4f738a13c20511dcdd1698 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -13,6 +13,7 @@
 #include <linux/fsnotify.h>
 #include <linux/fcntl.h>
 #include <linux/security.h>
+#include <linux/evm.h>
 
 /**
  * inode_change_ok - check if attribute changes to an inode are allowed
@@ -237,8 +238,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
        else
                error = simple_setattr(dentry, attr);
 
-       if (!error)
+       if (!error) {
                fsnotify_change(dentry, ia_valid);
+               evm_inode_post_setattr(dentry, ia_valid);
+       }
 
        return error;
 }
index 7ec14097fef1f3bbb9b7611a96111c55d0ba9e19..98ab240072e56e0a4550415ab7ec01598ed47c5d 100644 (file)
@@ -340,7 +340,7 @@ again:
                if (freezing(current)) {
                        worker->working = 0;
                        spin_unlock_irq(&worker->lock);
-                       refrigerator();
+                       try_to_freeze();
                } else {
                        spin_unlock_irq(&worker->lock);
                        if (!kthread_should_stop()) {
index 07b3ac662e193e6b3a19180c3c3c9bfccbeb8028..64b1c071bd647bc17aa8de9317c9d9407f9ebd55 100644 (file)
@@ -1508,9 +1508,7 @@ static int cleaner_kthread(void *arg)
                        btrfs_run_defrag_inodes(root->fs_info);
                }
 
-               if (freezing(current)) {
-                       refrigerator();
-               } else {
+               if (!try_to_freeze()) {
                        set_current_state(TASK_INTERRUPTIBLE);
                        if (!kthread_should_stop())
                                schedule();
@@ -1564,9 +1562,7 @@ sleep:
                wake_up_process(root->fs_info->cleaner_kthread);
                mutex_unlock(&root->fs_info->transaction_kthread_mutex);
 
-               if (freezing(current)) {
-                       refrigerator();
-               } else {
+               if (!try_to_freeze()) {
                        set_current_state(TASK_INTERRUPTIBLE);
                        if (!kthread_should_stop() &&
                            !btrfs_transaction_blocked(root->fs_info))
index d733b9cfea343207e71bdb6d8d8b51323717c800..6196e1a76c14fae0be3f584c9440429f68eef72a 100644 (file)
@@ -374,36 +374,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
                                XATTR_REPLACE);
 }
 
-int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
-                             struct inode *inode, struct inode *dir,
-                             const struct qstr *qstr)
+int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                    void *fs_info)
 {
-       int err;
-       size_t len;
-       void *value;
-       char *suffix;
+       const struct xattr *xattr;
+       struct btrfs_trans_handle *trans = fs_info;
        char *name;
+       int err = 0;
 
-       err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
-                                          &len);
-       if (err) {
-               if (err == -EOPNOTSUPP)
-                       return 0;
-               return err;
-       }
-
-       name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
-                      GFP_NOFS);
-       if (!name) {
-               err = -ENOMEM;
-       } else {
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
+                              strlen(xattr->name) + 1, GFP_NOFS);
+               if (!name) {
+                       err = -ENOMEM;
+                       break;
+               }
                strcpy(name, XATTR_SECURITY_PREFIX);
-               strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
-               err = __btrfs_setxattr(trans, inode, name, value, len, 0);
+               strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
+               err = __btrfs_setxattr(trans, inode, name,
+                                      xattr->value, xattr->value_len, 0);
                kfree(name);
+               if (err < 0)
+                       break;
        }
-
-       kfree(suffix);
-       kfree(value);
        return err;
 }
+
+int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
+                             struct inode *inode, struct inode *dir,
+                             const struct qstr *qstr)
+{
+       return security_inode_init_security(inode, dir, qstr,
+                                           &btrfs_initxattrs, trans);
+}
index a0358c2189cb5aba26de002d93727dedd5b7a3fe..3f458310e2876b5b5ea0eaf9bd86500bae2e0520 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/file.h>
 #include <linux/fs.h>
-#include <linux/fsnotify.h>
 #include <linux/quotaops.h>
 #include <linux/xattr.h>
 #include <linux/mount.h>
index e18b183b47e1c2e11aa49ad37ec6cf227305f68f..6e050686e9b364a351761fd660db0bf910fb577a 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/file.h>
 #include <linux/fs.h>
-#include <linux/fsnotify.h>
 #include <linux/quotaops.h>
 #include <linux/xattr.h>
 #include <linux/slab.h>
index 5a3953db81184170a8f221fc6c231996993724d2..e06a32214f0c26455713c5defc64e240f16e6682 100644 (file)
@@ -228,102 +228,154 @@ static int ceph_readpage(struct file *filp, struct page *page)
 }
 
 /*
- * Build a vector of contiguous pages from the provided page list.
+ * Finish an async read(ahead) op.
  */
-static struct page **page_vector_from_list(struct list_head *page_list,
-                                          unsigned *nr_pages)
+static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg)
 {
-       struct page **pages;
-       struct page *page;
-       int next_index, contig_pages = 0;
+       struct inode *inode = req->r_inode;
+       struct ceph_osd_reply_head *replyhead;
+       int rc, bytes;
+       int i;
 
-       /* build page vector */
-       pages = kmalloc(sizeof(*pages) * *nr_pages, GFP_NOFS);
-       if (!pages)
-               return ERR_PTR(-ENOMEM);
+       /* parse reply */
+       replyhead = msg->front.iov_base;
+       WARN_ON(le32_to_cpu(replyhead->num_ops) == 0);
+       rc = le32_to_cpu(replyhead->result);
+       bytes = le32_to_cpu(msg->hdr.data_len);
 
-       BUG_ON(list_empty(page_list));
-       next_index = list_entry(page_list->prev, struct page, lru)->index;
-       list_for_each_entry_reverse(page, page_list, lru) {
-               if (page->index == next_index) {
-                       dout("readpages page %d %p\n", contig_pages, page);
-                       pages[contig_pages] = page;
-                       contig_pages++;
-                       next_index++;
-               } else {
-                       break;
+       dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes);
+
+       /* unlock all pages, zeroing any data we didn't read */
+       for (i = 0; i < req->r_num_pages; i++, bytes -= PAGE_CACHE_SIZE) {
+               struct page *page = req->r_pages[i];
+
+               if (bytes < (int)PAGE_CACHE_SIZE) {
+                       /* zero (remainder of) page */
+                       int s = bytes < 0 ? 0 : bytes;
+                       zero_user_segment(page, s, PAGE_CACHE_SIZE);
                }
+               dout("finish_read %p uptodate %p idx %lu\n", inode, page,
+                    page->index);
+               flush_dcache_page(page);
+               SetPageUptodate(page);
+               unlock_page(page);
+               page_cache_release(page);
        }
-       *nr_pages = contig_pages;
-       return pages;
 }
 
 /*
- * Read multiple pages.  Leave pages we don't read + unlock in page_list;
- * the caller (VM) cleans them up.
+ * start an async read(ahead) operation.  return nr_pages we submitted
+ * a read for on success, or negative error code.
  */
-static int ceph_readpages(struct file *file, struct address_space *mapping,
-                         struct list_head *page_list, unsigned nr_pages)
+static int start_read(struct inode *inode, struct list_head *page_list, int max)
 {
-       struct inode *inode = file->f_dentry->d_inode;
-       struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_osd_client *osdc =
                &ceph_inode_to_client(inode)->client->osdc;
-       int rc = 0;
-       struct page **pages;
-       loff_t offset;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct page *page = list_entry(page_list->prev, struct page, lru);
+       struct ceph_osd_request *req;
+       u64 off;
        u64 len;
+       int i;
+       struct page **pages;
+       pgoff_t next_index;
+       int nr_pages = 0;
+       int ret;
 
-       dout("readpages %p file %p nr_pages %d\n",
-            inode, file, nr_pages);
-
-       pages = page_vector_from_list(page_list, &nr_pages);
-       if (IS_ERR(pages))
-               return PTR_ERR(pages);
+       off = page->index << PAGE_CACHE_SHIFT;
 
-       /* guess read extent */
-       offset = pages[0]->index << PAGE_CACHE_SHIFT;
+       /* count pages */
+       next_index = page->index;
+       list_for_each_entry_reverse(page, page_list, lru) {
+               if (page->index != next_index)
+                       break;
+               nr_pages++;
+               next_index++;
+               if (max && nr_pages == max)
+                       break;
+       }
        len = nr_pages << PAGE_CACHE_SHIFT;
-       rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
-                                offset, &len,
-                                ci->i_truncate_seq, ci->i_truncate_size,
-                                pages, nr_pages, 0);
-       if (rc == -ENOENT)
-               rc = 0;
-       if (rc < 0)
-               goto out;
-
-       for (; !list_empty(page_list) && len > 0;
-            rc -= PAGE_CACHE_SIZE, len -= PAGE_CACHE_SIZE) {
-               struct page *page =
-                       list_entry(page_list->prev, struct page, lru);
+       dout("start_read %p nr_pages %d is %lld~%lld\n", inode, nr_pages,
+            off, len);
+
+       req = ceph_osdc_new_request(osdc, &ci->i_layout, ceph_vino(inode),
+                                   off, &len,
+                                   CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
+                                   NULL, 0,
+                                   ci->i_truncate_seq, ci->i_truncate_size,
+                                   NULL, false, 1, 0);
+       if (!req)
+               return -ENOMEM;
 
+       /* build page vector */
+       nr_pages = len >> PAGE_CACHE_SHIFT;
+       pages = kmalloc(sizeof(*pages) * nr_pages, GFP_NOFS);
+       ret = -ENOMEM;
+       if (!pages)
+               goto out;
+       for (i = 0; i < nr_pages; ++i) {
+               page = list_entry(page_list->prev, struct page, lru);
+               BUG_ON(PageLocked(page));
                list_del(&page->lru);
-
-               if (rc < (int)PAGE_CACHE_SIZE) {
-                       /* zero (remainder of) page */
-                       int s = rc < 0 ? 0 : rc;
-                       zero_user_segment(page, s, PAGE_CACHE_SIZE);
-               }
-
-               if (add_to_page_cache_lru(page, mapping, page->index,
+               
+               dout("start_read %p adding %p idx %lu\n", inode, page,
+                    page->index);
+               if (add_to_page_cache_lru(page, &inode->i_data, page->index,
                                          GFP_NOFS)) {
                        page_cache_release(page);
-                       dout("readpages %p add_to_page_cache failed %p\n",
+                       dout("start_read %p add_to_page_cache failed %p\n",
                             inode, page);
-                       continue;
+                       nr_pages = i;
+                       goto out_pages;
                }
-               dout("readpages %p adding %p idx %lu\n", inode, page,
-                    page->index);
-               flush_dcache_page(page);
-               SetPageUptodate(page);
-               unlock_page(page);
-               page_cache_release(page);
+               pages[i] = page;
        }
-       rc = 0;
+       req->r_pages = pages;
+       req->r_num_pages = nr_pages;
+       req->r_callback = finish_read;
+       req->r_inode = inode;
+
+       dout("start_read %p starting %p %lld~%lld\n", inode, req, off, len);
+       ret = ceph_osdc_start_request(osdc, req, false);
+       if (ret < 0)
+               goto out_pages;
+       ceph_osdc_put_request(req);
+       return nr_pages;
 
+out_pages:
+       ceph_release_page_vector(pages, nr_pages);
+out:
+       ceph_osdc_put_request(req);
+       return ret;
+}
+
+
+/*
+ * Read multiple pages.  Leave pages we don't read + unlock in page_list;
+ * the caller (VM) cleans them up.
+ */
+static int ceph_readpages(struct file *file, struct address_space *mapping,
+                         struct list_head *page_list, unsigned nr_pages)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
+       int rc = 0;
+       int max = 0;
+
+       if (fsc->mount_options->rsize >= PAGE_CACHE_SIZE)
+               max = (fsc->mount_options->rsize + PAGE_CACHE_SIZE - 1)
+                       >> PAGE_SHIFT;
+
+       dout("readpages %p file %p nr_pages %d max %d\n", inode, file, nr_pages,
+            max);
+       while (!list_empty(page_list)) {
+               rc = start_read(inode, page_list, max);
+               if (rc < 0)
+                       goto out;
+               BUG_ON(rc == 0);
+       }
 out:
-       kfree(pages);
+       dout("readpages %p file %p ret %d\n", inode, file, rc);
        return rc;
 }
 
index 8d74ad7ba556624c4eb80e1f598ac908e5356d04..b8731bf3ef1f01c9e728788cc23a9aaecb76bbca 100644 (file)
@@ -945,7 +945,7 @@ static int send_cap_msg(struct ceph_mds_session *session,
             seq, issue_seq, mseq, follows, size, max_size,
             xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0);
 
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), GFP_NOFS);
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), GFP_NOFS, false);
        if (!msg)
                return -ENOMEM;
 
index 0c5167e43180c9a0f41b24f39a35b0a4e5de1246..be4a604873331dc7c547950650a899b514f56d26 100644 (file)
@@ -6,7 +6,31 @@
 
 #define CEPH_IOCTL_MAGIC 0x97
 
-/* just use u64 to align sanely on all archs */
+/*
+ * CEPH_IOC_GET_LAYOUT - get file layout or dir layout policy
+ * CEPH_IOC_SET_LAYOUT - set file layout
+ * CEPH_IOC_SET_LAYOUT_POLICY - set dir layout policy
+ *
+ * The file layout specifies how file data is striped over objects in
+ * the distributed object store, which object pool they belong to (if
+ * it differs from the default), and an optional 'preferred osd' to
+ * store them on.
+ *
+ * Files get a new layout based on the policy set on the containing
+ * directory or one of its ancestors.  The GET_LAYOUT ioctl will let
+ * you examine the layout for a file or the policy on a directory.
+ *
+ * SET_LAYOUT will let you set a layout on a newly created file.  This
+ * only works immediately after the file is created and before any
+ * data is written to it.
+ *
+ * SET_LAYOUT_POLICY will let you set a layout policy (default layout)
+ * on a directory that will apply to any new files created in that
+ * directory (or any child directory that doesn't specify a layout of
+ * its own).
+ */
+
+/* use u64 to align sanely on all archs */
 struct ceph_ioctl_layout {
        __u64 stripe_unit, stripe_count, object_size;
        __u64 data_pool;
@@ -21,6 +45,8 @@ struct ceph_ioctl_layout {
                                   struct ceph_ioctl_layout)
 
 /*
+ * CEPH_IOC_GET_DATALOC - get location of file data in the cluster
+ *
  * Extract identity, address of the OSD and object storing a given
  * file offset.
  */
@@ -39,7 +65,34 @@ struct ceph_ioctl_dataloc {
 #define CEPH_IOC_GET_DATALOC _IOWR(CEPH_IOCTL_MAGIC, 3,        \
                                   struct ceph_ioctl_dataloc)
 
+/*
+ * CEPH_IOC_LAZYIO - relax consistency
+ *
+ * Normally Ceph switches to synchronous IO when multiple clients have
+ * the file open (and or more for write).  Reads and writes bypass the
+ * page cache and go directly to the OSD.  Setting this flag on a file
+ * descriptor will allow buffered IO for this file in cases where the
+ * application knows it won't interfere with other nodes (or doesn't
+ * care).
+ */
 #define CEPH_IOC_LAZYIO _IO(CEPH_IOCTL_MAGIC, 4)
+
+/*
+ * CEPH_IOC_SYNCIO - force synchronous IO
+ *
+ * This ioctl sets a file flag that forces the synchronous IO that
+ * bypasses the page cache, even if it is not necessary.  This is
+ * essentially the opposite behavior of IOC_LAZYIO.  This forces the
+ * same read/write path as a file opened by multiple clients when one
+ * or more of those clients is opened for write.
+ *
+ * Note that this type of sync IO takes a different path than a file
+ * opened with O_SYNC/D_SYNC (writes hit the page cache and are
+ * immediately flushed on page boundaries).  It is very similar to
+ * O_DIRECT (writes bypass the page cache) excep that O_DIRECT writes
+ * are not copied (user page must remain stable) and O_DIRECT writes
+ * have alignment restrictions (on the buffer and file offset).
+ */
 #define CEPH_IOC_SYNCIO _IO(CEPH_IOCTL_MAGIC, 5)
 
 #endif
index fee028b5332e0d802b26fdc94dab21057b41028a..2712e8ff34d1f8ae72fd988d3ebb0cd05f435012 100644 (file)
@@ -764,7 +764,8 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq)
        struct ceph_msg *msg;
        struct ceph_mds_session_head *h;
 
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), GFP_NOFS);
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), GFP_NOFS,
+                          false);
        if (!msg) {
                pr_err("create_session_msg ENOMEM creating msg\n");
                return NULL;
@@ -1240,7 +1241,7 @@ int ceph_add_cap_releases(struct ceph_mds_client *mdsc,
        while (session->s_num_cap_releases < session->s_nr_caps + extra) {
                spin_unlock(&session->s_cap_lock);
                msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
-                                  GFP_NOFS);
+                                  GFP_NOFS, false);
                if (!msg)
                        goto out_unlocked;
                dout("add_cap_releases %p msg %p now %d\n", session, msg,
@@ -1652,7 +1653,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        if (req->r_old_dentry_drop)
                len += req->r_old_dentry->d_name.len;
 
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, GFP_NOFS);
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, GFP_NOFS, false);
        if (!msg) {
                msg = ERR_PTR(-ENOMEM);
                goto out_free2;
@@ -2518,7 +2519,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
                goto fail_nopagelist;
        ceph_pagelist_init(pagelist);
 
-       reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, GFP_NOFS);
+       reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, GFP_NOFS, false);
        if (!reply)
                goto fail_nomsg;
 
@@ -2831,7 +2832,7 @@ void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
        dnamelen = dentry->d_name.len;
        len += dnamelen;
 
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS);
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS, false);
        if (!msg)
                return;
        lease = msg->front.iov_base;
index d47c5ec7fb1ff0500ebbeb7f403debfa865c87a0..e0a6a0631ae0021ddc22bf9ed42c741cb6173eb8 100644 (file)
@@ -114,6 +114,7 @@ static int ceph_sync_fs(struct super_block *sb, int wait)
 enum {
        Opt_wsize,
        Opt_rsize,
+       Opt_rasize,
        Opt_caps_wanted_delay_min,
        Opt_caps_wanted_delay_max,
        Opt_cap_release_safety,
@@ -136,6 +137,7 @@ enum {
 static match_table_t fsopt_tokens = {
        {Opt_wsize, "wsize=%d"},
        {Opt_rsize, "rsize=%d"},
+       {Opt_rasize, "rasize=%d"},
        {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
        {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
        {Opt_cap_release_safety, "cap_release_safety=%d"},
@@ -196,6 +198,9 @@ static int parse_fsopt_token(char *c, void *private)
        case Opt_rsize:
                fsopt->rsize = intval;
                break;
+       case Opt_rasize:
+               fsopt->rasize = intval;
+               break;
        case Opt_caps_wanted_delay_min:
                fsopt->caps_wanted_delay_min = intval;
                break;
@@ -293,6 +298,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
         fsopt->flags = CEPH_MOUNT_OPT_DEFAULT;
 
         fsopt->rsize = CEPH_RSIZE_DEFAULT;
+        fsopt->rasize = CEPH_RASIZE_DEFAULT;
         fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
        fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
        fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
@@ -376,6 +382,8 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
                seq_printf(m, ",wsize=%d", fsopt->wsize);
        if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
                seq_printf(m, ",rsize=%d", fsopt->rsize);
+       if (fsopt->rasize != CEPH_RASIZE_DEFAULT)
+               seq_printf(m, ",rasize=%d", fsopt->rsize);
        if (fsopt->congestion_kb != default_congestion_kb())
                seq_printf(m, ",write_congestion_kb=%d", fsopt->congestion_kb);
        if (fsopt->caps_wanted_delay_min != CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT)
@@ -422,20 +430,23 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
                                        struct ceph_options *opt)
 {
        struct ceph_fs_client *fsc;
+       const unsigned supported_features =
+               CEPH_FEATURE_FLOCK |
+               CEPH_FEATURE_DIRLAYOUTHASH;
+       const unsigned required_features = 0;
        int err = -ENOMEM;
 
        fsc = kzalloc(sizeof(*fsc), GFP_KERNEL);
        if (!fsc)
                return ERR_PTR(-ENOMEM);
 
-       fsc->client = ceph_create_client(opt, fsc);
+       fsc->client = ceph_create_client(opt, fsc, supported_features,
+                                        required_features);
        if (IS_ERR(fsc->client)) {
                err = PTR_ERR(fsc->client);
                goto fail;
        }
        fsc->client->extra_mon_dispatch = extra_mon_dispatch;
-       fsc->client->supported_features |= CEPH_FEATURE_FLOCK |
-               CEPH_FEATURE_DIRLAYOUTHASH;
        fsc->client->monc.want_mdsmap = 1;
 
        fsc->mount_options = fsopt;
@@ -774,10 +785,10 @@ static int ceph_register_bdi(struct super_block *sb,
 {
        int err;
 
-       /* set ra_pages based on rsize mount option? */
-       if (fsc->mount_options->rsize >= PAGE_CACHE_SIZE)
+       /* set ra_pages based on rasize mount option? */
+       if (fsc->mount_options->rasize >= PAGE_CACHE_SIZE)
                fsc->backing_dev_info.ra_pages =
-                       (fsc->mount_options->rsize + PAGE_CACHE_SIZE - 1)
+                       (fsc->mount_options->rasize + PAGE_CACHE_SIZE - 1)
                        >> PAGE_SHIFT;
        else
                fsc->backing_dev_info.ra_pages =
index a23eed526f05c5c1509c2c9f713681a5d5a4fd18..5c72430b8f7171abbebe4c203f2f7a8d0ebed030 100644 (file)
@@ -36,7 +36,8 @@
 #define ceph_test_mount_opt(fsc, opt) \
        (!!((fsc)->mount_options->flags & CEPH_MOUNT_OPT_##opt))
 
-#define CEPH_RSIZE_DEFAULT             (512*1024) /* readahead */
+#define CEPH_RSIZE_DEFAULT             0           /* max read size */
+#define CEPH_RASIZE_DEFAULT            (8192*1024) /* readahead */
 #define CEPH_MAX_READDIR_DEFAULT        1024
 #define CEPH_MAX_READDIR_BYTES_DEFAULT  (512*1024)
 #define CEPH_SNAPDIRNAME_DEFAULT        ".snap"
@@ -45,8 +46,9 @@ struct ceph_mount_options {
        int flags;
        int sb_flags;
 
-       int wsize;
-       int rsize;            /* max readahead */
+       int wsize;            /* max write size */
+       int rsize;            /* max read size */
+       int rasize;           /* max readahead */
        int congestion_kb;    /* max writeback in flight */
        int caps_wanted_delay_min, caps_wanted_delay_max;
        int cap_release_safety;
index aac37d99a487bfe9b40d1107ba67973bf212ed54..a80f7bd97b90d541e9305d7e225c708f3f0cd3d1 100644 (file)
@@ -4079,7 +4079,8 @@ int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
        T2_FNEXT_RSP_PARMS *parms;
        char *response_data;
        int rc = 0;
-       int bytes_returned, name_len;
+       int bytes_returned;
+       unsigned int name_len;
        __u16 params, byte_count;
 
        cFYI(1, "In FindNext");
index 2a22fb2989e4780fd977c683b27ddf23e78e7d8e..c323088821485c226db0e0c0cb72f22f36370a7b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/fs.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #include "cifsglob.h"
 #define MAX_EA_VALUE_SIZE 65535
 #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
 #define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
-#define CIFS_XATTR_USER_PREFIX "user."
-#define CIFS_XATTR_SYSTEM_PREFIX "system."
-#define CIFS_XATTR_OS2_PREFIX "os2."
-#define CIFS_XATTR_SECURITY_PREFIX "security."
-#define CIFS_XATTR_TRUSTED_PREFIX "trusted."
-#define XATTR_TRUSTED_PREFIX_LEN  8
-#define XATTR_SECURITY_PREFIX_LEN 9
-/* BB need to add server (Samba e.g) support for security and trusted prefix */
-
 
+/* BB need to add server (Samba e.g) support for security and trusted prefix */
 
 int cifs_removexattr(struct dentry *direntry, const char *ea_name)
 {
@@ -76,8 +69,8 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
        }
        if (ea_name == NULL) {
                cFYI(1, "Null xattr names not supported");
-       } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)
-               && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {
+       } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
+               && (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) {
                cFYI(1,
                     "illegal xattr request %s (only user namespace supported)",
                     ea_name);
@@ -88,7 +81,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto remove_ea_exit;
 
-               ea_name += 5; /* skip past user. prefix */
+               ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
                rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
                        (__u16)0, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -149,21 +142,23 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
 
        if (ea_name == NULL) {
                cFYI(1, "Null xattr names not supported");
-       } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
+       } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
+                  == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto set_ea_exit;
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
                        cFYI(1, "attempt to set cifs inode metadata");
 
-               ea_name += 5; /* skip past user. prefix */
+               ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
                rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
                        (__u16)value_size, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-       } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
+       } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)
+                  == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto set_ea_exit;
 
-               ea_name += 4; /* skip past os2. prefix */
+               ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
                rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
                        (__u16)value_size, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -269,7 +264,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
        /* return alt name if available as pseudo attr */
        if (ea_name == NULL) {
                cFYI(1, "Null xattr names not supported");
-       } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
+       } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
+                  == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto get_ea_exit;
 
@@ -277,15 +273,15 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                        cFYI(1, "attempt to query cifs inode metadata");
                        /* revalidate/getattr then populate from inode */
                } /* BB add else when above is implemented */
-               ea_name += 5; /* skip past user. prefix */
+               ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
                rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
                        buf_size, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-       } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {
+       } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto get_ea_exit;
 
-               ea_name += 4; /* skip past os2. prefix */
+               ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
                rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
                        buf_size, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -339,10 +335,10 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                cFYI(1, "Query CIFS ACL not supported yet");
 #endif /* CONFIG_CIFS_ACL */
        } else if (strncmp(ea_name,
-                 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
+                 XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
                cFYI(1, "Trusted xattr namespace not supported yet");
        } else if (strncmp(ea_name,
-                 CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
+                 XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
                cFYI(1, "Security xattr namespace not supported yet");
        } else
                cFYI(1,
index e7a7a2f07324bbca0434445c04bfc8e181e001de..f3a257d7a9859b3598506330afa92ad6cb3ee502 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  file.c - part of debugfs, a tiny little debug file system
+ *  inode.c - part of debugfs, a tiny little debug file system
  *
  *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
  *  Copyright (C) 2004 IBM Inc.
index fe047d966dc5d9af1430dbb7596a511ce57131cb..9026fc91fe3bf34f2b8d71fd084dfac3ef1aa05c 100644 (file)
@@ -700,7 +700,7 @@ static const struct file_operations eventpoll_fops = {
        .llseek         = noop_llseek,
 };
 
-/* Fast test to see if the file is an evenpoll file */
+/* Fast test to see if the file is an eventpoll file */
 static inline int is_file_epoll(struct file *f)
 {
        return f->f_op == &eventpoll_fops;
index 25dcbe5fc35664d6f389ce48f051d6528d607014..8433e5de1c700b2b24fe8b52aeb858309684da2e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1914,7 +1914,6 @@ static int coredump_wait(int exit_code, struct core_state *core_state)
 {
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
-       struct completion *vfork_done;
        int core_waiters = -EBUSY;
 
        init_completion(&core_state->startup);
@@ -1926,22 +1925,9 @@ static int coredump_wait(int exit_code, struct core_state *core_state)
                core_waiters = zap_threads(tsk, mm, core_state, exit_code);
        up_write(&mm->mmap_sem);
 
-       if (unlikely(core_waiters < 0))
-               goto fail;
-
-       /*
-        * Make sure nobody is waiting for us to release the VM,
-        * otherwise we can deadlock when we wait on each other
-        */
-       vfork_done = tsk->vfork_done;
-       if (vfork_done) {
-               tsk->vfork_done = NULL;
-               complete(vfork_done);
-       }
-
-       if (core_waiters)
+       if (core_waiters > 0)
                wait_for_completion(&core_state->startup);
-fail:
+
        return core_waiters;
 }
 
index f4e442ec74452ce993c22c4f65051fd86855f188..7469981e618f1d1f6f65792643c70d4a3b8884e2 100644 (file)
@@ -66,9 +66,6 @@ struct exofs_sb_info {
        u32             s_next_generation;      /* next gen # to use          */
        atomic_t        s_curr_pending;         /* number of pending commands */
 
-       struct pnfs_osd_data_map data_map;      /* Default raid to use
-                                                * FIXME: Needed ?
-                                                */
        struct ore_layout       layout;         /* Default files layout       */
        struct ore_comp one_comp;               /* id & cred of partition id=0*/
        struct ore_components comps;            /* comps for the partition    */
index 274894053b025b69e9908012b11fc6d10ab32306..4628d37b1ca8ad2318b74cd775e9a4f25336515a 100644 (file)
@@ -481,64 +481,51 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
 {
        u64 stripe_length;
 
-       sbi->data_map.odm_num_comps   =
-                               le32_to_cpu(dt->dt_data_map.cb_num_comps);
-       sbi->data_map.odm_stripe_unit =
+       sbi->layout.stripe_unit =
                                le64_to_cpu(dt->dt_data_map.cb_stripe_unit);
-       sbi->data_map.odm_group_width =
+       sbi->layout.group_width =
                                le32_to_cpu(dt->dt_data_map.cb_group_width);
-       sbi->data_map.odm_group_depth =
+       sbi->layout.group_depth =
                                le32_to_cpu(dt->dt_data_map.cb_group_depth);
-       sbi->data_map.odm_mirror_cnt  =
-                               le32_to_cpu(dt->dt_data_map.cb_mirror_cnt);
-       sbi->data_map.odm_raid_algorithm  =
+       sbi->layout.mirrors_p1  =
+                               le32_to_cpu(dt->dt_data_map.cb_mirror_cnt) + 1;
+       sbi->layout.raid_algorithm  =
                                le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);
 
 /* FIXME: Only raid0 for now. if not so, do not mount */
-       if (sbi->data_map.odm_num_comps != numdevs) {
-               EXOFS_ERR("odm_num_comps(%u) != numdevs(%u)\n",
-                         sbi->data_map.odm_num_comps, numdevs);
-               return -EINVAL;
-       }
-       if (sbi->data_map.odm_raid_algorithm != PNFS_OSD_RAID_0) {
+       if (sbi->layout.raid_algorithm != PNFS_OSD_RAID_0) {
                EXOFS_ERR("Only RAID_0 for now\n");
                return -EINVAL;
        }
-       if (0 != (numdevs % (sbi->data_map.odm_mirror_cnt + 1))) {
-               EXOFS_ERR("Data Map wrong, numdevs=%d mirrors=%d\n",
-                         numdevs, sbi->data_map.odm_mirror_cnt);
+       if (numdevs < (sbi->layout.group_width * sbi->layout.mirrors_p1)) {
+               EXOFS_ERR("Data Map wrong, "
+                         "numdevs=%d < group_width=%d * mirrors=%d\n",
+                         numdevs, sbi->layout.group_width,
+                         sbi->layout.mirrors_p1);
                return -EINVAL;
        }
 
-       if (0 != (sbi->data_map.odm_stripe_unit & ~PAGE_MASK)) {
+       if (0 != (sbi->layout.stripe_unit & ~PAGE_MASK)) {
                EXOFS_ERR("Stripe Unit(0x%llx)"
                          " must be Multples of PAGE_SIZE(0x%lx)\n",
-                         _LLU(sbi->data_map.odm_stripe_unit), PAGE_SIZE);
+                         _LLU(sbi->layout.stripe_unit), PAGE_SIZE);
                return -EINVAL;
        }
 
-       sbi->layout.stripe_unit = sbi->data_map.odm_stripe_unit;
-       sbi->layout.mirrors_p1 = sbi->data_map.odm_mirror_cnt + 1;
-
-       if (sbi->data_map.odm_group_width) {
-               sbi->layout.group_width = sbi->data_map.odm_group_width;
-               sbi->layout.group_depth = sbi->data_map.odm_group_depth;
+       if (sbi->layout.group_width) {
                if (!sbi->layout.group_depth) {
                        EXOFS_ERR("group_depth == 0 && group_width != 0\n");
                        return -EINVAL;
                }
-               sbi->layout.group_count = sbi->data_map.odm_num_comps /
-                                               sbi->layout.mirrors_p1 /
-                                               sbi->data_map.odm_group_width;
+               sbi->layout.group_count = numdevs / sbi->layout.mirrors_p1 /
+                                               sbi->layout.group_width;
        } else {
-               if (sbi->data_map.odm_group_depth) {
+               if (sbi->layout.group_depth) {
                        printk(KERN_NOTICE "Warning: group_depth ignored "
-                               "group_width == 0 && group_depth == %d\n",
-                               sbi->data_map.odm_group_depth);
-                       sbi->data_map.odm_group_depth = 0;
+                               "group_width == 0 && group_depth == %lld\n",
+                               _LLU(sbi->layout.group_depth));
                }
-               sbi->layout.group_width = sbi->data_map.odm_num_comps /
-                                                       sbi->layout.mirrors_p1;
+               sbi->layout.group_width = numdevs / sbi->layout.mirrors_p1;
                sbi->layout.group_depth = -1;
                sbi->layout.group_count = 1;
        }
@@ -558,7 +545,7 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
                sbi->layout.group_width,
                _LLU(sbi->layout.group_depth),
                sbi->layout.mirrors_p1,
-               sbi->data_map.odm_raid_algorithm);
+               sbi->layout.raid_algorithm);
        return 0;
 }
 
index 5d979b4347b03c3b3820f6cb14c8566cdeb9497a..c922adc8ef4175844c42a2dcb4b08d7499694d08 100644 (file)
@@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
                              value, size, flags);
 }
 
-int
-ext2_init_security(struct inode *inode, struct inode *dir,
-                  const struct qstr *qstr)
+int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                   void *fs_info)
 {
-       int err;
-       size_t len;
-       void *value;
-       char *name;
+       const struct xattr *xattr;
+       int err = 0;
 
-       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
-       if (err) {
-               if (err == -EOPNOTSUPP)
-                       return 0;
-               return err;
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
+                                    xattr->name, xattr->value,
+                                    xattr->value_len, 0);
+               if (err < 0)
+                       break;
        }
-       err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
-                            name, value, len, 0);
-       kfree(name);
-       kfree(value);
        return err;
 }
 
+int
+ext2_init_security(struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
+{
+       return security_inode_init_security(inode, dir, qstr,
+                                           &ext2_initxattrs, NULL);
+}
+
 const struct xattr_handler ext2_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
        .list   = ext2_xattr_security_list,
index b8d9f83aa5c545f23b48f14530b6ee0578204a66..3c218b8a51d4a4668e3edb4ea144f92cc71dce7d 100644 (file)
@@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
                              name, value, size, flags);
 }
 
-int
-ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
-                  const struct qstr *qstr)
+int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                   void *fs_info)
 {
-       int err;
-       size_t len;
-       void *value;
-       char *name;
+       const struct xattr *xattr;
+       handle_t *handle = fs_info;
+       int err = 0;
 
-       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
-       if (err) {
-               if (err == -EOPNOTSUPP)
-                       return 0;
-               return err;
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               err = ext3_xattr_set_handle(handle, inode,
+                                           EXT3_XATTR_INDEX_SECURITY,
+                                           xattr->name, xattr->value,
+                                           xattr->value_len, 0);
+               if (err < 0)
+                       break;
        }
-       err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
-                                   name, value, len, 0);
-       kfree(name);
-       kfree(value);
        return err;
 }
 
+int
+ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
+{
+       return security_inode_init_security(inode, dir, qstr,
+                                           &ext3_initxattrs, handle);
+}
+
 const struct xattr_handler ext3_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
        .list   = ext3_xattr_security_list,
index e717dfd2f2b4b2e1871e4c66452202b89191ba61..b4bff1a38cf4fe9840e494b787e7e62cfb1d0aeb 100644 (file)
@@ -357,8 +357,7 @@ struct flex_groups {
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
-                          EXT4_SYNC_FL | EXT4_IMMUTABLE_FL | EXT4_APPEND_FL |\
-                          EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
+                          EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
                           EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
                           EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL)
 
@@ -528,6 +527,11 @@ struct ext4_new_group_data {
 #define EXT4_FREE_BLOCKS_VALIDATED     0x0004
 #define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE        0x0008
 
+/*
+ * Flags used by ext4_discard_partial_page_buffers
+ */
+#define EXT4_DSCRD_PARTIAL_PG_ZERO_UNMAPED     0x0001
+
 /*
  * ioctl commands
  */
@@ -917,6 +921,9 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_DISCARD             0x40000000 /* Issue DISCARD requests */
 #define EXT4_MOUNT_INIT_INODE_TABLE    0x80000000 /* Initialize uninitialized itables */
 
+#define EXT4_MOUNT2_EXPLICIT_DELALLOC  0x00000001 /* User explicitly
+                                                     specified delalloc */
+
 #define clear_opt(sb, opt)             EXT4_SB(sb)->s_mount_opt &= \
                                                ~EXT4_MOUNT_##opt
 #define set_opt(sb, opt)               EXT4_SB(sb)->s_mount_opt |= \
@@ -1838,6 +1845,12 @@ extern int ext4_block_truncate_page(handle_t *handle,
                struct address_space *mapping, loff_t from);
 extern int ext4_block_zero_page_range(handle_t *handle,
                struct address_space *mapping, loff_t from, loff_t length);
+extern int ext4_discard_partial_page_buffers(handle_t *handle,
+               struct address_space *mapping, loff_t from,
+               loff_t length, int flags);
+extern int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
+               struct inode *inode, struct page *page, loff_t from,
+               loff_t length, int flags);
 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
 extern qsize_t *ext4_get_reserved_space(struct inode *inode);
 extern void ext4_da_update_reserve_space(struct inode *inode,
index 57cf568a98ab652afcfe3581d093d5f2b5758689..475ddf5efba6a21b025d4e7c58e430162feae1c9 100644 (file)
@@ -4162,16 +4162,30 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
        struct address_space *mapping = inode->i_mapping;
        struct ext4_map_blocks map;
        handle_t *handle;
-       loff_t first_block_offset, last_block_offset, block_len;
+       loff_t first_block_offset, last_block_offset, page_len;
        loff_t first_page, last_page, first_page_offset, last_page_offset;
        int ret, credits, blocks_released, err = 0;
 
+       /* No need to punch hole beyond i_size */
+       if (offset >= inode->i_size)
+               return 0;
+
+       /*
+        * If the hole extends beyond i_size, set the hole
+        * to end after the page that contains i_size
+        */
+       if (offset + length > inode->i_size) {
+               length = inode->i_size +
+                  PAGE_CACHE_SIZE - (inode->i_size & (PAGE_CACHE_SIZE - 1)) -
+                  offset;
+       }
+
        first_block = (offset + sb->s_blocksize - 1) >>
                EXT4_BLOCK_SIZE_BITS(sb);
        last_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
 
-       first_block_offset = first_block << EXT4_BLOCK_SIZE_BITS(sb);
-       last_block_offset = last_block << EXT4_BLOCK_SIZE_BITS(sb);
+       first_block_offset = ((loff_t)first_block) << EXT4_BLOCK_SIZE_BITS(sb);
+       last_block_offset = ((loff_t)last_block) << EXT4_BLOCK_SIZE_BITS(sb);
 
        first_page = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
        last_page = (offset + length) >> PAGE_CACHE_SHIFT;
@@ -4185,11 +4199,10 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
         */
        if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
                err = filemap_write_and_wait_range(mapping,
-                       first_page_offset == 0 ? 0 : first_page_offset-1,
-                       last_page_offset);
+                       offset, offset + length - 1);
 
-                       if (err)
-                               return err;
+               if (err)
+                       return err;
        }
 
        /* Now release the pages */
@@ -4211,24 +4224,53 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
                goto out;
 
        /*
-        * Now we need to zero out the un block aligned data.
-        * If the file is smaller than a block, just
-        * zero out the middle
+        * Now we need to zero out the non-page-aligned data in the
+        * pages at the start and tail of the hole, and unmap the buffer
+        * heads for the block aligned regions of the page that were
+        * completely zeroed.
         */
-       if (first_block > last_block)
-               ext4_block_zero_page_range(handle, mapping, offset, length);
-       else {
-               /* zero out the head of the hole before the first block */
-               block_len  = first_block_offset - offset;
-               if (block_len > 0)
-                       ext4_block_zero_page_range(handle, mapping,
-                                                  offset, block_len);
-
-               /* zero out the tail of the hole after the last block */
-               block_len = offset + length - last_block_offset;
-               if (block_len > 0) {
-                       ext4_block_zero_page_range(handle, mapping,
-                                       last_block_offset, block_len);
+       if (first_page > last_page) {
+               /*
+                * If the file space being truncated is contained within a page
+                * just zero out and unmap the middle of that page
+                */
+               ext4_discard_partial_page_buffers(handle,
+                       mapping, offset, length, 0);
+       } else {
+               /*
+                * zero out and unmap the partial page that contains
+                * the start of the hole
+                */
+               page_len  = first_page_offset - offset;
+               if (page_len > 0)
+                       ext4_discard_partial_page_buffers(handle, mapping,
+                                                  offset, page_len, 0);
+
+               /*
+                * zero out and unmap the partial page that contains
+                * the end of the hole
+                */
+               page_len = offset + length - last_page_offset;
+               if (page_len > 0) {
+                       ext4_discard_partial_page_buffers(handle, mapping,
+                                       last_page_offset, page_len, 0);
+               }
+       }
+
+
+       /*
+        * If i_size is contained in the last page, we need to
+        * unmap and zero the partial page after i_size
+        */
+       if (inode->i_size >> PAGE_CACHE_SHIFT == last_page &&
+          inode->i_size % PAGE_CACHE_SIZE != 0) {
+
+               page_len = PAGE_CACHE_SIZE -
+                       (inode->i_size & (PAGE_CACHE_SIZE - 1));
+
+               if (page_len > 0) {
+                       ext4_discard_partial_page_buffers(handle,
+                         mapping, inode->i_size, page_len, 0);
                }
        }
 
index c4da98a959ae06deb04e25663ce8b697b0b31458..c3ce7547e315d410a760605c7e121357f5a5d2d2 100644 (file)
@@ -2258,6 +2258,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
        pgoff_t index;
        struct inode *inode = mapping->host;
        handle_t *handle;
+       loff_t page_len;
 
        index = pos >> PAGE_CACHE_SHIFT;
 
@@ -2304,6 +2305,11 @@ retry:
                 */
                if (pos + len > inode->i_size)
                        ext4_truncate_failed_write(inode);
+       } else {
+               page_len = pos & (PAGE_CACHE_SIZE - 1);
+               ext4_discard_partial_page_buffers_no_lock(handle,
+                       inode, page, pos - page_len, page_len,
+                       EXT4_DSCRD_PARTIAL_PG_ZERO_UNMAPED);
        }
 
        if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@ -2346,6 +2352,7 @@ static int ext4_da_write_end(struct file *file,
        loff_t new_i_size;
        unsigned long start, end;
        int write_mode = (int)(unsigned long)fsdata;
+       loff_t page_len;
 
        if (write_mode == FALL_BACK_TO_NONDELALLOC) {
                if (ext4_should_order_data(inode)) {
@@ -2394,6 +2401,14 @@ static int ext4_da_write_end(struct file *file,
        }
        ret2 = generic_write_end(file, mapping, pos, len, copied,
                                                        page, fsdata);
+
+       page_len = PAGE_CACHE_SIZE -
+                       ((pos + copied) & (PAGE_CACHE_SIZE - 1));
+
+       ext4_discard_partial_page_buffers_no_lock(handle,
+               inode, page, pos + copied, page_len,
+               EXT4_DSCRD_PARTIAL_PG_ZERO_UNMAPED);
+
        copied = ret2;
        if (ret2 < 0)
                ret = ret2;
@@ -2857,6 +2872,12 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
        struct inode *inode = file->f_mapping->host;
        ssize_t ret;
 
+       /*
+        * If we are doing data journalling we don't support O_DIRECT
+        */
+       if (ext4_should_journal_data(inode))
+               return 0;
+
        trace_ext4_direct_IO_enter(inode, offset, iov_length(iov, nr_segs), rw);
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
                ret = ext4_ext_direct_IO(rw, iocb, iov, offset, nr_segs);
@@ -2926,6 +2947,7 @@ static const struct address_space_operations ext4_journalled_aops = {
        .bmap                   = ext4_bmap,
        .invalidatepage         = ext4_invalidatepage,
        .releasepage            = ext4_releasepage,
+       .direct_IO              = ext4_direct_IO,
        .is_partially_uptodate  = block_is_partially_uptodate,
        .error_remove_page      = generic_error_remove_page,
 };
@@ -2962,6 +2984,165 @@ void ext4_set_aops(struct inode *inode)
                inode->i_mapping->a_ops = &ext4_journalled_aops;
 }
 
+
+/*
+ * ext4_discard_partial_page_buffers()
+ * Wrapper function for ext4_discard_partial_page_buffers_no_lock.
+ * This function finds and locks the page containing the offset
+ * "from" and passes it to ext4_discard_partial_page_buffers_no_lock.
+ * Calling functions that already have the page locked should call
+ * ext4_discard_partial_page_buffers_no_lock directly.
+ */
+int ext4_discard_partial_page_buffers(handle_t *handle,
+               struct address_space *mapping, loff_t from,
+               loff_t length, int flags)
+{
+       struct inode *inode = mapping->host;
+       struct page *page;
+       int err = 0;
+
+       page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT,
+                                  mapping_gfp_mask(mapping) & ~__GFP_FS);
+       if (!page)
+               return -EINVAL;
+
+       err = ext4_discard_partial_page_buffers_no_lock(handle, inode, page,
+               from, length, flags);
+
+       unlock_page(page);
+       page_cache_release(page);
+       return err;
+}
+
+/*
+ * ext4_discard_partial_page_buffers_no_lock()
+ * Zeros a page range of length 'length' starting from offset 'from'
+ * and unmaps the buffer heads that correspond to the block aligned
+ * regions of the page that were fully zeroed.  This function assumes
+ * that page has already been locked.  The range to be discarded
+ * must be contained with in the given page.  If the specified range
+ * exceeds the end of the page it will be shortened to the end
+ * of the page that corresponds to 'from'.  This function is appropriate
+ * for updateing a page and it buffer heads to be unmaped and zeroed
+ * for blocks that have been either released, or are going to be released.
+ *
+ * handle: The journal handle
+ * inode:  The files inode
+ * page:   A locked page that contains the offset "from"
+ * from:   The starting byte offset (from the begining of the file)
+ *         to begin discarding
+ * len:    The length of bytes to discard
+ * flags:  Optional flags that may be used:
+ *
+ *         EXT4_DSCRD_PARTIAL_PG_ZERO_UNMAPED
+ *         Only zero the regions of the page whose buffer heads
+ *         have already been unmapped.  This flag is appropriate
+ *         for updateing the contents of a page whose blocks may
+ *         have already been released, and we only want to zero
+ *         out the regions that correspond to those released blocks.
+ *
+ * Returns zero on sucess or negative on failure.
+ */
+int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
+               struct inode *inode, struct page *page, loff_t from,
+               loff_t length, int flags)
+{
+       ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
+       unsigned int offset = from & (PAGE_CACHE_SIZE-1);
+       unsigned int blocksize, max, pos;
+       unsigned int end_of_block, range_to_discard;
+       ext4_lblk_t iblock;
+       struct buffer_head *bh;
+       int err = 0;
+
+       blocksize = inode->i_sb->s_blocksize;
+       max = PAGE_CACHE_SIZE - offset;
+
+       if (index != page->index)
+               return -EINVAL;
+
+       /*
+        * correct length if it does not fall between
+        * 'from' and the end of the page
+        */
+       if (length > max || length < 0)
+               length = max;
+
+       iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+
+       if (!page_has_buffers(page))
+               return 0;
+
+       /* Find the buffer that contains "offset" */
+       bh = page_buffers(page);
+       pos = blocksize;
+       while (offset >= pos) {
+               bh = bh->b_this_page;
+               iblock++;
+               pos += blocksize;
+       }
+
+       pos = offset;
+       while (pos < offset + length) {
+               err = 0;
+
+               /* The length of space left to zero and unmap */
+               range_to_discard = offset + length - pos;
+
+               /* The length of space until the end of the block */
+               end_of_block = blocksize - (pos & (blocksize-1));
+
+               /* Do not unmap or zero past end of block */
+               if (range_to_discard > end_of_block)
+                       range_to_discard = end_of_block;
+
+
+               if (flags & EXT4_DSCRD_PARTIAL_PG_ZERO_UNMAPED &&
+                       buffer_mapped(bh))
+                               goto next;
+
+               if (ext4_should_journal_data(inode)) {
+                       BUFFER_TRACE(bh, "get write access");
+                       err = ext4_journal_get_write_access(handle, bh);
+                       if (err)
+                               goto unmap;
+               }
+
+               zero_user(page, pos, range_to_discard);
+
+               BUFFER_TRACE(bh, "buffer discarded");
+
+               err = 0;
+               if (ext4_should_journal_data(inode)) {
+                       err = ext4_handle_dirty_metadata(handle, inode, bh);
+               } else {
+                       if (ext4_should_order_data(inode) &&
+                           EXT4_I(inode)->jinode)
+                               err = ext4_jbd2_file_inode(handle, inode);
+               }
+unmap:
+
+               /* If the range is block aligned, unmap */
+               if (range_to_discard == blocksize) {
+                       clear_buffer_dirty(bh);
+                       bh->b_bdev = NULL;
+                       clear_buffer_mapped(bh);
+                       clear_buffer_req(bh);
+                       clear_buffer_new(bh);
+                       clear_buffer_delay(bh);
+                       clear_buffer_unwritten(bh);
+                       clear_buffer_uptodate(bh);
+                       ClearPageUptodate(page);
+               }
+next:
+               bh = bh->b_this_page;
+               iblock++;
+               pos += range_to_discard;
+       }
+
+       return err;
+}
+
 /*
  * ext4_block_truncate_page() zeroes out a mapping from file offset `from'
  * up to the end of the block which corresponds to `from'.
index f8068c7bae9fd05c7d94880dd909c1f17df7dad5..a067835bbac19ade2714ef972db92eeb0a6fdc1b 100644 (file)
@@ -1585,7 +1585,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
                        dxtrace(dx_show_index("node", frames[1].entries));
                        dxtrace(dx_show_index("node",
                               ((struct dx_node *) bh2->b_data)->entries));
-                       err = ext4_handle_dirty_metadata(handle, inode, bh2);
+                       err = ext4_handle_dirty_metadata(handle, dir, bh2);
                        if (err)
                                goto journal_error;
                        brelse (bh2);
@@ -1611,7 +1611,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
                        if (err)
                                goto journal_error;
                }
-               err = ext4_handle_dirty_metadata(handle, inode, frames[0].bh);
+               err = ext4_handle_dirty_metadata(handle, dir, frames[0].bh);
                if (err) {
                        ext4_std_error(inode->i_sb, err);
                        goto cleanup;
@@ -1862,7 +1862,7 @@ retry:
        ext4_set_de_type(dir->i_sb, de, S_IFDIR);
        inode->i_nlink = 2;
        BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
-       err = ext4_handle_dirty_metadata(handle, dir, dir_block);
+       err = ext4_handle_dirty_metadata(handle, inode, dir_block);
        if (err)
                goto out_clear_inode;
        err = ext4_mark_inode_dirty(handle, inode);
@@ -2529,7 +2529,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
                PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) =
                                                cpu_to_le32(new_dir->i_ino);
                BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
-               retval = ext4_handle_dirty_metadata(handle, old_dir, dir_bh);
+               retval = ext4_handle_dirty_metadata(handle, old_inode, dir_bh);
                if (retval) {
                        ext4_std_error(old_dir->i_sb, retval);
                        goto end_rename;
index 44d0c8db2239f958d08d4de4462cdc6ca936d1e1..8c9bb73f952d6afcb789882742a5161f9b6bf7ce 100644 (file)
@@ -1801,6 +1801,7 @@ set_qf_format:
                        break;
                case Opt_nodelalloc:
                        clear_opt(sb, DELALLOC);
+                       clear_opt2(sb, EXPLICIT_DELALLOC);
                        break;
                case Opt_mblk_io_submit:
                        set_opt(sb, MBLK_IO_SUBMIT);
@@ -1817,6 +1818,7 @@ set_qf_format:
                        break;
                case Opt_delalloc:
                        set_opt(sb, DELALLOC);
+                       set_opt2(sb, EXPLICIT_DELALLOC);
                        break;
                case Opt_block_validity:
                        set_opt(sb, BLOCK_VALIDITY);
@@ -2853,8 +2855,7 @@ cont_thread:
                }
                mutex_unlock(&eli->li_list_mtx);
 
-               if (freezing(current))
-                       refrigerator();
+               try_to_freeze();
 
                cur = jiffies;
                if ((time_after_eq(cur, next_wakeup)) ||
@@ -3224,6 +3225,31 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                           &journal_ioprio, NULL, 0))
                goto failed_mount;
 
+       if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
+               printk_once(KERN_WARNING "EXT4-fs: Warning: mounting "
+                           "with data=journal disables delayed "
+                           "allocation and O_DIRECT support!\n");
+               if (test_opt2(sb, EXPLICIT_DELALLOC)) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "both data=journal and delalloc");
+                       goto failed_mount;
+               }
+               if (test_opt(sb, DIOREAD_NOLOCK)) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "both data=journal and delalloc");
+                       goto failed_mount;
+               }
+               if (test_opt(sb, DELALLOC))
+                       clear_opt(sb, DELALLOC);
+       }
+       if (test_opt(sb, DIOREAD_NOLOCK)) {
+               if (sb->s_blocksize < PAGE_SIZE) {
+                       ext4_msg(sb, KERN_ERR, "can't mount with "
+                                "dioread_nolock if block size != PAGE_SIZE");
+                       goto failed_mount;
+               }
+       }
+
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
                (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
 
@@ -3679,25 +3705,6 @@ no_journal:
                         "available");
        }
 
-       if (test_opt(sb, DELALLOC) &&
-           (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) {
-               ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - "
-                        "requested data journaling mode");
-               clear_opt(sb, DELALLOC);
-       }
-       if (test_opt(sb, DIOREAD_NOLOCK)) {
-               if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
-                       ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock "
-                               "option - requested data journaling mode");
-                       clear_opt(sb, DIOREAD_NOLOCK);
-               }
-               if (sb->s_blocksize < PAGE_SIZE) {
-                       ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock "
-                               "option - block size is too small");
-                       clear_opt(sb, DIOREAD_NOLOCK);
-               }
-       }
-
        err = ext4_setup_system_zone(sb);
        if (err) {
                ext4_msg(sb, KERN_ERR, "failed to initialize system "
index 007c3bfbf094221988855d9eb754bfdf430d569e..34e4350dd4d92f2ee2273a909b3f1b85867cf580 100644 (file)
@@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
                              name, value, size, flags);
 }
 
-int
-ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
-                  const struct qstr *qstr)
+int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                   void *fs_info)
 {
-       int err;
-       size_t len;
-       void *value;
-       char *name;
+       const struct xattr *xattr;
+       handle_t *handle = fs_info;
+       int err = 0;
 
-       err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
-       if (err) {
-               if (err == -EOPNOTSUPP)
-                       return 0;
-               return err;
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               err = ext4_xattr_set_handle(handle, inode,
+                                           EXT4_XATTR_INDEX_SECURITY,
+                                           xattr->name, xattr->value,
+                                           xattr->value_len, 0);
+               if (err < 0)
+                       break;
        }
-       err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
-                                   name, value, len, 0);
-       kfree(name);
-       kfree(value);
        return err;
 }
 
+int
+ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
+                  const struct qstr *qstr)
+{
+       return security_inode_init_security(inode, dir, qstr,
+                                           &ext4_initxattrs, handle);
+}
+
 const struct xattr_handler ext4_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
        .list   = ext4_xattr_security_list,
index 04cf3b91e5016a1f7e3ceef734c7d85574ec296d..b36edb8418ced39b9ca8b761942a90da56e44308 100644 (file)
@@ -922,7 +922,7 @@ int bdi_writeback_thread(void *data)
 
        trace_writeback_thread_start(bdi);
 
-       while (!kthread_should_stop()) {
+       while (!kthread_freezable_should_stop(NULL)) {
                /*
                 * Remove own delayed wake-up timer, since we are already awake
                 * and we'll take care of the preriodic write-back.
@@ -952,8 +952,6 @@ int bdi_writeback_thread(void *data)
                         */
                        schedule();
                }
-
-               try_to_freeze();
        }
 
        /* Flush any work that raced with us exiting */
index 640fc229df10323b6c9fc94b0bda452157bf1ef0..168a80f7f12b856e795eb916bf79f5e2348e06f6 100644 (file)
@@ -1358,6 +1358,10 @@ static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
        if (outarg.namelen > FUSE_NAME_MAX)
                goto err;
 
+       err = -EINVAL;
+       if (size != sizeof(outarg) + outarg.namelen + 1)
+               goto err;
+
        name.name = buf;
        name.len = outarg.namelen;
        err = fuse_copy_one(cs, buf, outarg.namelen + 1);
index d480d9af46c964f8b86ced68feb7e787959a4fdb..594f07a81c2899ba33a173be33cfc818afa0d39b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/compat.h>
+#include <linux/swap.h>
 
 static const struct file_operations fuse_direct_io_file_operations;
 
@@ -245,6 +246,12 @@ void fuse_release_common(struct file *file, int opcode)
        req = ff->reserved_req;
        fuse_prepare_release(ff, file->f_flags, opcode);
 
+       if (ff->flock) {
+               struct fuse_release_in *inarg = &req->misc.release.in;
+               inarg->release_flags |= FUSE_RELEASE_FLOCK_UNLOCK;
+               inarg->lock_owner = fuse_lock_owner_id(ff->fc,
+                                                      (fl_owner_t) file);
+       }
        /* Hold vfsmount and dentry until release is finished */
        path_get(&file->f_path);
        req->misc.release.path = file->f_path;
@@ -755,18 +762,6 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
        return req->misc.write.out.size;
 }
 
-static int fuse_write_begin(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len, unsigned flags,
-                       struct page **pagep, void **fsdata)
-{
-       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-
-       *pagep = grab_cache_page_write_begin(mapping, index, flags);
-       if (!*pagep)
-               return -ENOMEM;
-       return 0;
-}
-
 void fuse_write_update_size(struct inode *inode, loff_t pos)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
@@ -779,62 +774,6 @@ void fuse_write_update_size(struct inode *inode, loff_t pos)
        spin_unlock(&fc->lock);
 }
 
-static int fuse_buffered_write(struct file *file, struct inode *inode,
-                              loff_t pos, unsigned count, struct page *page)
-{
-       int err;
-       size_t nres;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
-       struct fuse_req *req;
-
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       /*
-        * Make sure writepages on the same page are not mixed up with
-        * plain writes.
-        */
-       fuse_wait_on_page_writeback(inode, page->index);
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.argpages = 1;
-       req->num_pages = 1;
-       req->pages[0] = page;
-       req->page_offset = offset;
-       nres = fuse_send_write(req, file, pos, count, NULL);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err && !nres)
-               err = -EIO;
-       if (!err) {
-               pos += nres;
-               fuse_write_update_size(inode, pos);
-               if (count == PAGE_CACHE_SIZE)
-                       SetPageUptodate(page);
-       }
-       fuse_invalidate_attr(inode);
-       return err ? err : nres;
-}
-
-static int fuse_write_end(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len, unsigned copied,
-                       struct page *page, void *fsdata)
-{
-       struct inode *inode = mapping->host;
-       int res = 0;
-
-       if (copied)
-               res = fuse_buffered_write(file, inode, pos, copied, page);
-
-       unlock_page(page);
-       page_cache_release(page);
-       return res;
-}
-
 static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file,
                                    struct inode *inode, loff_t pos,
                                    size_t count)
@@ -908,6 +847,8 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                pagefault_enable();
                flush_dcache_page(page);
 
+               mark_page_accessed(page);
+
                if (!tmp) {
                        unlock_page(page);
                        page_cache_release(page);
@@ -1559,11 +1500,14 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
        struct fuse_conn *fc = get_fuse_conn(inode);
        int err;
 
-       if (fc->no_lock) {
+       if (fc->no_flock) {
                err = flock_lock_file_wait(file, fl);
        } else {
+               struct fuse_file *ff = file->private_data;
+
                /* emulate flock with POSIX locks */
                fl->fl_owner = (fl_owner_t) file;
+               ff->flock = true;
                err = fuse_setlk(file, fl, 1);
        }
 
@@ -2201,8 +2145,6 @@ static const struct address_space_operations fuse_file_aops  = {
        .readpage       = fuse_readpage,
        .writepage      = fuse_writepage,
        .launder_page   = fuse_launder_page,
-       .write_begin    = fuse_write_begin,
-       .write_end      = fuse_write_end,
        .readpages      = fuse_readpages,
        .set_page_dirty = __set_page_dirty_nobuffers,
        .bmap           = fuse_bmap,
index c6aa2d4b851733a250205734215c785be6944507..cf6db0a932192c30d6dc65a327cca84e7258a5dc 100644 (file)
@@ -135,6 +135,9 @@ struct fuse_file {
 
        /** Wait queue head for poll */
        wait_queue_head_t poll_wait;
+
+       /** Has flock been performed on this file? */
+       bool flock:1;
 };
 
 /** One input argument of a request */
@@ -448,7 +451,7 @@ struct fuse_conn {
        /** Is removexattr not implemented by fs? */
        unsigned no_removexattr:1;
 
-       /** Are file locking primitives not implemented by fs? */
+       /** Are posix file locking primitives not implemented by fs? */
        unsigned no_lock:1;
 
        /** Is access not implemented by fs? */
@@ -472,6 +475,9 @@ struct fuse_conn {
        /** Don't apply umask to creation modes */
        unsigned dont_mask:1;
 
+       /** Are BSD file locking primitives not implemented by fs? */
+       unsigned no_flock:1;
+
        /** The number of requests waiting for completion */
        atomic_t num_waiting;
 
index 38f84cd48b67d057798f8f75fe5c8f22f12b10dc..12b502929da9c51ef78f5ee6d53948e1f5b991a6 100644 (file)
@@ -71,7 +71,7 @@ struct fuse_mount_data {
        unsigned blksize;
 };
 
-struct fuse_forget_link *fuse_alloc_forget()
+struct fuse_forget_link *fuse_alloc_forget(void)
 {
        return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL);
 }
@@ -809,6 +809,10 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->async_read = 1;
                        if (!(arg->flags & FUSE_POSIX_LOCKS))
                                fc->no_lock = 1;
+                       if (arg->minor >= 17) {
+                               if (!(arg->flags & FUSE_FLOCK_LOCKS))
+                                       fc->no_flock = 1;
+                       }
                        if (arg->flags & FUSE_ATOMIC_O_TRUNC)
                                fc->atomic_o_trunc = 1;
                        if (arg->minor >= 9) {
@@ -823,6 +827,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
+                       fc->no_flock = 1;
                }
 
                fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages);
@@ -843,7 +848,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
        arg->minor = FUSE_KERNEL_MINOR_VERSION;
        arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
        arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
-               FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK;
+               FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
+               FUSE_FLOCK_LOCKS;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
index 34501b64bc47a416993677b641b30fe64a84d13c..65978d7885c863b896e7da2ca04062498c449ac2 100644 (file)
@@ -82,7 +82,7 @@ static int gfs2_set_mode(struct inode *inode, umode_t mode)
                iattr.ia_valid = ATTR_MODE;
                iattr.ia_mode = mode;
 
-               error = gfs2_setattr_simple(GFS2_I(inode), &iattr);
+               error = gfs2_setattr_simple(inode, &iattr);
        }
 
        return error;
@@ -160,6 +160,7 @@ out:
 
 int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
 {
+       struct inode *inode = &ip->i_inode;
        struct posix_acl *acl;
        char *data;
        unsigned int len;
@@ -169,7 +170,7 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
        if (IS_ERR(acl))
                return PTR_ERR(acl);
        if (!acl)
-               return gfs2_setattr_simple(ip, attr);
+               return gfs2_setattr_simple(inode, attr);
 
        error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode);
        if (error)
index f9fbbe96c222860374840a825f2168d14b340f83..212fe74927ba7852ee5843291bdfa30dee627404 100644 (file)
@@ -787,7 +787,6 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
        u64 to = pos + copied;
        void *kaddr;
        unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode);
-       struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
 
        BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
        kaddr = kmap_atomic(page, KM_USER0);
@@ -804,7 +803,6 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
        if (copied) {
                if (inode->i_size < to)
                        i_size_write(inode, to);
-               gfs2_dinode_out(ip, di);
                mark_inode_dirty(inode);
        }
 
@@ -873,10 +871,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
                gfs2_page_add_databufs(ip, page, from, to);
 
        ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
-       if (ret > 0) {
-               gfs2_dinode_out(ip, dibh->b_data);
-               mark_inode_dirty(inode);
-       }
 
        if (inode == sdp->sd_rindex) {
                adjust_fs_space(inode);
index 1cc2f8ec52a2cb76246eaba3ea08efac57bf0eae..898e62ed5b85f4685260d9b19bf15efe56d05365 100644 (file)
@@ -240,16 +240,15 @@ fail:
        return error;
 }
 
-static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf,
-                                u64 offset, unsigned int size)
+static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, __be64 *buf,
+                                unsigned int size)
 {
        struct buffer_head *dibh;
        int error;
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (!error) {
-               offset += sizeof(struct gfs2_dinode);
-               memcpy(buf, dibh->b_data + offset, size);
+               memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), size);
                brelse(dibh);
        }
 
@@ -261,13 +260,12 @@ static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf,
  * gfs2_dir_read_data - Read a data from a directory inode
  * @ip: The GFS2 Inode
  * @buf: The buffer to place result into
- * @offset: File offset to begin jdata_readng from
  * @size: Amount of data to transfer
  *
  * Returns: The amount of data actually copied or the error
  */
-static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
-                             unsigned int size, unsigned ra)
+static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf,
+                             unsigned int size)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        u64 lblock, dblock;
@@ -275,24 +273,14 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
        unsigned int o;
        int copied = 0;
        int error = 0;
-       u64 disksize = i_size_read(&ip->i_inode);
-
-       if (offset >= disksize)
-               return 0;
-
-       if (offset + size > disksize)
-               size = disksize - offset;
-
-       if (!size)
-               return 0;
 
        if (gfs2_is_stuffed(ip))
-               return gfs2_dir_read_stuffed(ip, buf, offset, size);
+               return gfs2_dir_read_stuffed(ip, buf, size);
 
        if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
                return -EINVAL;
 
-       lblock = offset;
+       lblock = 0;
        o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header);
 
        while (copied < size) {
@@ -311,8 +299,6 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
                        if (error || !dblock)
                                goto fail;
                        BUG_ON(extlen < 1);
-                       if (!ra)
-                               extlen = 1;
                        bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
                } else {
                        error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh);
@@ -328,7 +314,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
                extlen--;
                memcpy(buf, bh->b_data + o, amount);
                brelse(bh);
-               buf += amount;
+               buf += (amount/sizeof(__be64));
                copied += amount;
                lblock++;
                o = sizeof(struct gfs2_meta_header);
@@ -371,7 +357,7 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip)
        if (hc == NULL)
                return ERR_PTR(-ENOMEM);
 
-       ret = gfs2_dir_read_data(ip, (char *)hc, 0, hsize, 1);
+       ret = gfs2_dir_read_data(ip, hc, hsize);
        if (ret < 0) {
                kfree(hc);
                return ERR_PTR(ret);
@@ -1695,7 +1681,6 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry)
        const struct qstr *name = &dentry->d_name;
        struct gfs2_dirent *dent, *prev = NULL;
        struct buffer_head *bh;
-       int error;
 
        /* Returns _either_ the entry (if its first in block) or the
           previous entry otherwise */
@@ -1724,22 +1709,15 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry)
        }
        brelse(bh);
 
-       error = gfs2_meta_inode_buffer(dip, &bh);
-       if (error)
-               return error;
-
        if (!dip->i_entries)
                gfs2_consist_inode(dip);
-       gfs2_trans_add_bh(dip->i_gl, bh, 1);
        dip->i_entries--;
        dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
        if (S_ISDIR(dentry->d_inode->i_mode))
                drop_nlink(&dip->i_inode);
-       gfs2_dinode_out(dip, bh->b_data);
-       brelse(bh);
        mark_inode_dirty(&dip->i_inode);
 
-       return error;
+       return 0;
 }
 
 /**
index edeb9e80290382b39491d67c40ed3802535aac2b..d717b72500a47bab5adc85159666cbe7c894fd7b 100644 (file)
@@ -59,15 +59,24 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
        struct gfs2_holder i_gh;
        loff_t error;
 
-       if (origin == 2) {
+       switch (origin) {
+       case SEEK_END: /* These reference inode->i_size */
+       case SEEK_DATA:
+       case SEEK_HOLE:
                error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
                                           &i_gh);
                if (!error) {
                        error = generic_file_llseek_unlocked(file, offset, origin);
                        gfs2_glock_dq_uninit(&i_gh);
                }
-       } else
+               break;
+       case SEEK_CUR:
+       case SEEK_SET:
                error = generic_file_llseek_unlocked(file, offset, origin);
+               break;
+       default:
+               error = -EINVAL;
+       }
 
        return error;
 }
@@ -551,8 +560,16 @@ static int gfs2_close(struct inode *inode, struct file *file)
  * @end: the end position in the file to sync
  * @datasync: set if we can ignore timestamp changes
  *
- * The VFS will flush data for us. We only need to worry
- * about metadata here.
+ * We split the data flushing here so that we don't wait for the data
+ * until after we've also sent the metadata to disk. Note that for
+ * data=ordered, we will write & wait for the data at the log flush
+ * stage anyway, so this is unlikely to make much of a difference
+ * except in the data=writeback case.
+ *
+ * If the fdatawrite fails due to any reason except -EIO, we will
+ * continue the remainder of the fsync, although we'll still report
+ * the error at the end. This is to match filemap_write_and_wait_range()
+ * behaviour.
  *
  * Returns: errno
  */
@@ -560,30 +577,38 @@ static int gfs2_close(struct inode *inode, struct file *file)
 static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
                      int datasync)
 {
-       struct inode *inode = file->f_mapping->host;
+       struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
        int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);
        struct gfs2_inode *ip = GFS2_I(inode);
-       int ret;
+       int ret, ret1 = 0;
 
-       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
-       if (ret)
-               return ret;
-       mutex_lock(&inode->i_mutex);
+       if (mapping->nrpages) {
+               ret1 = filemap_fdatawrite_range(mapping, start, end);
+               if (ret1 == -EIO)
+                       return ret1;
+       }
 
        if (datasync)
                sync_state &= ~I_DIRTY_SYNC;
 
        if (sync_state) {
+               mutex_lock(&inode->i_mutex);
                ret = sync_inode_metadata(inode, 1);
                if (ret) {
                        mutex_unlock(&inode->i_mutex);
                        return ret;
                }
+               if (gfs2_is_jdata(ip))
+                       filemap_write_and_wait(mapping);
                gfs2_ail_flush(ip->i_gl);
+               mutex_unlock(&inode->i_mutex);
        }
 
-       mutex_unlock(&inode->i_mutex);
-       return 0;
+       if (mapping->nrpages)
+               ret = filemap_fdatawait_range(mapping, start, end);
+
+       return ret ? ret : ret1;
 }
 
 /**
@@ -786,7 +811,6 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
                from = 0;
        }
 
-       gfs2_dinode_out(ip, dibh->b_data);
        mark_inode_dirty(inode);
 
        brelse(dibh);
index da21ecaafcc2725e4cbff9ee3a469f237f2e31b2..0cc3ff48ce20b9dcb497820cb63591875ee3bcc9 100644 (file)
 #include "trans.h"
 #include "dir.h"
 
+static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
+{
+       fs_err(gl->gl_sbd, "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page state 0x%lx\n",
+              bh, (unsigned long long)bh->b_blocknr, bh->b_state,
+              bh->b_page->mapping, bh->b_page->flags);
+       fs_err(gl->gl_sbd, "AIL glock %u:%llu mapping %p\n",
+              gl->gl_name.ln_type, gl->gl_name.ln_number,
+              gfs2_glock2aspace(gl));
+       gfs2_lm_withdraw(gl->gl_sbd, "AIL error\n");
+}
+
 /**
  * __gfs2_ail_flush - remove all buffers for a given lock from the AIL
  * @gl: the glock
  * None of the buffers should be dirty, locked, or pinned.
  */
 
-static void __gfs2_ail_flush(struct gfs2_glock *gl)
+static void __gfs2_ail_flush(struct gfs2_glock *gl, unsigned long b_state)
 {
        struct gfs2_sbd *sdp = gl->gl_sbd;
        struct list_head *head = &gl->gl_ail_list;
        struct gfs2_bufdata *bd;
        struct buffer_head *bh;
+       sector_t blocknr;
 
        spin_lock(&sdp->sd_ail_lock);
        while (!list_empty(head)) {
                bd = list_entry(head->next, struct gfs2_bufdata,
                                bd_ail_gl_list);
                bh = bd->bd_bh;
-               gfs2_remove_from_ail(bd);
-               bd->bd_bh = NULL;
+               blocknr = bh->b_blocknr;
+               if (bh->b_state & b_state)
+                       gfs2_ail_error(gl, bh);
                bh->b_private = NULL;
+               gfs2_remove_from_ail(bd); /* drops ref on bh */
                spin_unlock(&sdp->sd_ail_lock);
 
-               bd->bd_blkno = bh->b_blocknr;
+               bd->bd_bh = NULL;
+               bd->bd_blkno = blocknr;
+
                gfs2_log_lock(sdp);
-               gfs2_assert_withdraw(sdp, !buffer_busy(bh));
                gfs2_trans_add_revoke(sdp, bd);
                gfs2_log_unlock(sdp);
 
@@ -84,7 +99,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
        BUG_ON(current->journal_info);
        current->journal_info = &tr;
 
-       __gfs2_ail_flush(gl);
+       __gfs2_ail_flush(gl, (1ul << BH_Dirty)|(1ul << BH_Pinned)|(1ul << BH_Lock));
 
        gfs2_trans_end(sdp);
        gfs2_log_flush(sdp, NULL);
@@ -102,7 +117,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl)
        ret = gfs2_trans_begin(sdp, 0, revokes);
        if (ret)
                return;
-       __gfs2_ail_flush(gl);
+       __gfs2_ail_flush(gl, (1ul << BH_Dirty)|(1ul << BH_Pinned));
        gfs2_trans_end(sdp);
        gfs2_log_flush(sdp, NULL);
 }
index 892ac37de8aed8e272e491354c62352df93e690e..be5801a754060246ff9fca238797f3d30a9a59a2 100644 (file)
@@ -267,6 +267,7 @@ struct gfs2_alloc {
 enum {
        GIF_INVALID             = 0,
        GIF_QD_LOCKED           = 1,
+       GIF_ALLOC_FAILED        = 2,
        GIF_SW_PAGED            = 3,
 };
 
index 900cf986aadcc155d26028971f71bc6fa9a972ec..5431de94085dc89152521e96e3c2b9dd18be59b7 100644 (file)
@@ -624,31 +624,29 @@ fail:
        return error;
 }
 
-static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
-                             const struct qstr *qstr)
+int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                   void *fs_info)
 {
-       int err;
-       size_t len;
-       void *value;
-       char *name;
-
-       err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
-                                          &name, &value, &len);
-
-       if (err) {
-               if (err == -EOPNOTSUPP)
-                       return 0;
-               return err;
+       const struct xattr *xattr;
+       int err = 0;
+
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               err = __gfs2_xattr_set(inode, xattr->name, xattr->value,
+                                      xattr->value_len, 0,
+                                      GFS2_EATYPE_SECURITY);
+               if (err < 0)
+                       break;
        }
-
-       err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0,
-                              GFS2_EATYPE_SECURITY);
-       kfree(value);
-       kfree(name);
-
        return err;
 }
 
+static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
+                             const struct qstr *qstr)
+{
+       return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
+                                           &gfs2_initxattrs, NULL);
+}
+
 /**
  * gfs2_create_inode - Create a new inode
  * @dir: The parent directory
@@ -663,7 +661,7 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
 
 static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
                             unsigned int mode, dev_t dev, const char *symname,
-                            unsigned int size)
+                            unsigned int size, int excl)
 {
        const struct qstr *name = &dentry->d_name;
        struct gfs2_holder ghs[2];
@@ -683,6 +681,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
                goto fail;
 
        error = create_ok(dip, name, mode);
+       if ((error == -EEXIST) && S_ISREG(mode) && !excl) {
+               inode = gfs2_lookupi(dir, &dentry->d_name, 0);
+               gfs2_glock_dq_uninit(ghs);
+               d_instantiate(dentry, inode);
+               return IS_ERR(inode) ? PTR_ERR(inode) : 0;
+       }
        if (error)
                goto fail_gunlock;
 
@@ -729,17 +733,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
                gfs2_inplace_release(dip);
        gfs2_quota_unlock(dip);
        gfs2_alloc_put(dip);
-       gfs2_glock_dq_uninit_m(2, ghs);
        mark_inode_dirty(inode);
+       gfs2_glock_dq_uninit_m(2, ghs);
        d_instantiate(dentry, inode);
        return 0;
 
 fail_gunlock2:
        gfs2_glock_dq_uninit(ghs + 1);
-       if (inode && !IS_ERR(inode))
-               iput(inode);
 fail_gunlock:
        gfs2_glock_dq_uninit(ghs);
+       if (inode && !IS_ERR(inode)) {
+               set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags);
+               iput(inode);
+       }
 fail:
        if (bh)
                brelse(bh);
@@ -758,24 +764,10 @@ fail:
 static int gfs2_create(struct inode *dir, struct dentry *dentry,
                       int mode, struct nameidata *nd)
 {
-       struct inode *inode;
-       int ret;
-
-       for (;;) {
-               ret = gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0);
-               if (ret != -EEXIST || (nd && (nd->flags & LOOKUP_EXCL)))
-                       return ret;
-
-               inode = gfs2_lookupi(dir, &dentry->d_name, 0);
-               if (inode) {
-                       if (!IS_ERR(inode))
-                               break;
-                       return PTR_ERR(inode);
-               }
-       }
-
-       d_instantiate(dentry, inode);
-       return 0;
+       int excl = 0;
+       if (nd && (nd->flags & LOOKUP_EXCL))
+               excl = 1;
+       return gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0, excl);
 }
 
 /**
@@ -924,8 +916,9 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        inc_nlink(&ip->i_inode);
        ip->i_inode.i_ctime = CURRENT_TIME;
-       gfs2_dinode_out(ip, dibh->b_data);
-       mark_inode_dirty(&ip->i_inode);
+       ihold(inode);
+       d_instantiate(dentry, inode);
+       mark_inode_dirty(inode);
 
 out_brelse:
        brelse(dibh);
@@ -947,11 +940,6 @@ out_child:
 out_parent:
        gfs2_holder_uninit(ghs);
        gfs2_holder_uninit(ghs + 1);
-       if (!error) {
-               ihold(inode);
-               d_instantiate(dentry, inode);
-               mark_inode_dirty(inode);
-       }
        return error;
 }
 
@@ -1024,8 +1012,6 @@ static int gfs2_unlink_inode(struct gfs2_inode *dip,
                clear_nlink(inode);
        else
                drop_nlink(inode);
-       gfs2_trans_add_bh(ip->i_gl, bh, 1);
-       gfs2_dinode_out(ip, bh->b_data);
        mark_inode_dirty(inode);
        if (inode->i_nlink == 0)
                gfs2_unlink_di(inode);
@@ -1139,7 +1125,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
        if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
                return -ENAMETOOLONG;
 
-       return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size);
+       return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size, 0);
 }
 
 /**
@@ -1153,7 +1139,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
 
 static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
-       return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0);
+       return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0, 0);
 }
 
 /**
@@ -1168,7 +1154,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
                      dev_t dev)
 {
-       return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0);
+       return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0, 0);
 }
 
 /*
@@ -1563,21 +1549,10 @@ int gfs2_permission(struct inode *inode, int mask)
        return error;
 }
 
-static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
+static int __gfs2_setattr_simple(struct inode *inode, struct iattr *attr)
 {
-       struct inode *inode = &ip->i_inode;
-       struct buffer_head *dibh;
-       int error;
-
-       error = gfs2_meta_inode_buffer(ip, &dibh);
-       if (error)
-               return error;
-
        setattr_copy(inode, attr);
        mark_inode_dirty(inode);
-       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-       gfs2_dinode_out(ip, dibh->b_data);
-       brelse(dibh);
        return 0;
 }
 
@@ -1589,19 +1564,19 @@ static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
  * Returns: errno
  */
 
-int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
+int gfs2_setattr_simple(struct inode *inode, struct iattr *attr)
 {
        int error;
 
        if (current->journal_info)
-               return __gfs2_setattr_simple(ip, attr);
+               return __gfs2_setattr_simple(inode, attr);
 
-       error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0);
+       error = gfs2_trans_begin(GFS2_SB(inode), RES_DINODE, 0);
        if (error)
                return error;
 
-       error = __gfs2_setattr_simple(ip, attr);
-       gfs2_trans_end(GFS2_SB(&ip->i_inode));
+       error = __gfs2_setattr_simple(inode, attr);
+       gfs2_trans_end(GFS2_SB(inode));
        return error;
 }
 
@@ -1639,7 +1614,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
        if (error)
                goto out_gunlock_q;
 
-       error = gfs2_setattr_simple(ip, attr);
+       error = gfs2_setattr_simple(inode, attr);
        if (error)
                goto out_end_trans;
 
@@ -1695,12 +1670,12 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
        else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode))
                error = gfs2_acl_chmod(ip, attr);
        else
-               error = gfs2_setattr_simple(ip, attr);
+               error = gfs2_setattr_simple(inode, attr);
 
 out:
-       gfs2_glock_dq_uninit(&i_gh);
        if (!error)
                mark_inode_dirty(inode);
+       gfs2_glock_dq_uninit(&i_gh);
        return error;
 }
 
index 8d90e0c076722b42e2ed8da9fa40e65e2142e94f..276e7b52b6585d8755b991d6ee745f9dd7d982df 100644 (file)
@@ -109,7 +109,7 @@ extern int gfs2_inode_refresh(struct gfs2_inode *ip);
 extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
                                  int is_root);
 extern int gfs2_permission(struct inode *inode, int mask);
-extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
+extern int gfs2_setattr_simple(struct inode *inode, struct iattr *attr);
 extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
 extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
 
index 85c62923ee292d9d663119854f9115ed26fff36b..b342c717fe978c86d0f8211807ab5aeb02010817 100644 (file)
@@ -951,8 +951,8 @@ int gfs2_logd(void *data)
                        wake_up(&sdp->sd_log_waitq);
 
                t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
-               if (freezing(current))
-                       refrigerator();
+
+               try_to_freeze();
 
                do {
                        prepare_to_wait(&sdp->sd_logd_waitq, &wait,
index 42e8d23bc0472007aa0178b7d049d952175b2391..8e295ba0f2a261616ba64f6c0f8606e7b9409ab1 100644 (file)
@@ -638,7 +638,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
        unsigned long index = loc >> PAGE_CACHE_SHIFT;
        unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
        unsigned blocksize, iblock, pos;
-       struct buffer_head *bh, *dibh;
+       struct buffer_head *bh;
        struct page *page;
        void *kaddr, *ptr;
        struct gfs2_quota q, *qp;
@@ -736,22 +736,13 @@ get_a_page:
                goto get_a_page;
        }
 
-       /* Update the disk inode timestamp and size (if extended) */
-       err = gfs2_meta_inode_buffer(ip, &dibh);
-       if (err)
-               goto out;
-
        size = loc + sizeof(struct gfs2_quota);
        if (size > inode->i_size)
                i_size_write(inode, size);
        inode->i_mtime = inode->i_atime = CURRENT_TIME;
-       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-       gfs2_dinode_out(ip, dibh->b_data);
-       brelse(dibh);
        mark_inode_dirty(inode);
-
-out:
        return err;
+
 unlock_out:
        unlock_page(page);
        page_cache_release(page);
@@ -1431,8 +1422,8 @@ int gfs2_quotad(void *data)
                /* Check for & recover partially truncated inodes */
                quotad_check_trunc_list(sdp);
 
-               if (freezing(current))
-                       refrigerator();
+               try_to_freeze();
+
                t = min(quotad_timeo, statfs_timeo);
 
                prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_INTERRUPTIBLE);
index b7beadd9ba4cfe5810c1747a566307878eca8204..b05fa59545500160436d467530dee381e694b2fc 100644 (file)
@@ -752,51 +752,77 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl);
        struct backing_dev_info *bdi = metamapping->backing_dev_info;
-       struct gfs2_holder gh;
+       int ret = 0;
+
+       if (wbc->sync_mode == WB_SYNC_ALL)
+               gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
+       if (bdi->dirty_exceeded)
+               gfs2_ail1_flush(sdp, wbc);
+       else
+               filemap_fdatawrite(metamapping);
+       if (wbc->sync_mode == WB_SYNC_ALL)
+               ret = filemap_fdatawait(metamapping);
+       if (ret)
+               mark_inode_dirty_sync(inode);
+       return ret;
+}
+
+/**
+ * gfs2_dirty_inode - check for atime updates
+ * @inode: The inode in question
+ * @flags: The type of dirty
+ *
+ * Unfortunately it can be called under any combination of inode
+ * glock and transaction lock, so we have to check carefully.
+ *
+ * At the moment this deals only with atime - it should be possible
+ * to expand that role in future, once a review of the locking has
+ * been carried out.
+ */
+
+static void gfs2_dirty_inode(struct inode *inode, int flags)
+{
+       struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct buffer_head *bh;
-       struct timespec atime;
-       struct gfs2_dinode *di;
-       int ret = -EAGAIN;
-       int unlock_required = 0;
-
-       /* Skip timestamp update, if this is from a memalloc */
-       if (current->flags & PF_MEMALLOC)
-               goto do_flush;
+       struct gfs2_holder gh;
+       int need_unlock = 0;
+       int need_endtrans = 0;
+       int ret;
+
+       if (!(flags & (I_DIRTY_DATASYNC|I_DIRTY_SYNC)))
+               return;
+
        if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
                ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
-               if (ret)
-                       goto do_flush;
-               unlock_required = 1;
+               if (ret) {
+                       fs_err(sdp, "dirty_inode: glock %d\n", ret);
+                       return;
+               }
+               need_unlock = 1;
        }
-       ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
-       if (ret)
-               goto do_unlock;
+
+       if (current->journal_info == NULL) {
+               ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
+               if (ret) {
+                       fs_err(sdp, "dirty_inode: gfs2_trans_begin %d\n", ret);
+                       goto out;
+               }
+               need_endtrans = 1;
+       }
+
        ret = gfs2_meta_inode_buffer(ip, &bh);
        if (ret == 0) {
-               di = (struct gfs2_dinode *)bh->b_data;
-               atime.tv_sec = be64_to_cpu(di->di_atime);
-               atime.tv_nsec = be32_to_cpu(di->di_atime_nsec);
-               if (timespec_compare(&inode->i_atime, &atime) > 0) {
-                       gfs2_trans_add_bh(ip->i_gl, bh, 1);
-                       gfs2_dinode_out(ip, bh->b_data);
-               }
+               gfs2_trans_add_bh(ip->i_gl, bh, 1);
+               gfs2_dinode_out(ip, bh->b_data);
                brelse(bh);
        }
-       gfs2_trans_end(sdp);
-do_unlock:
-       if (unlock_required)
+
+       if (need_endtrans)
+               gfs2_trans_end(sdp);
+out:
+       if (need_unlock)
                gfs2_glock_dq_uninit(&gh);
-do_flush:
-       if (wbc->sync_mode == WB_SYNC_ALL)
-               gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
-       filemap_fdatawrite(metamapping);
-       if (bdi->dirty_exceeded)
-               gfs2_ail1_flush(sdp, wbc);
-       if (!ret && (wbc->sync_mode == WB_SYNC_ALL))
-               ret = filemap_fdatawait(metamapping);
-       if (ret)
-               mark_inode_dirty_sync(inode);
-       return ret;
 }
 
 /**
@@ -1471,9 +1497,11 @@ static void gfs2_evict_inode(struct inode *inode)
                goto out;
        }
 
-       error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED);
-       if (error)
-               goto out_truncate;
+       if (!test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) {
+               error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED);
+               if (error)
+                       goto out_truncate;
+       }
 
        if (test_bit(GIF_INVALID, &ip->i_flags)) {
                error = gfs2_inode_refresh(ip);
@@ -1513,6 +1541,10 @@ static void gfs2_evict_inode(struct inode *inode)
        goto out_unlock;
 
 out_truncate:
+       gfs2_log_flush(sdp, ip->i_gl);
+       write_inode_now(inode, 1);
+       gfs2_ail_flush(ip->i_gl);
+
        /* Case 2 starts here */
        error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
        if (error)
@@ -1572,6 +1604,7 @@ const struct super_operations gfs2_super_ops = {
        .alloc_inode            = gfs2_alloc_inode,
        .destroy_inode          = gfs2_destroy_inode,
        .write_inode            = gfs2_write_inode,
+       .dirty_inode            = gfs2_dirty_inode,
        .evict_inode            = gfs2_evict_inode,
        .put_super              = gfs2_put_super,
        .sync_fs                = gfs2_sync_fs,
index 439b61c03262b767956e23f761b637e0b6905383..695304cf01cc672e7a1ce9d5036a1345a5a4f8ae 100644 (file)
@@ -1296,7 +1296,8 @@ fail:
 
 int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
 {
-       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       struct inode *inode = &ip->i_inode;
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_ea_location el;
        int error;
 
@@ -1319,7 +1320,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
        if (error)
                return error;
 
-       error = gfs2_setattr_simple(ip, attr);
+       error = gfs2_setattr_simple(inode, attr);
        gfs2_trans_end(sdp);
        return error;
 }
index 9fe061fb8779be389155a05672b267c8071623e7..908fdf0c0ab9c38c615359c5cb4950ee06a6cf8b 100644 (file)
@@ -166,7 +166,7 @@ loop:
                 */
                jbd_debug(1, "Now suspending kjournald\n");
                spin_unlock(&journal->j_state_lock);
-               refrigerator();
+               try_to_freeze();
                spin_lock(&journal->j_state_lock);
        } else {
                /*
index f24df13adc4e9cfb5d71d851c959193e0f1e2b61..874d1c4faeda26b937a23eca00d7045aee309c8d 100644 (file)
@@ -173,7 +173,7 @@ loop:
                 */
                jbd_debug(1, "Now suspending kjournald2\n");
                write_unlock(&journal->j_state_lock);
-               refrigerator();
+               try_to_freeze();
                write_lock(&journal->j_state_lock);
        } else {
                /*
index 2d7109414cdd6b7a4d21bdb2e738ff20581523a4..a242f6f6a6b19c2c0ea5c13eb655120ed341d956 100644 (file)
@@ -1093,8 +1093,20 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
         */
        if (jh->b_transaction == transaction && jh->b_jlist == BJ_Metadata) {
                JBUFFER_TRACE(jh, "fastpath");
-               J_ASSERT_JH(jh, jh->b_transaction ==
-                                       journal->j_running_transaction);
+               if (unlikely(jh->b_transaction !=
+                            journal->j_running_transaction)) {
+                       printk(KERN_EMERG "JBD: %s: "
+                              "jh->b_transaction (%llu, %p, %u) != "
+                              "journal->j_running_transaction (%p, %u)",
+                              journal->j_devname,
+                              (unsigned long long) bh->b_blocknr,
+                              jh->b_transaction,
+                              jh->b_transaction ? jh->b_transaction->t_tid : 0,
+                              journal->j_running_transaction,
+                              journal->j_running_transaction ?
+                                journal->j_running_transaction->t_tid : 0);
+                       BUG_ON(1);
+               }
                goto out_unlock_bh;
        }
 
@@ -1108,9 +1120,33 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
         */
        if (jh->b_transaction != transaction) {
                JBUFFER_TRACE(jh, "already on other transaction");
-               J_ASSERT_JH(jh, jh->b_transaction ==
-                                       journal->j_committing_transaction);
-               J_ASSERT_JH(jh, jh->b_next_transaction == transaction);
+               if (unlikely(jh->b_transaction !=
+                            journal->j_committing_transaction)) {
+                       printk(KERN_EMERG "JBD: %s: "
+                              "jh->b_transaction (%llu, %p, %u) != "
+                              "journal->j_committing_transaction (%p, %u)",
+                              journal->j_devname,
+                              (unsigned long long) bh->b_blocknr,
+                              jh->b_transaction,
+                              jh->b_transaction ? jh->b_transaction->t_tid : 0,
+                              journal->j_committing_transaction,
+                              journal->j_committing_transaction ?
+                                journal->j_committing_transaction->t_tid : 0);
+                       BUG_ON(1);
+               }
+               if (unlikely(jh->b_next_transaction != transaction)) {
+                       printk(KERN_EMERG "JBD: %s: "
+                              "jh->b_next_transaction (%llu, %p, %u) != "
+                              "transaction (%p, %u)",
+                              journal->j_devname,
+                              (unsigned long long) bh->b_blocknr,
+                              jh->b_next_transaction,
+                              jh->b_next_transaction ?
+                                jh->b_next_transaction->t_tid : 0,
+                              transaction,
+                              transaction ? transaction->t_tid : 0);
+                       BUG_ON(1);
+               }
                /* And this case is illegal: we can't reuse another
                 * transaction's data buffer, ever. */
                goto out_unlock_bh;
index 8d8cd3419d02a75a7b0a7336da995a430324448b..28107ca136e481a556f686376292bf2244a78a91 100644 (file)
@@ -275,9 +275,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
        else
                c->mtd->unpoint(c->mtd, 0, c->mtd->size);
 #endif
-       if (s)
-               kfree(s);
-
+       kfree(s);
        return ret;
 }
 
index cfeb7164b0853a0d163cf7552f89577743067575..0f20208df60278c9f63f6c14c7b626cfd632ebf2 100644 (file)
 #include <linux/security.h>
 #include "nodelist.h"
 
-/* ---- Initial Security Label Attachment -------------- */
-int jffs2_init_security(struct inode *inode, struct inode *dir,
-                       const struct qstr *qstr)
+/* ---- Initial Security Label(s) Attachment callback --- */
+int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                    void *fs_info)
 {
-       int rc;
-       size_t len;
-       void *value;
-       char *name;
+       const struct xattr *xattr;
+       int err = 0;
 
-       rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
-       if (rc) {
-               if (rc == -EOPNOTSUPP)
-                       return 0;
-               return rc;
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
+                                       xattr->name, xattr->value,
+                                       xattr->value_len, 0);
+               if (err < 0)
+                       break;
        }
-       rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0);
+       return err;
+}
 
-       kfree(name);
-       kfree(value);
-       return rc;
+/* ---- Initial Security Label(s) Attachment ----------- */
+int jffs2_init_security(struct inode *inode, struct inode *dir,
+                       const struct qstr *qstr)
+{
+       return security_inode_init_security(inode, dir, qstr,
+                                           &jffs2_initxattrs, NULL);
 }
 
 /* ---- XATTR Handler for "security.*" ----------------- */
index 4515bea0268fa6ac17f8b2d61bd818bea42b6674..a10fb24ca6e6ede89ec825c68f832ddd7fba89ed 100644 (file)
@@ -578,8 +578,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
        if (!jffs2_is_writebuffered(c))
                return 0;
 
-       if (mutex_trylock(&c->alloc_sem)) {
-               mutex_unlock(&c->alloc_sem);
+       if (!mutex_is_locked(&c->alloc_sem)) {
                printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n");
                BUG();
        }
index 583636f745e59dbe7e66e1b3871496ac3b29a63d..c8c2d358d8dbde890dca8c6831c6fa19e7956fe1 100644 (file)
@@ -2348,7 +2348,7 @@ int jfsIOWait(void *arg)
 
                if (freezing(current)) {
                        spin_unlock_irq(&log_redrive_lock);
-                       refrigerator();
+                       try_to_freeze();
                } else {
                        set_current_state(TASK_INTERRUPTIBLE);
                        spin_unlock_irq(&log_redrive_lock);
index af9606057ddefa08d32904320db859af5ec4cde3..bb8b661bcc5055aeb63796b1bbcc47c309608019 100644 (file)
@@ -2800,7 +2800,7 @@ int jfs_lazycommit(void *arg)
 
                if (freezing(current)) {
                        LAZY_UNLOCK(flags);
-                       refrigerator();
+                       try_to_freeze();
                } else {
                        DECLARE_WAITQUEUE(wq, current);
 
@@ -2994,7 +2994,7 @@ int jfs_sync(void *arg)
 
                if (freezing(current)) {
                        TXN_UNLOCK();
-                       refrigerator();
+                       try_to_freeze();
                } else {
                        set_current_state(TASK_INTERRUPTIBLE);
                        TXN_UNLOCK();
index e87fedef23db7938aa7b38f64f385b0615e193b4..26683e15b3ac9f23991110687023e0f6e3bb0db0 100644 (file)
@@ -1089,38 +1089,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
 }
 
 #ifdef CONFIG_JFS_SECURITY
-int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
-                     const struct qstr *qstr)
+int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                  void *fs_info)
 {
-       int rc;
-       size_t len;
-       void *value;
-       char *suffix;
+       const struct xattr *xattr;
+       tid_t *tid = fs_info;
        char *name;
-
-       rc = security_inode_init_security(inode, dir, qstr, &suffix, &value,
-                                         &len);
-       if (rc) {
-               if (rc == -EOPNOTSUPP)
-                       return 0;
-               return rc;
-       }
-       name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix),
-                      GFP_NOFS);
-       if (!name) {
-               rc = -ENOMEM;
-               goto kmalloc_failed;
+       int err = 0;
+
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
+                              strlen(xattr->name) + 1, GFP_NOFS);
+               if (!name) {
+                       err = -ENOMEM;
+                       break;
+               }
+               strcpy(name, XATTR_SECURITY_PREFIX);
+               strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
+
+               err = __jfs_setxattr(*tid, inode, name,
+                                    xattr->value, xattr->value_len, 0);
+               kfree(name);
+               if (err < 0)
+                       break;
        }
-       strcpy(name, XATTR_SECURITY_PREFIX);
-       strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
-
-       rc = __jfs_setxattr(tid, inode, name, value, len, 0);
-
-       kfree(name);
-kmalloc_failed:
-       kfree(suffix);
-       kfree(value);
+       return err;
+}
 
-       return rc;
+int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
+                     const struct qstr *qstr)
+{
+       return security_inode_init_security(inode, dir, qstr,
+                                           &jfs_initxattrs, &tid);
 }
 #endif
index 339e17e9133d0a87f3f8306062d016ea9d328500..d054d7e975caf159912a2503f1e792a1efe1c01f 100644 (file)
@@ -150,14 +150,13 @@ static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs)
        filler_t *filler = mtd_readpage;
        struct mtd_info *mtd = super->s_mtd;
 
-       if (!mtd->block_isbad)
-               return NULL;
-
        *ofs = 0;
-       while (mtd->block_isbad(mtd, *ofs)) {
-               *ofs += mtd->erasesize;
-               if (*ofs >= mtd->size)
-                       return NULL;
+       if (mtd->block_isbad) {
+               while (mtd->block_isbad(mtd, *ofs)) {
+                       *ofs += mtd->erasesize;
+                       if (*ofs >= mtd->size)
+                               return NULL;
+               }
        }
        BUG_ON(*ofs & ~PAGE_MASK);
        return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
@@ -170,14 +169,13 @@ static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs)
        filler_t *filler = mtd_readpage;
        struct mtd_info *mtd = super->s_mtd;
 
-       if (!mtd->block_isbad)
-               return NULL;
-
        *ofs = mtd->size - mtd->erasesize;
-       while (mtd->block_isbad(mtd, *ofs)) {
-               *ofs -= mtd->erasesize;
-               if (*ofs <= 0)
-                       return NULL;
+       if (mtd->block_isbad) {
+               while (mtd->block_isbad(mtd, *ofs)) {
+                       *ofs -= mtd->erasesize;
+                       if (*ofs <= 0)
+                               return NULL;
+               }
        }
        *ofs = *ofs + mtd->erasesize - 0x1000;
        BUG_ON(*ofs & ~PAGE_MASK);
index f22d108bfa5dd54d4ea81129561f093076559a9f..68e4fd275a02b4984a290e6a43b95de654cc45cb 100644 (file)
@@ -594,6 +594,7 @@ int logfs_init_mapping(struct super_block *sb);
 void logfs_sync_area(struct logfs_area *area);
 void logfs_sync_segments(struct super_block *sb);
 void freeseg(struct super_block *sb, u32 segno);
+void free_areas(struct super_block *sb);
 
 /* area handling */
 int logfs_init_areas(struct super_block *sb);
index d8d09380c7deafd2b27e10606ef2f951fb044083..6cc8d6205f29cc91edcd726d37a7a4e48f53c05f 100644 (file)
@@ -1570,11 +1570,15 @@ int logfs_write_buf(struct inode *inode, struct page *page, long flags)
 static int __logfs_delete(struct inode *inode, struct page *page)
 {
        long flags = WF_DELETE;
+       int err;
 
        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 
        if (page->index < I0_BLOCKS)
                return logfs_write_direct(inode, page, flags);
+       err = grow_inode(inode, page->index, 0);
+       if (err)
+               return err;
        return logfs_write_rec(inode, page, page->index, 0, flags);
 }
 
index 9d5187353255ddf630a44afcb5e7d020dc8dd25c..ee7d4aa4a5b74bcb125137c6c9fdbdac471ee6bf 100644 (file)
@@ -841,6 +841,16 @@ static void free_area(struct logfs_area *area)
        kfree(area);
 }
 
+void free_areas(struct super_block *sb)
+{
+       struct logfs_super *super = logfs_super(sb);
+       int i;
+
+       for_each_area(i)
+               free_area(super->s_area[i]);
+       free_area(super->s_journal_area);
+}
+
 static struct logfs_area *alloc_area(struct super_block *sb)
 {
        struct logfs_area *area;
@@ -923,10 +933,6 @@ err:
 void logfs_cleanup_areas(struct super_block *sb)
 {
        struct logfs_super *super = logfs_super(sb);
-       int i;
 
        btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias);
-       for_each_area(i)
-               free_area(super->s_area[i]);
-       free_area(super->s_journal_area);
 }
index ce03a182c771c42e39e90c0f7b3737b897d02215..6506e9e392eb8a4f19c5bfe51c2aaa6e58a67ee2 100644 (file)
@@ -507,6 +507,7 @@ static void logfs_kill_sb(struct super_block *sb)
        /* Alias entries slow down mount, so evict as many as possible */
        sync_filesystem(sb);
        logfs_write_anchor(sb);
+       free_areas(sb);
 
        /*
         * From this point on alias entries are simply dropped - and any
index e8915d4840ad48457f23ecaac9e551fed5fa5652..6976a72576f51c19e30927d3ac1ba4166f5c0d9a 100644 (file)
@@ -48,13 +48,13 @@ filelayout_get_dense_offset(struct nfs4_filelayout_segment *flseg,
                            loff_t offset)
 {
        u32 stripe_width = flseg->stripe_unit * flseg->dsaddr->stripe_count;
-       u64 tmp;
+       u64 tmp, uoff;
 
        offset -= flseg->pattern_offset;
-       tmp = offset;
+       tmp = uoff = offset;
        do_div(tmp, stripe_width);
 
-       return tmp * flseg->stripe_unit + do_div(offset, flseg->stripe_unit);
+       return tmp * flseg->stripe_unit + do_div(uoff, flseg->stripe_unit);
 }
 
 /* This function is used by the layout driver to calculate the
index e80777666618d40d9c3f096d4c452c35e3f93cdf..d784ceb81a62f053f9f6dc9faf90d18ed64797f4 100644 (file)
@@ -168,6 +168,24 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
        return status;
 }
 
+static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
+{
+       umode_t mode = fh->fh_dentry->d_inode->i_mode;
+
+       if (S_ISREG(mode))
+               return nfs_ok;
+       if (S_ISDIR(mode))
+               return nfserr_isdir;
+       /*
+        * Using err_symlink as our catch-all case may look odd; but
+        * there's no other obvious error for this case in 4.0, and we
+        * happen to know that it will cause the linux v4 client to do
+        * the right thing on attempts to open something other than a
+        * regular file.
+        */
+       return nfserr_symlink;
+}
+
 static __be32
 do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
 {
@@ -216,6 +234,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
                status = nfsd_lookup(rqstp, current_fh,
                                     open->op_fname.data, open->op_fname.len, &resfh);
                fh_unlock(current_fh);
+               if (status)
+                       goto out;
+               status = nfsd_check_obj_isreg(&resfh);
        }
        if (status)
                goto out;
@@ -691,7 +712,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
        readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
 
-       if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) ||
+       if ((cookie == 1) || (cookie == 2) ||
            (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
                return nfserr_bad_cookie;
 
index c8bf405d19de53dcf521a5cac313b4fbc3da6f24..f81099605256fdac4b3249a4d10cb93eaf507b46 100644 (file)
@@ -1623,6 +1623,18 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
                                                                \
        save = resp->p;
 
+static bool seqid_mutating_err(__be32 err)
+{
+       /* rfc 3530 section 8.1.5: */
+       return  err != nfserr_stale_clientid &&
+               err != nfserr_stale_stateid &&
+               err != nfserr_bad_stateid &&
+               err != nfserr_bad_seqid &&
+               err != nfserr_bad_xdr &&
+               err != nfserr_resource &&
+               err != nfserr_nofilehandle;
+}
+
 /*
  * Routine for encoding the result of a "seqid-mutating" NFSv4 operation.  This
  * is where sequence id's are incremented, and the replay cache is filled.
index 4eefaf1b42e885e97b85bbf01f2081ec82c0db97..5cfebe504056c62a65e8c826c8b99252e2688a30 100644 (file)
@@ -447,12 +447,6 @@ struct nfs4_stateid {
 #define WR_STATE               0x00000020
 #define CLOSE_STATE             0x00000040
 
-#define seqid_mutating_err(err)                       \
-       (((err) != nfserr_stale_clientid) &&    \
-       ((err) != nfserr_bad_seqid) &&          \
-       ((err) != nfserr_stale_stateid) &&      \
-       ((err) != nfserr_bad_stateid))
-
 struct nfsd4_compound_state;
 
 extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
index fd0acca5370a5da699fe62a5d94d0b6e81f67b78..9c7ef668f6b1f303f065610af13f2b640d25a00e 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/fcntl.h>
 #include <linux/namei.h>
 #include <linux/delay.h>
-#include <linux/fsnotify.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/xattr.h>
 #include <linux/jhash.h>
@@ -904,7 +903,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                nfsdstats.io_read += host_err;
                *count = host_err;
                err = 0;
-               fsnotify_access(file);
        } else 
                err = nfserrno(host_err);
        return err;
@@ -1006,7 +1004,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                goto out_nfserr;
        *cnt = host_err;
        nfsdstats.io_write += host_err;
-       fsnotify_modify(file);
 
        /* clear setuid/setgid flag after write */
        if (inode->i_mode & (S_ISUID | S_ISGID))
index bb24ab6c282fae5099bc9442478c6689e1d44c59..0e72ad6f22aacfe7c30776eaae2ecdef7f22aba3 100644 (file)
@@ -2470,7 +2470,7 @@ static int nilfs_segctor_thread(void *arg)
 
        if (freezing(current)) {
                spin_unlock(&sci->sc_state_lock);
-               refrigerator();
+               try_to_freeze();
                spin_lock(&sci->sc_state_lock);
        } else {
                DEFINE_WAIT(wait);
index 3344bdd5506e3f06259efb7f176e0263764fc2dd..89ec7e0c15bc323eda0145fbe625521530d131d2 100644 (file)
@@ -31,7 +31,6 @@ int dir_notify_enable __read_mostly = 1;
 static struct kmem_cache *dnotify_struct_cache __read_mostly;
 static struct kmem_cache *dnotify_mark_cache __read_mostly;
 static struct fsnotify_group *dnotify_group __read_mostly;
-static DEFINE_MUTEX(dnotify_mark_mutex);
 
 /*
  * dnotify will attach one of these to each inode (i_fsnotify_marks) which
@@ -183,7 +182,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
                return;
        dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
 
-       mutex_lock(&dnotify_mark_mutex);
+       mutex_lock(&dnotify_group->mutex);
 
        spin_lock(&fsn_mark->lock);
        prev = &dn_mark->dn;
@@ -199,11 +198,11 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
 
        spin_unlock(&fsn_mark->lock);
 
-       /* nothing else could have found us thanks to the dnotify_mark_mutex */
+       /* nothing else could have found us thanks to the dnotify_group mutex */
        if (dn_mark->dn == NULL)
                fsnotify_destroy_mark(fsn_mark);
 
-       mutex_unlock(&dnotify_mark_mutex);
+       mutex_unlock(&dnotify_group->mutex);
 
        fsnotify_put_mark(fsn_mark);
 }
@@ -326,7 +325,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
        new_dn_mark->dn = NULL;
 
        /* this is needed to prevent the fcntl/close race described below */
-       mutex_lock(&dnotify_mark_mutex);
+       mutex_lock(&dnotify_group->mutex);
 
        /* add the new_fsn_mark or find an old one. */
        fsn_mark = fsnotify_find_inode_mark(dnotify_group, inode);
@@ -348,8 +347,8 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 
        /* if (f != filp) means that we lost a race and another task/thread
         * actually closed the fd we are still playing with before we grabbed
-        * the dnotify_mark_mutex and fsn_mark->lock.  Since closing the fd is the
-        * only time we clean up the marks we need to get our mark off
+        * the dnotify_group mutex and fsn_mark->lock. Since closing the fd is
+        * the only time we clean up the marks we need to get our mark off
         * the list. */
        if (f != filp) {
                /* if we added ourselves, shoot ourselves, it's possible that
@@ -387,7 +386,7 @@ out:
        if (destroy)
                fsnotify_destroy_mark(fsn_mark);
 
-       mutex_unlock(&dnotify_mark_mutex);
+       mutex_unlock(&dnotify_group->mutex);
        fsnotify_put_mark(fsn_mark);
 out_err:
        if (new_fsn_mark)
index f35794b97e8e5cb5cc396af28206d69ca1202935..c2ba86a972e113955f4cbd193dbe663b51860f1f 100644 (file)
@@ -184,13 +184,6 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
                marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
                marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
        } else if (inode_mark) {
-               /*
-                * if the event is for a child and this inode doesn't care about
-                * events on the child, don't send it!
-                */
-               if ((event_mask & FS_EVENT_ON_CHILD) &&
-                   !(inode_mark->mask & FS_EVENT_ON_CHILD))
-                       return false;
                marks_mask = inode_mark->mask;
                marks_ignored_mask = inode_mark->ignored_mask;
        } else if (vfsmnt_mark) {
@@ -204,10 +197,21 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
            (marks_ignored_mask & FS_ISDIR))
                return false;
 
-       if (event_mask & marks_mask & ~marks_ignored_mask)
-               return true;
+       /*
+        * if the event is for a child and this inode doesn't care about
+        * events on the child, don't send it!
+        */
+       if ((event_mask & FS_EVENT_ON_CHILD) &&
+           !(marks_mask & FS_EVENT_ON_CHILD))
+               return false;
 
-       return false;
+       /*
+        * It might seem logical to check:
+        * if (event_mask & marks_mask & ~marks_ignored_mask)
+        *      return true;
+        * but we we know this was true from the caller so just return true.
+        */
+       return true;
 }
 
 static void fanotify_free_group_priv(struct fsnotify_group *group)
index 9fde1c00a29627b88f3023441a8fc840d2f415c6..3fe62cb9ad34b99fa0a4a8b569e5c6038c59b510 100644 (file)
@@ -62,6 +62,7 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
        struct dentry *dentry;
        struct vfsmount *mnt;
        struct file *new_file;
+       unsigned int flags;
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
@@ -83,12 +84,22 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
        mnt = mntget(event->path.mnt);
        /* it's possible this event was an overflow event.  in that case dentry and mnt
         * are NULL;  That's fine, just don't call dentry open */
-       if (dentry && mnt)
-               new_file = dentry_open(dentry, mnt,
-                                      group->fanotify_data.f_flags | FMODE_NONOTIFY,
-                                      current_cred());
-       else
+       if (dentry && mnt) {
+               flags = group->fanotify_data.f_flags;
+               new_file = dentry_open(dentry, mnt, flags, current_cred());
+               /*
+                * Attempt fallback to read-only access if writable was not possible
+                * in order to at least provide something to the listener.
+                */
+               if (IS_ERR(new_file) && group->fanotify_data.readonly_fallback) {
+                       flags &= ~O_ACCMODE;
+                       flags |= O_RDONLY;
+                       new_file = dentry_open(dentry, mnt, flags,
+                                              current_cred());
+               }
+       } else {
                new_file = ERR_PTR(-EOVERFLOW);
+       }
        if (IS_ERR(new_file)) {
                /*
                 * we still send an event even if we can't open the file.  this
@@ -208,14 +219,6 @@ static int prepare_for_access_response(struct fsnotify_group *group,
        re->fd = fd;
 
        mutex_lock(&group->fanotify_data.access_mutex);
-
-       if (atomic_read(&group->fanotify_data.bypass_perm)) {
-               mutex_unlock(&group->fanotify_data.access_mutex);
-               kmem_cache_free(fanotify_response_event_cache, re);
-               event->response = FAN_ALLOW;
-               return 0;
-       }
-               
        list_add_tail(&re->list, &group->fanotify_data.access_list);
        mutex_unlock(&group->fanotify_data.access_mutex);
 
@@ -516,6 +519,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
                                            unsigned int flags)
 {
        __u32 oldmask;
+       int destroy_mark;
 
        spin_lock(&fsn_mark->lock);
        if (!(flags & FAN_MARK_IGNORED_MASK)) {
@@ -525,9 +529,10 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
                oldmask = fsn_mark->ignored_mask;
                fsnotify_set_mark_ignored_mask_locked(fsn_mark, (oldmask & ~mask));
        }
+       destroy_mark = (!fsn_mark->mask && !fsn_mark->ignored_mask);
        spin_unlock(&fsn_mark->lock);
 
-       if (!(oldmask & ~mask))
+       if (destroy_mark)
                fsnotify_destroy_mark(fsn_mark);
 
        return mask & oldmask;
@@ -539,17 +544,23 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark = NULL;
        __u32 removed;
+       int ret;
 
+       mutex_lock(&group->mutex);
+       ret = -ENOENT;
        fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
        if (!fsn_mark)
-               return -ENOENT;
+               goto err;
 
        removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags);
        fsnotify_put_mark(fsn_mark);
        if (removed & mnt->mnt_fsnotify_mask)
                fsnotify_recalc_vfsmount_mask(mnt);
+       ret = 0;
+err:
+       mutex_unlock(&group->mutex);
 
-       return 0;
+       return ret;
 }
 
 static int fanotify_remove_inode_mark(struct fsnotify_group *group,
@@ -558,18 +569,24 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark = NULL;
        __u32 removed;
+       int ret;
 
+       mutex_lock(&group->mutex);
+       ret = -ENOENT;
        fsn_mark = fsnotify_find_inode_mark(group, inode);
        if (!fsn_mark)
-               return -ENOENT;
+               goto err;
 
        removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags);
        /* matches the fsnotify_find_inode_mark() */
        fsnotify_put_mark(fsn_mark);
        if (removed & inode->i_fsnotify_mask)
                fsnotify_recalc_inode_mask(inode);
+       ret = 0;
+err:
+       mutex_unlock(&group->mutex);
 
-       return 0;
+       return ret;
 }
 
 static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
@@ -605,28 +622,35 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark;
        __u32 added;
-       int ret = 0;
+       int ret;
 
+       mutex_lock(&group->mutex);
        fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
        if (!fsn_mark) {
-               if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
-                       return -ENOSPC;
+               ret = -ENOSPC;
+               if (atomic_read(&group->num_marks) >
+                   group->fanotify_data.max_marks)
+                       goto err;
 
+               ret = -ENOMEM;
                fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
                if (!fsn_mark)
-                       return -ENOMEM;
+                       goto err;
 
                fsnotify_init_mark(fsn_mark, fanotify_free_mark);
                ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0);
                if (ret)
-                       goto err;
+                       goto err2;
        }
        added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
 
        if (added & ~mnt->mnt_fsnotify_mask)
                fsnotify_recalc_vfsmount_mask(mnt);
-err:
+       ret = 0;
+err2:
        fsnotify_put_mark(fsn_mark);
+err:
+       mutex_unlock(&group->mutex);
        return ret;
 }
 
@@ -636,7 +660,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark;
        __u32 added;
-       int ret = 0;
+       int ret;
 
        pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
@@ -650,26 +674,33 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
            (atomic_read(&inode->i_writecount) > 0))
                return 0;
 
+       mutex_lock(&group->mutex);
        fsn_mark = fsnotify_find_inode_mark(group, inode);
        if (!fsn_mark) {
-               if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
-                       return -ENOSPC;
+               ret = -ENOSPC;
+               if (atomic_read(&group->num_marks) >
+                   group->fanotify_data.max_marks)
+                       goto err;
 
+               ret = -ENOMEM;
                fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
                if (!fsn_mark)
-                       return -ENOMEM;
+                       goto err;
 
                fsnotify_init_mark(fsn_mark, fanotify_free_mark);
                ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0);
                if (ret)
-                       goto err;
+                       goto err2;
        }
        added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
 
        if (added & ~inode->i_fsnotify_mask)
                fsnotify_recalc_inode_mask(inode);
-err:
+       ret = 0;
+err2:
        fsnotify_put_mark(fsn_mark);
+err:
+       mutex_unlock(&group->mutex);
        return ret;
 }
 
@@ -711,7 +742,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        group->fanotify_data.user = user;
        atomic_inc(&user->fanotify_listeners);
 
-       group->fanotify_data.f_flags = event_f_flags;
+       group->fanotify_data.f_flags = event_f_flags | FMODE_NONOTIFY;
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
        mutex_init(&group->fanotify_data.access_mutex);
        init_waitqueue_head(&group->fanotify_data.access_waitq);
@@ -751,6 +782,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
                group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
        }
 
+       fd = -EINVAL;
+       if (flags & FAN_READONLY_FALLBACK) {
+               if ((event_f_flags & O_ACCMODE) == O_RDWR)
+                       group->fanotify_data.readonly_fallback = true;
+               else
+                       goto out_put_group;
+       }
+
        fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
        if (fd < 0)
                goto out_put_group;
index 63fc294a469268d06d9ae1cc9f3d19f3ba95f695..7558c54f2b51efc05b32e6e6c78be7397b3541b1 100644 (file)
@@ -90,6 +90,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
         */
        atomic_set(&group->num_marks, 1);
 
+       mutex_init(&group->mutex);
        mutex_init(&group->notification_mutex);
        INIT_LIST_HEAD(&group->notification_list);
        init_waitqueue_head(&group->notification_waitq);
index e14587d55689dae3cedccd1d2afeb1242ab0947c..9d08e2a2acd770cd182e1e44bbfa53dc543a9f93 100644 (file)
@@ -102,17 +102,6 @@ static DEFINE_SPINLOCK(destroy_lock);
 static LIST_HEAD(destroy_list);
 static DECLARE_WAIT_QUEUE_HEAD(destroy_waitq);
 
-void fsnotify_get_mark(struct fsnotify_mark *mark)
-{
-       atomic_inc(&mark->refcnt);
-}
-
-void fsnotify_put_mark(struct fsnotify_mark *mark)
-{
-       if (atomic_dec_and_test(&mark->refcnt))
-               mark->free_mark(mark);
-}
-
 /*
  * Any time a mark is getting freed we end up here.
  * The caller had better be holding a reference to this mark so we don't actually
@@ -216,7 +205,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
                      struct fsnotify_group *group, struct inode *inode,
                      struct vfsmount *mnt, int allow_dups)
 {
-       int ret = 0;
+       int ret;
 
        BUG_ON(inode && mnt);
        BUG_ON(!inode && !mnt);
@@ -231,23 +220,20 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
        spin_lock(&group->mark_lock);
 
        mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE;
-
        mark->group = group;
        list_add(&mark->g_list, &group->marks_list);
-       atomic_inc(&group->num_marks);
        fsnotify_get_mark(mark); /* for i_list and g_list */
+       atomic_inc(&group->num_marks);
 
-       if (inode) {
+       ret = 0;
+       if (inode)
                ret = fsnotify_add_inode_mark(mark, group, inode, allow_dups);
-               if (ret)
-                       goto err;
-       } else if (mnt) {
+       else if (mnt)
                ret = fsnotify_add_vfsmount_mark(mark, group, mnt, allow_dups);
-               if (ret)
-                       goto err;
-       } else {
+       else
                BUG();
-       }
+       if (ret)
+               goto err;
 
        spin_unlock(&group->mark_lock);
 
@@ -259,7 +245,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
        if (inode)
                __fsnotify_update_child_dentry_flags(inode);
 
-       return ret;
+       return 0;
 err:
        mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
        list_del_init(&mark->g_list);
@@ -345,6 +331,10 @@ static int fsnotify_mark_destroy(void *ignored)
 
                synchronize_srcu(&fsnotify_mark_srcu);
 
+               /*
+                * at this point we cannot be found via the i_list or g_list so
+                * drop that reference.
+                */
                list_for_each_entry_safe(mark, next, &private_destroy_list, destroy_list) {
                        list_del_init(&mark->destroy_list);
                        fsnotify_put_mark(mark);
index c1efe939c774e2c9b909892f6c95434d6da760ee..78b68af3b0e32627b1874277d8ae58003501acb5 100644 (file)
@@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page)
        }
 
        if (down_read_trylock(&oi->ip_alloc_sem) == 0) {
+               /*
+                * Unlock the page and cycle ip_alloc_sem so that we don't
+                * busyloop waiting for ip_alloc_sem to unlock
+                */
                ret = AOP_TRUNCATED_PAGE;
+               unlock_page(page);
+               unlock = 0;
+               down_read(&oi->ip_alloc_sem);
+               up_read(&oi->ip_alloc_sem);
                goto out_inode_unlock;
        }
 
@@ -563,6 +571,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
        int level;
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
 
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
@@ -570,6 +579,15 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
        if (ocfs2_iocb_is_sem_locked(iocb))
                ocfs2_iocb_clear_sem_locked(iocb);
 
+       if (ocfs2_iocb_is_unaligned_aio(iocb)) {
+               ocfs2_iocb_clear_unaligned_aio(iocb);
+
+               if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) &&
+                   waitqueue_active(wq)) {
+                       wake_up_all(wq);
+               }
+       }
+
        ocfs2_iocb_clear_rw_locked(iocb);
 
        level = ocfs2_iocb_rw_locked_level(iocb);
@@ -862,6 +880,12 @@ struct ocfs2_write_ctxt {
        struct page                     *w_pages[OCFS2_MAX_CTXT_PAGES];
        struct page                     *w_target_page;
 
+       /*
+        * w_target_locked is used for page_mkwrite path indicating no unlocking
+        * against w_target_page in ocfs2_write_end_nolock.
+        */
+       unsigned int                    w_target_locked:1;
+
        /*
         * ocfs2_write_end() uses this to know what the real range to
         * write in the target should be.
@@ -895,6 +919,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
 
 static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
 {
+       int i;
+
+       /*
+        * w_target_locked is only set to true in the page_mkwrite() case.
+        * The intent is to allow us to lock the target page from write_begin()
+        * to write_end(). The caller must hold a ref on w_target_page.
+        */
+       if (wc->w_target_locked) {
+               BUG_ON(!wc->w_target_page);
+               for (i = 0; i < wc->w_num_pages; i++) {
+                       if (wc->w_target_page == wc->w_pages[i]) {
+                               wc->w_pages[i] = NULL;
+                               break;
+                       }
+               }
+               mark_page_accessed(wc->w_target_page);
+               page_cache_release(wc->w_target_page);
+       }
        ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
 
        brelse(wc->w_di_bh);
@@ -1132,20 +1174,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                         */
                        lock_page(mmap_page);
 
+                       /* Exit and let the caller retry */
                        if (mmap_page->mapping != mapping) {
+                               WARN_ON(mmap_page->mapping);
                                unlock_page(mmap_page);
-                               /*
-                                * Sanity check - the locking in
-                                * ocfs2_pagemkwrite() should ensure
-                                * that this code doesn't trigger.
-                                */
-                               ret = -EINVAL;
-                               mlog_errno(ret);
+                               ret = -EAGAIN;
                                goto out;
                        }
 
                        page_cache_get(mmap_page);
                        wc->w_pages[i] = mmap_page;
+                       wc->w_target_locked = true;
                } else {
                        wc->w_pages[i] = find_or_create_page(mapping, index,
                                                             GFP_NOFS);
@@ -1160,6 +1199,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                        wc->w_target_page = wc->w_pages[i];
        }
 out:
+       if (ret)
+               wc->w_target_locked = false;
        return ret;
 }
 
@@ -1817,11 +1858,23 @@ try_again:
         */
        ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
                                         cluster_of_pages, mmap_page);
-       if (ret) {
+       if (ret && ret != -EAGAIN) {
                mlog_errno(ret);
                goto out_quota;
        }
 
+       /*
+        * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
+        * the target page. In this case, we exit with no error and no target
+        * page. This will trigger the caller, page_mkwrite(), to re-try
+        * the operation.
+        */
+       if (ret == -EAGAIN) {
+               BUG_ON(wc->w_target_page);
+               ret = 0;
+               goto out_quota;
+       }
+
        ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
                                          len);
        if (ret) {
index 75cf3ad987a66d911c15234a803243185ccc5a94..ffb2da370a99d05dd4b919fc64a5483dbc2df7a3 100644 (file)
@@ -78,6 +78,7 @@ enum ocfs2_iocb_lock_bits {
        OCFS2_IOCB_RW_LOCK = 0,
        OCFS2_IOCB_RW_LOCK_LEVEL,
        OCFS2_IOCB_SEM,
+       OCFS2_IOCB_UNALIGNED_IO,
        OCFS2_IOCB_NUM_LOCKS
 };
 
@@ -91,4 +92,17 @@ enum ocfs2_iocb_lock_bits {
        clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
 #define ocfs2_iocb_is_sem_locked(iocb) \
        test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+
+#define ocfs2_iocb_set_unaligned_aio(iocb) \
+       set_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_unaligned_aio(iocb) \
+       clear_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_is_unaligned_aio(iocb) \
+       test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+
+#define OCFS2_IOEND_WQ_HASH_SZ 37
+#define ocfs2_ioend_wq(v)   (&ocfs2__ioend_wq[((unsigned long)(v)) %\
+                                           OCFS2_IOEND_WQ_HASH_SZ])
+extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 #endif /* OCFS2_FILE_H */
index 9a3e6bbff27bd4839b487c2c14282fd9ef1a4675..a4e855e3690e6ab844d37788b71649975321cb19 100644 (file)
@@ -216,6 +216,7 @@ struct o2hb_region {
 
        struct list_head        hr_all_item;
        unsigned                hr_unclean_stop:1,
+                               hr_aborted_start:1,
                                hr_item_pinned:1,
                                hr_item_dropped:1;
 
@@ -254,6 +255,10 @@ struct o2hb_region {
         * a more complete api that doesn't lead to this sort of fragility. */
        atomic_t                hr_steady_iterations;
 
+       /* terminate o2hb thread if it does not reach steady state
+        * (hr_steady_iterations == 0) within hr_unsteady_iterations */
+       atomic_t                hr_unsteady_iterations;
+
        char                    hr_dev_name[BDEVNAME_SIZE];
 
        unsigned int            hr_timeout_ms;
@@ -324,6 +329,10 @@ static void o2hb_write_timeout(struct work_struct *work)
 
 static void o2hb_arm_write_timeout(struct o2hb_region *reg)
 {
+       /* Arm writeout only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
+               return;
+
        mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n",
             O2HB_MAX_WRITE_TIMEOUT_MS);
 
@@ -537,9 +546,14 @@ static int o2hb_verify_crc(struct o2hb_region *reg,
        return read == computed;
 }
 
-/* We want to make sure that nobody is heartbeating on top of us --
- * this will help detect an invalid configuration. */
-static void o2hb_check_last_timestamp(struct o2hb_region *reg)
+/*
+ * Compare the slot data with what we wrote in the last iteration.
+ * If the match fails, print an appropriate error message. This is to
+ * detect errors like... another node hearting on the same slot,
+ * flaky device that is losing writes, etc.
+ * Returns 1 if check succeeds, 0 otherwise.
+ */
+static int o2hb_check_own_slot(struct o2hb_region *reg)
 {
        struct o2hb_disk_slot *slot;
        struct o2hb_disk_heartbeat_block *hb_block;
@@ -548,13 +562,13 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
        slot = &reg->hr_slots[o2nm_this_node()];
        /* Don't check on our 1st timestamp */
        if (!slot->ds_last_time)
-               return;
+               return 0;
 
        hb_block = slot->ds_raw_block;
        if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time &&
            le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation &&
            hb_block->hb_node == slot->ds_node_num)
-               return;
+               return 1;
 
 #define ERRSTR1                "Another node is heartbeating on device"
 #define ERRSTR2                "Heartbeat generation mismatch on device"
@@ -574,6 +588,8 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
             (unsigned long long)slot->ds_last_time, hb_block->hb_node,
             (unsigned long long)le64_to_cpu(hb_block->hb_generation),
             (unsigned long long)le64_to_cpu(hb_block->hb_seq));
+
+       return 0;
 }
 
 static inline void o2hb_prepare_block(struct o2hb_region *reg,
@@ -719,17 +735,24 @@ static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot)
        o2nm_node_put(node);
 }
 
-static void o2hb_set_quorum_device(struct o2hb_region *reg,
-                                  struct o2hb_disk_slot *slot)
+static void o2hb_set_quorum_device(struct o2hb_region *reg)
 {
-       assert_spin_locked(&o2hb_live_lock);
-
        if (!o2hb_global_heartbeat_active())
                return;
 
-       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+       /* Prevent race with o2hb_heartbeat_group_drop_item() */
+       if (kthread_should_stop())
+               return;
+
+       /* Tag region as quorum only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
                return;
 
+       spin_lock(&o2hb_live_lock);
+
+       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+               goto unlock;
+
        /*
         * A region can be added to the quorum only when it sees all
         * live nodes heartbeat on it. In other words, the region has been
@@ -737,13 +760,10 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
         */
        if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap,
                   sizeof(o2hb_live_node_bitmap)))
-               return;
-
-       if (slot->ds_changed_samples < O2HB_LIVE_THRESHOLD)
-               return;
+               goto unlock;
 
-       printk(KERN_NOTICE "o2hb: Region %s is now a quorum device\n",
-              config_item_name(&reg->hr_item));
+       printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n",
+              config_item_name(&reg->hr_item), reg->hr_dev_name);
 
        set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
 
@@ -754,6 +774,8 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
        if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
                           O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF)
                o2hb_region_unpin(NULL);
+unlock:
+       spin_unlock(&o2hb_live_lock);
 }
 
 static int o2hb_check_slot(struct o2hb_region *reg,
@@ -925,8 +947,6 @@ fire_callbacks:
                slot->ds_equal_samples = 0;
        }
 out:
-       o2hb_set_quorum_device(reg, slot);
-
        spin_unlock(&o2hb_live_lock);
 
        o2hb_run_event_list(&event);
@@ -957,7 +977,8 @@ static int o2hb_highest_node(unsigned long *nodes,
 
 static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 {
-       int i, ret, highest_node, change = 0;
+       int i, ret, highest_node;
+       int membership_change = 0, own_slot_ok = 0;
        unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
        unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
        struct o2hb_bio_wait_ctxt write_wc;
@@ -966,7 +987,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                                       sizeof(configured_nodes));
        if (ret) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /*
@@ -982,8 +1003,9 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 
        highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES);
        if (highest_node >= O2NM_MAX_NODES) {
-               mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n");
-               return -EINVAL;
+               mlog(ML_NOTICE, "o2hb: No configured nodes found!\n");
+               ret = -EINVAL;
+               goto bail;
        }
 
        /* No sense in reading the slots of nodes that don't exist
@@ -993,29 +1015,27 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
        ret = o2hb_read_slots(reg, highest_node + 1);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /* With an up to date view of the slots, we can check that no
         * other node has been improperly configured to heartbeat in
         * our slot. */
-       o2hb_check_last_timestamp(reg);
+       own_slot_ok = o2hb_check_own_slot(reg);
 
        /* fill in the proper info for our next heartbeat */
        o2hb_prepare_block(reg, reg->hr_generation);
 
-       /* And fire off the write. Note that we don't wait on this I/O
-        * until later. */
        ret = o2hb_issue_node_write(reg, &write_wc);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        i = -1;
        while((i = find_next_bit(configured_nodes,
                                 O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) {
-               change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
+               membership_change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
        }
 
        /*
@@ -1030,18 +1050,39 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                 * disk */
                mlog(ML_ERROR, "Write error %d on device \"%s\"\n",
                     write_wc.wc_error, reg->hr_dev_name);
-               return write_wc.wc_error;
+               ret = write_wc.wc_error;
+               goto bail;
        }
 
-       o2hb_arm_write_timeout(reg);
+       /* Skip disarming the timeout if own slot has stale/bad data */
+       if (own_slot_ok) {
+               o2hb_set_quorum_device(reg);
+               o2hb_arm_write_timeout(reg);
+       }
 
+bail:
        /* let the person who launched us know when things are steady */
-       if (!change && (atomic_read(&reg->hr_steady_iterations) != 0)) {
-               if (atomic_dec_and_test(&reg->hr_steady_iterations))
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (!ret && own_slot_ok && !membership_change) {
+                       if (atomic_dec_and_test(&reg->hr_steady_iterations))
+                               wake_up(&o2hb_steady_queue);
+               }
+       }
+
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (atomic_dec_and_test(&reg->hr_unsteady_iterations)) {
+                       printk(KERN_NOTICE "o2hb: Unable to stabilize "
+                              "heartbeart on region %s (%s)\n",
+                              config_item_name(&reg->hr_item),
+                              reg->hr_dev_name);
+                       atomic_set(&reg->hr_steady_iterations, 0);
+                       reg->hr_aborted_start = 1;
                        wake_up(&o2hb_steady_queue);
+                       ret = -EIO;
+               }
        }
 
-       return 0;
+       return ret;
 }
 
 /* Subtract b from a, storing the result in a. a *must* have a larger
@@ -1095,7 +1136,8 @@ static int o2hb_thread(void *data)
        /* Pin node */
        o2nm_depend_this_node();
 
-       while (!kthread_should_stop() && !reg->hr_unclean_stop) {
+       while (!kthread_should_stop() &&
+              !reg->hr_unclean_stop && !reg->hr_aborted_start) {
                /* We track the time spent inside
                 * o2hb_do_disk_heartbeat so that we avoid more than
                 * hr_timeout_ms between disk writes. On busy systems
@@ -1103,10 +1145,7 @@ static int o2hb_thread(void *data)
                 * likely to time itself out. */
                do_gettimeofday(&before_hb);
 
-               i = 0;
-               do {
-                       ret = o2hb_do_disk_heartbeat(reg);
-               } while (ret && ++i < 2);
+               ret = o2hb_do_disk_heartbeat(reg);
 
                do_gettimeofday(&after_hb);
                elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
@@ -1117,7 +1156,8 @@ static int o2hb_thread(void *data)
                     after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
                     elapsed_msec);
 
-               if (elapsed_msec < reg->hr_timeout_ms) {
+               if (!kthread_should_stop() &&
+                   elapsed_msec < reg->hr_timeout_ms) {
                        /* the kthread api has blocked signals for us so no
                         * need to record the return value. */
                        msleep_interruptible(reg->hr_timeout_ms - elapsed_msec);
@@ -1134,20 +1174,20 @@ static int o2hb_thread(void *data)
         * to timeout on this region when we could just as easily
         * write a clear generation - thus indicating to them that
         * this node has left this region.
-        *
-        * XXX: Should we skip this on unclean_stop? */
-       o2hb_prepare_block(reg, 0);
-       ret = o2hb_issue_node_write(reg, &write_wc);
-       if (ret == 0) {
-               o2hb_wait_on_io(reg, &write_wc);
-       } else {
-               mlog_errno(ret);
+        */
+       if (!reg->hr_unclean_stop && !reg->hr_aborted_start) {
+               o2hb_prepare_block(reg, 0);
+               ret = o2hb_issue_node_write(reg, &write_wc);
+               if (ret == 0)
+                       o2hb_wait_on_io(reg, &write_wc);
+               else
+                       mlog_errno(ret);
        }
 
        /* Unpin node */
        o2nm_undepend_this_node();
 
-       mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n");
+       mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n");
 
        return 0;
 }
@@ -1158,6 +1198,7 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
        struct o2hb_debug_buf *db = inode->i_private;
        struct o2hb_region *reg;
        unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long lts;
        char *buf = NULL;
        int i = -1;
        int out = 0;
@@ -1194,9 +1235,11 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
 
        case O2HB_DB_TYPE_REGION_ELAPSED_TIME:
                reg = (struct o2hb_region *)db->db_data;
-               out += snprintf(buf + out, PAGE_SIZE - out, "%u\n",
-                               jiffies_to_msecs(jiffies -
-                                                reg->hr_last_timeout_start));
+               lts = reg->hr_last_timeout_start;
+               /* If 0, it has never been set before */
+               if (lts)
+                       lts = jiffies_to_msecs(jiffies - lts);
+               out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts);
                goto done;
 
        case O2HB_DB_TYPE_REGION_PINNED:
@@ -1426,6 +1469,8 @@ static void o2hb_region_release(struct config_item *item)
        struct page *page;
        struct o2hb_region *reg = to_o2hb_region(item);
 
+       mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name);
+
        if (reg->hr_tmp_block)
                kfree(reg->hr_tmp_block);
 
@@ -1792,7 +1837,10 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                        live_threshold <<= 1;
                spin_unlock(&o2hb_live_lock);
        }
-       atomic_set(&reg->hr_steady_iterations, live_threshold + 1);
+       ++live_threshold;
+       atomic_set(&reg->hr_steady_iterations, live_threshold);
+       /* unsteady_iterations is double the steady_iterations */
+       atomic_set(&reg->hr_unsteady_iterations, (live_threshold << 1));
 
        hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
                              reg->hr_item.ci_name);
@@ -1809,14 +1857,12 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
        ret = wait_event_interruptible(o2hb_steady_queue,
                                atomic_read(&reg->hr_steady_iterations) == 0);
        if (ret) {
-               /* We got interrupted (hello ptrace!).  Clean up */
-               spin_lock(&o2hb_live_lock);
-               hb_task = reg->hr_task;
-               reg->hr_task = NULL;
-               spin_unlock(&o2hb_live_lock);
+               atomic_set(&reg->hr_steady_iterations, 0);
+               reg->hr_aborted_start = 1;
+       }
 
-               if (hb_task)
-                       kthread_stop(hb_task);
+       if (reg->hr_aborted_start) {
+               ret = -EIO;
                goto out;
        }
 
@@ -1833,8 +1879,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                ret = -EIO;
 
        if (hb_task && o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s\n",
-                      config_item_name(&reg->hr_item));
+               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n",
+                      config_item_name(&reg->hr_item), reg->hr_dev_name);
 
 out:
        if (filp)
@@ -2092,13 +2138,6 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
 
        /* stop the thread when the user removes the region dir */
        spin_lock(&o2hb_live_lock);
-       if (o2hb_global_heartbeat_active()) {
-               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
-               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
-               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
-                       quorum_region = 1;
-               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
-       }
        hb_task = reg->hr_task;
        reg->hr_task = NULL;
        reg->hr_item_dropped = 1;
@@ -2107,19 +2146,30 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
        if (hb_task)
                kthread_stop(hb_task);
 
+       if (o2hb_global_heartbeat_active()) {
+               spin_lock(&o2hb_live_lock);
+               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
+               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
+               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+                       quorum_region = 1;
+               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
+               spin_unlock(&o2hb_live_lock);
+               printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n",
+                      ((atomic_read(&reg->hr_steady_iterations) == 0) ?
+                       "stopped" : "start aborted"), config_item_name(item),
+                      reg->hr_dev_name);
+       }
+
        /*
         * If we're racing a dev_write(), we need to wake them.  They will
         * check reg->hr_task
         */
        if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               reg->hr_aborted_start = 1;
                atomic_set(&reg->hr_steady_iterations, 0);
                wake_up(&o2hb_steady_queue);
        }
 
-       if (o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n",
-                      config_item_name(&reg->hr_item));
-
        config_item_put(item);
 
        if (!o2hb_global_heartbeat_active() || !quorum_region)
index 3a5835904b3db4d522c561908171f528bb74f6bd..dc45deb19e6885e56a1f5be46cbd39444c46f810 100644 (file)
@@ -47,6 +47,7 @@
 #define SC_DEBUG_NAME          "sock_containers"
 #define NST_DEBUG_NAME         "send_tracking"
 #define STATS_DEBUG_NAME       "stats"
+#define NODES_DEBUG_NAME       "connected_nodes"
 
 #define SHOW_SOCK_CONTAINERS   0
 #define SHOW_SOCK_STATS                1
@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry;
 static struct dentry *sc_dentry;
 static struct dentry *nst_dentry;
 static struct dentry *stats_dentry;
+static struct dentry *nodes_dentry;
 
 static DEFINE_SPINLOCK(o2net_debug_lock);
 
@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = {
        .release = sc_fop_release,
 };
 
-int o2net_debugfs_init(void)
+static int o2net_fill_bitmap(char *buf, int len)
 {
-       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
-       if (!o2net_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       int i = -1, out = 0;
 
-       nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                        o2net_dentry, NULL,
-                                        &nst_seq_fops);
-       if (!nst_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       o2net_fill_node_map(map, sizeof(map));
 
-       sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                       o2net_dentry, NULL,
-                                       &sc_seq_fops);
-       if (!sc_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
+               out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
+       out += snprintf(buf + out, PAGE_SIZE - out, "\n");
 
-       stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                          o2net_dentry, NULL,
-                                          &stats_seq_fops);
-       if (!stats_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       return out;
+}
+
+static int nodes_fop_open(struct inode *inode, struct file *file)
+{
+       char *buf;
+
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE));
+
+       file->private_data = buf;
 
        return 0;
-bail:
-       debugfs_remove(stats_dentry);
-       debugfs_remove(sc_dentry);
-       debugfs_remove(nst_dentry);
-       debugfs_remove(o2net_dentry);
-       return -ENOMEM;
 }
 
+static int o2net_debug_release(struct inode *inode, struct file *file)
+{
+       kfree(file->private_data);
+       return 0;
+}
+
+static ssize_t o2net_debug_read(struct file *file, char __user *buf,
+                               size_t nbytes, loff_t *ppos)
+{
+       return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+                                      i_size_read(file->f_mapping->host));
+}
+
+static const struct file_operations nodes_fops = {
+       .open           = nodes_fop_open,
+       .release        = o2net_debug_release,
+       .read           = o2net_debug_read,
+       .llseek         = generic_file_llseek,
+};
+
 void o2net_debugfs_exit(void)
 {
+       debugfs_remove(nodes_dentry);
        debugfs_remove(stats_dentry);
        debugfs_remove(sc_dentry);
        debugfs_remove(nst_dentry);
        debugfs_remove(o2net_dentry);
 }
 
+int o2net_debugfs_init(void)
+{
+       mode_t mode = S_IFREG|S_IRUSR;
+
+       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
+       if (o2net_dentry)
+               nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nst_seq_fops);
+       if (nst_dentry)
+               sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &sc_seq_fops);
+       if (sc_dentry)
+               stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &stats_seq_fops);
+       if (stats_dentry)
+               nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nodes_fops);
+       if (nodes_dentry)
+               return 0;
+
+       o2net_debugfs_exit();
+       mlog_errno(-ENOMEM);
+       return -ENOMEM;
+}
+
 #endif /* CONFIG_DEBUG_FS */
index db5ee4b4f47aaf36f698a004fbc99b0f3e722380..ae13d5ca7908cdd1af57876c0ca0c755a94affcb 100644 (file)
@@ -545,7 +545,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
        }
 
        if (was_valid && !valid) {
-               printk(KERN_NOTICE "o2net: no longer connected to "
+               printk(KERN_NOTICE "o2net: No longer connected to "
                       SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc));
                o2net_complete_nodes_nsw(nn);
        }
@@ -555,7 +555,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                cancel_delayed_work(&nn->nn_connect_expired);
                printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n",
                       o2nm_this_node() > sc->sc_node->nd_num ?
-                               "connected to" : "accepted connection from",
+                      "Connected to" : "Accepted connection from",
                       SC_NODEF_ARGS(sc));
        }
 
@@ -643,7 +643,7 @@ static void o2net_state_change(struct sock *sk)
                        o2net_sc_queue_work(sc, &sc->sc_connect_work);
                        break;
                default:
-                       printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT
+                       printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT
                              " shutdown, state %d\n",
                              SC_NODEF_ARGS(sc), sk->sk_state);
                        o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
@@ -1034,6 +1034,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
        return ret;
 }
 
+/* Get a map of all nodes to which this node is currently connected to */
+void o2net_fill_node_map(unsigned long *map, unsigned bytes)
+{
+       struct o2net_sock_container *sc;
+       int node, ret;
+
+       BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));
+
+       memset(map, 0, bytes);
+       for (node = 0; node < O2NM_MAX_NODES; ++node) {
+               o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret);
+               if (!ret) {
+                       set_bit(node, map);
+                       sc_put(sc);
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(o2net_fill_node_map);
+
 int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                           size_t caller_veclen, u8 target_node, int *status)
 {
@@ -1284,11 +1303,11 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
 
        if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " advertised net protocol "
-                    "version %llu but %llu is required, disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    (unsigned long long)be64_to_cpu(hand->protocol_version),
-                    O2NET_PROTOCOL_VERSION);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net "
+                      "protocol version %llu but %llu is required. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      (unsigned long long)be64_to_cpu(hand->protocol_version),
+                      O2NET_PROTOCOL_VERSION);
 
                /* don't bother reconnecting if its the wrong version. */
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
@@ -1302,33 +1321,33 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
         */
        if (be32_to_cpu(hand->o2net_idle_timeout_ms) !=
                                o2net_idle_timeout()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_idle_timeout_ms),
-                    o2net_idle_timeout());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network "
+                      "idle timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_idle_timeout_ms),
+                      o2net_idle_timeout());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2net_keepalive_delay_ms) !=
                        o2net_keepalive_delay()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_keepalive_delay_ms),
-                    o2net_keepalive_delay());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive "
+                      "delay of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_keepalive_delay_ms),
+                      o2net_keepalive_delay());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) !=
                        O2HB_MAX_WRITE_TIMEOUT_MS) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
-                    O2HB_MAX_WRITE_TIMEOUT_MS);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat "
+                      "timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
+                      O2HB_MAX_WRITE_TIMEOUT_MS);
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
@@ -1539,28 +1558,16 @@ static void o2net_idle_timer(unsigned long data)
 {
        struct o2net_sock_container *sc = (struct o2net_sock_container *)data;
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
-
 #ifdef CONFIG_DEBUG_FS
-       ktime_t now = ktime_get();
+       unsigned long msecs = ktime_to_ms(ktime_get()) -
+               ktime_to_ms(sc->sc_tv_timer);
+#else
+       unsigned long msecs = o2net_idle_timeout();
 #endif
 
-       printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
-            "seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
-                    o2net_idle_timeout() / 1000,
-                    o2net_idle_timeout() % 1000);
-
-#ifdef CONFIG_DEBUG_FS
-       mlog(ML_NOTICE, "Here are some times that might help debug the "
-            "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, "
-            "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n",
-            (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now),
-            (long long)ktime_to_us(sc->sc_tv_data_ready),
-            (long long)ktime_to_us(sc->sc_tv_advance_start),
-            (long long)ktime_to_us(sc->sc_tv_advance_stop),
-            sc->sc_msg_key, sc->sc_msg_type,
-            (long long)ktime_to_us(sc->sc_tv_func_start),
-            (long long)ktime_to_us(sc->sc_tv_func_stop));
-#endif
+       printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been "
+              "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc),
+              msecs / 1000, msecs % 1000);
 
        /*
         * Initialize the nn_timeout so that the next connection attempt
@@ -1693,8 +1700,8 @@ static void o2net_start_connect(struct work_struct *work)
 
 out:
        if (ret) {
-               mlog(ML_NOTICE, "connect attempt to " SC_NODEF_FMT " failed "
-                    "with errno %d\n", SC_NODEF_ARGS(sc), ret);
+               printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT
+                      " failed with errno %d\n", SC_NODEF_ARGS(sc), ret);
                /* 0 err so that another will be queued and attempted
                 * from set_nn_state */
                if (sc)
@@ -1717,8 +1724,8 @@ static void o2net_connect_expired(struct work_struct *work)
 
        spin_lock(&nn->nn_lock);
        if (!nn->nn_sc_valid) {
-               mlog(ML_ERROR, "no connection established with node %u after "
-                    "%u.%u seconds, giving up and returning errors.\n",
+               printk(KERN_NOTICE "o2net: No connection established with "
+                      "node %u after %u.%u seconds, giving up.\n",
                     o2net_num_from_nn(nn),
                     o2net_idle_timeout() / 1000,
                     o2net_idle_timeout() % 1000);
@@ -1861,21 +1868,21 @@ static int o2net_accept_one(struct socket *sock)
 
        node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
        if (node == NULL) {
-               mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n",
-                    &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
+                      "node at %pI4:%d\n", &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
 
        if (o2nm_this_node() >= node->nd_num) {
                local_node = o2nm_get_node_by_num(o2nm_this_node());
-               mlog(ML_NOTICE, "unexpected connect attempt seen at node '%s' ("
-                    "%u, %pI4:%d) from node '%s' (%u, %pI4:%d)\n",
-                    local_node->nd_name, local_node->nd_num,
-                    &(local_node->nd_ipv4_address),
-                    ntohs(local_node->nd_ipv4_port),
-                    node->nd_name, node->nd_num, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Unexpected connect attempt seen "
+                      "at node '%s' (%u, %pI4:%d) from node '%s' (%u, "
+                      "%pI4:%d)\n", local_node->nd_name, local_node->nd_num,
+                      &(local_node->nd_ipv4_address),
+                      ntohs(local_node->nd_ipv4_port), node->nd_name,
+                      node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
@@ -1900,10 +1907,10 @@ static int o2net_accept_one(struct socket *sock)
                ret = 0;
        spin_unlock(&nn->nn_lock);
        if (ret) {
-               mlog(ML_NOTICE, "attempt to connect from node '%s' at "
-                    "%pI4:%d but it already has an open connection\n",
-                    node->nd_name, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
+                      "at %pI4:%d but it already has an open connection\n",
+                      node->nd_name, &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                goto out;
        }
 
@@ -1983,7 +1990,7 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
 
        ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to create socket, ret=%d\n", ret);
+               printk(KERN_ERR "o2net: Error %d while creating socket\n", ret);
                goto out;
        }
 
@@ -2000,16 +2007,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
        sock->sk->sk_reuse = 1;
        ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to bind socket at %pI4:%u, "
-                    "ret=%d\n", &addr, ntohs(port), ret);
+               printk(KERN_ERR "o2net: Error %d while binding socket at "
+                      "%pI4:%u\n", ret, &addr, ntohs(port)); 
                goto out;
        }
 
        ret = sock->ops->listen(sock, 64);
-       if (ret < 0) {
-               mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n",
-                    &addr, ntohs(port), ret);
-       }
+       if (ret < 0)
+               printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n",
+                      ret, &addr, ntohs(port));
 
 out:
        if (ret) {
index fd6179eb26d4cd2cfb43f4ff053237837712113e..5bada2a69b503cd365d626a25e4ae6d08ad50b7a 100644 (file)
@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
                           struct list_head *unreg_list);
 void o2net_unregister_handler_list(struct list_head *list);
 
+void o2net_fill_node_map(unsigned long *map, unsigned bytes);
+
 struct o2nm_node;
 int o2net_register_hb_callbacks(void);
 void o2net_unregister_hb_callbacks(void);
index 8582e3f4f120647d05df81556639e627882b5811..3302088e1f046fc59dcf0573e2c177b39d9e6202 100644 (file)
@@ -1184,8 +1184,7 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
                        if (pde)
                                le16_add_cpu(&pde->rec_len,
                                                le16_to_cpu(de->rec_len));
-                       else
-                               de->inode = 0;
+                       de->inode = 0;
                        dir->i_version++;
                        ocfs2_journal_dirty(handle, bh);
                        goto bail;
index d602abb51b610d525cc437daa05c25d2105fe0c3..a5952ceecba5a83147389ad4a1cd24972ee0bfbe 100644 (file)
@@ -859,8 +859,8 @@ void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
 void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
 void dlm_kick_recovery_thread(struct dlm_ctxt *dlm);
 int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
 
 void dlm_put(struct dlm_ctxt *dlm);
 struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
@@ -877,9 +877,8 @@ static inline void dlm_lockres_get(struct dlm_lock_resource *res)
        kref_get(&res->refs);
 }
 void dlm_lockres_put(struct dlm_lock_resource *res);
-void __dlm_unhash_lockres(struct dlm_lock_resource *res);
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                         struct dlm_lock_resource *res);
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
                                                     const char *name,
                                                     unsigned int len,
@@ -902,46 +901,15 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
                                          const char *name,
                                          unsigned int namelen);
 
-#define dlm_lockres_set_refmap_bit(bit,res)  \
-       __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__)
-#define dlm_lockres_clear_refmap_bit(bit,res)  \
-       __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit);
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit);
 
-static inline void __dlm_lockres_set_refmap_bit(int bit,
-                                               struct dlm_lock_resource *res,
-                                               const char *file,
-                                               int line)
-{
-       //printk("%s:%d:%.*s: setting bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       set_bit(bit, res->refmap);
-}
-
-static inline void __dlm_lockres_clear_refmap_bit(int bit,
-                                                 struct dlm_lock_resource *res,
-                                                 const char *file,
-                                                 int line)
-{
-       //printk("%s:%d:%.*s: clearing bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       clear_bit(bit, res->refmap);
-}
-
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line);
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line);
-#define dlm_lockres_drop_inflight_ref(d,r)  \
-       __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref_new(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
 
 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
index 6ed6b95dcf935a6516e935b85a3ca9ffc0b8a9d8..92f2ead0fab6de22fa138cc4410dee6e1544216c 100644 (file)
@@ -157,16 +157,18 @@ static int dlm_protocol_compare(struct dlm_protocol_version *existing,
 
 static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm);
 
-void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
-       if (!hlist_unhashed(&lockres->hash_node)) {
-               hlist_del_init(&lockres->hash_node);
-               dlm_lockres_put(lockres);
-       }
+       if (hlist_unhashed(&res->hash_node))
+               return;
+
+       mlog(0, "%s: Unhash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
+       hlist_del_init(&res->hash_node);
+       dlm_lockres_put(res);
 }
 
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                      struct dlm_lock_resource *res)
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
        struct hlist_head *bucket;
        struct qstr *q;
@@ -180,6 +182,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
        dlm_lockres_get(res);
 
        hlist_add_head(&res->hash_node, bucket);
+
+       mlog(0, "%s: Hash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
 }
 
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
@@ -539,17 +544,17 @@ again:
 
 static void __dlm_print_nodes(struct dlm_ctxt *dlm)
 {
-       int node = -1;
+       int node = -1, num = 0;
 
        assert_spin_locked(&dlm->spinlock);
 
-       printk(KERN_NOTICE "o2dlm: Nodes in domain %s: ", dlm->name);
-
+       printk("( ");
        while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
                                     node + 1)) < O2NM_MAX_NODES) {
                printk("%d ", node);
+               ++num;
        }
-       printk("\n");
+       printk(") %u nodes\n", num);
 }
 
 static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
@@ -566,11 +571,10 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
 
        node = exit_msg->node_idx;
 
-       printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s\n", node, dlm->name);
-
        spin_lock(&dlm->spinlock);
        clear_bit(node, dlm->domain_map);
        clear_bit(node, dlm->exit_domain_map);
+       printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s ", node, dlm->name);
        __dlm_print_nodes(dlm);
 
        /* notify anything attached to the heartbeat events */
@@ -755,6 +759,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
 
                dlm_mark_domain_leaving(dlm);
                dlm_leave_domain(dlm);
+               printk(KERN_NOTICE "o2dlm: Leaving domain %s\n", dlm->name);
                dlm_force_free_mles(dlm);
                dlm_complete_dlm_shutdown(dlm);
        }
@@ -970,7 +975,7 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
                clear_bit(assert->node_idx, dlm->exit_domain_map);
                __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
 
-               printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n",
+               printk(KERN_NOTICE "o2dlm: Node %u joins domain %s ",
                       assert->node_idx, dlm->name);
                __dlm_print_nodes(dlm);
 
@@ -1701,8 +1706,10 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
 bail:
        spin_lock(&dlm->spinlock);
        __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
-       if (!status)
+       if (!status) {
+               printk(KERN_NOTICE "o2dlm: Joining domain %s ", dlm->name);
                __dlm_print_nodes(dlm);
+       }
        spin_unlock(&dlm->spinlock);
 
        if (ctxt) {
@@ -2131,13 +2138,6 @@ struct dlm_ctxt * dlm_register_domain(const char *domain,
                goto leave;
        }
 
-       if (!o2hb_check_local_node_heartbeating()) {
-               mlog(ML_ERROR, "the local node has not been configured, or is "
-                    "not heartbeating\n");
-               ret = -EPROTO;
-               goto leave;
-       }
-
        mlog(0, "register called for domain \"%s\"\n", domain);
 
 retry:
index 8d39e0fd66f7379b8fb08ac40502efa0d4a51cc6..975810b98492a34f4576b9d3d3ac3e4421fb18c1 100644 (file)
@@ -183,10 +183,6 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm,
                        kick_thread = 1;
                }
        }
-       /* reduce the inflight count, this may result in the lockres
-        * being purged below during calc_usage */
-       if (lock->ml.node == dlm->node_num)
-               dlm_lockres_drop_inflight_ref(dlm, res);
 
        spin_unlock(&res->spinlock);
        wake_up(&res->wq);
@@ -231,10 +227,16 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm,
             lock->ml.type, res->lockname.len,
             res->lockname.name, flags);
 
+       /*
+        * Wait if resource is getting recovered, remastered, etc.
+        * If the resource was remastered and new owner is self, then exit.
+        */
        spin_lock(&res->spinlock);
-
-       /* will exit this call with spinlock held */
        __dlm_wait_on_lockres(res);
+       if (res->owner == dlm->node_num) {
+               spin_unlock(&res->spinlock);
+               return DLM_RECOVERING;
+       }
        res->state |= DLM_LOCK_RES_IN_PROGRESS;
 
        /* add lock to local (secondary) queue */
@@ -319,27 +321,23 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm,
        tmpret = o2net_send_message(DLM_CREATE_LOCK_MSG, dlm->key, &create,
                                    sizeof(create), res->owner, &status);
        if (tmpret >= 0) {
-               // successfully sent and received
-               ret = status;  // this is already a dlm_status
+               ret = status;
                if (ret == DLM_REJECTED) {
-                       mlog(ML_ERROR, "%s:%.*s: BUG.  this is a stale lockres "
-                            "no longer owned by %u.  that node is coming back "
-                            "up currently.\n", dlm->name, create.namelen,
+                       mlog(ML_ERROR, "%s: res %.*s, Stale lockres no longer "
+                            "owned by node %u. That node is coming back up "
+                            "currently.\n", dlm->name, create.namelen,
                             create.name, res->owner);
                        dlm_print_one_lock_resource(res);
                        BUG();
                }
        } else {
-               mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
-                    "node %u\n", tmpret, DLM_CREATE_LOCK_MSG, dlm->key,
-                    res->owner);
-               if (dlm_is_host_down(tmpret)) {
+               mlog(ML_ERROR, "%s: res %.*s, Error %d send CREATE LOCK to "
+                    "node %u\n", dlm->name, create.namelen, create.name,
+                    tmpret, res->owner);
+               if (dlm_is_host_down(tmpret))
                        ret = DLM_RECOVERING;
-                       mlog(0, "node %u died so returning DLM_RECOVERING "
-                            "from lock message!\n", res->owner);
-               } else {
+               else
                        ret = dlm_err_to_dlm_status(tmpret);
-               }
        }
 
        return ret;
@@ -440,7 +438,7 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
                /* zero memory only if kernel-allocated */
                lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
                if (!lksb) {
-                       kfree(lock);
+                       kmem_cache_free(dlm_lock_cache, lock);
                        return NULL;
                }
                kernel_allocated = 1;
@@ -718,18 +716,10 @@ retry_lock:
 
                if (status == DLM_RECOVERING || status == DLM_MIGRATING ||
                    status == DLM_FORWARD) {
-                       mlog(0, "retrying lock with migration/"
-                            "recovery/in progress\n");
                        msleep(100);
-                       /* no waiting for dlm_reco_thread */
                        if (recovery) {
                                if (status != DLM_RECOVERING)
                                        goto retry_lock;
-
-                               mlog(0, "%s: got RECOVERING "
-                                    "for $RECOVERY lock, master "
-                                    "was %u\n", dlm->name,
-                                    res->owner);
                                /* wait to see the node go down, then
                                 * drop down and allow the lockres to
                                 * get cleaned up.  need to remaster. */
@@ -741,6 +731,14 @@ retry_lock:
                        }
                }
 
+               /* Inflight taken in dlm_get_lock_resource() is dropped here */
+               spin_lock(&res->spinlock);
+               dlm_lockres_drop_inflight_ref(dlm, res);
+               spin_unlock(&res->spinlock);
+
+               dlm_lockres_calc_usage(dlm, res);
+               dlm_kick_thread(dlm, res);
+
                if (status != DLM_NORMAL) {
                        lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
                        if (status != DLM_NOTQUEUED)
index 11eefb8c12e98fb418f41c31a3b0a32201be3ca1..005261c333b090f5f53f376bd5bbed55b8e16ba7 100644 (file)
@@ -631,39 +631,54 @@ error:
        return NULL;
 }
 
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit)
 {
-       if (!new_lockres)
-               assert_spin_locked(&res->spinlock);
+       assert_spin_locked(&res->spinlock);
+
+       mlog(0, "res %.*s, set node %u, %ps()\n", res->lockname.len,
+            res->lockname.name, bit, __builtin_return_address(0));
+
+       set_bit(bit, res->refmap);
+}
+
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit)
+{
+       assert_spin_locked(&res->spinlock);
+
+       mlog(0, "res %.*s, clr node %u, %ps()\n", res->lockname.len,
+            res->lockname.name, bit, __builtin_return_address(0));
+
+       clear_bit(bit, res->refmap);
+}
+
+
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res)
+{
+       assert_spin_locked(&res->spinlock);
 
-       if (!test_bit(dlm->node_num, res->refmap)) {
-               BUG_ON(res->inflight_locks != 0);
-               dlm_lockres_set_refmap_bit(dlm->node_num, res);
-       }
        res->inflight_locks++;
-       mlog(0, "%s:%.*s: inflight++: now %u\n",
-            dlm->name, res->lockname.len, res->lockname.name,
-            res->inflight_locks);
+
+       mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
+            res->lockname.len, res->lockname.name, res->inflight_locks,
+            __builtin_return_address(0));
 }
 
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res)
 {
        assert_spin_locked(&res->spinlock);
 
        BUG_ON(res->inflight_locks == 0);
+
        res->inflight_locks--;
-       mlog(0, "%s:%.*s: inflight--: now %u\n",
-            dlm->name, res->lockname.len, res->lockname.name,
-            res->inflight_locks);
-       if (res->inflight_locks == 0)
-               dlm_lockres_clear_refmap_bit(dlm->node_num, res);
+
+       mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name,
+            res->lockname.len, res->lockname.name, res->inflight_locks,
+            __builtin_return_address(0));
+
        wake_up(&res->wq);
 }
 
@@ -697,7 +712,6 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
        unsigned int hash;
        int tries = 0;
        int bit, wait_on_recovery = 0;
-       int drop_inflight_if_nonlocal = 0;
 
        BUG_ON(!lockid);
 
@@ -709,36 +723,33 @@ lookup:
        spin_lock(&dlm->spinlock);
        tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash);
        if (tmpres) {
-               int dropping_ref = 0;
-
                spin_unlock(&dlm->spinlock);
-
                spin_lock(&tmpres->spinlock);
-               /* We wait for the other thread that is mastering the resource */
+               /* Wait on the thread that is mastering the resource */
                if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
                        __dlm_wait_on_lockres(tmpres);
                        BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN);
+                       spin_unlock(&tmpres->spinlock);
+                       dlm_lockres_put(tmpres);
+                       tmpres = NULL;
+                       goto lookup;
                }
 
-               if (tmpres->owner == dlm->node_num) {
-                       BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF);
-                       dlm_lockres_grab_inflight_ref(dlm, tmpres);
-               } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF)
-                       dropping_ref = 1;
-               spin_unlock(&tmpres->spinlock);
-
-               /* wait until done messaging the master, drop our ref to allow
-                * the lockres to be purged, start over. */
-               if (dropping_ref) {
-                       spin_lock(&tmpres->spinlock);
-                       __dlm_wait_on_lockres_flags(tmpres, DLM_LOCK_RES_DROPPING_REF);
+               /* Wait on the resource purge to complete before continuing */
+               if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) {
+                       BUG_ON(tmpres->owner == dlm->node_num);
+                       __dlm_wait_on_lockres_flags(tmpres,
+                                                   DLM_LOCK_RES_DROPPING_REF);
                        spin_unlock(&tmpres->spinlock);
                        dlm_lockres_put(tmpres);
                        tmpres = NULL;
                        goto lookup;
                }
 
-               mlog(0, "found in hash!\n");
+               /* Grab inflight ref to pin the resource */
+               dlm_lockres_grab_inflight_ref(dlm, tmpres);
+
+               spin_unlock(&tmpres->spinlock);
                if (res)
                        dlm_lockres_put(res);
                res = tmpres;
@@ -829,8 +840,8 @@ lookup:
                 * but they might own this lockres.  wait on them. */
                bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
                if (bit < O2NM_MAX_NODES) {
-                       mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
-                            "recover before lock mastery can begin\n",
+                       mlog(0, "%s: res %.*s, At least one node (%d) "
+                            "to recover before lock mastery can begin\n",
                             dlm->name, namelen, (char *)lockid, bit);
                        wait_on_recovery = 1;
                }
@@ -843,12 +854,11 @@ lookup:
 
        /* finally add the lockres to its hash bucket */
        __dlm_insert_lockres(dlm, res);
-       /* since this lockres is new it doesn't not require the spinlock */
-       dlm_lockres_grab_inflight_ref_new(dlm, res);
 
-       /* if this node does not become the master make sure to drop
-        * this inflight reference below */
-       drop_inflight_if_nonlocal = 1;
+       /* Grab inflight ref to pin the resource */
+       spin_lock(&res->spinlock);
+       dlm_lockres_grab_inflight_ref(dlm, res);
+       spin_unlock(&res->spinlock);
 
        /* get an extra ref on the mle in case this is a BLOCK
         * if so, the creator of the BLOCK may try to put the last
@@ -864,8 +874,8 @@ redo_request:
                 * dlm spinlock would be detectable be a change on the mle,
                 * so we only need to clear out the recovery map once. */
                if (dlm_is_recovery_lock(lockid, namelen)) {
-                       mlog(ML_NOTICE, "%s: recovery map is not empty, but "
-                            "must master $RECOVERY lock now\n", dlm->name);
+                       mlog(0, "%s: Recovery map is not empty, but must "
+                            "master $RECOVERY lock now\n", dlm->name);
                        if (!dlm_pre_master_reco_lockres(dlm, res))
                                wait_on_recovery = 0;
                        else {
@@ -883,8 +893,8 @@ redo_request:
                spin_lock(&dlm->spinlock);
                bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
                if (bit < O2NM_MAX_NODES) {
-                       mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
-                            "recover before lock mastery can begin\n",
+                       mlog(0, "%s: res %.*s, At least one node (%d) "
+                            "to recover before lock mastery can begin\n",
                             dlm->name, namelen, (char *)lockid, bit);
                        wait_on_recovery = 1;
                } else
@@ -913,8 +923,8 @@ redo_request:
                         * yet, keep going until it does.  this is how the
                         * master will know that asserts are needed back to
                         * the lower nodes. */
-                       mlog(0, "%s:%.*s: requests only up to %u but master "
-                            "is %u, keep going\n", dlm->name, namelen,
+                       mlog(0, "%s: res %.*s, Requests only up to %u but "
+                            "master is %u, keep going\n", dlm->name, namelen,
                             lockid, nodenum, mle->master);
                }
        }
@@ -924,13 +934,12 @@ wait:
        ret = dlm_wait_for_lock_mastery(dlm, res, mle, &blocked);
        if (ret < 0) {
                wait_on_recovery = 1;
-               mlog(0, "%s:%.*s: node map changed, redo the "
-                    "master request now, blocked=%d\n",
-                    dlm->name, res->lockname.len,
+               mlog(0, "%s: res %.*s, Node map changed, redo the master "
+                    "request now, blocked=%d\n", dlm->name, res->lockname.len,
                     res->lockname.name, blocked);
                if (++tries > 20) {
-                       mlog(ML_ERROR, "%s:%.*s: spinning on "
-                            "dlm_wait_for_lock_mastery, blocked=%d\n",
+                       mlog(ML_ERROR, "%s: res %.*s, Spinning on "
+                            "dlm_wait_for_lock_mastery, blocked = %d\n",
                             dlm->name, res->lockname.len,
                             res->lockname.name, blocked);
                        dlm_print_one_lock_resource(res);
@@ -940,7 +949,8 @@ wait:
                goto redo_request;
        }
 
-       mlog(0, "lockres mastered by %u\n", res->owner);
+       mlog(0, "%s: res %.*s, Mastered by %u\n", dlm->name, res->lockname.len,
+            res->lockname.name, res->owner);
        /* make sure we never continue without this */
        BUG_ON(res->owner == O2NM_MAX_NODES);
 
@@ -952,8 +962,6 @@ wait:
 
 wake_waiters:
        spin_lock(&res->spinlock);
-       if (res->owner != dlm->node_num && drop_inflight_if_nonlocal)
-               dlm_lockres_drop_inflight_ref(dlm, res);
        res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
        spin_unlock(&res->spinlock);
        wake_up(&res->wq);
@@ -1426,9 +1434,7 @@ way_up_top:
                }
 
                if (res->owner == dlm->node_num) {
-                       mlog(0, "%s:%.*s: setting bit %u in refmap\n",
-                            dlm->name, namelen, name, request->node_idx);
-                       dlm_lockres_set_refmap_bit(request->node_idx, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, request->node_idx);
                        spin_unlock(&res->spinlock);
                        response = DLM_MASTER_RESP_YES;
                        if (mle)
@@ -1493,10 +1499,8 @@ way_up_top:
                                 * go back and clean the mles on any
                                 * other nodes */
                                dispatch_assert = 1;
-                               dlm_lockres_set_refmap_bit(request->node_idx, res);
-                               mlog(0, "%s:%.*s: setting bit %u in refmap\n",
-                                    dlm->name, namelen, name,
-                                    request->node_idx);
+                               dlm_lockres_set_refmap_bit(dlm, res,
+                                                          request->node_idx);
                        } else
                                response = DLM_MASTER_RESP_NO;
                } else {
@@ -1702,7 +1706,7 @@ again:
                             "lockres, set the bit in the refmap\n",
                             namelen, lockname, to);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(to, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, to);
                        spin_unlock(&res->spinlock);
                }
        }
@@ -2187,8 +2191,6 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        namelen = res->lockname.len;
        BUG_ON(namelen > O2NM_MAX_NAME_LEN);
 
-       mlog(0, "%s:%.*s: sending deref to %d\n",
-            dlm->name, namelen, lockname, res->owner);
        memset(&deref, 0, sizeof(deref));
        deref.node_idx = dlm->node_num;
        deref.namelen = namelen;
@@ -2197,14 +2199,12 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        ret = o2net_send_message(DLM_DEREF_LOCKRES_MSG, dlm->key,
                                 &deref, sizeof(deref), res->owner, &r);
        if (ret < 0)
-               mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
-                    "node %u\n", ret, DLM_DEREF_LOCKRES_MSG, dlm->key,
-                    res->owner);
+               mlog(ML_ERROR, "%s: res %.*s, error %d send DEREF to node %u\n",
+                    dlm->name, namelen, lockname, ret, res->owner);
        else if (r < 0) {
                /* BAD.  other node says I did not have a ref. */
-               mlog(ML_ERROR,"while dropping ref on %s:%.*s "
-                   "(master=%u) got %d.\n", dlm->name, namelen,
-                   lockname, res->owner, r);
+               mlog(ML_ERROR, "%s: res %.*s, DEREF to node %u got %d\n",
+                    dlm->name, namelen, lockname, res->owner, r);
                dlm_print_one_lock_resource(res);
                BUG();
        }
@@ -2260,7 +2260,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
        else {
                BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF);
                if (test_bit(node, res->refmap)) {
-                       dlm_lockres_clear_refmap_bit(node, res);
+                       dlm_lockres_clear_refmap_bit(dlm, res, node);
                        cleared = 1;
                }
        }
@@ -2320,7 +2320,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
        BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF);
        if (test_bit(node, res->refmap)) {
                __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
-               dlm_lockres_clear_refmap_bit(node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, node);
                cleared = 1;
        }
        spin_unlock(&res->spinlock);
@@ -2802,7 +2802,8 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
                                BUG_ON(!list_empty(&lock->bast_list));
                                BUG_ON(lock->ast_pending);
                                BUG_ON(lock->bast_pending);
-                               dlm_lockres_clear_refmap_bit(lock->ml.node, res);
+                               dlm_lockres_clear_refmap_bit(dlm, res,
+                                                            lock->ml.node);
                                list_del_init(&lock->list);
                                dlm_lock_put(lock);
                                /* In a normal unlock, we would have added a
@@ -2823,7 +2824,7 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
                        mlog(0, "%s:%.*s: node %u had a ref to this "
                             "migrating lockres, clearing\n", dlm->name,
                             res->lockname.len, res->lockname.name, bit);
-                       dlm_lockres_clear_refmap_bit(bit, res);
+                       dlm_lockres_clear_refmap_bit(dlm, res, bit);
                }
                bit++;
        }
@@ -2916,9 +2917,9 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
                                         &migrate, sizeof(migrate), nodenum,
                                         &status);
                if (ret < 0) {
-                       mlog(ML_ERROR, "Error %d when sending message %u (key "
-                            "0x%x) to node %u\n", ret, DLM_MIGRATE_REQUEST_MSG,
-                            dlm->key, nodenum);
+                       mlog(ML_ERROR, "%s: res %.*s, Error %d send "
+                            "MIGRATE_REQUEST to node %u\n", dlm->name,
+                            migrate.namelen, migrate.name, ret, nodenum);
                        if (!dlm_is_host_down(ret)) {
                                mlog(ML_ERROR, "unhandled error=%d!\n", ret);
                                BUG();
@@ -2937,7 +2938,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
                             dlm->name, res->lockname.len, res->lockname.name,
                             nodenum);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(nodenum, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, nodenum);
                        spin_unlock(&res->spinlock);
                }
        }
@@ -3271,7 +3272,7 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
         * mastery reference here since old_master will briefly have
         * a reference after the migration completes */
        spin_lock(&res->spinlock);
-       dlm_lockres_set_refmap_bit(old_master, res);
+       dlm_lockres_set_refmap_bit(dlm, res, old_master);
        spin_unlock(&res->spinlock);
 
        mlog(0, "now time to do a migrate request to other nodes\n");
index 7efab6d28a21b4ee6a8376559d70f739a4e1da90..01ebfd0bdad72264b99345378f0c6febe246503d 100644 (file)
@@ -362,40 +362,38 @@ static int dlm_is_node_recovered(struct dlm_ctxt *dlm, u8 node)
 }
 
 
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)
 {
-       if (timeout) {
-               mlog(ML_NOTICE, "%s: waiting %dms for notification of "
-                    "death of node %u\n", dlm->name, timeout, node);
+       if (dlm_is_node_dead(dlm, node))
+               return;
+
+       printk(KERN_NOTICE "o2dlm: Waiting on the death of node %u in "
+              "domain %s\n", node, dlm->name);
+
+       if (timeout)
                wait_event_timeout(dlm->dlm_reco_thread_wq,
-                          dlm_is_node_dead(dlm, node),
-                          msecs_to_jiffies(timeout));
-       } else {
-               mlog(ML_NOTICE, "%s: waiting indefinitely for notification "
-                    "of death of node %u\n", dlm->name, node);
+                                  dlm_is_node_dead(dlm, node),
+                                  msecs_to_jiffies(timeout));
+       else
                wait_event(dlm->dlm_reco_thread_wq,
                           dlm_is_node_dead(dlm, node));
-       }
-       /* for now, return 0 */
-       return 0;
 }
 
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout)
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout)
 {
-       if (timeout) {
-               mlog(0, "%s: waiting %dms for notification of "
-                    "recovery of node %u\n", dlm->name, timeout, node);
+       if (dlm_is_node_recovered(dlm, node))
+               return;
+
+       printk(KERN_NOTICE "o2dlm: Waiting on the recovery of node %u in "
+              "domain %s\n", node, dlm->name);
+
+       if (timeout)
                wait_event_timeout(dlm->dlm_reco_thread_wq,
-                          dlm_is_node_recovered(dlm, node),
-                          msecs_to_jiffies(timeout));
-       } else {
-               mlog(0, "%s: waiting indefinitely for notification "
-                    "of recovery of node %u\n", dlm->name, node);
+                                  dlm_is_node_recovered(dlm, node),
+                                  msecs_to_jiffies(timeout));
+       else
                wait_event(dlm->dlm_reco_thread_wq,
                           dlm_is_node_recovered(dlm, node));
-       }
-       /* for now, return 0 */
-       return 0;
 }
 
 /* callers of the top-level api calls (dlmlock/dlmunlock) should
@@ -430,6 +428,8 @@ static void dlm_begin_recovery(struct dlm_ctxt *dlm)
 {
        spin_lock(&dlm->spinlock);
        BUG_ON(dlm->reco.state & DLM_RECO_STATE_ACTIVE);
+       printk(KERN_NOTICE "o2dlm: Begin recovery on domain %s for node %u\n",
+              dlm->name, dlm->reco.dead_node);
        dlm->reco.state |= DLM_RECO_STATE_ACTIVE;
        spin_unlock(&dlm->spinlock);
 }
@@ -440,9 +440,18 @@ static void dlm_end_recovery(struct dlm_ctxt *dlm)
        BUG_ON(!(dlm->reco.state & DLM_RECO_STATE_ACTIVE));
        dlm->reco.state &= ~DLM_RECO_STATE_ACTIVE;
        spin_unlock(&dlm->spinlock);
+       printk(KERN_NOTICE "o2dlm: End recovery on domain %s\n", dlm->name);
        wake_up(&dlm->reco.event);
 }
 
+static void dlm_print_recovery_master(struct dlm_ctxt *dlm)
+{
+       printk(KERN_NOTICE "o2dlm: Node %u (%s) is the Recovery Master for the "
+              "dead node %u in domain %s\n", dlm->reco.new_master,
+              (dlm->node_num == dlm->reco.new_master ? "me" : "he"),
+              dlm->reco.dead_node, dlm->name);
+}
+
 static int dlm_do_recovery(struct dlm_ctxt *dlm)
 {
        int status = 0;
@@ -505,9 +514,8 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
                }
                mlog(0, "another node will master this recovery session.\n");
        }
-       mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n",
-            dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master,
-            dlm->node_num, dlm->reco.dead_node);
+
+       dlm_print_recovery_master(dlm);
 
        /* it is safe to start everything back up here
         * because all of the dead node's lock resources
@@ -518,15 +526,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
        return 0;
 
 master_here:
-       mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node "
-            "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task),
-            dlm->node_num, dlm->reco.dead_node, dlm->name);
+       dlm_print_recovery_master(dlm);
 
        status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
        if (status < 0) {
                /* we should never hit this anymore */
-               mlog(ML_ERROR, "error %d remastering locks for node %u, "
-                    "retrying.\n", status, dlm->reco.dead_node);
+               mlog(ML_ERROR, "%s: Error %d remastering locks for node %u, "
+                    "retrying.\n", dlm->name, status, dlm->reco.dead_node);
                /* yield a bit to allow any final network messages
                 * to get handled on remaining nodes */
                msleep(100);
@@ -567,7 +573,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                BUG_ON(ndata->state != DLM_RECO_NODE_DATA_INIT);
                ndata->state = DLM_RECO_NODE_DATA_REQUESTING;
 
-               mlog(0, "requesting lock info from node %u\n",
+               mlog(0, "%s: Requesting lock info from node %u\n", dlm->name,
                     ndata->node_num);
 
                if (ndata->node_num == dlm->node_num) {
@@ -640,7 +646,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                spin_unlock(&dlm_reco_state_lock);
        }
 
-       mlog(0, "done requesting all lock info\n");
+       mlog(0, "%s: Done requesting all lock info\n", dlm->name);
 
        /* nodes should be sending reco data now
         * just need to wait */
@@ -802,10 +808,9 @@ static int dlm_request_all_locks(struct dlm_ctxt *dlm, u8 request_from,
 
        /* negative status is handled by caller */
        if (ret < 0)
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_LOCK_REQUEST_MSG,
-                    dlm->key, request_from);
-
+               mlog(ML_ERROR, "%s: Error %d send LOCK_REQUEST to node %u "
+                    "to recover dead node %u\n", dlm->name, ret,
+                    request_from, dead_node);
        // return from here, then
        // sleep until all received or error
        return ret;
@@ -956,9 +961,9 @@ static int dlm_send_all_done_msg(struct dlm_ctxt *dlm, u8 dead_node, u8 send_to)
        ret = o2net_send_message(DLM_RECO_DATA_DONE_MSG, dlm->key, &done_msg,
                                 sizeof(done_msg), send_to, &tmpret);
        if (ret < 0) {
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_RECO_DATA_DONE_MSG,
-                    dlm->key, send_to);
+               mlog(ML_ERROR, "%s: Error %d send RECO_DATA_DONE to node %u "
+                    "to recover dead node %u\n", dlm->name, ret, send_to,
+                    dead_node);
                if (!dlm_is_host_down(ret)) {
                        BUG();
                }
@@ -1127,9 +1132,11 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
        if (ret < 0) {
                /* XXX: negative status is not handled.
                 * this will end up killing this node. */
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_MIG_LOCKRES_MSG,
-                    dlm->key, send_to);
+               mlog(ML_ERROR, "%s: res %.*s, Error %d send MIG_LOCKRES to "
+                    "node %u (%s)\n", dlm->name, mres->lockname_len,
+                    mres->lockname, ret, send_to,
+                    (orig_flags & DLM_MRES_MIGRATION ?
+                     "migration" : "recovery"));
        } else {
                /* might get an -ENOMEM back here */
                ret = status;
@@ -1767,7 +1774,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
                             dlm->name, mres->lockname_len, mres->lockname,
                             from);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(from, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, from);
                        spin_unlock(&res->spinlock);
                        added++;
                        break;
@@ -1965,7 +1972,7 @@ skip_lvb:
                        mlog(0, "%s:%.*s: added lock for node %u, "
                             "setting refmap bit\n", dlm->name,
                             res->lockname.len, res->lockname.name, ml->node);
-                       dlm_lockres_set_refmap_bit(ml->node, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, ml->node);
                        added++;
                }
                spin_unlock(&res->spinlock);
@@ -2084,6 +2091,9 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
 
        list_for_each_entry_safe(res, next, &dlm->reco.resources, recovering) {
                if (res->owner == dead_node) {
+                       mlog(0, "%s: res %.*s, Changing owner from %u to %u\n",
+                            dlm->name, res->lockname.len, res->lockname.name,
+                            res->owner, new_master);
                        list_del_init(&res->recovering);
                        spin_lock(&res->spinlock);
                        /* new_master has our reference from
@@ -2105,40 +2115,30 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
        for (i = 0; i < DLM_HASH_BUCKETS; i++) {
                bucket = dlm_lockres_hash(dlm, i);
                hlist_for_each_entry(res, hash_iter, bucket, hash_node) {
-                       if (res->state & DLM_LOCK_RES_RECOVERING) {
-                               if (res->owner == dead_node) {
-                                       mlog(0, "(this=%u) res %.*s owner=%u "
-                                            "was not on recovering list, but "
-                                            "clearing state anyway\n",
-                                            dlm->node_num, res->lockname.len,
-                                            res->lockname.name, new_master);
-                               } else if (res->owner == dlm->node_num) {
-                                       mlog(0, "(this=%u) res %.*s owner=%u "
-                                            "was not on recovering list, "
-                                            "owner is THIS node, clearing\n",
-                                            dlm->node_num, res->lockname.len,
-                                            res->lockname.name, new_master);
-                               } else
-                                       continue;
+                       if (!(res->state & DLM_LOCK_RES_RECOVERING))
+                               continue;
 
-                               if (!list_empty(&res->recovering)) {
-                                       mlog(0, "%s:%.*s: lockres was "
-                                            "marked RECOVERING, owner=%u\n",
-                                            dlm->name, res->lockname.len,
-                                            res->lockname.name, res->owner);
-                                       list_del_init(&res->recovering);
-                                       dlm_lockres_put(res);
-                               }
-                               spin_lock(&res->spinlock);
-                               /* new_master has our reference from
-                                * the lock state sent during recovery */
-                               dlm_change_lockres_owner(dlm, res, new_master);
-                               res->state &= ~DLM_LOCK_RES_RECOVERING;
-                               if (__dlm_lockres_has_locks(res))
-                                       __dlm_dirty_lockres(dlm, res);
-                               spin_unlock(&res->spinlock);
-                               wake_up(&res->wq);
+                       if (res->owner != dead_node &&
+                           res->owner != dlm->node_num)
+                               continue;
+
+                       if (!list_empty(&res->recovering)) {
+                               list_del_init(&res->recovering);
+                               dlm_lockres_put(res);
                        }
+
+                       /* new_master has our reference from
+                        * the lock state sent during recovery */
+                       mlog(0, "%s: res %.*s, Changing owner from %u to %u\n",
+                            dlm->name, res->lockname.len, res->lockname.name,
+                            res->owner, new_master);
+                       spin_lock(&res->spinlock);
+                       dlm_change_lockres_owner(dlm, res, new_master);
+                       res->state &= ~DLM_LOCK_RES_RECOVERING;
+                       if (__dlm_lockres_has_locks(res))
+                               __dlm_dirty_lockres(dlm, res);
+                       spin_unlock(&res->spinlock);
+                       wake_up(&res->wq);
                }
        }
 }
@@ -2252,12 +2252,12 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm,
                             res->lockname.len, res->lockname.name, freed, dead_node);
                        __dlm_print_one_lock_resource(res);
                }
-               dlm_lockres_clear_refmap_bit(dead_node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, dead_node);
        } else if (test_bit(dead_node, res->refmap)) {
                mlog(0, "%s:%.*s: dead node %u had a ref, but had "
                     "no locks and had not purged before dying\n", dlm->name,
                     res->lockname.len, res->lockname.name, dead_node);
-               dlm_lockres_clear_refmap_bit(dead_node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, dead_node);
        }
 
        /* do not kick thread yet */
@@ -2324,9 +2324,9 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
                        dlm_revalidate_lvb(dlm, res, dead_node);
                        if (res->owner == dead_node) {
                                if (res->state & DLM_LOCK_RES_DROPPING_REF) {
-                                       mlog(ML_NOTICE, "Ignore %.*s for "
+                                       mlog(ML_NOTICE, "%s: res %.*s, Skip "
                                             "recovery as it is being freed\n",
-                                            res->lockname.len,
+                                            dlm->name, res->lockname.len,
                                             res->lockname.name);
                                } else
                                        dlm_move_lockres_to_recovery_list(dlm,
index 1d6d1d22c4715e3c89bef69570916cc5bf44c259..e73c833fc2a1a97cac35903f0439115cef813c69 100644 (file)
@@ -94,24 +94,26 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res)
 {
        int bit;
 
+       assert_spin_locked(&res->spinlock);
+
        if (__dlm_lockres_has_locks(res))
                return 0;
 
+       /* Locks are in the process of being created */
+       if (res->inflight_locks)
+               return 0;
+
        if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY)
                return 0;
 
        if (res->state & DLM_LOCK_RES_RECOVERING)
                return 0;
 
+       /* Another node has this resource with this node as the master */
        bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
        if (bit < O2NM_MAX_NODES)
                return 0;
 
-       /*
-        * since the bit for dlm->node_num is not set, inflight_locks better
-        * be zero
-        */
-       BUG_ON(res->inflight_locks != 0);
        return 1;
 }
 
@@ -185,8 +187,6 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
                /* clear our bit from the master's refmap, ignore errors */
                ret = dlm_drop_lockres_ref(dlm, res);
                if (ret < 0) {
-                       mlog(ML_ERROR, "%s: deref %.*s failed %d\n", dlm->name,
-                            res->lockname.len, res->lockname.name, ret);
                        if (!dlm_is_host_down(ret))
                                BUG();
                }
@@ -209,7 +209,7 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
                BUG();
        }
 
-       __dlm_unhash_lockres(res);
+       __dlm_unhash_lockres(dlm, res);
 
        /* lockres is not in the hash now.  drop the flag and wake up
         * any processes waiting in dlm_get_lock_resource. */
index 7642d7ca73e523f3bc29b7b8a5d767e8f7c7cb83..da103f555a621e82f178ec6ae47dbb074f727d60 100644 (file)
@@ -1692,7 +1692,7 @@ int ocfs2_open_lock(struct inode *inode)
        mlog(0, "inode %llu take PRMODE open lock\n",
             (unsigned long long)OCFS2_I(inode)->ip_blkno);
 
-       if (ocfs2_mount_local(osb))
+       if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
                goto out;
 
        lockres = &OCFS2_I(inode)->ip_open_lockres;
@@ -1718,6 +1718,12 @@ int ocfs2_try_open_lock(struct inode *inode, int write)
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             write ? "EXMODE" : "PRMODE");
 
+       if (ocfs2_is_hard_readonly(osb)) {
+               if (write)
+                       status = -EROFS;
+               goto out;
+       }
+
        if (ocfs2_mount_local(osb))
                goto out;
 
@@ -2298,7 +2304,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
        if (ocfs2_is_hard_readonly(osb)) {
                if (ex)
                        status = -EROFS;
-               goto bail;
+               goto getbh;
        }
 
        if (ocfs2_mount_local(osb))
@@ -2356,7 +2362,7 @@ local:
                        mlog_errno(status);
                goto bail;
        }
-
+getbh:
        if (ret_bh) {
                status = ocfs2_assign_bh(inode, ret_bh, local_bh);
                if (status < 0) {
@@ -2628,8 +2634,11 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex)
 
        BUG_ON(!dl);
 
-       if (ocfs2_is_hard_readonly(osb))
-               return -EROFS;
+       if (ocfs2_is_hard_readonly(osb)) {
+               if (ex)
+                       return -EROFS;
+               return 0;
+       }
 
        if (ocfs2_mount_local(osb))
                return 0;
@@ -2647,7 +2656,7 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex)
        struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
        struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
 
-       if (!ocfs2_mount_local(osb))
+       if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb))
                ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
 }
 
index 23457b491e8ce53ac5b71d9cd5fc2a5e1400a07f..2f5b92ef0e533146007b49d21dd705a242125dc5 100644 (file)
@@ -832,6 +832,102 @@ out:
        return ret;
 }
 
+int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret;
+       unsigned int is_last = 0, is_data = 0;
+       u16 cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+       u32 cpos, cend, clen, hole_size;
+       u64 extoff, extlen;
+       struct buffer_head *di_bh = NULL;
+       struct ocfs2_extent_rec rec;
+
+       BUG_ON(origin != SEEK_DATA && origin != SEEK_HOLE);
+
+       ret = ocfs2_inode_lock(inode, &di_bh, 0);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       if (*offset >= inode->i_size) {
+               ret = -ENXIO;
+               goto out_unlock;
+       }
+
+       if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+               if (origin == SEEK_HOLE)
+                       *offset = inode->i_size;
+               goto out_unlock;
+       }
+
+       clen = 0;
+       cpos = *offset >> cs_bits;
+       cend = ocfs2_clusters_for_bytes(inode->i_sb, inode->i_size);
+
+       while (cpos < cend && !is_last) {
+               ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos, &hole_size,
+                                                &rec, &is_last);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out_unlock;
+               }
+
+               extoff = cpos;
+               extoff <<= cs_bits;
+
+               if (rec.e_blkno == 0ULL) {
+                       clen = hole_size;
+                       is_data = 0;
+               } else {
+                       clen = le16_to_cpu(rec.e_leaf_clusters) -
+                               (cpos - le32_to_cpu(rec.e_cpos));
+                       is_data = (rec.e_flags & OCFS2_EXT_UNWRITTEN) ?  0 : 1;
+               }
+
+               if ((!is_data && origin == SEEK_HOLE) ||
+                   (is_data && origin == SEEK_DATA)) {
+                       if (extoff > *offset)
+                               *offset = extoff;
+                       goto out_unlock;
+               }
+
+               if (!is_last)
+                       cpos += clen;
+       }
+
+       if (origin == SEEK_HOLE) {
+               extoff = cpos;
+               extoff <<= cs_bits;
+               extlen = clen;
+               extlen <<=  cs_bits;
+
+               if ((extoff + extlen) > inode->i_size)
+                       extlen = inode->i_size - extoff;
+               extoff += extlen;
+               if (extoff > *offset)
+                       *offset = extoff;
+               goto out_unlock;
+       }
+
+       ret = -ENXIO;
+
+out_unlock:
+
+       brelse(di_bh);
+
+       up_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       ocfs2_inode_unlock(inode, 0);
+out:
+       if (ret && ret != -ENXIO)
+               ret = -ENXIO;
+       return ret;
+}
+
 int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
                           struct buffer_head *bhs[], int flags,
                           int (*validate)(struct super_block *sb,
index e79d41c2c90972fe801a99ec040b229a92debe98..67ea57d2fd594da7e456c1103bb1652fa68b5f69 100644 (file)
@@ -53,6 +53,8 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
 int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                 u64 map_start, u64 map_len);
 
+int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin);
+
 int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster,
                             u32 *p_cluster, u32 *num_clusters,
                             struct ocfs2_extent_list *el,
index de4ea1af041b654f8f1b4f1a000f6492226f701f..af3ae69b2ba3f020d29791a255e8105894df6160 100644 (file)
@@ -2052,6 +2052,23 @@ out:
        return ret;
 }
 
+static void ocfs2_aiodio_wait(struct inode *inode)
+{
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
+
+       wait_event(*wq, (atomic_read(&OCFS2_I(inode)->ip_unaligned_aio) == 0));
+}
+
+static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos)
+{
+       int blockmask = inode->i_sb->s_blocksize - 1;
+       loff_t final_size = pos + count;
+
+       if ((pos & blockmask) || (final_size & blockmask))
+               return 1;
+       return 0;
+}
+
 static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
                                            struct file *file,
                                            loff_t pos, size_t count,
@@ -2230,6 +2247,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        int full_coherency = !(osb->s_mount_opt &
                               OCFS2_MOUNT_COHERENCY_BUFFERED);
+       int unaligned_dio = 0;
 
        trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
                (unsigned long long)OCFS2_I(inode)->ip_blkno,
@@ -2297,6 +2315,10 @@ relock:
                goto out;
        }
 
+       if (direct_io && !is_sync_kiocb(iocb))
+               unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_left,
+                                                     *ppos);
+
        /*
         * We can't complete the direct I/O as requested, fall back to
         * buffered I/O.
@@ -2311,6 +2333,18 @@ relock:
                goto relock;
        }
 
+       if (unaligned_dio) {
+               /*
+                * Wait on previous unaligned aio to complete before
+                * proceeding.
+                */
+               ocfs2_aiodio_wait(inode);
+
+               /* Mark the iocb as needing a decrement in ocfs2_dio_end_io */
+               atomic_inc(&OCFS2_I(inode)->ip_unaligned_aio);
+               ocfs2_iocb_set_unaligned_aio(iocb);
+       }
+
        /*
         * To later detect whether a journal commit for sync writes is
         * necessary, we sample i_size, and cluster count here.
@@ -2382,8 +2416,12 @@ out_dio:
        if ((ret == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
                rw_level = -1;
                have_alloc_sem = 0;
+               unaligned_dio = 0;
        }
 
+       if (unaligned_dio)
+               atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio);
+
 out:
        if (rw_level != -1)
                ocfs2_rw_unlock(inode, rw_level);
@@ -2591,6 +2629,57 @@ bail:
        return ret;
 }
 
+/* Refer generic_file_llseek_unlocked() */
+static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret = 0;
+
+       mutex_lock(&inode->i_mutex);
+
+       switch (origin) {
+       case SEEK_SET:
+               break;
+       case SEEK_END:
+               offset += inode->i_size;
+               break;
+       case SEEK_CUR:
+               if (offset == 0) {
+                       offset = file->f_pos;
+                       goto out;
+               }
+               offset += file->f_pos;
+               break;
+       case SEEK_DATA:
+       case SEEK_HOLE:
+               ret = ocfs2_seek_data_hole_offset(file, &offset, origin);
+               if (ret)
+                       goto out;
+               break;
+       default:
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
+               ret = -EINVAL;
+       if (!ret && offset > inode->i_sb->s_maxbytes)
+               ret = -EINVAL;
+       if (ret)
+               goto out;
+
+       if (offset != file->f_pos) {
+               file->f_pos = offset;
+               file->f_version = 0;
+       }
+
+out:
+       mutex_unlock(&inode->i_mutex);
+       if (ret)
+               return ret;
+       return offset;
+}
+
 const struct inode_operations ocfs2_file_iops = {
        .setattr        = ocfs2_setattr,
        .getattr        = ocfs2_getattr,
@@ -2615,7 +2704,7 @@ const struct inode_operations ocfs2_special_file_iops = {
  * ocfs2_fops_no_plocks and ocfs2_dops_no_plocks!
  */
 const struct file_operations ocfs2_fops = {
-       .llseek         = generic_file_llseek,
+       .llseek         = ocfs2_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .mmap           = ocfs2_mmap,
@@ -2663,7 +2752,7 @@ const struct file_operations ocfs2_dops = {
  * the cluster.
  */
 const struct file_operations ocfs2_fops_no_plocks = {
-       .llseek         = generic_file_llseek,
+       .llseek         = ocfs2_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .mmap           = ocfs2_mmap,
index 1c508b149b3ac1bd4325fd33a9aae6bdb70e024a..88924a3133fae7c15ca3f5a5259b64eecd97022e 100644 (file)
@@ -43,6 +43,9 @@ struct ocfs2_inode_info
        /* protects extended attribute changes on this inode */
        struct rw_semaphore             ip_xattr_sem;
 
+       /* Number of outstanding AIO's which are not page aligned */
+       atomic_t                        ip_unaligned_aio;
+
        /* These fields are protected by ip_lock */
        spinlock_t                      ip_lock;
        u32                             ip_open_count;
index bc91072b72196fd335c4b7cbc02ba08cb67254e6..d9a6ce7792669fedc66cfdbe26b6fe4d00976e59 100644 (file)
@@ -381,7 +381,7 @@ int ocfs2_info_handle_freeinode(struct inode *inode,
        if (!oifi) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto bail;
+               goto out_err;
        }
 
        if (o2info_from_user(*oifi, req))
@@ -431,7 +431,7 @@ bail:
                o2info_set_request_error(&oifi->ifi_req, req);
 
        kfree(oifi);
-
+out_err:
        return status;
 }
 
@@ -666,7 +666,7 @@ int ocfs2_info_handle_freefrag(struct inode *inode,
        if (!oiff) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto bail;
+               goto out_err;
        }
 
        if (o2info_from_user(*oiff, req))
@@ -716,7 +716,7 @@ bail:
                o2info_set_request_error(&oiff->iff_req, req);
 
        kfree(oiff);
-
+out_err:
        return status;
 }
 
index 295d56454e8b23b6e9d97a6bd258e6170311c8f5..0a42ae96dca7d4a0f662505e0e51206895ce4156 100644 (file)
@@ -1544,9 +1544,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
        /* we need to run complete recovery for offline orphan slots */
        ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
 
-       mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
-            node_num, slot_num,
-            MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+       printk(KERN_NOTICE "ocfs2: Begin replay journal (node %d, slot %d) on "\
+              "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev),
+              MINOR(osb->sb->s_dev));
 
        OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
 
@@ -1601,6 +1601,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
 
        jbd2_journal_destroy(journal);
 
+       printk(KERN_NOTICE "ocfs2: End replay journal (node %d, slot %d) on "\
+              "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev),
+              MINOR(osb->sb->s_dev));
 done:
        /* drop the lock on this nodes journal */
        if (got_lock)
@@ -1808,6 +1811,20 @@ static inline unsigned long ocfs2_orphan_scan_timeout(void)
  * every slot, queuing a recovery of the slot on the ocfs2_wq thread. This
  * is done to catch any orphans that are left over in orphan directories.
  *
+ * It scans all slots, even ones that are in use. It does so to handle the
+ * case described below:
+ *
+ *   Node 1 has an inode it was using. The dentry went away due to memory
+ *   pressure.  Node 1 closes the inode, but it's on the free list. The node
+ *   has the open lock.
+ *   Node 2 unlinks the inode. It grabs the dentry lock to notify others,
+ *   but node 1 has no dentry and doesn't get the message. It trylocks the
+ *   open lock, sees that another node has a PR, and does nothing.
+ *   Later node 2 runs its orphan dir. It igets the inode, trylocks the
+ *   open lock, sees the PR still, and does nothing.
+ *   Basically, we have to trigger an orphan iput on node 1. The only way
+ *   for this to happen is if node 1 runs node 2's orphan dir.
+ *
  * ocfs2_queue_orphan_scan gets called every ORPHAN_SCAN_SCHEDULE_TIMEOUT
  * seconds.  It gets an EX lock on os_lockres and checks sequence number
  * stored in LVB. If the sequence number has changed, it means some other
index 3e9393ca39ebd823772ae910cda1b4516d46fa62..9cd41083e99123eca1c48085fb39809e6b906b40 100644 (file)
@@ -61,7 +61,7 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
 static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
                                struct page *page)
 {
-       int ret;
+       int ret = VM_FAULT_NOPAGE;
        struct inode *inode = file->f_path.dentry->d_inode;
        struct address_space *mapping = inode->i_mapping;
        loff_t pos = page_offset(page);
@@ -71,32 +71,25 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
        void *fsdata;
        loff_t size = i_size_read(inode);
 
-       /*
-        * Another node might have truncated while we were waiting on
-        * cluster locks.
-        * We don't check size == 0 before the shift. This is borrowed
-        * from do_generic_file_read.
-        */
        last_index = (size - 1) >> PAGE_CACHE_SHIFT;
-       if (unlikely(!size || page->index > last_index)) {
-               ret = -EINVAL;
-               goto out;
-       }
 
        /*
-        * The i_size check above doesn't catch the case where nodes
-        * truncated and then re-extended the file. We'll re-check the
-        * page mapping after taking the page lock inside of
-        * ocfs2_write_begin_nolock().
+        * There are cases that lead to the page no longer bebongs to the
+        * mapping.
+        * 1) pagecache truncates locally due to memory pressure.
+        * 2) pagecache truncates when another is taking EX lock against 
+        * inode lock. see ocfs2_data_convert_worker.
+        * 
+        * The i_size check doesn't catch the case where nodes truncated and
+        * then re-extended the file. We'll re-check the page mapping after
+        * taking the page lock inside of ocfs2_write_begin_nolock().
+        *
+        * Let VM retry with these cases.
         */
-       if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
-               /*
-                * the page has been umapped in ocfs2_data_downconvert_worker.
-                * So return 0 here and let VFS retry.
-                */
-               ret = 0;
+       if ((page->mapping != inode->i_mapping) ||
+           (!PageUptodate(page)) ||
+           (page_offset(page) >= size))
                goto out;
-       }
 
        /*
         * Call ocfs2_write_begin() and ocfs2_write_end() to take
@@ -116,17 +109,21 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
        if (ret) {
                if (ret != -ENOSPC)
                        mlog_errno(ret);
+               if (ret == -ENOMEM)
+                       ret = VM_FAULT_OOM;
+               else
+                       ret = VM_FAULT_SIGBUS;
                goto out;
        }
 
-       ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page,
-                                    fsdata);
-       if (ret < 0) {
-               mlog_errno(ret);
+       if (!locked_page) {
+               ret = VM_FAULT_NOPAGE;
                goto out;
        }
+       ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page,
+                                    fsdata);
        BUG_ON(ret != len);
-       ret = 0;
+       ret = VM_FAULT_LOCKED;
 out:
        return ret;
 }
@@ -168,8 +165,6 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
 out:
        ocfs2_unblock_signals(&oldset);
-       if (ret)
-               ret = VM_FAULT_SIGBUS;
        return ret;
 }
 
index d53cb706f14c27dfc5ec754dc6d0f846e424421c..184c76b8c293907368f325316da04f57801d87eb 100644 (file)
@@ -745,7 +745,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
         */
        ocfs2_probe_alloc_group(inode, gd_bh, &goal_bit, len, move_max_hop,
                                new_phys_cpos);
-       if (!new_phys_cpos) {
+       if (!*new_phys_cpos) {
                ret = -ENOSPC;
                goto out_commit;
        }
index 409285854f647e2357223bc7a8d24c36b376a6bb..bcde467acca396a1916831849bc495faa5d413b5 100644 (file)
@@ -836,13 +836,13 @@ static inline unsigned int ocfs2_clusters_to_megabytes(struct super_block *sb,
 
 static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
 {
-       __test_and_set_bit_le(bit, bitmap);
+       __set_bit_le(bit, bitmap);
 }
 #define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
 
 static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
 {
-       __test_and_clear_bit_le(bit, bitmap);
+       __clear_bit_le(bit, bitmap);
 }
 #define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
 
index dc8007fc924718c6d461b22cee52e4a8fbd6ae7d..942fd65bdad3fe2be63f42f4539a92343a2eb9f6 100644 (file)
@@ -404,7 +404,9 @@ struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
        int status = 0;
        struct ocfs2_quota_recovery *rec;
 
-       mlog(ML_NOTICE, "Beginning quota recovery in slot %u\n", slot_num);
+       printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+
        rec = ocfs2_alloc_quota_recovery();
        if (!rec)
                return ERR_PTR(-ENOMEM);
@@ -596,7 +598,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
        struct inode *lqinode;
        unsigned int flags;
 
-       mlog(ML_NOTICE, "Finishing quota recovery in slot %u\n", slot_num);
+       printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+
        mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
        for (type = 0; type < MAXQUOTAS; type++) {
                if (list_empty(&(rec->r_list[type])))
@@ -612,8 +616,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
                /* Someone else is holding the lock? Then he must be
                 * doing the recovery. Just skip the file... */
                if (status == -EAGAIN) {
-                       mlog(ML_NOTICE, "skipping quota recovery for slot %d "
-                            "because quota file is locked.\n", slot_num);
+                       printk(KERN_NOTICE "ocfs2: Skipping quota recovery on "
+                              "device (%s) for slot %d because quota file is "
+                              "locked.\n", osb->dev_str, slot_num);
                        status = 0;
                        goto out_put;
                } else if (status < 0) {
index 26fc0014d50936137d0afb898b7c9541e8026087..1424c151cccce0170819ce4e0f36dad7d97461b8 100644 (file)
@@ -493,8 +493,8 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
                        goto bail;
                }
        } else
-               mlog(ML_NOTICE, "slot %d is already allocated to this node!\n",
-                    slot);
+               printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already "
+                      "allocated to this node!\n", slot, osb->dev_str);
 
        ocfs2_set_slot(si, slot, osb->node_num);
        osb->slot_num = slot;
index 19965b00c43caee7df4e09428775a55150ba9f8c..94368017edb378ce1e3961d1976408c954677c9a 100644 (file)
@@ -28,6 +28,7 @@
 #include "cluster/masklog.h"
 #include "cluster/nodemanager.h"
 #include "cluster/heartbeat.h"
+#include "cluster/tcp.h"
 
 #include "stackglue.h"
 
@@ -255,6 +256,61 @@ static void o2cb_dump_lksb(struct ocfs2_dlm_lksb *lksb)
        dlm_print_one_lock(lksb->lksb_o2dlm.lockid);
 }
 
+/*
+ * Check if this node is heartbeating and is connected to all other
+ * heartbeating nodes.
+ */
+static int o2cb_cluster_check(void)
+{
+       u8 node_num;
+       int i;
+       unsigned long hbmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long netmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+
+       node_num = o2nm_this_node();
+       if (node_num == O2NM_MAX_NODES) {
+               printk(KERN_ERR "o2cb: This node has not been configured.\n");
+               return -EINVAL;
+       }
+
+       /*
+        * o2dlm expects o2net sockets to be created. If not, then
+        * dlm_join_domain() fails with a stack of errors which are both cryptic
+        * and incomplete. The idea here is to detect upfront whether we have
+        * managed to connect to all nodes or not. If not, then list the nodes
+        * to allow the user to check the configuration (incorrect IP, firewall,
+        * etc.) Yes, this is racy. But its not the end of the world.
+        */
+#define        O2CB_MAP_STABILIZE_COUNT        60
+       for (i = 0; i < O2CB_MAP_STABILIZE_COUNT; ++i) {
+               o2hb_fill_node_map(hbmap, sizeof(hbmap));
+               if (!test_bit(node_num, hbmap)) {
+                       printk(KERN_ERR "o2cb: %s heartbeat has not been "
+                              "started.\n", (o2hb_global_heartbeat_active() ?
+                                             "Global" : "Local"));
+                       return -EINVAL;
+               }
+               o2net_fill_node_map(netmap, sizeof(netmap));
+               /* Force set the current node to allow easy compare */
+               set_bit(node_num, netmap);
+               if (!memcmp(hbmap, netmap, sizeof(hbmap)))
+                       return 0;
+               if (i < O2CB_MAP_STABILIZE_COUNT)
+                       msleep(1000);
+       }
+
+       printk(KERN_ERR "o2cb: This node could not connect to nodes:");
+       i = -1;
+       while ((i = find_next_bit(hbmap, O2NM_MAX_NODES,
+                                 i + 1)) < O2NM_MAX_NODES) {
+               if (!test_bit(i, netmap))
+                       printk(" %u", i);
+       }
+       printk(".\n");
+
+       return -ENOTCONN;
+}
+
 /*
  * Called from the dlm when it's about to evict a node. This is how the
  * classic stack signals node death.
@@ -263,8 +319,8 @@ static void o2dlm_eviction_cb(int node_num, void *data)
 {
        struct ocfs2_cluster_connection *conn = data;
 
-       mlog(ML_NOTICE, "o2dlm has evicted node %d from group %.*s\n",
-            node_num, conn->cc_namelen, conn->cc_name);
+       printk(KERN_NOTICE "o2cb: o2dlm has evicted node %d from domain %.*s\n",
+              node_num, conn->cc_namelen, conn->cc_name);
 
        conn->cc_recovery_handler(node_num, conn->cc_recovery_data);
 }
@@ -280,12 +336,11 @@ static int o2cb_cluster_connect(struct ocfs2_cluster_connection *conn)
        BUG_ON(conn == NULL);
        BUG_ON(conn->cc_proto == NULL);
 
-       /* for now we only have one cluster/node, make sure we see it
-        * in the heartbeat universe */
-       if (!o2hb_check_local_node_heartbeating()) {
-               if (o2hb_global_heartbeat_active())
-                       mlog(ML_ERROR, "Global heartbeat not started\n");
-               rc = -EINVAL;
+       /* Ensure cluster stack is up and all nodes are connected */
+       rc = o2cb_cluster_check();
+       if (rc) {
+               printk(KERN_ERR "o2cb: Cluster check failed. Fix errors "
+                      "before retrying.\n");
                goto out;
        }
 
index 56f61027236b696fce1ccde3e1edaf86acee59a0..938e2b2b0c9c9f8635a43ad4686dff675885361f 100644 (file)
@@ -54,6 +54,7 @@
 #include "ocfs1_fs_compat.h"
 
 #include "alloc.h"
+#include "aops.h"
 #include "blockcheck.h"
 #include "dlmglue.h"
 #include "export.h"
@@ -1107,9 +1108,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 
                ocfs2_set_ro_flag(osb, 1);
 
-               printk(KERN_NOTICE "Readonly device detected. No cluster "
-                      "services will be utilized for this mount. Recovery "
-                      "will be skipped.\n");
+               printk(KERN_NOTICE "ocfs2: Readonly device (%s) detected. "
+                      "Cluster services will not be used for this mount. "
+                      "Recovery will be skipped.\n", osb->dev_str);
        }
 
        if (!ocfs2_is_hard_readonly(osb)) {
@@ -1616,12 +1617,17 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
        return 0;
 }
 
+wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 static int __init ocfs2_init(void)
 {
-       int status;
+       int status, i;
 
        ocfs2_print_version();
 
+       for (i = 0; i < OCFS2_IOEND_WQ_HASH_SZ; i++)
+               init_waitqueue_head(&ocfs2__ioend_wq[i]);
+
        status = init_ocfs2_uptodate_cache();
        if (status < 0) {
                mlog_errno(status);
@@ -1760,7 +1766,7 @@ static void ocfs2_inode_init_once(void *data)
        ocfs2_extent_map_init(&oi->vfs_inode);
        INIT_LIST_HEAD(&oi->ip_io_markers);
        oi->ip_dir_start_lookup = 0;
-
+       atomic_set(&oi->ip_unaligned_aio, 0);
        init_rwsem(&oi->ip_alloc_sem);
        init_rwsem(&oi->ip_xattr_sem);
        mutex_init(&oi->ip_io_mutex);
@@ -1974,7 +1980,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
         * If we failed before we got a uuid_str yet, we can't stop
         * heartbeat.  Otherwise, do it.
         */
-       if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str)
+       if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str &&
+           !ocfs2_is_hard_readonly(osb))
                hangup_needed = 1;
 
        if (osb->cconn)
@@ -2462,8 +2469,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
                        goto finally;
                }
        } else {
-               mlog(ML_NOTICE, "File system was not unmounted cleanly, "
-                    "recovering volume.\n");
+               printk(KERN_NOTICE "ocfs2: File system on device (%s) was not "
+                      "unmounted cleanly, recovering it.\n", osb->dev_str);
        }
 
        local = ocfs2_mount_local(osb);
index 81ecf9c0bf0ad41e0ac2fd523b1538afc3f57a07..194fb22ef79d590580f3245b522d0b095ef3794c 100644 (file)
@@ -7185,20 +7185,9 @@ int ocfs2_init_security_and_acl(struct inode *dir,
 {
        int ret = 0;
        struct buffer_head *dir_bh = NULL;
-       struct ocfs2_security_xattr_info si = {
-               .enable = 1,
-       };
 
-       ret = ocfs2_init_security_get(inode, dir, qstr, &si);
+       ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
        if (!ret) {
-               ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
-                                     si.name, si.value, si.value_len,
-                                     XATTR_CREATE);
-               if (ret) {
-                       mlog_errno(ret);
-                       goto leave;
-               }
-       } else if (ret != -EOPNOTSUPP) {
                mlog_errno(ret);
                goto leave;
        }
@@ -7255,6 +7244,22 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
                               name, value, size, flags);
 }
 
+int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                    void *fs_info)
+{
+       const struct xattr *xattr;
+       int err = 0;
+
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
+                                     xattr->name, xattr->value,
+                                     xattr->value_len, XATTR_CREATE);
+               if (err)
+                       break;
+       }
+       return err;
+}
+
 int ocfs2_init_security_get(struct inode *inode,
                            struct inode *dir,
                            const struct qstr *qstr,
@@ -7263,8 +7268,13 @@ int ocfs2_init_security_get(struct inode *inode,
        /* check whether ocfs2 support feature xattr */
        if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
                return -EOPNOTSUPP;
-       return security_inode_init_security(inode, dir, qstr, &si->name,
-                                           &si->value, &si->value_len);
+       if (si)
+               return security_old_inode_init_security(inode, dir, qstr,
+                                                       &si->name, &si->value,
+                                                       &si->value_len);
+
+       return security_inode_init_security(inode, dir, qstr,
+                                           &ocfs2_initxattrs, NULL);
 }
 
 int ocfs2_init_security_set(handle_t *handle,
index 7ed72d6c1c6fc4d2c528e7c5578c2836a2875914..9c70229b6c35d24eba67b5fc48c64987b27910a3 100644 (file)
@@ -29,6 +29,7 @@ static void proc_evict_inode(struct inode *inode)
        struct proc_dir_entry *de;
        struct ctl_table_header *head;
        const struct proc_ns_operations *ns_ops;
+       void *ns;
 
        truncate_inode_pages(&inode->i_data, 0);
        end_writeback(inode);
@@ -47,8 +48,9 @@ static void proc_evict_inode(struct inode *inode)
        }
        /* Release any associated namespace */
        ns_ops = PROC_I(inode)->ns_ops;
-       if (ns_ops && ns_ops->put)
-               ns_ops->put(PROC_I(inode)->ns);
+       ns = PROC_I(inode)->ns;
+       if (ns_ops && ns)
+               ns_ops->put(ns);
 }
 
 static struct kmem_cache * proc_inode_cachep;
index be177f702acbc9bc352c0e13f5b37aeedbf6dd25..53d4cc890aa4939c44dfb6ce898800da49ee8a82 100644 (file)
@@ -31,6 +31,140 @@ static const struct file_operations ns_file_operations = {
        .llseek         = no_llseek,
 };
 
+static const struct inode_operations ns_inode_operations = {
+       .setattr        = proc_setattr,
+};
+
+static int ns_delete_dentry(const struct dentry *dentry)
+{
+       /* Don't cache namespace dentries when not in use */
+       return 1;
+}
+
+static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+       struct inode *inode = dentry->d_inode;
+       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
+
+       return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
+               ns_ops->name, inode->i_ino);
+}
+
+static const struct dentry_operations ns_dentry_operations =
+{
+       .d_delete       = ns_delete_dentry,
+       .d_dname        = ns_dname,
+};
+
+static struct dentry *proc_ns_get_dentry(struct super_block *sb,
+       struct task_struct *task, const struct proc_ns_operations *ns_ops)
+{
+       struct dentry *dentry;
+       struct inode *inode;
+       struct proc_inode *ei;
+       struct qstr qname = { .name = "", };
+       void *ns;
+
+       ns = ns_ops->get(task);
+       if (!ns)
+               return ERR_PTR(-ENOENT);
+
+       dentry = d_alloc_pseudo(sb, &qname);
+       if (!dentry) {
+               ns_ops->put(ns);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       inode = new_inode(sb);
+       if (!inode) {
+               dput(dentry);
+               ns_ops->put(ns);
+               return ERR_PTR(-ENOMEM);
+       }
+               
+       ei = PROC_I(inode);
+       inode->i_ino = get_next_ino();
+       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+       inode->i_op = &ns_inode_operations;
+       inode->i_mode = S_IFREG|S_IRUSR;
+       inode->i_fop = &ns_file_operations;
+       ei->ns_ops = ns_ops;
+       ei->ns = ns;
+
+       d_set_d_op(dentry, &ns_dentry_operations);
+       d_instantiate(dentry, inode);
+
+       return dentry;
+}
+
+static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       struct inode *inode = dentry->d_inode;
+       struct super_block *sb = inode->i_sb;
+       struct proc_inode *ei = PROC_I(inode);
+       struct task_struct *task;
+       struct dentry *ns_dentry;
+       void *error = ERR_PTR(-EACCES);
+       
+       task = get_proc_task(inode);
+       if (!task)
+               goto out;
+
+       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+               goto out_put_task;
+
+       ns_dentry = proc_ns_get_dentry(sb, task, ei->ns_ops);
+       if (IS_ERR(ns_dentry)) {
+               error = ERR_CAST(ns_dentry);
+               goto out_put_task;
+       }
+
+       dput(nd->path.dentry);
+       nd->path.dentry = ns_dentry;
+       error = NULL;
+
+out_put_task:
+       put_task_struct(task);
+out:
+       return error;
+}
+
+static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+{
+       struct inode *inode = dentry->d_inode;
+       struct proc_inode *ei = PROC_I(inode);
+       const struct proc_ns_operations *ns_ops = ei->ns_ops;
+       struct task_struct *task;
+       char name[50];
+       int len = -EACCES;
+
+       task = get_proc_task(inode);
+       if (!task)
+               goto out;
+
+       if (!ptrace_may_access(task, PTRACE_MODE_READ))
+               goto out_put_task;
+
+       snprintf(name, sizeof(name), "%s", ns_ops->name);
+       len = strlen(name);
+
+       if (len > buflen)
+               len = buflen;
+       if (copy_to_user(buffer, ns_ops->name, len))
+               len = -EFAULT;
+
+out_put_task:
+       put_task_struct(task);
+out:
+       return len;
+}
+
+static const struct inode_operations proc_ns_link_inode_operations = {
+       .readlink       = proc_ns_readlink,
+       .follow_link    = proc_ns_follow_link,
+       .setattr        = proc_setattr,
+};
+
 static struct dentry *proc_ns_instantiate(struct inode *dir,
        struct dentry *dentry, struct task_struct *task, const void *ptr)
 {
@@ -38,32 +172,23 @@ static struct dentry *proc_ns_instantiate(struct inode *dir,
        struct inode *inode;
        struct proc_inode *ei;
        struct dentry *error = ERR_PTR(-ENOENT);
-       void *ns;
 
        inode = proc_pid_make_inode(dir->i_sb, task);
        if (!inode)
                goto out;
 
-       ns = ns_ops->get(task);
-       if (!ns)
-               goto out_iput;
-
        ei = PROC_I(inode);
-       inode->i_mode = S_IFREG|S_IRUSR;
-       inode->i_fop  = &ns_file_operations;
-       ei->ns_ops    = ns_ops;
-       ei->ns        = ns;
+       inode->i_mode = S_IFLNK|S_IRWXUGO;
+       inode->i_op = &proc_ns_link_inode_operations;
+       ei->ns_ops = ns_ops;
 
-       dentry->d_op = &pid_dentry_operations;
+       d_set_d_op(dentry, &pid_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (pid_revalidate(dentry, NULL))
                error = NULL;
 out:
        return error;
-out_iput:
-       iput(inode);
-       goto out;
 }
 
 static int proc_ns_fill_cache(struct file *filp, void *dirent,
@@ -90,10 +215,6 @@ static int proc_ns_dir_readdir(struct file *filp, void *dirent,
        if (!task)
                goto out_no_task;
 
-       ret = -EPERM;
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
-               goto out;
-
        ret = 0;
        i = filp->f_pos;
        switch (i) {
@@ -153,10 +274,6 @@ static struct dentry *proc_ns_dir_lookup(struct inode *dir,
        if (!task)
                goto out_no_task;
 
-       error = ERR_PTR(-EPERM);
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
-               goto out;
-
        last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
        for (entry = ns_entries; entry <= last; entry++) {
                if (strlen((*entry)->name) != len)
@@ -164,7 +281,6 @@ static struct dentry *proc_ns_dir_lookup(struct inode *dir,
                if (!memcmp(dentry->d_name.name, (*entry)->name, len))
                        break;
        }
-       error = ERR_PTR(-ENOENT);
        if (entry > last)
                goto out;
 
index 1a77dbef226f00a2c41a5606b6e3c95fece6f5aa..1435ef5e94ca15de25637fb5e8e79f467e7465a1 100644 (file)
@@ -49,17 +49,11 @@ out:
 
 static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name)
 {
-       int len;
        for ( ; p->procname; p++) {
-
-               if (!p->procname)
-                       continue;
-
-               len = strlen(p->procname);
-               if (len != name->len)
+               if (strlen(p->procname) != name->len)
                        continue;
 
-               if (memcmp(p->procname, name->name, len) != 0)
+               if (memcmp(p->procname, name->name, name->len) != 0)
                        continue;
 
                /* I have a match */
@@ -223,10 +217,6 @@ static int scan(struct ctl_table_header *head, ctl_table *table,
        for (; table->procname; table++, (*pos)++) {
                int res;
 
-               /* Can't do anything without a proc name */
-               if (!table->procname)
-                       continue;
-
                if (*pos < file->f_pos)
                        continue;
 
index 893b961dcfd8b45219a9266ca4db78ee9b44fb71..379a02dc1217adf24450af7bae64279e78d85793 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/init.h>
+#include <linux/list.h>
 #include <linux/string.h>
 #include <linux/mount.h>
 #include <linux/ramfs.h>
 #include <linux/magic.h>
 #include <linux/pstore.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/uaccess.h>
 
 #include "internal.h"
 
 #define        PSTORE_NAMELEN  64
 
+static DEFINE_SPINLOCK(allpstore_lock);
+static LIST_HEAD(allpstore);
+
 struct pstore_private {
+       struct list_head list;
        struct pstore_info *psi;
        enum pstore_type_id type;
        u64     id;
@@ -81,8 +87,16 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
 
 static void pstore_evict_inode(struct inode *inode)
 {
+       struct pstore_private   *p = inode->i_private;
+       unsigned long           flags;
+
        end_writeback(inode);
-       kfree(inode->i_private);
+       if (p) {
+               spin_lock_irqsave(&allpstore_lock, flags);
+               list_del(&p->list);
+               spin_unlock_irqrestore(&allpstore_lock, flags);
+               kfree(p);
+       }
 }
 
 static const struct inode_operations pstore_dir_inode_operations = {
@@ -182,9 +196,23 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
        struct dentry           *root = pstore_sb->s_root;
        struct dentry           *dentry;
        struct inode            *inode;
-       int                     rc;
+       int                     rc = 0;
        char                    name[PSTORE_NAMELEN];
-       struct pstore_private   *private;
+       struct pstore_private   *private, *pos;
+       unsigned long           flags;
+
+       spin_lock_irqsave(&allpstore_lock, flags);
+       list_for_each_entry(pos, &allpstore, list) {
+               if (pos->type == type &&
+                   pos->id == id &&
+                   pos->psi == psi) {
+                       rc = -EEXIST;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&allpstore_lock, flags);
+       if (rc)
+               return rc;
 
        rc = -ENOMEM;
        inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0);
@@ -229,6 +257,10 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
 
        d_add(dentry, inode);
 
+       spin_lock_irqsave(&allpstore_lock, flags);
+       list_add(&private->list, &allpstore);
+       spin_unlock_irqrestore(&allpstore_lock, flags);
+
        mutex_unlock(&root->d_inode->i_mutex);
 
        return 0;
@@ -277,7 +309,7 @@ int pstore_fill_super(struct super_block *sb, void *data, int silent)
                goto fail;
        }
 
-       pstore_get_records();
+       pstore_get_records(0);
 
        return 0;
 fail:
index 611c1b3c46fae9b71756e1c2bd9df54e6466c17d..3bde461c3f349cfe1932d94a5f3b424e9184bebc 100644 (file)
@@ -1,5 +1,5 @@
 extern void    pstore_set_kmsg_bytes(int);
-extern void    pstore_get_records(void);
+extern void    pstore_get_records(int);
 extern int     pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
                              char *data, size_t size,
                              struct timespec time, struct pstore_info *psi);
index c5300ec316965ac456091ae91ec18f1704b97681..0472924024cc293dcd2f3dd842cb79d4b60a637e 100644 (file)
 #include <linux/module.h>
 #include <linux/pstore.h>
 #include <linux/string.h>
+#include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/hardirq.h>
+#include <linux/workqueue.h>
 
 #include "internal.h"
 
+/*
+ * We defer making "oops" entries appear in pstore - see
+ * whether the system is actually still running well enough
+ * to let someone see the entry
+ */
+#define        PSTORE_INTERVAL (60 * HZ)
+
+static int pstore_new_entry;
+
+static void pstore_timefunc(unsigned long);
+static DEFINE_TIMER(pstore_timer, pstore_timefunc, 0, 0);
+
+static void pstore_dowork(struct work_struct *);
+static DECLARE_WORK(pstore_work, pstore_dowork);
+
 /*
  * pstore_lock just protects "psinfo" during
  * calls to pstore_register()
@@ -71,13 +89,20 @@ static void pstore_dump(struct kmsg_dumper *dumper,
        u64             id;
        int             hsize;
        unsigned int    part = 1;
+       unsigned long   flags = 0;
+       int             is_locked = 0;
 
        if (reason < ARRAY_SIZE(reason_str))
                why = reason_str[reason];
        else
                why = "Unknown";
 
-       mutex_lock(&psinfo->buf_mutex);
+       if (in_nmi()) {
+               is_locked = spin_trylock(&psinfo->buf_lock);
+               if (!is_locked)
+                       pr_err("pstore dump routine blocked in NMI, may corrupt error record\n");
+       } else
+               spin_lock_irqsave(&psinfo->buf_lock, flags);
        oopscount++;
        while (total < kmsg_bytes) {
                dst = psinfo->buf;
@@ -100,15 +125,17 @@ static void pstore_dump(struct kmsg_dumper *dumper,
                id = psinfo->write(PSTORE_TYPE_DMESG, part,
                                   hsize + l1_cpy + l2_cpy, psinfo);
                if (reason == KMSG_DUMP_OOPS && pstore_is_mounted())
-                       pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id,
-                                     psinfo->buf, hsize + l1_cpy + l2_cpy,
-                                     CURRENT_TIME, psinfo);
+                       pstore_new_entry = 1;
                l1 -= l1_cpy;
                l2 -= l2_cpy;
                total += l1_cpy + l2_cpy;
                part++;
        }
-       mutex_unlock(&psinfo->buf_mutex);
+       if (in_nmi()) {
+               if (is_locked)
+                       spin_unlock(&psinfo->buf_lock);
+       } else
+               spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 }
 
 static struct kmsg_dumper pstore_dumper = {
@@ -148,19 +175,24 @@ int pstore_register(struct pstore_info *psi)
        }
 
        if (pstore_is_mounted())
-               pstore_get_records();
+               pstore_get_records(0);
 
        kmsg_dump_register(&pstore_dumper);
 
+       pstore_timer.expires = jiffies + PSTORE_INTERVAL;
+       add_timer(&pstore_timer);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(pstore_register);
 
 /*
- * Read all the records from the persistent store. Create and
- * file files in our filesystem.
+ * Read all the records from the persistent store. Create
+ * files in our filesystem.  Don't warn about -EEXIST errors
+ * when we are re-scanning the backing store looking to add new
+ * error records.
  */
-void pstore_get_records(void)
+void pstore_get_records(int quiet)
 {
        struct pstore_info *psi = psinfo;
        ssize_t                 size;
@@ -168,36 +200,54 @@ void pstore_get_records(void)
        enum pstore_type_id     type;
        struct timespec         time;
        int                     failed = 0, rc;
+       unsigned long           flags;
 
        if (!psi)
                return;
 
-       mutex_lock(&psinfo->buf_mutex);
+       spin_lock_irqsave(&psinfo->buf_lock, flags);
        rc = psi->open(psi);
        if (rc)
                goto out;
 
        while ((size = psi->read(&id, &type, &time, psi)) > 0) {
-               if (pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size,
-                                 time, psi))
+               rc = pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size,
+                                 time, psi);
+               if (rc && (rc != -EEXIST || !quiet))
                        failed++;
        }
        psi->close(psi);
 out:
-       mutex_unlock(&psinfo->buf_mutex);
+       spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 
        if (failed)
                printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n",
                       failed, psi->name);
 }
 
+static void pstore_dowork(struct work_struct *work)
+{
+       pstore_get_records(1);
+}
+
+static void pstore_timefunc(unsigned long dummy)
+{
+       if (pstore_new_entry) {
+               pstore_new_entry = 0;
+               schedule_work(&pstore_work);
+       }
+
+       mod_timer(&pstore_timer, jiffies + PSTORE_INTERVAL);
+}
+
 /*
  * Call platform driver to write a record to the
  * persistent store.
  */
 int pstore_write(enum pstore_type_id type, char *buf, size_t size)
 {
-       u64     id;
+       u64             id;
+       unsigned long   flags;
 
        if (!psinfo)
                return -ENODEV;
@@ -205,13 +255,13 @@ int pstore_write(enum pstore_type_id type, char *buf, size_t size)
        if (size > psinfo->bufsize)
                return -EFBIG;
 
-       mutex_lock(&psinfo->buf_mutex);
+       spin_lock_irqsave(&psinfo->buf_lock, flags);
        memcpy(psinfo->buf, buf, size);
        id = psinfo->write(type, 0, size, psinfo);
        if (pstore_is_mounted())
                pstore_mkfile(PSTORE_TYPE_DMESG, psinfo->name, id, psinfo->buf,
                              size, CURRENT_TIME, psinfo);
-       mutex_unlock(&psinfo->buf_mutex);
+       spin_unlock_irqrestore(&psinfo->buf_lock, flags);
 
        return 0;
 }
index ef66c18a933266e9c658fde311f7a1d0e2d6d023..534668fa41bee012a038ce48a94af04ad0d19327 100644 (file)
@@ -66,8 +66,8 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
        if (IS_PRIVATE(dir))
                return 0;
 
-       error = security_inode_init_security(inode, dir, qstr, &sec->name,
-                                            &sec->value, &sec->length);
+       error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
+                                                &sec->value, &sec->length);
        if (error) {
                if (error == -EOPNOTSUPP)
                        error = 0;
index ea9120a830d824feb798db501a4b61fbd98f6071..c3646d93a032b9b90e35830551b5b6ac7e7e1361 100644 (file)
@@ -43,20 +43,47 @@ static DEFINE_IDA(sysfs_ino_ida);
 static void sysfs_link_sibling(struct sysfs_dirent *sd)
 {
        struct sysfs_dirent *parent_sd = sd->s_parent;
-       struct sysfs_dirent **pos;
 
-       BUG_ON(sd->s_sibling);
-
-       /* Store directory entries in order by ino.  This allows
-        * readdir to properly restart without having to add a
-        * cursor into the s_dir.children list.
-        */
-       for (pos = &parent_sd->s_dir.children; *pos; pos = &(*pos)->s_sibling) {
-               if (sd->s_ino < (*pos)->s_ino)
-                       break;
+       struct rb_node **p;
+       struct rb_node *parent;
+
+       if (sysfs_type(sd) == SYSFS_DIR)
+               parent_sd->s_dir.subdirs++;
+
+       p = &parent_sd->s_dir.inode_tree.rb_node;
+       parent = NULL;
+       while (*p) {
+               parent = *p;
+#define node   rb_entry(parent, struct sysfs_dirent, inode_node)
+               if (sd->s_ino < node->s_ino) {
+                       p = &node->inode_node.rb_left;
+               } else if (sd->s_ino > node->s_ino) {
+                       p = &node->inode_node.rb_right;
+               } else {
+                       printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n", sd->s_ino);
+                       BUG();
+               }
+#undef node
        }
-       sd->s_sibling = *pos;
-       *pos = sd;
+       rb_link_node(&sd->inode_node, parent, p);
+       rb_insert_color(&sd->inode_node, &parent_sd->s_dir.inode_tree);
+
+       p = &parent_sd->s_dir.name_tree.rb_node;
+       parent = NULL;
+       while (*p) {
+               int c;
+               parent = *p;
+#define node   rb_entry(parent, struct sysfs_dirent, name_node)
+               c = strcmp(sd->s_name, node->s_name);
+               if (c < 0) {
+                       p = &node->name_node.rb_left;
+               } else {
+                       p = &node->name_node.rb_right;
+               }
+#undef node
+       }
+       rb_link_node(&sd->name_node, parent, p);
+       rb_insert_color(&sd->name_node, &parent_sd->s_dir.name_tree);
 }
 
 /**
@@ -71,16 +98,11 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
  */
 static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
 {
-       struct sysfs_dirent **pos;
+       if (sysfs_type(sd) == SYSFS_DIR)
+               sd->s_parent->s_dir.subdirs--;
 
-       for (pos = &sd->s_parent->s_dir.children; *pos;
-            pos = &(*pos)->s_sibling) {
-               if (*pos == sd) {
-                       *pos = sd->s_sibling;
-                       sd->s_sibling = NULL;
-                       break;
-               }
-       }
+       rb_erase(&sd->inode_node, &sd->s_parent->s_dir.inode_tree);
+       rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree);
 }
 
 /**
@@ -126,7 +148,6 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
  */
 void sysfs_put_active(struct sysfs_dirent *sd)
 {
-       struct completion *cmpl;
        int v;
 
        if (unlikely(!sd))
@@ -138,10 +159,9 @@ void sysfs_put_active(struct sysfs_dirent *sd)
                return;
 
        /* atomic_dec_return() is a mb(), we'll always see the updated
-        * sd->s_sibling.
+        * sd->u.completion.
         */
-       cmpl = (void *)sd->s_sibling;
-       complete(cmpl);
+       complete(sd->u.completion);
 }
 
 /**
@@ -155,16 +175,16 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
        DECLARE_COMPLETION_ONSTACK(wait);
        int v;
 
-       BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
+       BUG_ON(!(sd->s_flags & SYSFS_FLAG_REMOVED));
 
        if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
                return;
 
-       sd->s_sibling = (void *)&wait;
+       sd->u.completion = (void *)&wait;
 
        rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
        /* atomic_add_return() is a mb(), put_active() will always see
-        * the updated sd->s_sibling.
+        * the updated sd->u.completion.
         */
        v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
 
@@ -173,8 +193,6 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
                wait_for_completion(&wait);
        }
 
-       sd->s_sibling = NULL;
-
        lock_acquired(&sd->dep_map, _RET_IP_);
        rwsem_release(&sd->dep_map, 1, _RET_IP_);
 }
@@ -490,7 +508,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
        }
 
        sd->s_flags |= SYSFS_FLAG_REMOVED;
-       sd->s_sibling = acxt->removed;
+       sd->u.removed_list = acxt->removed;
        acxt->removed = sd;
 }
 
@@ -514,8 +532,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
        while (acxt->removed) {
                struct sysfs_dirent *sd = acxt->removed;
 
-               acxt->removed = sd->s_sibling;
-               sd->s_sibling = NULL;
+               acxt->removed = sd->u.removed_list;
 
                sysfs_deactivate(sd);
                unmap_bin_file(sd);
@@ -540,15 +557,36 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
                                       const void *ns,
                                       const unsigned char *name)
 {
-       struct sysfs_dirent *sd;
+       struct rb_node *p = parent_sd->s_dir.name_tree.rb_node;
+       struct sysfs_dirent *found = NULL;
+
+       while (p) {
+               int c;
+#define node   rb_entry(p, struct sysfs_dirent, name_node)
+               c = strcmp(name, node->s_name);
+               if (c < 0) {
+                       p = node->name_node.rb_left;
+               } else if (c > 0) {
+                       p = node->name_node.rb_right;
+               } else {
+                       found = node;
+                       p = node->name_node.rb_left;
+               }
+#undef node
+       }
 
-       for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
-               if (ns && sd->s_ns && (sd->s_ns != ns))
-                       continue;
-               if (!strcmp(sd->s_name, name))
-                       return sd;
+       if (found && ns) {
+               while (found->s_ns && found->s_ns != ns) {
+                       p = rb_next(&found->name_node);
+                       if (!p)
+                               return NULL;
+                       found = rb_entry(p, struct sysfs_dirent, name_node);
+                       if (strcmp(name, found->s_name))
+                               return NULL;
+               }
        }
-       return NULL;
+
+       return found;
 }
 
 /**
@@ -744,21 +782,19 @@ void sysfs_remove_subdir(struct sysfs_dirent *sd)
 static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
 {
        struct sysfs_addrm_cxt acxt;
-       struct sysfs_dirent **pos;
+       struct rb_node *pos;
 
        if (!dir_sd)
                return;
 
        pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
        sysfs_addrm_start(&acxt, dir_sd);
-       pos = &dir_sd->s_dir.children;
-       while (*pos) {
-               struct sysfs_dirent *sd = *pos;
-
+       pos = rb_first(&dir_sd->s_dir.inode_tree);
+       while (pos) {
+               struct sysfs_dirent *sd = rb_entry(pos, struct sysfs_dirent, inode_node);
+               pos = rb_next(pos);
                if (sysfs_type(sd) != SYSFS_DIR)
                        sysfs_remove_one(&acxt, sd);
-               else
-                       pos = &(*pos)->s_sibling;
        }
        sysfs_addrm_finish(&acxt);
 
@@ -881,12 +917,28 @@ static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
                        pos = NULL;
        }
        if (!pos && (ino > 1) && (ino < INT_MAX)) {
-               pos = parent_sd->s_dir.children;
-               while (pos && (ino > pos->s_ino))
-                       pos = pos->s_sibling;
+               struct rb_node *p = parent_sd->s_dir.inode_tree.rb_node;
+               while (p) {
+#define node   rb_entry(p, struct sysfs_dirent, inode_node)
+                       if (ino < node->s_ino) {
+                               pos = node;
+                               p = node->inode_node.rb_left;
+                       } else if (ino > node->s_ino) {
+                               p = node->inode_node.rb_right;
+                       } else {
+                               pos = node;
+                               break;
+                       }
+#undef node
+               }
+       }
+       while (pos && pos->s_ns && pos->s_ns != ns) {
+               struct rb_node *p = rb_next(&pos->inode_node);
+               if (!p)
+                       pos = NULL;
+               else
+                       pos = rb_entry(p, struct sysfs_dirent, inode_node);
        }
-       while (pos && pos->s_ns && pos->s_ns != ns)
-               pos = pos->s_sibling;
        return pos;
 }
 
@@ -894,10 +946,13 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
        struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
 {
        pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
-       if (pos)
-               pos = pos->s_sibling;
-       while (pos && pos->s_ns && pos->s_ns != ns)
-               pos = pos->s_sibling;
+       if (pos) do {
+               struct rb_node *p = rb_next(&pos->inode_node);
+               if (!p)
+                       pos = NULL;
+               else
+                       pos = rb_entry(p, struct sysfs_dirent, inode_node);
+       } while (pos && pos->s_ns && pos->s_ns != ns);
        return pos;
 }
 
index e3f091a81c724bcf830184e1b8db4d66c40b4c5d..1ee18c81df7814949eae2d3d75ccea96cdcf2039 100644 (file)
@@ -202,18 +202,6 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
        inode->i_ctime = iattr->ia_ctime;
 }
 
-static int sysfs_count_nlink(struct sysfs_dirent *sd)
-{
-       struct sysfs_dirent *child;
-       int nr = 0;
-
-       for (child = sd->s_dir.children; child; child = child->s_sibling)
-               if (sysfs_type(child) == SYSFS_DIR)
-                       nr++;
-
-       return nr + 2;
-}
-
 static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
 {
        struct sysfs_inode_attrs *iattrs = sd->s_iattr;
@@ -230,7 +218,7 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
        }
 
        if (sysfs_type(sd) == SYSFS_DIR)
-               inode->i_nlink = sysfs_count_nlink(sd);
+               inode->i_nlink = sd->s_dir.subdirs + 2;
 }
 
 int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
index 845ab3ad229d60616807bb39f0adaceb73a3ad8e..ce29e28b766d9dbe6812ca506e6fbb0f7a44ec9e 100644 (file)
 #include <linux/lockdep.h>
 #include <linux/kobject_ns.h>
 #include <linux/fs.h>
+#include <linux/rbtree.h>
 
 struct sysfs_open_dirent;
 
 /* type-specific structures for sysfs_dirent->s_* union members */
 struct sysfs_elem_dir {
        struct kobject          *kobj;
-       /* children list starts here and goes through sd->s_sibling */
-       struct sysfs_dirent     *children;
+
+       unsigned long           subdirs;
+
+       struct rb_root          inode_tree;
+       struct rb_root          name_tree;
 };
 
 struct sysfs_elem_symlink {
@@ -56,9 +60,16 @@ struct sysfs_dirent {
        struct lockdep_map      dep_map;
 #endif
        struct sysfs_dirent     *s_parent;
-       struct sysfs_dirent     *s_sibling;
        const char              *s_name;
 
+       struct rb_node          inode_node;
+       struct rb_node          name_node;
+
+       union {
+               struct completion       *completion;
+               struct sysfs_dirent     *removed_list;
+       } u;
+
        const void              *s_ns; /* namespace tag */
        union {
                struct sysfs_elem_dir           s_dir;
index 45174b53437730b350d97658318721579448d20f..feb361e252acfe801d186849430c553e39a4268e 100644 (file)
@@ -335,9 +335,9 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
 #define DBGKEY(key)  ((char *)(key))
 #define DBGKEY1(key) ((char *)(key))
 
-#define ubifs_dbg_msg(fmt, ...) do {               \
-       if (0)                                     \
-               pr_debug(fmt "\n", ##__VA_ARGS__); \
+#define ubifs_dbg_msg(fmt, ...) do {                        \
+       if (0)                                              \
+               printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \
 } while (0)
 
 #define dbg_dump_stack()
index f060663ab70c2b2c602aa7a7f4f8a343f621f5e4..67583de8218cf54213379f586926824f30da5350 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/security.h>
+#include <linux/evm.h>
 #include <linux/syscalls.h>
 #include <linux/module.h>
 #include <linux/fsnotify.h>
@@ -166,6 +167,64 @@ out_noalloc:
 }
 EXPORT_SYMBOL_GPL(xattr_getsecurity);
 
+/*
+ * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
+ *
+ * Allocate memory, if not already allocated, or re-allocate correct size,
+ * before retrieving the extended attribute.
+ *
+ * Returns the result of alloc, if failed, or the getxattr operation.
+ */
+ssize_t
+vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
+                  size_t xattr_size, gfp_t flags)
+{
+       struct inode *inode = dentry->d_inode;
+       char *value = *xattr_value;
+       int error;
+
+       error = xattr_permission(inode, name, MAY_READ);
+       if (error)
+               return error;
+
+       if (!inode->i_op->getxattr)
+               return -EOPNOTSUPP;
+
+       error = inode->i_op->getxattr(dentry, name, NULL, 0);
+       if (error < 0)
+               return error;
+
+       if (!value || (error > xattr_size)) {
+               value = krealloc(*xattr_value, error + 1, flags);
+               if (!value)
+                       return -ENOMEM;
+               memset(value, 0, error + 1);
+       }
+
+       error = inode->i_op->getxattr(dentry, name, value, error);
+       *xattr_value = value;
+       return error;
+}
+
+/* Compare an extended attribute value with the given value */
+int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
+                 const char *value, size_t size, gfp_t flags)
+{
+       char *xattr_value = NULL;
+       int rc;
+
+       rc = vfs_getxattr_alloc(dentry, xattr_name, &xattr_value, 0, flags);
+       if (rc < 0)
+               return rc;
+
+       if ((rc != size) || (memcmp(xattr_value, value, rc) != 0))
+               rc = -EINVAL;
+       else
+               rc = 0;
+       kfree(xattr_value);
+       return rc;
+}
+
 ssize_t
 vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
 {
@@ -243,8 +302,10 @@ vfs_removexattr(struct dentry *dentry, const char *name)
        error = inode->i_op->removexattr(dentry, name);
        mutex_unlock(&inode->i_mutex);
 
-       if (!error)
+       if (!error) {
                fsnotify_xattr(dentry);
+               evm_inode_post_removexattr(dentry, name);
+       }
        return error;
 }
 EXPORT_SYMBOL_GPL(vfs_removexattr);
index 75bb316529ddabb27855025fd59832bc4a52a4c8..427a4e82a588759dbfb49394f73eca9400d455e7 100644 (file)
 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
-ccflags-y := -I$(src) -I$(src)/linux-2.6
-ccflags-$(CONFIG_XFS_DEBUG) += -g
+ccflags-y += -I$(src)                  # needed for trace events
 
-XFS_LINUX := linux-2.6
+ccflags-$(CONFIG_XFS_DEBUG) += -g
 
 obj-$(CONFIG_XFS_FS)           += xfs.o
 
-xfs-y                          += linux-2.6/xfs_trace.o
-
-xfs-$(CONFIG_XFS_QUOTA)                += $(addprefix quota/, \
-                                  xfs_dquot.o \
-                                  xfs_dquot_item.o \
-                                  xfs_trans_dquot.o \
-                                  xfs_qm_syscalls.o \
-                                  xfs_qm_bhv.o \
-                                  xfs_qm.o)
-xfs-$(CONFIG_XFS_QUOTA)                += linux-2.6/xfs_quotaops.o
-
-ifeq ($(CONFIG_XFS_QUOTA),y)
-xfs-$(CONFIG_PROC_FS)          += quota/xfs_qm_stats.o
-endif
-
-xfs-$(CONFIG_XFS_RT)           += xfs_rtalloc.o
-xfs-$(CONFIG_XFS_POSIX_ACL)    += $(XFS_LINUX)/xfs_acl.o
-xfs-$(CONFIG_PROC_FS)          += $(XFS_LINUX)/xfs_stats.o
-xfs-$(CONFIG_SYSCTL)           += $(XFS_LINUX)/xfs_sysctl.o
-xfs-$(CONFIG_COMPAT)           += $(XFS_LINUX)/xfs_ioctl32.o
+# this one should be compiled first, as the tracing macros can easily blow up
+xfs-y                          += xfs_trace.o
 
+# highlevel code
+xfs-y                          += xfs_aops.o \
+                                  xfs_bit.o \
+                                  xfs_buf.o \
+                                  xfs_dfrag.o \
+                                  xfs_discard.o \
+                                  xfs_error.o \
+                                  xfs_export.o \
+                                  xfs_file.o \
+                                  xfs_filestream.o \
+                                  xfs_fsops.o \
+                                  xfs_fs_subr.o \
+                                  xfs_globals.o \
+                                  xfs_iget.o \
+                                  xfs_ioctl.o \
+                                  xfs_iomap.o \
+                                  xfs_iops.o \
+                                  xfs_itable.o \
+                                  xfs_message.o \
+                                  xfs_mru_cache.o \
+                                  xfs_super.o \
+                                  xfs_sync.o \
+                                  xfs_xattr.o \
+                                  xfs_rename.o \
+                                  xfs_rw.o \
+                                  xfs_utils.o \
+                                  xfs_vnodeops.o \
+                                  kmem.o \
+                                  uuid.o
 
+# code shared with libxfs
 xfs-y                          += xfs_alloc.o \
                                   xfs_alloc_btree.o \
                                   xfs_attr.o \
                                   xfs_attr_leaf.o \
-                                  xfs_bit.o \
                                   xfs_bmap.o \
                                   xfs_bmap_btree.o \
                                   xfs_btree.o \
-                                  xfs_buf_item.o \
                                   xfs_da_btree.o \
                                   xfs_dir2.o \
                                   xfs_dir2_block.o \
@@ -61,49 +70,37 @@ xfs-y                               += xfs_alloc.o \
                                   xfs_dir2_leaf.o \
                                   xfs_dir2_node.o \
                                   xfs_dir2_sf.o \
-                                  xfs_error.o \
-                                  xfs_extfree_item.o \
-                                  xfs_filestream.o \
-                                  xfs_fsops.o \
                                   xfs_ialloc.o \
                                   xfs_ialloc_btree.o \
-                                  xfs_iget.o \
                                   xfs_inode.o \
-                                  xfs_inode_item.o \
-                                  xfs_iomap.o \
-                                  xfs_itable.o \
-                                  xfs_dfrag.o \
-                                  xfs_log.o \
-                                  xfs_log_cil.o \
                                   xfs_log_recover.o \
                                   xfs_mount.o \
-                                  xfs_mru_cache.o \
-                                  xfs_rename.o \
-                                  xfs_trans.o \
+                                  xfs_trans.o
+
+# low-level transaction/log code
+xfs-y                          += xfs_log.o \
+                                  xfs_log_cil.o \
+                                  xfs_buf_item.o \
+                                  xfs_extfree_item.o \
+                                  xfs_inode_item.o \
                                   xfs_trans_ail.o \
                                   xfs_trans_buf.o \
                                   xfs_trans_extfree.o \
                                   xfs_trans_inode.o \
-                                  xfs_utils.o \
-                                  xfs_vnodeops.o \
-                                  xfs_rw.o
-
-# Objects in linux/
-xfs-y                          += $(addprefix $(XFS_LINUX)/, \
-                                  kmem.o \
-                                  xfs_aops.o \
-                                  xfs_buf.o \
-                                  xfs_discard.o \
-                                  xfs_export.o \
-                                  xfs_file.o \
-                                  xfs_fs_subr.o \
-                                  xfs_globals.o \
-                                  xfs_ioctl.o \
-                                  xfs_iops.o \
-                                  xfs_message.o \
-                                  xfs_super.o \
-                                  xfs_sync.o \
-                                  xfs_xattr.o)
 
-# Objects in support/
-xfs-y                          += support/uuid.o
+# optional features
+xfs-$(CONFIG_XFS_QUOTA)                += xfs_dquot.o \
+                                  xfs_dquot_item.o \
+                                  xfs_trans_dquot.o \
+                                  xfs_qm_syscalls.o \
+                                  xfs_qm_bhv.o \
+                                  xfs_qm.o \
+                                  xfs_quotaops.o
+ifeq ($(CONFIG_XFS_QUOTA),y)
+xfs-$(CONFIG_PROC_FS)          += xfs_qm_stats.o
+endif
+xfs-$(CONFIG_XFS_RT)           += xfs_rtalloc.o
+xfs-$(CONFIG_XFS_POSIX_ACL)    += xfs_acl.o
+xfs-$(CONFIG_PROC_FS)          += xfs_stats.o
+xfs-$(CONFIG_SYSCTL)           += xfs_sysctl.o
+xfs-$(CONFIG_COMPAT)           += xfs_ioctl32.o
similarity index 100%
rename from fs/xfs/linux-2.6/kmem.c
rename to fs/xfs/kmem.c
similarity index 100%
rename from fs/xfs/linux-2.6/kmem.h
rename to fs/xfs/kmem.h
similarity index 100%
rename from fs/xfs/linux-2.6/mrlock.h
rename to fs/xfs/mrlock.h
similarity index 100%
rename from fs/xfs/linux-2.6/time.h
rename to fs/xfs/time.h
similarity index 100%
rename from fs/xfs/support/uuid.c
rename to fs/xfs/uuid.c
similarity index 100%
rename from fs/xfs/support/uuid.h
rename to fs/xfs/uuid.h
index 53ec3ea9a625f40e36a16d7950e624e198836ee7..d8b11b7f94aae5bf7f591037d1fc07eaf79e7c25 100644 (file)
@@ -24,5 +24,6 @@
 #define XFS_BUF_LOCK_TRACKING 1
 #endif
 
-#include <linux-2.6/xfs_linux.h>
+#include "xfs_linux.h"
+
 #endif /* __XFS_H__ */
similarity index 100%
rename from fs/xfs/linux-2.6/xfs_acl.c
rename to fs/xfs/xfs_acl.c
similarity index 99%
rename from fs/xfs/linux-2.6/xfs_buf.c
rename to fs/xfs/xfs_buf.c
index c57836dc778f9c9263770516ba0248dfe20c8aab..9b6c2234622e2a5ee1d28b86d31dfef81371c730 100644 (file)
@@ -1741,7 +1741,7 @@ xfsbufd(
 
                if (unlikely(freezing(current))) {
                        set_bit(XBT_FORCE_SLEEP, &target->bt_flags);
-                       refrigerator();
+                       try_to_freeze();
                } else {
                        clear_bit(XBT_FORCE_SLEEP, &target->bt_flags);
                }
similarity index 100%
rename from fs/xfs/linux-2.6/xfs_buf.h
rename to fs/xfs/xfs_buf.h
similarity index 100%
rename from fs/xfs/quota/xfs_dquot.c
rename to fs/xfs/xfs_dquot.c
similarity index 100%
rename from fs/xfs/quota/xfs_dquot.h
rename to fs/xfs/xfs_dquot.h
similarity index 98%
rename from fs/xfs/linux-2.6/xfs_iops.c
rename to fs/xfs/xfs_iops.c
index b9c172b3fbbec1c6b8ac2874151f0bb1aa19240d..37194607162d38c326804c5e55a279e4124aa975 100644 (file)
@@ -94,37 +94,38 @@ xfs_mark_inode_dirty(
                mark_inode_dirty(inode);
 }
 
+
+int xfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
+                  void *fs_info)
+{
+       const struct xattr *xattr;
+       struct xfs_inode *ip = XFS_I(inode);
+       int error = 0;
+
+       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
+               error = xfs_attr_set(ip, xattr->name, xattr->value,
+                                    xattr->value_len, ATTR_SECURE);
+               if (error < 0)
+                       break;
+       }
+       return error;
+}
+
 /*
  * Hook in SELinux.  This is not quite correct yet, what we really need
  * here (as we do for default ACLs) is a mechanism by which creation of
  * these attrs can be journalled at inode creation time (along with the
  * inode, of course, such that log replay can't cause these to be lost).
  */
+
 STATIC int
 xfs_init_security(
        struct inode    *inode,
        struct inode    *dir,
        const struct qstr *qstr)
 {
-       struct xfs_inode *ip = XFS_I(inode);
-       size_t          length;
-       void            *value;
-       unsigned char   *name;
-       int             error;
-
-       error = security_inode_init_security(inode, dir, qstr, (char **)&name,
-                                            &value, &length);
-       if (error) {
-               if (error == -EOPNOTSUPP)
-                       return 0;
-               return -error;
-       }
-
-       error = xfs_attr_set(ip, name, value, length, ATTR_SECURE);
-
-       kfree(name);
-       kfree(value);
-       return error;
+       return security_inode_init_security(inode, dir, qstr,
+                                           &xfs_initxattrs, NULL);
 }
 
 static void
similarity index 96%
rename from fs/xfs/linux-2.6/xfs_linux.h
rename to fs/xfs/xfs_linux.h
index d42f814e4d35530dd4b65e5f38801edad18746cd..1e8a45e74c3e5826db4bc56c9260e0af583d6262 100644 (file)
 # define XFS_BIG_INUMS 0
 #endif
 
-#include <xfs_types.h>
+#include "xfs_types.h"
 
-#include <kmem.h>
-#include <mrlock.h>
-#include <time.h>
-
-#include <support/uuid.h>
+#include "kmem.h"
+#include "mrlock.h"
+#include "time.h"
+#include "uuid.h"
 
 #include <linux/semaphore.h>
 #include <linux/mm.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
-#include <xfs_vnode.h>
-#include <xfs_stats.h>
-#include <xfs_sysctl.h>
-#include <xfs_iops.h>
-#include <xfs_aops.h>
-#include <xfs_super.h>
-#include <xfs_buf.h>
-#include <xfs_message.h>
+#include "xfs_vnode.h"
+#include "xfs_stats.h"
+#include "xfs_sysctl.h"
+#include "xfs_iops.h"
+#include "xfs_aops.h"
+#include "xfs_super.h"
+#include "xfs_buf.h"
+#include "xfs_message.h"
 
 #ifdef __BIG_ENDIAN
 #define XFS_NATIVE_HOST 1
similarity index 100%
rename from fs/xfs/quota/xfs_qm.c
rename to fs/xfs/xfs_qm.c
similarity index 100%
rename from fs/xfs/quota/xfs_qm.h
rename to fs/xfs/xfs_qm.h
similarity index 99%
rename from fs/xfs/linux-2.6/xfs_quotaops.c
rename to fs/xfs/xfs_quotaops.c
index 29b9d642e93d08123ddf1db5a01e1edddd1ee17b..7e76f537abb74022fc2077f136d5d5ec6828cfba 100644 (file)
@@ -25,7 +25,7 @@
 #include "xfs_trans.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_inode.h"
-#include "quota/xfs_qm.h"
+#include "xfs_qm.h"
 #include <linux/quota.h>
 
 
similarity index 96%
rename from fs/xfs/linux-2.6/xfs_trace.c
rename to fs/xfs/xfs_trace.c
index 88d25d4aa56ec34b0a9039af8d52d567c478a429..9010ce885e6ae3681df24f0575f3f308ef03db96 100644 (file)
@@ -43,8 +43,8 @@
 #include "xfs_quota.h"
 #include "xfs_iomap.h"
 #include "xfs_aops.h"
-#include "quota/xfs_dquot_item.h"
-#include "quota/xfs_dquot.h"
+#include "xfs_dquot_item.h"
+#include "xfs_dquot.h"
 #include "xfs_log_recover.h"
 #include "xfs_inode_item.h"
 
index 069e85ba97e1874a6f92cb98dc0f4794e8969249..c6c9c1fe460c20e1d11e923c500a872f225d3c29 100644 (file)
@@ -82,4 +82,9 @@ struct sha512_state {
        u8 buf[SHA512_BLOCK_SIZE];
 };
 
+struct shash_desc;
+
+extern int crypto_sha1_update(struct shash_desc *desc, const u8 *data,
+                             unsigned int len);
+
 #endif
index 3e09b345f4d675ffddcab95e6d6b72039d141237..4c7a4b2104bfc6b105f5258763fda8f0fa6685df 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __LINUX_ATMEL_MCI_H
 #define __LINUX_ATMEL_MCI_H
 
-#define ATMEL_MCI_MAX_NR_SLOTS 2
+#define ATMCI_MAX_NR_SLOTS     2
 
 /**
  * struct mci_slot_pdata - board-specific per-slot configuration
@@ -33,7 +33,7 @@ struct mci_slot_pdata {
  */
 struct mci_platform_data {
        struct mci_dma_data     *dma_slave;
-       struct mci_slot_pdata   slot[ATMEL_MCI_MAX_NR_SLOTS];
+       struct mci_slot_pdata   slot[ATMCI_MAX_NR_SLOTS];
 };
 
 #endif /* __LINUX_ATMEL_MCI_H */
index 5058a31d2ce8d19ff297ea1d71464e56b146c3ba..63499ce806eaf984c00bbc93b2fb018e5b3de999 100644 (file)
@@ -33,4 +33,6 @@
 
 #define ATMEL_PDC_PTSR         0x124   /* Transfer Status Register */
 
+#define ATMEL_PDC_SCND_BUF_OFF 0x10    /* Offset between first and second buffer registers */
+
 #endif
index 8c96654bef16bb8cba98267f2f0e1a42e13e47bc..5dbd7055cb86204c6cd8d2d18f5709c4e6604c1e 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/bcma/bcma_driver_chipcommon.h>
 #include <linux/bcma/bcma_driver_pci.h>
+#include <linux/bcma/bcma_driver_mips.h>
 #include <linux/ssb/ssb.h> /* SPROM sharing */
 
 #include "bcma_regs.h"
@@ -14,9 +15,9 @@ struct bcma_device;
 struct bcma_bus;
 
 enum bcma_hosttype {
-       BCMA_HOSTTYPE_NONE,
        BCMA_HOSTTYPE_PCI,
        BCMA_HOSTTYPE_SDIO,
+       BCMA_HOSTTYPE_SOC,
 };
 
 struct bcma_chipinfo {
@@ -130,6 +131,7 @@ struct bcma_device {
 
        struct device dev;
        struct device *dma_dev;
+
        unsigned int irq;
        bool dev_registered;
 
@@ -138,6 +140,9 @@ struct bcma_device {
        u32 addr;
        u32 wrap;
 
+       void __iomem *io_addr;
+       void __iomem *io_wrap;
+
        void *drvdata;
        struct list_head list;
 };
@@ -190,9 +195,11 @@ struct bcma_bus {
        struct bcma_device *mapped_core;
        struct list_head cores;
        u8 nr_cores;
+       u8 init_done:1;
 
        struct bcma_drv_cc drv_cc;
        struct bcma_drv_pci drv_pci;
+       struct bcma_drv_mips drv_mips;
 
        /* We decided to share SPROM struct with SSB as long as we do not need
         * any hacks for BCMA. This simplifies drivers code. */
index a0f684615ae561a6c1cc241808512655533ee420..a7ae33d06f246006f56a39b2a84adc40a0114c59 100644 (file)
@@ -24,6 +24,7 @@
 #define   BCMA_CC_FLASHT_NONE          0x00000000      /* No flash */
 #define   BCMA_CC_FLASHT_STSER         0x00000100      /* ST serial flash */
 #define   BCMA_CC_FLASHT_ATSER         0x00000200      /* Atmel serial flash */
+#define   BCMA_CC_FLASHT_NFLASH                0x00000200
 #define          BCMA_CC_FLASHT_PARA           0x00000700      /* Parallel flash */
 #define  BCMA_CC_CAP_PLLT              0x00038000      /* PLL Type */
 #define   BCMA_PLLTYPE_NONE            0x00000000
 #define BCMA_CC_PROG_CFG               0x0120
 #define BCMA_CC_PROG_WAITCNT           0x0124
 #define BCMA_CC_FLASH_CFG              0x0128
+#define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
 #define BCMA_CC_FLASH_WAITCNT          0x012C
 /* 0x1E0 is defined as shared BCMA_CLKCTLST */
 #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
 #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
 #define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
 
+/* Divider allocation in 4716/47162/5356 */
+#define BCMA_CC_PMU5_MAINPLL_CPU       1
+#define BCMA_CC_PMU5_MAINPLL_MEM       2
+#define BCMA_CC_PMU5_MAINPLL_SSB       3
+
+/* PLL usage in 4716/47162 */
+#define BCMA_CC_PMU4716_MAINPLL_PLL0   12
+
+/* PLL usage in 5356/5357 */
+#define BCMA_CC_PMU5356_MAINPLL_PLL0   0
+#define BCMA_CC_PMU5357_MAINPLL_PLL0   0
+
+/* 4706 PMU */
+#define BCMA_CC_PMU4706_MAINPLL_PLL0   0
+
+/* ALP clock on pre-PMU chips */
+#define BCMA_CC_PMU_ALP_CLOCK          20000000
+/* HT clock for systems with PMU-enabled chipcommon */
+#define BCMA_CC_PMU_HT_CLOCK           80000000
+
+/* PMU rev 5 (& 6) */
+#define BCMA_CC_PPL_P1P2_OFF           0
+#define BCMA_CC_PPL_P1_MASK            0x0f000000
+#define BCMA_CC_PPL_P1_SHIFT           24
+#define BCMA_CC_PPL_P2_MASK            0x00f00000
+#define BCMA_CC_PPL_P2_SHIFT           20
+#define BCMA_CC_PPL_M14_OFF            1
+#define BCMA_CC_PPL_MDIV_MASK          0x000000ff
+#define BCMA_CC_PPL_MDIV_WIDTH         8
+#define BCMA_CC_PPL_NM5_OFF            2
+#define BCMA_CC_PPL_NDIV_MASK          0xfff00000
+#define BCMA_CC_PPL_NDIV_SHIFT         20
+#define BCMA_CC_PPL_FMAB_OFF           3
+#define BCMA_CC_PPL_MRAT_MASK          0xf0000000
+#define BCMA_CC_PPL_MRAT_SHIFT         28
+#define BCMA_CC_PPL_ABRAT_MASK         0x08000000
+#define BCMA_CC_PPL_ABRAT_SHIFT                27
+#define BCMA_CC_PPL_FDIV_MASK          0x07ffffff
+#define BCMA_CC_PPL_PLLCTL_OFF         4
+#define BCMA_CC_PPL_PCHI_OFF           5
+#define BCMA_CC_PPL_PCHI_MASK          0x0000003f
+
+/* BCM4331 ChipControl numbers. */
+#define BCMA_CHIPCTL_4331_BT_COEXIST           BIT(0)  /* 0 disable */
+#define BCMA_CHIPCTL_4331_SECI                 BIT(1)  /* 0 SECI is disabled (JATG functional) */
+#define BCMA_CHIPCTL_4331_EXT_LNA              BIT(2)  /* 0 disable */
+#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15      BIT(3)  /* sprom/gpio13-15 mux */
+#define BCMA_CHIPCTL_4331_EXTPA_EN             BIT(4)  /* 0 ext pa disable, 1 ext pa enabled */
+#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS   BIT(5)  /* set drive out GPIO_CLK on sprom_cs pin */
+#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6)  /* use sprom_cs pin as PCIE mdio interface */
+#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5     BIT(7)  /* aband extpa will be at gpio2/5 and sprom_dout */
+#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN     BIT(8)  /* override core control on pipe_AuxClkEnable */
+#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN   BIT(9)  /* override core control on pipe_AuxPowerDown */
+#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN                BIT(10) /* pcie_auxclkenable */
+#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN    BIT(11) /* pcie_pipe_pllpowerdown */
+#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4     BIT(16) /* enable bt_shd0 at gpio4 */
+#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5     BIT(17) /* enable bt_shd1 at gpio5 */
+
 /* Data for the PMU, if available.
  * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
  */
@@ -247,14 +307,37 @@ struct bcma_chipcommon_pmu {
        u32 crystalfreq;        /* The active crystal frequency (in kHz) */
 };
 
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+struct bcma_pflash {
+       u8 buswidth;
+       u32 window;
+       u32 window_size;
+};
+
+struct bcma_serial_port {
+       void *regs;
+       unsigned long clockspeed;
+       unsigned int irq;
+       unsigned int baud_base;
+       unsigned int reg_shift;
+};
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
+
 struct bcma_drv_cc {
        struct bcma_device *core;
        u32 status;
        u32 capabilities;
        u32 capabilities_ext;
+       u8 setup_done:1;
        /* Fast Powerup Delay constant */
        u16 fast_pwrup_delay;
        struct bcma_chipcommon_pmu pmu;
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+       struct bcma_pflash pflash;
+
+       int nr_serial_ports;
+       struct bcma_serial_port serial_ports[4];
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
 };
 
 /* Register access */
@@ -275,6 +358,8 @@ extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
 
+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
+
 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
                                          u32 ticks);
 
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
new file mode 100644 (file)
index 0000000..c004364
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef LINUX_BCMA_DRIVER_MIPS_H_
+#define LINUX_BCMA_DRIVER_MIPS_H_
+
+#define BCMA_MIPS_IPSFLAG              0x0F08
+/* which sbflags get routed to mips interrupt 1 */
+#define  BCMA_MIPS_IPSFLAG_IRQ1                0x0000003F
+#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT  0
+/* which sbflags get routed to mips interrupt 2 */
+#define  BCMA_MIPS_IPSFLAG_IRQ2                0x00003F00
+#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT  8
+/* which sbflags get routed to mips interrupt 3 */
+#define  BCMA_MIPS_IPSFLAG_IRQ3                0x003F0000
+#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT  16
+/* which sbflags get routed to mips interrupt 4 */
+#define  BCMA_MIPS_IPSFLAG_IRQ4                0x3F000000
+#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT  24
+
+/* MIPS 74K core registers */
+#define BCMA_MIPS_MIPS74K_CORECTL      0x0000
+#define BCMA_MIPS_MIPS74K_EXCEPTBASE   0x0004
+#define BCMA_MIPS_MIPS74K_BIST         0x000C
+#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
+#define BCMA_MIPS_MIPS74K_INTMASK(int) \
+       ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
+#define BCMA_MIPS_MIPS74K_NMIMASK      0x002C
+#define BCMA_MIPS_MIPS74K_GPIOSEL      0x0040
+#define BCMA_MIPS_MIPS74K_GPIOOUT      0x0044
+#define BCMA_MIPS_MIPS74K_GPIOEN       0x0048
+#define BCMA_MIPS_MIPS74K_CLKCTLST     0x01E0
+
+#define BCMA_MIPS_OOBSELOUTA30         0x100
+
+struct bcma_device;
+
+struct bcma_drv_mips {
+       struct bcma_device *core;
+       u8 setup_done:1;
+       unsigned int assigned_irqs;
+};
+
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
+#else
+static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
+#endif
+
+extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
+
+extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
+
+#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h
new file mode 100644 (file)
index 0000000..4203c55
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef LINUX_BCMA_SOC_H_
+#define LINUX_BCMA_SOC_H_
+
+#include <linux/bcma/bcma.h>
+
+struct bcma_soc {
+       struct bcma_bus bus;
+       struct bcma_device core_cc;
+       struct bcma_device core_mips;
+};
+
+int __init bcma_host_soc_register(struct bcma_soc *soc);
+
+int bcma_bus_register(struct bcma_bus *bus);
+
+#endif /* LINUX_BCMA_SOC_H_ */
diff --git a/include/linux/bma150.h b/include/linux/bma150.h
new file mode 100644 (file)
index 0000000..7911fda
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011 Bosch Sensortec GmbH
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _BMA150_H_
+#define _BMA150_H_
+
+#define BMA150_DRIVER          "bma150"
+
+struct bma150_cfg {
+       bool any_motion_int;            /* Set to enable any-motion interrupt */
+       bool hg_int;                    /* Set to enable high-G interrupt */
+       bool lg_int;                    /* Set to enable low-G interrupt */
+       unsigned char any_motion_dur;   /* Any-motion duration */
+       unsigned char any_motion_thres; /* Any-motion threshold */
+       unsigned char hg_hyst;          /* High-G hysterisis */
+       unsigned char hg_dur;           /* High-G duration */
+       unsigned char hg_thres;         /* High-G threshold */
+       unsigned char lg_hyst;          /* Low-G hysterisis */
+       unsigned char lg_dur;           /* Low-G duration */
+       unsigned char lg_thres;         /* Low-G threshold */
+       unsigned char range;            /* BMA0150_RANGE_xxx (in G) */
+       unsigned char bandwidth;        /* BMA0150_BW_xxx (in Hz) */
+};
+
+struct bma150_platform_data {
+       struct bma150_cfg cfg;
+       int (*irq_gpio_cfg)(void);
+};
+
+#endif /* _BMA150_H_ */
index 563755181c1ea33e7a4c8ff99565704b5432d566..95bd8502e715e48f8222345e1274761fee030662 100644 (file)
@@ -215,7 +215,9 @@ extern void ceph_destroy_options(struct ceph_options *opt);
 extern int ceph_compare_options(struct ceph_options *new_opt,
                                struct ceph_client *client);
 extern struct ceph_client *ceph_create_client(struct ceph_options *opt,
-                                             void *private);
+                                             void *private,
+                                             unsigned supported_features,
+                                             unsigned required_features);
 extern u64 ceph_client_id(struct ceph_client *client);
 extern void ceph_destroy_client(struct ceph_client *client);
 extern int __ceph_open_session(struct ceph_client *client,
index d7adf151d3351c4fb315952231c7768a6e6c9cf7..bbd4a4bb2c6bc53f8161c216c7f44447315f8db1 100644 (file)
@@ -238,7 +238,8 @@ extern void ceph_con_keepalive(struct ceph_connection *con);
 extern struct ceph_connection *ceph_con_get(struct ceph_connection *con);
 extern void ceph_con_put(struct ceph_connection *con);
 
-extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags);
+extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
+                                    bool can_fail);
 extern void ceph_msg_kfree(struct ceph_msg *m);
 
 
index 74054074e876d8da1ae9de24dc8ae64f856391c7..5c4abce94ad1665803c79fd61a501e6969477029 100644 (file)
@@ -10,6 +10,7 @@
 #define ELFCORE_ADDR_ERR       (-2ULL)
 
 extern unsigned long long elfcorehdr_addr;
+extern unsigned long long elfcorehdr_size;
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
                                                unsigned long, int);
index 3fa1f3d90ce0e21cb3ba27fa98d3201252f91f8e..e46e91080f8608f1d5c09eeee186028899c8c570 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/ratelimit.h>
 
 struct dm_dev;
 struct dm_target;
@@ -127,10 +128,6 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d);
  * Information about a target type
  */
 
-/*
- * Target features
- */
-
 struct target_type {
        uint64_t features;
        const char *name;
@@ -159,6 +156,20 @@ struct target_type {
        struct list_head list;
 };
 
+/*
+ * Target features
+ */
+
+/*
+ * Any table that contains an instance of this target must have only one.
+ */
+#define DM_TARGET_SINGLETON            0x00000001
+#define dm_target_needs_singleton(type)        ((type)->features & DM_TARGET_SINGLETON)
+
+#define DM_TARGET_ALWAYS_WRITEABLE     0x00000002
+#define dm_target_always_writeable(type) \
+               ((type)->features & DM_TARGET_ALWAYS_WRITEABLE)
+
 struct dm_target {
        struct dm_table *table;
        struct target_type *type;
@@ -197,6 +208,11 @@ struct dm_target {
         * whether or not its underlying devices have support.
         */
        unsigned discards_supported:1;
+
+       /*
+        * Set if this target does not return zeroes on discarded blocks.
+        */
+       unsigned discard_zeroes_data_unsupported:1;
 };
 
 /* Each target can link one of these into the table */
@@ -370,6 +386,14 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
  *---------------------------------------------------------------*/
 #define DM_NAME "device-mapper"
 
+#ifdef CONFIG_PRINTK
+extern struct ratelimit_state dm_ratelimit_state;
+
+#define dm_ratelimit() __ratelimit(&dm_ratelimit_state)
+#else
+#define dm_ratelimit() 0
+#endif
+
 #define DMCRIT(f, arg...) \
        printk(KERN_CRIT DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 
@@ -377,7 +401,7 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
        printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMERR_LIMIT(f, arg...) \
        do { \
-               if (printk_ratelimit()) \
+               if (dm_ratelimit())     \
                        printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " \
                               f "\n", ## arg); \
        } while (0)
@@ -386,7 +410,7 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
        printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMWARN_LIMIT(f, arg...) \
        do { \
-               if (printk_ratelimit()) \
+               if (dm_ratelimit())     \
                        printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " \
                               f "\n", ## arg); \
        } while (0)
@@ -395,7 +419,7 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
        printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMINFO_LIMIT(f, arg...) \
        do { \
-               if (printk_ratelimit()) \
+               if (dm_ratelimit())     \
                        printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f \
                               "\n", ## arg); \
        } while (0)
@@ -405,7 +429,7 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
        printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
 #  define DMDEBUG_LIMIT(f, arg...) \
        do { \
-               if (printk_ratelimit()) \
+               if (dm_ratelimit())     \
                        printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX ": " f \
                               "\n", ## arg); \
        } while (0)
index c20dfbfc49b425b39794011ab0fed4d226c4ad50..e36e2e9aa0ced5e5e9477ce2c0f729d2a3ac45b8 100644 (file)
@@ -636,6 +636,11 @@ static inline void set_dev_node(struct device *dev, int node)
 }
 #endif
 
+static inline struct pm_subsys_data *dev_to_psd(struct device *dev)
+{
+       return dev ? dev->power.subsys_data : NULL;
+}
+
 static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
 {
        return dev->kobj.uevent_suppress;
@@ -785,6 +790,8 @@ extern const char *dev_driver_string(const struct device *dev);
 
 #ifdef CONFIG_PRINTK
 
+extern int __dev_printk(const char *level, const struct device *dev,
+                       struct va_format *vaf);
 extern int dev_printk(const char *level, const struct device *dev,
                      const char *fmt, ...)
        __attribute__ ((format (printf, 3, 4)));
@@ -805,6 +812,9 @@ extern int _dev_info(const struct device *dev, const char *fmt, ...)
 
 #else
 
+static inline int __dev_printk(const char *level, const struct device *dev,
+                              struct va_format *vaf)
+        { return 0; }
 static inline int dev_printk(const char *level, const struct device *dev,
                      const char *fmt, ...)
        __attribute__ ((format (printf, 3, 4)));
index 5e54458e920f36466a29d83ccbe913a03f347a01..47d9d376e4e7a9e0cecb609065b3d735825cfdb9 100644 (file)
@@ -57,5 +57,9 @@ void *dm_kcopyd_prepare_callback(struct dm_kcopyd_client *kc,
                                 dm_kcopyd_notify_fn fn, void *context);
 void dm_kcopyd_do_callback(void *job, int read_err, unsigned long write_err);
 
+int dm_kcopyd_zero(struct dm_kcopyd_client *kc,
+                  unsigned num_dests, struct dm_io_region *dests,
+                  unsigned flags, dm_kcopyd_notify_fn fn, void *context);
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_DM_KCOPYD_H */
index 8fbf40e0713cfc9a4dd7ec64bc66010a42afc644..ace51af4369f668ea647f47c2d87f76d4478b121 100644 (file)
@@ -24,8 +24,7 @@
 #include <linux/device.h>
 #include <linux/uio.h>
 #include <linux/dma-direction.h>
-
-struct scatterlist;
+#include <linux/scatterlist.h>
 
 /**
  * typedef dma_cookie_t - an opaque DMA cookie
@@ -519,6 +518,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
                        (unsigned long)config);
 }
 
+static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
+       struct dma_chan *chan, void *buf, size_t len,
+       enum dma_data_direction dir, unsigned long flags)
+{
+       struct scatterlist sg;
+       sg_init_one(&sg, buf, len);
+
+       return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
+}
+
 static inline int dmaengine_terminate_all(struct dma_chan *chan)
 {
        return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
index e747ecd48e1c043a87549cb2cdab62e04e1edbf5..feaac1ee300178cbd70665bf04be04200cd2015b 100644 (file)
@@ -1,13 +1,6 @@
 #ifndef _DYNAMIC_DEBUG_H
 #define _DYNAMIC_DEBUG_H
 
-/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
- * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
- * use independent hash functions, to reduce the chance of false positives.
- */
-extern long long dynamic_debug_enabled;
-extern long long dynamic_debug_enabled2;
-
 /*
  * An instance of this structure is created in a special
  * ELF section at every dynamic debug callsite.  At runtime,
@@ -47,6 +40,20 @@ extern int ddebug_remove_module(const char *mod_name);
 extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
        __attribute__ ((format (printf, 2, 3)));
 
+struct device;
+
+extern int __dynamic_dev_dbg(struct _ddebug *descriptor,
+                            const struct device *dev,
+                            const char *fmt, ...)
+       __attribute__ ((format (printf, 3, 4)));
+
+struct net_device;
+
+extern int __dynamic_netdev_dbg(struct _ddebug *descriptor,
+                            const struct net_device *dev,
+                            const char *fmt, ...)
+       __attribute__ ((format (printf, 3, 4)));
+
 #define dynamic_pr_debug(fmt, ...) do {                                        \
        static struct _ddebug descriptor                                \
        __used                                                          \
@@ -57,7 +64,6 @@ extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
                __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
        } while (0)
 
-
 #define dynamic_dev_dbg(dev, fmt, ...) do {                            \
        static struct _ddebug descriptor                                \
        __used                                                          \
@@ -65,7 +71,17 @@ extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
        { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__,            \
                _DPRINTK_FLAGS_DEFAULT };                               \
        if (unlikely(descriptor.enabled))                               \
-               dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__);        \
+               __dynamic_dev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__);        \
+       } while (0)
+
+#define dynamic_netdev_dbg(dev, fmt, ...) do {                         \
+       static struct _ddebug descriptor                                \
+       __used                                                          \
+       __attribute__((section("__verbose"), aligned(8))) =             \
+       { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__,            \
+               _DPRINTK_FLAGS_DEFAULT };                               \
+       if (unlikely(descriptor.enabled))                               \
+               __dynamic_netdev_dbg(&descriptor, dev, fmt, ##__VA_ARGS__);\
        } while (0)
 
 #else
index 4a73257b47d0cca22e1f33cdb47a8075eb1a358c..055b248bdd5328dfbac8e59836563771eb8fcd58 100644 (file)
@@ -42,4 +42,354 @@ static inline void opstate_init(void)
        return;
 }
 
+#define EDAC_MC_LABEL_LEN      31
+#define MC_PROC_NAME_MAX_LEN   7
+
+/* memory devices */
+enum dev_type {
+       DEV_UNKNOWN = 0,
+       DEV_X1,
+       DEV_X2,
+       DEV_X4,
+       DEV_X8,
+       DEV_X16,
+       DEV_X32,                /* Do these parts exist? */
+       DEV_X64                 /* Do these parts exist? */
+};
+
+#define DEV_FLAG_UNKNOWN       BIT(DEV_UNKNOWN)
+#define DEV_FLAG_X1            BIT(DEV_X1)
+#define DEV_FLAG_X2            BIT(DEV_X2)
+#define DEV_FLAG_X4            BIT(DEV_X4)
+#define DEV_FLAG_X8            BIT(DEV_X8)
+#define DEV_FLAG_X16           BIT(DEV_X16)
+#define DEV_FLAG_X32           BIT(DEV_X32)
+#define DEV_FLAG_X64           BIT(DEV_X64)
+
+/* memory types */
+enum mem_type {
+       MEM_EMPTY = 0,          /* Empty csrow */
+       MEM_RESERVED,           /* Reserved csrow type */
+       MEM_UNKNOWN,            /* Unknown csrow type */
+       MEM_FPM,                /* Fast page mode */
+       MEM_EDO,                /* Extended data out */
+       MEM_BEDO,               /* Burst Extended data out */
+       MEM_SDR,                /* Single data rate SDRAM */
+       MEM_RDR,                /* Registered single data rate SDRAM */
+       MEM_DDR,                /* Double data rate SDRAM */
+       MEM_RDDR,               /* Registered Double data rate SDRAM */
+       MEM_RMBS,               /* Rambus DRAM */
+       MEM_DDR2,               /* DDR2 RAM */
+       MEM_FB_DDR2,            /* fully buffered DDR2 */
+       MEM_RDDR2,              /* Registered DDR2 RAM */
+       MEM_XDR,                /* Rambus XDR */
+       MEM_DDR3,               /* DDR3 RAM */
+       MEM_RDDR3,              /* Registered DDR3 RAM */
+};
+
+#define MEM_FLAG_EMPTY         BIT(MEM_EMPTY)
+#define MEM_FLAG_RESERVED      BIT(MEM_RESERVED)
+#define MEM_FLAG_UNKNOWN       BIT(MEM_UNKNOWN)
+#define MEM_FLAG_FPM           BIT(MEM_FPM)
+#define MEM_FLAG_EDO           BIT(MEM_EDO)
+#define MEM_FLAG_BEDO          BIT(MEM_BEDO)
+#define MEM_FLAG_SDR           BIT(MEM_SDR)
+#define MEM_FLAG_RDR           BIT(MEM_RDR)
+#define MEM_FLAG_DDR           BIT(MEM_DDR)
+#define MEM_FLAG_RDDR          BIT(MEM_RDDR)
+#define MEM_FLAG_RMBS          BIT(MEM_RMBS)
+#define MEM_FLAG_DDR2           BIT(MEM_DDR2)
+#define MEM_FLAG_FB_DDR2        BIT(MEM_FB_DDR2)
+#define MEM_FLAG_RDDR2          BIT(MEM_RDDR2)
+#define MEM_FLAG_XDR            BIT(MEM_XDR)
+#define MEM_FLAG_DDR3           BIT(MEM_DDR3)
+#define MEM_FLAG_RDDR3          BIT(MEM_RDDR3)
+
+/* chipset Error Detection and Correction capabilities and mode */
+enum edac_type {
+       EDAC_UNKNOWN = 0,       /* Unknown if ECC is available */
+       EDAC_NONE,              /* Doesn't support ECC */
+       EDAC_RESERVED,          /* Reserved ECC type */
+       EDAC_PARITY,            /* Detects parity errors */
+       EDAC_EC,                /* Error Checking - no correction */
+       EDAC_SECDED,            /* Single bit error correction, Double detection */
+       EDAC_S2ECD2ED,          /* Chipkill x2 devices - do these exist? */
+       EDAC_S4ECD4ED,          /* Chipkill x4 devices */
+       EDAC_S8ECD8ED,          /* Chipkill x8 devices */
+       EDAC_S16ECD16ED,        /* Chipkill x16 devices */
+};
+
+#define EDAC_FLAG_UNKNOWN      BIT(EDAC_UNKNOWN)
+#define EDAC_FLAG_NONE         BIT(EDAC_NONE)
+#define EDAC_FLAG_PARITY       BIT(EDAC_PARITY)
+#define EDAC_FLAG_EC           BIT(EDAC_EC)
+#define EDAC_FLAG_SECDED       BIT(EDAC_SECDED)
+#define EDAC_FLAG_S2ECD2ED     BIT(EDAC_S2ECD2ED)
+#define EDAC_FLAG_S4ECD4ED     BIT(EDAC_S4ECD4ED)
+#define EDAC_FLAG_S8ECD8ED     BIT(EDAC_S8ECD8ED)
+#define EDAC_FLAG_S16ECD16ED   BIT(EDAC_S16ECD16ED)
+
+/* scrubbing capabilities */
+enum scrub_type {
+       SCRUB_UNKNOWN = 0,      /* Unknown if scrubber is available */
+       SCRUB_NONE,             /* No scrubber */
+       SCRUB_SW_PROG,          /* SW progressive (sequential) scrubbing */
+       SCRUB_SW_SRC,           /* Software scrub only errors */
+       SCRUB_SW_PROG_SRC,      /* Progressive software scrub from an error */
+       SCRUB_SW_TUNABLE,       /* Software scrub frequency is tunable */
+       SCRUB_HW_PROG,          /* HW progressive (sequential) scrubbing */
+       SCRUB_HW_SRC,           /* Hardware scrub only errors */
+       SCRUB_HW_PROG_SRC,      /* Progressive hardware scrub from an error */
+       SCRUB_HW_TUNABLE        /* Hardware scrub frequency is tunable */
+};
+
+#define SCRUB_FLAG_SW_PROG     BIT(SCRUB_SW_PROG)
+#define SCRUB_FLAG_SW_SRC      BIT(SCRUB_SW_SRC)
+#define SCRUB_FLAG_SW_PROG_SRC BIT(SCRUB_SW_PROG_SRC)
+#define SCRUB_FLAG_SW_TUN      BIT(SCRUB_SW_SCRUB_TUNABLE)
+#define SCRUB_FLAG_HW_PROG     BIT(SCRUB_HW_PROG)
+#define SCRUB_FLAG_HW_SRC      BIT(SCRUB_HW_SRC)
+#define SCRUB_FLAG_HW_PROG_SRC BIT(SCRUB_HW_PROG_SRC)
+#define SCRUB_FLAG_HW_TUN      BIT(SCRUB_HW_TUNABLE)
+
+/* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */
+
+/* EDAC internal operation states */
+#define        OP_ALLOC                0x100
+#define OP_RUNNING_POLL                0x201
+#define OP_RUNNING_INTERRUPT   0x202
+#define OP_RUNNING_POLL_INTR   0x203
+#define OP_OFFLINE             0x300
+
+/*
+ * There are several things to be aware of that aren't at all obvious:
+ *
+ *
+ * SOCKETS, SOCKET SETS, BANKS, ROWS, CHIP-SELECT ROWS, CHANNELS, etc..
+ *
+ * These are some of the many terms that are thrown about that don't always
+ * mean what people think they mean (Inconceivable!).  In the interest of
+ * creating a common ground for discussion, terms and their definitions
+ * will be established.
+ *
+ * Memory devices:     The individual chip on a memory stick.  These devices
+ *                     commonly output 4 and 8 bits each.  Grouping several
+ *                     of these in parallel provides 64 bits which is common
+ *                     for a memory stick.
+ *
+ * Memory Stick:       A printed circuit board that aggregates multiple
+ *                     memory devices in parallel.  This is the atomic
+ *                     memory component that is purchaseable by Joe consumer
+ *                     and loaded into a memory socket.
+ *
+ * Socket:             A physical connector on the motherboard that accepts
+ *                     a single memory stick.
+ *
+ * Channel:            Set of memory devices on a memory stick that must be
+ *                     grouped in parallel with one or more additional
+ *                     channels from other memory sticks.  This parallel
+ *                     grouping of the output from multiple channels are
+ *                     necessary for the smallest granularity of memory access.
+ *                     Some memory controllers are capable of single channel -
+ *                     which means that memory sticks can be loaded
+ *                     individually.  Other memory controllers are only
+ *                     capable of dual channel - which means that memory
+ *                     sticks must be loaded as pairs (see "socket set").
+ *
+ * Chip-select row:    All of the memory devices that are selected together.
+ *                     for a single, minimum grain of memory access.
+ *                     This selects all of the parallel memory devices across
+ *                     all of the parallel channels.  Common chip-select rows
+ *                     for single channel are 64 bits, for dual channel 128
+ *                     bits.
+ *
+ * Single-Ranked stick:        A Single-ranked stick has 1 chip-select row of memory.
+ *                     Motherboards commonly drive two chip-select pins to
+ *                     a memory stick. A single-ranked stick, will occupy
+ *                     only one of those rows. The other will be unused.
+ *
+ * Double-Ranked stick:        A double-ranked stick has two chip-select rows which
+ *                     access different sets of memory devices.  The two
+ *                     rows cannot be accessed concurrently.
+ *
+ * Double-sided stick: DEPRECATED TERM, see Double-Ranked stick.
+ *                     A double-sided stick has two chip-select rows which
+ *                     access different sets of memory devices.  The two
+ *                     rows cannot be accessed concurrently.  "Double-sided"
+ *                     is irrespective of the memory devices being mounted
+ *                     on both sides of the memory stick.
+ *
+ * Socket set:         All of the memory sticks that are required for
+ *                     a single memory access or all of the memory sticks
+ *                     spanned by a chip-select row.  A single socket set
+ *                     has two chip-select rows and if double-sided sticks
+ *                     are used these will occupy those chip-select rows.
+ *
+ * Bank:               This term is avoided because it is unclear when
+ *                     needing to distinguish between chip-select rows and
+ *                     socket sets.
+ *
+ * Controller pages:
+ *
+ * Physical pages:
+ *
+ * Virtual pages:
+ *
+ *
+ * STRUCTURE ORGANIZATION AND CHOICES
+ *
+ *
+ *
+ * PS - I enjoyed writing all that about as much as you enjoyed reading it.
+ */
+
+struct channel_info {
+       int chan_idx;           /* channel index */
+       u32 ce_count;           /* Correctable Errors for this CHANNEL */
+       char label[EDAC_MC_LABEL_LEN + 1];      /* DIMM label on motherboard */
+       struct csrow_info *csrow;       /* the parent */
+};
+
+struct csrow_info {
+       unsigned long first_page;       /* first page number in dimm */
+       unsigned long last_page;        /* last page number in dimm */
+       unsigned long page_mask;        /* used for interleaving -
+                                        * 0UL for non intlv
+                                        */
+       u32 nr_pages;           /* number of pages in csrow */
+       u32 grain;              /* granularity of reported error in bytes */
+       int csrow_idx;          /* the chip-select row */
+       enum dev_type dtype;    /* memory device type */
+       u32 ue_count;           /* Uncorrectable Errors for this csrow */
+       u32 ce_count;           /* Correctable Errors for this csrow */
+       enum mem_type mtype;    /* memory csrow type */
+       enum edac_type edac_mode;       /* EDAC mode for this csrow */
+       struct mem_ctl_info *mci;       /* the parent */
+
+       struct kobject kobj;    /* sysfs kobject for this csrow */
+
+       /* channel information for this csrow */
+       u32 nr_channels;
+       struct channel_info *channels;
+};
+
+struct mcidev_sysfs_group {
+       const char *name;                               /* group name */
+       const struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */
+};
+
+struct mcidev_sysfs_group_kobj {
+       struct list_head list;          /* list for all instances within a mc */
+
+       struct kobject kobj;            /* kobj for the group */
+
+       const struct mcidev_sysfs_group *grp;   /* group description table */
+       struct mem_ctl_info *mci;       /* the parent */
+};
+
+/* mcidev_sysfs_attribute structure
+ *     used for driver sysfs attributes and in mem_ctl_info
+ *     sysfs top level entries
+ */
+struct mcidev_sysfs_attribute {
+       /* It should use either attr or grp */
+       struct attribute attr;
+       const struct mcidev_sysfs_group *grp;   /* Points to a group of attributes */
+
+       /* Ops for show/store values at the attribute - not used on group */
+        ssize_t (*show)(struct mem_ctl_info *,char *);
+        ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
+};
+
+/* MEMORY controller information structure
+ */
+struct mem_ctl_info {
+       struct list_head link;  /* for global list of mem_ctl_info structs */
+
+       struct module *owner;   /* Module owner of this control struct */
+
+       unsigned long mtype_cap;        /* memory types supported by mc */
+       unsigned long edac_ctl_cap;     /* Mem controller EDAC capabilities */
+       unsigned long edac_cap; /* configuration capabilities - this is
+                                * closely related to edac_ctl_cap.  The
+                                * difference is that the controller may be
+                                * capable of s4ecd4ed which would be listed
+                                * in edac_ctl_cap, but if channels aren't
+                                * capable of s4ecd4ed then the edac_cap would
+                                * not have that capability.
+                                */
+       unsigned long scrub_cap;        /* chipset scrub capabilities */
+       enum scrub_type scrub_mode;     /* current scrub mode */
+
+       /* Translates sdram memory scrub rate given in bytes/sec to the
+          internal representation and configures whatever else needs
+          to be configured.
+        */
+       int (*set_sdram_scrub_rate) (struct mem_ctl_info * mci, u32 bw);
+
+       /* Get the current sdram memory scrub rate from the internal
+          representation and converts it to the closest matching
+          bandwidth in bytes/sec.
+        */
+       int (*get_sdram_scrub_rate) (struct mem_ctl_info * mci);
+
+
+       /* pointer to edac checking routine */
+       void (*edac_check) (struct mem_ctl_info * mci);
+
+       /*
+        * Remaps memory pages: controller pages to physical pages.
+        * For most MC's, this will be NULL.
+        */
+       /* FIXME - why not send the phys page to begin with? */
+       unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
+                                          unsigned long page);
+       int mc_idx;
+       int nr_csrows;
+       struct csrow_info *csrows;
+       /*
+        * FIXME - what about controllers on other busses? - IDs must be
+        * unique.  dev pointer should be sufficiently unique, but
+        * BUS:SLOT.FUNC numbers may not be unique.
+        */
+       struct device *dev;
+       const char *mod_name;
+       const char *mod_ver;
+       const char *ctl_name;
+       const char *dev_name;
+       char proc_name[MC_PROC_NAME_MAX_LEN + 1];
+       void *pvt_info;
+       u32 ue_noinfo_count;    /* Uncorrectable Errors w/o info */
+       u32 ce_noinfo_count;    /* Correctable Errors w/o info */
+       u32 ue_count;           /* Total Uncorrectable Errors for this MC */
+       u32 ce_count;           /* Total Correctable Errors for this MC */
+       unsigned long start_time;       /* mci load start time (in jiffies) */
+
+       struct completion complete;
+
+       /* edac sysfs device control */
+       struct kobject edac_mci_kobj;
+
+       /* list for all grp instances within a mc */
+       struct list_head grp_kobj_list;
+
+       /* Additional top controller level attributes, but specified
+        * by the low level driver.
+        *
+        * Set by the low level driver to provide attributes at the
+        * controller level, same level as 'ue_count' and 'ce_count' above.
+        * An array of structures, NULL terminated
+        *
+        * If attributes are desired, then set to array of attributes
+        * If no attributes are desired, leave NULL
+        */
+       const struct mcidev_sysfs_attribute *mc_driver_sysfs_attributes;
+
+       /* work struct for this MC */
+       struct delayed_work work;
+
+       /* the internal state of this controller instance */
+       int op_state;
+};
+
 #endif
diff --git a/include/linux/edac_mce.h b/include/linux/edac_mce.h
deleted file mode 100644 (file)
index f974fc0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Provides edac interface to mcelog events
- *
- * This file may be distributed under the terms of the
- * GNU General Public License version 2.
- *
- * Copyright (c) 2009 by:
- *      Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * Red Hat Inc. http://www.redhat.com
- */
-
-#if defined(CONFIG_EDAC_MCE) || \
-                       (defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE))
-
-#include <asm/mce.h>
-#include <linux/list.h>
-
-struct edac_mce {
-       struct list_head list;
-
-       void *priv;
-       int (*check_error)(void *priv, struct mce *mce);
-};
-
-int edac_mce_register(struct edac_mce *edac_mce);
-void edac_mce_unregister(struct edac_mce *edac_mce);
-int edac_mce_parse(struct mce *mce);
-
-#else
-#define edac_mce_parse(mce) (0)
-#endif
index c6e427ab65fe0a802878d1ebac438364956a44bf..3829712ccc054e129b9bc389b029367c28a17475 100644 (file)
@@ -117,99 +117,101 @@ struct ethtool_eeprom {
        __u8    data[0];
 };
 
-/* for configuring coalescing parameters of chip */
+/**
+ * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates
+ * @cmd: ETHTOOL_{G,S}COALESCE
+ * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after
+ *     a packet arrives.
+ * @rx_max_coalesced_frames: Maximum number of packets to receive
+ *     before an RX interrupt.
+ * @rx_coalesce_usecs_irq: Same as @rx_coalesce_usecs, except that
+ *     this value applies while an IRQ is being serviced by the host.
+ * @rx_max_coalesced_frames_irq: Same as @rx_max_coalesced_frames,
+ *     except that this value applies while an IRQ is being serviced
+ *     by the host.
+ * @tx_coalesce_usecs: How many usecs to delay a TX interrupt after
+ *     a packet is sent.
+ * @tx_max_coalesced_frames: Maximum number of packets to be sent
+ *     before a TX interrupt.
+ * @tx_coalesce_usecs_irq: Same as @tx_coalesce_usecs, except that
+ *     this value applies while an IRQ is being serviced by the host.
+ * @tx_max_coalesced_frames_irq: Same as @tx_max_coalesced_frames,
+ *     except that this value applies while an IRQ is being serviced
+ *     by the host.
+ * @stats_block_coalesce_usecs: How many usecs to delay in-memory
+ *     statistics block updates.  Some drivers do not have an
+ *     in-memory statistic block, and in such cases this value is
+ *     ignored.  This value must not be zero.
+ * @use_adaptive_rx_coalesce: Enable adaptive RX coalescing.
+ * @use_adaptive_tx_coalesce: Enable adaptive TX coalescing.
+ * @pkt_rate_low: Threshold for low packet rate (packets per second).
+ * @rx_coalesce_usecs_low: How many usecs to delay an RX interrupt after
+ *     a packet arrives, when the packet rate is below @pkt_rate_low.
+ * @rx_max_coalesced_frames_low: Maximum number of packets to be received
+ *     before an RX interrupt, when the packet rate is below @pkt_rate_low.
+ * @tx_coalesce_usecs_low: How many usecs to delay a TX interrupt after
+ *     a packet is sent, when the packet rate is below @pkt_rate_low.
+ * @tx_max_coalesced_frames_low: Maximum nuumber of packets to be sent before
+ *     a TX interrupt, when the packet rate is below @pkt_rate_low.
+ * @pkt_rate_high: Threshold for high packet rate (packets per second).
+ * @rx_coalesce_usecs_high: How many usecs to delay an RX interrupt after
+ *     a packet arrives, when the packet rate is above @pkt_rate_high.
+ * @rx_max_coalesced_frames_high: Maximum number of packets to be received
+ *     before an RX interrupt, when the packet rate is above @pkt_rate_high.
+ * @tx_coalesce_usecs_high: How many usecs to delay a TX interrupt after
+ *     a packet is sent, when the packet rate is above @pkt_rate_high.
+ * @tx_max_coalesced_frames_high: Maximum number of packets to be sent before
+ *     a TX interrupt, when the packet rate is above @pkt_rate_high.
+ * @rate_sample_interval: How often to do adaptive coalescing packet rate
+ *     sampling, measured in seconds.  Must not be zero.
+ *
+ * Each pair of (usecs, max_frames) fields specifies this exit
+ * condition for interrupt coalescing:
+ *     (usecs > 0 && time_since_first_completion >= usecs) ||
+ *     (max_frames > 0 && completed_frames >= max_frames)
+ * It is illegal to set both usecs and max_frames to zero as this
+ * would cause interrupts to never be generated.  To disable
+ * coalescing, set usecs = 0 and max_frames = 1.
+ *
+ * Some implementations ignore the value of max_frames and use the
+ * condition:
+ *     time_since_first_completion >= usecs
+ * This is deprecated.  Drivers for hardware that does not support
+ * counting completions should validate that max_frames == !rx_usecs.
+ *
+ * Adaptive RX/TX coalescing is an algorithm implemented by some
+ * drivers to improve latency under low packet rates and improve
+ * throughput under high packet rates.  Some drivers only implement
+ * one of RX or TX adaptive coalescing.  Anything not implemented by
+ * the driver causes these values to be silently ignored.
+ *
+ * When the packet rate is below @pkt_rate_high but above
+ * @pkt_rate_low (both measured in packets per second) the
+ * normal {rx,tx}_* coalescing parameters are used.
+ */
 struct ethtool_coalesce {
-       __u32   cmd;    /* ETHTOOL_{G,S}COALESCE */
-
-       /* How many usecs to delay an RX interrupt after
-        * a packet arrives.  If 0, only rx_max_coalesced_frames
-        * is used.
-        */
+       __u32   cmd;
        __u32   rx_coalesce_usecs;
-
-       /* How many packets to delay an RX interrupt after
-        * a packet arrives.  If 0, only rx_coalesce_usecs is
-        * used.  It is illegal to set both usecs and max frames
-        * to zero as this would cause RX interrupts to never be
-        * generated.
-        */
        __u32   rx_max_coalesced_frames;
-
-       /* Same as above two parameters, except that these values
-        * apply while an IRQ is being serviced by the host.  Not
-        * all cards support this feature and the values are ignored
-        * in that case.
-        */
        __u32   rx_coalesce_usecs_irq;
        __u32   rx_max_coalesced_frames_irq;
-
-       /* How many usecs to delay a TX interrupt after
-        * a packet is sent.  If 0, only tx_max_coalesced_frames
-        * is used.
-        */
        __u32   tx_coalesce_usecs;
-
-       /* How many packets to delay a TX interrupt after
-        * a packet is sent.  If 0, only tx_coalesce_usecs is
-        * used.  It is illegal to set both usecs and max frames
-        * to zero as this would cause TX interrupts to never be
-        * generated.
-        */
        __u32   tx_max_coalesced_frames;
-
-       /* Same as above two parameters, except that these values
-        * apply while an IRQ is being serviced by the host.  Not
-        * all cards support this feature and the values are ignored
-        * in that case.
-        */
        __u32   tx_coalesce_usecs_irq;
        __u32   tx_max_coalesced_frames_irq;
-
-       /* How many usecs to delay in-memory statistics
-        * block updates.  Some drivers do not have an in-memory
-        * statistic block, and in such cases this value is ignored.
-        * This value must not be zero.
-        */
        __u32   stats_block_coalesce_usecs;
-
-       /* Adaptive RX/TX coalescing is an algorithm implemented by
-        * some drivers to improve latency under low packet rates and
-        * improve throughput under high packet rates.  Some drivers
-        * only implement one of RX or TX adaptive coalescing.  Anything
-        * not implemented by the driver causes these values to be
-        * silently ignored.
-        */
        __u32   use_adaptive_rx_coalesce;
        __u32   use_adaptive_tx_coalesce;
-
-       /* When the packet rate (measured in packets per second)
-        * is below pkt_rate_low, the {rx,tx}_*_low parameters are
-        * used.
-        */
        __u32   pkt_rate_low;
        __u32   rx_coalesce_usecs_low;
        __u32   rx_max_coalesced_frames_low;
        __u32   tx_coalesce_usecs_low;
        __u32   tx_max_coalesced_frames_low;
-
-       /* When the packet rate is below pkt_rate_high but above
-        * pkt_rate_low (both measured in packets per second) the
-        * normal {rx,tx}_* coalescing parameters are used.
-        */
-
-       /* When the packet rate is (measured in packets per second)
-        * is above pkt_rate_high, the {rx,tx}_*_high parameters are
-        * used.
-        */
        __u32   pkt_rate_high;
        __u32   rx_coalesce_usecs_high;
        __u32   rx_max_coalesced_frames_high;
        __u32   tx_coalesce_usecs_high;
        __u32   tx_max_coalesced_frames_high;
-
-       /* How often to do adaptive coalescing packet rate sampling,
-        * measured in seconds.  Must not be zero.
-        */
        __u32   rate_sample_interval;
 };
 
diff --git a/include/linux/evm.h b/include/linux/evm.h
new file mode 100644 (file)
index 0000000..ea603c9
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * evm.h
+ *
+ * Copyright (c) 2009 IBM Corporation
+ * Author: Mimi Zohar <zohar@us.ibm.com>
+ */
+
+#ifndef _LINUX_EVM_H
+#define _LINUX_EVM_H
+
+#include <linux/integrity.h>
+#include <linux/xattr.h>
+
+struct integrity_iint_cache;
+
+#ifdef CONFIG_EVM
+extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
+                                            const char *xattr_name,
+                                            void *xattr_value,
+                                            size_t xattr_value_len,
+                                            struct integrity_iint_cache *iint);
+extern int evm_inode_setattr(struct dentry *dentry, struct iattr *attr);
+extern void evm_inode_post_setattr(struct dentry *dentry, int ia_valid);
+extern int evm_inode_setxattr(struct dentry *dentry, const char *name,
+                             const void *value, size_t size);
+extern void evm_inode_post_setxattr(struct dentry *dentry,
+                                   const char *xattr_name,
+                                   const void *xattr_value,
+                                   size_t xattr_value_len);
+extern int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name);
+extern void evm_inode_post_removexattr(struct dentry *dentry,
+                                      const char *xattr_name);
+extern int evm_inode_init_security(struct inode *inode,
+                                  const struct xattr *xattr_array,
+                                  struct xattr *evm);
+#else
+#ifdef CONFIG_INTEGRITY
+static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
+                                                   const char *xattr_name,
+                                                   void *xattr_value,
+                                                   size_t xattr_value_len,
+                                       struct integrity_iint_cache *iint)
+{
+       return INTEGRITY_UNKNOWN;
+}
+#endif
+
+static inline int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
+{
+       return 0;
+}
+
+static inline void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
+{
+       return;
+}
+
+static inline int evm_inode_setxattr(struct dentry *dentry, const char *name,
+                                    const void *value, size_t size)
+{
+       return 0;
+}
+
+static inline void evm_inode_post_setxattr(struct dentry *dentry,
+                                          const char *xattr_name,
+                                          const void *xattr_value,
+                                          size_t xattr_value_len)
+{
+       return;
+}
+
+static inline int evm_inode_removexattr(struct dentry *dentry,
+                                       const char *xattr_name)
+{
+       return 0;
+}
+
+static inline void evm_inode_post_removexattr(struct dentry *dentry,
+                                             const char *xattr_name)
+{
+       return;
+}
+
+static inline int evm_inode_init_security(struct inode *inode,
+                                         const struct xattr *xattr_array,
+                                         struct xattr *evm)
+{
+       return 0;
+}
+
+#endif /* CONFIG_EVM_H */
+#endif /* LINUX_EVM_H */
index 53792bf36c715d4c7f16c08a4a71a02ebda0eefd..ce1b719e8bd467f7a82ed8c7b4175665b7d8ffc5 100644 (file)
@@ -197,8 +197,8 @@ struct ext2_group_desc
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT2_FL_INHERITED (EXT2_SECRM_FL | EXT2_UNRM_FL | EXT2_COMPR_FL |\
-                          EXT2_SYNC_FL | EXT2_IMMUTABLE_FL | EXT2_APPEND_FL |\
-                          EXT2_NODUMP_FL | EXT2_NOATIME_FL | EXT2_COMPRBLK_FL|\
+                          EXT2_SYNC_FL | EXT2_NODUMP_FL |\
+                          EXT2_NOATIME_FL | EXT2_COMPRBLK_FL |\
                           EXT2_NOCOMP_FL | EXT2_JOURNAL_DATA_FL |\
                           EXT2_NOTAIL_FL | EXT2_DIRSYNC_FL)
 
index 67a803aee619c0b75593e4c740abc35087f28d49..0244611eb2b836b6a2f5434a1fc8c966bc15e25b 100644 (file)
@@ -180,8 +180,8 @@ struct ext3_group_desc
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\
-                          EXT3_SYNC_FL | EXT3_IMMUTABLE_FL | EXT3_APPEND_FL |\
-                          EXT3_NODUMP_FL | EXT3_NOATIME_FL | EXT3_COMPRBLK_FL|\
+                          EXT3_SYNC_FL | EXT3_NODUMP_FL |\
+                          EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\
                           EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\
                           EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL)
 
index 6c6133f76e163c88041c4a13a4b091ef6ccf13ac..b5fac2ba4a0756916d2231da984341bea79087bb 100644 (file)
 #define FAN_UNLIMITED_QUEUE    0x00000010
 #define FAN_UNLIMITED_MARKS    0x00000020
 
+/* Attempt read-only open if read-write failed. */
+#define FAN_READONLY_FALLBACK  0x00000040
+
 #define FAN_ALL_INIT_FLAGS     (FAN_CLOEXEC | FAN_NONBLOCK | \
                                 FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
-                                FAN_UNLIMITED_MARKS)
+                                FAN_UNLIMITED_MARKS | FAN_READONLY_FALLBACK)
 
 /* flags used for fanotify_modify_mark() */
 #define FAN_MARK_ADD           0x00000001
index 1effc8b56b4e44fa169b4538b64f22e53c8b8bef..122b5ce186df35c56c5c779e48b22801789631ea 100644 (file)
@@ -5,70 +5,57 @@
 
 #include <linux/sched.h>
 #include <linux/wait.h>
+#include <linux/atomic.h>
 
 #ifdef CONFIG_FREEZER
+extern atomic_t system_freezing_cnt;   /* nr of freezing conds in effect */
+extern bool pm_freezing;               /* PM freezing in effect */
+extern bool pm_nosig_freezing;         /* PM nosig freezing in effect */
+
 /*
  * Check if a process has been frozen
  */
-static inline int frozen(struct task_struct *p)
+static inline bool frozen(struct task_struct *p)
 {
        return p->flags & PF_FROZEN;
 }
 
-/*
- * Check if there is a request to freeze a process
- */
-static inline int freezing(struct task_struct *p)
-{
-       return test_tsk_thread_flag(p, TIF_FREEZE);
-}
+extern bool freezing_slow_path(struct task_struct *p);
 
 /*
- * Request that a process be frozen
- */
-static inline void set_freeze_flag(struct task_struct *p)
-{
-       set_tsk_thread_flag(p, TIF_FREEZE);
-}
-
-/*
- * Sometimes we may need to cancel the previous 'freeze' request
+ * Check if there is a request to freeze a process
  */
-static inline void clear_freeze_flag(struct task_struct *p)
-{
-       clear_tsk_thread_flag(p, TIF_FREEZE);
-}
-
-static inline bool should_send_signal(struct task_struct *p)
+static inline bool freezing(struct task_struct *p)
 {
-       return !(p->flags & PF_FREEZER_NOSIG);
+       if (likely(!atomic_read(&system_freezing_cnt)))
+               return false;
+       return freezing_slow_path(p);
 }
 
 /* Takes and releases task alloc lock using task_lock() */
-extern int thaw_process(struct task_struct *p);
+extern void __thaw_task(struct task_struct *t);
 
-extern void refrigerator(void);
+extern bool __refrigerator(bool check_kthr_stop);
 extern int freeze_processes(void);
 extern void thaw_processes(void);
 
-static inline int try_to_freeze(void)
+static inline bool try_to_freeze(void)
 {
-       if (freezing(current)) {
-               refrigerator();
-               return 1;
-       } else
-               return 0;
+       might_sleep();
+       if (likely(!freezing(current)))
+               return false;
+       return __refrigerator(false);
 }
 
 extern bool freeze_task(struct task_struct *p, bool sig_only);
-extern void cancel_freezing(struct task_struct *p);
+extern bool __set_freezable(bool with_signal);
 
 #ifdef CONFIG_CGROUP_FREEZER
-extern int cgroup_freezing_or_frozen(struct task_struct *task);
+extern bool cgroup_freezing(struct task_struct *task);
 #else /* !CONFIG_CGROUP_FREEZER */
-static inline int cgroup_freezing_or_frozen(struct task_struct *task)
+static inline bool cgroup_freezing(struct task_struct *task)
 {
-       return 0;
+       return false;
 }
 #endif /* !CONFIG_CGROUP_FREEZER */
 
@@ -119,18 +106,18 @@ static inline int freezer_should_skip(struct task_struct *p)
 /*
  * Tell the freezer that the current task should be frozen by it
  */
-static inline void set_freezable(void)
+static inline bool set_freezable(void)
 {
-       current->flags &= ~PF_NOFREEZE;
+       return __set_freezable(false);
 }
 
 /*
  * Tell the freezer that the current task should be frozen by it and that it
  * should send a fake signal to the task to freeze it.
  */
-static inline void set_freezable_with_signal(void)
+static inline bool set_freezable_with_signal(void)
 {
-       current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
+       return __set_freezable(true);
 }
 
 /*
@@ -164,17 +151,14 @@ static inline void set_freezable_with_signal(void)
        __retval;                                                       \
 })
 #else /* !CONFIG_FREEZER */
-static inline int frozen(struct task_struct *p) { return 0; }
-static inline int freezing(struct task_struct *p) { return 0; }
-static inline void set_freeze_flag(struct task_struct *p) {}
-static inline void clear_freeze_flag(struct task_struct *p) {}
-static inline int thaw_process(struct task_struct *p) { return 1; }
+static inline bool frozen(struct task_struct *p) { return false; }
+static inline bool freezing(struct task_struct *p) { return false; }
 
-static inline void refrigerator(void) {}
+static inline bool __refrigerator(bool check_kthr_stop) { return false; }
 static inline int freeze_processes(void) { BUG(); return 0; }
 static inline void thaw_processes(void) {}
 
-static inline int try_to_freeze(void) { return 0; }
+static inline bool try_to_freeze(void) { return false; }
 
 static inline void freezer_do_not_count(void) {}
 static inline void freezer_count(void) {}
index 91d0e0a34ef3185a6051d8394cab63dfb76a04cb..226c791ff2e2261c9180db4d44ce87ae0b471c7a 100644 (file)
@@ -125,6 +125,7 @@ struct fsnotify_group {
 
        const struct fsnotify_ops *ops; /* how this group handles things */
 
+       struct mutex mutex;
        /* needed to send notification to userspace */
        struct mutex notification_mutex;        /* protect the notification_list */
        struct list_head notification_list;     /* list of event_holder this group needs to send to userspace */
@@ -168,6 +169,7 @@ struct fsnotify_group {
                        wait_queue_head_t access_waitq;
                        atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
+                       bool readonly_fallback;
                        int f_flags;
                        unsigned int max_marks;
                        struct user_struct *user;
@@ -415,8 +417,6 @@ extern void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group);
 extern void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, unsigned int flags);
 /* run all the marks in a group, and flag them to be freed */
 extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);
-extern void fsnotify_get_mark(struct fsnotify_mark *mark);
-extern void fsnotify_put_mark(struct fsnotify_mark *mark);
 extern void fsnotify_unmount_inodes(struct list_head *list);
 
 /* put here because inotify does some weird stuff when destroying watches */
@@ -430,6 +430,16 @@ extern struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_ev
 extern int fsnotify_replace_event(struct fsnotify_event_holder *old_holder,
                                  struct fsnotify_event *new_event);
 
+static inline void fsnotify_get_mark(struct fsnotify_mark *mark)
+{
+       atomic_inc(&mark->refcnt);
+}
+
+static inline void fsnotify_put_mark(struct fsnotify_mark *mark)
+{
+       if (atomic_dec_and_test(&mark->refcnt))
+               mark->free_mark(mark);
+}
 #else
 
 static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
index d464de53db4399c598ec3793f75290856b049255..464cff52686092c0f862f551b2db53ed3050b629 100644 (file)
@@ -47,6 +47,9 @@
  *  - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct
  *    fuse_ioctl_iovec' instead of ambiguous 'struct iovec'
  *  - add FUSE_IOCTL_32BIT flag
+ *
+ * 7.17
+ *  - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
  */
 
 #ifndef _LINUX_FUSE_H
@@ -78,7 +81,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 16
+#define FUSE_KERNEL_MINOR_VERSION 17
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -153,8 +156,10 @@ struct fuse_file_lock {
 /**
  * INIT request/reply flags
  *
+ * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
  * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
  * FUSE_DONT_MASK: don't apply umask to file mode on create operations
+ * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
@@ -163,6 +168,7 @@ struct fuse_file_lock {
 #define FUSE_EXPORT_SUPPORT    (1 << 4)
 #define FUSE_BIG_WRITES                (1 << 5)
 #define FUSE_DONT_MASK         (1 << 6)
+#define FUSE_FLOCK_LOCKS       (1 << 10)
 
 /**
  * CUSE INIT request/reply flags
@@ -175,6 +181,7 @@ struct fuse_file_lock {
  * Release flags
  */
 #define FUSE_RELEASE_FLUSH     (1 << 0)
+#define FUSE_RELEASE_FLOCK_UNLOCK      (1 << 1)
 
 /**
  * Getattr flags
index 9cf8e7ae7450b1fbbb250b664a4d5db8d79c058f..9c02d07af0d18466da9428163176348b2332370e 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/input.h>
+#include <linux/semaphore.h>
 
 /*
  * We parse each description item into this structure. Short items data
@@ -475,6 +476,7 @@ struct hid_device {                                                 /* device report descriptor */
        unsigned country;                                               /* HID country */
        struct hid_report_enum report_enum[HID_REPORT_TYPES];
 
+       struct semaphore driver_lock;                                   /* protects the current driver */
        struct device dev;                                              /* device */
        struct hid_driver *driver;
        struct hid_ll_driver *ll_driver;
index 6427d298fbfc7d319321d8b9c287fc5761f9a2a4..530e11ba07387bfa7da5c32c800e341a9f1c4d7d 100644 (file)
@@ -129,6 +129,10 @@ enum sample_type {
 #define REG_BCICTL2             0x024
 #define TWL4030_BCI_ITHSENS    0x007
 
+/* Register and bits for GPBR1 register */
+#define TWL4030_REG_GPBR1              0x0c
+#define TWL4030_GPBR1_MADC_HFCLK_EN    (1 << 7)
+
 struct twl4030_madc_user_parms {
        int channel;
        int average;
index 54c878960872e47053751b57edd8187295b6fa1f..03cfbf393a6358b4f2907f2bf86dd70880d636d2 100644 (file)
@@ -629,6 +629,7 @@ struct ieee80211_rann_ie {
        u8 rann_ttl;
        u8 rann_addr[6];
        u32 rann_seq;
+       u32 rann_interval;
        u32 rann_metric;
 } __attribute__ ((packed));
 
@@ -736,19 +737,10 @@ struct ieee80211_mgmt {
                                        __le16 params;
                                        __le16 reason_code;
                                } __attribute__((packed)) delba;
-                               struct{
+                               struct {
                                        u8 action_code;
-                                       /* capab_info for open and confirm,
-                                        * reason for close
-                                        */
-                                       __le16 aux;
-                                       /* Followed in plink_confirm by status
-                                        * code, AID and supported rates,
-                                        * and directly by supported rates in
-                                        * plink_open and plink_close
-                                        */
                                        u8 variable[0];
-                               } __attribute__((packed)) plink_action;
+                               } __attribute__((packed)) self_prot;
                                struct{
                                        u8 action_code;
                                        u8 variable[0];
@@ -816,9 +808,11 @@ struct ieee80211_bar {
 } __attribute__((packed));
 
 /* 802.11 BAR control masks */
-#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL     0x0000
-#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA  0x0004
-
+#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL   0x0000
+#define IEEE80211_BAR_CTRL_MULTI_TID           0x0002
+#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA        0x0004
+#define IEEE80211_BAR_CTRL_TID_INFO_MASK       0xf000
+#define IEEE80211_BAR_CTRL_TID_INFO_SHIFT      12
 
 #define IEEE80211_HT_MCS_MASK_LEN              10
 
@@ -1194,11 +1188,6 @@ enum ieee80211_eid {
        WLAN_EID_MESH_ID = 114,
        WLAN_EID_LINK_METRIC_REPORT = 115,
        WLAN_EID_CONGESTION_NOTIFICATION = 116,
-       /* Note that the Peer Link IE has been replaced with the similar
-        * Peer Management IE.  We will keep the former definition until mesh
-        * code is changed to comply with latest 802.11s drafts.
-        */
-       WLAN_EID_PEER_LINK = 55,  /* no longer in 802.11s drafts */
        WLAN_EID_PEER_MGMT = 117,
        WLAN_EID_CHAN_SWITCH_PARAM = 118,
        WLAN_EID_MESH_AWAKE_WINDOW = 119,
@@ -1281,9 +1270,6 @@ enum ieee80211_category {
        WLAN_CATEGORY_MULTIHOP_ACTION = 14,
        WLAN_CATEGORY_SELF_PROTECTED = 15,
        WLAN_CATEGORY_WMM = 17,
-       /* TODO: remove MESH_PATH_SEL after mesh is updated
-        * to current 802.11s draft  */
-       WLAN_CATEGORY_MESH_PATH_SEL = 32,
        WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
        WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
 };
@@ -1309,6 +1295,31 @@ enum ieee80211_ht_actioncode {
        WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7,
 };
 
+/* Self Protected Action codes */
+enum ieee80211_self_protected_actioncode {
+       WLAN_SP_RESERVED = 0,
+       WLAN_SP_MESH_PEERING_OPEN = 1,
+       WLAN_SP_MESH_PEERING_CONFIRM = 2,
+       WLAN_SP_MESH_PEERING_CLOSE = 3,
+       WLAN_SP_MGK_INFORM = 4,
+       WLAN_SP_MGK_ACK = 5,
+};
+
+/* Mesh action codes */
+enum ieee80211_mesh_actioncode {
+       WLAN_MESH_ACTION_LINK_METRIC_REPORT,
+       WLAN_MESH_ACTION_HWMP_PATH_SELECTION,
+       WLAN_MESH_ACTION_GATE_ANNOUNCEMENT,
+       WLAN_MESH_ACTION_CONGESTION_CONTROL_NOTIFICATION,
+       WLAN_MESH_ACTION_MCCA_SETUP_REQUEST,
+       WLAN_MESH_ACTION_MCCA_SETUP_REPLY,
+       WLAN_MESH_ACTION_MCCA_ADVERTISEMENT_REQUEST,
+       WLAN_MESH_ACTION_MCCA_ADVERTISEMENT,
+       WLAN_MESH_ACTION_MCCA_TEARDOWN,
+       WLAN_MESH_ACTION_TBTT_ADJUSTMENT_REQUEST,
+       WLAN_MESH_ACTION_TBTT_ADJUSTMENT_RESPONSE,
+};
+
 /* Security key length */
 enum ieee80211_key_len {
        WLAN_KEY_LEN_WEP40 = 5,
index 03489ca92ded4e1f901af97a76e0ca042297cdd0..db20bd4fd16b9189534a0cc15aa6335925cd3ace 100644 (file)
@@ -78,6 +78,7 @@
                                         * datapath port */
 #define IFF_TX_SKB_SHARING     0x10000 /* The interface supports sharing
                                         * skbs on transmit */
+#define IFF_UNICAST_FLT        0x20000         /* Supports unicast filtering   */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
index a3d99ff6e3b5c01120f93aa0beadbdfbe9f52c20..c63bbd754a846756cf6b4630336e2284ddffc24f 100644 (file)
@@ -88,6 +88,7 @@
 #define ETH_P_QINQ2    0x9200          /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_QINQ3    0x9300          /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_EDSA     0xDADA          /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_AF_IUCV   0xFBFB         /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
 
 /*
  *     Non DIX types. Won't clash for 1500 types.
index 09e6e62f9953f445e4e92df8bfeb99c6ae4e8f1a..6ac8e50c6cf5453e338fec108f9dd1418046e3e9 100644 (file)
@@ -15,8 +15,6 @@ struct linux_binprm;
 
 #ifdef CONFIG_IMA
 extern int ima_bprm_check(struct linux_binprm *bprm);
-extern int ima_inode_alloc(struct inode *inode);
-extern void ima_inode_free(struct inode *inode);
 extern int ima_file_check(struct file *file, int mask);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
@@ -27,16 +25,6 @@ static inline int ima_bprm_check(struct linux_binprm *bprm)
        return 0;
 }
 
-static inline int ima_inode_alloc(struct inode *inode)
-{
-       return 0;
-}
-
-static inline void ima_inode_free(struct inode *inode)
-{
-       return;
-}
-
 static inline int ima_file_check(struct file *file, int mask)
 {
        return 0;
@@ -51,6 +39,5 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
 {
        return 0;
 }
-
 #endif /* CONFIG_IMA_H */
 #endif /* _LINUX_IMA_H */
diff --git a/include/linux/integrity.h b/include/linux/integrity.h
new file mode 100644 (file)
index 0000000..9684433
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 IBM Corporation
+ * Author: Mimi Zohar <zohar@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#ifndef _LINUX_INTEGRITY_H
+#define _LINUX_INTEGRITY_H
+
+#include <linux/fs.h>
+
+enum integrity_status {
+       INTEGRITY_PASS = 0,
+       INTEGRITY_FAIL,
+       INTEGRITY_NOLABEL,
+       INTEGRITY_UNKNOWN,
+};
+
+/* List of EVM protected security xattrs */
+#ifdef CONFIG_INTEGRITY
+extern int integrity_inode_alloc(struct inode *inode);
+extern void integrity_inode_free(struct inode *inode);
+
+#else
+static inline int integrity_inode_alloc(struct inode *inode)
+{
+       return 0;
+}
+
+static inline void integrity_inode_free(struct inode *inode)
+{
+       return;
+}
+#endif /* CONFIG_INTEGRITY_H */
+#endif /* _LINUX_INTEGRITY_H */
index c2478a342cd7d9f9b4a754cb73f906745cf4f42c..07d9aba7556298afc63719fa6af5342884f67811 100644 (file)
 #error KEXEC_ARCH not defined
 #endif
 
+#ifndef KEXEC_CRASH_CONTROL_MEMORY_LIMIT
+#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT
+#endif
+
 #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
 #define KEXEC_CORE_NOTE_NAME "CORE"
 #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
index 1e923e5e88e81cdc83c8455eefb776eb1b5de588..6c1903da180f8d7dc1209c88d7f561d55ca3d067 100644 (file)
@@ -35,6 +35,7 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
 void kthread_bind(struct task_struct *k, unsigned int cpu);
 int kthread_stop(struct task_struct *k);
 int kthread_should_stop(void);
+bool kthread_freezable_should_stop(bool *was_frozen);
 void *kthread_data(struct task_struct *k);
 
 int kthreadd(void *unused);
index ef820a3c378bb421a51fb0920f289571f8f96382..b6a56e37284c41e0954a7a794ddab4b617ebf547 100644 (file)
@@ -548,7 +548,7 @@ do {                                                                        \
 #endif
 
 #ifdef CONFIG_PROVE_RCU
-extern void lockdep_rcu_dereference(const char *file, const int line);
+void lockdep_rcu_suspicious(const char *file, const int line, const char *s);
 #endif
 
 #endif /* __LINUX_LOCKDEP_H */
index 46b954011f1685112401d7f98332064441f333b5..252966769d939fae571aa6dc260b86e1280bfc2f 100644 (file)
@@ -27,6 +27,9 @@
 struct ab8500_gpadc;
 
 struct ab8500_gpadc *ab8500_gpadc_get(char *name);
-int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input);
+int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel);
+int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel);
+int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc,
+    u8 channel, int ad_value);
 
 #endif /* _AB8500_GPADC_H */
index 5ff2400ad46cd4325b31027ff8b82554eb6bc592..3f4deb62d6b0d4c4c3475e074244860977fd259c 100644 (file)
@@ -326,7 +326,6 @@ struct max8997_dev {
        int irq;
        int ono;
        int irq_base;
-       bool wakeup;
        struct mutex irqlock;
        int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
        int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
index 50d4a047118db3e59792d1dbfdcb405db0e25758..a80840752b4cbea3481473532499b0b65513057a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mfd/pcf50633/backlight.h>
 
 struct pcf50633;
+struct regmap;
 
 #define PCF50633_NUM_REGULATORS        11
 
@@ -134,7 +135,7 @@ enum {
 
 struct pcf50633 {
        struct device *dev;
-       struct i2c_client *i2c_client;
+       struct regmap *regmap;
 
        struct pcf50633_platform_data *pdata;
        int irq;
index 8dda8ded5cda666c0147a197188c6f5de98030f4..44acdb25681b855a5be64b349dbf2a9e5066cc02 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/regmap.h>
 
 /*
  * Register values.
@@ -361,12 +362,8 @@ struct wm831x {
        struct mutex io_lock;
 
        struct device *dev;
-       int (*read_dev)(struct wm831x *wm831x, unsigned short reg,
-                       int bytes, void *dest);
-       int (*write_dev)(struct wm831x *wm831x, unsigned short reg,
-                        int bytes, void *src);
 
-       void *control_data;
+       struct regmap *regmap;
 
        int irq;  /* Our chip IRQ */
        struct mutex irq_lock;
@@ -416,4 +413,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq);
 void wm831x_irq_exit(struct wm831x *wm831x);
 void wm831x_auxadc_init(struct wm831x *wm831x);
 
+extern struct regmap_config wm831x_regmap_config;
+
 #endif
index 2aab4e93a5c94efc47d37526400b4fcf771a7396..0147b696851072fde8a6074cb762257aa1654aad 100644 (file)
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 
+struct regmap;
+
 #define WM8400_REGISTER_COUNT 0x55
 
 struct wm8400 {
        struct device *dev;
 
-       int (*read_dev)(void *data, char reg, int count, u16 *dst);
-       int (*write_dev)(void *data, char reg, int count, const u16 *src);
-
        struct mutex io_lock;
-       void *io_data;
+       struct regmap *regmap;
 
        u16 reg_cache[WM8400_REGISTER_COUNT];
 
index f0b69cdae41cc94f24c995d9812301d9eb711451..a275798d690bc54f5d23b42f0ce5d5e808a7245e 100644 (file)
@@ -24,6 +24,7 @@ enum wm8994_type {
 
 struct regulator_dev;
 struct regulator_bulk_data;
+struct regmap;
 
 #define WM8994_NUM_GPIO_REGS 11
 #define WM8994_NUM_LDO_REGS   2
@@ -50,18 +51,14 @@ struct regulator_bulk_data;
 #define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN)
 
 struct wm8994 {
-       struct mutex io_lock;
        struct mutex irq_lock;
 
        enum wm8994_type type;
 
        struct device *dev;
-       int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
-                       int bytes, void *dest);
-       int (*write_dev)(struct wm8994 *wm8994, unsigned short reg,
-                        int bytes, const void *src);
+       struct regmap *regmap;
 
-       void *control_data;
+       bool ldo_ena_always_driven;
 
        int gpio_base;
        int irq_base;
index d12f8d635a8159b8ce54a144dbf9eda1d90e29d8..ea32f306dca6963c312fe4f4b4e3968233f68393 100644 (file)
@@ -26,7 +26,7 @@ struct wm8994_ldo_pdata {
        struct regulator_init_data *init_data;
 };
 
-#define WM8994_CONFIGURE_GPIO 0x8000
+#define WM8994_CONFIGURE_GPIO 0x10000
 
 #define WM8994_DRC_REGS 5
 #define WM8994_EQ_REGS  20
@@ -167,6 +167,13 @@ struct wm8994_pdata {
 
        /* WM8958 microphone bias configuration */
        int micbias[2];
+
+       /* Disable the internal pull downs on the LDOs if they are
+        * always driven (eg, connected to an always on supply or
+        * GPIO that always drives an output.  If they float power
+        * consumption will rise.
+        */
+       bool ldo_ena_always_driven;
 };
 
 #endif
index f3ee84284670f5e42fc4871cdfc18bc2f7171d87..83ecdcd8aaf90393e6044b76e9110ce61bada806 100644 (file)
@@ -72,6 +72,7 @@
 #define WM8994_DC_SERVO_2                       0x55
 #define WM8994_DC_SERVO_4                       0x57
 #define WM8994_DC_SERVO_READBACK                0x58
+#define WM8994_DC_SERVO_4E                     0x59
 #define WM8994_ANALOGUE_HP_1                    0x60
 #define WM8958_MIC_DETECT_1                     0xD0
 #define WM8958_MIC_DETECT_2                     0xD1
 #define WM8994_AIF1_DAC1_FILTERS_2              0x421
 #define WM8994_AIF1_DAC2_FILTERS_1              0x422
 #define WM8994_AIF1_DAC2_FILTERS_2              0x423
+#define WM8958_AIF1_DAC1_NOISE_GATE             0x430
+#define WM8958_AIF1_DAC2_NOISE_GATE             0x431
 #define WM8994_AIF1_DRC1_1                      0x440
 #define WM8994_AIF1_DRC1_2                      0x441
 #define WM8994_AIF1_DRC1_3                      0x442
 #define WM8994_AIF2_ADC_FILTERS                 0x510
 #define WM8994_AIF2_DAC_FILTERS_1               0x520
 #define WM8994_AIF2_DAC_FILTERS_2               0x521
+#define WM8958_AIF2_DAC_NOISE_GATE              0x530
 #define WM8994_AIF2_DRC_1                       0x540
 #define WM8994_AIF2_DRC_2                       0x541
 #define WM8994_AIF2_DRC_3                       0x542
 #define WM8994_LDO2_DISCH_SHIFT                      0  /* LDO2_DISCH */
 #define WM8994_LDO2_DISCH_WIDTH                      1  /* LDO2_DISCH */
 
+/*
+ * R61 (0x3D) - MICBIAS1
+ */
+#define WM8958_MICB1_RATE                       0x0020  /* MICB1_RATE */
+#define WM8958_MICB1_RATE_MASK                  0x0020  /* MICB1_RATE */
+#define WM8958_MICB1_RATE_SHIFT                      5  /* MICB1_RATE */
+#define WM8958_MICB1_RATE_WIDTH                      1  /* MICB1_RATE */
+#define WM8958_MICB1_MODE                       0x0010  /* MICB1_MODE */
+#define WM8958_MICB1_MODE_MASK                  0x0010  /* MICB1_MODE */
+#define WM8958_MICB1_MODE_SHIFT                      4  /* MICB1_MODE */
+#define WM8958_MICB1_MODE_WIDTH                      1  /* MICB1_MODE */
+#define WM8958_MICB1_LVL_MASK                   0x000E  /* MICB1_LVL - [3:1] */
+#define WM8958_MICB1_LVL_SHIFT                       1  /* MICB1_LVL - [3:1] */
+#define WM8958_MICB1_LVL_WIDTH                       3  /* MICB1_LVL - [3:1] */
+#define WM8958_MICB1_DISCH                      0x0001  /* MICB1_DISCH */
+#define WM8958_MICB1_DISCH_MASK                 0x0001  /* MICB1_DISCH */
+#define WM8958_MICB1_DISCH_SHIFT                     0  /* MICB1_DISCH */
+#define WM8958_MICB1_DISCH_WIDTH                     1  /* MICB1_DISCH */
+
+/*
+ * R62 (0x3E) - MICBIAS2
+ */
+#define WM8958_MICB2_RATE                       0x0020  /* MICB2_RATE */
+#define WM8958_MICB2_RATE_MASK                  0x0020  /* MICB2_RATE */
+#define WM8958_MICB2_RATE_SHIFT                      5  /* MICB2_RATE */
+#define WM8958_MICB2_RATE_WIDTH                      1  /* MICB2_RATE */
+#define WM8958_MICB2_MODE                       0x0010  /* MICB2_MODE */
+#define WM8958_MICB2_MODE_MASK                  0x0010  /* MICB2_MODE */
+#define WM8958_MICB2_MODE_SHIFT                      4  /* MICB2_MODE */
+#define WM8958_MICB2_MODE_WIDTH                      1  /* MICB2_MODE */
+#define WM8958_MICB2_LVL_MASK                   0x000E  /* MICB2_LVL - [3:1] */
+#define WM8958_MICB2_LVL_SHIFT                       1  /* MICB2_LVL - [3:1] */
+#define WM8958_MICB2_LVL_WIDTH                       3  /* MICB2_LVL - [3:1] */
+#define WM8958_MICB2_DISCH                      0x0001  /* MICB2_DISCH */
+#define WM8958_MICB2_DISCH_MASK                 0x0001  /* MICB2_DISCH */
+#define WM8958_MICB2_DISCH_SHIFT                     0  /* MICB2_DISCH */
+#define WM8958_MICB2_DISCH_WIDTH                     1  /* MICB2_DISCH */
+
 /*
  * R76 (0x4C) - Charge Pump (1)
  */
 #define WM8994_AIF1DAC2_3D_ENA_SHIFT                 8  /* AIF1DAC2_3D_ENA */
 #define WM8994_AIF1DAC2_3D_ENA_WIDTH                 1  /* AIF1DAC2_3D_ENA */
 
+/*
+ * R1072 (0x430) - AIF1 DAC1 Noise Gate
+ */
+#define WM8958_AIF1DAC1_NG_HLD_MASK             0x0060  /* AIF1DAC1_NG_HLD - [6:5] */
+#define WM8958_AIF1DAC1_NG_HLD_SHIFT                 5  /* AIF1DAC1_NG_HLD - [6:5] */
+#define WM8958_AIF1DAC1_NG_HLD_WIDTH                 2  /* AIF1DAC1_NG_HLD - [6:5] */
+#define WM8958_AIF1DAC1_NG_THR_MASK             0x000E  /* AIF1DAC1_NG_THR - [3:1] */
+#define WM8958_AIF1DAC1_NG_THR_SHIFT                 1  /* AIF1DAC1_NG_THR - [3:1] */
+#define WM8958_AIF1DAC1_NG_THR_WIDTH                 3  /* AIF1DAC1_NG_THR - [3:1] */
+#define WM8958_AIF1DAC1_NG_ENA                  0x0001  /* AIF1DAC1_NG_ENA */
+#define WM8958_AIF1DAC1_NG_ENA_MASK             0x0001  /* AIF1DAC1_NG_ENA */
+#define WM8958_AIF1DAC1_NG_ENA_SHIFT                 0  /* AIF1DAC1_NG_ENA */
+#define WM8958_AIF1DAC1_NG_ENA_WIDTH                 1  /* AIF1DAC1_NG_ENA */
+
+/*
+ * R1073 (0x431) - AIF1 DAC2 Noise Gate
+ */
+#define WM8958_AIF1DAC2_NG_HLD_MASK             0x0060  /* AIF1DAC2_NG_HLD - [6:5] */
+#define WM8958_AIF1DAC2_NG_HLD_SHIFT                 5  /* AIF1DAC2_NG_HLD - [6:5] */
+#define WM8958_AIF1DAC2_NG_HLD_WIDTH                 2  /* AIF1DAC2_NG_HLD - [6:5] */
+#define WM8958_AIF1DAC2_NG_THR_MASK             0x000E  /* AIF1DAC2_NG_THR - [3:1] */
+#define WM8958_AIF1DAC2_NG_THR_SHIFT                 1  /* AIF1DAC2_NG_THR - [3:1] */
+#define WM8958_AIF1DAC2_NG_THR_WIDTH                 3  /* AIF1DAC2_NG_THR - [3:1] */
+#define WM8958_AIF1DAC2_NG_ENA                  0x0001  /* AIF1DAC2_NG_ENA */
+#define WM8958_AIF1DAC2_NG_ENA_MASK             0x0001  /* AIF1DAC2_NG_ENA */
+#define WM8958_AIF1DAC2_NG_ENA_SHIFT                 0  /* AIF1DAC2_NG_ENA */
+#define WM8958_AIF1DAC2_NG_ENA_WIDTH                 1  /* AIF1DAC2_NG_ENA */
+
 /*
  * R1088 (0x440) - AIF1 DRC1 (1)
  */
 #define WM8994_AIF2DAC_3D_ENA_SHIFT                  8  /* AIF2DAC_3D_ENA */
 #define WM8994_AIF2DAC_3D_ENA_WIDTH                  1  /* AIF2DAC_3D_ENA */
 
+/*
+ * R1328 (0x530) - AIF2 DAC Noise Gate
+ */
+#define WM8958_AIF2DAC_NG_HLD_MASK              0x0060  /* AIF2DAC_NG_HLD - [6:5] */
+#define WM8958_AIF2DAC_NG_HLD_SHIFT                  5  /* AIF2DAC_NG_HLD - [6:5] */
+#define WM8958_AIF2DAC_NG_HLD_WIDTH                  2  /* AIF2DAC_NG_HLD - [6:5] */
+#define WM8958_AIF2DAC_NG_THR_MASK              0x000E  /* AIF2DAC_NG_THR - [3:1] */
+#define WM8958_AIF2DAC_NG_THR_SHIFT                  1  /* AIF2DAC_NG_THR - [3:1] */
+#define WM8958_AIF2DAC_NG_THR_WIDTH                  3  /* AIF2DAC_NG_THR - [3:1] */
+#define WM8958_AIF2DAC_NG_ENA                   0x0001  /* AIF2DAC_NG_ENA */
+#define WM8958_AIF2DAC_NG_ENA_MASK              0x0001  /* AIF2DAC_NG_ENA */
+#define WM8958_AIF2DAC_NG_ENA_SHIFT                  0  /* AIF2DAC_NG_ENA */
+#define WM8958_AIF2DAC_NG_ENA_WIDTH                  1  /* AIF2DAC_NG_ENA */
+
 /*
  * R1344 (0x540) - AIF2 DRC (1)
  */
index 1d09562ccf7394b2ae0a2cdf38cf52e17ccd53ec..4c4bddf5ef61b7561a0e6582ae25bdbc8c3fe246 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/leds.h>
 #include <linux/sched.h>
+#include <linux/fault-inject.h>
 
 #include <linux/mmc/core.h>
 #include <linux/mmc/pm.h>
@@ -302,6 +303,10 @@ struct mmc_host {
 
        struct mmc_async_req    *areq;          /* active async req */
 
+#ifdef CONFIG_FAIL_MMC_REQUEST
+       struct fault_attr       fail_mmc_request;
+#endif
+
        unsigned long           private[0] ____cacheline_aligned;
 };
 
index 57cc0e63714f9651462450db8fbbc78df79b82f1..c4eec228eef9756c660b538018550ab6bfc8790e 100644 (file)
@@ -86,24 +86,39 @@ struct nand_bbt_descr {
 #define NAND_BBT_VERSION       0x00000100
 /* Create a bbt if none exists */
 #define NAND_BBT_CREATE                0x00000200
+/*
+ * Create an empty BBT with no vendor information. Vendor's information may be
+ * unavailable, for example, if the NAND controller has a different data and OOB
+ * layout or if this information is already purged. Must be used in conjunction
+ * with NAND_BBT_CREATE.
+ */
+#define NAND_BBT_CREATE_EMPTY  0x00000400
 /* Search good / bad pattern through all pages of a block */
-#define NAND_BBT_SCANALLPAGES  0x00000400
+#define NAND_BBT_SCANALLPAGES  0x00000800
 /* Scan block empty during good / bad block scan */
-#define NAND_BBT_SCANEMPTY     0x00000800
+#define NAND_BBT_SCANEMPTY     0x00001000
 /* Write bbt if neccecary */
-#define NAND_BBT_WRITE         0x00001000
+#define NAND_BBT_WRITE         0x00002000
 /* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x00002000
+#define NAND_BBT_SAVECONTENT   0x00004000
 /* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x00004000
+#define NAND_BBT_SCAN2NDPAGE   0x00008000
 /* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x00008000
-/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
-#define NAND_BBT_SCANBYTE1AND6 0x00100000
-/* The nand_bbt_descr was created dynamicaly and must be freed */
-#define NAND_BBT_DYNAMICSTRUCT 0x00200000
-/* The bad block table does not OOB for marker */
-#define NAND_BBT_NO_OOB                0x00400000
+#define NAND_BBT_SCANLASTPAGE  0x00010000
+/*
+ * Use a flash based bad block table. By default, OOB identifier is saved in
+ * OOB area. This option is passed to the default bad block table function.
+ */
+#define NAND_BBT_USE_FLASH     0x00020000
+/* Do not store flash based bad block table in OOB area; store it in-band */
+#define NAND_BBT_NO_OOB                0x00040000
+
+/*
+ * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
+ * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
+ * in nand_chip.bbt_options.
+ */
+#define NAND_BBT_DYNAMICSTRUCT 0x80000000
 
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS        4
index 2541fb848daa7c2108c7ff74e27a44d146731642..68ea22963a3365f19f735a6188a66bfe8eeb11ae 100644 (file)
@@ -172,7 +172,7 @@ struct mtd_info {
        const char *name;
        int index;
 
-       /* ecc layout structure pointer - read only ! */
+       /* ECC layout structure pointer - read only! */
        struct nand_ecclayout *ecclayout;
 
        /* Data for variable erase regions. If numeraseregions is zero,
@@ -323,10 +323,15 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
        /* Kernel-side ioctl definitions */
 
 struct mtd_partition;
-
-extern int mtd_device_register(struct mtd_info *master,
-                              const struct mtd_partition *parts,
-                              int nr_parts);
+struct mtd_part_parser_data;
+
+extern int mtd_device_parse_register(struct mtd_info *mtd,
+                             const char **part_probe_types,
+                             struct mtd_part_parser_data *parser_data,
+                             const struct mtd_partition *defparts,
+                             int defnr_parts);
+#define mtd_device_register(master, parts, nr_parts)   \
+       mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
 extern int mtd_device_unregister(struct mtd_info *master);
 extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
 extern int __get_mtd_device(struct mtd_info *mtd);
@@ -355,27 +360,4 @@ void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
 
 void mtd_erase_callback(struct erase_info *instr);
 
-/*
- * Debugging macro and defines
- */
-#define MTD_DEBUG_LEVEL0       (0)     /* Quiet   */
-#define MTD_DEBUG_LEVEL1       (1)     /* Audible */
-#define MTD_DEBUG_LEVEL2       (2)     /* Loud    */
-#define MTD_DEBUG_LEVEL3       (3)     /* Noisy   */
-
-#ifdef CONFIG_MTD_DEBUG
-#define DEBUG(n, args...)                              \
-       do {                                            \
-               if (n <= CONFIG_MTD_DEBUG_VERBOSE)      \
-                       printk(KERN_INFO args);         \
-       } while(0)
-#else /* CONFIG_MTD_DEBUG */
-#define DEBUG(n, args...)                              \
-       do {                                            \
-               if (0)                                  \
-                       printk(KERN_INFO args);         \
-       } while(0)
-
-#endif /* CONFIG_MTD_DEBUG */
-
 #endif /* __MTD_MTD_H__ */
index c2b9ac4fbc4ab588074acd2d77f2ad20bc1bddb6..6d5696876b3f6f6393617866051a3e91ce8c226f 100644 (file)
@@ -42,10 +42,10 @@ extern void nand_release(struct mtd_info *mtd);
 /* Internal helper for board drivers which need to override command function */
 extern void nand_wait_ready(struct mtd_info *mtd);
 
-/* locks all blockes present in the device */
+/* locks all blocks present in the device */
 extern int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 
-/* unlocks specified locked blockes */
+/* unlocks specified locked blocks */
 extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 
 /* The maximum number of NAND chips in an array */
@@ -150,7 +150,7 @@ typedef enum {
 #define NAND_ECC_READ          0
 /* Reset Hardware ECC for write */
 #define NAND_ECC_WRITE         1
-/* Enable Hardware ECC before syndrom is read back from flash */
+/* Enable Hardware ECC before syndrome is read back from flash */
 #define NAND_ECC_READSYN       2
 
 /* Bit mask for flags passed to do_nand_read_ecc */
@@ -163,7 +163,7 @@ typedef enum {
  */
 /* Chip can not auto increment pages */
 #define NAND_NO_AUTOINCR       0x00000001
-/* Buswitdh is 16 bit */
+/* Buswidth is 16 bit */
 #define NAND_BUSWIDTH_16       0x00000002
 /* Device supports partial programming without padding */
 #define NAND_NO_PADDING                0x00000004
@@ -219,27 +219,15 @@ typedef enum {
 #define NAND_CHIPOPTIONS_MSK   (0x0000ffff & ~NAND_NO_AUTOINCR)
 
 /* Non chip related options */
-/*
- * Use a flash based bad block table. OOB identifier is saved in OOB area.
- * This option is passed to the default bad block table function.
- */
-#define NAND_USE_FLASH_BBT     0x00010000
 /* This option skips the bbt scan during initialization. */
-#define NAND_SKIP_BBTSCAN      0x00020000
+#define NAND_SKIP_BBTSCAN      0x00010000
 /*
  * This option is defined if the board driver allocates its own buffers
  * (e.g. because it needs them DMA-coherent).
  */
-#define NAND_OWN_BUFFERS       0x00040000
+#define NAND_OWN_BUFFERS       0x00020000
 /* Chip may not exist, so silence any errors in scan */
-#define NAND_SCAN_SILENT_NODEV 0x00080000
-/*
- * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch
- * the OOB area.
- */
-#define NAND_USE_FLASH_BBT_NO_OOB      0x00800000
-/* Create an empty BBT with no vendor information if the BBT is available */
-#define NAND_CREATE_EMPTY_BBT          0x01000000
+#define NAND_SCAN_SILENT_NODEV 0x00040000
 
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
@@ -331,26 +319,26 @@ struct nand_hw_control {
 };
 
 /**
- * struct nand_ecc_ctrl - Control structure for ecc
- * @mode:      ecc mode
- * @steps:     number of ecc steps per page
- * @size:      data bytes per ecc step
- * @bytes:     ecc bytes per step
- * @total:     total number of ecc bytes per page
- * @prepad:    padding information for syndrome based ecc generators
- * @postpad:   padding information for syndrome based ecc generators
+ * struct nand_ecc_ctrl - Control structure for ECC
+ * @mode:      ECC mode
+ * @steps:     number of ECC steps per page
+ * @size:      data bytes per ECC step
+ * @bytes:     ECC bytes per step
+ * @total:     total number of ECC bytes per page
+ * @prepad:    padding information for syndrome based ECC generators
+ * @postpad:   padding information for syndrome based ECC generators
  * @layout:    ECC layout control struct pointer
- * @priv:      pointer to private ecc control data
- * @hwctl:     function to control hardware ecc generator. Must only
+ * @priv:      pointer to private ECC control data
+ * @hwctl:     function to control hardware ECC generator. Must only
  *             be provided if an hardware ECC is available
- * @calculate: function for ecc calculation or readback from ecc hardware
- * @correct:   function for ecc correction, matching to ecc generator (sw/hw)
+ * @calculate: function for ECC calculation or readback from ECC hardware
+ * @correct:   function for ECC correction, matching to ECC generator (sw/hw)
  * @read_page_raw:     function to read a raw page without ECC
  * @write_page_raw:    function to write a raw page without ECC
- * @read_page: function to read a page according to the ecc generator
+ * @read_page: function to read a page according to the ECC generator
  *             requirements.
  * @read_subpage:      function to read parts of the page covered by ECC.
- * @write_page:        function to write a page according to the ecc generator
+ * @write_page:        function to write a page according to the ECC generator
  *             requirements.
  * @read_oob:  function to read chip OOB data
  * @write_oob: function to write chip OOB data
@@ -388,8 +376,8 @@ struct nand_ecc_ctrl {
 
 /**
  * struct nand_buffers - buffer structure for read/write
- * @ecccalc:   buffer for calculated ecc
- * @ecccode:   buffer for ecc read from flash
+ * @ecccalc:   buffer for calculated ECC
+ * @ecccode:   buffer for ECC read from flash
  * @databuf:   buffer for data - dynamically sized
  *
  * Do not change the order of buffers. databuf and oobrbuf must be in
@@ -422,7 +410,7 @@ struct nand_buffers {
  *                     mtd->oobsize, mtd->writesize and so on.
  *                     @id_data contains the 8 bytes values of NAND_CMD_READID.
  *                     Return with the bus width.
- * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accesing
+ * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accessing
  *                     device ready/busy line. If set to NULL no access to
  *                     ready/busy is available and the ready/busy information
  *                     is read from the chip status register.
@@ -430,7 +418,7 @@ struct nand_buffers {
  *                     commands to the chip.
  * @waitfunc:          [REPLACEABLE] hardwarespecific function for wait on
  *                     ready.
- * @ecc:               [BOARDSPECIFIC] ecc control ctructure
+ * @ecc:               [BOARDSPECIFIC] ECC control structure
  * @buffers:           buffer structure for read/write
  * @hwcontrol:         platform-specific hardware control structure
  * @ops:               oob operation operands
@@ -449,6 +437,9 @@ struct nand_buffers {
  * @options:           [BOARDSPECIFIC] various chip options. They can partly
  *                     be set to inform nand_scan about special functionality.
  *                     See the defines for further explanation.
+ * @bbt_options:       [INTERN] bad block specific options. All options used
+ *                     here must come from bbm.h. By default, these options
+ *                     will be copied to the appropriate nand_bbt_descr's.
  * @badblockpos:       [INTERN] position of the bad block marker in the oob
  *                     area.
  * @badblockbits:      [INTERN] number of bits to left-shift the bad block
@@ -464,7 +455,7 @@ struct nand_buffers {
  *                     non 0 if ONFI supported.
  * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
  *                     supported, 0 otherwise.
- * @ecclayout:         [REPLACEABLE] the default ecc placement scheme
+ * @ecclayout:         [REPLACEABLE] the default ECC placement scheme
  * @bbt:               [INTERN] bad block table pointer
  * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
  *                     lookup.
@@ -472,7 +463,7 @@ struct nand_buffers {
  * @badblock_pattern:  [REPLACEABLE] bad block scan pattern used for initial
  *                     bad block scan.
  * @controller:                [REPLACEABLE] a pointer to a hardware controller
- *                     structure which is shared among multiple independend
+ *                     structure which is shared among multiple independent
  *                     devices.
  * @priv:              [OPTIONAL] pointer to private chip date
  * @errstat:           [OPTIONAL] hardware specific function to perform
@@ -509,6 +500,7 @@ struct nand_chip {
 
        int chip_delay;
        unsigned int options;
+       unsigned int bbt_options;
 
        int page_shift;
        int phys_erase_shift;
@@ -611,10 +603,9 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
  * @partitions:                mtd partition list
  * @chip_delay:                R/B delay value in us
  * @options:           Option flags, e.g. 16bit buswidth
- * @ecclayout:         ecc layout info structure
+ * @bbt_options:       BBT option flags, e.g. NAND_BBT_USE_FLASH
+ * @ecclayout:         ECC layout info structure
  * @part_probe_types:  NULL-terminated array of probe types
- * @set_parts:         platform specific function to set partitions
- * @priv:              hardware controller specific settings
  */
 struct platform_nand_chip {
        int nr_chips;
@@ -624,9 +615,8 @@ struct platform_nand_chip {
        struct nand_ecclayout *ecclayout;
        int chip_delay;
        unsigned int options;
+       unsigned int bbt_options;
        const char **part_probe_types;
-       void (*set_parts)(uint64_t size, struct platform_nand_chip *chip);
-       void *priv;
 };
 
 /* Keep gcc happy */
index 52b6f187bf49bfdc3038dff70f3117eb4e9a1a97..4596503c9da9e0952d4953fa856572898aabc9be 100644 (file)
@@ -184,6 +184,9 @@ struct onenand_chip {
 #define ONENAND_IS_CACHE_PROGRAM(this)                                 \
        (this->options & ONENAND_HAS_CACHE_PROGRAM)
 
+#define ONENAND_IS_NOP_1(this)                                         \
+       (this->options & ONENAND_HAS_NOP_1)
+
 /* Check byte access in OneNAND */
 #define ONENAND_CHECK_BYTE_ACCESS(addr)                (addr & 0x1)
 
@@ -195,6 +198,7 @@ struct onenand_chip {
 #define ONENAND_HAS_2PLANE             (0x0004)
 #define ONENAND_HAS_4KB_PAGE           (0x0008)
 #define ONENAND_HAS_CACHE_PROGRAM      (0x0010)
+#define ONENAND_HAS_NOP_1              (0x0020)
 #define ONENAND_SKIP_UNLOCK_CHECK      (0x0100)
 #define ONENAND_PAGEBUF_ALLOC          (0x1000)
 #define ONENAND_OOBBUF_ALLOC           (0x2000)
index 3a6f0372fc9658f267fabdf61190b9a32ed4d7e3..2475228c1158e6f54e4f7ce02b2607ee9f487922 100644 (file)
@@ -24,7 +24,9 @@
  *     will extend to the end of the master MTD device.
  * offset: absolute starting position within the master MTD device; if
  *     defined as MTDPART_OFS_APPEND, the partition will start where the
- *     previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
+ *     previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block;
+ *     if MTDPART_OFS_RETAIN, consume as much as possible, leaving size
+ *     after the end of partition.
  * mask_flags: contains flags that have to be masked (removed) from the
  *     master MTD flag set for the corresponding MTD partition.
  *     For example, to force a read-only partition, simply adding
@@ -42,12 +44,25 @@ struct mtd_partition {
        struct nand_ecclayout *ecclayout;       /* out of band layout for this partition (NAND only) */
 };
 
+#define MTDPART_OFS_RETAIN     (-3)
 #define MTDPART_OFS_NXTBLK     (-2)
 #define MTDPART_OFS_APPEND     (-1)
 #define MTDPART_SIZ_FULL       (0)
 
 
 struct mtd_info;
+struct device_node;
+
+/**
+ * struct mtd_part_parser_data - used to pass data to MTD partition parsers.
+ * @origin: for RedBoot, start address of MTD device
+ * @of_node: for OF parsers, device node containing partitioning information
+ */
+struct mtd_part_parser_data {
+       unsigned long origin;
+       struct device_node *of_node;
+};
+
 
 /*
  * Functions dealing with the various ways of partitioning the space
@@ -57,37 +72,12 @@ struct mtd_part_parser {
        struct list_head list;
        struct module *owner;
        const char *name;
-       int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long);
+       int (*parse_fn)(struct mtd_info *, struct mtd_partition **,
+                       struct mtd_part_parser_data *);
 };
 
 extern int register_mtd_parser(struct mtd_part_parser *parser);
 extern int deregister_mtd_parser(struct mtd_part_parser *parser);
-extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
-                               struct mtd_partition **pparts, unsigned long origin);
-
-#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
-
-struct device;
-struct device_node;
-
-#ifdef CONFIG_MTD_OF_PARTS
-int __devinit of_mtd_parse_partitions(struct device *dev,
-                                      struct device_node *node,
-                                      struct mtd_partition **pparts);
-#else
-static inline int of_mtd_parse_partitions(struct device *dev,
-                                         struct device_node *node,
-                                         struct mtd_partition **pparts)
-{
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static inline int mtd_has_cmdlinepart(void) { return 1; }
-#else
-static inline int mtd_has_cmdlinepart(void) { return 0; }
-#endif
 
 int mtd_is_partition(struct mtd_info *mtd);
 int mtd_add_partition(struct mtd_info *master, char *name,
index e5f21d293c70175f1395c3355b3da5a230ee0d99..04e018160e2b516be1e29c383e983036c31ffef6 100644 (file)
@@ -32,21 +32,4 @@ struct physmap_flash_data {
        struct mtd_partition    *parts;
 };
 
-/*
- * Board needs to specify the exact mapping during their setup time.
- */
-void physmap_configure(unsigned long addr, unsigned long size,
-               int bankwidth, void (*set_vpp)(struct map_info *, int) );
-
-/*
- * Machines that wish to do flash partition may want to call this function in
- * their setup routine.
- *
- *     physmap_set_partitions(mypartitions, num_parts);
- *
- * Note that one can always override this hard-coded partition with
- * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
- */
-void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
-
 #endif /* __LINUX_MTD_PHYSMAP__ */
index ddee79bb8f1583e8dd45a46e25e264da84967104..720776084a2e220cd9ce7ee70c8fe8d223310bc8 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/if_link.h>
 
 #ifdef __KERNEL__
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/atomic.h>
@@ -723,9 +723,8 @@ struct netdev_tc_txq {
  *
  * void (*ndo_set_rx_mode)(struct net_device *dev);
  *     This function is called device changes address list filtering.
- *
- * void (*ndo_set_multicast_list)(struct net_device *dev);
- *     This function is called when the multicast address list changes.
+ *     If driver handles unicast address filtering, it should set
+ *     IFF_UNICAST_FLT to its priv_flags.
  *
  * int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
  *     This function  is called when the Media Access Control address
@@ -868,7 +867,6 @@ struct net_device_ops {
        void                    (*ndo_change_rx_flags)(struct net_device *dev,
                                                       int flags);
        void                    (*ndo_set_rx_mode)(struct net_device *dev);
-       void                    (*ndo_set_multicast_list)(struct net_device *dev);
        int                     (*ndo_set_mac_address)(struct net_device *dev,
                                                       void *addr);
        int                     (*ndo_validate_addr)(struct net_device *dev);
@@ -964,7 +962,7 @@ struct net_device {
         */
        char                    name[IFNAMSIZ];
 
-       struct pm_qos_request_list pm_qos_req;
+       struct pm_qos_request   pm_qos_req;
 
        /* device name hash chain */
        struct hlist_node       name_hlist;
@@ -2617,6 +2615,9 @@ static inline const char *netdev_name(const struct net_device *dev)
        return dev->name;
 }
 
+extern int __netdev_printk(const char *level, const struct net_device *dev,
+                       struct va_format *vaf);
+
 extern int netdev_printk(const char *level, const struct net_device *dev,
                         const char *format, ...)
        __attribute__ ((format (printf, 3, 4)));
@@ -2644,8 +2645,7 @@ extern int netdev_info(const struct net_device *dev, const char *format, ...)
 #elif defined(CONFIG_DYNAMIC_DEBUG)
 #define netdev_dbg(__dev, format, args...)                     \
 do {                                                           \
-       dynamic_dev_dbg((__dev)->dev.parent, "%s: " format,     \
-                       netdev_name(__dev), ##args);            \
+       dynamic_netdev_dbg(__dev, format, ##args);              \
 } while (0)
 #else
 #define netdev_dbg(__dev, format, args...)                     \
@@ -2712,9 +2712,7 @@ do {                                                              \
 #define netif_dbg(priv, type, netdev, format, args...)         \
 do {                                                           \
        if (netif_msg_##type(priv))                             \
-               dynamic_dev_dbg((netdev)->dev.parent,           \
-                               "%s: " format,                  \
-                               netdev_name(netdev), ##args);   \
+               dynamic_netdev_dbg(netdev, format, ##args);     \
 } while (0)
 #else
 #define netif_dbg(priv, type, dev, format, args...)                    \
index 8ad70dcac3f9195140e04ebcf1b008ecc44bbaf1..89dec16b4697c3d26430560f780cc8c56894f770 100644 (file)
  * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
  *     using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
  *     %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes.
+ *     Following attributes are provided for drivers that generate full Beacon
+ *     and Probe Response frames internally: %NL80211_ATTR_SSID,
+ *     %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
+ *     %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
+ *     %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
+ *     %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_IE, %NL80211_ATTR_IE_PROBE_RESP,
+ *     %NL80211_ATTR_IE_ASSOC_RESP.
  * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
  *     parameters are like for %NL80211_CMD_SET_BEACON.
  * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
@@ -842,18 +849,20 @@ enum nl80211_commands {
  * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
  *     event (u16)
  * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
- *     that protected APs should be used.
+ *     that protected APs should be used. This is also used with NEW_BEACON to
+ *     indicate that the BSS is to use protection.
  *
- * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to
- *     indicate which unicast key ciphers will be used with the connection
+ * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON
+ *     to indicate which unicast key ciphers will be used with the connection
  *     (an array of u32).
- * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate
- *     which group key cipher will be used with the connection (a u32).
- * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE to indicate
- *     which WPA version(s) the AP we want to associate with is using
+ * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ *     indicate which group key cipher will be used with the connection (a
+ *     u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ *     indicate which WPA version(s) the AP we want to associate with is using
  *     (a u32 with flags from &enum nl80211_wpa_versions).
- * @NL80211_ATTR_AKM_SUITES: Used with CONNECT and ASSOCIATE to indicate
- *     which key management algorithm(s) to use (an array of u32).
+ * @NL80211_ATTR_AKM_SUITES: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ *     indicate which key management algorithm(s) to use (an array of u32).
  *
  * @NL80211_ATTR_REQ_IE: (Re)association request information elements as
  *     sent out by the card, for ROAM and successful CONNECT events.
@@ -1019,6 +1028,20 @@ enum nl80211_commands {
  *     being a list of supported rates as defined by IEEE 802.11 7.3.2.2 but
  *     without the length restriction (at most %NL80211_MAX_SUPP_RATES).
  *
+ * @NL80211_ATTR_HIDDEN_SSID: indicates whether SSID is to be hidden from Beacon
+ *     and Probe Response (when response to wildcard Probe Request); see
+ *     &enum nl80211_hidden_ssid, represented as a u32
+ *
+ * @NL80211_ATTR_IE_PROBE_RESP: Information element(s) for Probe Response frame.
+ *     This is used with %NL80211_CMD_NEW_BEACON and %NL80211_CMD_SET_BEACON to
+ *     provide extra IEs (e.g., WPS/P2P IE) into Probe Response frames when the
+ *     driver (or firmware) replies to Probe Request frames.
+ * @NL80211_ATTR_IE_ASSOC_RESP: Information element(s) for (Re)Association
+ *     Response frames. This is used with %NL80211_CMD_NEW_BEACON and
+ *     %NL80211_CMD_SET_BEACON to provide extra IEs (e.g., WPS/P2P IE) into
+ *     (Re)Association Response frames when the driver (or firmware) replies to
+ *     (Re)Association Request frames.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1224,6 +1247,11 @@ enum nl80211_attrs {
 
        NL80211_ATTR_SCAN_SUPP_RATES,
 
+       NL80211_ATTR_HIDDEN_SSID,
+
+       NL80211_ATTR_IE_PROBE_RESP,
+       NL80211_ATTR_IE_ASSOC_RESP,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -2430,4 +2458,19 @@ enum nl80211_rekey_data {
        MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1
 };
 
+/**
+ * enum nl80211_hidden_ssid - values for %NL80211_ATTR_HIDDEN_SSID
+ * @NL80211_HIDDEN_SSID_NOT_IN_USE: do not hide SSID (i.e., broadcast it in
+ *     Beacon frames)
+ * @NL80211_HIDDEN_SSID_ZERO_LEN: hide SSID by using zero-length SSID element
+ *     in Beacon frames
+ * @NL80211_HIDDEN_SSID_ZERO_CONTENTS: hide SSID by using correct length of SSID
+ *     element in Beacon frames but zero out each byte in the SSID
+ */
+enum nl80211_hidden_ssid {
+       NL80211_HIDDEN_SSID_NOT_IN_USE,
+       NL80211_HIDDEN_SSID_ZERO_LEN,
+       NL80211_HIDDEN_SSID_ZERO_CONTENTS
+};
+
 #endif /* __LINUX_NL80211_H */
index c9e4d814ff7795414b028ee7ebcd7ed46fcdddef..2bb62bf296ac2078d08005e6b3b728c6927bb440 100644 (file)
@@ -35,6 +35,8 @@ struct pda_power_pdata {
        unsigned int polling_interval; /* msecs, default is 2000 */
 
        unsigned long ac_max_uA; /* current to draw when on AC */
+
+       bool use_otg_notifier;
 };
 
 #endif /* __PDA_POWER_H__ */
index f7c84c9abd30e9a876223cc8bbec8e85d6d5eb66..73f85f4a4006abf3ee656923a4a9dd5a1542c90f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/wait.h>
 #include <linux/timer.h>
 #include <linux/completion.h>
@@ -366,6 +367,8 @@ extern struct dev_pm_ops generic_subsys_pm_ops;
 #define PMSG_AUTO_RESUME       ((struct pm_message) \
                                        { .event = PM_EVENT_AUTO_RESUME, })
 
+#define PMSG_IS_AUTO(msg)      (((msg).event & PM_EVENT_AUTO) != 0)
+
 /**
  * Device run-time power management status.
  *
@@ -419,8 +422,32 @@ enum rpm_request {
        RPM_REQ_RESUME,
 };
 
+/* Per-device PM QoS constraints data struct state */
+enum dev_pm_qos_state {
+       DEV_PM_QOS_NO_DEVICE,           /* No device present */
+       DEV_PM_QOS_DEVICE_PRESENT,      /* Device present, data not allocated */
+       DEV_PM_QOS_ALLOCATED,           /* Device present, data allocated */
+};
+
 struct wakeup_source;
 
+struct pm_domain_data {
+       struct list_head list_node;
+       struct device *dev;
+       bool need_restore;
+};
+
+struct pm_subsys_data {
+       struct mutex lock;
+       unsigned int refcount;
+#ifdef CONFIG_PM_CLK
+       struct list_head clock_list;
+#endif
+#ifdef CONFIG_PM_GENERIC_DOMAINS
+       struct pm_domain_data domain_data;
+#endif
+};
+
 struct dev_pm_info {
        pm_message_t            power_state;
        unsigned int            can_wakeup:1;
@@ -462,10 +489,14 @@ struct dev_pm_info {
        unsigned long           suspended_jiffies;
        unsigned long           accounting_timestamp;
 #endif
-       void                    *subsys_data;  /* Owned by the subsystem. */
+       struct pm_subsys_data   *subsys_data;  /* Owned by the subsystem. */
+       struct pm_qos_constraints *constraints;
+       enum dev_pm_qos_state   constraints_state;
 };
 
 extern void update_pm_runtime_accounting(struct device *dev);
+extern int dev_pm_get_subsys_data(struct device *dev);
+extern int dev_pm_put_subsys_data(struct device *dev);
 
 /*
  * Power domains provide callbacks that are executed during system suspend,
diff --git a/include/linux/pm_clock.h b/include/linux/pm_clock.h
new file mode 100644 (file)
index 0000000..8348866
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * pm_clock.h - Definitions and headers related to device clocks.
+ *
+ * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#ifndef _LINUX_PM_CLOCK_H
+#define _LINUX_PM_CLOCK_H
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+struct pm_clk_notifier_block {
+       struct notifier_block nb;
+       struct dev_pm_domain *pm_domain;
+       char *con_ids[];
+};
+
+#ifdef CONFIG_PM_CLK
+static inline bool pm_clk_no_clocks(struct device *dev)
+{
+       return dev && dev->power.subsys_data
+               && list_empty(&dev->power.subsys_data->clock_list);
+}
+
+extern void pm_clk_init(struct device *dev);
+extern int pm_clk_create(struct device *dev);
+extern void pm_clk_destroy(struct device *dev);
+extern int pm_clk_add(struct device *dev, const char *con_id);
+extern void pm_clk_remove(struct device *dev, const char *con_id);
+extern int pm_clk_suspend(struct device *dev);
+extern int pm_clk_resume(struct device *dev);
+#else
+static inline bool pm_clk_no_clocks(struct device *dev)
+{
+       return true;
+}
+static inline void pm_clk_init(struct device *dev)
+{
+}
+static inline int pm_clk_create(struct device *dev)
+{
+       return -EINVAL;
+}
+static inline void pm_clk_destroy(struct device *dev)
+{
+}
+static inline int pm_clk_add(struct device *dev, const char *con_id)
+{
+       return -EINVAL;
+}
+static inline void pm_clk_remove(struct device *dev, const char *con_id)
+{
+}
+#define pm_clk_suspend NULL
+#define pm_clk_resume  NULL
+#endif
+
+#ifdef CONFIG_HAVE_CLK
+extern void pm_clk_add_notifier(struct bus_type *bus,
+                                       struct pm_clk_notifier_block *clknb);
+#else
+static inline void pm_clk_add_notifier(struct bus_type *bus,
+                                       struct pm_clk_notifier_block *clknb)
+{
+}
+#endif
+
+#endif
index f9ec1736a116a3f157d0abb49234be0597572c2c..5cce46c2d926a062a56585d683b6f9c266ad7c14 100644 (file)
@@ -13,6 +13,7 @@
 
 enum gpd_status {
        GPD_STATE_ACTIVE = 0,   /* PM domain is active */
+       GPD_STATE_WAIT_MASTER,  /* PM domain's master is being waited for */
        GPD_STATE_BUSY,         /* Something is happening to the PM domain */
        GPD_STATE_REPEAT,       /* Power off in progress, to be repeated */
        GPD_STATE_POWER_OFF,    /* PM domain is off */
@@ -25,15 +26,14 @@ struct dev_power_governor {
 struct generic_pm_domain {
        struct dev_pm_domain domain;    /* PM domain operations */
        struct list_head gpd_list_node; /* Node in the global PM domains list */
-       struct list_head sd_node;       /* Node in the parent's subdomain list */
-       struct generic_pm_domain *parent;       /* Parent PM domain */
-       struct list_head sd_list;       /* List of dubdomains */
+       struct list_head master_links;  /* Links with PM domain as a master */
+       struct list_head slave_links;   /* Links with PM domain as a slave */
        struct list_head dev_list;      /* List of devices */
        struct mutex lock;
        struct dev_power_governor *gov;
        struct work_struct power_off_work;
        unsigned int in_progress;       /* Number of devices being suspended now */
-       unsigned int sd_count;  /* Number of subdomains with power "on" */
+       atomic_t sd_count;      /* Number of subdomains with power "on" */
        enum gpd_status status; /* Current state of the domain */
        wait_queue_head_t status_wait_queue;
        struct task_struct *poweroff_task;      /* Powering off task */
@@ -54,10 +54,11 @@ static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
        return container_of(pd, struct generic_pm_domain, domain);
 }
 
-struct dev_list_entry {
-       struct list_head node;
-       struct device *dev;
-       bool need_restore;
+struct gpd_link {
+       struct generic_pm_domain *master;
+       struct list_head master_node;
+       struct generic_pm_domain *slave;
+       struct list_head slave_node;
 };
 
 #ifdef CONFIG_PM_GENERIC_DOMAINS
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
new file mode 100644 (file)
index 0000000..ca7bd3f
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef _LINUX_PM_QOS_H
+#define _LINUX_PM_QOS_H
+/* interface for the pm_qos_power infrastructure of the linux kernel.
+ *
+ * Mark Gross <mgross@linux.intel.com>
+ */
+#include <linux/plist.h>
+#include <linux/notifier.h>
+#include <linux/miscdevice.h>
+
+#define PM_QOS_RESERVED 0
+#define PM_QOS_CPU_DMA_LATENCY 1
+#define PM_QOS_NETWORK_LATENCY 2
+#define PM_QOS_NETWORK_THROUGHPUT 3
+
+#define PM_QOS_NUM_CLASSES 4
+#define PM_QOS_DEFAULT_VALUE -1
+
+#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE       (2000 * USEC_PER_SEC)
+#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE       (2000 * USEC_PER_SEC)
+#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE        0
+#define PM_QOS_DEV_LAT_DEFAULT_VALUE           0
+
+struct pm_qos_request {
+       struct plist_node node;
+       int pm_qos_class;
+};
+
+struct dev_pm_qos_request {
+       struct plist_node node;
+       struct device *dev;
+};
+
+enum pm_qos_type {
+       PM_QOS_UNITIALIZED,
+       PM_QOS_MAX,             /* return the largest value */
+       PM_QOS_MIN              /* return the smallest value */
+};
+
+/*
+ * Note: The lockless read path depends on the CPU accessing
+ * target_value atomically.  Atomic access is only guaranteed on all CPU
+ * types linux supports for 32 bit quantites
+ */
+struct pm_qos_constraints {
+       struct plist_head list;
+       s32 target_value;       /* Do not change to 64 bit */
+       s32 default_value;
+       enum pm_qos_type type;
+       struct blocking_notifier_head *notifiers;
+};
+
+/* Action requested to pm_qos_update_target */
+enum pm_qos_req_action {
+       PM_QOS_ADD_REQ,         /* Add a new request */
+       PM_QOS_UPDATE_REQ,      /* Update an existing request */
+       PM_QOS_REMOVE_REQ       /* Remove an existing request */
+};
+
+static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req)
+{
+       return req->dev != 0;
+}
+
+#ifdef CONFIG_PM
+int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
+                        enum pm_qos_req_action action, int value);
+void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class,
+                       s32 value);
+void pm_qos_update_request(struct pm_qos_request *req,
+                          s32 new_value);
+void pm_qos_remove_request(struct pm_qos_request *req);
+
+int pm_qos_request(int pm_qos_class);
+int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_request_active(struct pm_qos_request *req);
+s32 pm_qos_read_value(struct pm_qos_constraints *c);
+
+int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
+                          s32 value);
+int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value);
+int dev_pm_qos_remove_request(struct dev_pm_qos_request *req);
+int dev_pm_qos_add_notifier(struct device *dev,
+                           struct notifier_block *notifier);
+int dev_pm_qos_remove_notifier(struct device *dev,
+                              struct notifier_block *notifier);
+int dev_pm_qos_add_global_notifier(struct notifier_block *notifier);
+int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier);
+void dev_pm_qos_constraints_init(struct device *dev);
+void dev_pm_qos_constraints_destroy(struct device *dev);
+#else
+static inline int pm_qos_update_target(struct pm_qos_constraints *c,
+                                      struct plist_node *node,
+                                      enum pm_qos_req_action action,
+                                      int value)
+                       { return 0; }
+static inline void pm_qos_add_request(struct pm_qos_request *req,
+                                     int pm_qos_class, s32 value)
+                       { return; }
+static inline void pm_qos_update_request(struct pm_qos_request *req,
+                                        s32 new_value)
+                       { return; }
+static inline void pm_qos_remove_request(struct pm_qos_request *req)
+                       { return; }
+
+static inline int pm_qos_request(int pm_qos_class)
+                       { return 0; }
+static inline int pm_qos_add_notifier(int pm_qos_class,
+                                     struct notifier_block *notifier)
+                       { return 0; }
+static inline int pm_qos_remove_notifier(int pm_qos_class,
+                                        struct notifier_block *notifier)
+                       { return 0; }
+static inline int pm_qos_request_active(struct pm_qos_request *req)
+                       { return 0; }
+static inline s32 pm_qos_read_value(struct pm_qos_constraints *c)
+                       { return 0; }
+
+static inline int dev_pm_qos_add_request(struct device *dev,
+                                        struct dev_pm_qos_request *req,
+                                        s32 value)
+                       { return 0; }
+static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
+                                           s32 new_value)
+                       { return 0; }
+static inline int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
+                       { return 0; }
+static inline int dev_pm_qos_add_notifier(struct device *dev,
+                                         struct notifier_block *notifier)
+                       { return 0; }
+static inline int dev_pm_qos_remove_notifier(struct device *dev,
+                                            struct notifier_block *notifier)
+                       { return 0; }
+static inline int dev_pm_qos_add_global_notifier(
+                                       struct notifier_block *notifier)
+                       { return 0; }
+static inline int dev_pm_qos_remove_global_notifier(
+                                       struct notifier_block *notifier)
+                       { return 0; }
+static inline void dev_pm_qos_constraints_init(struct device *dev)
+                       { return; }
+static inline void dev_pm_qos_constraints_destroy(struct device *dev)
+                       { return; }
+#endif
+
+#endif
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
deleted file mode 100644 (file)
index a7d87f9..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _LINUX_PM_QOS_PARAMS_H
-#define _LINUX_PM_QOS_PARAMS_H
-/* interface for the pm_qos_power infrastructure of the linux kernel.
- *
- * Mark Gross <mgross@linux.intel.com>
- */
-#include <linux/plist.h>
-#include <linux/notifier.h>
-#include <linux/miscdevice.h>
-
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
-
-#define PM_QOS_NUM_CLASSES 4
-#define PM_QOS_DEFAULT_VALUE -1
-
-#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE       (2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE       (2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE        0
-
-struct pm_qos_request_list {
-       struct plist_node list;
-       int pm_qos_class;
-};
-
-void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
-void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
-               s32 new_value);
-void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
-
-int pm_qos_request(int pm_qos_class);
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_request_active(struct pm_qos_request_list *req);
-
-#endif
index daac05d751b2f144bedcb347148e7fde23b5fdec..70b284024d9ea52abb5d54f178815c39369c13ed 100644 (file)
@@ -251,46 +251,4 @@ static inline void pm_runtime_dont_use_autosuspend(struct device *dev)
        __pm_runtime_use_autosuspend(dev, false);
 }
 
-struct pm_clk_notifier_block {
-       struct notifier_block nb;
-       struct dev_pm_domain *pm_domain;
-       char *con_ids[];
-};
-
-#ifdef CONFIG_PM_CLK
-extern int pm_clk_init(struct device *dev);
-extern void pm_clk_destroy(struct device *dev);
-extern int pm_clk_add(struct device *dev, const char *con_id);
-extern void pm_clk_remove(struct device *dev, const char *con_id);
-extern int pm_clk_suspend(struct device *dev);
-extern int pm_clk_resume(struct device *dev);
-#else
-static inline int pm_clk_init(struct device *dev)
-{
-       return -EINVAL;
-}
-static inline void pm_clk_destroy(struct device *dev)
-{
-}
-static inline int pm_clk_add(struct device *dev, const char *con_id)
-{
-       return -EINVAL;
-}
-static inline void pm_clk_remove(struct device *dev, const char *con_id)
-{
-}
-#define pm_clk_suspend NULL
-#define pm_clk_resume  NULL
-#endif
-
-#ifdef CONFIG_HAVE_CLK
-extern void pm_clk_add_notifier(struct bus_type *bus,
-                                       struct pm_clk_notifier_block *clknb);
-#else
-static inline void pm_clk_add_notifier(struct bus_type *bus,
-                                       struct pm_clk_notifier_block *clknb)
-{
-}
-#endif
-
 #endif
index cc03bbf5c4b8e4dbe8c2b91b39f7a1b83b866fcb..b91440e64d6e6de31f98ae8e278c465531d1049d 100644 (file)
@@ -32,7 +32,7 @@ enum pstore_type_id {
 struct pstore_info {
        struct module   *owner;
        char            *name;
-       struct mutex    buf_mutex;      /* serialize access to 'buf' */
+       spinlock_t      buf_lock;       /* serialize access to 'buf' */
        char            *buf;
        size_t          bufsize;
        int             (*open)(struct pstore_info *psi);
index d13059f3ea32e5ab08859c08d71ac04a4d31817d..8f74538c96db5bd8615896593c2825628a29613c 100644 (file)
@@ -91,6 +91,19 @@ static inline void prandom32_seed(struct rnd_state *state, u64 seed)
        state->s3 = __seed(i, 15);
 }
 
+#ifdef CONFIG_ARCH_RANDOM
+# include <asm/archrandom.h>
+#else
+static inline int arch_get_random_long(unsigned long *v)
+{
+       return 0;
+}
+static inline int arch_get_random_int(unsigned int *v)
+{
+       return 0;
+}
+#endif
+
 #endif /* __KERNEL___ */
 
 #endif /* _LINUX_RANDOM_H */
index 8f4f881a0ad8153dd82150745aee03881448a3b0..2cf4226ade7e60c11ed6d0a3d3f1a4f90496bc24 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef __LINUX_RCUPDATE_H
 #define __LINUX_RCUPDATE_H
 
+#include <linux/types.h>
 #include <linux/cache.h>
 #include <linux/spinlock.h>
 #include <linux/threads.h>
@@ -64,32 +65,74 @@ static inline void rcutorture_record_progress(unsigned long vernum)
 #define ULONG_CMP_GE(a, b)     (ULONG_MAX / 2 >= (a) - (b))
 #define ULONG_CMP_LT(a, b)     (ULONG_MAX / 2 < (a) - (b))
 
+/* Exported common interfaces */
+
+#ifdef CONFIG_PREEMPT_RCU
+
 /**
- * struct rcu_head - callback structure for use with RCU
- * @next: next update requests in a list
- * @func: actual update function to call after the grace period.
+ * call_rcu() - Queue an RCU callback for invocation after a grace period.
+ * @head: structure to be used for queueing the RCU updates.
+ * @func: actual callback function to be invoked after the grace period
+ *
+ * The callback function will be invoked some time after a full grace
+ * period elapses, in other words after all pre-existing RCU read-side
+ * critical sections have completed.  However, the callback function
+ * might well execute concurrently with RCU read-side critical sections
+ * that started after call_rcu() was invoked.  RCU read-side critical
+ * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
+ * and may be nested.
  */
-struct rcu_head {
-       struct rcu_head *next;
-       void (*func)(struct rcu_head *head);
-};
+extern void call_rcu(struct rcu_head *head,
+                             void (*func)(struct rcu_head *head));
 
-/* Exported common interfaces */
+#else /* #ifdef CONFIG_PREEMPT_RCU */
+
+/* In classic RCU, call_rcu() is just call_rcu_sched(). */
+#define        call_rcu        call_rcu_sched
+
+#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
+
+/**
+ * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
+ * @head: structure to be used for queueing the RCU updates.
+ * @func: actual callback function to be invoked after the grace period
+ *
+ * The callback function will be invoked some time after a full grace
+ * period elapses, in other words after all currently executing RCU
+ * read-side critical sections have completed. call_rcu_bh() assumes
+ * that the read-side critical sections end on completion of a softirq
+ * handler. This means that read-side critical sections in process
+ * context must not be interrupted by softirqs. This interface is to be
+ * used when most of the read-side critical sections are in softirq context.
+ * RCU read-side critical sections are delimited by :
+ *  - rcu_read_lock() and  rcu_read_unlock(), if in interrupt context.
+ *  OR
+ *  - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
+ *  These may be nested.
+ */
+extern void call_rcu_bh(struct rcu_head *head,
+                       void (*func)(struct rcu_head *head));
+
+/**
+ * call_rcu_sched() - Queue an RCU for invocation after sched grace period.
+ * @head: structure to be used for queueing the RCU updates.
+ * @func: actual callback function to be invoked after the grace period
+ *
+ * The callback function will be invoked some time after a full grace
+ * period elapses, in other words after all currently executing RCU
+ * read-side critical sections have completed. call_rcu_sched() assumes
+ * that the read-side critical sections end on enabling of preemption
+ * or on voluntary preemption.
+ * RCU read-side critical sections are delimited by :
+ *  - rcu_read_lock_sched() and  rcu_read_unlock_sched(),
+ *  OR
+ *  anything that disables preemption.
+ *  These may be nested.
+ */
 extern void call_rcu_sched(struct rcu_head *head,
                           void (*func)(struct rcu_head *rcu));
-extern void synchronize_sched(void);
-extern void rcu_barrier_bh(void);
-extern void rcu_barrier_sched(void);
-
-static inline void __rcu_read_lock_bh(void)
-{
-       local_bh_disable();
-}
 
-static inline void __rcu_read_unlock_bh(void)
-{
-       local_bh_enable();
-}
+extern void synchronize_sched(void);
 
 #ifdef CONFIG_PREEMPT_RCU
 
@@ -152,6 +195,15 @@ static inline void rcu_exit_nohz(void)
 
 #endif /* #else #ifdef CONFIG_NO_HZ */
 
+/*
+ * Infrastructure to implement the synchronize_() primitives in
+ * TREE_RCU and rcu_barrier_() primitives in TINY_RCU.
+ */
+
+typedef void call_rcu_func_t(struct rcu_head *head,
+                            void (*func)(struct rcu_head *head));
+void wait_rcu_gp(call_rcu_func_t crf);
+
 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
 #include <linux/rcutree.h>
 #elif defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU)
@@ -297,19 +349,31 @@ extern int rcu_my_thread_group_empty(void);
 /**
  * rcu_lockdep_assert - emit lockdep splat if specified condition not met
  * @c: condition to check
+ * @s: informative message
  */
-#define rcu_lockdep_assert(c)                                          \
+#define rcu_lockdep_assert(c, s)                                       \
        do {                                                            \
                static bool __warned;                                   \
                if (debug_lockdep_rcu_enabled() && !__warned && !(c)) { \
                        __warned = true;                                \
-                       lockdep_rcu_dereference(__FILE__, __LINE__);    \
+                       lockdep_rcu_suspicious(__FILE__, __LINE__, s);  \
                }                                                       \
        } while (0)
 
+#define rcu_sleep_check()                                              \
+       do {                                                            \
+               rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),     \
+                                  "Illegal context switch in RCU-bh"   \
+                                  " read-side critical section");      \
+               rcu_lockdep_assert(!lock_is_held(&rcu_sched_lock_map),  \
+                                  "Illegal context switch in RCU-sched"\
+                                  " read-side critical section");      \
+       } while (0)
+
 #else /* #ifdef CONFIG_PROVE_RCU */
 
-#define rcu_lockdep_assert(c) do { } while (0)
+#define rcu_lockdep_assert(c, s) do { } while (0)
+#define rcu_sleep_check() do { } while (0)
 
 #endif /* #else #ifdef CONFIG_PROVE_RCU */
 
@@ -338,14 +402,16 @@ extern int rcu_my_thread_group_empty(void);
 #define __rcu_dereference_check(p, c, space) \
        ({ \
                typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
-               rcu_lockdep_assert(c); \
+               rcu_lockdep_assert(c, "suspicious rcu_dereference_check()" \
+                                     " usage"); \
                rcu_dereference_sparse(p, space); \
                smp_read_barrier_depends(); \
                ((typeof(*p) __force __kernel *)(_________p1)); \
        })
 #define __rcu_dereference_protected(p, c, space) \
        ({ \
-               rcu_lockdep_assert(c); \
+               rcu_lockdep_assert(c, "suspicious rcu_dereference_protected()" \
+                                     " usage"); \
                rcu_dereference_sparse(p, space); \
                ((typeof(*p) __force __kernel *)(p)); \
        })
@@ -359,15 +425,15 @@ extern int rcu_my_thread_group_empty(void);
 #define __rcu_dereference_index_check(p, c) \
        ({ \
                typeof(p) _________p1 = ACCESS_ONCE(p); \
-               rcu_lockdep_assert(c); \
+               rcu_lockdep_assert(c, \
+                                  "suspicious rcu_dereference_index_check()" \
+                                  " usage"); \
                smp_read_barrier_depends(); \
                (_________p1); \
        })
 #define __rcu_assign_pointer(p, v, space) \
        ({ \
-               if (!__builtin_constant_p(v) || \
-                   ((v) != NULL)) \
-                       smp_wmb(); \
+               smp_wmb(); \
                (p) = (typeof(*v) __force space *)(v); \
        })
 
@@ -500,26 +566,6 @@ extern int rcu_my_thread_group_empty(void);
 #define rcu_dereference_protected(p, c) \
        __rcu_dereference_protected((p), (c), __rcu)
 
-/**
- * rcu_dereference_bh_protected() - fetch RCU-bh pointer when updates prevented
- * @p: The pointer to read, prior to dereferencing
- * @c: The conditions under which the dereference will take place
- *
- * This is the RCU-bh counterpart to rcu_dereference_protected().
- */
-#define rcu_dereference_bh_protected(p, c) \
-       __rcu_dereference_protected((p), (c), __rcu)
-
-/**
- * rcu_dereference_sched_protected() - fetch RCU-sched pointer when updates prevented
- * @p: The pointer to read, prior to dereferencing
- * @c: The conditions under which the dereference will take place
- *
- * This is the RCU-sched counterpart to rcu_dereference_protected().
- */
-#define rcu_dereference_sched_protected(p, c) \
-       __rcu_dereference_protected((p), (c), __rcu)
-
 
 /**
  * rcu_dereference() - fetch RCU-protected pointer for dereferencing
@@ -630,7 +676,7 @@ static inline void rcu_read_unlock(void)
  */
 static inline void rcu_read_lock_bh(void)
 {
-       __rcu_read_lock_bh();
+       local_bh_disable();
        __acquire(RCU_BH);
        rcu_read_acquire_bh();
 }
@@ -644,7 +690,7 @@ static inline void rcu_read_unlock_bh(void)
 {
        rcu_read_release_bh();
        __release(RCU_BH);
-       __rcu_read_unlock_bh();
+       local_bh_enable();
 }
 
 /**
@@ -698,11 +744,18 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
  * any prior initialization.  Returns the value assigned.
  *
  * Inserts memory barriers on architectures that require them
- * (pretty much all of them other than x86), and also prevents
- * the compiler from reordering the code that initializes the
- * structure after the pointer assignment.  More importantly, this
- * call documents which pointers will be dereferenced by RCU read-side
- * code.
+ * (which is most of them), and also prevents the compiler from
+ * reordering the code that initializes the structure after the pointer
+ * assignment.  More importantly, this call documents which pointers
+ * will be dereferenced by RCU read-side code.
+ *
+ * In some special cases, you may use RCU_INIT_POINTER() instead
+ * of rcu_assign_pointer().  RCU_INIT_POINTER() is a bit faster due
+ * to the fact that it does not constrain either the CPU or the compiler.
+ * That said, using RCU_INIT_POINTER() when you should have used
+ * rcu_assign_pointer() is a very bad thing that results in
+ * impossible-to-diagnose memory corruption.  So please be careful.
+ * See the RCU_INIT_POINTER() comment header for details.
  */
 #define rcu_assign_pointer(p, v) \
        __rcu_assign_pointer((p), (v), __rcu)
@@ -710,105 +763,38 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
 /**
  * RCU_INIT_POINTER() - initialize an RCU protected pointer
  *
- * Initialize an RCU-protected pointer in such a way to avoid RCU-lockdep
- * splats.
+ * Initialize an RCU-protected pointer in special cases where readers
+ * do not need ordering constraints on the CPU or the compiler.  These
+ * special cases are:
+ *
+ * 1.  This use of RCU_INIT_POINTER() is NULLing out the pointer -or-
+ * 2.  The caller has taken whatever steps are required to prevent
+ *     RCU readers from concurrently accessing this pointer -or-
+ * 3.  The referenced data structure has already been exposed to
+ *     readers either at compile time or via rcu_assign_pointer() -and-
+ *     a.      You have not made -any- reader-visible changes to
+ *             this structure since then -or-
+ *     b.      It is OK for readers accessing this structure from its
+ *             new location to see the old state of the structure.  (For
+ *             example, the changes were to statistical counters or to
+ *             other state where exact synchronization is not required.)
+ *
+ * Failure to follow these rules governing use of RCU_INIT_POINTER() will
+ * result in impossible-to-diagnose memory corruption.  As in the structures
+ * will look OK in crash dumps, but any concurrent RCU readers might
+ * see pre-initialized values of the referenced data structure.  So
+ * please be very careful how you use RCU_INIT_POINTER()!!!
+ *
+ * If you are creating an RCU-protected linked structure that is accessed
+ * by a single external-to-structure RCU-protected pointer, then you may
+ * use RCU_INIT_POINTER() to initialize the internal RCU-protected
+ * pointers, but you must use rcu_assign_pointer() to initialize the
+ * external-to-structure pointer -after- you have completely initialized
+ * the reader-accessible portions of the linked structure.
  */
 #define RCU_INIT_POINTER(p, v) \
                p = (typeof(*v) __force __rcu *)(v)
 
-/* Infrastructure to implement the synchronize_() primitives. */
-
-struct rcu_synchronize {
-       struct rcu_head head;
-       struct completion completion;
-};
-
-extern void wakeme_after_rcu(struct rcu_head  *head);
-
-#ifdef CONFIG_PREEMPT_RCU
-
-/**
- * call_rcu() - Queue an RCU callback for invocation after a grace period.
- * @head: structure to be used for queueing the RCU updates.
- * @func: actual callback function to be invoked after the grace period
- *
- * The callback function will be invoked some time after a full grace
- * period elapses, in other words after all pre-existing RCU read-side
- * critical sections have completed.  However, the callback function
- * might well execute concurrently with RCU read-side critical sections
- * that started after call_rcu() was invoked.  RCU read-side critical
- * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
- * and may be nested.
- */
-extern void call_rcu(struct rcu_head *head,
-                             void (*func)(struct rcu_head *head));
-
-#else /* #ifdef CONFIG_PREEMPT_RCU */
-
-/* In classic RCU, call_rcu() is just call_rcu_sched(). */
-#define        call_rcu        call_rcu_sched
-
-#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
-
-/**
- * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
- * @head: structure to be used for queueing the RCU updates.
- * @func: actual callback function to be invoked after the grace period
- *
- * The callback function will be invoked some time after a full grace
- * period elapses, in other words after all currently executing RCU
- * read-side critical sections have completed. call_rcu_bh() assumes
- * that the read-side critical sections end on completion of a softirq
- * handler. This means that read-side critical sections in process
- * context must not be interrupted by softirqs. This interface is to be
- * used when most of the read-side critical sections are in softirq context.
- * RCU read-side critical sections are delimited by :
- *  - rcu_read_lock() and  rcu_read_unlock(), if in interrupt context.
- *  OR
- *  - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context.
- *  These may be nested.
- */
-extern void call_rcu_bh(struct rcu_head *head,
-                       void (*func)(struct rcu_head *head));
-
-/*
- * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
- * by call_rcu() and rcu callback execution, and are therefore not part of the
- * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
- */
-
-#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
-# define STATE_RCU_HEAD_READY  0
-# define STATE_RCU_HEAD_QUEUED 1
-
-extern struct debug_obj_descr rcuhead_debug_descr;
-
-static inline void debug_rcu_head_queue(struct rcu_head *head)
-{
-       WARN_ON_ONCE((unsigned long)head & 0x3);
-       debug_object_activate(head, &rcuhead_debug_descr);
-       debug_object_active_state(head, &rcuhead_debug_descr,
-                                 STATE_RCU_HEAD_READY,
-                                 STATE_RCU_HEAD_QUEUED);
-}
-
-static inline void debug_rcu_head_unqueue(struct rcu_head *head)
-{
-       debug_object_active_state(head, &rcuhead_debug_descr,
-                                 STATE_RCU_HEAD_QUEUED,
-                                 STATE_RCU_HEAD_READY);
-       debug_object_deactivate(head, &rcuhead_debug_descr);
-}
-#else  /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-static inline void debug_rcu_head_queue(struct rcu_head *head)
-{
-}
-
-static inline void debug_rcu_head_unqueue(struct rcu_head *head)
-{
-}
-#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
-
 static __always_inline bool __is_kfree_rcu_offset(unsigned long offset)
 {
        return offset < 4096;
@@ -827,18 +813,6 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset)
        call_rcu(head, (rcu_callback)offset);
 }
 
-extern void kfree(const void *);
-
-static inline void __rcu_reclaim(struct rcu_head *head)
-{
-       unsigned long offset = (unsigned long)head->func;
-
-       if (__is_kfree_rcu_offset(offset))
-               kfree((void *)head - offset);
-       else
-               head->func(head);
-}
-
 /**
  * kfree_rcu() - kfree an object after a grace period.
  * @ptr:       pointer to kfree
index 52b3e0281fd0ab2e5699783ca6f206a653bd280a..00b7a5e493d22340725e43553884d2f36972198c 100644 (file)
 
 #include <linux/cache.h>
 
+#ifdef CONFIG_RCU_BOOST
 static inline void rcu_init(void)
 {
 }
+#else /* #ifdef CONFIG_RCU_BOOST */
+void rcu_init(void);
+#endif /* #else #ifdef CONFIG_RCU_BOOST */
+
+static inline void rcu_barrier_bh(void)
+{
+       wait_rcu_gp(call_rcu_bh);
+}
+
+static inline void rcu_barrier_sched(void)
+{
+       wait_rcu_gp(call_rcu_sched);
+}
 
 #ifdef CONFIG_TINY_RCU
 
@@ -45,9 +59,13 @@ static inline void rcu_barrier(void)
 
 #else /* #ifdef CONFIG_TINY_RCU */
 
-void rcu_barrier(void);
 void synchronize_rcu_expedited(void);
 
+static inline void rcu_barrier(void)
+{
+       wait_rcu_gp(call_rcu);
+}
+
 #endif /* #else #ifdef CONFIG_TINY_RCU */
 
 static inline void synchronize_rcu_bh(void)
index e65d06634dd80c7afc94ea7032110bcd925ac258..67458468f1a8508becb63997f20271de14df458e 100644 (file)
@@ -67,6 +67,8 @@ static inline void synchronize_rcu_bh_expedited(void)
 }
 
 extern void rcu_barrier(void);
+extern void rcu_barrier_bh(void);
+extern void rcu_barrier_sched(void);
 
 extern unsigned long rcutorture_testseq;
 extern unsigned long rcutorture_vernum;
index 60a65cd7e1a01baef9007e0c97d4aca1d6d04b7b..449e2642da9561df9c2c0a36a4a654695bb05bf0 100644 (file)
 struct i2c_client;
 struct spi_device;
 
+/**
+ * Default value for a register.  We use an array of structs rather
+ * than a simple array as many modern devices have very sparse
+ * register maps.
+ *
+ * @reg: Register address.
+ * @def: Register default value.
+ */
+struct reg_default {
+       unsigned int reg;
+       unsigned int def;
+};
+
+/**
+ * Configuration for the register map of a device.
+ *
+ * @reg_bits: Number of bits in a register address, mandatory.
+ * @val_bits: Number of bits in a register value, mandatory.
+ *
+ * @writeable_reg: Optional callback returning true if the register
+ *                 can be written to.
+ * @readable_reg: Optional callback returning true if the register
+ *                can be read from.
+ * @volatile_reg: Optional callback returning true if the register
+ *                value can't be cached.
+ * @precious_reg: Optional callback returning true if the rgister
+ *                should not be read outside of a call from the driver
+ *                (eg, a clear on read interrupt status register).
+ *
+ * @max_register: Optional, specifies the maximum valid register index.
+ * @reg_defaults: Power on reset values for registers (for use with
+ *                register cache support).
+ * @num_reg_defaults: Number of elements in reg_defaults.
+ */
 struct regmap_config {
        int reg_bits;
        int val_bits;
+
+       bool (*writeable_reg)(struct device *dev, unsigned int reg);
+       bool (*readable_reg)(struct device *dev, unsigned int reg);
+       bool (*volatile_reg)(struct device *dev, unsigned int reg);
+       bool (*precious_reg)(struct device *dev, unsigned int reg);
+
+       unsigned int max_register;
+       struct reg_default *reg_defaults;
+       int num_reg_defaults;
 };
 
 typedef int (*regmap_hw_write)(struct device *dev, const void *data,
@@ -37,8 +80,6 @@ typedef int (*regmap_hw_read)(struct device *dev,
 /**
  * Description of a hardware bus for the register map infrastructure.
  *
- * @list: Internal use.
- * @type: Bus type, used to identify bus to be used for a device.
  * @write: Write operation.
  * @gather_write: Write operation with split register/value, return -ENOTSUPP
  *                if not implemented  on a given device.
@@ -50,8 +91,6 @@ typedef int (*regmap_hw_read)(struct device *dev,
  *                  a read.
  */
 struct regmap_bus {
-       struct list_head list;
-       struct bus_type *type;
        regmap_hw_write write;
        regmap_hw_gather_write gather_write;
        regmap_hw_read read;
index 26f6ea4444e39fedda935b5505439a6de3301f41..b47771aa57180b6d553fbdb9363973f28569fde6 100644 (file)
@@ -123,7 +123,7 @@ struct regulator_bulk_data {
        const char *supply;
        struct regulator *consumer;
 
-       /* Internal use */
+       /* private: Internal use */
        int ret;
 };
 
index 4ac2c0578e0ff9133c4c761fcf3291879ae646d4..7bb54b40206dc12c518cdf282c87337c7c86e60d 100644 (file)
@@ -219,7 +219,7 @@ extern char ___assert_task_state[1 - 2*!!(
                        ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
 #define task_contributes_to_load(task) \
                                ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \
-                                (task->flags & PF_FREEZING) == 0)
+                                (task->flags & PF_FROZEN) == 0)
 
 #define __set_task_state(tsk, state_value)             \
        do { (tsk)->state = (state_value); } while (0)
@@ -270,7 +270,6 @@ extern void init_idle_bootup_task(struct task_struct *idle);
 
 extern int runqueue_is_locked(int cpu);
 
-extern cpumask_var_t nohz_cpu_mask;
 #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
 extern void select_nohz_load_balancer(int stop_tick);
 extern int get_nohz_timer_target(void);
@@ -1260,9 +1259,6 @@ struct task_struct {
 #ifdef CONFIG_PREEMPT_RCU
        int rcu_read_lock_nesting;
        char rcu_read_unlock_special;
-#if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU)
-       int rcu_boosted;
-#endif /* #if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) */
        struct list_head rcu_node_entry;
 #endif /* #ifdef CONFIG_PREEMPT_RCU */
 #ifdef CONFIG_TREE_PREEMPT_RCU
@@ -1756,7 +1752,6 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 /*
  * Per process flags
  */
-#define PF_STARTING    0x00000002      /* being created */
 #define PF_EXITING     0x00000004      /* getting shut down */
 #define PF_EXITPIDONE  0x00000008      /* pi exit done on shut down */
 #define PF_VCPU                0x00000010      /* I'm a virtual CPU */
@@ -1769,7 +1764,6 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *
 #define PF_MEMALLOC    0x00000800      /* Allocating memory */
 #define PF_NPROC_EXCEEDED 0x00001000   /* set_user noticed that RLIMIT_NPROC was exceeded */
 #define PF_USED_MATH   0x00002000      /* if unset the fpu must be initialized before use */
-#define PF_FREEZING    0x00004000      /* freeze in progress. do not account to load */
 #define PF_NOFREEZE    0x00008000      /* this thread should not be frozen */
 #define PF_FROZEN      0x00010000      /* frozen for system suspend */
 #define PF_FSTRANS     0x00020000      /* inside a filesystem transaction */
@@ -2334,7 +2328,7 @@ static inline int thread_group_empty(struct task_struct *p)
  * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
  * pins the final release of task.io_context.  Also protects ->cpuset and
- * ->cgroup.subsys[].
+ * ->cgroup.subsys[]. And ->vfork_done.
  *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
index ebd2a53a3d073cbf0489848c50725250a3f6872b..d9f7ec41ba5124e6aa59da368eff8b59906d321c 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/key.h>
 #include <linux/xfrm.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 #include <net/flow.h>
 
 /* Maximum number of letters for an LSM name string */
@@ -147,6 +148,10 @@ extern int mmap_min_addr_handler(struct ctl_table *table, int write,
                                 void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
+/* security_inode_init_security callback function to write xattrs */
+typedef int (*initxattrs) (struct inode *inode,
+                          const struct xattr *xattr_array, void *fs_data);
+
 #ifdef CONFIG_SECURITY
 
 struct security_mnt_opts {
@@ -1704,8 +1709,11 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
 int security_inode_alloc(struct inode *inode);
 void security_inode_free(struct inode *inode);
 int security_inode_init_security(struct inode *inode, struct inode *dir,
-                                const struct qstr *qstr, char **name,
-                                void **value, size_t *len);
+                                const struct qstr *qstr,
+                                initxattrs initxattrs, void *fs_data);
+int security_old_inode_init_security(struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr, char **name,
+                                    void **value, size_t *len);
 int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
                         struct dentry *new_dentry);
@@ -2034,11 +2042,19 @@ static inline void security_inode_free(struct inode *inode)
 static inline int security_inode_init_security(struct inode *inode,
                                                struct inode *dir,
                                                const struct qstr *qstr,
-                                               char **name,
-                                               void **value,
-                                               size_t *len)
+                                               initxattrs initxattrs,
+                                               void *fs_data)
 {
-       return -EOPNOTSUPP;
+       return 0;
+}
+
+static inline int security_old_inode_init_security(struct inode *inode,
+                                                  struct inode *dir,
+                                                  const struct qstr *qstr,
+                                                  char **name, void **value,
+                                                  size_t *len)
+{
+       return 0;
 }
 
 static inline int security_inode_create(struct inode *dir,
index 7b996ed86d5b823d1b92a0df82da033cafa4d6c3..7b0e1773f9cd0b2efb859f0d2a6b10dedfe594ef 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/rcupdate.h>
 #include <linux/dmaengine.h>
 #include <linux/hrtimer.h>
+#include <linux/dma-mapping.h>
 
 /* Don't change this without changing skb_csum_unnecessary! */
 #define CHECKSUM_NONE 0
@@ -322,6 +323,8 @@ typedef unsigned char *sk_buff_data_t;
  *     @queue_mapping: Queue mapping for multiqueue devices
  *     @ndisc_nodetype: router type (from link layer)
  *     @ooo_okay: allow the mapping of a socket to a queue to be changed
+ *     @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport
+ *             ports.
  *     @dma_cookie: a cookie to one of several possible DMA operations
  *             done by skb DMA functions
  *     @secmark: security marking
@@ -414,6 +417,7 @@ struct sk_buff {
        __u8                    ndisc_nodetype:2;
 #endif
        __u8                    ooo_okay:1;
+       __u8                    l4_rxhash:1;
        kmemcheck_bitfield_end(flags2);
 
        /* 0/13 bit hole */
@@ -572,11 +576,11 @@ extern unsigned int   skb_find_text(struct sk_buff *skb, unsigned int from,
                                    unsigned int to, struct ts_config *config,
                                    struct ts_state *state);
 
-extern __u32 __skb_get_rxhash(struct sk_buff *skb);
+extern void __skb_get_rxhash(struct sk_buff *skb);
 static inline __u32 skb_get_rxhash(struct sk_buff *skb)
 {
        if (!skb->rxhash)
-               skb->rxhash = __skb_get_rxhash(skb);
+               __skb_get_rxhash(skb);
 
        return skb->rxhash;
 }
@@ -1126,14 +1130,47 @@ static inline int skb_pagelen(const struct sk_buff *skb)
        return len + skb_headlen(skb);
 }
 
-static inline void skb_fill_page_desc(struct sk_buff *skb, int i,
-                                     struct page *page, int off, int size)
+/**
+ * __skb_fill_page_desc - initialise a paged fragment in an skb
+ * @skb: buffer containing fragment to be initialised
+ * @i: paged fragment index to initialise
+ * @page: the page to use for this fragment
+ * @off: the offset to the data with @page
+ * @size: the length of the data
+ *
+ * Initialises the @i'th fragment of @skb to point to &size bytes at
+ * offset @off within @page.
+ *
+ * Does not take any additional reference on the fragment.
+ */
+static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
+                                       struct page *page, int off, int size)
 {
        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
        frag->page                = page;
        frag->page_offset         = off;
        frag->size                = size;
+}
+
+/**
+ * skb_fill_page_desc - initialise a paged fragment in an skb
+ * @skb: buffer containing fragment to be initialised
+ * @i: paged fragment index to initialise
+ * @page: the page to use for this fragment
+ * @off: the offset to the data with @page
+ * @size: the length of the data
+ *
+ * As per __skb_fill_page_desc() -- initialises the @i'th fragment of
+ * @skb to point to &size bytes at offset @off within @page. In
+ * addition updates @skb such that @i is the last fragment.
+ *
+ * Does not take any additional reference on the fragment.
+ */
+static inline void skb_fill_page_desc(struct sk_buff *skb, int i,
+                                     struct page *page, int off, int size)
+{
+       __skb_fill_page_desc(skb, i, page, off, size);
        skb_shinfo(skb)->nr_frags = i + 1;
 }
 
@@ -1627,6 +1664,138 @@ static inline void netdev_free_page(struct net_device *dev, struct page *page)
        __free_page(page);
 }
 
+/**
+ * skb_frag_page - retrieve the page refered to by a paged fragment
+ * @frag: the paged fragment
+ *
+ * Returns the &struct page associated with @frag.
+ */
+static inline struct page *skb_frag_page(const skb_frag_t *frag)
+{
+       return frag->page;
+}
+
+/**
+ * __skb_frag_ref - take an addition reference on a paged fragment.
+ * @frag: the paged fragment
+ *
+ * Takes an additional reference on the paged fragment @frag.
+ */
+static inline void __skb_frag_ref(skb_frag_t *frag)
+{
+       get_page(skb_frag_page(frag));
+}
+
+/**
+ * skb_frag_ref - take an addition reference on a paged fragment of an skb.
+ * @skb: the buffer
+ * @f: the fragment offset.
+ *
+ * Takes an additional reference on the @f'th paged fragment of @skb.
+ */
+static inline void skb_frag_ref(struct sk_buff *skb, int f)
+{
+       __skb_frag_ref(&skb_shinfo(skb)->frags[f]);
+}
+
+/**
+ * __skb_frag_unref - release a reference on a paged fragment.
+ * @frag: the paged fragment
+ *
+ * Releases a reference on the paged fragment @frag.
+ */
+static inline void __skb_frag_unref(skb_frag_t *frag)
+{
+       put_page(skb_frag_page(frag));
+}
+
+/**
+ * skb_frag_unref - release a reference on a paged fragment of an skb.
+ * @skb: the buffer
+ * @f: the fragment offset
+ *
+ * Releases a reference on the @f'th paged fragment of @skb.
+ */
+static inline void skb_frag_unref(struct sk_buff *skb, int f)
+{
+       __skb_frag_unref(&skb_shinfo(skb)->frags[f]);
+}
+
+/**
+ * skb_frag_address - gets the address of the data contained in a paged fragment
+ * @frag: the paged fragment buffer
+ *
+ * Returns the address of the data within @frag. The page must already
+ * be mapped.
+ */
+static inline void *skb_frag_address(const skb_frag_t *frag)
+{
+       return page_address(skb_frag_page(frag)) + frag->page_offset;
+}
+
+/**
+ * skb_frag_address_safe - gets the address of the data contained in a paged fragment
+ * @frag: the paged fragment buffer
+ *
+ * Returns the address of the data within @frag. Checks that the page
+ * is mapped and returns %NULL otherwise.
+ */
+static inline void *skb_frag_address_safe(const skb_frag_t *frag)
+{
+       void *ptr = page_address(skb_frag_page(frag));
+       if (unlikely(!ptr))
+               return NULL;
+
+       return ptr + frag->page_offset;
+}
+
+/**
+ * __skb_frag_set_page - sets the page contained in a paged fragment
+ * @frag: the paged fragment
+ * @page: the page to set
+ *
+ * Sets the fragment @frag to contain @page.
+ */
+static inline void __skb_frag_set_page(skb_frag_t *frag, struct page *page)
+{
+       frag->page = page;
+       __skb_frag_ref(frag);
+}
+
+/**
+ * skb_frag_set_page - sets the page contained in a paged fragment of an skb
+ * @skb: the buffer
+ * @f: the fragment offset
+ * @page: the page to set
+ *
+ * Sets the @f'th fragment of @skb to contain @page.
+ */
+static inline void skb_frag_set_page(struct sk_buff *skb, int f,
+                                    struct page *page)
+{
+       __skb_frag_set_page(&skb_shinfo(skb)->frags[f], page);
+}
+
+/**
+ * skb_frag_dma_map - maps a paged fragment via the DMA API
+ * @device: the device to map the fragment to
+ * @frag: the paged fragment to map
+ * @offset: the offset within the fragment (starting at the
+ *          fragment's own offset)
+ * @size: the number of bytes to map
+ * @direction: the direction of the mapping (%PCI_DMA_*)
+ *
+ * Maps the page associated with @frag to @device.
+ */
+static inline dma_addr_t skb_frag_dma_map(struct device *dev,
+                                         const skb_frag_t *frag,
+                                         size_t offset, size_t size,
+                                         enum dma_data_direction dir)
+{
+       return dma_map_page(dev, skb_frag_page(frag),
+                           frag->page_offset + offset, size, dir);
+}
+
 /**
  *     skb_clone_writable - is the header of a clone writable
  *     @skb: buffer to check
index efbf459d571c03eed928edd5f2fda9fc6f835019..98941203a27f248cf8215f998d17e15e12aed598 100644 (file)
 #define SSB_SPROM8_OFDM5GLPO           0x014A  /* 5.2GHz OFDM power offset */
 #define SSB_SPROM8_OFDM5GHPO           0x014E  /* 5.8GHz OFDM power offset */
 
+/* Values for boardflags_lo read from SPROM */
+#define SSB_BFL_BTCOEXIST              0x0001  /* implements Bluetooth coexistance */
+#define SSB_BFL_PACTRL                 0x0002  /* GPIO 9 controlling the PA */
+#define SSB_BFL_AIRLINEMODE            0x0004  /* implements GPIO 13 radio disable indication */
+#define SSB_BFL_RSSI                   0x0008  /* software calculates nrssi slope. */
+#define SSB_BFL_ENETSPI                        0x0010  /* has ephy roboswitch spi */
+#define SSB_BFL_XTAL_NOSLOW            0x0020  /* no slow clock available */
+#define SSB_BFL_CCKHIPWR               0x0040  /* can do high power CCK transmission */
+#define SSB_BFL_ENETADM                        0x0080  /* has ADMtek switch */
+#define SSB_BFL_ENETVLAN               0x0100  /* can do vlan */
+#define SSB_BFL_AFTERBURNER            0x0200  /* supports Afterburner mode */
+#define SSB_BFL_NOPCI                  0x0400  /* board leaves PCI floating */
+#define SSB_BFL_FEM                    0x0800  /* supports the Front End Module */
+#define SSB_BFL_EXTLNA                 0x1000  /* has an external LNA */
+#define SSB_BFL_HGPA                   0x2000  /* had high gain PA */
+#define SSB_BFL_BTCMOD                 0x4000  /* BFL_BTCOEXIST is given in alternate GPIOs */
+#define SSB_BFL_ALTIQ                  0x8000  /* alternate I/Q settings */
+
+/* Values for boardflags_hi read from SPROM */
+#define SSB_BFH_NOPA                   0x0001  /* has no PA */
+#define SSB_BFH_RSSIINV                        0x0002  /* RSSI uses positive slope (not TSSI) */
+#define SSB_BFH_PAREF                  0x0004  /* uses the PARef LDO */
+#define SSB_BFH_3TSWITCH               0x0008  /* uses a triple throw switch shared with bluetooth */
+#define SSB_BFH_PHASESHIFT             0x0010  /* can support phase shifter */
+#define SSB_BFH_BUCKBOOST              0x0020  /* has buck/booster */
+#define SSB_BFH_FEM_BT                 0x0040  /* has FEM and switch to share antenna with bluetooth */
+
+/* Values for boardflags2_lo read from SPROM */
+#define SSB_BFL2_RXBB_INT_REG_DIS      0x0001  /* external RX BB regulator present */
+#define SSB_BFL2_APLL_WAR              0x0002  /* alternative A-band PLL settings implemented */
+#define SSB_BFL2_TXPWRCTRL_EN          0x0004  /* permits enabling TX Power Control */
+#define SSB_BFL2_2X4_DIV               0x0008  /* 2x4 diversity switch */
+#define SSB_BFL2_5G_PWRGAIN            0x0010  /* supports 5G band power gain */
+#define SSB_BFL2_PCIEWAR_OVR           0x0020  /* overrides ASPM and Clkreq settings */
+#define SSB_BFL2_CAESERS_BRD           0x0040  /* is Caesers board (unused) */
+#define SSB_BFL2_BTC3WIRE              0x0080  /* used 3-wire bluetooth coexist */
+#define SSB_BFL2_SKWRKFEM_BRD          0x0100  /* 4321mcm93 uses Skyworks FEM */
+#define SSB_BFL2_SPUR_WAR              0x0200  /* has a workaround for clock-harmonic spurs */
+#define SSB_BFL2_GPLL_WAR              0x0400  /* altenative G-band PLL settings implemented */
+
 /* Values for SSB_SPROM1_BINF_CCODE */
 enum {
        SSB_SPROM1CCODE_WORLD = 0,
similarity index 98%
rename from drivers/net/sungem_phy.h
rename to include/linux/sungem_phy.h
index af02f9479cbbab0c7dcfd85da2a91a0d2cee26eb..bd9be9f59d3a7ad5afc2b8c10af4681bee7d79af 100644 (file)
@@ -61,7 +61,7 @@ struct mii_phy
 /* Pass in a struct mii_phy with dev, mdio_read and mdio_write
  * filled, the remaining fields will be filled on return
  */
-extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
+extern int sungem_phy_probe(struct mii_phy *phy, int mii_id);
 
 
 /* MII definitions missing from mii.h */
index 6bbcef22e1054766f01a36f6e352c0ea5d06770c..46f3548aef2d23368c4f655f7e3d9cd82fa79c94 100644 (file)
@@ -34,6 +34,58 @@ typedef int __bitwise suspend_state_t;
 #define PM_SUSPEND_MEM         ((__force suspend_state_t) 3)
 #define PM_SUSPEND_MAX         ((__force suspend_state_t) 4)
 
+enum suspend_stat_step {
+       SUSPEND_FREEZE = 1,
+       SUSPEND_PREPARE,
+       SUSPEND_SUSPEND,
+       SUSPEND_SUSPEND_NOIRQ,
+       SUSPEND_RESUME_NOIRQ,
+       SUSPEND_RESUME
+};
+
+struct suspend_stats {
+       int     success;
+       int     fail;
+       int     failed_freeze;
+       int     failed_prepare;
+       int     failed_suspend;
+       int     failed_suspend_noirq;
+       int     failed_resume;
+       int     failed_resume_noirq;
+#define        REC_FAILED_NUM  2
+       int     last_failed_dev;
+       char    failed_devs[REC_FAILED_NUM][40];
+       int     last_failed_errno;
+       int     errno[REC_FAILED_NUM];
+       int     last_failed_step;
+       enum suspend_stat_step  failed_steps[REC_FAILED_NUM];
+};
+
+extern struct suspend_stats suspend_stats;
+
+static inline void dpm_save_failed_dev(const char *name)
+{
+       strlcpy(suspend_stats.failed_devs[suspend_stats.last_failed_dev],
+               name,
+               sizeof(suspend_stats.failed_devs[0]));
+       suspend_stats.last_failed_dev++;
+       suspend_stats.last_failed_dev %= REC_FAILED_NUM;
+}
+
+static inline void dpm_save_failed_errno(int err)
+{
+       suspend_stats.errno[suspend_stats.last_failed_errno] = err;
+       suspend_stats.last_failed_errno++;
+       suspend_stats.last_failed_errno %= REC_FAILED_NUM;
+}
+
+static inline void dpm_save_failed_step(enum suspend_stat_step step)
+{
+       suspend_stats.failed_steps[suspend_stats.last_failed_step] = step;
+       suspend_stats.last_failed_step++;
+       suspend_stats.last_failed_step %= REC_FAILED_NUM;
+}
+
 /**
  * struct platform_suspend_ops - Callbacks for managing platform dependent
  *     system sleep states.
@@ -334,4 +386,38 @@ static inline void unlock_system_sleep(void)
 }
 #endif
 
+#ifdef CONFIG_ARCH_SAVE_PAGE_KEYS
+/*
+ * The ARCH_SAVE_PAGE_KEYS functions can be used by an architecture
+ * to save/restore additional information to/from the array of page
+ * frame numbers in the hibernation image. For s390 this is used to
+ * save and restore the storage key for each page that is included
+ * in the hibernation image.
+ */
+unsigned long page_key_additional_pages(unsigned long pages);
+int page_key_alloc(unsigned long pages);
+void page_key_free(void);
+void page_key_read(unsigned long *pfn);
+void page_key_memorize(unsigned long *pfn);
+void page_key_write(void *address);
+
+#else /* !CONFIG_ARCH_SAVE_PAGE_KEYS */
+
+static inline unsigned long page_key_additional_pages(unsigned long pages)
+{
+       return 0;
+}
+
+static inline int  page_key_alloc(unsigned long pages)
+{
+       return 0;
+}
+
+static inline void page_key_free(void) {}
+static inline void page_key_read(unsigned long *pfn) {}
+static inline void page_key_memorize(unsigned long *pfn) {}
+static inline void page_key_write(void *address) {}
+
+#endif /* !CONFIG_ARCH_SAVE_PAGE_KEYS */
+
 #endif /* _LINUX_SUSPEND_H */
index b004e557caa9c064c15b41b26bf773677f529913..2ef4385da6bf7a70ed60a8a01b7fdb54201c1840 100644 (file)
@@ -410,7 +410,28 @@ struct gps_event_hdr {
        u16 plen;
 } __attribute__ ((packed));
 
-/* platform data */
+/**
+ * struct ti_st_plat_data - platform data shared between ST driver and
+ *     platform specific board file which adds the ST device.
+ * @nshutdown_gpio: Host's GPIO line to which chip's BT_EN is connected.
+ * @dev_name: The UART/TTY name to which chip is interfaced. (eg: /dev/ttyS1)
+ * @flow_cntrl: Should always be 1, since UART's CTS/RTS is used for PM
+ *     purposes.
+ * @baud_rate: The baud rate supported by the Host UART controller, this will
+ *     be shared across with the chip via a HCI VS command from User-Space Init
+ *     Mgr application.
+ * @suspend:
+ * @resume: legacy PM routines hooked to platform specific board file, so as
+ *     to take chip-host interface specific action.
+ * @chip_enable:
+ * @chip_disable: Platform/Interface specific mux mode setting, GPIO
+ *     configuring, Host side PM disabling etc.. can be done here.
+ * @chip_asleep:
+ * @chip_awake: Chip specific deep sleep states is communicated to Host
+ *     specific board-xx.c to take actions such as cut UART clocks when chip
+ *     asleep or run host faster when chip awake etc..
+ *
+ */
 struct ti_st_plat_data {
        long nshutdown_gpio;
        unsigned char dev_name[UART_DEV_NAME_LEN]; /* uart name */
@@ -418,6 +439,10 @@ struct ti_st_plat_data {
        unsigned long baud_rate;
        int (*suspend)(struct platform_device *, pm_message_t);
        int (*resume)(struct platform_device *);
+       int (*chip_enable) (struct kim_data_s *);
+       int (*chip_disable) (struct kim_data_s *);
+       int (*chip_asleep) (struct kim_data_s *);
+       int (*chip_awake) (struct kim_data_s *);
 };
 
 #endif /* TI_WILINK_ST_H */
index 44bc0c5617e1c227df1b3699dbdac1ac7dbab191..5f2ede82b3d67e5223089f6db9cec489267991ef 100644 (file)
@@ -421,6 +421,8 @@ extern void tty_driver_flush_buffer(struct tty_struct *tty);
 extern void tty_throttle(struct tty_struct *tty);
 extern void tty_unthrottle(struct tty_struct *tty);
 extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws);
+extern void tty_driver_remove_tty(struct tty_driver *driver,
+                                 struct tty_struct *tty);
 extern void tty_shutdown(struct tty_struct *tty);
 extern void tty_free_termios(struct tty_struct *tty);
 extern int is_current_pgrp_orphaned(void);
index 9deeac85524078f0ef97b140f270c39391509f51..ecdaeb98b293727274b6511ee7ef523c00324564 100644 (file)
@@ -47,6 +47,9 @@
  *
  *     This routine is called synchronously when a particular tty device
  *     is closed for the last time freeing up the resources.
+ *     Note that tty_shutdown() is not called if ops->shutdown is defined.
+ *     This means one is responsible to take care of calling ops->remove (e.g.
+ *     via tty_driver_remove_tty) and releasing tty->termios.
  *
  *
  * void (*cleanup)(struct tty_struct * tty);
index 176da8c1fbb180e20a925ba79e80420bdf66b7a9..57a97234bec13d37ce2809cde476152abe907d2e 100644 (file)
@@ -238,6 +238,16 @@ struct ustat {
        char                    f_fpack[6];
 };
 
+/**
+ * struct rcu_head - callback structure for use with RCU
+ * @next: next update requests in a list
+ * @func: actual update function to call after the grace period.
+ */
+struct rcu_head {
+       struct rcu_head *next;
+       void (*func)(struct rcu_head *head);
+};
+
 #endif /* __KERNEL__ */
 #endif /*  __ASSEMBLY__ */
 #endif /* _LINUX_TYPES_H */
index 39c88c5ad19dfd85c5fcbed38837d514c477679f..add4790b21fe4ee18635db9456a43db71bb39997 100644 (file)
@@ -155,6 +155,9 @@ static inline bool virtio_has_feature(const struct virtio_device *vdev,
 #define virtio_config_val(vdev, fbit, offset, v) \
        virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(*v))
 
+#define virtio_config_val_len(vdev, fbit, offset, v, len) \
+       virtio_config_buf((vdev), (fbit), (offset), (v), (len))
+
 static inline int virtio_config_buf(struct virtio_device *vdev,
                                    unsigned int fbit,
                                    unsigned int offset,
index aed54c50aa665b89e61bf007c6715e65a26cbefb..b20cb965c3226b7cecab5a4e9629abec64ec2984 100644 (file)
@@ -30,6 +30,9 @@
 #define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
 
 /* Security namespace */
+#define XATTR_EVM_SUFFIX "evm"
+#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
+
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
 
@@ -67,6 +70,12 @@ struct xattr_handler {
                   size_t size, int flags, int handler_flags);
 };
 
+struct xattr {
+       char *name;
+       void *value;
+       size_t value_len;
+};
+
 ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
 ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
 ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
@@ -78,7 +87,10 @@ ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer,
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
 int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
 int generic_removexattr(struct dentry *dentry, const char *name);
-
+ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
+                          char **xattr_value, size_t size, gfp_t flags);
+int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
+                 const char *value, size_t size, gfp_t flags);
 #endif  /*  __KERNEL__  */
 
 #endif /* _LINUX_XATTR_H */
index 342dcf13d039a8470ddcf4628b55c510c7fb13fe..d83a013008717faa8c73b8eda856ae1ba7c0065e 100644 (file)
@@ -288,6 +288,35 @@ enum p9_perm_t {
        P9_DMSETVTX = 0x00010000,
 };
 
+/* 9p2000.L open flags */
+#define P9_DOTL_RDONLY        00000000
+#define P9_DOTL_WRONLY        00000001
+#define P9_DOTL_RDWR          00000002
+#define P9_DOTL_NOACCESS      00000003
+#define P9_DOTL_CREATE        00000100
+#define P9_DOTL_EXCL          00000200
+#define P9_DOTL_NOCTTY        00000400
+#define P9_DOTL_TRUNC         00001000
+#define P9_DOTL_APPEND        00002000
+#define P9_DOTL_NONBLOCK      00004000
+#define P9_DOTL_DSYNC         00010000
+#define P9_DOTL_FASYNC        00020000
+#define P9_DOTL_DIRECT        00040000
+#define P9_DOTL_LARGEFILE     00100000
+#define P9_DOTL_DIRECTORY     00200000
+#define P9_DOTL_NOFOLLOW      00400000
+#define P9_DOTL_NOATIME       01000000
+#define P9_DOTL_CLOEXEC       02000000
+#define P9_DOTL_SYNC          04000000
+
+/* 9p2000.L at flags */
+#define P9_DOTL_AT_REMOVEDIR           0x200
+
+/* 9p2000.L lock type */
+#define P9_LOCK_TYPE_RDLCK 0
+#define P9_LOCK_TYPE_WRLCK 1
+#define P9_LOCK_TYPE_UNLCK 2
+
 /**
  * enum p9_qid_t - QID types
  * @P9_QTDIR: directory
@@ -330,6 +359,9 @@ enum p9_qid_t {
 /* Room for readdir header */
 #define P9_READDIRHDRSZ        24
 
+/* size of header for zero copy read/write */
+#define P9_ZC_HDR_SZ 4096
+
 /**
  * struct p9_qid - file system entity information
  * @type: 8-bit type &p9_qid_t
@@ -526,10 +558,6 @@ struct p9_rstatfs {
  * @tag: transaction id of the request
  * @offset: used by marshalling routines to track current position in buffer
  * @capacity: used by marshalling routines to track total malloc'd capacity
- * @pubuf: Payload user buffer given by the caller
- * @pkbuf: Payload kernel buffer given by the caller
- * @pbuf_size: pubuf/pkbuf(only one will be !NULL) size to be read/write.
- * @private: For transport layer's use.
  * @sdata: payload
  *
  * &p9_fcall represents the structure for all 9P RPC
@@ -546,10 +574,6 @@ struct p9_fcall {
 
        size_t offset;
        size_t capacity;
-       char __user *pubuf;
-       char *pkbuf;
-       size_t pbuf_size;
-       void *private;
 
        u8 *sdata;
 };
index 83531ebeee99084746d9679dce3c29e47471e38c..adcbb20f65118be16489b65f2e087d3bf3128980 100644 (file)
 #ifndef NET_9P_TRANSPORT_H
 #define NET_9P_TRANSPORT_H
 
-#define P9_TRANS_PREF_PAYLOAD_MASK 0x1
-
-/* Default. Add Payload to PDU before sending it down to transport layer */
-#define P9_TRANS_PREF_PAYLOAD_DEF  0x0
-/* Send pay load separately to transport layer along with PDU.*/
-#define P9_TRANS_PREF_PAYLOAD_SEP  0x1
-
 /**
  * struct p9_trans_module - transport module interface
  * @list: used to maintain a list of currently available transports
@@ -56,13 +49,14 @@ struct p9_trans_module {
        struct list_head list;
        char *name;             /* name of transport */
        int maxsize;            /* max message size of transport */
-       int pref;               /* Preferences of this transport */
        int def;                /* this transport should be default */
        struct module *owner;
        int (*create)(struct p9_client *, const char *, char *);
        void (*close) (struct p9_client *);
        int (*request) (struct p9_client *, struct p9_req_t *req);
        int (*cancel) (struct p9_client *, struct p9_req_t *req);
+       int (*zc_request)(struct p9_client *, struct p9_req_t *,
+                         char *, char *, int , int, int, int);
 };
 
 void v9fs_register_trans(struct p9_trans_module *m);
index 582e4ae707530f45df3f3a513dc1e1a418e89784..cbc6bb0a68386da58ec539fe19fa3cc7356fdfdc 100644 (file)
@@ -8,7 +8,7 @@
 
 #define TEMP_VALID_LIFETIME            (7*86400)
 #define TEMP_PREFERRED_LIFETIME                (86400)
-#define REGEN_MAX_RETRY                        (5)
+#define REGEN_MAX_RETRY                        (3)
 #define MAX_DESYNC_FACTOR              (600)
 
 #define ADDR_CHECK_FREQUENCY           (120*HZ)
index 4f34ad25e75c62b3ce2f5c642c79d7c26ecdcf58..6fa114074ff98ee9ed01f8a61302189f711cbf0f 100644 (file)
@@ -354,8 +354,8 @@ struct l2cap_chan {
        __u8            retry_count;
        __u8            num_acked;
        __u16           sdu_len;
-       __u16           partial_sdu_len;
        struct sk_buff  *sdu;
+       struct sk_buff  *sdu_last_frag;
 
        __u8            remote_tx_win;
        __u8            remote_max_tx;
@@ -454,7 +454,6 @@ enum {
 #define L2CAP_CONF_MAX_CONF_RSP 2
 
 enum {
-       CONN_SAR_SDU,
        CONN_SREJ_SENT,
        CONN_WAIT_F,
        CONN_SREJ_ACT,
diff --git a/include/net/cfg80211-wext.h b/include/net/cfg80211-wext.h
new file mode 100644 (file)
index 0000000..25baddc
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __NET_CFG80211_WEXT_H
+#define __NET_CFG80211_WEXT_H
+/*
+ * 802.11 device and configuration interface -- wext handlers
+ *
+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+/*
+ * Temporary wext handlers & helper functions
+ *
+ * These are used only by drivers that aren't yet fully
+ * converted to cfg80211.
+ */
+int cfg80211_wext_giwname(struct net_device *dev,
+                         struct iw_request_info *info,
+                         char *name, char *extra);
+int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
+                         u32 *mode, char *extra);
+int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
+                         u32 *mode, char *extra);
+int cfg80211_wext_siwscan(struct net_device *dev,
+                         struct iw_request_info *info,
+                         union iwreq_data *wrqu, char *extra);
+int cfg80211_wext_giwscan(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_point *data, char *extra);
+int cfg80211_wext_giwrange(struct net_device *dev,
+                          struct iw_request_info *info,
+                          struct iw_point *data, char *extra);
+int cfg80211_wext_siwrts(struct net_device *dev,
+                        struct iw_request_info *info,
+                        struct iw_param *rts, char *extra);
+int cfg80211_wext_giwrts(struct net_device *dev,
+                        struct iw_request_info *info,
+                        struct iw_param *rts, char *extra);
+int cfg80211_wext_siwfrag(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_param *frag, char *extra);
+int cfg80211_wext_giwfrag(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_param *frag, char *extra);
+int cfg80211_wext_giwretry(struct net_device *dev,
+                          struct iw_request_info *info,
+                          struct iw_param *retry, char *extra);
+
+#endif /* __NET_CFG80211_WEXT_H */
index d17f47fc9e31b9a3298b1911b5c46c9fb34d3400..497e5839d87c10c8be10de02bf5c031cad6994a2 100644 (file)
 #include <linux/ieee80211.h>
 #include <net/regulatory.h>
 
-/* remove once we remove the wext stuff */
-#include <net/iw_handler.h>
-#include <linux/wireless.h>
-
-
 /**
  * DOC: Introduction
  *
@@ -338,6 +333,36 @@ struct survey_info {
        s8 noise;
 };
 
+/**
+ * struct cfg80211_crypto_settings - Crypto settings
+ * @wpa_versions: indicates which, if any, WPA versions are enabled
+ *     (from enum nl80211_wpa_versions)
+ * @cipher_group: group key cipher suite (or 0 if unset)
+ * @n_ciphers_pairwise: number of AP supported unicast ciphers
+ * @ciphers_pairwise: unicast key cipher suites
+ * @n_akm_suites: number of AKM suites
+ * @akm_suites: AKM suites
+ * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
+ *     sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ *     required to assume that the port is unauthorized until authorized by
+ *     user space. Otherwise, port is marked authorized by default.
+ * @control_port_ethertype: the control port protocol that should be
+ *     allowed through even on unauthorized ports
+ * @control_port_no_encrypt: TRUE to prevent encryption of control port
+ *     protocol frames.
+ */
+struct cfg80211_crypto_settings {
+       u32 wpa_versions;
+       u32 cipher_group;
+       int n_ciphers_pairwise;
+       u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES];
+       int n_akm_suites;
+       u32 akm_suites[NL80211_MAX_NR_AKM_SUITES];
+       bool control_port;
+       __be16 control_port_ethertype;
+       bool control_port_no_encrypt;
+};
+
 /**
  * struct beacon_parameters - beacon parameters
  *
@@ -351,11 +376,38 @@ struct survey_info {
  * @dtim_period: DTIM period or zero if not changed
  * @head_len: length of @head
  * @tail_len: length of @tail
+ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from
+ *     user space)
+ * @ssid_len: length of @ssid
+ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames
+ * @crypto: crypto settings
+ * @privacy: the BSS uses privacy
+ * @auth_type: Authentication type (algorithm)
+ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL
+ * @beacon_ies_len: length of beacon_ies in octets
+ * @proberesp_ies: extra information element(s) to add into Probe Response
+ *     frames or %NULL
+ * @proberesp_ies_len: length of proberesp_ies in octets
+ * @assocresp_ies: extra information element(s) to add into (Re)Association
+ *     Response frames or %NULL
+ * @assocresp_ies_len: length of assocresp_ies in octets
  */
 struct beacon_parameters {
        u8 *head, *tail;
        int interval, dtim_period;
        int head_len, tail_len;
+       const u8 *ssid;
+       size_t ssid_len;
+       enum nl80211_hidden_ssid hidden_ssid;
+       struct cfg80211_crypto_settings crypto;
+       bool privacy;
+       enum nl80211_auth_type auth_type;
+       const u8 *beacon_ies;
+       size_t beacon_ies_len;
+       const u8 *proberesp_ies;
+       size_t proberesp_ies_len;
+       const u8 *assocresp_ies;
+       size_t assocresp_ies_len;
 };
 
 /**
@@ -426,6 +478,7 @@ struct station_parameters {
  * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
  * @STATION_INFO_BSS_PARAM: @bss_param filled
  * @STATION_INFO_CONNECTED_TIME: @connected_time filled
+ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
  */
 enum station_info_flags {
        STATION_INFO_INACTIVE_TIME      = 1<<0,
@@ -444,7 +497,8 @@ enum station_info_flags {
        STATION_INFO_SIGNAL_AVG         = 1<<13,
        STATION_INFO_RX_BITRATE         = 1<<14,
        STATION_INFO_BSS_PARAM          = 1<<15,
-       STATION_INFO_CONNECTED_TIME     = 1<<16
+       STATION_INFO_CONNECTED_TIME     = 1<<16,
+       STATION_INFO_ASSOC_REQ_IES      = 1<<17
 };
 
 /**
@@ -536,6 +590,11 @@ struct sta_bss_parameters {
  *     This number should increase every time the list of stations
  *     changes, i.e. when a station is added or removed, so that
  *     userspace can tell whether it got a consistent snapshot.
+ * @assoc_req_ies: IEs from (Re)Association Request.
+ *     This is used only when in AP mode with drivers that do not use
+ *     user space MLME/SME implementation. The information is provided for
+ *     the cfg80211_new_sta() calls to notify user space of the IEs.
+ * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
  */
 struct station_info {
        u32 filled;
@@ -558,6 +617,14 @@ struct station_info {
        struct sta_bss_parameters bss_param;
 
        int generation;
+
+       const u8 *assoc_req_ies;
+       size_t assoc_req_ies_len;
+
+       /*
+        * Note: Add a new enum station_info_flags value for each new field and
+        * use it to check which fields are initialized.
+        */
 };
 
 /**
@@ -895,36 +962,6 @@ struct cfg80211_bss {
 const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
 
 
-/**
- * struct cfg80211_crypto_settings - Crypto settings
- * @wpa_versions: indicates which, if any, WPA versions are enabled
- *     (from enum nl80211_wpa_versions)
- * @cipher_group: group key cipher suite (or 0 if unset)
- * @n_ciphers_pairwise: number of AP supported unicast ciphers
- * @ciphers_pairwise: unicast key cipher suites
- * @n_akm_suites: number of AKM suites
- * @akm_suites: AKM suites
- * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
- *     sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
- *     required to assume that the port is unauthorized until authorized by
- *     user space. Otherwise, port is marked authorized by default.
- * @control_port_ethertype: the control port protocol that should be
- *     allowed through even on unauthorized ports
- * @control_port_no_encrypt: TRUE to prevent encryption of control port
- *     protocol frames.
- */
-struct cfg80211_crypto_settings {
-       u32 wpa_versions;
-       u32 cipher_group;
-       int n_ciphers_pairwise;
-       u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES];
-       int n_akm_suites;
-       u32 akm_suites[NL80211_MAX_NR_AKM_SUITES];
-       bool control_port;
-       __be16 control_port_ethertype;
-       bool control_port_no_encrypt;
-};
-
 /**
  * struct cfg80211_auth_request - Authentication request data
  *
@@ -1865,6 +1902,9 @@ struct wiphy {
         * you need use set_wiphy_dev() (see below) */
        struct device dev;
 
+       /* protects ->resume, ->suspend sysfs callbacks against unregister hw */
+       bool registered;
+
        /* dir in debugfs: ieee80211/<wiphyname> */
        struct dentry *debugfsdir;
 
@@ -2230,6 +2270,69 @@ extern int ieee80211_radiotap_iterator_next(
 extern const unsigned char rfc1042_header[6];
 extern const unsigned char bridge_tunnel_header[6];
 
+/* Parsed Information Elements */
+struct ieee802_11_elems {
+       u8 *ie_start;
+       size_t total_len;
+
+       /* pointers to IEs */
+       u8 *ssid;
+       u8 *supp_rates;
+       u8 *fh_params;
+       u8 *ds_params;
+       u8 *cf_params;
+       struct ieee80211_tim_ie *tim;
+       u8 *ibss_params;
+       u8 *challenge;
+       u8 *wpa;
+       u8 *rsn;
+       u8 *erp_info;
+       u8 *ext_supp_rates;
+       u8 *wmm_info;
+       u8 *wmm_param;
+       struct ieee80211_ht_cap *ht_cap_elem;
+       struct ieee80211_ht_info *ht_info_elem;
+       struct ieee80211_meshconf_ie *mesh_config;
+       u8 *mesh_id;
+       u8 *peering;
+       u8 *preq;
+       u8 *prep;
+       u8 *perr;
+       struct ieee80211_rann_ie *rann;
+       u8 *ch_switch_elem;
+       u8 *country_elem;
+       u8 *pwr_constr_elem;
+       u8 *quiet_elem; /* first quite element */
+       u8 *timeout_int;
+
+       /* length of them, respectively */
+       u8 ssid_len;
+       u8 supp_rates_len;
+       u8 fh_params_len;
+       u8 ds_params_len;
+       u8 cf_params_len;
+       u8 tim_len;
+       u8 ibss_params_len;
+       u8 challenge_len;
+       u8 wpa_len;
+       u8 rsn_len;
+       u8 erp_info_len;
+       u8 ext_supp_rates_len;
+       u8 wmm_info_len;
+       u8 wmm_param_len;
+       u8 mesh_id_len;
+       u8 peering_len;
+       u8 preq_len;
+       u8 prep_len;
+       u8 perr_len;
+       u8 ch_switch_elem_len;
+       u8 country_elem_len;
+       u8 pwr_constr_elem_len;
+       u8 quiet_elem_len;
+       u8 num_of_quiet_elem;   /* can be more the one */
+       u8 timeout_int_len;
+};
+
 /**
  * ieee80211_get_hdrlen_from_skb - get header length from data
  *
@@ -2392,113 +2495,6 @@ extern int freq_reg_info(struct wiphy *wiphy,
                         u32 desired_bw_khz,
                         const struct ieee80211_reg_rule **reg_rule);
 
-/*
- * Temporary wext handlers & helper functions
- *
- * In the future cfg80211 will simply assign the entire wext handler
- * structure to netdevs it manages, but we're not there yet.
- */
-int cfg80211_wext_giwname(struct net_device *dev,
-                         struct iw_request_info *info,
-                         char *name, char *extra);
-int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
-                         u32 *mode, char *extra);
-int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
-                         u32 *mode, char *extra);
-int cfg80211_wext_siwscan(struct net_device *dev,
-                         struct iw_request_info *info,
-                         union iwreq_data *wrqu, char *extra);
-int cfg80211_wext_giwscan(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_point *data, char *extra);
-int cfg80211_wext_siwmlme(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_point *data, char *extra);
-int cfg80211_wext_giwrange(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *extra);
-int cfg80211_wext_siwgenie(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *extra);
-int cfg80211_wext_siwauth(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *data, char *extra);
-int cfg80211_wext_giwauth(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *data, char *extra);
-
-int cfg80211_wext_siwfreq(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_freq *freq, char *extra);
-int cfg80211_wext_giwfreq(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_freq *freq, char *extra);
-int cfg80211_wext_siwessid(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *ssid);
-int cfg80211_wext_giwessid(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *ssid);
-int cfg80211_wext_siwrate(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *rate, char *extra);
-int cfg80211_wext_giwrate(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *rate, char *extra);
-
-int cfg80211_wext_siwrts(struct net_device *dev,
-                        struct iw_request_info *info,
-                        struct iw_param *rts, char *extra);
-int cfg80211_wext_giwrts(struct net_device *dev,
-                        struct iw_request_info *info,
-                        struct iw_param *rts, char *extra);
-int cfg80211_wext_siwfrag(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *frag, char *extra);
-int cfg80211_wext_giwfrag(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *frag, char *extra);
-int cfg80211_wext_siwretry(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *retry, char *extra);
-int cfg80211_wext_giwretry(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *retry, char *extra);
-int cfg80211_wext_siwencodeext(struct net_device *dev,
-                              struct iw_request_info *info,
-                              struct iw_point *erq, char *extra);
-int cfg80211_wext_siwencode(struct net_device *dev,
-                           struct iw_request_info *info,
-                           struct iw_point *erq, char *keybuf);
-int cfg80211_wext_giwencode(struct net_device *dev,
-                           struct iw_request_info *info,
-                           struct iw_point *erq, char *keybuf);
-int cfg80211_wext_siwtxpower(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *data, char *keybuf);
-int cfg80211_wext_giwtxpower(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *data, char *keybuf);
-struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev);
-
-int cfg80211_wext_siwpower(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *wrq, char *extra);
-int cfg80211_wext_giwpower(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *wrq, char *extra);
-
-int cfg80211_wext_siwap(struct net_device *dev,
-                       struct iw_request_info *info,
-                       struct sockaddr *ap_addr, char *extra);
-int cfg80211_wext_giwap(struct net_device *dev,
-                       struct iw_request_info *info,
-                       struct sockaddr *ap_addr, char *extra);
-
-int cfg80211_wext_siwpmksa(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *extra);
-
 /*
  * callbacks for asynchronous cfg80211 methods, notification
  * functions and BSS handling helpers
index 13d507d69ddbcfb01bd717ba1fd2659cc74e53d6..4fb6c43817918992f8334c49022d5184ea45c8e4 100644 (file)
@@ -325,7 +325,14 @@ static inline void skb_dst_force(struct sk_buff *skb)
 static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
 {
        skb->dev = dev;
-       skb->rxhash = 0;
+
+       /*
+        * Clear rxhash so that we can recalulate the hash for the
+        * encapsulated packet, unless we have already determine the hash
+        * over the L4 4-tuple.
+        */
+       if (!skb->l4_rxhash)
+               skb->rxhash = 0;
        skb_set_queue_mapping(skb, 0);
        skb_dst_drop(skb);
        nf_reset(skb);
index 11cf373970a960d248a3c7d240c62e9f20f3512c..51a7031b4aa379463a56fca35f69f97dfdf4ffa8 100644 (file)
@@ -41,6 +41,7 @@ struct inet6_ifaddr {
        struct in6_addr         addr;
        __u32                   prefix_len;
        
+       /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */
        __u32                   valid_lft;
        __u32                   prefered_lft;
        atomic_t                refcnt;
index f82a1e87737241ec0b7a5cb961b0a90e7ed8d503..f2419cf44cefd96d899b0f18e0b9f33c582d04d0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/poll.h>
 #include <linux/socket.h>
+#include <net/iucv/iucv.h>
 
 #ifndef AF_IUCV
 #define AF_IUCV                32
@@ -33,6 +34,7 @@ enum {
 };
 
 #define IUCV_QUEUELEN_DEFAULT  65535
+#define IUCV_HIPER_MSGLIM_DEFAULT      128
 #define IUCV_CONN_TIMEOUT      (HZ * 40)
 #define IUCV_DISCONN_TIMEOUT   (HZ * 2)
 #define IUCV_CONN_IDLE_TIMEOUT (HZ * 60)
@@ -57,8 +59,51 @@ struct sock_msg_q {
        spinlock_t              lock;
 };
 
+#define AF_IUCV_FLAG_ACK 0x1
+#define AF_IUCV_FLAG_SYN 0x2
+#define AF_IUCV_FLAG_FIN 0x4
+#define AF_IUCV_FLAG_WIN 0x8
+
+struct af_iucv_trans_hdr {
+       u16 magic;
+       u8 version;
+       u8 flags;
+       u16 window;
+       char destNodeID[8];
+       char destUserID[8];
+       char destAppName[16];
+       char srcNodeID[8];
+       char srcUserID[8];
+       char srcAppName[16];             /* => 70 bytes */
+       struct iucv_message iucv_hdr;    /* => 33 bytes */
+       u8 pad;                          /* total 104 bytes */
+} __packed;
+
+enum iucv_tx_notify {
+       /* transmission of skb is completed and was successful */
+       TX_NOTIFY_OK = 0,
+       /* target is unreachable */
+       TX_NOTIFY_UNREACHABLE = 1,
+       /* transfer pending queue full */
+       TX_NOTIFY_TPQFULL = 2,
+       /* general error */
+       TX_NOTIFY_GENERALERROR = 3,
+       /* transmission of skb is pending - may interleave
+        * with TX_NOTIFY_DELAYED_* */
+       TX_NOTIFY_PENDING = 4,
+       /* transmission of skb was done successfully (delayed) */
+       TX_NOTIFY_DELAYED_OK = 5,
+       /* target unreachable (detected delayed) */
+       TX_NOTIFY_DELAYED_UNREACHABLE = 6,
+       /* general error (detected delayed) */
+       TX_NOTIFY_DELAYED_GENERALERROR = 7,
+};
+
 #define iucv_sk(__sk) ((struct iucv_sock *) __sk)
 
+#define AF_IUCV_TRANS_IUCV 0
+#define AF_IUCV_TRANS_HIPER 1
+
 struct iucv_sock {
        struct sock             sk;
        char                    src_user_id[8];
@@ -75,6 +120,13 @@ struct iucv_sock {
        unsigned int            send_tag;
        u8                      flags;
        u16                     msglimit;
+       u16                     msglimit_peer;
+       atomic_t                msg_sent;
+       atomic_t                msg_recv;
+       atomic_t                pendings;
+       int                     transport;
+       void                    (*sk_txnotify)(struct sk_buff *skb,
+                                              enum iucv_tx_notify n);
 };
 
 /* iucv socket options (SOL_IUCV) */
index 1121baa9f695828aa444de2b41f50b7cf0260f99..0894ced31957cf64f992e4676fdd402056e2a39b 100644 (file)
@@ -120,7 +120,7 @@ struct iucv_message {
        u32 reply_size;
        u8  rmmsg[8];
        u8  flags;
-};
+} __packed;
 
 /*
  * struct iucv_handler
@@ -459,3 +459,37 @@ int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
 int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
                          u8 flags, u32 srccls, void *buffer, size_t size,
                          void *answer, size_t asize, size_t *residual);
+
+struct iucv_interface {
+       int (*message_receive)(struct iucv_path *path, struct iucv_message *msg,
+               u8 flags, void *buffer, size_t size, size_t *residual);
+       int (*__message_receive)(struct iucv_path *path,
+               struct iucv_message *msg, u8 flags, void *buffer, size_t size,
+               size_t *residual);
+       int (*message_reply)(struct iucv_path *path, struct iucv_message *msg,
+               u8 flags, void *reply, size_t size);
+       int (*message_reject)(struct iucv_path *path, struct iucv_message *msg);
+       int (*message_send)(struct iucv_path *path, struct iucv_message *msg,
+               u8 flags, u32 srccls, void *buffer, size_t size);
+       int (*__message_send)(struct iucv_path *path, struct iucv_message *msg,
+               u8 flags, u32 srccls, void *buffer, size_t size);
+       int (*message_send2way)(struct iucv_path *path,
+               struct iucv_message *msg, u8 flags, u32 srccls, void *buffer,
+               size_t size, void *answer, size_t asize, size_t *residual);
+       int (*message_purge)(struct iucv_path *path, struct iucv_message *msg,
+               u32 srccls);
+       int (*path_accept)(struct iucv_path *path, struct iucv_handler *handler,
+               u8 userdata[16], void *private);
+       int (*path_connect)(struct iucv_path *path,
+               struct iucv_handler *handler,
+               u8 userid[8], u8 system[8], u8 userdata[16], void *private);
+       int (*path_quiesce)(struct iucv_path *path, u8 userdata[16]);
+       int (*path_resume)(struct iucv_path *path, u8 userdata[16]);
+       int (*path_sever)(struct iucv_path *path, u8 userdata[16]);
+       int (*iucv_register)(struct iucv_handler *handler, int smp);
+       void (*iucv_unregister)(struct iucv_handler *handler, int smp);
+       struct bus_type *bus;
+       struct device *root;
+};
+
+extern struct iucv_interface iucv_if;
index b95bbb083ee8f24d1309fb19d8121d083656da59..2ec896bb72b21787962fb1546b4565b930e503da 100644 (file)
@@ -117,10 +117,7 @@ void lib80211_crypt_info_free(struct lib80211_crypt_info *info);
 int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops);
 int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops);
 struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name);
-void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *, int);
-void lib80211_crypt_deinit_handler(unsigned long);
 void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
                                    struct lib80211_crypt_data **crypt);
-void lib80211_crypt_quiescing(struct lib80211_crypt_info *info);
 
 #endif /* LIB80211_H */
index 9259e97864d78f89046cf5d5068ce7b84f3334ef..2f01d84ca52f2d690eae5f6fd432a92e7b747288 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/if_ether.h>
 #include <linux/skbuff.h>
-#include <linux/wireless.h>
 #include <linux/device.h>
 #include <linux/ieee80211.h>
 #include <net/cfg80211.h>
@@ -1896,11 +1895,6 @@ enum ieee80211_tx_sync_type {
  *     ieee80211_remain_on_channel_expired(). This callback may sleep.
  * @cancel_remain_on_channel: Requests that an ongoing off-channel period is
  *     aborted before it expires. This callback may sleep.
- * @offchannel_tx: Transmit frame on another channel, wait for a response
- *     and return. Reliable TX status must be reported for the frame. If the
- *     return value is 1, then the @remain_on_channel will be used with a
- *     regular transmission (if supported.)
- * @offchannel_tx_cancel_wait: cancel wait associated with offchannel TX
  *
  * @set_ringparam: Set tx and rx ring sizes.
  *
@@ -2019,11 +2013,6 @@ struct ieee80211_ops {
                                 enum nl80211_channel_type channel_type,
                                 int duration);
        int (*cancel_remain_on_channel)(struct ieee80211_hw *hw);
-       int (*offchannel_tx)(struct ieee80211_hw *hw, struct sk_buff *skb,
-                            struct ieee80211_channel *chan,
-                            enum nl80211_channel_type channel_type,
-                            unsigned int wait);
-       int (*offchannel_tx_cancel_wait)(struct ieee80211_hw *hw);
        int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
        void (*get_ringparam)(struct ieee80211_hw *hw,
                              u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
index 8e4062f165b8ec19bab5aeea63730577aa3c31a8..5ac682f73d6389ab4fe4977fb183ab13044929b1 100644 (file)
@@ -686,16 +686,25 @@ static inline void sock_rps_reset_flow(const struct sock *sk)
 #endif
 }
 
-static inline void sock_rps_save_rxhash(struct sock *sk, u32 rxhash)
+static inline void sock_rps_save_rxhash(struct sock *sk,
+                                       const struct sk_buff *skb)
 {
 #ifdef CONFIG_RPS
-       if (unlikely(sk->sk_rxhash != rxhash)) {
+       if (unlikely(sk->sk_rxhash != skb->rxhash)) {
                sock_rps_reset_flow(sk);
-               sk->sk_rxhash = rxhash;
+               sk->sk_rxhash = skb->rxhash;
        }
 #endif
 }
 
+static inline void sock_rps_reset_rxhash(struct sock *sk)
+{
+#ifdef CONFIG_RPS
+       sock_rps_reset_flow(sk);
+       sk->sk_rxhash = 0;
+#endif
+}
+
 #define sk_wait_event(__sk, __timeo, __condition)                      \
        ({      int __rc;                                               \
                release_sock(__sk);                                     \
index c5c5e008e6de742cc2f0a9cc27ed596fd0e91b10..0ac493142056874bef6e7e8f822bb844f95a0b6f 100644 (file)
@@ -34,6 +34,8 @@ struct ore_comp {
 
 struct ore_layout {
        /* Our way of looking at the data_map */
+       enum pnfs_osd_raid_algorithm4
+                raid_algorithm;
        unsigned stripe_unit;
        unsigned mirrors_p1;
 
diff --git a/include/sound/adau1373.h b/include/sound/adau1373.h
new file mode 100644 (file)
index 0000000..1b19c76
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Analog Devices ADAU1373 Audio Codec drive
+ *
+ * Copyright 2011 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __SOUND_ADAU1373_H__
+#define __SOUND_ADAU1373_H__
+
+enum adau1373_micbias_voltage {
+       ADAU1373_MICBIAS_2_9V = 0,
+       ADAU1373_MICBIAS_2_2V = 1,
+       ADAU1373_MICBIAS_2_6V = 2,
+       ADAU1373_MICBIAS_1_8V = 3,
+};
+
+#define ADAU1373_DRC_SIZE 13
+
+struct adau1373_platform_data {
+       bool input_differential[4];
+       bool lineout_differential;
+       bool lineout_ground_sense;
+
+       unsigned int num_drc;
+       uint8_t drc_setting[3][ADAU1373_DRC_SIZE];
+
+       enum adau1373_micbias_voltage micbias1;
+       enum adau1373_micbias_voltage micbias2;
+};
+
+#endif
index 57e71fa33f7ce8eac899870d9e11937a2240a6dd..54cb079b7bf16b7a0b7057135d105ece7db0b986 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/poll.h>
 #include <linux/mm.h>
 #include <linux/bitops.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 
 #define snd_pcm_substream_chip(substream) ((substream)->private_data)
 #define snd_pcm_chip(pcm) ((pcm)->private_data)
@@ -373,7 +373,7 @@ struct snd_pcm_substream {
        int number;
        char name[32];                  /* substream name */
        int stream;                     /* stream (direction) */
-       struct pm_qos_request_list latency_pm_qos_req; /* pm_qos request */
+       struct pm_qos_request latency_pm_qos_req; /* pm_qos request */
        size_t buffer_bytes_max;        /* limit ring buffer size */
        struct snd_dma_buffer dma_buffer;
        unsigned int dma_buf_id;
index e0583b7769cb505648f005be33f8b6c10f3c4049..350b1b395cac56fb876314fd0cf3414ab629b108 100644 (file)
@@ -524,6 +524,8 @@ struct snd_soc_dapm_context {
        enum snd_soc_bias_level target_bias_level;
        struct list_head list;
 
+       int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
+
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_dapm;
 #endif
index aa19f5a32ba8774a085a085d52866ede8d63fd3f..6da55a17fcfd4a208323b067e903f35d4a2c363e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/regmap.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
@@ -260,6 +261,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
 enum snd_soc_control_type {
        SND_SOC_I2C = 1,
        SND_SOC_SPI,
+       SND_SOC_REGMAP,
 };
 
 enum snd_soc_compress_type {
@@ -576,6 +578,7 @@ struct snd_soc_codec {
        const void *reg_def_copy;
        const struct snd_soc_cache_ops *cache_ops;
        struct mutex cache_rw_mutex;
+       int val_bytes;
 
        /* dapm */
        struct snd_soc_dapm_context dapm;
@@ -630,10 +633,14 @@ struct snd_soc_codec_driver {
        /* codec bias level */
        int (*set_bias_level)(struct snd_soc_codec *,
                              enum snd_soc_bias_level level);
+       bool idle_bias_off;
 
        void (*seq_notifier)(struct snd_soc_dapm_context *,
                             enum snd_soc_dapm_type, int);
 
+       /* codec stream completion event */
+       int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
+
        /* probe ordering - for components with runtime dependencies */
        int probe_order;
        int remove_order;
@@ -669,6 +676,9 @@ struct snd_soc_platform_driver {
        /* platform stream ops */
        struct snd_pcm_ops *ops;
 
+       /* platform stream completion event */
+       int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
+
        /* probe ordering - for components with runtime dependencies */
        int probe_order;
        int remove_order;
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
new file mode 100644 (file)
index 0000000..96740e4
--- /dev/null
@@ -0,0 +1,459 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rcu
+
+#if !defined(_TRACE_RCU_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RCU_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracepoint for start/end markers used for utilization calculations.
+ * By convention, the string is of the following forms:
+ *
+ * "Start <activity>" -- Mark the start of the specified activity,
+ *                      such as "context switch".  Nesting is permitted.
+ * "End <activity>" -- Mark the end of the specified activity.
+ *
+ * An "@" character within "<activity>" is a comment character: Data
+ * reduction scripts will ignore the "@" and the remainder of the line.
+ */
+TRACE_EVENT(rcu_utilization,
+
+       TP_PROTO(char *s),
+
+       TP_ARGS(s),
+
+       TP_STRUCT__entry(
+               __field(char *, s)
+       ),
+
+       TP_fast_assign(
+               __entry->s = s;
+       ),
+
+       TP_printk("%s", __entry->s)
+);
+
+#ifdef CONFIG_RCU_TRACE
+
+#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
+
+/*
+ * Tracepoint for grace-period events: starting and ending a grace
+ * period ("start" and "end", respectively), a CPU noting the start
+ * of a new grace period or the end of an old grace period ("cpustart"
+ * and "cpuend", respectively), a CPU passing through a quiescent
+ * state ("cpuqs"), a CPU coming online or going offline ("cpuonl"
+ * and "cpuofl", respectively), and a CPU being kicked for being too
+ * long in dyntick-idle mode ("kick").
+ */
+TRACE_EVENT(rcu_grace_period,
+
+       TP_PROTO(char *rcuname, unsigned long gpnum, char *gpevent),
+
+       TP_ARGS(rcuname, gpnum, gpevent),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(unsigned long, gpnum)
+               __field(char *, gpevent)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->gpnum = gpnum;
+               __entry->gpevent = gpevent;
+       ),
+
+       TP_printk("%s %lu %s",
+                 __entry->rcuname, __entry->gpnum, __entry->gpevent)
+);
+
+/*
+ * Tracepoint for grace-period-initialization events.  These are
+ * distinguished by the type of RCU, the new grace-period number, the
+ * rcu_node structure level, the starting and ending CPU covered by the
+ * rcu_node structure, and the mask of CPUs that will be waited for.
+ * All but the type of RCU are extracted from the rcu_node structure.
+ */
+TRACE_EVENT(rcu_grace_period_init,
+
+       TP_PROTO(char *rcuname, unsigned long gpnum, u8 level,
+                int grplo, int grphi, unsigned long qsmask),
+
+       TP_ARGS(rcuname, gpnum, level, grplo, grphi, qsmask),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(unsigned long, gpnum)
+               __field(u8, level)
+               __field(int, grplo)
+               __field(int, grphi)
+               __field(unsigned long, qsmask)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->gpnum = gpnum;
+               __entry->level = level;
+               __entry->grplo = grplo;
+               __entry->grphi = grphi;
+               __entry->qsmask = qsmask;
+       ),
+
+       TP_printk("%s %lu %u %d %d %lx",
+                 __entry->rcuname, __entry->gpnum, __entry->level,
+                 __entry->grplo, __entry->grphi, __entry->qsmask)
+);
+
+/*
+ * Tracepoint for tasks blocking within preemptible-RCU read-side
+ * critical sections.  Track the type of RCU (which one day might
+ * include SRCU), the grace-period number that the task is blocking
+ * (the current or the next), and the task's PID.
+ */
+TRACE_EVENT(rcu_preempt_task,
+
+       TP_PROTO(char *rcuname, int pid, unsigned long gpnum),
+
+       TP_ARGS(rcuname, pid, gpnum),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(unsigned long, gpnum)
+               __field(int, pid)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->gpnum = gpnum;
+               __entry->pid = pid;
+       ),
+
+       TP_printk("%s %lu %d",
+                 __entry->rcuname, __entry->gpnum, __entry->pid)
+);
+
+/*
+ * Tracepoint for tasks that blocked within a given preemptible-RCU
+ * read-side critical section exiting that critical section.  Track the
+ * type of RCU (which one day might include SRCU) and the task's PID.
+ */
+TRACE_EVENT(rcu_unlock_preempted_task,
+
+       TP_PROTO(char *rcuname, unsigned long gpnum, int pid),
+
+       TP_ARGS(rcuname, gpnum, pid),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(unsigned long, gpnum)
+               __field(int, pid)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->gpnum = gpnum;
+               __entry->pid = pid;
+       ),
+
+       TP_printk("%s %lu %d", __entry->rcuname, __entry->gpnum, __entry->pid)
+);
+
+/*
+ * Tracepoint for quiescent-state-reporting events.  These are
+ * distinguished by the type of RCU, the grace-period number, the
+ * mask of quiescent lower-level entities, the rcu_node structure level,
+ * the starting and ending CPU covered by the rcu_node structure, and
+ * whether there are any blocked tasks blocking the current grace period.
+ * All but the type of RCU are extracted from the rcu_node structure.
+ */
+TRACE_EVENT(rcu_quiescent_state_report,
+
+       TP_PROTO(char *rcuname, unsigned long gpnum,
+                unsigned long mask, unsigned long qsmask,
+                u8 level, int grplo, int grphi, int gp_tasks),
+
+       TP_ARGS(rcuname, gpnum, mask, qsmask, level, grplo, grphi, gp_tasks),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(unsigned long, gpnum)
+               __field(unsigned long, mask)
+               __field(unsigned long, qsmask)
+               __field(u8, level)
+               __field(int, grplo)
+               __field(int, grphi)
+               __field(u8, gp_tasks)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->gpnum = gpnum;
+               __entry->mask = mask;
+               __entry->qsmask = qsmask;
+               __entry->level = level;
+               __entry->grplo = grplo;
+               __entry->grphi = grphi;
+               __entry->gp_tasks = gp_tasks;
+       ),
+
+       TP_printk("%s %lu %lx>%lx %u %d %d %u",
+                 __entry->rcuname, __entry->gpnum,
+                 __entry->mask, __entry->qsmask, __entry->level,
+                 __entry->grplo, __entry->grphi, __entry->gp_tasks)
+);
+
+/*
+ * Tracepoint for quiescent states detected by force_quiescent_state().
+ * These trace events include the type of RCU, the grace-period number
+ * that was blocked by the CPU, the CPU itself, and the type of quiescent
+ * state, which can be "dti" for dyntick-idle mode, "ofl" for CPU offline,
+ * or "kick" when kicking a CPU that has been in dyntick-idle mode for
+ * too long.
+ */
+TRACE_EVENT(rcu_fqs,
+
+       TP_PROTO(char *rcuname, unsigned long gpnum, int cpu, char *qsevent),
+
+       TP_ARGS(rcuname, gpnum, cpu, qsevent),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(unsigned long, gpnum)
+               __field(int, cpu)
+               __field(char *, qsevent)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->gpnum = gpnum;
+               __entry->cpu = cpu;
+               __entry->qsevent = qsevent;
+       ),
+
+       TP_printk("%s %lu %d %s",
+                 __entry->rcuname, __entry->gpnum,
+                 __entry->cpu, __entry->qsevent)
+);
+
+#endif /* #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) */
+
+/*
+ * Tracepoint for dyntick-idle entry/exit events.  These take a string
+ * as argument: "Start" for entering dyntick-idle mode and "End" for
+ * leaving it.
+ */
+TRACE_EVENT(rcu_dyntick,
+
+       TP_PROTO(char *polarity),
+
+       TP_ARGS(polarity),
+
+       TP_STRUCT__entry(
+               __field(char *, polarity)
+       ),
+
+       TP_fast_assign(
+               __entry->polarity = polarity;
+       ),
+
+       TP_printk("%s", __entry->polarity)
+);
+
+/*
+ * Tracepoint for the registration of a single RCU callback function.
+ * The first argument is the type of RCU, the second argument is
+ * a pointer to the RCU callback itself, and the third element is the
+ * new RCU callback queue length for the current CPU.
+ */
+TRACE_EVENT(rcu_callback,
+
+       TP_PROTO(char *rcuname, struct rcu_head *rhp, long qlen),
+
+       TP_ARGS(rcuname, rhp, qlen),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(void *, rhp)
+               __field(void *, func)
+               __field(long, qlen)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->rhp = rhp;
+               __entry->func = rhp->func;
+               __entry->qlen = qlen;
+       ),
+
+       TP_printk("%s rhp=%p func=%pf %ld",
+                 __entry->rcuname, __entry->rhp, __entry->func, __entry->qlen)
+);
+
+/*
+ * Tracepoint for the registration of a single RCU callback of the special
+ * kfree() form.  The first argument is the RCU type, the second argument
+ * is a pointer to the RCU callback, the third argument is the offset
+ * of the callback within the enclosing RCU-protected data structure,
+ * and the fourth argument is the new RCU callback queue length for the
+ * current CPU.
+ */
+TRACE_EVENT(rcu_kfree_callback,
+
+       TP_PROTO(char *rcuname, struct rcu_head *rhp, unsigned long offset,
+                long qlen),
+
+       TP_ARGS(rcuname, rhp, offset, qlen),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(void *, rhp)
+               __field(unsigned long, offset)
+               __field(long, qlen)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->rhp = rhp;
+               __entry->offset = offset;
+               __entry->qlen = qlen;
+       ),
+
+       TP_printk("%s rhp=%p func=%ld %ld",
+                 __entry->rcuname, __entry->rhp, __entry->offset,
+                 __entry->qlen)
+);
+
+/*
+ * Tracepoint for marking the beginning rcu_do_batch, performed to start
+ * RCU callback invocation.  The first argument is the RCU flavor,
+ * the second is the total number of callbacks (including those that
+ * are not yet ready to be invoked), and the third argument is the
+ * current RCU-callback batch limit.
+ */
+TRACE_EVENT(rcu_batch_start,
+
+       TP_PROTO(char *rcuname, long qlen, int blimit),
+
+       TP_ARGS(rcuname, qlen, blimit),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(long, qlen)
+               __field(int, blimit)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->qlen = qlen;
+               __entry->blimit = blimit;
+       ),
+
+       TP_printk("%s CBs=%ld bl=%d",
+                 __entry->rcuname, __entry->qlen, __entry->blimit)
+);
+
+/*
+ * Tracepoint for the invocation of a single RCU callback function.
+ * The first argument is the type of RCU, and the second argument is
+ * a pointer to the RCU callback itself.
+ */
+TRACE_EVENT(rcu_invoke_callback,
+
+       TP_PROTO(char *rcuname, struct rcu_head *rhp),
+
+       TP_ARGS(rcuname, rhp),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(void *, rhp)
+               __field(void *, func)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->rhp = rhp;
+               __entry->func = rhp->func;
+       ),
+
+       TP_printk("%s rhp=%p func=%pf",
+                 __entry->rcuname, __entry->rhp, __entry->func)
+);
+
+/*
+ * Tracepoint for the invocation of a single RCU callback of the special
+ * kfree() form.  The first argument is the RCU flavor, the second
+ * argument is a pointer to the RCU callback, and the third argument
+ * is the offset of the callback within the enclosing RCU-protected
+ * data structure.
+ */
+TRACE_EVENT(rcu_invoke_kfree_callback,
+
+       TP_PROTO(char *rcuname, struct rcu_head *rhp, unsigned long offset),
+
+       TP_ARGS(rcuname, rhp, offset),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(void *, rhp)
+               __field(unsigned long, offset)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->rhp = rhp;
+               __entry->offset = offset;
+       ),
+
+       TP_printk("%s rhp=%p func=%ld",
+                 __entry->rcuname,__entry->rhp, __entry->offset)
+);
+
+/*
+ * Tracepoint for exiting rcu_do_batch after RCU callbacks have been
+ * invoked.  The first argument is the name of the RCU flavor and
+ * the second argument is number of callbacks actually invoked.
+ */
+TRACE_EVENT(rcu_batch_end,
+
+       TP_PROTO(char *rcuname, int callbacks_invoked),
+
+       TP_ARGS(rcuname, callbacks_invoked),
+
+       TP_STRUCT__entry(
+               __field(char *, rcuname)
+               __field(int, callbacks_invoked)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->callbacks_invoked = callbacks_invoked;
+       ),
+
+       TP_printk("%s CBs-invoked=%d",
+                 __entry->rcuname, __entry->callbacks_invoked)
+);
+
+#else /* #ifdef CONFIG_RCU_TRACE */
+
+#define trace_rcu_grace_period(rcuname, gpnum, gpevent) do { } while (0)
+#define trace_rcu_grace_period_init(rcuname, gpnum, level, grplo, grphi, qsmask) do { } while (0)
+#define trace_rcu_preempt_task(rcuname, pid, gpnum) do { } while (0)
+#define trace_rcu_unlock_preempted_task(rcuname, gpnum, pid) do { } while (0)
+#define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, grplo, grphi, gp_tasks) do { } while (0)
+#define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0)
+#define trace_rcu_dyntick(polarity) do { } while (0)
+#define trace_rcu_callback(rcuname, rhp, qlen) do { } while (0)
+#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen) do { } while (0)
+#define trace_rcu_batch_start(rcuname, qlen, blimit) do { } while (0)
+#define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0)
+#define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0)
+#define trace_rcu_batch_end(rcuname, callbacks_invoked) do { } while (0)
+
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+#endif /* _TRACE_RCU_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/regmap.h b/include/trace/events/regmap.h
new file mode 100644 (file)
index 0000000..e35e37c
--- /dev/null
@@ -0,0 +1,112 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM regmap
+
+#if !defined(_TRACE_REGMAP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_REGMAP_H
+
+#include <linux/device.h>
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+struct regmap;
+
+/*
+ * Log register events
+ */
+DECLARE_EVENT_CLASS(regmap_reg,
+
+       TP_PROTO(struct device *dev, unsigned int reg,
+                unsigned int val),
+
+       TP_ARGS(dev, reg, val),
+
+       TP_STRUCT__entry(
+               __string(       name,           dev_name(dev)   )
+               __field(        unsigned int,   reg             )
+               __field(        unsigned int,   val             )
+       ),
+
+       TP_fast_assign(
+               __assign_str(name, dev_name(dev));
+               __entry->reg = reg;
+               __entry->val = val;
+       ),
+
+       TP_printk("%s reg=%x val=%x", __get_str(name),
+                 (unsigned int)__entry->reg,
+                 (unsigned int)__entry->val)
+);
+
+DEFINE_EVENT(regmap_reg, regmap_reg_write,
+
+       TP_PROTO(struct device *dev, unsigned int reg,
+                unsigned int val),
+
+       TP_ARGS(dev, reg, val)
+
+);
+
+DEFINE_EVENT(regmap_reg, regmap_reg_read,
+
+       TP_PROTO(struct device *dev, unsigned int reg,
+                unsigned int val),
+
+       TP_ARGS(dev, reg, val)
+
+);
+
+DECLARE_EVENT_CLASS(regmap_block,
+
+       TP_PROTO(struct device *dev, unsigned int reg, int count),
+
+       TP_ARGS(dev, reg, count),
+
+       TP_STRUCT__entry(
+               __string(       name,           dev_name(dev)   )
+               __field(        unsigned int,   reg             )
+               __field(        int,            count           )
+       ),
+
+       TP_fast_assign(
+               __assign_str(name, dev_name(dev));
+               __entry->reg = reg;
+               __entry->count = count;
+       ),
+
+       TP_printk("%s reg=%x count=%d", __get_str(name),
+                 (unsigned int)__entry->reg,
+                 (int)__entry->count)
+);
+
+DEFINE_EVENT(regmap_block, regmap_hw_read_start,
+
+       TP_PROTO(struct device *dev, unsigned int reg, int count),
+
+       TP_ARGS(dev, reg, count)
+);
+
+DEFINE_EVENT(regmap_block, regmap_hw_read_done,
+
+       TP_PROTO(struct device *dev, unsigned int reg, int count),
+
+       TP_ARGS(dev, reg, count)
+);
+
+DEFINE_EVENT(regmap_block, regmap_hw_write_start,
+
+       TP_PROTO(struct device *dev, unsigned int reg, int count),
+
+       TP_ARGS(dev, reg, count)
+);
+
+DEFINE_EVENT(regmap_block, regmap_hw_write_done,
+
+       TP_PROTO(struct device *dev, unsigned int reg, int count),
+
+       TP_ARGS(dev, reg, count)
+);
+
+#endif /* _TRACE_REGMAP_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index d62778390e5556af22a95cc61d6b5e0cdeeb262e..dc7e27bf89a860a5290d656a34b0369f0600d3b0 100644 (file)
@@ -391,7 +391,7 @@ config TREE_RCU
 
 config TREE_PREEMPT_RCU
        bool "Preemptible tree-based hierarchical RCU"
-       depends on PREEMPT
+       depends on PREEMPT && SMP
        help
          This option selects the RCU implementation that is
          designed for very large SMP systems with hundreds or
@@ -401,7 +401,7 @@ config TREE_PREEMPT_RCU
 
 config TINY_RCU
        bool "UP-only small-memory-footprint RCU"
-       depends on !SMP
+       depends on !PREEMPT && !SMP
        help
          This option selects the RCU implementation that is
          designed for UP systems from which real-time response
@@ -410,7 +410,7 @@ config TINY_RCU
 
 config TINY_PREEMPT_RCU
        bool "Preemptible UP-only small-memory-footprint RCU"
-       depends on !SMP && PREEMPT
+       depends on PREEMPT && !SMP
        help
          This option selects the RCU implementation that is designed
          for real-time UP systems.  This option greatly reduces the
index eca595e2fd523e9dac8ac582b5fa2f4400887afa..2da48d3515ebd955fab857fb4924c9b15800a5aa 100644 (file)
@@ -9,7 +9,7 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
            rcupdate.o extable.o params.o posix-timers.o \
            kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
            hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
-           notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
+           notifier.o ksysfs.o sched_clock.o cred.o \
            async.o range.o
 obj-y += groups.o
 
index e691818d7e450f5f8785b8b97a08cdbb2f4e1493..4e825253523107845e0c5a720d01008181e918d8 100644 (file)
@@ -48,19 +48,17 @@ static inline struct freezer *task_freezer(struct task_struct *task)
                            struct freezer, css);
 }
 
-static inline int __cgroup_freezing_or_frozen(struct task_struct *task)
+bool cgroup_freezing(struct task_struct *task)
 {
-       enum freezer_state state = task_freezer(task)->state;
-       return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN);
-}
+       enum freezer_state state;
+       bool ret;
 
-int cgroup_freezing_or_frozen(struct task_struct *task)
-{
-       int result;
-       task_lock(task);
-       result = __cgroup_freezing_or_frozen(task);
-       task_unlock(task);
-       return result;
+       rcu_read_lock();
+       state = task_freezer(task)->state;
+       ret = state == CGROUP_FREEZING || state == CGROUP_FROZEN;
+       rcu_read_unlock();
+
+       return ret;
 }
 
 /*
@@ -102,9 +100,6 @@ struct cgroup_subsys freezer_subsys;
  * freezer_can_attach():
  * cgroup_mutex (held by caller of can_attach)
  *
- * cgroup_freezing_or_frozen():
- * task->alloc_lock (to get task's cgroup)
- *
  * freezer_fork() (preserving fork() performance means can't take cgroup_mutex):
  * freezer->lock
  *  sighand->siglock (if the cgroup is freezing)
@@ -130,7 +125,7 @@ struct cgroup_subsys freezer_subsys;
  *   write_lock css_set_lock (cgroup iterator start)
  *    task->alloc_lock
  *   read_lock css_set_lock (cgroup iterator start)
- *    task->alloc_lock (inside thaw_process(), prevents race with refrigerator())
+ *    task->alloc_lock (inside __thaw_task(), prevents race with refrigerator())
  *     sighand->siglock
  */
 static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss,
@@ -150,7 +145,11 @@ static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss,
 static void freezer_destroy(struct cgroup_subsys *ss,
                            struct cgroup *cgroup)
 {
-       kfree(cgroup_freezer(cgroup));
+       struct freezer *freezer = cgroup_freezer(cgroup);
+
+       if (freezer->state != CGROUP_THAWED)
+               atomic_dec(&system_freezing_cnt);
+       kfree(freezer);
 }
 
 /*
@@ -177,13 +176,7 @@ static int freezer_can_attach(struct cgroup_subsys *ss,
 
 static int freezer_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 {
-       rcu_read_lock();
-       if (__cgroup_freezing_or_frozen(tsk)) {
-               rcu_read_unlock();
-               return -EBUSY;
-       }
-       rcu_read_unlock();
-       return 0;
+       return cgroup_freezing(tsk) ? -EBUSY : 0;
 }
 
 static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
@@ -279,7 +272,6 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
        struct task_struct *task;
        unsigned int num_cant_freeze_now = 0;
 
-       freezer->state = CGROUP_FREEZING;
        cgroup_iter_start(cgroup, &it);
        while ((task = cgroup_iter_next(cgroup, &it))) {
                if (!freeze_task(task, true))
@@ -300,12 +292,9 @@ static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
        struct task_struct *task;
 
        cgroup_iter_start(cgroup, &it);
-       while ((task = cgroup_iter_next(cgroup, &it))) {
-               thaw_process(task);
-       }
+       while ((task = cgroup_iter_next(cgroup, &it)))
+               __thaw_task(task);
        cgroup_iter_end(cgroup, &it);
-
-       freezer->state = CGROUP_THAWED;
 }
 
 static int freezer_change_state(struct cgroup *cgroup,
@@ -322,11 +311,15 @@ static int freezer_change_state(struct cgroup *cgroup,
        if (goal_state == freezer->state)
                goto out;
 
+       freezer->state = goal_state;
+
        switch (goal_state) {
        case CGROUP_THAWED:
+               atomic_dec(&system_freezing_cnt);
                unfreeze_cgroup(cgroup, freezer);
                break;
        case CGROUP_FROZEN:
+               atomic_inc(&system_freezing_cnt);
                retval = try_to_freeze_cgroup(cgroup, freezer);
                break;
        default:
index 5f85690285d489543bf3b447d788f2ca09790d8b..69ebf3380bac362afc73904be855dc87abdb52ee 100644 (file)
@@ -19,9 +19,16 @@ unsigned long saved_max_pfn;
  */
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
 
+/*
+ * stores the size of elf header of crash image
+ */
+unsigned long long elfcorehdr_size;
+
 /*
  * elfcorehdr= specifies the location of elf core header stored by the crashed
  * kernel. This option will be passed by kexec loader to the capture kernel.
+ *
+ * Syntax: elfcorehdr=[size[KMG]@]offset[KMG]
  */
 static int __init setup_elfcorehdr(char *arg)
 {
@@ -29,6 +36,10 @@ static int __init setup_elfcorehdr(char *arg)
        if (!arg)
                return -EINVAL;
        elfcorehdr_addr = memparse(arg, &end);
+       if (*end == '@') {
+               elfcorehdr_size = elfcorehdr_addr;
+               elfcorehdr_addr = memparse(end + 1, &end);
+       }
        return end > arg ? 0 : -EINVAL;
 }
 early_param("elfcorehdr", setup_elfcorehdr);
index 8ef31f53c44c9aa8e74d3b15649fdf7d246a2a36..bb55d052d858f6c2f356d32f36a77445dcda20fa 100644 (file)
@@ -644,6 +644,9 @@ void __init cred_init(void)
  */
 struct cred *prepare_kernel_cred(struct task_struct *daemon)
 {
+#ifdef CONFIG_KEYS
+       struct thread_group_cred *tgcred;
+#endif
        const struct cred *old;
        struct cred *new;
 
@@ -651,6 +654,14 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
        if (!new)
                return NULL;
 
+#ifdef CONFIG_KEYS
+       tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
+       if (!tgcred) {
+               kmem_cache_free(cred_jar, new);
+               return NULL;
+       }
+#endif
+
        kdebug("prepare_kernel_cred() alloc %p", new);
 
        if (daemon)
@@ -667,8 +678,11 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
        get_group_info(new->group_info);
 
 #ifdef CONFIG_KEYS
-       atomic_inc(&init_tgcred.usage);
-       new->tgcred = &init_tgcred;
+       atomic_set(&tgcred->usage, 1);
+       spin_lock_init(&tgcred->lock);
+       tgcred->process_keyring = NULL;
+       tgcred->session_keyring = NULL;
+       new->tgcred = tgcred;
        new->request_key_auth = NULL;
        new->thread_keyring = NULL;
        new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
index 2913b3509d4288026990cc087894e69eace6c564..ac58259a9f8a224ebe4800b195062db65e4b85a4 100644 (file)
@@ -679,8 +679,6 @@ static void exit_mm(struct task_struct * tsk)
        tsk->mm = NULL;
        up_read(&mm->mmap_sem);
        enter_lazy_tlb(mm, current);
-       /* We don't want this task to be frozen prematurely */
-       clear_freeze_flag(tsk);
        if (tsk->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
                atomic_dec(&mm->oom_disable_count);
        task_unlock(tsk);
@@ -915,6 +913,12 @@ NORET_TYPE void do_exit(long code)
 
        ptrace_event(PTRACE_EVENT_EXIT, code);
 
+       /*
+        * With ptrace notification done, there's no point in freezing from
+        * here on.  Disallow freezing.
+        */
+       current->flags |= PF_NOFREEZE;
+
        validate_creds_for_do_exit(tsk);
 
        /*
index 8e6b6f4fb272ba498a4acdbcb6a29c8f7e6c87dd..948271451ffe33fa40c884733027f8d0d2249a23 100644 (file)
@@ -650,6 +650,38 @@ struct mm_struct *get_task_mm(struct task_struct *task)
 }
 EXPORT_SYMBOL_GPL(get_task_mm);
 
+static void complete_vfork_done(struct task_struct *tsk)
+{
+       struct completion *vfork;
+
+       task_lock(tsk);
+       vfork = tsk->vfork_done;
+       if (likely(vfork)) {
+               tsk->vfork_done = NULL;
+               complete(vfork);
+       }
+       task_unlock(tsk);
+}
+
+static int wait_for_vfork_done(struct task_struct *child,
+                               struct completion *vfork)
+{
+       int killed;
+
+       freezer_do_not_count();
+       killed = wait_for_completion_killable(vfork);
+       freezer_count();
+
+       if (killed) {
+               task_lock(child);
+               child->vfork_done = NULL;
+               task_unlock(child);
+       }
+
+       put_task_struct(child);
+       return killed;
+}
+
 /* Please note the differences between mmput and mm_release.
  * mmput is called whenever we stop holding onto a mm_struct,
  * error success whatever.
@@ -665,8 +697,6 @@ EXPORT_SYMBOL_GPL(get_task_mm);
  */
 void mm_release(struct task_struct *tsk, struct mm_struct *mm)
 {
-       struct completion *vfork_done = tsk->vfork_done;
-
        /* Get rid of any futexes when releasing the mm */
 #ifdef CONFIG_FUTEX
        if (unlikely(tsk->robust_list)) {
@@ -686,17 +716,15 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
        /* Get rid of any cached register state */
        deactivate_mm(tsk, mm);
 
-       /* notify parent sleeping on vfork() */
-       if (vfork_done) {
-               tsk->vfork_done = NULL;
-               complete(vfork_done);
-       }
+       if (tsk->vfork_done)
+               complete_vfork_done(tsk);
 
        /*
         * If we're exiting normally, clear a user-space tid field if
         * requested.  We leave this alone when dying by signal, to leave
         * the value intact in a core dump, and to save the unnecessary
-        * trouble otherwise.  Userland only wants this done for a sys_exit.
+        * trouble, say, a killed vfork parent shouldn't touch this mm.
+        * Userland only wants this done for a sys_exit.
         */
        if (tsk->clear_child_tid) {
                if (!(tsk->flags & PF_SIGNALED) &&
@@ -998,9 +1026,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p)
 
        new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
        new_flags |= PF_FORKNOEXEC;
-       new_flags |= PF_STARTING;
        p->flags = new_flags;
-       clear_freeze_flag(p);
 }
 
 SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
@@ -1531,18 +1557,10 @@ long do_fork(unsigned long clone_flags,
                if (clone_flags & CLONE_VFORK) {
                        p->vfork_done = &vfork;
                        init_completion(&vfork);
+                       get_task_struct(p);
                }
 
                audit_finish_fork(p);
-
-               /*
-                * We set PF_STARTING at creation in case tracing wants to
-                * use this to distinguish a fully live task from one that
-                * hasn't finished SIGSTOP raising yet.  Now we clear it
-                * and set the child going.
-                */
-               p->flags &= ~PF_STARTING;
-
                wake_up_new_task(p);
 
                /* forking complete and child started to run, tell ptracer */
@@ -1550,10 +1568,8 @@ long do_fork(unsigned long clone_flags,
                        ptrace_event(trace, nr);
 
                if (clone_flags & CLONE_VFORK) {
-                       freezer_do_not_count();
-                       wait_for_completion(&vfork);
-                       freezer_count();
-                       ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
+                       if (!wait_for_vfork_done(p, &vfork))
+                               ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
                }
        } else {
                nr = PTR_ERR(p);
index 7b01de98bb6a97aea6e1d5b99f38b113c099b780..466ea6bd7ff05ace227b6ad60face0cf916aada6 100644 (file)
@@ -9,34 +9,59 @@
 #include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/freezer.h>
+#include <linux/kthread.h>
 
-/*
- * freezing is complete, mark current process as frozen
+/* total number of freezing conditions in effect */
+atomic_t system_freezing_cnt = ATOMIC_INIT(0);
+EXPORT_SYMBOL(system_freezing_cnt);
+
+/* indicate whether PM freezing is in effect, protected by pm_mutex */
+bool pm_freezing;
+bool pm_nosig_freezing;
+
+/* protects freezing and frozen transitions */
+static DEFINE_SPINLOCK(freezer_lock);
+
+/**
+ * freezing_slow_path - slow path for testing whether a task needs to be frozen
+ * @p: task to be tested
+ *
+ * This function is called by freezing() if system_freezing_cnt isn't zero
+ * and tests whether @p needs to enter and stay in frozen state.  Can be
+ * called under any context.  The freezers are responsible for ensuring the
+ * target tasks see the updated state.
  */
-static inline void frozen_process(void)
+bool freezing_slow_path(struct task_struct *p)
 {
-       if (!unlikely(current->flags & PF_NOFREEZE)) {
-               current->flags |= PF_FROZEN;
-               smp_wmb();
-       }
-       clear_freeze_flag(current);
+       if (p->flags & PF_NOFREEZE)
+               return false;
+
+       if (pm_nosig_freezing || cgroup_freezing(p))
+               return true;
+
+       if (pm_freezing && !(p->flags & PF_FREEZER_NOSIG))
+               return true;
+
+       return false;
 }
+EXPORT_SYMBOL(freezing_slow_path);
 
 /* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(void)
+bool __refrigerator(bool check_kthr_stop)
 {
        /* Hmm, should we be allowed to suspend when there are realtime
           processes around? */
+       bool was_frozen = false;
        long save;
 
-       task_lock(current);
-       if (freezing(current)) {
-               frozen_process();
-               task_unlock(current);
-       } else {
-               task_unlock(current);
-               return;
-       }
+       /*
+        * No point in checking freezing() again - the caller already did.
+        * Proceed to enter FROZEN.
+        */
+       spin_lock_irq(&freezer_lock);
+       current->flags |= PF_FROZEN;
+       spin_unlock_irq(&freezer_lock);
+
        save = current->state;
        pr_debug("%s entered refrigerator\n", current->comm);
 
@@ -44,23 +69,32 @@ void refrigerator(void)
        recalc_sigpending(); /* We sent fake signal, clean it up */
        spin_unlock_irq(&current->sighand->siglock);
 
-       /* prevent accounting of that task to load */
-       current->flags |= PF_FREEZING;
-
        for (;;) {
                set_current_state(TASK_UNINTERRUPTIBLE);
-               if (!frozen(current))
+               if (!freezing(current) ||
+                   (check_kthr_stop && kthread_should_stop()))
                        break;
+               was_frozen = true;
                schedule();
        }
 
-       /* Remove the accounting blocker */
-       current->flags &= ~PF_FREEZING;
+       /* leave FROZEN */
+       spin_lock_irq(&freezer_lock);
+       current->flags &= ~PF_FROZEN;
+       spin_unlock_irq(&freezer_lock);
 
        pr_debug("%s left refrigerator\n", current->comm);
-       __set_current_state(save);
+
+       /*
+        * Restore saved task state before returning.  The mb'd version
+        * needs to be used; otherwise, it might silently break
+        * synchronization which depends on ordered task state change.
+        */
+       set_current_state(save);
+
+       return was_frozen;
 }
-EXPORT_SYMBOL(refrigerator);
+EXPORT_SYMBOL(__refrigerator);
 
 static void fake_signal_wake_up(struct task_struct *p)
 {
@@ -87,23 +121,15 @@ static void fake_signal_wake_up(struct task_struct *p)
  */
 bool freeze_task(struct task_struct *p, bool sig_only)
 {
-       /*
-        * We first check if the task is freezing and next if it has already
-        * been frozen to avoid the race with frozen_process() which first marks
-        * the task as frozen and next clears its TIF_FREEZE.
-        */
-       if (!freezing(p)) {
-               smp_rmb();
-               if (frozen(p))
-                       return false;
-
-               if (!sig_only || should_send_signal(p))
-                       set_freeze_flag(p);
-               else
-                       return false;
+       unsigned long flags;
+
+       spin_lock_irqsave(&freezer_lock, flags);
+       if (!freezing(p) || frozen(p)) {
+               spin_unlock_irqrestore(&freezer_lock, flags);
+               return false;
        }
 
-       if (should_send_signal(p)) {
+       if (!(p->flags & PF_FREEZER_NOSIG)) {
                fake_signal_wake_up(p);
                /*
                 * fake_signal_wake_up() goes through p's scheduler
@@ -111,56 +137,59 @@ bool freeze_task(struct task_struct *p, bool sig_only)
                 * TASK_RUNNING transition can't race with task state
                 * testing in try_to_freeze_tasks().
                 */
-       } else if (sig_only) {
-               return false;
        } else {
                wake_up_state(p, TASK_INTERRUPTIBLE);
        }
 
+       spin_unlock_irqrestore(&freezer_lock, flags);
        return true;
 }
 
-void cancel_freezing(struct task_struct *p)
+void __thaw_task(struct task_struct *p)
 {
        unsigned long flags;
 
-       if (freezing(p)) {
-               pr_debug("  clean up: %s\n", p->comm);
-               clear_freeze_flag(p);
-               spin_lock_irqsave(&p->sighand->siglock, flags);
-               recalc_sigpending_and_wake(p);
-               spin_unlock_irqrestore(&p->sighand->siglock, flags);
-       }
-}
-
-static int __thaw_process(struct task_struct *p)
-{
+       /*
+        * Clear freezing and kick @p if FROZEN.  Clearing is guaranteed to
+        * be visible to @p as waking up implies wmb.  Waking up inside
+        * freezer_lock also prevents wakeups from leaking outside
+        * refrigerator.
+        *
+        * If !FROZEN, @p hasn't reached refrigerator, recalc sigpending to
+        * avoid leaving dangling TIF_SIGPENDING behind.
+        */
+       spin_lock_irqsave(&freezer_lock, flags);
        if (frozen(p)) {
-               p->flags &= ~PF_FROZEN;
-               return 1;
+               wake_up_process(p);
+       } else {
+               spin_lock(&p->sighand->siglock);
+               recalc_sigpending_and_wake(p);
+               spin_unlock(&p->sighand->siglock);
        }
-       clear_freeze_flag(p);
-       return 0;
+       spin_unlock_irqrestore(&freezer_lock, flags);
 }
 
-/*
- * Wake up a frozen process
+/**
+ * __set_freezable - make %current freezable
+ * @with_signal: do we want %TIF_SIGPENDING for notification too?
  *
- * task_lock() is needed to prevent the race with refrigerator() which may
- * occur if the freezing of tasks fails.  Namely, without the lock, if the
- * freezing of tasks failed, thaw_tasks() might have run before a task in
- * refrigerator() could call frozen_process(), in which case the task would be
- * frozen and no one would thaw it.
+ * Mark %current freezable and enter refrigerator if necessary.
  */
-int thaw_process(struct task_struct *p)
+bool __set_freezable(bool with_signal)
 {
-       task_lock(p);
-       if (__thaw_process(p) == 1) {
-               task_unlock(p);
-               wake_up_process(p);
-               return 1;
-       }
-       task_unlock(p);
-       return 0;
+       might_sleep();
+
+       /*
+        * Modify flags while holding freezer_lock.  This ensures the
+        * freezer notices that we aren't frozen yet or the freezing
+        * condition is visible to try_to_freeze() below.
+        */
+       spin_lock_irq(&freezer_lock);
+       current->flags &= ~PF_NOFREEZE;
+       if (with_signal)
+               current->flags &= ~PF_FREEZER_NOSIG;
+       spin_unlock_irq(&freezer_lock);
+
+       return try_to_freeze();
 }
-EXPORT_SYMBOL(thaw_process);
+EXPORT_SYMBOL(__set_freezable);
index 2e9425889fa8874f742820b0f886f1cf0ee0a77c..9b956fa20308032c33c6b9550faacf9718b9fc6d 100644 (file)
@@ -1331,7 +1331,6 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
                if (!thread_fn)
                        return -EINVAL;
                handler = irq_default_primary_handler;
-               irqflags |= IRQF_ONESHOT;
        }
 
        action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
index 296fbc84d659d7d5749353e06d814b579ff50989..7204fb982ed599e9fa20d1e7572fe3808e091d8e 100644 (file)
@@ -498,7 +498,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
        while (hole_end <= crashk_res.end) {
                unsigned long i;
 
-               if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
+               if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
                        break;
                if (hole_end > crashk_res.end)
                        break;
index 4ba7cccb4994f24d6bc5965cda9b7f568d214f35..a6cbeea573d8d95284a7ccf18981305ce6fd918c 100644 (file)
@@ -58,6 +58,31 @@ int kthread_should_stop(void)
 }
 EXPORT_SYMBOL(kthread_should_stop);
 
+/**
+ * kthread_freezable_should_stop - should this freezable kthread return now?
+ * @was_frozen: optional out parameter, indicates whether %current was frozen
+ *
+ * kthread_should_stop() for freezable kthreads, which will enter
+ * refrigerator if necessary.  This function is safe from kthread_stop() /
+ * freezer deadlock and freezable kthreads should use this function instead
+ * of calling try_to_freeze() directly.
+ */
+bool kthread_freezable_should_stop(bool *was_frozen)
+{
+       bool frozen = false;
+
+       might_sleep();
+
+       if (unlikely(freezing(current)))
+               frozen = __refrigerator(true);
+
+       if (was_frozen)
+               *was_frozen = frozen;
+
+       return kthread_should_stop();
+}
+EXPORT_SYMBOL_GPL(kthread_freezable_should_stop);
+
 /**
  * kthread_data - return data value specified on kthread creation
  * @task: kthread task in question
index 91d67ce3a8d520a5cdc43d7abe6534c59710e79d..1e48f1c3ea700348ddb3173084b06d347e0a5ec8 100644 (file)
@@ -1129,10 +1129,11 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth,
        if (debug_locks_silent)
                return 0;
 
-       printk("\n=======================================================\n");
-       printk(  "[ INFO: possible circular locking dependency detected ]\n");
+       printk("\n");
+       printk("======================================================\n");
+       printk("[ INFO: possible circular locking dependency detected ]\n");
        print_kernel_version();
-       printk(  "-------------------------------------------------------\n");
+       printk("-------------------------------------------------------\n");
        printk("%s/%d is trying to acquire lock:\n",
                curr->comm, task_pid_nr(curr));
        print_lock(check_src);
@@ -1463,11 +1464,12 @@ print_bad_irq_dependency(struct task_struct *curr,
        if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
-       printk("\n======================================================\n");
-       printk(  "[ INFO: %s-safe -> %s-unsafe lock order detected ]\n",
+       printk("\n");
+       printk("======================================================\n");
+       printk("[ INFO: %s-safe -> %s-unsafe lock order detected ]\n",
                irqclass, irqclass);
        print_kernel_version();
-       printk(  "------------------------------------------------------\n");
+       printk("------------------------------------------------------\n");
        printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
                curr->comm, task_pid_nr(curr),
                curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT,
@@ -1692,10 +1694,11 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
        if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
-       printk("\n=============================================\n");
-       printk(  "[ INFO: possible recursive locking detected ]\n");
+       printk("\n");
+       printk("=============================================\n");
+       printk("[ INFO: possible recursive locking detected ]\n");
        print_kernel_version();
-       printk(  "---------------------------------------------\n");
+       printk("---------------------------------------------\n");
        printk("%s/%d is trying to acquire lock:\n",
                curr->comm, task_pid_nr(curr));
        print_lock(next);
@@ -2177,10 +2180,11 @@ print_usage_bug(struct task_struct *curr, struct held_lock *this,
        if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
-       printk("\n=================================\n");
-       printk(  "[ INFO: inconsistent lock state ]\n");
+       printk("\n");
+       printk("=================================\n");
+       printk("[ INFO: inconsistent lock state ]\n");
        print_kernel_version();
-       printk(  "---------------------------------\n");
+       printk("---------------------------------\n");
 
        printk("inconsistent {%s} -> {%s} usage.\n",
                usage_str[prev_bit], usage_str[new_bit]);
@@ -2241,10 +2245,11 @@ print_irq_inversion_bug(struct task_struct *curr,
        if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
-       printk("\n=========================================================\n");
-       printk(  "[ INFO: possible irq lock inversion dependency detected ]\n");
+       printk("\n");
+       printk("=========================================================\n");
+       printk("[ INFO: possible irq lock inversion dependency detected ]\n");
        print_kernel_version();
-       printk(  "---------------------------------------------------------\n");
+       printk("---------------------------------------------------------\n");
        printk("%s/%d just changed the state of lock:\n",
                curr->comm, task_pid_nr(curr));
        print_lock(this);
@@ -3065,9 +3070,10 @@ print_unlock_inbalance_bug(struct task_struct *curr, struct lockdep_map *lock,
        if (debug_locks_silent)
                return 0;
 
-       printk("\n=====================================\n");
-       printk(  "[ BUG: bad unlock balance detected! ]\n");
-       printk(  "-------------------------------------\n");
+       printk("\n");
+       printk("=====================================\n");
+       printk("[ BUG: bad unlock balance detected! ]\n");
+       printk("-------------------------------------\n");
        printk("%s/%d is trying to release lock (",
                curr->comm, task_pid_nr(curr));
        print_lockdep_cache(lock);
@@ -3478,9 +3484,10 @@ print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock,
        if (debug_locks_silent)
                return 0;
 
-       printk("\n=================================\n");
-       printk(  "[ BUG: bad contention detected! ]\n");
-       printk(  "---------------------------------\n");
+       printk("\n");
+       printk("=================================\n");
+       printk("[ BUG: bad contention detected! ]\n");
+       printk("---------------------------------\n");
        printk("%s/%d is trying to contend lock (",
                curr->comm, task_pid_nr(curr));
        print_lockdep_cache(lock);
@@ -3839,9 +3846,10 @@ print_freed_lock_bug(struct task_struct *curr, const void *mem_from,
        if (debug_locks_silent)
                return;
 
-       printk("\n=========================\n");
-       printk(  "[ BUG: held lock freed! ]\n");
-       printk(  "-------------------------\n");
+       printk("\n");
+       printk("=========================\n");
+       printk("[ BUG: held lock freed! ]\n");
+       printk("-------------------------\n");
        printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
                curr->comm, task_pid_nr(curr), mem_from, mem_to-1);
        print_lock(hlock);
@@ -3895,9 +3903,10 @@ static void print_held_locks_bug(struct task_struct *curr)
        if (debug_locks_silent)
                return;
 
-       printk("\n=====================================\n");
-       printk(  "[ BUG: lock held at task exit time! ]\n");
-       printk(  "-------------------------------------\n");
+       printk("\n");
+       printk("=====================================\n");
+       printk("[ BUG: lock held at task exit time! ]\n");
+       printk("-------------------------------------\n");
        printk("%s/%d is exiting with locks still held!\n",
                curr->comm, task_pid_nr(curr));
        lockdep_print_held_locks(curr);
@@ -3991,16 +4000,17 @@ void lockdep_sys_exit(void)
        if (unlikely(curr->lockdep_depth)) {
                if (!debug_locks_off())
                        return;
-               printk("\n================================================\n");
-               printk(  "[ BUG: lock held when returning to user space! ]\n");
-               printk(  "------------------------------------------------\n");
+               printk("\n");
+               printk("================================================\n");
+               printk("[ BUG: lock held when returning to user space! ]\n");
+               printk("------------------------------------------------\n");
                printk("%s/%d is leaving the kernel with locks still held!\n",
                                curr->comm, curr->pid);
                lockdep_print_held_locks(curr);
        }
 }
 
-void lockdep_rcu_dereference(const char *file, const int line)
+void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
 {
        struct task_struct *curr = current;
 
@@ -4009,15 +4019,15 @@ void lockdep_rcu_dereference(const char *file, const int line)
                return;
 #endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
        /* Note: the following can be executed concurrently, so be careful. */
-       printk("\n===================================================\n");
-       printk(  "[ INFO: suspicious rcu_dereference_check() usage. ]\n");
-       printk(  "---------------------------------------------------\n");
-       printk("%s:%d invoked rcu_dereference_check() without protection!\n",
-                       file, line);
+       printk("\n");
+       printk("===============================\n");
+       printk("[ INFO: suspicious RCU usage. ]\n");
+       printk("-------------------------------\n");
+       printk("%s:%d %s!\n", file, line, s);
        printk("\nother info that might help us debug this:\n\n");
        printk("\nrcu_scheduler_active = %d, debug_locks = %d\n", rcu_scheduler_active, debug_locks);
        lockdep_print_held_locks(curr);
        printk("\nstack backtrace:\n");
        dump_stack();
 }
-EXPORT_SYMBOL_GPL(lockdep_rcu_dereference);
+EXPORT_SYMBOL_GPL(lockdep_rcu_suspicious);
index e432057f3b2147873f0de30ad00b16bbaecbedb1..8cafe7e72ad2b83ff0bc7f7d0e12b710e6f9a519 100644 (file)
@@ -418,7 +418,9 @@ EXPORT_SYMBOL(pid_task);
  */
 struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
 {
-       rcu_lockdep_assert(rcu_read_lock_held());
+       rcu_lockdep_assert(rcu_read_lock_held(),
+                          "find_task_by_pid_ns() needs rcu_read_lock()"
+                          " protection");
        return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
 }
 
index 3744c594b19b18b779b8d1f8660788a1e0aeacbf..e01e6899592c6b43b3d983fc300d8f62cfc2cb4f 100644 (file)
@@ -65,6 +65,9 @@ config HIBERNATION
 
          For more information take a look at <file:Documentation/power/swsusp.txt>.
 
+config ARCH_SAVE_PAGE_KEYS
+       bool
+
 config PM_STD_PARTITION
        string "Default resume partition"
        depends on HIBERNATION
index c5ebc6a9064390583ed4f9cb6c11cf857fd0c318..ad6bdd8b401aea9c189e7c2447937fcd8e674270 100644 (file)
@@ -1,7 +1,7 @@
 
 ccflags-$(CONFIG_PM_DEBUG)     := -DDEBUG
 
-obj-$(CONFIG_PM)               += main.o
+obj-$(CONFIG_PM)               += main.o qos.o
 obj-$(CONFIG_PM_SLEEP)         += console.o
 obj-$(CONFIG_FREEZER)          += process.o
 obj-$(CONFIG_SUSPEND)          += suspend.o
index 8f7b1db1ece1b3273f9eebbc128d7c884390c638..5fed34d7ccec6172f5be4b48dd2f17ca8db3c8c8 100644 (file)
@@ -586,17 +586,6 @@ static void power_down(void)
        while(1);
 }
 
-static int prepare_processes(void)
-{
-       int error = 0;
-
-       if (freeze_processes()) {
-               error = -EBUSY;
-               thaw_processes();
-       }
-       return error;
-}
-
 /**
  * hibernate - Carry out system hibernation, including saving the image.
  */
@@ -629,7 +618,7 @@ int hibernate(void)
        sys_sync();
        printk("done.\n");
 
-       error = prepare_processes();
+       error = freeze_processes();
        if (error)
                goto Finish;
 
@@ -776,7 +765,7 @@ static int software_resume(void)
                goto close_finish;
 
        pr_debug("PM: Preparing processes for restore.\n");
-       error = prepare_processes();
+       error = freeze_processes();
        if (error) {
                swsusp_close(FMODE_READ);
                goto Done;
index 6c601f871964408e7df2b376dd69d86006103b0e..a52e88425a31a351cb7b80822462503e0c74dbbe 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/string.h>
 #include <linux/resume-trace.h>
 #include <linux/workqueue.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #include "power.h"
 
@@ -131,6 +133,101 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
 power_attr(pm_test);
 #endif /* CONFIG_PM_DEBUG */
 
+#ifdef CONFIG_DEBUG_FS
+static char *suspend_step_name(enum suspend_stat_step step)
+{
+       switch (step) {
+       case SUSPEND_FREEZE:
+               return "freeze";
+       case SUSPEND_PREPARE:
+               return "prepare";
+       case SUSPEND_SUSPEND:
+               return "suspend";
+       case SUSPEND_SUSPEND_NOIRQ:
+               return "suspend_noirq";
+       case SUSPEND_RESUME_NOIRQ:
+               return "resume_noirq";
+       case SUSPEND_RESUME:
+               return "resume";
+       default:
+               return "";
+       }
+}
+
+static int suspend_stats_show(struct seq_file *s, void *unused)
+{
+       int i, index, last_dev, last_errno, last_step;
+
+       last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
+       last_dev %= REC_FAILED_NUM;
+       last_errno = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
+       last_errno %= REC_FAILED_NUM;
+       last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
+       last_step %= REC_FAILED_NUM;
+       seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
+                       "%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
+                       "success", suspend_stats.success,
+                       "fail", suspend_stats.fail,
+                       "failed_freeze", suspend_stats.failed_freeze,
+                       "failed_prepare", suspend_stats.failed_prepare,
+                       "failed_suspend", suspend_stats.failed_suspend,
+                       "failed_suspend_noirq",
+                               suspend_stats.failed_suspend_noirq,
+                       "failed_resume", suspend_stats.failed_resume,
+                       "failed_resume_noirq",
+                               suspend_stats.failed_resume_noirq);
+       seq_printf(s,   "failures:\n  last_failed_dev:\t%-s\n",
+                       suspend_stats.failed_devs[last_dev]);
+       for (i = 1; i < REC_FAILED_NUM; i++) {
+               index = last_dev + REC_FAILED_NUM - i;
+               index %= REC_FAILED_NUM;
+               seq_printf(s, "\t\t\t%-s\n",
+                       suspend_stats.failed_devs[index]);
+       }
+       seq_printf(s,   "  last_failed_errno:\t%-d\n",
+                       suspend_stats.errno[last_errno]);
+       for (i = 1; i < REC_FAILED_NUM; i++) {
+               index = last_errno + REC_FAILED_NUM - i;
+               index %= REC_FAILED_NUM;
+               seq_printf(s, "\t\t\t%-d\n",
+                       suspend_stats.errno[index]);
+       }
+       seq_printf(s,   "  last_failed_step:\t%-s\n",
+                       suspend_step_name(
+                               suspend_stats.failed_steps[last_step]));
+       for (i = 1; i < REC_FAILED_NUM; i++) {
+               index = last_step + REC_FAILED_NUM - i;
+               index %= REC_FAILED_NUM;
+               seq_printf(s, "\t\t\t%-s\n",
+                       suspend_step_name(
+                               suspend_stats.failed_steps[index]));
+       }
+
+       return 0;
+}
+
+static int suspend_stats_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, suspend_stats_show, NULL);
+}
+
+static const struct file_operations suspend_stats_operations = {
+       .open           = suspend_stats_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init pm_debugfs_init(void)
+{
+       debugfs_create_file("suspend_stats", S_IFREG | S_IRUGO,
+                       NULL, NULL, &suspend_stats_operations);
+       return 0;
+}
+
+late_initcall(pm_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+
 #endif /* CONFIG_PM_SLEEP */
 
 struct kobject *power_kobj;
@@ -194,6 +291,11 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
        }
        if (state < PM_SUSPEND_MAX && *s)
                error = enter_state(state);
+               if (error) {
+                       suspend_stats.fail++;
+                       dpm_save_failed_errno(error);
+               } else
+                       suspend_stats.success++;
 #endif
 
  Exit:
index 0cf3a27a6c9d53e32ca449ea6a350770f4caa039..fe06ddf4b4d67d5992178003ad447b70d7bb42b5 100644 (file)
  */
 #define TIMEOUT        (20 * HZ)
 
-static inline int freezable(struct task_struct * p)
-{
-       if ((p == current) ||
-           (p->flags & PF_NOFREEZE) ||
-           (p->exit_state != 0))
-               return 0;
-       return 1;
-}
-
 static int try_to_freeze_tasks(bool sig_only)
 {
        struct task_struct *g, *p;
@@ -53,10 +44,7 @@ static int try_to_freeze_tasks(bool sig_only)
                todo = 0;
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       if (frozen(p) || !freezable(p))
-                               continue;
-
-                       if (!freeze_task(p, sig_only))
+                       if (p == current || !freeze_task(p, sig_only))
                                continue;
 
                        /*
@@ -103,11 +91,6 @@ static int try_to_freeze_tasks(bool sig_only)
        elapsed_csecs = elapsed_csecs64;
 
        if (todo) {
-               /* This does not unfreeze processes that are already frozen
-                * (we have slightly ugly calling convention in that respect,
-                * and caller must call thaw_processes() if something fails),
-                * but it cleans up leftover PF_FREEZE requests.
-                */
                printk("\n");
                printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
                       "(%d tasks refusing to freeze, wq_busy=%d):\n",
@@ -115,15 +98,11 @@ static int try_to_freeze_tasks(bool sig_only)
                       elapsed_csecs / 100, elapsed_csecs % 100,
                       todo - wq_busy, wq_busy);
 
-               thaw_workqueues();
-
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       task_lock(p);
-                       if (!wakeup && freezing(p) && !freezer_should_skip(p))
+                       if (!wakeup && !freezer_should_skip(p) &&
+                           p != current && freezing(p) && !frozen(p))
                                sched_show_task(p);
-                       cancel_freezing(p);
-                       task_unlock(p);
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
        } else {
@@ -141,13 +120,18 @@ int freeze_processes(void)
 {
        int error;
 
+       if (!pm_freezing)
+               atomic_inc(&system_freezing_cnt);
+
        printk("Freezing user space processes ... ");
+       pm_freezing = true;
        error = try_to_freeze_tasks(true);
        if (error)
                goto Exit;
        printk("done.\n");
 
        printk("Freezing remaining freezable tasks ... ");
+       pm_nosig_freezing = true;
        error = try_to_freeze_tasks(false);
        if (error)
                goto Exit;
@@ -155,40 +139,35 @@ int freeze_processes(void)
 
        oom_killer_disable();
  Exit:
+       if (error)
+               thaw_processes();
        BUG_ON(in_atomic());
        printk("\n");
 
        return error;
 }
 
-static void thaw_tasks(bool nosig_only)
+void thaw_processes(void)
 {
        struct task_struct *g, *p;
 
-       read_lock(&tasklist_lock);
-       do_each_thread(g, p) {
-               if (!freezable(p))
-                       continue;
+       if (pm_freezing)
+               atomic_dec(&system_freezing_cnt);
+       pm_freezing = false;
+       pm_nosig_freezing = false;
 
-               if (nosig_only && should_send_signal(p))
-                       continue;
+       oom_killer_enable();
 
-               if (cgroup_freezing_or_frozen(p))
-                       continue;
+       printk("Restarting tasks ... ");
+
+       thaw_workqueues();
 
-               thaw_process(p);
+       read_lock(&tasklist_lock);
+       do_each_thread(g, p) {
+               __thaw_task(p);
        } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
-}
 
-void thaw_processes(void)
-{
-       oom_killer_enable();
-
-       printk("Restarting tasks ... ");
-       thaw_workqueues();
-       thaw_tasks(true);
-       thaw_tasks(false);
        schedule();
        printk("done.\n");
 }
similarity index 71%
rename from kernel/pm_qos_params.c
rename to kernel/power/qos.c
index 37f05d0f07939e696eb8657fbd80ce08bab7ef15..1c1797dd1d1d3f05c3260f47e0f6c22efc1c815c 100644 (file)
@@ -29,7 +29,7 @@
 
 /*#define DEBUG*/
 
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 
 /*
- * locking rule: all changes to requests or notifiers lists
+ * locking rule: all changes to constraints or notifiers lists
  * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
  * held, taken with _irqsave.  One lock to rule them all
  */
-enum pm_qos_type {
-       PM_QOS_MAX,             /* return the largest value */
-       PM_QOS_MIN              /* return the smallest value */
-};
-
-/*
- * Note: The lockless read path depends on the CPU accessing
- * target_value atomically.  Atomic access is only guaranteed on all CPU
- * types linux supports for 32 bit quantites
- */
 struct pm_qos_object {
-       struct plist_head requests;
-       struct blocking_notifier_head *notifiers;
+       struct pm_qos_constraints *constraints;
        struct miscdevice pm_qos_power_miscdev;
        char *name;
-       s32 target_value;       /* Do not change to 64 bit */
-       s32 default_value;
-       enum pm_qos_type type;
 };
 
 static DEFINE_SPINLOCK(pm_qos_lock);
 
 static struct pm_qos_object null_pm_qos;
+
 static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
-static struct pm_qos_object cpu_dma_pm_qos = {
-       .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests),
-       .notifiers = &cpu_dma_lat_notifier,
-       .name = "cpu_dma_latency",
+static struct pm_qos_constraints cpu_dma_constraints = {
+       .list = PLIST_HEAD_INIT(cpu_dma_constraints.list),
        .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
        .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
        .type = PM_QOS_MIN,
+       .notifiers = &cpu_dma_lat_notifier,
+};
+static struct pm_qos_object cpu_dma_pm_qos = {
+       .constraints = &cpu_dma_constraints,
 };
 
 static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
-static struct pm_qos_object network_lat_pm_qos = {
-       .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests),
-       .notifiers = &network_lat_notifier,
-       .name = "network_latency",
+static struct pm_qos_constraints network_lat_constraints = {
+       .list = PLIST_HEAD_INIT(network_lat_constraints.list),
        .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
        .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
-       .type = PM_QOS_MIN
+       .type = PM_QOS_MIN,
+       .notifiers = &network_lat_notifier,
+};
+static struct pm_qos_object network_lat_pm_qos = {
+       .constraints = &network_lat_constraints,
+       .name = "network_latency",
 };
 
 
 static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
-static struct pm_qos_object network_throughput_pm_qos = {
-       .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests),
-       .notifiers = &network_throughput_notifier,
-       .name = "network_throughput",
+static struct pm_qos_constraints network_tput_constraints = {
+       .list = PLIST_HEAD_INIT(network_tput_constraints.list),
        .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
        .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
        .type = PM_QOS_MAX,
+       .notifiers = &network_throughput_notifier,
+};
+static struct pm_qos_object network_throughput_pm_qos = {
+       .constraints = &network_tput_constraints,
+       .name = "network_throughput",
 };
 
 
@@ -127,17 +122,17 @@ static const struct file_operations pm_qos_power_fops = {
 };
 
 /* unlocked internal variant */
-static inline int pm_qos_get_value(struct pm_qos_object *o)
+static inline int pm_qos_get_value(struct pm_qos_constraints *c)
 {
-       if (plist_head_empty(&o->requests))
-               return o->default_value;
+       if (plist_head_empty(&c->list))
+               return c->default_value;
 
-       switch (o->type) {
+       switch (c->type) {
        case PM_QOS_MIN:
-               return plist_first(&o->requests)->prio;
+               return plist_first(&c->list)->prio;
 
        case PM_QOS_MAX:
-               return plist_last(&o->requests)->prio;
+               return plist_last(&c->list)->prio;
 
        default:
                /* runtime check for not using enum */
@@ -145,69 +140,73 @@ static inline int pm_qos_get_value(struct pm_qos_object *o)
        }
 }
 
-static inline s32 pm_qos_read_value(struct pm_qos_object *o)
+s32 pm_qos_read_value(struct pm_qos_constraints *c)
 {
-       return o->target_value;
+       return c->target_value;
 }
 
-static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
+static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value)
 {
-       o->target_value = value;
+       c->target_value = value;
 }
 
-static void update_target(struct pm_qos_object *o, struct plist_node *node,
-                         int del, int value)
+/**
+ * pm_qos_update_target - manages the constraints list and calls the notifiers
+ *  if needed
+ * @c: constraints data struct
+ * @node: request to add to the list, to update or to remove
+ * @action: action to take on the constraints list
+ * @value: value of the request to add or update
+ *
+ * This function returns 1 if the aggregated constraint value has changed, 0
+ *  otherwise.
+ */
+int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
+                        enum pm_qos_req_action action, int value)
 {
        unsigned long flags;
-       int prev_value, curr_value;
+       int prev_value, curr_value, new_value;
 
        spin_lock_irqsave(&pm_qos_lock, flags);
-       prev_value = pm_qos_get_value(o);
-       /* PM_QOS_DEFAULT_VALUE is a signal that the value is unchanged */
-       if (value != PM_QOS_DEFAULT_VALUE) {
+       prev_value = pm_qos_get_value(c);
+       if (value == PM_QOS_DEFAULT_VALUE)
+               new_value = c->default_value;
+       else
+               new_value = value;
+
+       switch (action) {
+       case PM_QOS_REMOVE_REQ:
+               plist_del(node, &c->list);
+               break;
+       case PM_QOS_UPDATE_REQ:
                /*
                 * to change the list, we atomically remove, reinit
                 * with new value and add, then see if the extremal
                 * changed
                 */
-               plist_del(node, &o->requests);
-               plist_node_init(node, value);
-               plist_add(node, &o->requests);
-       } else if (del) {
-               plist_del(node, &o->requests);
-       } else {
-               plist_add(node, &o->requests);
+               plist_del(node, &c->list);
+       case PM_QOS_ADD_REQ:
+               plist_node_init(node, new_value);
+               plist_add(node, &c->list);
+               break;
+       default:
+               /* no action */
+               ;
        }
-       curr_value = pm_qos_get_value(o);
-       pm_qos_set_value(o, curr_value);
+
+       curr_value = pm_qos_get_value(c);
+       pm_qos_set_value(c, curr_value);
+
        spin_unlock_irqrestore(&pm_qos_lock, flags);
 
-       if (prev_value != curr_value)
-               blocking_notifier_call_chain(o->notifiers,
+       if (prev_value != curr_value) {
+               blocking_notifier_call_chain(c->notifiers,
                                             (unsigned long)curr_value,
                                             NULL);
-}
-
-static int register_pm_qos_misc(struct pm_qos_object *qos)
-{
-       qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR;
-       qos->pm_qos_power_miscdev.name = qos->name;
-       qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops;
-
-       return misc_register(&qos->pm_qos_power_miscdev);
-}
-
-static int find_pm_qos_object_by_minor(int minor)
-{
-       int pm_qos_class;
-
-       for (pm_qos_class = 0;
-               pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
-               if (minor ==
-                       pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
-                       return pm_qos_class;
+               return 1;
+       } else {
+               return 0;
        }
-       return -1;
 }
 
 /**
@@ -218,11 +217,11 @@ static int find_pm_qos_object_by_minor(int minor)
  */
 int pm_qos_request(int pm_qos_class)
 {
-       return pm_qos_read_value(pm_qos_array[pm_qos_class]);
+       return pm_qos_read_value(pm_qos_array[pm_qos_class]->constraints);
 }
 EXPORT_SYMBOL_GPL(pm_qos_request);
 
-int pm_qos_request_active(struct pm_qos_request_list *req)
+int pm_qos_request_active(struct pm_qos_request *req)
 {
        return req->pm_qos_class != 0;
 }
@@ -230,40 +229,36 @@ EXPORT_SYMBOL_GPL(pm_qos_request_active);
 
 /**
  * pm_qos_add_request - inserts new qos request into the list
- * @dep: pointer to a preallocated handle
+ * @req: pointer to a preallocated handle
  * @pm_qos_class: identifies which list of qos request to use
  * @value: defines the qos request
  *
  * This function inserts a new entry in the pm_qos_class list of requested qos
  * performance characteristics.  It recomputes the aggregate QoS expectations
- * for the pm_qos_class of parameters and initializes the pm_qos_request_list
+ * for the pm_qos_class of parameters and initializes the pm_qos_request
  * handle.  Caller needs to save this handle for later use in updates and
  * removal.
  */
 
-void pm_qos_add_request(struct pm_qos_request_list *dep,
+void pm_qos_add_request(struct pm_qos_request *req,
                        int pm_qos_class, s32 value)
 {
-       struct pm_qos_object *o =  pm_qos_array[pm_qos_class];
-       int new_value;
+       if (!req) /*guard against callers passing in null */
+               return;
 
-       if (pm_qos_request_active(dep)) {
+       if (pm_qos_request_active(req)) {
                WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
                return;
        }
-       if (value == PM_QOS_DEFAULT_VALUE)
-               new_value = o->default_value;
-       else
-               new_value = value;
-       plist_node_init(&dep->list, new_value);
-       dep->pm_qos_class = pm_qos_class;
-       update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
+       req->pm_qos_class = pm_qos_class;
+       pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints,
+                            &req->node, PM_QOS_ADD_REQ, value);
 }
 EXPORT_SYMBOL_GPL(pm_qos_add_request);
 
 /**
  * pm_qos_update_request - modifies an existing qos request
- * @pm_qos_req : handle to list element holding a pm_qos request to use
+ * @req : handle to list element holding a pm_qos request to use
  * @value: defines the qos request
  *
  * Updates an existing qos request for the pm_qos_class of parameters along
@@ -271,56 +266,47 @@ EXPORT_SYMBOL_GPL(pm_qos_add_request);
  *
  * Attempts are made to make this code callable on hot code paths.
  */
-void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
+void pm_qos_update_request(struct pm_qos_request *req,
                           s32 new_value)
 {
-       s32 temp;
-       struct pm_qos_object *o;
-
-       if (!pm_qos_req) /*guard against callers passing in null */
+       if (!req) /*guard against callers passing in null */
                return;
 
-       if (!pm_qos_request_active(pm_qos_req)) {
+       if (!pm_qos_request_active(req)) {
                WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
                return;
        }
 
-       o = pm_qos_array[pm_qos_req->pm_qos_class];
-
-       if (new_value == PM_QOS_DEFAULT_VALUE)
-               temp = o->default_value;
-       else
-               temp = new_value;
-
-       if (temp != pm_qos_req->list.prio)
-               update_target(o, &pm_qos_req->list, 0, temp);
+       if (new_value != req->node.prio)
+               pm_qos_update_target(
+                       pm_qos_array[req->pm_qos_class]->constraints,
+                       &req->node, PM_QOS_UPDATE_REQ, new_value);
 }
 EXPORT_SYMBOL_GPL(pm_qos_update_request);
 
 /**
  * pm_qos_remove_request - modifies an existing qos request
- * @pm_qos_req: handle to request list element
+ * @req: handle to request list element
  *
- * Will remove pm qos request from the list of requests and
+ * Will remove pm qos request from the list of constraints and
  * recompute the current target value for the pm_qos_class.  Call this
  * on slow code paths.
  */
-void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
+void pm_qos_remove_request(struct pm_qos_request *req)
 {
-       struct pm_qos_object *o;
-
-       if (pm_qos_req == NULL)
+       if (!req) /*guard against callers passing in null */
                return;
                /* silent return to keep pcm code cleaner */
 
-       if (!pm_qos_request_active(pm_qos_req)) {
+       if (!pm_qos_request_active(req)) {
                WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
                return;
        }
 
-       o = pm_qos_array[pm_qos_req->pm_qos_class];
-       update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
-       memset(pm_qos_req, 0, sizeof(*pm_qos_req));
+       pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints,
+                            &req->node, PM_QOS_REMOVE_REQ,
+                            PM_QOS_DEFAULT_VALUE);
+       memset(req, 0, sizeof(*req));
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_request);
 
@@ -337,7 +323,8 @@ int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
        int retval;
 
        retval = blocking_notifier_chain_register(
-                       pm_qos_array[pm_qos_class]->notifiers, notifier);
+                       pm_qos_array[pm_qos_class]->constraints->notifiers,
+                       notifier);
 
        return retval;
 }
@@ -356,19 +343,43 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
        int retval;
 
        retval = blocking_notifier_chain_unregister(
-                       pm_qos_array[pm_qos_class]->notifiers, notifier);
+                       pm_qos_array[pm_qos_class]->constraints->notifiers,
+                       notifier);
 
        return retval;
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
+/* User space interface to PM QoS classes via misc devices */
+static int register_pm_qos_misc(struct pm_qos_object *qos)
+{
+       qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR;
+       qos->pm_qos_power_miscdev.name = qos->name;
+       qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops;
+
+       return misc_register(&qos->pm_qos_power_miscdev);
+}
+
+static int find_pm_qos_object_by_minor(int minor)
+{
+       int pm_qos_class;
+
+       for (pm_qos_class = 0;
+               pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
+               if (minor ==
+                       pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
+                       return pm_qos_class;
+       }
+       return -1;
+}
+
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
        long pm_qos_class;
 
        pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
        if (pm_qos_class >= 0) {
-               struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL);
+               struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL);
                if (!req)
                        return -ENOMEM;
 
@@ -383,7 +394,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
 
 static int pm_qos_power_release(struct inode *inode, struct file *filp)
 {
-       struct pm_qos_request_list *req;
+       struct pm_qos_request *req;
 
        req = filp->private_data;
        pm_qos_remove_request(req);
@@ -398,17 +409,15 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
 {
        s32 value;
        unsigned long flags;
-       struct pm_qos_object *o;
-       struct pm_qos_request_list *pm_qos_req = filp->private_data;
+       struct pm_qos_request *req = filp->private_data;
 
-       if (!pm_qos_req)
+       if (!req)
                return -EINVAL;
-       if (!pm_qos_request_active(pm_qos_req))
+       if (!pm_qos_request_active(req))
                return -EINVAL;
 
-       o = pm_qos_array[pm_qos_req->pm_qos_class];
        spin_lock_irqsave(&pm_qos_lock, flags);
-       value = pm_qos_get_value(o);
+       value = pm_qos_get_value(pm_qos_array[req->pm_qos_class]->constraints);
        spin_unlock_irqrestore(&pm_qos_lock, flags);
 
        return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32));
@@ -418,7 +427,7 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
                size_t count, loff_t *f_pos)
 {
        s32 value;
-       struct pm_qos_request_list *pm_qos_req;
+       struct pm_qos_request *req;
 
        if (count == sizeof(s32)) {
                if (copy_from_user(&value, buf, sizeof(s32)))
@@ -449,8 +458,8 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
                return -EINVAL;
        }
 
-       pm_qos_req = filp->private_data;
-       pm_qos_update_request(pm_qos_req, value);
+       req = filp->private_data;
+       pm_qos_update_request(req, value);
 
        return count;
 }
index 06efa54f93d6686bfc2f218d92149ee56cf9e511..cbe2c14413927c665f25d778fb03fde84af73421 100644 (file)
@@ -1339,6 +1339,9 @@ int hibernate_preallocate_memory(void)
        count += highmem;
        count -= totalreserve_pages;
 
+       /* Add number of pages required for page keys (s390 only). */
+       size += page_key_additional_pages(saveable);
+
        /* Compute the maximum number of saveable pages to leave in memory. */
        max_size = (count - (size + PAGES_FOR_IO)) / 2
                        - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE);
@@ -1662,6 +1665,8 @@ pack_pfns(unsigned long *buf, struct memory_bitmap *bm)
                buf[j] = memory_bm_next_pfn(bm);
                if (unlikely(buf[j] == BM_END_OF_MAP))
                        break;
+               /* Save page key for data page (s390 only). */
+               page_key_read(buf + j);
        }
 }
 
@@ -1821,6 +1826,9 @@ static int unpack_orig_pfns(unsigned long *buf, struct memory_bitmap *bm)
                if (unlikely(buf[j] == BM_END_OF_MAP))
                        break;
 
+               /* Extract and buffer page key for data page (s390 only). */
+               page_key_memorize(buf + j);
+
                if (memory_bm_pfn_present(bm, buf[j]))
                        memory_bm_set_bit(bm, buf[j]);
                else
@@ -2223,6 +2231,11 @@ int snapshot_write_next(struct snapshot_handle *handle)
                if (error)
                        return error;
 
+               /* Allocate buffer for page keys. */
+               error = page_key_alloc(nr_copy_pages);
+               if (error)
+                       return error;
+
        } else if (handle->cur <= nr_meta_pages + 1) {
                error = unpack_orig_pfns(buffer, &copy_bm);
                if (error)
@@ -2243,6 +2256,8 @@ int snapshot_write_next(struct snapshot_handle *handle)
                }
        } else {
                copy_last_highmem_page();
+               /* Restore page key for data page (s390 only). */
+               page_key_write(handle->buffer);
                handle->buffer = get_buffer(&orig_bm, &ca);
                if (IS_ERR(handle->buffer))
                        return PTR_ERR(handle->buffer);
@@ -2264,6 +2279,9 @@ int snapshot_write_next(struct snapshot_handle *handle)
 void snapshot_write_finalize(struct snapshot_handle *handle)
 {
        copy_last_highmem_page();
+       /* Restore page key for data page (s390 only). */
+       page_key_write(handle->buffer);
+       page_key_free();
        /* Free only if we have loaded the image entirely */
        if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages) {
                memory_bm_free(&orig_bm, PG_UNSAFE_CLEAR);
index b6b71ad2208fd1a0a04bd31fe4437f6d99bf7f9d..595a3dd56a8a832c9029086de9b2a11460951d3d 100644 (file)
@@ -104,7 +104,10 @@ static int suspend_prepare(void)
                goto Finish;
 
        error = suspend_freeze_processes();
-       if (!error)
+       if (error) {
+               suspend_stats.failed_freeze++;
+               dpm_save_failed_step(SUSPEND_FREEZE);
+       } else
                return 0;
 
        suspend_thaw_processes();
@@ -315,8 +318,16 @@ int enter_state(suspend_state_t state)
  */
 int pm_suspend(suspend_state_t state)
 {
-       if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX)
-               return enter_state(state);
+       int ret;
+       if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX) {
+               ret = enter_state(state);
+               if (ret) {
+                       suspend_stats.fail++;
+                       dpm_save_failed_errno(ret);
+               } else
+                       suspend_stats.success++;
+               return ret;
+       }
        return -EINVAL;
 }
 EXPORT_SYMBOL(pm_suspend);
index 42ddbc6f0de6ffcf2d245dd9c8ec253c2780ffab..afe7737a0eda459891affba67dcc8ed4da908d86 100644 (file)
@@ -256,10 +256,8 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                        break;
 
                error = freeze_processes();
-               if (error) {
-                       thaw_processes();
+               if (error)
                        usermodehelper_enable();
-               }
                if (!error)
                        data->frozen = 1;
                break;
diff --git a/kernel/rcu.h b/kernel/rcu.h
new file mode 100644 (file)
index 0000000..f600868
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Read-Copy Update definitions shared among RCU implementations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation, 2011
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#ifndef __LINUX_RCU_H
+#define __LINUX_RCU_H
+
+#ifdef CONFIG_RCU_TRACE
+#define RCU_TRACE(stmt) stmt
+#else /* #ifdef CONFIG_RCU_TRACE */
+#define RCU_TRACE(stmt)
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+/*
+ * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
+ * by call_rcu() and rcu callback execution, and are therefore not part of the
+ * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors.
+ */
+
+#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
+# define STATE_RCU_HEAD_READY  0
+# define STATE_RCU_HEAD_QUEUED 1
+
+extern struct debug_obj_descr rcuhead_debug_descr;
+
+static inline void debug_rcu_head_queue(struct rcu_head *head)
+{
+       WARN_ON_ONCE((unsigned long)head & 0x3);
+       debug_object_activate(head, &rcuhead_debug_descr);
+       debug_object_active_state(head, &rcuhead_debug_descr,
+                                 STATE_RCU_HEAD_READY,
+                                 STATE_RCU_HEAD_QUEUED);
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+       debug_object_active_state(head, &rcuhead_debug_descr,
+                                 STATE_RCU_HEAD_QUEUED,
+                                 STATE_RCU_HEAD_READY);
+       debug_object_deactivate(head, &rcuhead_debug_descr);
+}
+#else  /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+static inline void debug_rcu_head_queue(struct rcu_head *head)
+{
+}
+
+static inline void debug_rcu_head_unqueue(struct rcu_head *head)
+{
+}
+#endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
+
+extern void kfree(const void *);
+
+static inline void __rcu_reclaim(char *rn, struct rcu_head *head)
+{
+       unsigned long offset = (unsigned long)head->func;
+
+       if (__is_kfree_rcu_offset(offset)) {
+               RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset));
+               kfree((void *)head - offset);
+       } else {
+               RCU_TRACE(trace_rcu_invoke_callback(rn, head));
+               head->func(head);
+       }
+}
+
+#endif /* __LINUX_RCU_H */
index ddddb320be61ee463cc4e7ea163a379c908745de..ca0d23b6b3e86461f34cfb003858ed2028045e84 100644 (file)
 #include <linux/module.h>
 #include <linux/hardirq.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/rcu.h>
+
+#include "rcu.h"
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key rcu_lock_key;
 struct lockdep_map rcu_lock_map =
@@ -94,11 +99,16 @@ EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
 
 #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
+struct rcu_synchronize {
+       struct rcu_head head;
+       struct completion completion;
+};
+
 /*
  * Awaken the corresponding synchronize_rcu() instance now that a
  * grace period has elapsed.
  */
-void wakeme_after_rcu(struct rcu_head  *head)
+static void wakeme_after_rcu(struct rcu_head  *head)
 {
        struct rcu_synchronize *rcu;
 
@@ -106,6 +116,20 @@ void wakeme_after_rcu(struct rcu_head  *head)
        complete(&rcu->completion);
 }
 
+void wait_rcu_gp(call_rcu_func_t crf)
+{
+       struct rcu_synchronize rcu;
+
+       init_rcu_head_on_stack(&rcu.head);
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       crf(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
+}
+EXPORT_SYMBOL_GPL(wait_rcu_gp);
+
 #ifdef CONFIG_PROVE_RCU
 /*
  * wrapper function to avoid #include problems.
index 7bbac7d0f5abc1d4737c0664c6779d9db1ca5b85..da775c87f27f6aa146bf9b929f72fe0e386d8b41 100644 (file)
 #include <linux/cpu.h>
 #include <linux/prefetch.h>
 
-/* Controls for rcu_kthread() kthread, replacing RCU_SOFTIRQ used previously. */
-static struct task_struct *rcu_kthread_task;
-static DECLARE_WAIT_QUEUE_HEAD(rcu_kthread_wq);
-static unsigned long have_rcu_kthread_work;
+#ifdef CONFIG_RCU_TRACE
+#include <trace/events/rcu.h>
+#endif /* #else #ifdef CONFIG_RCU_TRACE */
+
+#include "rcu.h"
 
 /* Forward declarations for rcutiny_plugin.h. */
 struct rcu_ctrlblk;
-static void invoke_rcu_kthread(void);
-static void rcu_process_callbacks(struct rcu_ctrlblk *rcp);
-static int rcu_kthread(void *arg);
+static void invoke_rcu_callbacks(void);
+static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp);
+static void rcu_process_callbacks(struct softirq_action *unused);
 static void __call_rcu(struct rcu_head *head,
                       void (*func)(struct rcu_head *rcu),
                       struct rcu_ctrlblk *rcp);
@@ -95,16 +96,6 @@ static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
        return 0;
 }
 
-/*
- * Wake up rcu_kthread() to process callbacks now eligible for invocation
- * or to boost readers.
- */
-static void invoke_rcu_kthread(void)
-{
-       have_rcu_kthread_work = 1;
-       wake_up(&rcu_kthread_wq);
-}
-
 /*
  * Record an rcu quiescent state.  And an rcu_bh quiescent state while we
  * are at it, given that any rcu quiescent state is also an rcu_bh
@@ -117,7 +108,7 @@ void rcu_sched_qs(int cpu)
        local_irq_save(flags);
        if (rcu_qsctr_help(&rcu_sched_ctrlblk) +
            rcu_qsctr_help(&rcu_bh_ctrlblk))
-               invoke_rcu_kthread();
+               invoke_rcu_callbacks();
        local_irq_restore(flags);
 }
 
@@ -130,7 +121,7 @@ void rcu_bh_qs(int cpu)
 
        local_irq_save(flags);
        if (rcu_qsctr_help(&rcu_bh_ctrlblk))
-               invoke_rcu_kthread();
+               invoke_rcu_callbacks();
        local_irq_restore(flags);
 }
 
@@ -154,18 +145,23 @@ void rcu_check_callbacks(int cpu, int user)
  * Invoke the RCU callbacks on the specified rcu_ctrlkblk structure
  * whose grace period has elapsed.
  */
-static void rcu_process_callbacks(struct rcu_ctrlblk *rcp)
+static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
 {
+       char *rn = NULL;
        struct rcu_head *next, *list;
        unsigned long flags;
        RCU_TRACE(int cb_count = 0);
 
        /* If no RCU callbacks ready to invoke, just return. */
-       if (&rcp->rcucblist == rcp->donetail)
+       if (&rcp->rcucblist == rcp->donetail) {
+               RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, -1));
+               RCU_TRACE(trace_rcu_batch_end(rcp->name, 0));
                return;
+       }
 
        /* Move the ready-to-invoke callbacks to a local list. */
        local_irq_save(flags);
+       RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, -1));
        list = rcp->rcucblist;
        rcp->rcucblist = *rcp->donetail;
        *rcp->donetail = NULL;
@@ -176,49 +172,26 @@ static void rcu_process_callbacks(struct rcu_ctrlblk *rcp)
        local_irq_restore(flags);
 
        /* Invoke the callbacks on the local list. */
+       RCU_TRACE(rn = rcp->name);
        while (list) {
                next = list->next;
                prefetch(next);
                debug_rcu_head_unqueue(list);
                local_bh_disable();
-               __rcu_reclaim(list);
+               __rcu_reclaim(rn, list);
                local_bh_enable();
                list = next;
                RCU_TRACE(cb_count++);
        }
        RCU_TRACE(rcu_trace_sub_qlen(rcp, cb_count));
+       RCU_TRACE(trace_rcu_batch_end(rcp->name, cb_count));
 }
 
-/*
- * This kthread invokes RCU callbacks whose grace periods have
- * elapsed.  It is awakened as needed, and takes the place of the
- * RCU_SOFTIRQ that was used previously for this purpose.
- * This is a kthread, but it is never stopped, at least not until
- * the system goes down.
- */
-static int rcu_kthread(void *arg)
+static void rcu_process_callbacks(struct softirq_action *unused)
 {
-       unsigned long work;
-       unsigned long morework;
-       unsigned long flags;
-
-       for (;;) {
-               wait_event_interruptible(rcu_kthread_wq,
-                                        have_rcu_kthread_work != 0);
-               morework = rcu_boost();
-               local_irq_save(flags);
-               work = have_rcu_kthread_work;
-               have_rcu_kthread_work = morework;
-               local_irq_restore(flags);
-               if (work) {
-                       rcu_process_callbacks(&rcu_sched_ctrlblk);
-                       rcu_process_callbacks(&rcu_bh_ctrlblk);
-                       rcu_preempt_process_callbacks();
-               }
-               schedule_timeout_interruptible(1); /* Leave CPU for others. */
-       }
-
-       return 0;  /* Not reached, but needed to shut gcc up. */
+       __rcu_process_callbacks(&rcu_sched_ctrlblk);
+       __rcu_process_callbacks(&rcu_bh_ctrlblk);
+       rcu_preempt_process_callbacks();
 }
 
 /*
@@ -280,45 +253,3 @@ void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
        __call_rcu(head, func, &rcu_bh_ctrlblk);
 }
 EXPORT_SYMBOL_GPL(call_rcu_bh);
-
-void rcu_barrier_bh(void)
-{
-       struct rcu_synchronize rcu;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu_bh(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_bh);
-
-void rcu_barrier_sched(void)
-{
-       struct rcu_synchronize rcu;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu_sched(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_sched);
-
-/*
- * Spawn the kthread that invokes RCU callbacks.
- */
-static int __init rcu_spawn_kthreads(void)
-{
-       struct sched_param sp;
-
-       rcu_kthread_task = kthread_run(rcu_kthread, NULL, "rcu_kthread");
-       sp.sched_priority = RCU_BOOST_PRIO;
-       sched_setscheduler_nocheck(rcu_kthread_task, SCHED_FIFO, &sp);
-       return 0;
-}
-early_initcall(rcu_spawn_kthreads);
index f259c676195fcab24fb36af68130519a931778e0..48f20beb378a60ffe16e5f87d47f9b01f0e0c601 100644 (file)
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 
-#ifdef CONFIG_RCU_TRACE
-#define RCU_TRACE(stmt)        stmt
-#else /* #ifdef CONFIG_RCU_TRACE */
-#define RCU_TRACE(stmt)
-#endif /* #else #ifdef CONFIG_RCU_TRACE */
-
 /* Global control variables for rcupdate callback mechanism. */
 struct rcu_ctrlblk {
        struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
        struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
        struct rcu_head **curtail;      /* ->next pointer of last CB. */
        RCU_TRACE(long qlen);           /* Number of pending CBs. */
+       RCU_TRACE(char *name);          /* Name of RCU type. */
 };
 
 /* Definition for rcupdate control block. */
 static struct rcu_ctrlblk rcu_sched_ctrlblk = {
        .donetail       = &rcu_sched_ctrlblk.rcucblist,
        .curtail        = &rcu_sched_ctrlblk.rcucblist,
+       RCU_TRACE(.name = "rcu_sched")
 };
 
 static struct rcu_ctrlblk rcu_bh_ctrlblk = {
        .donetail       = &rcu_bh_ctrlblk.rcucblist,
        .curtail        = &rcu_bh_ctrlblk.rcucblist,
+       RCU_TRACE(.name = "rcu_bh")
 };
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -131,6 +128,7 @@ static struct rcu_preempt_ctrlblk rcu_preempt_ctrlblk = {
        .rcb.curtail = &rcu_preempt_ctrlblk.rcb.rcucblist,
        .nexttail = &rcu_preempt_ctrlblk.rcb.rcucblist,
        .blkd_tasks = LIST_HEAD_INIT(rcu_preempt_ctrlblk.blkd_tasks),
+       RCU_TRACE(.rcb.name = "rcu_preempt")
 };
 
 static int rcu_preempted_readers_exp(void);
@@ -247,6 +245,13 @@ static void show_tiny_preempt_stats(struct seq_file *m)
 
 #include "rtmutex_common.h"
 
+#define RCU_BOOST_PRIO CONFIG_RCU_BOOST_PRIO
+
+/* Controls for rcu_kthread() kthread. */
+static struct task_struct *rcu_kthread_task;
+static DECLARE_WAIT_QUEUE_HEAD(rcu_kthread_wq);
+static unsigned long have_rcu_kthread_work;
+
 /*
  * Carry out RCU priority boosting on the task indicated by ->boost_tasks,
  * and advance ->boost_tasks to the next task in the ->blkd_tasks list.
@@ -334,7 +339,7 @@ static int rcu_initiate_boost(void)
                if (rcu_preempt_ctrlblk.exp_tasks == NULL)
                        rcu_preempt_ctrlblk.boost_tasks =
                                rcu_preempt_ctrlblk.gp_tasks;
-               invoke_rcu_kthread();
+               invoke_rcu_callbacks();
        } else
                RCU_TRACE(rcu_initiate_boost_trace());
        return 1;
@@ -352,14 +357,6 @@ static void rcu_preempt_boost_start_gp(void)
 
 #else /* #ifdef CONFIG_RCU_BOOST */
 
-/*
- * If there is no RCU priority boosting, we don't boost.
- */
-static int rcu_boost(void)
-{
-       return 0;
-}
-
 /*
  * If there is no RCU priority boosting, we don't initiate boosting,
  * but we do indicate whether there are blocked readers blocking the
@@ -427,7 +424,7 @@ static void rcu_preempt_cpu_qs(void)
 
        /* If there are done callbacks, cause them to be invoked. */
        if (*rcu_preempt_ctrlblk.rcb.donetail != NULL)
-               invoke_rcu_kthread();
+               invoke_rcu_callbacks();
 }
 
 /*
@@ -648,7 +645,7 @@ static void rcu_preempt_check_callbacks(void)
                rcu_preempt_cpu_qs();
        if (&rcu_preempt_ctrlblk.rcb.rcucblist !=
            rcu_preempt_ctrlblk.rcb.donetail)
-               invoke_rcu_kthread();
+               invoke_rcu_callbacks();
        if (rcu_preempt_gp_in_progress() &&
            rcu_cpu_blocking_cur_gp() &&
            rcu_preempt_running_reader())
@@ -674,7 +671,7 @@ static void rcu_preempt_remove_callbacks(struct rcu_ctrlblk *rcp)
  */
 static void rcu_preempt_process_callbacks(void)
 {
-       rcu_process_callbacks(&rcu_preempt_ctrlblk.rcb);
+       __rcu_process_callbacks(&rcu_preempt_ctrlblk.rcb);
 }
 
 /*
@@ -697,20 +694,6 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
-void rcu_barrier(void)
-{
-       struct rcu_synchronize rcu;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier);
-
 /*
  * synchronize_rcu - wait until a grace period has elapsed.
  *
@@ -863,15 +846,6 @@ static void show_tiny_preempt_stats(struct seq_file *m)
 
 #endif /* #ifdef CONFIG_RCU_TRACE */
 
-/*
- * Because preemptible RCU does not exist, it is never necessary to
- * boost preempted RCU readers.
- */
-static int rcu_boost(void)
-{
-       return 0;
-}
-
 /*
  * Because preemptible RCU does not exist, it never has any callbacks
  * to check.
@@ -898,6 +872,79 @@ static void rcu_preempt_process_callbacks(void)
 
 #endif /* #else #ifdef CONFIG_TINY_PREEMPT_RCU */
 
+#ifdef CONFIG_RCU_BOOST
+
+/*
+ * Wake up rcu_kthread() to process callbacks now eligible for invocation
+ * or to boost readers.
+ */
+static void invoke_rcu_callbacks(void)
+{
+       have_rcu_kthread_work = 1;
+       wake_up(&rcu_kthread_wq);
+}
+
+/*
+ * This kthread invokes RCU callbacks whose grace periods have
+ * elapsed.  It is awakened as needed, and takes the place of the
+ * RCU_SOFTIRQ that is used for this purpose when boosting is disabled.
+ * This is a kthread, but it is never stopped, at least not until
+ * the system goes down.
+ */
+static int rcu_kthread(void *arg)
+{
+       unsigned long work;
+       unsigned long morework;
+       unsigned long flags;
+
+       for (;;) {
+               wait_event_interruptible(rcu_kthread_wq,
+                                        have_rcu_kthread_work != 0);
+               morework = rcu_boost();
+               local_irq_save(flags);
+               work = have_rcu_kthread_work;
+               have_rcu_kthread_work = morework;
+               local_irq_restore(flags);
+               if (work) {
+                       rcu_process_callbacks(NULL);
+               }
+               schedule_timeout_interruptible(1); /* Leave CPU for others. */
+       }
+
+       return 0;  /* Not reached, but needed to shut gcc up. */
+}
+
+/*
+ * Spawn the kthread that invokes RCU callbacks.
+ */
+static int __init rcu_spawn_kthreads(void)
+{
+       struct sched_param sp;
+
+       rcu_kthread_task = kthread_run(rcu_kthread, NULL, "rcu_kthread");
+       sp.sched_priority = RCU_BOOST_PRIO;
+       sched_setscheduler_nocheck(rcu_kthread_task, SCHED_FIFO, &sp);
+       return 0;
+}
+early_initcall(rcu_spawn_kthreads);
+
+#else /* #ifdef CONFIG_RCU_BOOST */
+
+/*
+ * Start up softirq processing of callbacks.
+ */
+void invoke_rcu_callbacks(void)
+{
+       raise_softirq(RCU_SOFTIRQ);
+}
+
+void rcu_init(void)
+{
+       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+}
+
+#endif /* #else #ifdef CONFIG_RCU_BOOST */
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 #include <linux/kernel_stat.h>
 
@@ -913,12 +960,6 @@ void __init rcu_scheduler_starting(void)
 
 #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
-#ifdef CONFIG_RCU_BOOST
-#define RCU_BOOST_PRIO CONFIG_RCU_BOOST_PRIO
-#else /* #ifdef CONFIG_RCU_BOOST */
-#define RCU_BOOST_PRIO 1
-#endif /* #else #ifdef CONFIG_RCU_BOOST */
-
 #ifdef CONFIG_RCU_TRACE
 
 #ifdef CONFIG_RCU_BOOST
index 98f51b13bb7ec659b3a40f22a4f52b7bb62dfae3..2431d576e9cabbd436d0b1a29c2cae04ffc245b0 100644 (file)
@@ -73,7 +73,7 @@ module_param(nreaders, int, 0444);
 MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
 module_param(nfakewriters, int, 0444);
 MODULE_PARM_DESC(nfakewriters, "Number of RCU fake writer threads");
-module_param(stat_interval, int, 0444);
+module_param(stat_interval, int, 0644);
 MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
 module_param(verbose, bool, 0444);
 MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
@@ -480,30 +480,6 @@ static void rcu_bh_torture_deferred_free(struct rcu_torture *p)
        call_rcu_bh(&p->rtort_rcu, rcu_torture_cb);
 }
 
-struct rcu_bh_torture_synchronize {
-       struct rcu_head head;
-       struct completion completion;
-};
-
-static void rcu_bh_torture_wakeme_after_cb(struct rcu_head *head)
-{
-       struct rcu_bh_torture_synchronize *rcu;
-
-       rcu = container_of(head, struct rcu_bh_torture_synchronize, head);
-       complete(&rcu->completion);
-}
-
-static void rcu_bh_torture_synchronize(void)
-{
-       struct rcu_bh_torture_synchronize rcu;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       call_rcu_bh(&rcu.head, rcu_bh_torture_wakeme_after_cb);
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
-}
-
 static struct rcu_torture_ops rcu_bh_ops = {
        .init           = NULL,
        .cleanup        = NULL,
@@ -512,7 +488,7 @@ static struct rcu_torture_ops rcu_bh_ops = {
        .readunlock     = rcu_bh_torture_read_unlock,
        .completed      = rcu_bh_torture_completed,
        .deferred_free  = rcu_bh_torture_deferred_free,
-       .sync           = rcu_bh_torture_synchronize,
+       .sync           = synchronize_rcu_bh,
        .cb_barrier     = rcu_barrier_bh,
        .fqs            = rcu_bh_force_quiescent_state,
        .stats          = NULL,
@@ -528,7 +504,7 @@ static struct rcu_torture_ops rcu_bh_sync_ops = {
        .readunlock     = rcu_bh_torture_read_unlock,
        .completed      = rcu_bh_torture_completed,
        .deferred_free  = rcu_sync_torture_deferred_free,
-       .sync           = rcu_bh_torture_synchronize,
+       .sync           = synchronize_rcu_bh,
        .cb_barrier     = NULL,
        .fqs            = rcu_bh_force_quiescent_state,
        .stats          = NULL,
@@ -536,6 +512,22 @@ static struct rcu_torture_ops rcu_bh_sync_ops = {
        .name           = "rcu_bh_sync"
 };
 
+static struct rcu_torture_ops rcu_bh_expedited_ops = {
+       .init           = rcu_sync_torture_init,
+       .cleanup        = NULL,
+       .readlock       = rcu_bh_torture_read_lock,
+       .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
+       .readunlock     = rcu_bh_torture_read_unlock,
+       .completed      = rcu_bh_torture_completed,
+       .deferred_free  = rcu_sync_torture_deferred_free,
+       .sync           = synchronize_rcu_bh_expedited,
+       .cb_barrier     = NULL,
+       .fqs            = rcu_bh_force_quiescent_state,
+       .stats          = NULL,
+       .irq_capable    = 1,
+       .name           = "rcu_bh_expedited"
+};
+
 /*
  * Definitions for srcu torture testing.
  */
@@ -659,11 +651,6 @@ static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
        call_rcu_sched(&p->rtort_rcu, rcu_torture_cb);
 }
 
-static void sched_torture_synchronize(void)
-{
-       synchronize_sched();
-}
-
 static struct rcu_torture_ops sched_ops = {
        .init           = rcu_sync_torture_init,
        .cleanup        = NULL,
@@ -672,7 +659,7 @@ static struct rcu_torture_ops sched_ops = {
        .readunlock     = sched_torture_read_unlock,
        .completed      = rcu_no_completed,
        .deferred_free  = rcu_sched_torture_deferred_free,
-       .sync           = sched_torture_synchronize,
+       .sync           = synchronize_sched,
        .cb_barrier     = rcu_barrier_sched,
        .fqs            = rcu_sched_force_quiescent_state,
        .stats          = NULL,
@@ -688,7 +675,7 @@ static struct rcu_torture_ops sched_sync_ops = {
        .readunlock     = sched_torture_read_unlock,
        .completed      = rcu_no_completed,
        .deferred_free  = rcu_sync_torture_deferred_free,
-       .sync           = sched_torture_synchronize,
+       .sync           = synchronize_sched,
        .cb_barrier     = NULL,
        .fqs            = rcu_sched_force_quiescent_state,
        .stats          = NULL,
@@ -754,7 +741,7 @@ static int rcu_torture_boost(void *arg)
        do {
                /* Wait for the next test interval. */
                oldstarttime = boost_starttime;
-               while (jiffies - oldstarttime > ULONG_MAX / 2) {
+               while (ULONG_CMP_LT(jiffies, oldstarttime)) {
                        schedule_timeout_uninterruptible(1);
                        rcu_stutter_wait("rcu_torture_boost");
                        if (kthread_should_stop() ||
@@ -765,7 +752,7 @@ static int rcu_torture_boost(void *arg)
                /* Do one boost-test interval. */
                endtime = oldstarttime + test_boost_duration * HZ;
                call_rcu_time = jiffies;
-               while (jiffies - endtime > ULONG_MAX / 2) {
+               while (ULONG_CMP_LT(jiffies, endtime)) {
                        /* If we don't have a callback in flight, post one. */
                        if (!rbi.inflight) {
                                smp_mb(); /* RCU core before ->inflight = 1. */
@@ -809,11 +796,11 @@ checkwait:        rcu_stutter_wait("rcu_torture_boost");
 
        /* Clean up and exit. */
        VERBOSE_PRINTK_STRING("rcu_torture_boost task stopping");
-       destroy_rcu_head_on_stack(&rbi.rcu);
        rcutorture_shutdown_absorb("rcu_torture_boost");
        while (!kthread_should_stop() || rbi.inflight)
                schedule_timeout_uninterruptible(1);
        smp_mb(); /* order accesses to ->inflight before stack-frame death. */
+       destroy_rcu_head_on_stack(&rbi.rcu);
        return 0;
 }
 
@@ -831,11 +818,13 @@ rcu_torture_fqs(void *arg)
        VERBOSE_PRINTK_STRING("rcu_torture_fqs task started");
        do {
                fqs_resume_time = jiffies + fqs_stutter * HZ;
-               while (jiffies - fqs_resume_time > LONG_MAX) {
+               while (ULONG_CMP_LT(jiffies, fqs_resume_time) &&
+                      !kthread_should_stop()) {
                        schedule_timeout_interruptible(1);
                }
                fqs_burst_remaining = fqs_duration;
-               while (fqs_burst_remaining > 0) {
+               while (fqs_burst_remaining > 0 &&
+                      !kthread_should_stop()) {
                        cur_ops->fqs();
                        udelay(fqs_holdoff);
                        fqs_burst_remaining -= fqs_holdoff;
@@ -1280,8 +1269,9 @@ static int rcutorture_booster_init(int cpu)
        /* Don't allow time recalculation while creating a new task. */
        mutex_lock(&boost_mutex);
        VERBOSE_PRINTK_STRING("Creating rcu_torture_boost task");
-       boost_tasks[cpu] = kthread_create(rcu_torture_boost, NULL,
-                                         "rcu_torture_boost");
+       boost_tasks[cpu] = kthread_create_on_node(rcu_torture_boost, NULL,
+                                                 cpu_to_node(cpu),
+                                                 "rcu_torture_boost");
        if (IS_ERR(boost_tasks[cpu])) {
                retval = PTR_ERR(boost_tasks[cpu]);
                VERBOSE_PRINTK_STRING("rcu_torture_boost task create failed");
@@ -1424,7 +1414,7 @@ rcu_torture_init(void)
        int firsterr = 0;
        static struct rcu_torture_ops *torture_ops[] =
                { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops,
-                 &rcu_bh_ops, &rcu_bh_sync_ops,
+                 &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops,
                  &srcu_ops, &srcu_expedited_ops,
                  &sched_ops, &sched_sync_ops, &sched_expedited_ops, };
 
index ba06207b1dd3bf9f9d42bc8800998b80b909c02d..23ce24e751fd6cee6d43ce7463653deba5ecdd9b 100644 (file)
 #include <linux/prefetch.h>
 
 #include "rcutree.h"
+#include <trace/events/rcu.h>
+
+#include "rcu.h"
 
 /* Data structures. */
 
 static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
 
 #define RCU_STATE_INITIALIZER(structname) { \
-       .level = { &structname.node[0] }, \
+       .level = { &structname##_state.node[0] }, \
        .levelcnt = { \
                NUM_RCU_LVL_0,  /* root of hierarchy. */ \
                NUM_RCU_LVL_1, \
@@ -69,17 +72,17 @@ static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
        .signaled = RCU_GP_IDLE, \
        .gpnum = -300, \
        .completed = -300, \
-       .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname.onofflock), \
-       .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname.fqslock), \
+       .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.onofflock), \
+       .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.fqslock), \
        .n_force_qs = 0, \
        .n_force_qs_ngp = 0, \
        .name = #structname, \
 }
 
-struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched_state);
+struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched);
 DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
 
-struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
+struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh);
 DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
 
 static struct rcu_state *rcu_state;
@@ -156,33 +159,41 @@ static int rcu_gp_in_progress(struct rcu_state *rsp)
  * Note a quiescent state.  Because we do not need to know
  * how many quiescent states passed, just if there was at least
  * one since the start of the grace period, this just sets a flag.
+ * The caller must have disabled preemption.
  */
 void rcu_sched_qs(int cpu)
 {
        struct rcu_data *rdp = &per_cpu(rcu_sched_data, cpu);
 
-       rdp->passed_quiesc_completed = rdp->gpnum - 1;
+       rdp->passed_quiesce_gpnum = rdp->gpnum;
        barrier();
-       rdp->passed_quiesc = 1;
+       if (rdp->passed_quiesce == 0)
+               trace_rcu_grace_period("rcu_sched", rdp->gpnum, "cpuqs");
+       rdp->passed_quiesce = 1;
 }
 
 void rcu_bh_qs(int cpu)
 {
        struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
 
-       rdp->passed_quiesc_completed = rdp->gpnum - 1;
+       rdp->passed_quiesce_gpnum = rdp->gpnum;
        barrier();
-       rdp->passed_quiesc = 1;
+       if (rdp->passed_quiesce == 0)
+               trace_rcu_grace_period("rcu_bh", rdp->gpnum, "cpuqs");
+       rdp->passed_quiesce = 1;
 }
 
 /*
  * Note a context switch.  This is a quiescent state for RCU-sched,
  * and requires special handling for preemptible RCU.
+ * The caller must have disabled preemption.
  */
 void rcu_note_context_switch(int cpu)
 {
+       trace_rcu_utilization("Start context switch");
        rcu_sched_qs(cpu);
        rcu_preempt_note_context_switch(cpu);
+       trace_rcu_utilization("End context switch");
 }
 EXPORT_SYMBOL_GPL(rcu_note_context_switch);
 
@@ -193,7 +204,7 @@ DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
 };
 #endif /* #ifdef CONFIG_NO_HZ */
 
-static int blimit = 10;                /* Maximum callbacks per softirq. */
+static int blimit = 10;                /* Maximum callbacks per rcu_do_batch. */
 static int qhimark = 10000;    /* If this many pending, ignore blimit. */
 static int qlowmark = 100;     /* Once only this many pending, use blimit. */
 
@@ -314,6 +325,7 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
         * trust its state not to change because interrupts are disabled.
         */
        if (cpu_is_offline(rdp->cpu)) {
+               trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, "ofl");
                rdp->offline_fqs++;
                return 1;
        }
@@ -354,19 +366,13 @@ void rcu_enter_nohz(void)
                local_irq_restore(flags);
                return;
        }
+       trace_rcu_dyntick("Start");
        /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
        smp_mb__before_atomic_inc();  /* See above. */
        atomic_inc(&rdtp->dynticks);
        smp_mb__after_atomic_inc();  /* Force ordering with next sojourn. */
        WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
        local_irq_restore(flags);
-
-       /* If the interrupt queued a callback, get out of dyntick mode. */
-       if (in_irq() &&
-           (__get_cpu_var(rcu_sched_data).nxtlist ||
-            __get_cpu_var(rcu_bh_data).nxtlist ||
-            rcu_preempt_needs_cpu(smp_processor_id())))
-               set_need_resched();
 }
 
 /*
@@ -391,6 +397,7 @@ void rcu_exit_nohz(void)
        /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
        smp_mb__after_atomic_inc();  /* See above. */
        WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
+       trace_rcu_dyntick("End");
        local_irq_restore(flags);
 }
 
@@ -469,7 +476,9 @@ void rcu_irq_exit(void)
  */
 static int dyntick_save_progress_counter(struct rcu_data *rdp)
 {
+       smp_mb();  /* Work around some architectures weak impls. */
        rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks);
+       smp_mb();  /* Work around some architectures weak impls. */
        return 0;
 }
 
@@ -481,11 +490,13 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp)
  */
 static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
 {
-       unsigned long curr;
-       unsigned long snap;
+       unsigned int curr;
+       unsigned int snap;
 
-       curr = (unsigned long)atomic_add_return(0, &rdp->dynticks->dynticks);
-       snap = (unsigned long)rdp->dynticks_snap;
+       smp_mb();  /* Work around some architectures weak impls. */
+       curr = (unsigned int)atomic_add_return(0, &rdp->dynticks->dynticks);
+       smp_mb();  /* Work around some architectures weak impls. */
+       snap = (unsigned int)rdp->dynticks_snap;
 
        /*
         * If the CPU passed through or entered a dynticks idle phase with
@@ -495,7 +506,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
         * read-side critical section that started before the beginning
         * of the current RCU grace period.
         */
-       if ((curr & 0x1) == 0 || ULONG_CMP_GE(curr, snap + 2)) {
+       if ((curr & 0x1) == 0 || UINT_CMP_GE(curr, snap + 2)) {
+               trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, "dti");
                rdp->dynticks_fqs++;
                return 1;
        }
@@ -537,6 +549,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
        int cpu;
        long delta;
        unsigned long flags;
+       int ndetected;
        struct rcu_node *rnp = rcu_get_root(rsp);
 
        /* Only let one CPU complain about others per time interval. */
@@ -553,7 +566,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
         * Now rat on any tasks that got kicked up to the root rcu_node
         * due to CPU offlining.
         */
-       rcu_print_task_stall(rnp);
+       ndetected = rcu_print_task_stall(rnp);
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
 
        /*
@@ -565,17 +578,22 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
               rsp->name);
        rcu_for_each_leaf_node(rsp, rnp) {
                raw_spin_lock_irqsave(&rnp->lock, flags);
-               rcu_print_task_stall(rnp);
+               ndetected += rcu_print_task_stall(rnp);
                raw_spin_unlock_irqrestore(&rnp->lock, flags);
                if (rnp->qsmask == 0)
                        continue;
                for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
-                       if (rnp->qsmask & (1UL << cpu))
+                       if (rnp->qsmask & (1UL << cpu)) {
                                printk(" %d", rnp->grplo + cpu);
+                               ndetected++;
+                       }
        }
        printk("} (detected by %d, t=%ld jiffies)\n",
               smp_processor_id(), (long)(jiffies - rsp->gp_start));
-       trigger_all_cpu_backtrace();
+       if (ndetected == 0)
+               printk(KERN_ERR "INFO: Stall ended before state dump start\n");
+       else if (!trigger_all_cpu_backtrace())
+               dump_stack();
 
        /* If so configured, complain about tasks blocking the grace period. */
 
@@ -596,7 +614,8 @@ static void print_cpu_stall(struct rcu_state *rsp)
         */
        printk(KERN_ERR "INFO: %s detected stall on CPU %d (t=%lu jiffies)\n",
               rsp->name, smp_processor_id(), jiffies - rsp->gp_start);
-       trigger_all_cpu_backtrace();
+       if (!trigger_all_cpu_backtrace())
+               dump_stack();
 
        raw_spin_lock_irqsave(&rnp->lock, flags);
        if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
@@ -678,9 +697,10 @@ static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct
                 * go looking for one.
                 */
                rdp->gpnum = rnp->gpnum;
+               trace_rcu_grace_period(rsp->name, rdp->gpnum, "cpustart");
                if (rnp->qsmask & rdp->grpmask) {
                        rdp->qs_pending = 1;
-                       rdp->passed_quiesc = 0;
+                       rdp->passed_quiesce = 0;
                } else
                        rdp->qs_pending = 0;
        }
@@ -741,6 +761,7 @@ __rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_dat
 
                /* Remember that we saw this grace-period completion. */
                rdp->completed = rnp->completed;
+               trace_rcu_grace_period(rsp->name, rdp->gpnum, "cpuend");
 
                /*
                 * If we were in an extended quiescent state, we may have
@@ -826,8 +847,11 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
        struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
        struct rcu_node *rnp = rcu_get_root(rsp);
 
-       if (!cpu_needs_another_gp(rsp, rdp) || rsp->fqs_active) {
-               if (cpu_needs_another_gp(rsp, rdp))
+       if (!rcu_scheduler_fully_active ||
+           !cpu_needs_another_gp(rsp, rdp) ||
+           rsp->fqs_active) {
+               if (rcu_scheduler_fully_active &&
+                   cpu_needs_another_gp(rsp, rdp))
                        rsp->fqs_need_gp = 1;
                if (rnp->completed == rsp->completed) {
                        raw_spin_unlock_irqrestore(&rnp->lock, flags);
@@ -851,6 +875,7 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 
        /* Advance to a new grace period and initialize state. */
        rsp->gpnum++;
+       trace_rcu_grace_period(rsp->name, rsp->gpnum, "start");
        WARN_ON_ONCE(rsp->signaled == RCU_GP_INIT);
        rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */
        rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
@@ -865,6 +890,9 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
                rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */
                rcu_start_gp_per_cpu(rsp, rnp, rdp);
                rcu_preempt_boost_start_gp(rnp);
+               trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
+                                           rnp->level, rnp->grplo,
+                                           rnp->grphi, rnp->qsmask);
                raw_spin_unlock_irqrestore(&rnp->lock, flags);
                return;
        }
@@ -901,6 +929,9 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
                if (rnp == rdp->mynode)
                        rcu_start_gp_per_cpu(rsp, rnp, rdp);
                rcu_preempt_boost_start_gp(rnp);
+               trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
+                                           rnp->level, rnp->grplo,
+                                           rnp->grphi, rnp->qsmask);
                raw_spin_unlock(&rnp->lock);    /* irqs remain disabled. */
        }
 
@@ -934,6 +965,7 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
        if (gp_duration > rsp->gp_max)
                rsp->gp_max = gp_duration;
        rsp->completed = rsp->gpnum;
+       trace_rcu_grace_period(rsp->name, rsp->completed, "end");
        rsp->signaled = RCU_GP_IDLE;
        rcu_start_gp(rsp, flags);  /* releases root node's rnp->lock. */
 }
@@ -962,6 +994,10 @@ rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
                        return;
                }
                rnp->qsmask &= ~mask;
+               trace_rcu_quiescent_state_report(rsp->name, rnp->gpnum,
+                                                mask, rnp->qsmask, rnp->level,
+                                                rnp->grplo, rnp->grphi,
+                                                !!rnp->gp_tasks);
                if (rnp->qsmask != 0 || rcu_preempt_blocked_readers_cgp(rnp)) {
 
                        /* Other bits still set at this level, so done. */
@@ -1000,7 +1036,7 @@ rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
  * based on quiescent states detected in an earlier grace period!
  */
 static void
-rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
+rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastgp)
 {
        unsigned long flags;
        unsigned long mask;
@@ -1008,17 +1044,15 @@ rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long las
 
        rnp = rdp->mynode;
        raw_spin_lock_irqsave(&rnp->lock, flags);
-       if (lastcomp != rnp->completed) {
+       if (lastgp != rnp->gpnum || rnp->completed == rnp->gpnum) {
 
                /*
-                * Someone beat us to it for this grace period, so leave.
-                * The race with GP start is resolved by the fact that we
-                * hold the leaf rcu_node lock, so that the per-CPU bits
-                * cannot yet be initialized -- so we would simply find our
-                * CPU's bit already cleared in rcu_report_qs_rnp() if this
-                * race occurred.
+                * The grace period in which this quiescent state was
+                * recorded has ended, so don't report it upwards.
+                * We will instead need a new quiescent state that lies
+                * within the current grace period.
                 */
-               rdp->passed_quiesc = 0; /* try again later! */
+               rdp->passed_quiesce = 0;        /* need qs for new gp. */
                raw_spin_unlock_irqrestore(&rnp->lock, flags);
                return;
        }
@@ -1062,14 +1096,14 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
         * Was there a quiescent state since the beginning of the grace
         * period? If no, then exit and wait for the next call.
         */
-       if (!rdp->passed_quiesc)
+       if (!rdp->passed_quiesce)
                return;
 
        /*
         * Tell RCU we are done (but rcu_report_qs_rdp() will be the
         * judge of that).
         */
-       rcu_report_qs_rdp(rdp->cpu, rsp, rdp, rdp->passed_quiesc_completed);
+       rcu_report_qs_rdp(rdp->cpu, rsp, rdp, rdp->passed_quiesce_gpnum);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -1130,11 +1164,20 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
                if (rnp->qsmaskinit != 0) {
                        if (rnp != rdp->mynode)
                                raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
+                       else
+                               trace_rcu_grace_period(rsp->name,
+                                                      rnp->gpnum + 1 -
+                                                      !!(rnp->qsmask & mask),
+                                                      "cpuofl");
                        break;
                }
-               if (rnp == rdp->mynode)
+               if (rnp == rdp->mynode) {
+                       trace_rcu_grace_period(rsp->name,
+                                              rnp->gpnum + 1 -
+                                              !!(rnp->qsmask & mask),
+                                              "cpuofl");
                        need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
-               else
+               else
                        raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
                mask = rnp->grpmask;
                rnp = rnp->parent;
@@ -1190,17 +1233,22 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 {
        unsigned long flags;
        struct rcu_head *next, *list, **tail;
-       int count;
+       int bl, count;
 
        /* If no callbacks are ready, just return.*/
-       if (!cpu_has_callbacks_ready_to_invoke(rdp))
+       if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
+               trace_rcu_batch_start(rsp->name, 0, 0);
+               trace_rcu_batch_end(rsp->name, 0);
                return;
+       }
 
        /*
         * Extract the list of ready callbacks, disabling to prevent
         * races with call_rcu() from interrupt handlers.
         */
        local_irq_save(flags);
+       bl = rdp->blimit;
+       trace_rcu_batch_start(rsp->name, rdp->qlen, bl);
        list = rdp->nxtlist;
        rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
        *rdp->nxttail[RCU_DONE_TAIL] = NULL;
@@ -1216,13 +1264,14 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
                next = list->next;
                prefetch(next);
                debug_rcu_head_unqueue(list);
-               __rcu_reclaim(list);
+               __rcu_reclaim(rsp->name, list);
                list = next;
-               if (++count >= rdp->blimit)
+               if (++count >= bl)
                        break;
        }
 
        local_irq_save(flags);
+       trace_rcu_batch_end(rsp->name, count);
 
        /* Update count, and requeue any remaining callbacks. */
        rdp->qlen -= count;
@@ -1250,7 +1299,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 
        local_irq_restore(flags);
 
-       /* Re-raise the RCU softirq if there are callbacks remaining. */
+       /* Re-invoke RCU core processing if there are callbacks remaining. */
        if (cpu_has_callbacks_ready_to_invoke(rdp))
                invoke_rcu_core();
 }
@@ -1258,7 +1307,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 /*
  * Check to see if this CPU is in a non-context-switch quiescent state
  * (user mode or idle loop for rcu, non-softirq execution for rcu_bh).
- * Also schedule the RCU softirq handler.
+ * Also schedule RCU core processing.
  *
  * This function must be called with hardirqs disabled.  It is normally
  * invoked from the scheduling-clock interrupt.  If rcu_pending returns
@@ -1266,6 +1315,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
  */
 void rcu_check_callbacks(int cpu, int user)
 {
+       trace_rcu_utilization("Start scheduler-tick");
        if (user ||
            (idle_cpu(cpu) && rcu_scheduler_active &&
             !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
@@ -1299,6 +1349,7 @@ void rcu_check_callbacks(int cpu, int user)
        rcu_preempt_check_callbacks(cpu);
        if (rcu_pending(cpu))
                invoke_rcu_core();
+       trace_rcu_utilization("End scheduler-tick");
 }
 
 #ifdef CONFIG_SMP
@@ -1360,10 +1411,14 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
        unsigned long flags;
        struct rcu_node *rnp = rcu_get_root(rsp);
 
-       if (!rcu_gp_in_progress(rsp))
+       trace_rcu_utilization("Start fqs");
+       if (!rcu_gp_in_progress(rsp)) {
+               trace_rcu_utilization("End fqs");
                return;  /* No grace period in progress, nothing to force. */
+       }
        if (!raw_spin_trylock_irqsave(&rsp->fqslock, flags)) {
                rsp->n_force_qs_lh++; /* Inexact, can lose counts.  Tough! */
+               trace_rcu_utilization("End fqs");
                return; /* Someone else is already on the job. */
        }
        if (relaxed && ULONG_CMP_GE(rsp->jiffies_force_qs, jiffies))
@@ -1412,11 +1467,13 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
                raw_spin_unlock(&rsp->fqslock); /* irqs remain disabled */
                rsp->fqs_need_gp = 0;
                rcu_start_gp(rsp, flags); /* releases rnp->lock */
+               trace_rcu_utilization("End fqs");
                return;
        }
        raw_spin_unlock(&rnp->lock);  /* irqs remain disabled */
 unlock_fqs_ret:
        raw_spin_unlock_irqrestore(&rsp->fqslock, flags);
+       trace_rcu_utilization("End fqs");
 }
 
 #else /* #ifdef CONFIG_SMP */
@@ -1429,9 +1486,9 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
 #endif /* #else #ifdef CONFIG_SMP */
 
 /*
- * This does the RCU processing work from softirq context for the
- * specified rcu_state and rcu_data structures.  This may be called
- * only from the CPU to whom the rdp belongs.
+ * This does the RCU core processing work for the specified rcu_state
+ * and rcu_data structures.  This may be called only from the CPU to
+ * whom the rdp belongs.
  */
 static void
 __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
@@ -1468,10 +1525,11 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
 }
 
 /*
- * Do softirq processing for the current CPU.
+ * Do RCU core processing for the current CPU.
  */
 static void rcu_process_callbacks(struct softirq_action *unused)
 {
+       trace_rcu_utilization("Start RCU core");
        __rcu_process_callbacks(&rcu_sched_state,
                                &__get_cpu_var(rcu_sched_data));
        __rcu_process_callbacks(&rcu_bh_state, &__get_cpu_var(rcu_bh_data));
@@ -1479,13 +1537,15 @@ static void rcu_process_callbacks(struct softirq_action *unused)
 
        /* If we are last CPU on way to dyntick-idle mode, accelerate it. */
        rcu_needs_cpu_flush();
+       trace_rcu_utilization("End RCU core");
 }
 
 /*
- * Wake up the current CPU's kthread.  This replaces raise_softirq()
- * in earlier versions of RCU.  Note that because we are running on
- * the current CPU with interrupts disabled, the rcu_cpu_kthread_task
- * cannot disappear out from under us.
+ * Schedule RCU callback invocation.  If the specified type of RCU
+ * does not support RCU priority boosting, just do a direct call,
+ * otherwise wake up the per-CPU kernel kthread.  Note that because we
+ * are running on the current CPU with interrupts disabled, the
+ * rcu_cpu_kthread_task cannot disappear out from under us.
  */
 static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp)
 {
@@ -1530,6 +1590,12 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
        rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
        rdp->qlen++;
 
+       if (__is_kfree_rcu_offset((unsigned long)func))
+               trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
+                                        rdp->qlen);
+       else
+               trace_rcu_callback(rsp->name, head, rdp->qlen);
+
        /* If interrupts were disabled, don't dive into RCU core. */
        if (irqs_disabled_flags(flags)) {
                local_irq_restore(flags);
@@ -1613,18 +1679,9 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
  */
 void synchronize_sched(void)
 {
-       struct rcu_synchronize rcu;
-
        if (rcu_blocking_is_gp())
                return;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu_sched(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
+       wait_rcu_gp(call_rcu_sched);
 }
 EXPORT_SYMBOL_GPL(synchronize_sched);
 
@@ -1639,18 +1696,9 @@ EXPORT_SYMBOL_GPL(synchronize_sched);
  */
 void synchronize_rcu_bh(void)
 {
-       struct rcu_synchronize rcu;
-
        if (rcu_blocking_is_gp())
                return;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu_bh(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
+       wait_rcu_gp(call_rcu_bh);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
 
@@ -1671,7 +1719,8 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
        check_cpu_stall(rsp, rdp);
 
        /* Is the RCU core waiting for a quiescent state from this CPU? */
-       if (rdp->qs_pending && !rdp->passed_quiesc) {
+       if (rcu_scheduler_fully_active &&
+           rdp->qs_pending && !rdp->passed_quiesce) {
 
                /*
                 * If force_quiescent_state() coming soon and this CPU
@@ -1683,7 +1732,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
                    ULONG_CMP_LT(ACCESS_ONCE(rsp->jiffies_force_qs) - 1,
                                 jiffies))
                        set_need_resched();
-       } else if (rdp->qs_pending && rdp->passed_quiesc) {
+       } else if (rdp->qs_pending && rdp->passed_quiesce) {
                rdp->n_rp_report_qs++;
                return 1;
        }
@@ -1846,6 +1895,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
        rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
 #endif /* #ifdef CONFIG_NO_HZ */
        rdp->cpu = cpu;
+       rdp->rsp = rsp;
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
 }
 
@@ -1865,8 +1915,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
 
        /* Set up local state, ensuring consistent view of global state. */
        raw_spin_lock_irqsave(&rnp->lock, flags);
-       rdp->passed_quiesc = 0;  /* We could be racing with new GP, */
-       rdp->qs_pending = 1;     /*  so set up to respond to current GP. */
        rdp->beenonline = 1;     /* We have now been online. */
        rdp->preemptible = preemptible;
        rdp->qlen_last_fqs_check = 0;
@@ -1891,9 +1939,17 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
                rnp->qsmaskinit |= mask;
                mask = rnp->grpmask;
                if (rnp == rdp->mynode) {
-                       rdp->gpnum = rnp->completed; /* if GP in progress... */
+                       /*
+                        * If there is a grace period in progress, we will
+                        * set up to wait for it next time we run the
+                        * RCU core code.
+                        */
+                       rdp->gpnum = rnp->completed;
                        rdp->completed = rnp->completed;
-                       rdp->passed_quiesc_completed = rnp->completed - 1;
+                       rdp->passed_quiesce = 0;
+                       rdp->qs_pending = 0;
+                       rdp->passed_quiesce_gpnum = rnp->gpnum - 1;
+                       trace_rcu_grace_period(rsp->name, rdp->gpnum, "cpuonl");
                }
                raw_spin_unlock(&rnp->lock); /* irqs already disabled. */
                rnp = rnp->parent;
@@ -1919,6 +1975,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
        struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu);
        struct rcu_node *rnp = rdp->mynode;
 
+       trace_rcu_utilization("Start CPU hotplug");
        switch (action) {
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
@@ -1954,6 +2011,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
        default:
                break;
        }
+       trace_rcu_utilization("End CPU hotplug");
        return NOTIFY_OK;
 }
 
index 01b2ccda26fbf82880cc1d4a50bf9f2877e91bba..f509f728f9fbe970a2ecae3d5d6d278cccb88961 100644 (file)
@@ -230,9 +230,9 @@ struct rcu_data {
                                        /*  in order to detect GP end. */
        unsigned long   gpnum;          /* Highest gp number that this CPU */
                                        /*  is aware of having started. */
-       unsigned long   passed_quiesc_completed;
-                                       /* Value of completed at time of qs. */
-       bool            passed_quiesc /* User-mode/idle loop etc. */
+       unsigned long   passed_quiesce_gpnum;
+                                       /* gpnum at time of quiescent state. */
+       bool            passed_quiesce; /* User-mode/idle loop etc. */
        bool            qs_pending;     /* Core waits for quiesc state. */
        bool            beenonline;     /* CPU online at least once. */
        bool            preemptible;    /* Preemptible RCU? */
@@ -299,6 +299,7 @@ struct rcu_data {
        unsigned long n_rp_need_nothing;
 
        int cpu;
+       struct rcu_state *rsp;
 };
 
 /* Values for signaled field in struct rcu_state. */
@@ -417,6 +418,13 @@ extern struct rcu_state rcu_preempt_state;
 DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
 #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
 
+#ifdef CONFIG_RCU_BOOST
+DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
+DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu);
+DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
+DECLARE_PER_CPU(char, rcu_cpu_has_work);
+#endif /* #ifdef CONFIG_RCU_BOOST */
+
 #ifndef RCU_TREE_NONCORE
 
 /* Forward declarations for rcutree_plugin.h */
@@ -430,7 +438,7 @@ static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp,
 static void rcu_stop_cpu_kthread(int cpu);
 #endif /* #ifdef CONFIG_HOTPLUG_CPU */
 static void rcu_print_detail_task_stall(struct rcu_state *rsp);
-static void rcu_print_task_stall(struct rcu_node *rnp);
+static int rcu_print_task_stall(struct rcu_node *rnp);
 static void rcu_preempt_stall_reset(void);
 static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
 #ifdef CONFIG_HOTPLUG_CPU
index 8aafbb80b8b093e1072f2fcc4dc66bf40f249b7f..b8e902c2f9eae096ce464a8aa56082c1d5e77b43 100644 (file)
@@ -64,7 +64,7 @@ static void __init rcu_bootup_announce_oddness(void)
 
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
-struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state);
+struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt);
 DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data);
 static struct rcu_state *rcu_state = &rcu_preempt_state;
 
@@ -122,9 +122,11 @@ static void rcu_preempt_qs(int cpu)
 {
        struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
 
-       rdp->passed_quiesc_completed = rdp->gpnum - 1;
+       rdp->passed_quiesce_gpnum = rdp->gpnum;
        barrier();
-       rdp->passed_quiesc = 1;
+       if (rdp->passed_quiesce == 0)
+               trace_rcu_grace_period("rcu_preempt", rdp->gpnum, "cpuqs");
+       rdp->passed_quiesce = 1;
        current->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
 }
 
@@ -190,6 +192,11 @@ static void rcu_preempt_note_context_switch(int cpu)
                        if (rnp->qsmask & rdp->grpmask)
                                rnp->gp_tasks = &t->rcu_node_entry;
                }
+               trace_rcu_preempt_task(rdp->rsp->name,
+                                      t->pid,
+                                      (rnp->qsmask & rdp->grpmask)
+                                      ? rnp->gpnum
+                                      : rnp->gpnum + 1);
                raw_spin_unlock_irqrestore(&rnp->lock, flags);
        } else if (t->rcu_read_lock_nesting < 0 &&
                   t->rcu_read_unlock_special) {
@@ -299,6 +306,9 @@ static noinline void rcu_read_unlock_special(struct task_struct *t)
        int empty_exp;
        unsigned long flags;
        struct list_head *np;
+#ifdef CONFIG_RCU_BOOST
+       struct rt_mutex *rbmp = NULL;
+#endif /* #ifdef CONFIG_RCU_BOOST */
        struct rcu_node *rnp;
        int special;
 
@@ -344,6 +354,9 @@ static noinline void rcu_read_unlock_special(struct task_struct *t)
                smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
                np = rcu_next_node_entry(t, rnp);
                list_del_init(&t->rcu_node_entry);
+               t->rcu_blocked_node = NULL;
+               trace_rcu_unlock_preempted_task("rcu_preempt",
+                                               rnp->gpnum, t->pid);
                if (&t->rcu_node_entry == rnp->gp_tasks)
                        rnp->gp_tasks = np;
                if (&t->rcu_node_entry == rnp->exp_tasks)
@@ -351,30 +364,34 @@ static noinline void rcu_read_unlock_special(struct task_struct *t)
 #ifdef CONFIG_RCU_BOOST
                if (&t->rcu_node_entry == rnp->boost_tasks)
                        rnp->boost_tasks = np;
-               /* Snapshot and clear ->rcu_boosted with rcu_node lock held. */
-               if (t->rcu_boosted) {
-                       special |= RCU_READ_UNLOCK_BOOSTED;
-                       t->rcu_boosted = 0;
+               /* Snapshot/clear ->rcu_boost_mutex with rcu_node lock held. */
+               if (t->rcu_boost_mutex) {
+                       rbmp = t->rcu_boost_mutex;
+                       t->rcu_boost_mutex = NULL;
                }
 #endif /* #ifdef CONFIG_RCU_BOOST */
-               t->rcu_blocked_node = NULL;
 
                /*
                 * If this was the last task on the current list, and if
                 * we aren't waiting on any CPUs, report the quiescent state.
                 * Note that rcu_report_unblock_qs_rnp() releases rnp->lock.
                 */
-               if (empty)
-                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
-               else
+               if (!empty && !rcu_preempt_blocked_readers_cgp(rnp)) {
+                       trace_rcu_quiescent_state_report("preempt_rcu",
+                                                        rnp->gpnum,
+                                                        0, rnp->qsmask,
+                                                        rnp->level,
+                                                        rnp->grplo,
+                                                        rnp->grphi,
+                                                        !!rnp->gp_tasks);
                        rcu_report_unblock_qs_rnp(rnp, flags);
+               } else
+                       raw_spin_unlock_irqrestore(&rnp->lock, flags);
 
 #ifdef CONFIG_RCU_BOOST
                /* Unboost if we were boosted. */
-               if (special & RCU_READ_UNLOCK_BOOSTED) {
-                       rt_mutex_unlock(t->rcu_boost_mutex);
-                       t->rcu_boost_mutex = NULL;
-               }
+               if (rbmp)
+                       rt_mutex_unlock(rbmp);
 #endif /* #ifdef CONFIG_RCU_BOOST */
 
                /*
@@ -399,10 +416,10 @@ void __rcu_read_unlock(void)
 {
        struct task_struct *t = current;
 
-       barrier();  /* needed if we ever invoke rcu_read_unlock in rcutree.c */
        if (t->rcu_read_lock_nesting != 1)
                --t->rcu_read_lock_nesting;
        else {
+               barrier();  /* critical section before exit code. */
                t->rcu_read_lock_nesting = INT_MIN;
                barrier();  /* assign before ->rcu_read_unlock_special load */
                if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special)))
@@ -466,16 +483,20 @@ static void rcu_print_detail_task_stall(struct rcu_state *rsp)
  * Scan the current list of tasks blocked within RCU read-side critical
  * sections, printing out the tid of each.
  */
-static void rcu_print_task_stall(struct rcu_node *rnp)
+static int rcu_print_task_stall(struct rcu_node *rnp)
 {
        struct task_struct *t;
+       int ndetected = 0;
 
        if (!rcu_preempt_blocked_readers_cgp(rnp))
-               return;
+               return 0;
        t = list_entry(rnp->gp_tasks,
                       struct task_struct, rcu_node_entry);
-       list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry)
+       list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
                printk(" P%d", t->pid);
+               ndetected++;
+       }
+       return ndetected;
 }
 
 /*
@@ -656,18 +677,9 @@ EXPORT_SYMBOL_GPL(call_rcu);
  */
 void synchronize_rcu(void)
 {
-       struct rcu_synchronize rcu;
-
        if (!rcu_scheduler_active)
                return;
-
-       init_rcu_head_on_stack(&rcu.head);
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-       destroy_rcu_head_on_stack(&rcu.head);
+       wait_rcu_gp(call_rcu);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
@@ -968,8 +980,9 @@ static void rcu_print_detail_task_stall(struct rcu_state *rsp)
  * Because preemptible RCU does not exist, we never have to check for
  * tasks blocked within RCU read-side critical sections.
  */
-static void rcu_print_task_stall(struct rcu_node *rnp)
+static int rcu_print_task_stall(struct rcu_node *rnp)
 {
+       return 0;
 }
 
 /*
@@ -1136,6 +1149,8 @@ static void rcu_initiate_boost_trace(struct rcu_node *rnp)
 
 #endif /* #else #ifdef CONFIG_RCU_TRACE */
 
+static struct lock_class_key rcu_boost_class;
+
 /*
  * Carry out RCU priority boosting on the task indicated by ->exp_tasks
  * or ->boost_tasks, advancing the pointer to the next task in the
@@ -1198,11 +1213,14 @@ static int rcu_boost(struct rcu_node *rnp)
         */
        t = container_of(tb, struct task_struct, rcu_node_entry);
        rt_mutex_init_proxy_locked(&mtx, t);
+       /* Avoid lockdep false positives.  This rt_mutex is its own thing. */
+       lockdep_set_class_and_name(&mtx.wait_lock, &rcu_boost_class,
+                                  "rcu_boost_mutex");
        t->rcu_boost_mutex = &mtx;
-       t->rcu_boosted = 1;
        raw_spin_unlock_irqrestore(&rnp->lock, flags);
        rt_mutex_lock(&mtx);  /* Side effect: boosts task t's priority. */
        rt_mutex_unlock(&mtx);  /* Keep lockdep happy. */
+       local_irq_restore(flags);
 
        return rnp->exp_tasks != NULL || rnp->boost_tasks != NULL;
 }
@@ -1228,9 +1246,12 @@ static int rcu_boost_kthread(void *arg)
        int spincnt = 0;
        int more2boost;
 
+       trace_rcu_utilization("Start boost kthread@init");
        for (;;) {
                rnp->boost_kthread_status = RCU_KTHREAD_WAITING;
+               trace_rcu_utilization("End boost kthread@rcu_wait");
                rcu_wait(rnp->boost_tasks || rnp->exp_tasks);
+               trace_rcu_utilization("Start boost kthread@rcu_wait");
                rnp->boost_kthread_status = RCU_KTHREAD_RUNNING;
                more2boost = rcu_boost(rnp);
                if (more2boost)
@@ -1238,11 +1259,14 @@ static int rcu_boost_kthread(void *arg)
                else
                        spincnt = 0;
                if (spincnt > 10) {
+                       trace_rcu_utilization("End boost kthread@rcu_yield");
                        rcu_yield(rcu_boost_kthread_timer, (unsigned long)rnp);
+                       trace_rcu_utilization("Start boost kthread@rcu_yield");
                        spincnt = 0;
                }
        }
        /* NOTREACHED */
+       trace_rcu_utilization("End boost kthread@notreached");
        return 0;
 }
 
@@ -1291,11 +1315,9 @@ static void invoke_rcu_callbacks_kthread(void)
 
        local_irq_save(flags);
        __this_cpu_write(rcu_cpu_has_work, 1);
-       if (__this_cpu_read(rcu_cpu_kthread_task) == NULL) {
-               local_irq_restore(flags);
-               return;
-       }
-       wake_up_process(__this_cpu_read(rcu_cpu_kthread_task));
+       if (__this_cpu_read(rcu_cpu_kthread_task) != NULL &&
+           current != __this_cpu_read(rcu_cpu_kthread_task))
+               wake_up_process(__this_cpu_read(rcu_cpu_kthread_task));
        local_irq_restore(flags);
 }
 
@@ -1489,7 +1511,8 @@ static int rcu_cpu_kthread_should_stop(int cpu)
 
 /*
  * Per-CPU kernel thread that invokes RCU callbacks.  This replaces the
- * earlier RCU softirq.
+ * RCU softirq used in flavors and configurations of RCU that do not
+ * support RCU priority boosting.
  */
 static int rcu_cpu_kthread(void *arg)
 {
@@ -1500,9 +1523,12 @@ static int rcu_cpu_kthread(void *arg)
        char work;
        char *workp = &per_cpu(rcu_cpu_has_work, cpu);
 
+       trace_rcu_utilization("Start CPU kthread@init");
        for (;;) {
                *statusp = RCU_KTHREAD_WAITING;
+               trace_rcu_utilization("End CPU kthread@rcu_wait");
                rcu_wait(*workp != 0 || kthread_should_stop());
+               trace_rcu_utilization("Start CPU kthread@rcu_wait");
                local_bh_disable();
                if (rcu_cpu_kthread_should_stop(cpu)) {
                        local_bh_enable();
@@ -1523,11 +1549,14 @@ static int rcu_cpu_kthread(void *arg)
                        spincnt = 0;
                if (spincnt > 10) {
                        *statusp = RCU_KTHREAD_YIELDING;
+                       trace_rcu_utilization("End CPU kthread@rcu_yield");
                        rcu_yield(rcu_cpu_kthread_timer, (unsigned long)cpu);
+                       trace_rcu_utilization("Start CPU kthread@rcu_yield");
                        spincnt = 0;
                }
        }
        *statusp = RCU_KTHREAD_STOPPED;
+       trace_rcu_utilization("End CPU kthread@term");
        return 0;
 }
 
@@ -1560,7 +1589,10 @@ static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu)
        if (!rcu_scheduler_fully_active ||
            per_cpu(rcu_cpu_kthread_task, cpu) != NULL)
                return 0;
-       t = kthread_create(rcu_cpu_kthread, (void *)(long)cpu, "rcuc%d", cpu);
+       t = kthread_create_on_node(rcu_cpu_kthread,
+                                  (void *)(long)cpu,
+                                  cpu_to_node(cpu),
+                                  "rcuc%d", cpu);
        if (IS_ERR(t))
                return PTR_ERR(t);
        if (cpu_online(cpu))
@@ -1594,7 +1626,9 @@ static int rcu_node_kthread(void *arg)
                rcu_wait(atomic_read(&rnp->wakemask) != 0);
                rnp->node_kthread_status = RCU_KTHREAD_RUNNING;
                raw_spin_lock_irqsave(&rnp->lock, flags);
+               smp_mb();  /* Work around some architectures weak impls. */
                mask = atomic_xchg(&rnp->wakemask, 0);
+               smp_mb();  /* Work around some architectures weak impls. */
                rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */
                for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) {
                        if ((mask & 0x1) == 0)
@@ -1830,7 +1864,9 @@ void synchronize_sched_expedited(void)
        int firstsnap, s, snap, trycount = 0;
 
        /* Note that atomic_inc_return() implies full memory barrier. */
+       smp_mb();  /* Work around some architectures weak impls. */
        firstsnap = snap = atomic_inc_return(&sync_sched_expedited_started);
+       smp_mb();  /* Work around some architectures weak impls. */
        get_online_cpus();
 
        /*
@@ -1883,6 +1919,7 @@ void synchronize_sched_expedited(void)
                        break;
                }
        } while (atomic_cmpxchg(&sync_sched_expedited_done, s, snap) != s);
+       smp_mb();
 
        put_online_cpus();
 }
@@ -1953,9 +1990,10 @@ int rcu_needs_cpu(int cpu)
        for_each_online_cpu(thatcpu) {
                if (thatcpu == cpu)
                        continue;
+               smp_mb();  /* Work around some architectures weak impls. */
                snap = atomic_add_return(0, &per_cpu(rcu_dynticks,
                                                     thatcpu).dynticks);
-               smp_mb(); /* Order sampling of snap with end of grace period. */
+               smp_mb();  /* Work around some architectures weak impls. */
                if ((snap & 0x1) != 0) {
                        per_cpu(rcu_dyntick_drain, cpu) = 0;
                        per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
index 3b0c0986afc0f0ec6d190176aa9695ba4d998957..9feffa4c069567909452e276633f25f512191f58 100644 (file)
 
 #ifdef CONFIG_RCU_BOOST
 
-DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
-DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_cpu);
-DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops);
-DECLARE_PER_CPU(char, rcu_cpu_has_work);
-
 static char convert_kthread_status(unsigned int kthread_status)
 {
        if (kthread_status > RCU_KTHREAD_MAX)
@@ -66,11 +61,11 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
 {
        if (!rdp->beenonline)
                return;
-       seq_printf(m, "%3d%cc=%lu g=%lu pq=%d pqc=%lu qp=%d",
+       seq_printf(m, "%3d%cc=%lu g=%lu pq=%d pgp=%lu qp=%d",
                   rdp->cpu,
                   cpu_is_offline(rdp->cpu) ? '!' : ' ',
                   rdp->completed, rdp->gpnum,
-                  rdp->passed_quiesc, rdp->passed_quiesc_completed,
+                  rdp->passed_quiesce, rdp->passed_quiesce_gpnum,
                   rdp->qs_pending);
 #ifdef CONFIG_NO_HZ
        seq_printf(m, " dt=%d/%d/%d df=%lu",
@@ -144,7 +139,7 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
                   rdp->cpu,
                   cpu_is_offline(rdp->cpu) ? "\"N\"" : "\"Y\"",
                   rdp->completed, rdp->gpnum,
-                  rdp->passed_quiesc, rdp->passed_quiesc_completed,
+                  rdp->passed_quiesce, rdp->passed_quiesce_gpnum,
                   rdp->qs_pending);
 #ifdef CONFIG_NO_HZ
        seq_printf(m, ",%d,%d,%d,%lu",
@@ -175,7 +170,7 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
 
 static int show_rcudata_csv(struct seq_file *m, void *unused)
 {
-       seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\",");
+       seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pgp\",\"pq\",");
 #ifdef CONFIG_NO_HZ
        seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\",");
 #endif /* #ifdef CONFIG_NO_HZ */
index 255e1662acdb496b77c50205daa455d404f7749b..e7d813c30d9b6b5026736a2297d0d9a9f8db823f 100644 (file)
@@ -579,6 +579,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state,
                    struct rt_mutex_waiter *waiter)
 {
        int ret = 0;
+       int was_disabled;
 
        for (;;) {
                /* Try to acquire the lock: */
@@ -601,10 +602,16 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state,
 
                raw_spin_unlock(&lock->wait_lock);
 
+               if (was_disabled = irqs_disabled())
+                       local_irq_enable();
+
                debug_rt_mutex_print_deadlock(waiter);
 
                schedule_rt_mutex(lock);
 
+               if (was_disabled)
+                       local_irq_disable();
+
                raw_spin_lock(&lock->wait_lock);
                set_current_state(state);
        }
index ccacdbdecf452bda8769878ca6e558d13ebb4e74..50e3f564d5b5fbd1033c9b8f5717f79de4741f31 100644 (file)
@@ -4237,6 +4237,7 @@ static inline void schedule_debug(struct task_struct *prev)
         */
        if (unlikely(in_atomic_preempt_off() && !prev->exit_state))
                __schedule_bug(prev);
+       rcu_sleep_check();
 
        profile_hit(SCHED_PROFILING, __builtin_return_address(0));
 
@@ -5968,15 +5969,6 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
        ftrace_graph_init_idle_task(idle, cpu);
 }
 
-/*
- * In a system that switches off the HZ timer nohz_cpu_mask
- * indicates which cpus entered this state. This is used
- * in the rcu update to wait only for active cpus. For system
- * which do not switch off the HZ timer nohz_cpu_mask should
- * always be CPU_BITS_NONE.
- */
-cpumask_var_t nohz_cpu_mask;
-
 /*
  * Increase the granularity value when there are more CPUs,
  * because with more CPUs the 'effective latency' as visible
@@ -8188,8 +8180,6 @@ void __init sched_init(void)
         */
        current->sched_class = &fair_sched_class;
 
-       /* Allocate the nohz_cpu_mask if CONFIG_CPUMASK_OFFSTACK */
-       zalloc_cpumask_var(&nohz_cpu_mask, GFP_NOWAIT);
 #ifdef CONFIG_SMP
        zalloc_cpumask_var(&sched_domains_tmpmask, GFP_NOWAIT);
 #ifdef CONFIG_NO_HZ
@@ -8219,6 +8209,7 @@ void __might_sleep(const char *file, int line, int preempt_offset)
 {
        static unsigned long prev_jiffy;        /* ratelimiting */
 
+       rcu_sleep_check(); /* WARN_ON_ONCE() by default, no rate limit reqd. */
        if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) ||
            system_state != SYSTEM_RUNNING || oops_in_progress)
                return;
index 3b8e028b96014a088b6227859b9163e8bceddb5a..e8bffbe2ba4b3c078594f34f4594769dfc18f2c3 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/stat.h>
 #include <linux/sysctl.h>
-#include "../fs/xfs/linux-2.6/xfs_sysctl.h"
+#include "../fs/xfs/xfs_sysctl.h"
 #include <linux/sunrpc/debug.h>
 #include <linux/string.h>
 #include <net/ip_vs.h>
index 4e4932a7b3608ac6e32175ee87481c1ac47a3572..362da653813da60e339d57c9d28262b0dc7c36cd 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/stat.h>
 #include <linux/sysctl.h>
-#include "../fs/xfs/linux-2.6/xfs_sysctl.h"
+#include "../fs/xfs/xfs_sysctl.h"
 #include <linux/sunrpc/debug.h>
 #include <linux/string.h>
 #include <net/ip_vs.h>
index d5097c44b407e25a1acae0f5d85c520eda555ae5..eb98e55196b96275f6ee73af0b5d6e351d9162dc 100644 (file)
@@ -139,7 +139,6 @@ static void tick_nohz_update_jiffies(ktime_t now)
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
        unsigned long flags;
 
-       cpumask_clear_cpu(cpu, nohz_cpu_mask);
        ts->idle_waketime = now;
 
        local_irq_save(flags);
@@ -389,9 +388,6 @@ void tick_nohz_stop_sched_tick(int inidle)
                else
                        expires.tv64 = KTIME_MAX;
 
-               if (delta_jiffies > 1)
-                       cpumask_set_cpu(cpu, nohz_cpu_mask);
-
                /* Skip reprogram of event if its not changed */
                if (ts->tick_stopped && ktime_equal(expires, dev->next_event))
                        goto out;
@@ -441,7 +437,6 @@ void tick_nohz_stop_sched_tick(int inidle)
                 * softirq.
                 */
                tick_do_update_jiffies64(ktime_get());
-               cpumask_clear_cpu(cpu, nohz_cpu_mask);
        }
        raise_softirq_irqoff(TIMER_SOFTIRQ);
 out:
@@ -524,7 +519,6 @@ void tick_nohz_restart_sched_tick(void)
        /* Update jiffies first */
        select_nohz_load_balancer(0);
        tick_do_update_jiffies64(now);
-       cpumask_clear_cpu(cpu, nohz_cpu_mask);
 
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
        /*
index c0cb9c4bc46d661ef5f37fda9ac8faa199a1ca23..639c95aca53cf4b63069fe0689ed212f6bb7744b 100644 (file)
@@ -835,7 +835,7 @@ config DEBUG_CREDENTIALS
 
 #
 # Select this config option from the architecture Kconfig, if it
-# it is preferred to always offer frame pointers as a config
+# is preferred to always offer frame pointers as a config
 # option on the architecture (regardless of KERNEL_DEBUG):
 #
 config ARCH_WANT_FRAME_POINTERS
@@ -1070,6 +1070,17 @@ config FAIL_IO_TIMEOUT
          Only works with drivers that use the generic timeout handling,
          for others it wont do anything.
 
+config FAIL_MMC_REQUEST
+       bool "Fault-injection capability for MMC IO"
+       select DEBUG_FS
+       depends on FAULT_INJECTION && MMC
+       help
+         Provide fault-injection capability for MMC IO.
+         This will make the mmc core return data errors. This is
+         useful to test the error handling in the mmc block device
+         and to test how the mmc host driver handles retries from
+         the block device.
+
 config FAULT_INJECTION_DEBUG_FS
        bool "Debugfs entries for fault-injection capabilities"
        depends on FAULT_INJECTION && SYSFS && DEBUG_FS
index 75ca78f3a8c9bc39cb60bcad14535b7978f52e00..ee3b9ba625c5401ecc537eee81827ed8312aced3 100644 (file)
@@ -10,6 +10,8 @@
  * Copyright (C) 2011 Bart Van Assche.  All Rights Reserved.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -30,6 +32,8 @@
 #include <linux/jump_label.h>
 #include <linux/hardirq.h>
 #include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
 
 extern struct _ddebug __start___verbose[];
 extern struct _ddebug __stop___verbose[];
@@ -159,8 +163,7 @@ static void ddebug_change(const struct ddebug_query *query,
                        else
                                dp->enabled = 0;
                        if (verbose)
-                               printk(KERN_INFO
-                                       "ddebug: changed %s:%d [%s]%s %s\n",
+                               pr_info("changed %s:%d [%s]%s %s\n",
                                        dp->filename, dp->lineno,
                                        dt->mod_name, dp->function,
                                        ddebug_describe_flags(dp, flagbuf,
@@ -170,7 +173,7 @@ static void ddebug_change(const struct ddebug_query *query,
        mutex_unlock(&ddebug_lock);
 
        if (!nfound && verbose)
-               printk(KERN_INFO "ddebug: no matches for query\n");
+               pr_info("no matches for query\n");
 }
 
 /*
@@ -215,10 +218,10 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
 
        if (verbose) {
                int i;
-               printk(KERN_INFO "%s: split into words:", __func__);
+               pr_info("split into words:");
                for (i = 0 ; i < nwords ; i++)
-                       printk(" \"%s\"", words[i]);
-               printk("\n");
+                       pr_cont(" \"%s\"", words[i]);
+               pr_cont("\n");
        }
 
        return nwords;
@@ -330,16 +333,15 @@ static int ddebug_parse_query(char *words[], int nwords,
                        }
                } else {
                        if (verbose)
-                               printk(KERN_ERR "%s: unknown keyword \"%s\"\n",
-                                       __func__, words[i]);
+                               pr_err("unknown keyword \"%s\"\n", words[i]);
                        return -EINVAL;
                }
        }
 
        if (verbose)
-               printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" "
-                      "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
-                       __func__, query->function, query->filename,
+               pr_info("q->function=\"%s\" q->filename=\"%s\" "
+                       "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
+                       query->function, query->filename,
                        query->module, query->format, query->first_lineno,
                        query->last_lineno);
 
@@ -368,7 +370,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
                return -EINVAL;
        }
        if (verbose)
-               printk(KERN_INFO "%s: op='%c'\n", __func__, op);
+               pr_info("op='%c'\n", op);
 
        for ( ; *str ; ++str) {
                for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
@@ -383,7 +385,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
        if (flags == 0)
                return -EINVAL;
        if (verbose)
-               printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags);
+               pr_info("flags=0x%x\n", flags);
 
        /* calculate final *flagsp, *maskp according to mask and op */
        switch (op) {
@@ -401,8 +403,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
                break;
        }
        if (verbose)
-               printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n",
-                       __func__, *flagsp, *maskp);
+               pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
        return 0;
 }
 
@@ -427,6 +428,39 @@ static int ddebug_exec_query(char *query_string)
        return 0;
 }
 
+static int dynamic_emit_prefix(const struct _ddebug *descriptor)
+{
+       char tid[sizeof(int) + sizeof(int)/2 + 4];
+       char lineno[sizeof(int) + sizeof(int)/2];
+
+       if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) {
+               if (in_interrupt())
+                       snprintf(tid, sizeof(tid), "%s", "<intr> ");
+               else
+                       snprintf(tid, sizeof(tid), "[%d] ",
+                                task_pid_vnr(current));
+       } else {
+               tid[0] = 0;
+       }
+
+       if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO)
+               snprintf(lineno, sizeof(lineno), "%d", descriptor->lineno);
+       else
+               lineno[0] = 0;
+
+       return printk(KERN_DEBUG "%s%s%s%s%s%s",
+                     tid,
+                     (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ?
+                     descriptor->modname : "",
+                     (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ?
+                     ":" : "",
+                     (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ?
+                     descriptor->function : "",
+                     (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ?
+                     ":" : "",
+                     lineno);
+}
+
 int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
 {
        va_list args;
@@ -436,31 +470,69 @@ int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
        BUG_ON(!fmt);
 
        va_start(args, fmt);
-       res = printk(KERN_DEBUG);
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) {
-               if (in_interrupt())
-                       res += printk(KERN_CONT "<intr> ");
-               else
-                       res += printk(KERN_CONT "[%d] ", task_pid_vnr(current));
-       }
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME)
-               res += printk(KERN_CONT "%s:", descriptor->modname);
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
-               res += printk(KERN_CONT "%s:", descriptor->function);
-       if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO)
-               res += printk(KERN_CONT "%d ", descriptor->lineno);
+
+       res = dynamic_emit_prefix(descriptor);
        res += vprintk(fmt, args);
+
        va_end(args);
 
        return res;
 }
 EXPORT_SYMBOL(__dynamic_pr_debug);
 
+int __dynamic_dev_dbg(struct _ddebug *descriptor,
+                     const struct device *dev, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+       int res;
+
+       BUG_ON(!descriptor);
+       BUG_ON(!fmt);
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       res = dynamic_emit_prefix(descriptor);
+       res += __dev_printk(KERN_CONT, dev, &vaf);
+
+       va_end(args);
+
+       return res;
+}
+EXPORT_SYMBOL(__dynamic_dev_dbg);
+
+int __dynamic_netdev_dbg(struct _ddebug *descriptor,
+                     const struct net_device *dev, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+       int res;
+
+       BUG_ON(!descriptor);
+       BUG_ON(!fmt);
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       res = dynamic_emit_prefix(descriptor);
+       res += __netdev_printk(KERN_CONT, dev, &vaf);
+
+       va_end(args);
+
+       return res;
+}
+EXPORT_SYMBOL(__dynamic_netdev_dbg);
+
 static __initdata char ddebug_setup_string[1024];
 static __init int ddebug_setup_query(char *str)
 {
        if (strlen(str) >= 1024) {
-               pr_warning("ddebug boot param string too large\n");
+               pr_warn("ddebug boot param string too large\n");
                return 0;
        }
        strcpy(ddebug_setup_string, str);
@@ -488,8 +560,7 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
                return -EFAULT;
        tmpbuf[len] = '\0';
        if (verbose)
-               printk(KERN_INFO "%s: read %d bytes from userspace\n",
-                       __func__, (int)len);
+               pr_info("read %d bytes from userspace\n", (int)len);
 
        ret = ddebug_exec_query(tmpbuf);
        if (ret)
@@ -552,8 +623,7 @@ static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
        int n = *pos;
 
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p *pos=%lld\n",
-                       __func__, m, (unsigned long long)*pos);
+               pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
 
        mutex_lock(&ddebug_lock);
 
@@ -578,8 +648,8 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
        struct _ddebug *dp;
 
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n",
-                       __func__, m, p, (unsigned long long)*pos);
+               pr_info("called m=%p p=%p *pos=%lld\n",
+                       m, p, (unsigned long long)*pos);
 
        if (p == SEQ_START_TOKEN)
                dp = ddebug_iter_first(iter);
@@ -602,8 +672,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
        char flagsbuf[8];
 
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p p=%p\n",
-                       __func__, m, p);
+               pr_info("called m=%p p=%p\n", m, p);
 
        if (p == SEQ_START_TOKEN) {
                seq_puts(m,
@@ -628,8 +697,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
 static void ddebug_proc_stop(struct seq_file *m, void *p)
 {
        if (verbose)
-               printk(KERN_INFO "%s: called m=%p p=%p\n",
-                       __func__, m, p);
+               pr_info("called m=%p p=%p\n", m, p);
        mutex_unlock(&ddebug_lock);
 }
 
@@ -652,7 +720,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file)
        int err;
 
        if (verbose)
-               printk(KERN_INFO "%s: called\n", __func__);
+               pr_info("called\n");
 
        iter = kzalloc(sizeof(*iter), GFP_KERNEL);
        if (iter == NULL)
@@ -704,8 +772,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
        mutex_unlock(&ddebug_lock);
 
        if (verbose)
-               printk(KERN_INFO "%u debug prints in module %s\n",
-                                n, dt->mod_name);
+               pr_info("%u debug prints in module %s\n", n, dt->mod_name);
        return 0;
 }
 EXPORT_SYMBOL_GPL(ddebug_add_module);
@@ -727,8 +794,7 @@ int ddebug_remove_module(const char *mod_name)
        int ret = -ENOENT;
 
        if (verbose)
-               printk(KERN_INFO "%s: removing module \"%s\"\n",
-                               __func__, mod_name);
+               pr_info("removing module \"%s\"\n", mod_name);
 
        mutex_lock(&ddebug_lock);
        list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
@@ -804,8 +870,8 @@ static int __init dynamic_debug_init(void)
        if (ddebug_setup_string[0] != '\0') {
                ret = ddebug_exec_query(ddebug_setup_string);
                if (ret)
-                       pr_warning("Invalid ddebug boot param %s",
-                                  ddebug_setup_string);
+                       pr_warn("Invalid ddebug boot param %s",
+                               ddebug_setup_string);
                else
                        pr_info("ddebug initialized with string %s",
                                ddebug_setup_string);
index f193b7796449a04870b401f96931ef71c18f808d..328d43357ed2bf147832d2261cb962f095ea430c 100644 (file)
@@ -130,6 +130,7 @@ bool should_fail(struct fault_attr *attr, ssize_t size)
 
        return true;
 }
+EXPORT_SYMBOL_GPL(should_fail);
 
 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
 
@@ -243,5 +244,6 @@ fail:
 
        return ERR_PTR(-ENOMEM);
 }
+EXPORT_SYMBOL_GPL(fault_create_debugfs_attr);
 
 #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
index db040ce3fa73a328a118a93097d6e5062c16409d..5acf9bb10968caa97ec123ca464906fff4de42bc 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -860,7 +860,7 @@ EXPORT_SYMBOL(ida_get_new_above);
  * and go back to the idr_pre_get() call.  If the idr is full, it will
  * return %-ENOSPC.
  *
- * @id returns a value in the range %0 ... %0x7fffffff.
+ * @p_id returns a value in the range %0 ... %0x7fffffff.
  */
 int ida_get_new(struct ida *ida, int *p_id)
 {
index 70af0a7f97c0eb4801e177458d182ab6baad2767..ad72a03ce5e96d6b5e84727bf092bdc2ef25641a 100644 (file)
@@ -282,7 +282,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
                                                            kobj_bcast_filter,
                                                            kobj);
                        /* ENOBUFS should be handled in userspace */
-                       if (retval == -ENOBUFS)
+                       if (retval == -ENOBUFS || retval == -ESRCH)
                                retval = 0;
                } else
                        retval = -ENOMEM;
index d6edf8d14f9cd7fb5b9f143a7f529498ee0e9dc1..d73a5aa0805796303083e5175123021ef11d7a76 100644 (file)
@@ -586,14 +586,10 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 
        /*
         * Finally, kill the kernel thread. We don't need to be RCU
-        * safe anymore, since the bdi is gone from visibility. Force
-        * unfreeze of the thread before calling kthread_stop(), otherwise
-        * it would never exet if it is currently stuck in the refrigerator.
+        * safe anymore, since the bdi is gone from visibility.
         */
-       if (bdi->wb.task) {
-               thaw_process(bdi->wb.task);
+       if (bdi->wb.task)
                kthread_stop(bdi->wb.task);
-       }
 }
 
 /*
index ea534960a04bcda7e87a18cacf67bd2eb1fc5fe0..29e3730d2ffd54e93741a356a6f45a442ea2fdc9 100644 (file)
@@ -50,14 +50,13 @@ static struct page **pcpu_get_pages_and_bitmap(struct pcpu_chunk *chunk,
 
        if (!pages || !bitmap) {
                if (may_alloc && !pages)
-                       pages = pcpu_mem_alloc(pages_size);
+                       pages = pcpu_mem_zalloc(pages_size);
                if (may_alloc && !bitmap)
-                       bitmap = pcpu_mem_alloc(bitmap_size);
+                       bitmap = pcpu_mem_zalloc(bitmap_size);
                if (!pages || !bitmap)
                        return NULL;
        }
 
-       memset(pages, 0, pages_size);
        bitmap_copy(bitmap, chunk->populated, pcpu_unit_pages);
 
        *bitmapp = bitmap;
index bf80e55dbed7e66fcd28f6dbc46c86fbd222a008..28c37a2e2de23acb140a02a3f08779b22b40b976 100644 (file)
@@ -273,11 +273,11 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk,
             (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end)))
 
 /**
- * pcpu_mem_alloc - allocate memory
+ * pcpu_mem_zalloc - allocate memory
  * @size: bytes to allocate
  *
  * Allocate @size bytes.  If @size is smaller than PAGE_SIZE,
- * kzalloc() is used; otherwise, vmalloc() is used.  The returned
+ * kzalloc() is used; otherwise, vzalloc() is used.  The returned
  * memory is always zeroed.
  *
  * CONTEXT:
@@ -286,7 +286,7 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk,
  * RETURNS:
  * Pointer to the allocated area on success, NULL on failure.
  */
-static void *pcpu_mem_alloc(size_t size)
+static void *pcpu_mem_zalloc(size_t size)
 {
        if (WARN_ON_ONCE(!slab_is_available()))
                return NULL;
@@ -302,7 +302,7 @@ static void *pcpu_mem_alloc(size_t size)
  * @ptr: memory to free
  * @size: size of the area
  *
- * Free @ptr.  @ptr should have been allocated using pcpu_mem_alloc().
+ * Free @ptr.  @ptr should have been allocated using pcpu_mem_zalloc().
  */
 static void pcpu_mem_free(void *ptr, size_t size)
 {
@@ -384,7 +384,7 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc)
        size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
        unsigned long flags;
 
-       new = pcpu_mem_alloc(new_size);
+       new = pcpu_mem_zalloc(new_size);
        if (!new)
                return -ENOMEM;
 
@@ -604,11 +604,12 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void)
 {
        struct pcpu_chunk *chunk;
 
-       chunk = pcpu_mem_alloc(pcpu_chunk_struct_size);
+       chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size);
        if (!chunk)
                return NULL;
 
-       chunk->map = pcpu_mem_alloc(PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0]));
+       chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC *
+                                               sizeof(chunk->map[0]));
        if (!chunk->map) {
                kfree(chunk);
                return NULL;
@@ -1889,7 +1890,7 @@ void __init percpu_init_late(void)
 
                BUILD_BUG_ON(size > PAGE_SIZE);
 
-               map = pcpu_mem_alloc(size);
+               map = pcpu_mem_zalloc(size);
                BUG_ON(!map);
 
                spin_lock_irqsave(&pcpu_lock, flags);
index 32f6763f16fb82ad7068c4d73479a96583f4ef15..2d357729529880b29f18704edda807108f6cdc5b 100644 (file)
@@ -1458,7 +1458,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
        inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
        if (inode) {
                error = security_inode_init_security(inode, dir,
-                                                    &dentry->d_name, NULL,
+                                                    &dentry->d_name,
                                                     NULL, NULL);
                if (error) {
                        if (error != -EOPNOTSUPP) {
@@ -1598,7 +1598,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
        if (!inode)
                return -ENOSPC;
 
-       error = security_inode_init_security(inode, dir, &dentry->d_name, NULL,
+       error = security_inode_init_security(inode, dir, &dentry->d_name,
                                             NULL, NULL);
        if (error) {
                if (error != -EOPNOTSUPP) {
index 16102951d36aa39cdda6953f36c78320cb0a965b..070bf4403bf8fdde83a99c60c4c7b20b50ed831d 100644 (file)
@@ -553,7 +553,7 @@ static void garp_release_port(struct net_device *dev)
                if (rtnl_dereference(port->applicants[i]))
                        return;
        }
-       rcu_assign_pointer(dev->garp_port, NULL);
+       RCU_INIT_POINTER(dev->garp_port, NULL);
        kfree_rcu(port, rcu);
 }
 
@@ -605,7 +605,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
 
        ASSERT_RTNL();
 
-       rcu_assign_pointer(port->applicants[appl->type], NULL);
+       RCU_INIT_POINTER(port->applicants[appl->type], NULL);
 
        /* Delete timer and generate a final TRANSMIT_PDU event to flush out
         * all pending messages before the applicant is gone. */
index 978c30b1b36b5a138eeeb7b9780009686f356d6e..0e136ef1e4bab47307d9fc382709b2c552281ecd 100644 (file)
@@ -88,9 +88,9 @@ void stp_proto_unregister(const struct stp_proto *proto)
 {
        mutex_lock(&stp_proto_mutex);
        if (is_zero_ether_addr(proto->group_address))
-               rcu_assign_pointer(stp_proto, NULL);
+               RCU_INIT_POINTER(stp_proto, NULL);
        else
-               rcu_assign_pointer(garp_protos[proto->group_address[5] -
+               RCU_INIT_POINTER(garp_protos[proto->group_address[5] -
                                               GARP_ADDR_MIN], NULL);
        synchronize_rcu();
 
index 8970ba139d73f84f81ea3577621d9959bec267b6..5471628d3ffe73fd0f8b3cc8d3504cfeae78019c 100644 (file)
@@ -133,7 +133,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
        if (grp->nr_vlans == 0) {
                vlan_gvrp_uninit_applicant(real_dev);
 
-               rcu_assign_pointer(real_dev->vlgrp, NULL);
+               RCU_INIT_POINTER(real_dev->vlgrp, NULL);
 
                /* Free the group, after all cpu's are done. */
                call_rcu(&grp->rcu, vlan_rcu_free);
index 5f27f8e302546371dec3b6ff24e62d389e4c41c2..f1f2f7bb6661e18c77276d20598e59caba8c34ed 100644 (file)
@@ -167,6 +167,8 @@ struct sk_buff *vlan_untag(struct sk_buff *skb)
        if (unlikely(!skb))
                goto err_free;
 
+       skb_reset_network_header(skb);
+       skb_reset_transport_header(skb);
        return skb;
 
 err_free:
index 9d40a071d0382e7e893483066fa3bb5285fa8bc0..eba705b92d6f562c2247f08594efc168c275386f 100644 (file)
@@ -674,7 +674,6 @@ static const struct net_device_ops vlan_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = vlan_dev_set_mac_address,
        .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
-       .ndo_set_multicast_list = vlan_dev_set_rx_mode,
        .ndo_change_rx_flags    = vlan_dev_change_rx_flags,
        .ndo_do_ioctl           = vlan_dev_ioctl,
        .ndo_neigh_setup        = vlan_dev_neigh_setup,
index 0505a03c374c1599cac7bffbf1ec6d0af311910e..3f8c0467154aa02857bff39503197125e67bb8a5 100644 (file)
@@ -203,11 +203,12 @@ free_and_return:
  *
  */
 
-static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
+static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag, int max_size)
 {
        unsigned long flags;
        int row, col;
        struct p9_req_t *req;
+       int alloc_msize = min(c->msize, max_size);
 
        /* This looks up the original request by tag so we know which
         * buffer to read the data into */
@@ -245,23 +246,12 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
                        return ERR_PTR(-ENOMEM);
                }
                init_waitqueue_head(req->wq);
-               if ((c->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) ==
-                               P9_TRANS_PREF_PAYLOAD_SEP) {
-                       int alloc_msize = min(c->msize, 4096);
-                       req->tc = kmalloc(sizeof(struct p9_fcall)+alloc_msize,
-                                         GFP_NOFS);
-                       req->tc->capacity = alloc_msize;
-                       req->rc = kmalloc(sizeof(struct p9_fcall)+alloc_msize,
-                                         GFP_NOFS);
-                       req->rc->capacity = alloc_msize;
-               } else {
-                       req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize,
-                                         GFP_NOFS);
-                       req->tc->capacity = c->msize;
-                       req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize,
-                                         GFP_NOFS);
-                       req->rc->capacity = c->msize;
-               }
+               req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
+                                 GFP_NOFS);
+               req->tc->capacity = alloc_msize;
+               req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
+                                 GFP_NOFS);
+               req->rc->capacity = alloc_msize;
                if ((!req->tc) || (!req->rc)) {
                        printk(KERN_ERR "Couldn't grow tag array\n");
                        kfree(req->tc);
@@ -485,27 +475,8 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
 
        if (!p9_is_proto_dotl(c)) {
                char *ename;
-
-               if (req->tc->pbuf_size) {
-                       /* Handle user buffers */
-                       size_t len = req->rc->size - req->rc->offset;
-                       if (req->tc->pubuf) {
-                               /* User Buffer */
-                               err = copy_from_user(
-                                       &req->rc->sdata[req->rc->offset],
-                                       req->tc->pubuf, len);
-                               if (err) {
-                                       err = -EFAULT;
-                                       goto out_err;
-                               }
-                       } else {
-                               /* Kernel Buffer */
-                               memmove(&req->rc->sdata[req->rc->offset],
-                                               req->tc->pkbuf, len);
-                       }
-               }
                err = p9pdu_readf(req->rc, c->proto_version, "s?d",
-                               &ename, &ecode);
+                                 &ename, &ecode);
                if (err)
                        goto out_err;
 
@@ -515,11 +486,10 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
                if (!err || !IS_ERR_VALUE(err)) {
                        err = p9_errstr2errno(ename, strlen(ename));
 
-                       P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode,
-                                       ename);
-
-                       kfree(ename);
+                       P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
+                                  -ecode, ename);
                }
+               kfree(ename);
        } else {
                err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
                err = -ecode;
@@ -527,7 +497,6 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
                P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
        }
 
-
        return err;
 
 out_err:
@@ -536,6 +505,110 @@ out_err:
        return err;
 }
 
+/**
+ * p9_check_zc_errors - check 9p packet for error return and process it
+ * @c: current client instance
+ * @req: request to parse and check for error conditions
+ * @in_hdrlen: Size of response protocol buffer.
+ *
+ * returns error code if one is discovered, otherwise returns 0
+ *
+ * this will have to be more complicated if we have multiple
+ * error packet types
+ */
+
+static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
+                             char *uidata, int in_hdrlen, int kern_buf)
+{
+       int err;
+       int ecode;
+       int8_t type;
+       char *ename = NULL;
+
+       err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
+       if (err) {
+               P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
+               return err;
+       }
+
+       if (type != P9_RERROR && type != P9_RLERROR)
+               return 0;
+
+       if (!p9_is_proto_dotl(c)) {
+               /* Error is reported in string format */
+               uint16_t len;
+               /* 7 = header size for RERROR, 2 is the size of string len; */
+               int inline_len = in_hdrlen - (7 + 2);
+
+               /* Read the size of error string */
+               err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
+               if (err)
+                       goto out_err;
+
+               ename = kmalloc(len + 1, GFP_NOFS);
+               if (!ename) {
+                       err = -ENOMEM;
+                       goto out_err;
+               }
+               if (len <= inline_len) {
+                       /* We have error in protocol buffer itself */
+                       if (pdu_read(req->rc, ename, len)) {
+                               err = -EFAULT;
+                               goto out_free;
+
+                       }
+               } else {
+                       /*
+                        *  Part of the data is in user space buffer.
+                        */
+                       if (pdu_read(req->rc, ename, inline_len)) {
+                               err = -EFAULT;
+                               goto out_free;
+
+                       }
+                       if (kern_buf) {
+                               memcpy(ename + inline_len, uidata,
+                                      len - inline_len);
+                       } else {
+                               err = copy_from_user(ename + inline_len,
+                                                    uidata, len - inline_len);
+                               if (err) {
+                                       err = -EFAULT;
+                                       goto out_free;
+                               }
+                       }
+               }
+               ename[len] = 0;
+               if (p9_is_proto_dotu(c)) {
+                       /* For dotu we also have error code */
+                       err = p9pdu_readf(req->rc,
+                                         c->proto_version, "d", &ecode);
+                       if (err)
+                               goto out_free;
+                       err = -ecode;
+               }
+               if (!err || !IS_ERR_VALUE(err)) {
+                       err = p9_errstr2errno(ename, strlen(ename));
+
+                       P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
+                                  -ecode, ename);
+               }
+               kfree(ename);
+       } else {
+               err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
+               err = -ecode;
+
+               P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
+       }
+       return err;
+
+out_free:
+       kfree(ename);
+out_err:
+       P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
+       return err;
+}
+
 static struct p9_req_t *
 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
 
@@ -579,23 +652,12 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
        return 0;
 }
 
-/**
- * p9_client_rpc - issue a request and wait for a response
- * @c: client session
- * @type: type of request
- * @fmt: protocol format string (see protocol.c)
- *
- * Returns request structure (which client must free using p9_free_req)
- */
-
-static struct p9_req_t *
-p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
+                                             int8_t type, int req_size,
+                                             const char *fmt, va_list ap)
 {
-       va_list ap;
        int tag, err;
        struct p9_req_t *req;
-       unsigned long flags;
-       int sigpending;
 
        P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
 
@@ -607,12 +669,6 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
        if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
                return ERR_PTR(-EIO);
 
-       if (signal_pending(current)) {
-               sigpending = 1;
-               clear_thread_flag(TIF_SIGPENDING);
-       } else
-               sigpending = 0;
-
        tag = P9_NOTAG;
        if (type != P9_TVERSION) {
                tag = p9_idpool_get(c->tagpool);
@@ -620,18 +676,50 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
                        return ERR_PTR(-ENOMEM);
        }
 
-       req = p9_tag_alloc(c, tag);
+       req = p9_tag_alloc(c, tag, req_size);
        if (IS_ERR(req))
                return req;
 
        /* marshall the data */
        p9pdu_prepare(req->tc, tag, type);
-       va_start(ap, fmt);
        err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
-       va_end(ap);
        if (err)
                goto reterr;
        p9pdu_finalize(req->tc);
+       return req;
+reterr:
+       p9_free_req(c, req);
+       return ERR_PTR(err);
+}
+
+/**
+ * p9_client_rpc - issue a request and wait for a response
+ * @c: client session
+ * @type: type of request
+ * @fmt: protocol format string (see protocol.c)
+ *
+ * Returns request structure (which client must free using p9_free_req)
+ */
+
+static struct p9_req_t *
+p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+{
+       va_list ap;
+       int sigpending, err;
+       unsigned long flags;
+       struct p9_req_t *req;
+
+       va_start(ap, fmt);
+       req = p9_client_prepare_req(c, type, c->msize, fmt, ap);
+       va_end(ap);
+       if (IS_ERR(req))
+               return req;
+
+       if (signal_pending(current)) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+       } else
+               sigpending = 0;
 
        err = c->trans_mod->request(c, req);
        if (err < 0) {
@@ -639,18 +727,14 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
                        c->status = Disconnected;
                goto reterr;
        }
-
-       P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag);
+       /* Wait for the response */
        err = wait_event_interruptible(*req->wq,
-                                               req->status >= REQ_STATUS_RCVD);
-       P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d\n",
-                                               req->wq, tag, err);
+                                      req->status >= REQ_STATUS_RCVD);
 
        if (req->status == REQ_STATUS_ERROR) {
                P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
                err = req->t_err;
        }
-
        if ((err == -ERESTARTSYS) && (c->status == Connected)) {
                P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
                sigpending = 1;
@@ -663,13 +747,11 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
                if (req->status == REQ_STATUS_RCVD)
                        err = 0;
        }
-
        if (sigpending) {
                spin_lock_irqsave(&current->sighand->siglock, flags);
                recalc_sigpending();
                spin_unlock_irqrestore(&current->sighand->siglock, flags);
        }
-
        if (err < 0)
                goto reterr;
 
@@ -678,7 +760,92 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
                P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
                return req;
        }
+reterr:
+       P9_DPRINTK(P9_DEBUG_MUX,
+                  "exit: client %p op %d error: %d\n", c, type, err);
+       p9_free_req(c, req);
+       return ERR_PTR(err);
+}
+
+/**
+ * p9_client_zc_rpc - issue a request and wait for a response
+ * @c: client session
+ * @type: type of request
+ * @uidata: user bffer that should be ued for zero copy read
+ * @uodata: user buffer that shoud be user for zero copy write
+ * @inlen: read buffer size
+ * @olen: write buffer size
+ * @hdrlen: reader header size, This is the size of response protocol data
+ * @fmt: protocol format string (see protocol.c)
+ *
+ * Returns request structure (which client must free using p9_free_req)
+ */
+static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+                                        char *uidata, char *uodata,
+                                        int inlen, int olen, int in_hdrlen,
+                                        int kern_buf, const char *fmt, ...)
+{
+       va_list ap;
+       int sigpending, err;
+       unsigned long flags;
+       struct p9_req_t *req;
+
+       va_start(ap, fmt);
+       /*
+        * We allocate a inline protocol data of only 4k bytes.
+        * The actual content is passed in zero-copy fashion.
+        */
+       req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
+       va_end(ap);
+       if (IS_ERR(req))
+               return req;
+
+       if (signal_pending(current)) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+       } else
+               sigpending = 0;
+
+       /* If we are called with KERNEL_DS force kern_buf */
+       if (segment_eq(get_fs(), KERNEL_DS))
+               kern_buf = 1;
+
+       err = c->trans_mod->zc_request(c, req, uidata, uodata,
+                                      inlen, olen, in_hdrlen, kern_buf);
+       if (err < 0) {
+               if (err == -EIO)
+                       c->status = Disconnected;
+               goto reterr;
+       }
+       if (req->status == REQ_STATUS_ERROR) {
+               P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+               err = req->t_err;
+       }
+       if ((err == -ERESTARTSYS) && (c->status == Connected)) {
+               P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
 
+               if (c->trans_mod->cancel(c, req))
+                       p9_client_flush(c, req);
+
+               /* if we received the response anyway, don't signal error */
+               if (req->status == REQ_STATUS_RCVD)
+                       err = 0;
+       }
+       if (sigpending) {
+               spin_lock_irqsave(&current->sighand->siglock, flags);
+               recalc_sigpending();
+               spin_unlock_irqrestore(&current->sighand->siglock, flags);
+       }
+       if (err < 0)
+               goto reterr;
+
+       err = p9_check_zc_errors(c, req, uidata, in_hdrlen, kern_buf);
+       if (!err) {
+               P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
+               return req;
+       }
 reterr:
        P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
                                                                        err);
@@ -1330,13 +1497,15 @@ int
 p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
                                                                u32 count)
 {
-       int err, rsize;
-       struct p9_client *clnt;
-       struct p9_req_t *req;
        char *dataptr;
+       int kernel_buf = 0;
+       struct p9_req_t *req;
+       struct p9_client *clnt;
+       int err, rsize, non_zc = 0;
+
 
-       P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid,
-                                       (long long unsigned) offset, count);
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
+                  fid->fid, (long long unsigned) offset, count);
        err = 0;
        clnt = fid->clnt;
 
@@ -1347,14 +1516,25 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
        if (count < rsize)
                rsize = count;
 
-       /* Don't bother zerocopy for small IO (< 1024) */
-       if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) ==
-                       P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) {
-               req = p9_client_rpc(clnt, P9_TREAD, "dqE", fid->fid, offset,
-                               rsize, data, udata);
+       /* Don't bother zerocopy form small IO (< 1024) */
+       if (clnt->trans_mod->zc_request && rsize > 1024) {
+               char *indata;
+               if (data) {
+                       kernel_buf = 1;
+                       indata = data;
+               } else
+                       indata = (char *)udata;
+               /*
+                * response header len is 11
+                * PDU Header(7) + IO Size (4)
+                */
+               req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0,
+                                      11, kernel_buf, "dqd", fid->fid,
+                                      offset, rsize);
        } else {
+               non_zc = 1;
                req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
-                               rsize);
+                                   rsize);
        }
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
@@ -1370,7 +1550,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
        P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
        P9_DUMP_PKT(1, req->rc);
 
-       if (!req->tc->pbuf_size) {
+       if (non_zc) {
                if (data) {
                        memmove(data, dataptr, count);
                } else {
@@ -1396,6 +1576,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
                                                        u64 offset, u32 count)
 {
        int err, rsize;
+       int kernel_buf = 0;
        struct p9_client *clnt;
        struct p9_req_t *req;
 
@@ -1412,18 +1593,23 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
                rsize = count;
 
        /* Don't bother zerocopy form small IO (< 1024) */
-       if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) ==
-                               P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) {
-               req = p9_client_rpc(clnt, P9_TWRITE, "dqE", fid->fid, offset,
-                               rsize, data, udata);
+       if (clnt->trans_mod->zc_request && rsize > 1024) {
+               char *odata;
+               if (data) {
+                       kernel_buf = 1;
+                       odata = data;
+               } else
+                       odata = (char *)udata;
+               req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, odata, 0, rsize,
+                                      P9_ZC_HDR_SZ, kernel_buf, "dqd",
+                                      fid->fid, offset, rsize);
        } else {
-
                if (data)
                        req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid,
-                                       offset, rsize, data);
+                                           offset, rsize, data);
                else
                        req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid,
-                                       offset, rsize, udata);
+                                           offset, rsize, udata);
        }
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
@@ -1824,7 +2010,7 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
 
 int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
 {
-       int err, rsize;
+       int err, rsize, non_zc = 0;
        struct p9_client *clnt;
        struct p9_req_t *req;
        char *dataptr;
@@ -1842,13 +2028,18 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
        if (count < rsize)
                rsize = count;
 
-       if ((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) ==
-                       P9_TRANS_PREF_PAYLOAD_SEP) {
-               req = p9_client_rpc(clnt, P9_TREADDIR, "dqF", fid->fid,
-                               offset, rsize, data);
+       /* Don't bother zerocopy form small IO (< 1024) */
+       if (clnt->trans_mod->zc_request && rsize > 1024) {
+               /*
+                * response header len is 11
+                * PDU Header(7) + IO Size (4)
+                */
+               req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0,
+                                      11, 1, "dqd", fid->fid, offset, rsize);
        } else {
+               non_zc = 1;
                req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
-                               offset, rsize);
+                                   offset, rsize);
        }
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
@@ -1863,7 +2054,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
 
        P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
 
-       if (!req->tc->pbuf_size && data)
+       if (non_zc)
                memmove(data, dataptr, count);
 
        p9_free_req(clnt, req);
index df58375ea6b33890030c649938403cf73c2f30f6..b7d4e8aa5383e7e2022cdcdd92205d0b634fe06e 100644 (file)
@@ -81,7 +81,7 @@ void p9stat_free(struct p9_wstat *stbuf)
 }
 EXPORT_SYMBOL(p9stat_free);
 
-static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
+size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
 {
        size_t len = min(pdu->size - pdu->offset, size);
        memcpy(data, &pdu->sdata[pdu->offset], len);
@@ -108,26 +108,6 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
        return size - len;
 }
 
-static size_t
-pdu_write_urw(struct p9_fcall *pdu, const char *kdata, const char __user *udata,
-               size_t size)
-{
-       BUG_ON(pdu->size > P9_IOHDRSZ);
-       pdu->pubuf = (char __user *)udata;
-       pdu->pkbuf = (char *)kdata;
-       pdu->pbuf_size = size;
-       return 0;
-}
-
-static size_t
-pdu_write_readdir(struct p9_fcall *pdu, const char *kdata, size_t size)
-{
-       BUG_ON(pdu->size > P9_READDIRHDRSZ);
-       pdu->pkbuf = (char *)kdata;
-       pdu->pbuf_size = size;
-       return 0;
-}
-
 /*
        b - int8_t
        w - int16_t
@@ -459,26 +439,6 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
                                        errcode = -EFAULT;
                        }
                        break;
-               case 'E':{
-                                int32_t cnt = va_arg(ap, int32_t);
-                                const char *k = va_arg(ap, const void *);
-                                const char __user *u = va_arg(ap,
-                                                       const void __user *);
-                                errcode = p9pdu_writef(pdu, proto_version, "d",
-                                                cnt);
-                                if (!errcode && pdu_write_urw(pdu, k, u, cnt))
-                                       errcode = -EFAULT;
-                        }
-                        break;
-               case 'F':{
-                                int32_t cnt = va_arg(ap, int32_t);
-                                const char *k = va_arg(ap, const void *);
-                                errcode = p9pdu_writef(pdu, proto_version, "d",
-                                                cnt);
-                                if (!errcode && pdu_write_readdir(pdu, k, cnt))
-                                       errcode = -EFAULT;
-                        }
-                        break;
                case 'U':{
                                int32_t count = va_arg(ap, int32_t);
                                const char __user *udata =
@@ -637,10 +597,6 @@ void p9pdu_reset(struct p9_fcall *pdu)
 {
        pdu->offset = 0;
        pdu->size = 0;
-       pdu->private = NULL;
-       pdu->pubuf = NULL;
-       pdu->pkbuf = NULL;
-       pdu->pbuf_size = 0;
 }
 
 int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,
index 2431c0f38d56784c02f42e077fcaa990e523882c..a0eb8ff11f22a1c53b91968f1112e28f16edbaff 100644 (file)
@@ -32,3 +32,4 @@ int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
 int p9pdu_finalize(struct p9_fcall *pdu);
 void p9pdu_dump(int, struct p9_fcall *);
 void p9pdu_reset(struct p9_fcall *pdu);
+size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size);
index 9a70ebdec56e11357ba1f78c0938385881c7d4b3..de8df957867def380831cc9a3589386f82a78aae 100644 (file)
 
 /**
  *  p9_release_req_pages - Release pages after the transaction.
- *  @*private: PDU's private page of struct trans_rpage_info
  */
-void
-p9_release_req_pages(struct trans_rpage_info *rpinfo)
+void p9_release_pages(struct page **pages, int nr_pages)
 {
        int i = 0;
-
-       while (rpinfo->rp_data[i] && rpinfo->rp_nr_pages--) {
-               put_page(rpinfo->rp_data[i]);
+       while (pages[i] && nr_pages--) {
+               put_page(pages[i]);
                i++;
        }
 }
-EXPORT_SYMBOL(p9_release_req_pages);
+EXPORT_SYMBOL(p9_release_pages);
 
 /**
  * p9_nr_pages - Return number of pages needed to accommodate the payload.
  */
-int
-p9_nr_pages(struct p9_req_t *req)
+int p9_nr_pages(char *data, int len)
 {
        unsigned long start_page, end_page;
-       start_page =  (unsigned long)req->tc->pubuf >> PAGE_SHIFT;
-       end_page = ((unsigned long)req->tc->pubuf + req->tc->pbuf_size +
-                       PAGE_SIZE - 1) >> PAGE_SHIFT;
+       start_page =  (unsigned long)data >> PAGE_SHIFT;
+       end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
        return end_page - start_page;
 }
 EXPORT_SYMBOL(p9_nr_pages);
@@ -58,35 +53,17 @@ EXPORT_SYMBOL(p9_nr_pages);
  * @nr_pages: number of pages to accommodate the payload
  * @rw: Indicates if the pages are for read or write.
  */
-int
-p9_payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len,
-               int nr_pages, u8 rw)
-{
-       uint32_t first_page_bytes = 0;
-       int32_t pdata_mapped_pages;
-       struct trans_rpage_info  *rpinfo;
-
-       *pdata_off = (__force size_t)req->tc->pubuf & (PAGE_SIZE-1);
 
-       if (*pdata_off)
-               first_page_bytes = min(((size_t)PAGE_SIZE - *pdata_off),
-                                      req->tc->pbuf_size);
+int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
+{
+       int nr_mapped_pages;
 
-       rpinfo = req->tc->private;
-       pdata_mapped_pages = get_user_pages_fast((unsigned long)req->tc->pubuf,
-                       nr_pages, rw, &rpinfo->rp_data[0]);
-       if (pdata_mapped_pages <= 0)
-               return pdata_mapped_pages;
+       nr_mapped_pages = get_user_pages_fast((unsigned long)data,
+                                             *nr_pages, write, pages);
+       if (nr_mapped_pages <= 0)
+               return nr_mapped_pages;
 
-       rpinfo->rp_nr_pages = pdata_mapped_pages;
-       if (*pdata_off) {
-               *pdata_len = first_page_bytes;
-               *pdata_len += min((req->tc->pbuf_size - *pdata_len),
-                               ((size_t)pdata_mapped_pages - 1) << PAGE_SHIFT);
-       } else {
-               *pdata_len = min(req->tc->pbuf_size,
-                               (size_t)pdata_mapped_pages << PAGE_SHIFT);
-       }
+       *nr_pages = nr_mapped_pages;
        return 0;
 }
 EXPORT_SYMBOL(p9_payload_gup);
index 76309223bb024d7725b2ade9e70bee7fa37f1ce4..173bb550a9eb163df30c3b46b8770d0a37c84aa3 100644 (file)
  *
  */
 
-/* TRUE if it is user context */
-#define P9_IS_USER_CONTEXT (!segment_eq(get_fs(), KERNEL_DS))
-
-/**
- * struct trans_rpage_info - To store mapped page information in PDU.
- * @rp_alloc:Set if this structure is allocd, not a reuse unused space in pdu.
- * @rp_nr_pages: Number of mapped pages
- * @rp_data: Array of page pointers
- */
-struct trans_rpage_info {
-       u8 rp_alloc;
-       int rp_nr_pages;
-       struct page *rp_data[0];
-};
-
-void p9_release_req_pages(struct trans_rpage_info *);
-int p9_payload_gup(struct p9_req_t *, size_t *, int *, int, u8);
-int p9_nr_pages(struct p9_req_t *);
+void p9_release_pages(struct page **, int);
+int p9_payload_gup(char *, int *, struct page **, int);
+int p9_nr_pages(char *, int);
index 175b5135bdcf524d324c73298cd17da0819c9a1e..952db3f173fd4a37a9dee73b2032a0192a99a3b7 100644 (file)
@@ -163,17 +163,6 @@ static void req_done(struct virtqueue *vq)
                P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc);
                P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
                req = p9_tag_lookup(chan->client, rc->tag);
-               if (req->tc->private) {
-                       struct trans_rpage_info *rp = req->tc->private;
-                       int p = rp->rp_nr_pages;
-                       /*Release pages */
-                       p9_release_req_pages(rp);
-                       atomic_sub(p, &vp_pinned);
-                       wake_up(&vp_wq);
-                       if (rp->rp_alloc)
-                               kfree(rp);
-                       req->tc->private = NULL;
-               }
                req->status = REQ_STATUS_RCVD;
                p9_client_cb(chan->client, req);
        }
@@ -193,9 +182,8 @@ static void req_done(struct virtqueue *vq)
  *
  */
 
-static int
-pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
-                                                               int count)
+static int pack_sg_list(struct scatterlist *sg, int start,
+                       int limit, char *data, int count)
 {
        int s;
        int index = start;
@@ -224,31 +212,36 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
  * this takes a list of pages.
  * @sg: scatter/gather list to pack into
  * @start: which segment of the sg_list to start at
- * @pdata_off: Offset into the first page
  * @**pdata: a list of pages to add into sg.
+ * @nr_pages: number of pages to pack into the scatter/gather list
+ * @data: data to pack into scatter/gather list
  * @count: amount of data to pack into the scatter/gather list
  */
 static int
-pack_sg_list_p(struct scatterlist *sg, int start, int limit, size_t pdata_off,
-               struct page **pdata, int count)
+pack_sg_list_p(struct scatterlist *sg, int start, int limit,
+              struct page **pdata, int nr_pages, char *data, int count)
 {
-       int s;
-       int i = 0;
+       int i = 0, s;
+       int data_off;
        int index = start;
 
-       if (pdata_off) {
-               s = min((int)(PAGE_SIZE - pdata_off), count);
-               sg_set_page(&sg[index++], pdata[i++], s, pdata_off);
-               count -= s;
-       }
-
-       while (count) {
-               BUG_ON(index > limit);
-               s = min((int)PAGE_SIZE, count);
-               sg_set_page(&sg[index++], pdata[i++], s, 0);
+       BUG_ON(nr_pages > (limit - start));
+       /*
+        * if the first page doesn't start at
+        * page boundary find the offset
+        */
+       data_off = offset_in_page(data);
+       while (nr_pages) {
+               s = rest_of_page(data);
+               if (s > count)
+                       s = count;
+               sg_set_page(&sg[index++], pdata[i++], s, data_off);
+               data_off = 0;
+               data += s;
                count -= s;
+               nr_pages--;
        }
-       return index-start;
+       return index - start;
 }
 
 /**
@@ -261,114 +254,166 @@ pack_sg_list_p(struct scatterlist *sg, int start, int limit, size_t pdata_off,
 static int
 p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
 {
-       int in, out, inp, outp;
-       struct virtio_chan *chan = client->trans;
-       char *rdata = (char *)req->rc+sizeof(struct p9_fcall);
+       int err;
+       int in, out;
        unsigned long flags;
-       size_t pdata_off = 0;
-       struct trans_rpage_info *rpinfo = NULL;
-       int err, pdata_len = 0;
+       struct virtio_chan *chan = client->trans;
 
        P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
 
        req->status = REQ_STATUS_SENT;
+req_retry:
+       spin_lock_irqsave(&chan->lock, flags);
 
-       if (req->tc->pbuf_size && (req->tc->pubuf && P9_IS_USER_CONTEXT)) {
-               int nr_pages = p9_nr_pages(req);
-               int rpinfo_size = sizeof(struct trans_rpage_info) +
-                       sizeof(struct page *) * nr_pages;
+       /* Handle out VirtIO ring buffers */
+       out = pack_sg_list(chan->sg, 0,
+                          VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
 
-               if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
-                       err = wait_event_interruptible(vp_wq,
-                               atomic_read(&vp_pinned) < chan->p9_max_pages);
+       in = pack_sg_list(chan->sg, out,
+                         VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
+
+       err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
+       if (err < 0) {
+               if (err == -ENOSPC) {
+                       chan->ring_bufs_avail = 0;
+                       spin_unlock_irqrestore(&chan->lock, flags);
+                       err = wait_event_interruptible(*chan->vc_wq,
+                                                       chan->ring_bufs_avail);
                        if (err  == -ERESTARTSYS)
                                return err;
-                       P9_DPRINTK(P9_DEBUG_TRANS, "9p: May gup pages now.\n");
-               }
 
-               if (rpinfo_size <= (req->tc->capacity - req->tc->size)) {
-                       /* We can use sdata */
-                       req->tc->private = req->tc->sdata + req->tc->size;
-                       rpinfo = (struct trans_rpage_info *)req->tc->private;
-                       rpinfo->rp_alloc = 0;
+                       P9_DPRINTK(P9_DEBUG_TRANS, "9p:Retry virtio request\n");
+                       goto req_retry;
                } else {
-                       req->tc->private = kmalloc(rpinfo_size, GFP_NOFS);
-                       if (!req->tc->private) {
-                               P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: "
-                                       "private kmalloc returned NULL");
-                               return -ENOMEM;
-                       }
-                       rpinfo = (struct trans_rpage_info *)req->tc->private;
-                       rpinfo->rp_alloc = 1;
+                       spin_unlock_irqrestore(&chan->lock, flags);
+                       P9_DPRINTK(P9_DEBUG_TRANS,
+                                       "9p debug: "
+                                       "virtio rpc add_buf returned failure");
+                       return -EIO;
                }
+       }
+       virtqueue_kick(chan->vq);
+       spin_unlock_irqrestore(&chan->lock, flags);
+
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
+       return 0;
+}
 
-               err = p9_payload_gup(req, &pdata_off, &pdata_len, nr_pages,
-                               req->tc->id == P9_TREAD ? 1 : 0);
-               if (err < 0) {
-                       if (rpinfo->rp_alloc)
-                               kfree(rpinfo);
+static int p9_get_mapped_pages(struct virtio_chan *chan,
+                              struct page **pages, char *data,
+                              int nr_pages, int write, int kern_buf)
+{
+       int err;
+       if (!kern_buf) {
+               /*
+                * We allow only p9_max_pages pinned. We wait for the
+                * Other zc request to finish here
+                */
+               if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
+                       err = wait_event_interruptible(vp_wq,
+                             (atomic_read(&vp_pinned) < chan->p9_max_pages));
+                       if (err == -ERESTARTSYS)
+                               return err;
+               }
+               err = p9_payload_gup(data, &nr_pages, pages, write);
+               if (err < 0)
                        return err;
-               } else {
-                       atomic_add(rpinfo->rp_nr_pages, &vp_pinned);
+               atomic_add(nr_pages, &vp_pinned);
+       } else {
+               /* kernel buffer, no need to pin pages */
+               int s, index = 0;
+               int count = nr_pages;
+               while (nr_pages) {
+                       s = rest_of_page(data);
+                       pages[index++] = virt_to_page(data);
+                       data += s;
+                       nr_pages--;
                }
+               nr_pages = count;
        }
+       return nr_pages;
+}
 
-req_retry_pinned:
-       spin_lock_irqsave(&chan->lock, flags);
+/**
+ * p9_virtio_zc_request - issue a zero copy request
+ * @client: client instance issuing the request
+ * @req: request to be issued
+ * @uidata: user bffer that should be ued for zero copy read
+ * @uodata: user buffer that shoud be user for zero copy write
+ * @inlen: read buffer size
+ * @olen: write buffer size
+ * @hdrlen: reader header size, This is the size of response protocol data
+ *
+ */
+static int
+p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
+                    char *uidata, char *uodata, int inlen,
+                    int outlen, int in_hdr_len, int kern_buf)
+{
+       int in, out, err;
+       unsigned long flags;
+       int in_nr_pages = 0, out_nr_pages = 0;
+       struct page **in_pages = NULL, **out_pages = NULL;
+       struct virtio_chan *chan = client->trans;
 
-       /* Handle out VirtIO ring buffers */
-       out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata,
-                       req->tc->size);
-
-       if (req->tc->pbuf_size && (req->tc->id == P9_TWRITE)) {
-               /* We have additional write payload buffer to take care */
-               if (req->tc->pubuf && P9_IS_USER_CONTEXT) {
-                       outp = pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
-                                       pdata_off, rpinfo->rp_data, pdata_len);
-               } else {
-                       char *pbuf;
-                       if (req->tc->pubuf)
-                               pbuf = (__force char *) req->tc->pubuf;
-                       else
-                               pbuf = req->tc->pkbuf;
-                       outp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, pbuf,
-                                       req->tc->pbuf_size);
+       P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
+
+       if (uodata) {
+               out_nr_pages = p9_nr_pages(uodata, outlen);
+               out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
+                                   GFP_NOFS);
+               if (!out_pages) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
+               out_nr_pages = p9_get_mapped_pages(chan, out_pages, uodata,
+                                                  out_nr_pages, 0, kern_buf);
+               if (out_nr_pages < 0) {
+                       err = out_nr_pages;
+                       kfree(out_pages);
+                       out_pages = NULL;
+                       goto err_out;
                }
-               out += outp;
        }
-
-       /* Handle in VirtIO ring buffers */
-       if (req->tc->pbuf_size &&
-               ((req->tc->id == P9_TREAD) || (req->tc->id == P9_TREADDIR))) {
-               /*
-                * Take care of additional Read payload.
-                * 11 is the read/write header = PDU Header(7) + IO Size (4).
-                * Arrange in such a way that server places header in the
-                * alloced memory and payload onto the user buffer.
-                */
-               inp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, 11);
-               /*
-                * Running executables in the filesystem may result in
-                * a read request with kernel buffer as opposed to user buffer.
-                */
-               if (req->tc->pubuf && P9_IS_USER_CONTEXT) {
-                       in = pack_sg_list_p(chan->sg, out+inp, VIRTQUEUE_NUM,
-                                       pdata_off, rpinfo->rp_data, pdata_len);
-               } else {
-                       char *pbuf;
-                       if (req->tc->pubuf)
-                               pbuf = (__force char *) req->tc->pubuf;
-                       else
-                               pbuf = req->tc->pkbuf;
-
-                       in = pack_sg_list(chan->sg, out+inp, VIRTQUEUE_NUM,
-                                       pbuf, req->tc->pbuf_size);
+       if (uidata) {
+               in_nr_pages = p9_nr_pages(uidata, inlen);
+               in_pages = kmalloc(sizeof(struct page *) * in_nr_pages,
+                                  GFP_NOFS);
+               if (!in_pages) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
+               in_nr_pages = p9_get_mapped_pages(chan, in_pages, uidata,
+                                                 in_nr_pages, 1, kern_buf);
+               if (in_nr_pages < 0) {
+                       err = in_nr_pages;
+                       kfree(in_pages);
+                       in_pages = NULL;
+                       goto err_out;
                }
-               in += inp;
-       } else {
-               in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata,
-                               req->rc->capacity);
        }
+       req->status = REQ_STATUS_SENT;
+req_retry_pinned:
+       spin_lock_irqsave(&chan->lock, flags);
+       /* out data */
+       out = pack_sg_list(chan->sg, 0,
+                          VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
+
+       if (out_pages)
+               out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
+                                     out_pages, out_nr_pages, uodata, outlen);
+       /*
+        * Take care of in data
+        * For example TREAD have 11.
+        * 11 is the read/write header = PDU Header(7) + IO Size (4).
+        * Arrange in such a way that server places header in the
+        * alloced memory and payload onto the user buffer.
+        */
+       in = pack_sg_list(chan->sg, out,
+                         VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
+       if (in_pages)
+               in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
+                                    in_pages, in_nr_pages, uidata, inlen);
 
        err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
        if (err < 0) {
@@ -376,28 +421,45 @@ req_retry_pinned:
                        chan->ring_bufs_avail = 0;
                        spin_unlock_irqrestore(&chan->lock, flags);
                        err = wait_event_interruptible(*chan->vc_wq,
-                                                       chan->ring_bufs_avail);
+                                                      chan->ring_bufs_avail);
                        if (err  == -ERESTARTSYS)
-                               return err;
+                               goto err_out;
 
                        P9_DPRINTK(P9_DEBUG_TRANS, "9p:Retry virtio request\n");
                        goto req_retry_pinned;
                } else {
                        spin_unlock_irqrestore(&chan->lock, flags);
                        P9_DPRINTK(P9_DEBUG_TRANS,
-                                       "9p debug: "
-                                       "virtio rpc add_buf returned failure");
-                       if (rpinfo && rpinfo->rp_alloc)
-                               kfree(rpinfo);
-                       return -EIO;
+                                  "9p debug: "
+                                  "virtio rpc add_buf returned failure");
+                       err = -EIO;
+                       goto err_out;
                }
        }
-
        virtqueue_kick(chan->vq);
        spin_unlock_irqrestore(&chan->lock, flags);
-
        P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
-       return 0;
+       err = wait_event_interruptible(*req->wq,
+                                      req->status >= REQ_STATUS_RCVD);
+       /*
+        * Non kernel buffers are pinned, unpin them
+        */
+err_out:
+       if (!kern_buf) {
+               if (in_pages) {
+                       p9_release_pages(in_pages, in_nr_pages);
+                       atomic_sub(in_nr_pages, &vp_pinned);
+               }
+               if (out_pages) {
+                       p9_release_pages(out_pages, out_nr_pages);
+                       atomic_sub(out_nr_pages, &vp_pinned);
+               }
+               /* wakeup anybody waiting for slots to pin pages */
+               wake_up(&vp_wq);
+       }
+       kfree(in_pages);
+       kfree(out_pages);
+       return err;
 }
 
 static ssize_t p9_mount_tag_show(struct device *dev,
@@ -591,9 +653,15 @@ static struct p9_trans_module p9_virtio_trans = {
        .create = p9_virtio_create,
        .close = p9_virtio_close,
        .request = p9_virtio_request,
+       .zc_request = p9_virtio_zc_request,
        .cancel = p9_virtio_cancel,
-       .maxsize = PAGE_SIZE*VIRTQUEUE_NUM,
-       .pref = P9_TRANS_PREF_PAYLOAD_SEP,
+       /*
+        * We leave one entry for input and one entry for response
+        * headers. We also skip one more entry to accomodate, address
+        * that are not at page boundary, that can result in an extra
+        * page in zero copy.
+        */
+       .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
        .def = 0,
        .owner = THIS_MODULE,
 };
index 52cfd0c3ea71f19ef844531d055b4f96a0eb6e27..d07223c834af2a6b2bc45606d64d0093f30d9897 100644 (file)
@@ -558,12 +558,13 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
        spin_unlock_irqrestore(&rq->lock, flags);
 
        skb_queue_walk_safe(&queue, skb, tmp) {
-               struct net_device *dev = skb->dev;
+               struct net_device *dev;
+
+               br2684_push(atmvcc, skb);
+               dev = skb->dev;
 
                dev->stats.rx_bytes -= skb->len;
                dev->stats.rx_packets--;
-
-               br2684_push(atmvcc, skb);
        }
 
        /* initialize netdev carrier state */
index 215c9fad7cdf48161628a0db9486590f40b74f50..f1964caa0f83862b792107f024efee3ed0b54745 100644 (file)
@@ -643,7 +643,7 @@ static const struct net_device_ops lec_netdev_ops = {
        .ndo_start_xmit         = lec_start_xmit,
        .ndo_change_mtu         = lec_change_mtu,
        .ndo_tx_timeout         = lec_tx_timeout,
-       .ndo_set_multicast_list = lec_set_multicast_list,
+       .ndo_set_rx_mode        = lec_set_multicast_list,
 };
 
 static const unsigned char lec_ctrl_magic[] = {
index 8add9b4999129bcbdf62122221bd4bfec0c686ac..062124cd89cf2a560cff39b80b7f3cbcdb66c1a3 100644 (file)
@@ -349,7 +349,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                }
 
                chunk = min_t(unsigned int, skb->len, size);
-               if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+               if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, chunk)) {
                        skb_queue_head(&sk->sk_receive_queue, skb);
                        if (!copied)
                                copied = -EFAULT;
@@ -361,7 +361,33 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                sock_recv_ts_and_drops(msg, sk, skb);
 
                if (!(flags & MSG_PEEK)) {
-                       skb_pull(skb, chunk);
+                       int skb_len = skb_headlen(skb);
+
+                       if (chunk <= skb_len) {
+                               __skb_pull(skb, chunk);
+                       } else {
+                               struct sk_buff *frag;
+
+                               __skb_pull(skb, skb_len);
+                               chunk -= skb_len;
+
+                               skb_walk_frags(skb, frag) {
+                                       if (chunk <= frag->len) {
+                                               /* Pulling partial data */
+                                               skb->len -= chunk;
+                                               skb->data_len -= chunk;
+                                               __skb_pull(frag, chunk);
+                                               break;
+                                       } else if (frag->len) {
+                                               /* Pulling all frag data */
+                                               chunk -= frag->len;
+                                               skb->len -= frag->len;
+                                               skb->data_len -= frag->len;
+                                               __skb_pull(frag, frag->len);
+                                       }
+                               }
+                       }
+
                        if (skb->len) {
                                skb_queue_head(&sk->sk_receive_queue, skb);
                                break;
@@ -494,9 +520,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
        BT_DBG("sk %p", sk);
 
        add_wait_queue(sk_sleep(sk), &wait);
+       set_current_state(TASK_INTERRUPTIBLE);
        while (sk->sk_state != state) {
-               set_current_state(TASK_INTERRUPTIBLE);
-
                if (!timeo) {
                        err = -EINPROGRESS;
                        break;
@@ -510,12 +535,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
                release_sock(sk);
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
+               set_current_state(TASK_INTERRUPTIBLE);
 
                err = sock_error(sk);
                if (err)
                        break;
        }
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(sk_sleep(sk), &wait);
        return err;
 }
index 8e6c06158f8ebf02268362d4286b4763813b4e0c..e7ee5314f39a1e6a611dd3f0bd59c10c012ae699 100644 (file)
@@ -155,6 +155,7 @@ struct bnep_session {
        unsigned int  role;
        unsigned long state;
        unsigned long flags;
+       atomic_t      terminate;
        struct task_struct *task;
 
        struct ethhdr eh;
index ca39fcf010ce3353e73312f4172f32c9ce12cb1f..91bcd3a961ec22c501451ef588fe86b171c55ae3 100644 (file)
@@ -484,13 +484,18 @@ static int bnep_session(void *arg)
 
        init_waitqueue_entry(&wait, current);
        add_wait_queue(sk_sleep(sk), &wait);
-       while (!kthread_should_stop()) {
+       while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
 
+               if (atomic_read(&s->terminate))
+                       break;
                /* RX */
                while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
                        skb_orphan(skb);
-                       bnep_rx_frame(s, skb);
+                       if (!skb_linearize(skb))
+                               bnep_rx_frame(s, skb);
+                       else
+                               kfree_skb(skb);
                }
 
                if (sk->sk_state != BT_CONNECTED)
@@ -504,7 +509,7 @@ static int bnep_session(void *arg)
 
                schedule();
        }
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(sk_sleep(sk), &wait);
 
        /* Cleanup session */
@@ -640,9 +645,10 @@ int bnep_del_connection(struct bnep_conndel_req *req)
        down_read(&bnep_session_sem);
 
        s = __bnep_get_session(req->dst);
-       if (s)
-               kthread_stop(s->task);
-       else
+       if (s) {
+               atomic_inc(&s->terminate);
+               wake_up_process(s->task);
+       } else
                err = -ENOENT;
 
        up_read(&bnep_session_sem);
index d4f5dff7c95510f9b31cbd0797210f9105c0e098..bc4086480d97fa7586c3f8b01e07cd1c8ebbc69d 100644 (file)
@@ -217,7 +217,7 @@ static const struct net_device_ops bnep_netdev_ops = {
        .ndo_stop            = bnep_net_close,
        .ndo_start_xmit      = bnep_net_xmit,
        .ndo_validate_addr   = eth_validate_addr,
-       .ndo_set_multicast_list = bnep_net_set_mc_list,
+       .ndo_set_rx_mode     = bnep_net_set_mc_list,
        .ndo_set_mac_address = bnep_net_set_mac_addr,
        .ndo_tx_timeout      = bnep_net_timeout,
        .ndo_change_mtu      = eth_change_mtu,
index 040f67b12978c17713e4040937127b0cc814de8e..50f0d135eb8f201daf8156c433f08a973bfa338f 100644 (file)
@@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl)
 
        capi_ctr_down(ctrl);
 
-       kthread_stop(session->task);
+       atomic_inc(&session->terminate);
+       wake_up_process(session->task);
 }
 
 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
index db43b54ac9afb91cfc78f911f8a15c05104fe7ed..c32638dddbf9409d685c3436eb1b1541d04d5a9e 100644 (file)
@@ -81,6 +81,7 @@ struct cmtp_session {
 
        char name[BTNAMSIZ];
 
+       atomic_t terminate;
        struct task_struct *task;
 
        wait_queue_head_t wait;
index c5b11af908be4fc3ab6c7a0cebb9639900feb162..7d00ddf9e9dcb55ab74cf768db31a3e15af647ac 100644 (file)
@@ -292,22 +292,27 @@ static int cmtp_session(void *arg)
 
        init_waitqueue_entry(&wait, current);
        add_wait_queue(sk_sleep(sk), &wait);
-       while (!kthread_should_stop()) {
+       while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
 
+               if (atomic_read(&session->terminate))
+                       break;
                if (sk->sk_state != BT_CONNECTED)
                        break;
 
                while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
                        skb_orphan(skb);
-                       cmtp_recv_frame(session, skb);
+                       if (!skb_linearize(skb))
+                               cmtp_recv_frame(session, skb);
+                       else
+                               kfree_skb(skb);
                }
 
                cmtp_process_transmit(session);
 
                schedule();
        }
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(sk_sleep(sk), &wait);
 
        down_write(&cmtp_session_sem);
@@ -380,16 +385,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
 
        if (!(session->flags & (1 << CMTP_LOOPBACK))) {
                err = cmtp_attach_device(session);
-               if (err < 0)
-                       goto detach;
+               if (err < 0) {
+                       atomic_inc(&session->terminate);
+                       wake_up_process(session->task);
+                       up_write(&cmtp_session_sem);
+                       return err;
+               }
        }
 
        up_write(&cmtp_session_sem);
        return 0;
 
-detach:
-       cmtp_detach_device(session);
-
 unlink:
        __cmtp_unlink_session(session);
 
@@ -414,7 +420,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req)
                skb_queue_purge(&session->transmit);
 
                /* Stop session thread */
-               kthread_stop(session->task);
+               atomic_inc(&session->terminate);
+               wake_up_process(session->task);
        } else
                err = -ENOENT;
 
index ea7f031f3b04607efc65e79ab061dd0c5cb9337c..fa6820e86578ee6fddb741a4fd2c29b64f37df2a 100644 (file)
@@ -56,15 +56,15 @@ static void hci_le_connect(struct hci_conn *conn)
        conn->sec_level = BT_SECURITY_LOW;
 
        memset(&cp, 0, sizeof(cp));
-       cp.scan_interval = cpu_to_le16(0x0004);
-       cp.scan_window = cpu_to_le16(0x0004);
+       cp.scan_interval = cpu_to_le16(0x0060);
+       cp.scan_window = cpu_to_le16(0x0030);
        bacpy(&cp.peer_addr, &conn->dst);
        cp.peer_addr_type = conn->dst_type;
-       cp.conn_interval_min = cpu_to_le16(0x0008);
-       cp.conn_interval_max = cpu_to_le16(0x0100);
-       cp.supervision_timeout = cpu_to_le16(0x0064);
-       cp.min_ce_len = cpu_to_le16(0x0001);
-       cp.max_ce_len = cpu_to_le16(0x0001);
+       cp.conn_interval_min = cpu_to_le16(0x0028);
+       cp.conn_interval_max = cpu_to_le16(0x0038);
+       cp.supervision_timeout = cpu_to_le16(0x002a);
+       cp.min_ce_len = cpu_to_le16(0x0000);
+       cp.max_ce_len = cpu_to_le16(0x0000);
 
        hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
 }
index ec0bc3f60f2eea4216471746fdbea09c51b3fbcb..56943add45cc44707167f4877e27fe5630b00c95 100644 (file)
@@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg)
 
        BT_ERR("%s command tx timeout", hdev->name);
        atomic_set(&hdev->cmd_cnt, 1);
-       clear_bit(HCI_RESET, &hdev->flags);
        tasklet_schedule(&hdev->cmd_task);
 }
 
@@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
 
        entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
        if (!entry) {
-               return -ENOMEM;
+               err = -ENOMEM;
                goto err;
        }
 
@@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg)
                if (hdev->sent_cmd) {
                        atomic_dec(&hdev->cmd_cnt);
                        hci_send_frame(skb);
-                       mod_timer(&hdev->cmd_timer,
+                       if (test_bit(HCI_RESET, &hdev->flags))
+                               del_timer(&hdev->cmd_timer);
+                       else
+                               mod_timer(&hdev->cmd_timer,
                                  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
                } else {
                        skb_queue_head(&hdev->cmd_q, skb);
index 43b4c2deb7cc05bdc875e3f7b23a999468f5c1a4..dc620a38bc5dab9a7f1366d7356dabf5c3835c77 100644 (file)
@@ -716,12 +716,18 @@ static int hidp_session(void *arg)
 
                while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
                        skb_orphan(skb);
-                       hidp_recv_ctrl_frame(session, skb);
+                       if (!skb_linearize(skb))
+                               hidp_recv_ctrl_frame(session, skb);
+                       else
+                               kfree_skb(skb);
                }
 
                while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
                        skb_orphan(skb);
-                       hidp_recv_intr_frame(session, skb);
+                       if (!skb_linearize(skb))
+                               hidp_recv_intr_frame(session, skb);
+                       else
+                               kfree_skb(skb);
                }
 
                hidp_process_transmit(session);
@@ -764,6 +770,7 @@ static int hidp_session(void *arg)
 
        up_write(&hidp_session_sem);
 
+       kfree(session->rd_data);
        kfree(session);
        return 0;
 }
@@ -841,7 +848,8 @@ static int hidp_setup_input(struct hidp_session *session,
 
        err = input_register_device(input);
        if (err < 0) {
-               hci_conn_put_device(session->conn);
+               input_free_device(input);
+               session->input = NULL;
                return err;
        }
 
@@ -1044,8 +1052,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
        }
 
        err = hid_add_device(session->hid);
-       if (err < 0)
-               goto err_add_device;
+       if (err < 0) {
+               atomic_inc(&session->terminate);
+               wake_up_process(session->task);
+               up_write(&hidp_session_sem);
+               return err;
+       }
 
        if (session->input) {
                hidp_send_ctrl_message(session,
@@ -1059,12 +1071,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
        up_write(&hidp_session_sem);
        return 0;
 
-err_add_device:
-       hid_destroy_device(session->hid);
-       session->hid = NULL;
-       atomic_inc(&session->terminate);
-       wake_up_process(session->task);
-
 unlink:
        hidp_del_timer(session);
 
@@ -1090,7 +1096,6 @@ purge:
 failed:
        up_write(&hidp_session_sem);
 
-       input_free_device(session->input);
        kfree(session);
        return err;
 }
index 3204ba8a701ca0d7c99eebfc629d22e51a007021..be30c3221a886221ac03d43295d375530ca6bbdb 100644 (file)
@@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk)
        int timeo = HZ/5;
 
        add_wait_queue(sk_sleep(sk), &wait);
-       while ((chan->unacked_frames > 0 && chan->conn)) {
-               set_current_state(TASK_INTERRUPTIBLE);
-
+       set_current_state(TASK_INTERRUPTIBLE);
+       while (chan->unacked_frames > 0 && chan->conn) {
                if (!timeo)
                        timeo = HZ/5;
 
@@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk)
                release_sock(sk);
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
+               set_current_state(TASK_INTERRUPTIBLE);
 
                err = sock_error(sk);
                if (err)
@@ -1240,7 +1240,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
                __clear_retrans_timer(chan);
 }
 
-void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
+static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
 {
        struct hci_conn *hcon = chan->conn->hcon;
        u16 flags;
@@ -1256,7 +1256,7 @@ void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
        hci_send_acl(hcon, skb, flags);
 }
 
-void l2cap_streaming_send(struct l2cap_chan *chan)
+static void l2cap_streaming_send(struct l2cap_chan *chan)
 {
        struct sk_buff *skb;
        u16 control, fcs;
@@ -1322,7 +1322,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
        l2cap_do_send(chan, tx_skb);
 }
 
-int l2cap_ertm_send(struct l2cap_chan *chan)
+static int l2cap_ertm_send(struct l2cap_chan *chan)
 {
        struct sk_buff *skb, *tx_skb;
        u16 control, fcs;
@@ -1460,7 +1460,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
        return sent;
 }
 
-struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 {
        struct sock *sk = chan->sk;
        struct l2cap_conn *conn = chan->conn;
@@ -1490,7 +1490,7 @@ struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr
        return skb;
 }
 
-struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 {
        struct sock *sk = chan->sk;
        struct l2cap_conn *conn = chan->conn;
@@ -1519,7 +1519,7 @@ struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *m
        return skb;
 }
 
-struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
+static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
 {
        struct sock *sk = chan->sk;
        struct l2cap_conn *conn = chan->conn;
@@ -1565,7 +1565,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *
        return skb;
 }
 
-int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 {
        struct sk_buff *skb;
        struct sk_buff_head sar_queue;
@@ -3121,102 +3121,104 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
        return 0;
 }
 
-static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
+static void append_skb_frag(struct sk_buff *skb,
+                       struct sk_buff *new_frag, struct sk_buff **last_frag)
 {
-       struct sk_buff *_skb;
-       int err;
+       /* skb->len reflects data in skb as well as all fragments
+        * skb->data_len reflects only data in fragments
+        */
+       if (!skb_has_frag_list(skb))
+               skb_shinfo(skb)->frag_list = new_frag;
+
+       new_frag->next = NULL;
+
+       (*last_frag)->next = new_frag;
+       *last_frag = new_frag;
+
+       skb->len += new_frag->len;
+       skb->data_len += new_frag->len;
+       skb->truesize += new_frag->truesize;
+}
+
+static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
+{
+       int err = -EINVAL;
 
        switch (control & L2CAP_CTRL_SAR) {
        case L2CAP_SDU_UNSEGMENTED:
-               if (test_bit(CONN_SAR_SDU, &chan->conn_state))
-                       goto drop;
+               if (chan->sdu)
+                       break;
 
-               return chan->ops->recv(chan->data, skb);
+               err = chan->ops->recv(chan->data, skb);
+               break;
 
        case L2CAP_SDU_START:
-               if (test_bit(CONN_SAR_SDU, &chan->conn_state))
-                       goto drop;
+               if (chan->sdu)
+                       break;
 
                chan->sdu_len = get_unaligned_le16(skb->data);
+               skb_pull(skb, 2);
 
-               if (chan->sdu_len > chan->imtu)
-                       goto disconnect;
-
-               chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
-               if (!chan->sdu)
-                       return -ENOMEM;
+               if (chan->sdu_len > chan->imtu) {
+                       err = -EMSGSIZE;
+                       break;
+               }
 
-               /* pull sdu_len bytes only after alloc, because of Local Busy
-                * condition we have to be sure that this will be executed
-                * only once, i.e., when alloc does not fail */
-               skb_pull(skb, 2);
+               if (skb->len >= chan->sdu_len)
+                       break;
 
-               memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
+               chan->sdu = skb;
+               chan->sdu_last_frag = skb;
 
-               set_bit(CONN_SAR_SDU, &chan->conn_state);
-               chan->partial_sdu_len = skb->len;
+               skb = NULL;
+               err = 0;
                break;
 
        case L2CAP_SDU_CONTINUE:
-               if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
-                       goto disconnect;
-
                if (!chan->sdu)
-                       goto disconnect;
+                       break;
 
-               chan->partial_sdu_len += skb->len;
-               if (chan->partial_sdu_len > chan->sdu_len)
-                       goto drop;
+               append_skb_frag(chan->sdu, skb,
+                               &chan->sdu_last_frag);
+               skb = NULL;
 
-               memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
+               if (chan->sdu->len >= chan->sdu_len)
+                       break;
 
+               err = 0;
                break;
 
        case L2CAP_SDU_END:
-               if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
-                       goto disconnect;
-
                if (!chan->sdu)
-                       goto disconnect;
-
-               chan->partial_sdu_len += skb->len;
-
-               if (chan->partial_sdu_len > chan->imtu)
-                       goto drop;
+                       break;
 
-               if (chan->partial_sdu_len != chan->sdu_len)
-                       goto drop;
+               append_skb_frag(chan->sdu, skb,
+                               &chan->sdu_last_frag);
+               skb = NULL;
 
-               memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
+               if (chan->sdu->len != chan->sdu_len)
+                       break;
 
-               _skb = skb_clone(chan->sdu, GFP_ATOMIC);
-               if (!_skb) {
-                       return -ENOMEM;
-               }
+               err = chan->ops->recv(chan->data, chan->sdu);
 
-               err = chan->ops->recv(chan->data, _skb);
-               if (err < 0) {
-                       kfree_skb(_skb);
-                       return err;
+               if (!err) {
+                       /* Reassembly complete */
+                       chan->sdu = NULL;
+                       chan->sdu_last_frag = NULL;
+                       chan->sdu_len = 0;
                }
-
-               clear_bit(CONN_SAR_SDU, &chan->conn_state);
-
-               kfree_skb(chan->sdu);
                break;
        }
 
-       kfree_skb(skb);
-       return 0;
-
-drop:
-       kfree_skb(chan->sdu);
-       chan->sdu = NULL;
+       if (err) {
+               kfree_skb(skb);
+               kfree_skb(chan->sdu);
+               chan->sdu = NULL;
+               chan->sdu_last_frag = NULL;
+               chan->sdu_len = 0;
+       }
 
-disconnect:
-       l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
-       kfree_skb(skb);
-       return 0;
+       return err;
 }
 
 static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan)
@@ -3270,99 +3272,6 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
        }
 }
 
-static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
-{
-       struct sk_buff *_skb;
-       int err = -EINVAL;
-
-       /*
-        * TODO: We have to notify the userland if some data is lost with the
-        * Streaming Mode.
-        */
-
-       switch (control & L2CAP_CTRL_SAR) {
-       case L2CAP_SDU_UNSEGMENTED:
-               if (test_bit(CONN_SAR_SDU, &chan->conn_state)) {
-                       kfree_skb(chan->sdu);
-                       break;
-               }
-
-               err = chan->ops->recv(chan->data, skb);
-               if (!err)
-                       return 0;
-
-               break;
-
-       case L2CAP_SDU_START:
-               if (test_bit(CONN_SAR_SDU, &chan->conn_state)) {
-                       kfree_skb(chan->sdu);
-                       break;
-               }
-
-               chan->sdu_len = get_unaligned_le16(skb->data);
-               skb_pull(skb, 2);
-
-               if (chan->sdu_len > chan->imtu) {
-                       err = -EMSGSIZE;
-                       break;
-               }
-
-               chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
-               if (!chan->sdu) {
-                       err = -ENOMEM;
-                       break;
-               }
-
-               memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
-
-               set_bit(CONN_SAR_SDU, &chan->conn_state);
-               chan->partial_sdu_len = skb->len;
-               err = 0;
-               break;
-
-       case L2CAP_SDU_CONTINUE:
-               if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
-                       break;
-
-               memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
-
-               chan->partial_sdu_len += skb->len;
-               if (chan->partial_sdu_len > chan->sdu_len)
-                       kfree_skb(chan->sdu);
-               else
-                       err = 0;
-
-               break;
-
-       case L2CAP_SDU_END:
-               if (!test_bit(CONN_SAR_SDU, &chan->conn_state))
-                       break;
-
-               memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len);
-
-               clear_bit(CONN_SAR_SDU, &chan->conn_state);
-               chan->partial_sdu_len += skb->len;
-
-               if (chan->partial_sdu_len > chan->imtu)
-                       goto drop;
-
-               if (chan->partial_sdu_len == chan->sdu_len) {
-                       _skb = skb_clone(chan->sdu, GFP_ATOMIC);
-                       err = chan->ops->recv(chan->data, _skb);
-                       if (err < 0)
-                               kfree_skb(_skb);
-               }
-               err = 0;
-
-drop:
-               kfree_skb(chan->sdu);
-               break;
-       }
-
-       kfree_skb(skb);
-       return err;
-}
-
 static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
 {
        struct sk_buff *skb;
@@ -3377,7 +3286,7 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq)
 
                skb = skb_dequeue(&chan->srej_q);
                control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
-               err = l2cap_ertm_reassembly_sdu(chan, skb, control);
+               err = l2cap_reassemble_sdu(chan, skb, control);
 
                if (err < 0) {
                        l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
@@ -3537,7 +3446,7 @@ expected:
                return 0;
        }
 
-       err = l2cap_ertm_reassembly_sdu(chan, skb, rx_control);
+       err = l2cap_reassemble_sdu(chan, skb, rx_control);
        chan->buffer_seq = (chan->buffer_seq + 1) % 64;
        if (err < 0) {
                l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
@@ -3853,12 +3762,20 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
 
                tx_seq = __get_txseq(control);
 
-               if (chan->expected_tx_seq == tx_seq)
-                       chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
-               else
-                       chan->expected_tx_seq = (tx_seq + 1) % 64;
+               if (chan->expected_tx_seq != tx_seq) {
+                       /* Frame(s) missing - must discard partial SDU */
+                       kfree_skb(chan->sdu);
+                       chan->sdu = NULL;
+                       chan->sdu_last_frag = NULL;
+                       chan->sdu_len = 0;
 
-               l2cap_streaming_reassembly_sdu(chan, skb, control);
+                       /* TODO: Notify userland of missing data */
+               }
+
+               chan->expected_tx_seq = (tx_seq + 1) % 64;
+
+               if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE)
+                       l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
 
                goto done;
 
index 5c36b3e8739cb706f9aa47e74a0ed9c5f72b8e24..61f1f623091dbcd89992a64a635fc8de62963795 100644 (file)
@@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
 
        lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
 
-       if (sk->sk_state != BT_LISTEN) {
-               err = -EBADFD;
-               goto done;
-       }
-
        timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
        BT_DBG("sk %p timeo %ld", sk, timeo);
 
        /* Wait for an incoming connection. (wake-one). */
        add_wait_queue_exclusive(sk_sleep(sk), &wait);
-       while (!(nsk = bt_accept_dequeue(sk, newsock))) {
+       while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
-               if (!timeo) {
-                       err = -EAGAIN;
+
+               if (sk->sk_state != BT_LISTEN) {
+                       err = -EBADFD;
                        break;
                }
 
-               release_sock(sk);
-               timeo = schedule_timeout(timeo);
-               lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+               nsk = bt_accept_dequeue(sk, newsock);
+               if (nsk)
+                       break;
 
-               if (sk->sk_state != BT_LISTEN) {
-                       err = -EBADFD;
+               if (!timeo) {
+                       err = -EAGAIN;
                        break;
                }
 
@@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
                        err = sock_intr_errno(timeo);
                        break;
                }
+
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
        }
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(sk_sleep(sk), &wait);
 
        if (err)
@@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
        INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
 
        sk->sk_destruct = l2cap_sock_destruct;
-       sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
+       sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
 
        sock_reset_flag(sk, SOCK_ZAPPED);
 
index 5759bb7054f7f4aca8822271b7de4da8997af915..38b618c96de64a13a1d724a954352cec27264fae 100644 (file)
@@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex);
 #define rfcomm_lock()  mutex_lock(&rfcomm_mutex)
 #define rfcomm_unlock()        mutex_unlock(&rfcomm_mutex)
 
-static unsigned long rfcomm_event;
 
 static LIST_HEAD(session_list);
 
@@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void)
 {
        if (!rfcomm_thread)
                return;
-       set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
        wake_up_process(rfcomm_thread);
 }
 
@@ -1855,7 +1853,10 @@ static inline void rfcomm_process_rx(struct rfcomm_session *s)
        /* Get data directly from socket receive queue without copying it. */
        while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
                skb_orphan(skb);
-               rfcomm_recv_frame(s, skb);
+               if (!skb_linearize(skb))
+                       rfcomm_recv_frame(s, skb);
+               else
+                       kfree_skb(skb);
        }
 
        if (sk->sk_state == BT_CLOSED) {
@@ -2038,19 +2039,18 @@ static int rfcomm_run(void *unused)
 
        rfcomm_add_listener(BDADDR_ANY);
 
-       while (!kthread_should_stop()) {
+       while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
-               if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-                       /* No pending events. Let's sleep.
-                        * Incoming connections and data will wake us up. */
-                       schedule();
-               }
-               set_current_state(TASK_RUNNING);
+
+               if (kthread_should_stop())
+                       break;
 
                /* Process stuff */
-               clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
                rfcomm_process_sessions();
+
+               schedule();
        }
+       __set_current_state(TASK_RUNNING);
 
        rfcomm_kill_listener();
 
index 8f01e6b11a7037d487c5a32072d460d56760a64a..482722bbc7a052c67053a95ad357463a5bc641bf 100644 (file)
@@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
 
        lock_sock(sk);
 
-       if (sk->sk_state != BT_LISTEN) {
-               err = -EBADFD;
-               goto done;
-       }
-
        if (sk->sk_type != SOCK_STREAM) {
                err = -EINVAL;
                goto done;
@@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
 
        /* Wait for an incoming connection. (wake-one). */
        add_wait_queue_exclusive(sk_sleep(sk), &wait);
-       while (!(nsk = bt_accept_dequeue(sk, newsock))) {
+       while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
-               if (!timeo) {
-                       err = -EAGAIN;
+
+               if (sk->sk_state != BT_LISTEN) {
+                       err = -EBADFD;
                        break;
                }
 
-               release_sock(sk);
-               timeo = schedule_timeout(timeo);
-               lock_sock(sk);
+               nsk = bt_accept_dequeue(sk, newsock);
+               if (nsk)
+                       break;
 
-               if (sk->sk_state != BT_LISTEN) {
-                       err = -EBADFD;
+               if (!timeo) {
+                       err = -EAGAIN;
                        break;
                }
 
@@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
                        err = sock_intr_errno(timeo);
                        break;
                }
+
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
        }
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(sk_sleep(sk), &wait);
 
        if (err)
index 4c3621b5e0aa2344196767bdeb6be407918732b4..8270f05e3f1f27b0883020eede325df8d17154d0 100644 (file)
@@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
 
        lock_sock(sk);
 
-       if (sk->sk_state != BT_LISTEN) {
-               err = -EBADFD;
-               goto done;
-       }
-
        timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
        BT_DBG("sk %p timeo %ld", sk, timeo);
 
        /* Wait for an incoming connection. (wake-one). */
        add_wait_queue_exclusive(sk_sleep(sk), &wait);
-       while (!(ch = bt_accept_dequeue(sk, newsock))) {
+       while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
-               if (!timeo) {
-                       err = -EAGAIN;
+
+               if (sk->sk_state != BT_LISTEN) {
+                       err = -EBADFD;
                        break;
                }
 
-               release_sock(sk);
-               timeo = schedule_timeout(timeo);
-               lock_sock(sk);
+               ch = bt_accept_dequeue(sk, newsock);
+               if (ch)
+                       break;
 
-               if (sk->sk_state != BT_LISTEN) {
-                       err = -EBADFD;
+               if (!timeo) {
+                       err = -EAGAIN;
                        break;
                }
 
@@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
                        err = sock_intr_errno(timeo);
                        break;
                }
+
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
        }
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(sk_sleep(sk), &wait);
 
        if (err)
index 32b8f9f7f79e4a5ce555e4c803f7ecd79878006e..ee68eee79e52570d73ad740e03dad1c8829ac364 100644 (file)
@@ -304,7 +304,7 @@ static const struct net_device_ops br_netdev_ops = {
        .ndo_start_xmit          = br_dev_xmit,
        .ndo_get_stats64         = br_get_stats64,
        .ndo_set_mac_address     = br_set_mac_address,
-       .ndo_set_multicast_list  = br_dev_set_multicast_list,
+       .ndo_set_rx_mode         = br_dev_set_multicast_list,
        .ndo_change_mtu          = br_change_mtu,
        .ndo_do_ioctl            = br_dev_ioctl,
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 1bcaf36ad612739f54e411984218f79ec645e808..40d8258bf74f89fbd31193c72b436b1d802f8a7f 100644 (file)
@@ -87,14 +87,14 @@ static int __init ebtable_broute_init(void)
        if (ret < 0)
                return ret;
        /* see br_input.c */
-       rcu_assign_pointer(br_should_route_hook,
+       RCU_INIT_POINTER(br_should_route_hook,
                           (br_should_route_hook_t *)ebt_broute);
        return 0;
 }
 
 static void __exit ebtable_broute_fini(void)
 {
-       rcu_assign_pointer(br_should_route_hook, NULL);
+       RCU_INIT_POINTER(br_should_route_hook, NULL);
        synchronize_net();
        unregister_pernet_subsys(&broute_net_ops);
 }
index c23979e79dfadce502c5d70927412849b79b868e..b36f24a4c8e74951f07bb06f2dfd6b6c3f81bfa4 100644 (file)
@@ -108,7 +108,7 @@ struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid)
        int idx = phyid % DN_CACHE_SIZE;
 
        spin_lock_bh(&muxl->transmit_lock);
-       rcu_assign_pointer(muxl->dn_cache[idx], NULL);
+       RCU_INIT_POINTER(muxl->dn_cache[idx], NULL);
        dn = get_from_id(&muxl->frml_list, phyid);
        if (dn == NULL)
                goto out;
@@ -164,7 +164,7 @@ struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id)
        if (up == NULL)
                goto out;
 
-       rcu_assign_pointer(muxl->up_cache[idx], NULL);
+       RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
        list_del_rcu(&up->node);
 out:
        spin_unlock_bh(&muxl->receive_lock);
@@ -261,7 +261,7 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
 
                                idx = layer->id % UP_CACHE_SIZE;
                                spin_lock_bh(&muxl->receive_lock);
-                               rcu_assign_pointer(muxl->up_cache[idx], NULL);
+                               RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
                                list_del_rcu(&layer->node);
                                spin_unlock_bh(&muxl->receive_lock);
                        }
index 8ce926d3b2cb9e51f053a8a06c271eb50ee481ea..b9efa944cab9cfc5953e9a6c7bd625c390488a87 100644 (file)
@@ -719,7 +719,7 @@ int can_proto_register(const struct can_proto *cp)
                       proto);
                err = -EBUSY;
        } else
-               rcu_assign_pointer(proto_tab[proto], cp);
+               RCU_INIT_POINTER(proto_tab[proto], cp);
 
        mutex_unlock(&proto_tab_lock);
 
@@ -740,7 +740,7 @@ void can_proto_unregister(const struct can_proto *cp)
 
        mutex_lock(&proto_tab_lock);
        BUG_ON(proto_tab[proto] != cp);
-       rcu_assign_pointer(proto_tab[proto], NULL);
+       RCU_INIT_POINTER(proto_tab[proto], NULL);
        mutex_unlock(&proto_tab_lock);
 
        synchronize_rcu();
index 132963abc266282db76a7268f96257fec2d76627..d4038ca3a26bb3f3eea853cbd04b7da4b7b375b9 100644 (file)
@@ -431,9 +431,12 @@ EXPORT_SYMBOL(ceph_client_id);
 /*
  * create a fresh client instance
  */
-struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
+struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private,
+                                      unsigned supported_features,
+                                      unsigned required_features)
 {
        struct ceph_client *client;
+       struct ceph_entity_addr *myaddr = NULL;
        int err = -ENOMEM;
 
        client = kzalloc(sizeof(*client), GFP_KERNEL);
@@ -448,15 +451,27 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
        client->auth_err = 0;
 
        client->extra_mon_dispatch = NULL;
-       client->supported_features = CEPH_FEATURE_SUPPORTED_DEFAULT;
-       client->required_features = CEPH_FEATURE_REQUIRED_DEFAULT;
-
-       client->msgr = NULL;
+       client->supported_features = CEPH_FEATURE_SUPPORTED_DEFAULT |
+               supported_features;
+       client->required_features = CEPH_FEATURE_REQUIRED_DEFAULT |
+               required_features;
+
+       /* msgr */
+       if (ceph_test_opt(client, MYIP))
+               myaddr = &client->options->my_addr;
+       client->msgr = ceph_messenger_create(myaddr,
+                                            client->supported_features,
+                                            client->required_features);
+       if (IS_ERR(client->msgr)) {
+               err = PTR_ERR(client->msgr);
+               goto fail;
+       }
+       client->msgr->nocrc = ceph_test_opt(client, NOCRC);
 
        /* subsystems */
        err = ceph_monc_init(&client->monc, client);
        if (err < 0)
-               goto fail;
+               goto fail_msgr;
        err = ceph_osdc_init(&client->osdc, client);
        if (err < 0)
                goto fail_monc;
@@ -465,6 +480,8 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
 
 fail_monc:
        ceph_monc_stop(&client->monc);
+fail_msgr:
+       ceph_messenger_destroy(client->msgr);
 fail:
        kfree(client);
        return ERR_PTR(err);
@@ -489,8 +506,7 @@ void ceph_destroy_client(struct ceph_client *client)
 
        ceph_debugfs_client_cleanup(client);
 
-       if (client->msgr)
-               ceph_messenger_destroy(client->msgr);
+       ceph_messenger_destroy(client->msgr);
 
        ceph_destroy_options(client->options);
 
@@ -513,24 +529,9 @@ static int have_mon_and_osd_map(struct ceph_client *client)
  */
 int __ceph_open_session(struct ceph_client *client, unsigned long started)
 {
-       struct ceph_entity_addr *myaddr = NULL;
        int err;
        unsigned long timeout = client->options->mount_timeout * HZ;
 
-       /* initialize the messenger */
-       if (client->msgr == NULL) {
-               if (ceph_test_opt(client, MYIP))
-                       myaddr = &client->options->my_addr;
-               client->msgr = ceph_messenger_create(myaddr,
-                                       client->supported_features,
-                                       client->required_features);
-               if (IS_ERR(client->msgr)) {
-                       client->msgr = NULL;
-                       return PTR_ERR(client->msgr);
-               }
-               client->msgr->nocrc = ceph_test_opt(client, NOCRC);
-       }
-
        /* open session, and wait for mon and osd maps */
        err = ceph_monc_open_session(&client->monc);
        if (err < 0)
index c340e2e0765b4bdf72efc9f2bd484bc7f7f36de5..e6d485724dd592c5d0c76c49630cf37b1964df85 100644 (file)
@@ -2281,7 +2281,8 @@ EXPORT_SYMBOL(ceph_con_keepalive);
  * construct a new message with given type, size
  * the new msg has a ref count of 1.
  */
-struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
+struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
+                             bool can_fail)
 {
        struct ceph_msg *m;
 
@@ -2332,7 +2333,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
                        m->front.iov_base = kmalloc(front_len, flags);
                }
                if (m->front.iov_base == NULL) {
-                       pr_err("msg_new can't allocate %d bytes\n",
+                       dout("ceph_msg_new can't allocate %d bytes\n",
                             front_len);
                        goto out2;
                }
@@ -2347,7 +2348,14 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
 out2:
        ceph_msg_put(m);
 out:
-       pr_err("msg_new can't create type %d front %d\n", type, front_len);
+       if (!can_fail) {
+               pr_err("msg_new can't create type %d front %d\n", type,
+                      front_len);
+               WARN_ON(1);
+       } else {
+               dout("msg_new can't create type %d front %d\n", type,
+                    front_len);
+       }
        return NULL;
 }
 EXPORT_SYMBOL(ceph_msg_new);
@@ -2397,7 +2405,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
        }
        if (!msg) {
                *skip = 0;
-               msg = ceph_msg_new(type, front_len, GFP_NOFS);
+               msg = ceph_msg_new(type, front_len, GFP_NOFS, false);
                if (!msg) {
                        pr_err("unable to allocate msg type %d len %d\n",
                               type, front_len);
index cbe31fa45508ce8fc06e55edd43b914cc513258f..af2ef30824994b83860083044ac9cc01ad6d9360 100644 (file)
@@ -116,14 +116,12 @@ static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
  */
 static void __close_session(struct ceph_mon_client *monc)
 {
-       if (monc->con) {
-               dout("__close_session closing mon%d\n", monc->cur_mon);
-               ceph_con_revoke(monc->con, monc->m_auth);
-               ceph_con_close(monc->con);
-               monc->cur_mon = -1;
-               monc->pending_auth = 0;
-               ceph_auth_reset(monc->auth);
-       }
+       dout("__close_session closing mon%d\n", monc->cur_mon);
+       ceph_con_revoke(monc->con, monc->m_auth);
+       ceph_con_close(monc->con);
+       monc->cur_mon = -1;
+       monc->pending_auth = 0;
+       ceph_auth_reset(monc->auth);
 }
 
 /*
@@ -302,15 +300,6 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
  */
 int ceph_monc_open_session(struct ceph_mon_client *monc)
 {
-       if (!monc->con) {
-               monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
-               if (!monc->con)
-                       return -ENOMEM;
-               ceph_con_init(monc->client->msgr, monc->con);
-               monc->con->private = monc;
-               monc->con->ops = &mon_con_ops;
-       }
-
        mutex_lock(&monc->mutex);
        __open_session(monc);
        __schedule_delayed(monc);
@@ -528,10 +517,12 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
        init_completion(&req->completion);
 
        err = -ENOMEM;
-       req->request = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), GFP_NOFS);
+       req->request = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), GFP_NOFS,
+                                   true);
        if (!req->request)
                goto out;
-       req->reply = ceph_msg_new(CEPH_MSG_STATFS_REPLY, 1024, GFP_NOFS);
+       req->reply = ceph_msg_new(CEPH_MSG_STATFS_REPLY, 1024, GFP_NOFS,
+                                 true);
        if (!req->reply)
                goto out;
 
@@ -626,10 +617,12 @@ int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op,
        init_completion(&req->completion);
 
        err = -ENOMEM;
-       req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS);
+       req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS,
+                                   true);
        if (!req->request)
                goto out;
-       req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS);
+       req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS,
+                                 true);
        if (!req->reply)
                goto out;
 
@@ -755,7 +748,13 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
        if (err)
                goto out;
 
-       monc->con = NULL;
+       /* connection */
+       monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
+       if (!monc->con)
+               goto out_monmap;
+       ceph_con_init(monc->client->msgr, monc->con);
+       monc->con->private = monc;
+       monc->con->ops = &mon_con_ops;
 
        /* authentication */
        monc->auth = ceph_auth_init(cl->options->name,
@@ -770,19 +769,21 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
        err = -ENOMEM;
        monc->m_subscribe_ack = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE_ACK,
                                     sizeof(struct ceph_mon_subscribe_ack),
-                                    GFP_NOFS);
+                                    GFP_NOFS, true);
        if (!monc->m_subscribe_ack)
-               goto out_monmap;
+               goto out_con;
 
-       monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, GFP_NOFS);
+       monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, GFP_NOFS,
+                                        true);
        if (!monc->m_subscribe)
                goto out_subscribe_ack;
 
-       monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096, GFP_NOFS);
+       monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096, GFP_NOFS,
+                                         true);
        if (!monc->m_auth_reply)
                goto out_subscribe;
 
-       monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_NOFS);
+       monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_NOFS, true);
        monc->pending_auth = 0;
        if (!monc->m_auth)
                goto out_auth_reply;
@@ -808,6 +809,8 @@ out_subscribe:
        ceph_msg_put(monc->m_subscribe);
 out_subscribe_ack:
        ceph_msg_put(monc->m_subscribe_ack);
+out_con:
+       monc->con->ops->put(monc->con);
 out_monmap:
        kfree(monc->monmap);
 out:
@@ -822,11 +825,11 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
 
        mutex_lock(&monc->mutex);
        __close_session(monc);
-       if (monc->con) {
-               monc->con->private = NULL;
-               monc->con->ops->put(monc->con);
-               monc->con = NULL;
-       }
+
+       monc->con->private = NULL;
+       monc->con->ops->put(monc->con);
+       monc->con = NULL;
+
        mutex_unlock(&monc->mutex);
 
        ceph_auth_destroy(monc->auth);
@@ -973,7 +976,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
        case CEPH_MSG_MON_MAP:
        case CEPH_MSG_MDS_MAP:
        case CEPH_MSG_OSD_MAP:
-               m = ceph_msg_new(type, front_len, GFP_NOFS);
+               m = ceph_msg_new(type, front_len, GFP_NOFS, false);
                break;
        }
 
@@ -1000,7 +1003,7 @@ static void mon_fault(struct ceph_connection *con)
        if (!con->private)
                goto out;
 
-       if (monc->con && !monc->hunting)
+       if (!monc->hunting)
                pr_info("mon%d %s session lost, "
                        "hunting for new mon\n", monc->cur_mon,
                        ceph_pr_addr(&monc->con->peer_addr.in_addr));
index d5f2d97ac05caf40124fe4f628efe77a514d8e55..11d5f4196a73cfeef3492389c76f9f285c50188d 100644 (file)
@@ -7,27 +7,37 @@
 
 #include <linux/ceph/msgpool.h>
 
-static void *alloc_fn(gfp_t gfp_mask, void *arg)
+static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
 {
        struct ceph_msgpool *pool = arg;
-       void *p;
+       struct ceph_msg *msg;
 
-       p = ceph_msg_new(0, pool->front_len, gfp_mask);
-       if (!p)
-               pr_err("msgpool %s alloc failed\n", pool->name);
-       return p;
+       msg = ceph_msg_new(0, pool->front_len, gfp_mask, true);
+       if (!msg) {
+               dout("msgpool_alloc %s failed\n", pool->name);
+       } else {
+               dout("msgpool_alloc %s %p\n", pool->name, msg);
+               msg->pool = pool;
+       }
+       return msg;
 }
 
-static void free_fn(void *element, void *arg)
+static void msgpool_free(void *element, void *arg)
 {
-       ceph_msg_put(element);
+       struct ceph_msgpool *pool = arg;
+       struct ceph_msg *msg = element;
+
+       dout("msgpool_release %s %p\n", pool->name, msg);
+       msg->pool = NULL;
+       ceph_msg_put(msg);
 }
 
 int ceph_msgpool_init(struct ceph_msgpool *pool,
                      int front_len, int size, bool blocking, const char *name)
 {
+       dout("msgpool %s init\n", name);
        pool->front_len = front_len;
-       pool->pool = mempool_create(size, alloc_fn, free_fn, pool);
+       pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool);
        if (!pool->pool)
                return -ENOMEM;
        pool->name = name;
@@ -36,29 +46,37 @@ int ceph_msgpool_init(struct ceph_msgpool *pool,
 
 void ceph_msgpool_destroy(struct ceph_msgpool *pool)
 {
+       dout("msgpool %s destroy\n", pool->name);
        mempool_destroy(pool->pool);
 }
 
 struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool,
                                  int front_len)
 {
+       struct ceph_msg *msg;
+
        if (front_len > pool->front_len) {
-               pr_err("msgpool_get pool %s need front %d, pool size is %d\n",
+               dout("msgpool_get %s need front %d, pool size is %d\n",
                       pool->name, front_len, pool->front_len);
                WARN_ON(1);
 
                /* try to alloc a fresh message */
-               return ceph_msg_new(0, front_len, GFP_NOFS);
+               return ceph_msg_new(0, front_len, GFP_NOFS, false);
        }
 
-       return mempool_alloc(pool->pool, GFP_NOFS);
+       msg = mempool_alloc(pool->pool, GFP_NOFS);
+       dout("msgpool_get %s %p\n", pool->name, msg);
+       return msg;
 }
 
 void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
 {
+       dout("msgpool_put %s %p\n", pool->name, msg);
+
        /* reset msg front_len; user may have changed it */
        msg->front.iov_len = pool->front_len;
        msg->hdr.front_len = cpu_to_le32(pool->front_len);
 
        kref_init(&msg->kref);  /* retake single ref */
+       mempool_free(msg, pool->pool);
 }
index ce310eee708d9f76c0a631b32edb6eb046cff153..9276c32a78dc04ed749d10954288536cc14170f2 100644 (file)
@@ -226,7 +226,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
                msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
        else
                msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY,
-                                  OSD_OPREPLY_FRONT_LEN, gfp_flags);
+                                  OSD_OPREPLY_FRONT_LEN, gfp_flags, true);
        if (!msg) {
                ceph_osdc_put_request(req);
                return NULL;
@@ -249,7 +249,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
        if (use_mempool)
                msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
        else
-               msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp_flags);
+               msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp_flags, true);
        if (!msg) {
                ceph_osdc_put_request(req);
                return NULL;
@@ -2022,7 +2022,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
        if (front > req->r_reply->front.iov_len) {
                pr_warning("get_reply front %d > preallocated %d\n",
                           front, (int)req->r_reply->front.iov_len);
-               m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, GFP_NOFS);
+               m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, GFP_NOFS, false);
                if (!m)
                        goto out;
                ceph_msg_put(req->r_reply);
@@ -2070,7 +2070,7 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con,
        switch (type) {
        case CEPH_MSG_OSD_MAP:
        case CEPH_MSG_WATCH_NOTIFY:
-               return ceph_msg_new(type, front, GFP_NOFS);
+               return ceph_msg_new(type, front, GFP_NOFS, false);
        case CEPH_MSG_OSD_OPREPLY:
                return get_reply(con, hdr, skip);
        default:
index 17d67b579beb0c3f6f97bfd8add5d7027741854a..91c1bde5ba5ecf282d71fd5ad69b9bfaabdda1bd 100644 (file)
 #include <linux/pci.h>
 #include <linux/inetdevice.h>
 #include <linux/cpu_rmap.h>
+#include <linux/if_tunnel.h>
+#include <linux/if_pppox.h>
 
 #include "net-sysfs.h"
 
@@ -2519,24 +2521,29 @@ static inline void ____napi_schedule(struct softnet_data *sd,
 
 /*
  * __skb_get_rxhash: calculate a flow hash based on src/dst addresses
- * and src/dst port numbers. Returns a non-zero hash number on success
- * and 0 on failure.
+ * and src/dst port numbers.  Sets rxhash in skb to non-zero hash value
+ * on success, zero indicates no valid hash.  Also, sets l4_rxhash in skb
+ * if hash is a canonical 4-tuple hash over transport ports.
  */
-__u32 __skb_get_rxhash(struct sk_buff *skb)
+void __skb_get_rxhash(struct sk_buff *skb)
 {
        int nhoff, hash = 0, poff;
        const struct ipv6hdr *ip6;
        const struct iphdr *ip;
+       const struct vlan_hdr *vlan;
        u8 ip_proto;
-       u32 addr1, addr2, ihl;
+       u32 addr1, addr2;
+       u16 proto;
        union {
                u32 v32;
                u16 v16[2];
        } ports;
 
        nhoff = skb_network_offset(skb);
+       proto = skb->protocol;
 
-       switch (skb->protocol) {
+again:
+       switch (proto) {
        case __constant_htons(ETH_P_IP):
                if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
                        goto done;
@@ -2548,7 +2555,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
                        ip_proto = ip->protocol;
                addr1 = (__force u32) ip->saddr;
                addr2 = (__force u32) ip->daddr;
-               ihl = ip->ihl;
+               nhoff += ip->ihl * 4;
                break;
        case __constant_htons(ETH_P_IPV6):
                if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
@@ -2558,20 +2565,62 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
                ip_proto = ip6->nexthdr;
                addr1 = (__force u32) ip6->saddr.s6_addr32[3];
                addr2 = (__force u32) ip6->daddr.s6_addr32[3];
-               ihl = (40 >> 2);
+               nhoff += 40;
                break;
+       case __constant_htons(ETH_P_8021Q):
+               if (!pskb_may_pull(skb, sizeof(*vlan) + nhoff))
+                       goto done;
+               vlan = (const struct vlan_hdr *) (skb->data + nhoff);
+               proto = vlan->h_vlan_encapsulated_proto;
+               nhoff += sizeof(*vlan);
+               goto again;
+       case __constant_htons(ETH_P_PPP_SES):
+               if (!pskb_may_pull(skb, PPPOE_SES_HLEN + nhoff))
+                       goto done;
+               proto = *((__be16 *) (skb->data + nhoff +
+                                     sizeof(struct pppoe_hdr)));
+               nhoff += PPPOE_SES_HLEN;
+               goto again;
        default:
                goto done;
        }
 
+       switch (ip_proto) {
+       case IPPROTO_GRE:
+               if (pskb_may_pull(skb, nhoff + 16)) {
+                       u8 *h = skb->data + nhoff;
+                       __be16 flags = *(__be16 *)h;
+
+                       /*
+                        * Only look inside GRE if version zero and no
+                        * routing
+                        */
+                       if (!(flags & (GRE_VERSION|GRE_ROUTING))) {
+                               proto = *(__be16 *)(h + 2);
+                               nhoff += 4;
+                               if (flags & GRE_CSUM)
+                                       nhoff += 4;
+                               if (flags & GRE_KEY)
+                                       nhoff += 4;
+                               if (flags & GRE_SEQ)
+                                       nhoff += 4;
+                               goto again;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+
        ports.v32 = 0;
        poff = proto_ports_offset(ip_proto);
        if (poff >= 0) {
-               nhoff += ihl * 4 + poff;
+               nhoff += poff;
                if (pskb_may_pull(skb, nhoff + 4)) {
                        ports.v32 = * (__force u32 *) (skb->data + nhoff);
                        if (ports.v16[1] < ports.v16[0])
                                swap(ports.v16[0], ports.v16[1]);
+                       skb->l4_rxhash = 1;
                }
        }
 
@@ -2584,7 +2633,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
                hash = 1;
 
 done:
-       return hash;
+       skb->rxhash = hash;
 }
 EXPORT_SYMBOL(__skb_get_rxhash);
 
@@ -2673,13 +2722,13 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
        map = rcu_dereference(rxqueue->rps_map);
        if (map) {
                if (map->len == 1 &&
-                   !rcu_dereference_raw(rxqueue->rps_flow_table)) {
+                   !rcu_access_pointer(rxqueue->rps_flow_table)) {
                        tcpu = map->cpus[0];
                        if (cpu_online(tcpu))
                                cpu = tcpu;
                        goto done;
                }
-       } else if (!rcu_dereference_raw(rxqueue->rps_flow_table)) {
+       } else if (!rcu_access_pointer(rxqueue->rps_flow_table)) {
                goto done;
        }
 
@@ -3094,8 +3143,8 @@ void netdev_rx_handler_unregister(struct net_device *dev)
 {
 
        ASSERT_RTNL();
-       rcu_assign_pointer(dev->rx_handler, NULL);
-       rcu_assign_pointer(dev->rx_handler_data, NULL);
+       RCU_INIT_POINTER(dev->rx_handler, NULL);
+       RCU_INIT_POINTER(dev->rx_handler_data, NULL);
 }
 EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
 
@@ -3187,10 +3236,9 @@ ncls:
                        ret = deliver_skb(skb, pt_prev, orig_dev);
                        pt_prev = NULL;
                }
-               if (vlan_do_receive(&skb)) {
-                       ret = __netif_receive_skb(skb);
-                       goto out;
-               } else if (unlikely(!skb))
+               if (vlan_do_receive(&skb))
+                       goto another_round;
+               else if (unlikely(!skb))
                        goto out;
        }
 
@@ -4489,9 +4537,7 @@ void __dev_set_rx_mode(struct net_device *dev)
        if (!netif_device_present(dev))
                return;
 
-       if (ops->ndo_set_rx_mode)
-               ops->ndo_set_rx_mode(dev);
-       else {
+       if (!(dev->priv_flags & IFF_UNICAST_FLT)) {
                /* Unicast addresses changes may only happen under the rtnl,
                 * therefore calling __dev_set_promiscuity here is safe.
                 */
@@ -4502,10 +4548,10 @@ void __dev_set_rx_mode(struct net_device *dev)
                        __dev_set_promiscuity(dev, -1);
                        dev->uc_promisc = false;
                }
-
-               if (ops->ndo_set_multicast_list)
-                       ops->ndo_set_multicast_list(dev);
        }
+
+       if (ops->ndo_set_rx_mode)
+               ops->ndo_set_rx_mode(dev);
 }
 
 void dev_set_rx_mode(struct net_device *dev)
@@ -4855,7 +4901,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
                return -EOPNOTSUPP;
 
        case SIOCADDMULTI:
-               if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
+               if (!ops->ndo_set_rx_mode ||
                    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
                        return -EINVAL;
                if (!netif_device_present(dev))
@@ -4863,7 +4909,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
                return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data);
 
        case SIOCDELMULTI:
-               if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
+               if (!ops->ndo_set_rx_mode ||
                    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
                        return -EINVAL;
                if (!netif_device_present(dev))
@@ -5727,8 +5773,8 @@ void netdev_run_todo(void)
 
                /* paranoia */
                BUG_ON(netdev_refcnt_read(dev));
-               WARN_ON(rcu_dereference_raw(dev->ip_ptr));
-               WARN_ON(rcu_dereference_raw(dev->ip6_ptr));
+               WARN_ON(rcu_access_pointer(dev->ip_ptr));
+               WARN_ON(rcu_access_pointer(dev->ip6_ptr));
                WARN_ON(dev->dn_ptr);
 
                if (dev->destructor)
@@ -5932,7 +5978,7 @@ void free_netdev(struct net_device *dev)
        kfree(dev->_rx);
 #endif
 
-       kfree(rcu_dereference_raw(dev->ingress_queue));
+       kfree(rcu_dereference_protected(dev->ingress_queue, 1));
 
        /* Flush device addresses */
        dev_addr_flush(dev);
@@ -6290,7 +6336,7 @@ const char *netdev_drivername(const struct net_device *dev)
        return empty;
 }
 
-static int __netdev_printk(const char *level, const struct net_device *dev,
+int __netdev_printk(const char *level, const struct net_device *dev,
                           struct va_format *vaf)
 {
        int r;
@@ -6305,6 +6351,7 @@ static int __netdev_printk(const char *level, const struct net_device *dev,
 
        return r;
 }
+EXPORT_SYMBOL(__netdev_printk);
 
 int netdev_printk(const char *level, const struct net_device *dev,
                  const char *format, ...)
index e2e66939ed009df93fe61b22c07d33c892fdeb4e..283d1b863876ec176988d12442a71a540168ee22 100644 (file)
@@ -591,8 +591,8 @@ EXPORT_SYMBOL(dev_mc_del_global);
  *     addresses that have no users left. The source device must be
  *     locked by netif_tx_lock_bh.
  *
- *     This function is intended to be called from the dev->set_multicast_list
- *     or dev->set_rx_mode function of layered software devices.
+ *     This function is intended to be called from the ndo_set_rx_mode
+ *     function of layered software devices.
  */
 int dev_mc_sync(struct net_device *to, struct net_device *from)
 {
index 14b33baf0733b51db4ded1d6022a731939922aeb..d5e2c4c0910763b180fcb73d9722a770c7f2b863 100644 (file)
@@ -171,7 +171,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
        dst_init_metrics(dst, dst_default_metrics, true);
        dst->expires = 0UL;
        dst->path = dst;
-       dst->_neighbour = NULL;
+       RCU_INIT_POINTER(dst->_neighbour, NULL);
 #ifdef CONFIG_XFRM
        dst->xfrm = NULL;
 #endif
@@ -229,11 +229,11 @@ struct dst_entry *dst_destroy(struct dst_entry * dst)
        smp_rmb();
 
 again:
-       neigh = dst->_neighbour;
+       neigh = rcu_dereference_protected(dst->_neighbour, 1);
        child = dst->child;
 
        if (neigh) {
-               dst->_neighbour = NULL;
+               RCU_INIT_POINTER(dst->_neighbour, NULL);
                neigh_release(neigh);
        }
 
@@ -360,14 +360,19 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        if (!unregister) {
                dst->input = dst->output = dst_discard;
        } else {
+               struct neighbour *neigh;
+
                dst->dev = dev_net(dst->dev)->loopback_dev;
                dev_hold(dst->dev);
                dev_put(dev);
-               if (dst->_neighbour && dst->_neighbour->dev == dev) {
-                       dst->_neighbour->dev = dst->dev;
+               rcu_read_lock();
+               neigh = dst_get_neighbour(dst);
+               if (neigh && neigh->dev == dev) {
+                       neigh->dev = dst->dev;
                        dev_hold(dst->dev);
                        dev_put(dev);
                }
+               rcu_read_unlock();
        }
 }
 
index e7ab0c0285b5f077ea4322755a10dc70cc608ec6..67c5c288cd8013b3f1e2a55c8c4c61f03b6471b1 100644 (file)
@@ -487,7 +487,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                if (ops->nr_goto_rules > 0) {
                        list_for_each_entry(tmp, &ops->rules_list, list) {
                                if (rtnl_dereference(tmp->ctarget) == rule) {
-                                       rcu_assign_pointer(tmp->ctarget, NULL);
+                                       RCU_INIT_POINTER(tmp->ctarget, NULL);
                                        ops->unresolved_rules++;
                                }
                        }
@@ -545,7 +545,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
        frh->flags = rule->flags;
 
        if (rule->action == FR_ACT_GOTO &&
-           rcu_dereference_raw(rule->ctarget) == NULL)
+           rcu_access_pointer(rule->ctarget) == NULL)
                frh->flags |= FIB_RULE_UNRESOLVED;
 
        if (rule->iifname[0]) {
index 36f975fa87cb4975a01e4105c5cc3b0f9d905367..8fcc2d776e096164e134db9256cba2ac17dc4a92 100644 (file)
@@ -645,7 +645,7 @@ int sk_detach_filter(struct sock *sk)
        filter = rcu_dereference_protected(sk->sk_filter,
                                           sock_owned_by_user(sk));
        if (filter) {
-               rcu_assign_pointer(sk->sk_filter, NULL);
+               RCU_INIT_POINTER(sk->sk_filter, NULL);
                sk_filter_uncharge(sk, filter);
                ret = 0;
        }
index 8fab9b0bb2036784e002a4b3bb0464db059bd5ad..4002261f20d13db6e80ed331272e5bbf0f2eb8d5 100644 (file)
@@ -844,6 +844,19 @@ static void neigh_invalidate(struct neighbour *neigh)
        skb_queue_purge(&neigh->arp_queue);
 }
 
+static void neigh_probe(struct neighbour *neigh)
+       __releases(neigh->lock)
+{
+       struct sk_buff *skb = skb_peek(&neigh->arp_queue);
+       /* keep skb alive even if arp_queue overflows */
+       if (skb)
+               skb = skb_copy(skb, GFP_ATOMIC);
+       write_unlock(&neigh->lock);
+       neigh->ops->solicit(neigh, skb);
+       atomic_inc(&neigh->probes);
+       kfree_skb(skb);
+}
+
 /* Called when a timer expires for a neighbour entry. */
 
 static void neigh_timer_handler(unsigned long arg)
@@ -920,14 +933,7 @@ static void neigh_timer_handler(unsigned long arg)
                        neigh_hold(neigh);
        }
        if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
-               struct sk_buff *skb = skb_peek(&neigh->arp_queue);
-               /* keep skb alive even if arp_queue overflows */
-               if (skb)
-                       skb = skb_copy(skb, GFP_ATOMIC);
-               write_unlock(&neigh->lock);
-               neigh->ops->solicit(neigh, skb);
-               atomic_inc(&neigh->probes);
-               kfree_skb(skb);
+               neigh_probe(neigh);
        } else {
 out:
                write_unlock(&neigh->lock);
@@ -942,7 +948,7 @@ out:
 int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
        int rc;
-       unsigned long now;
+       bool immediate_probe = false;
 
        write_lock_bh(&neigh->lock);
 
@@ -950,14 +956,16 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
        if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
                goto out_unlock_bh;
 
-       now = jiffies;
-
        if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {
                if (neigh->parms->mcast_probes + neigh->parms->app_probes) {
+                       unsigned long next, now = jiffies;
+
                        atomic_set(&neigh->probes, neigh->parms->ucast_probes);
                        neigh->nud_state     = NUD_INCOMPLETE;
-                       neigh->updated = jiffies;
-                       neigh_add_timer(neigh, now + 1);
+                       neigh->updated = now;
+                       next = now + max(neigh->parms->retrans_time, HZ/2);
+                       neigh_add_timer(neigh, next);
+                       immediate_probe = true;
                } else {
                        neigh->nud_state = NUD_FAILED;
                        neigh->updated = jiffies;
@@ -989,7 +997,11 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                rc = 1;
        }
 out_unlock_bh:
-       write_unlock_bh(&neigh->lock);
+       if (immediate_probe)
+               neigh_probe(neigh);
+       else
+               write_unlock(&neigh->lock);
+       local_bh_enable();
        return rc;
 }
 EXPORT_SYMBOL(__neigh_event_send);
index 1683e5db2f27610983f042158b1aea2a071cf465..56e42ab7cbc6f292da4ae3502f0ab8da55d3a722 100644 (file)
@@ -712,13 +712,13 @@ static void rx_queue_release(struct kobject *kobj)
        struct rps_dev_flow_table *flow_table;
 
 
-       map = rcu_dereference_raw(queue->rps_map);
+       map = rcu_dereference_protected(queue->rps_map, 1);
        if (map) {
                RCU_INIT_POINTER(queue->rps_map, NULL);
                kfree_rcu(map, rcu);
        }
 
-       flow_table = rcu_dereference_raw(queue->rps_flow_table);
+       flow_table = rcu_dereference_protected(queue->rps_flow_table, 1);
        if (flow_table) {
                RCU_INIT_POINTER(queue->rps_flow_table, NULL);
                call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
@@ -987,10 +987,10 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
        }
 
        if (nonempty)
-               rcu_assign_pointer(dev->xps_maps, new_dev_maps);
+               RCU_INIT_POINTER(dev->xps_maps, new_dev_maps);
        else {
                kfree(new_dev_maps);
-               rcu_assign_pointer(dev->xps_maps, NULL);
+               RCU_INIT_POINTER(dev->xps_maps, NULL);
        }
 
        if (dev_maps)
index adf84dd8c7b5b44a215b7e79a3b3a838fe09b7d2..d676a561d983afd62db8cf917816367727ae8b16 100644 (file)
@@ -760,7 +760,7 @@ int __netpoll_setup(struct netpoll *np)
        }
 
        /* last thing to do is link it to the net device structure */
-       rcu_assign_pointer(ndev->npinfo, npinfo);
+       RCU_INIT_POINTER(ndev->npinfo, npinfo);
 
        return 0;
 
@@ -901,7 +901,7 @@ void __netpoll_cleanup(struct netpoll *np)
                if (ops->ndo_netpoll_cleanup)
                        ops->ndo_netpoll_cleanup(np->dev);
 
-               rcu_assign_pointer(np->dev->npinfo, NULL);
+               RCU_INIT_POINTER(np->dev->npinfo, NULL);
 
                /* avoid racing with NAPI reading npinfo */
                synchronize_rcu_bh();
index 99d9e953fe3953adf96cc44cf85be380b6b3ff55..39f8dd6a2821620fca1c1ba932065435da41ab6c 100644 (file)
@@ -1604,7 +1604,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
        dev_net_set(dev, net);
        dev->rtnl_link_ops = ops;
        dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
-       dev->real_num_tx_queues = real_num_queues;
 
        if (tb[IFLA_MTU])
                dev->mtu = nla_get_u32(tb[IFLA_MTU]);
index 27002dffe7ed3ea4df4f9b8d77b4210615d668c2..e27334ec367a59a7341fe3083c0764490dd8ce98 100644 (file)
@@ -529,6 +529,8 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->mac_header         = old->mac_header;
        skb_dst_copy(new, old);
        new->rxhash             = old->rxhash;
+       new->ooo_okay           = old->ooo_okay;
+       new->l4_rxhash          = old->l4_rxhash;
 #ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
 #endif
index bc745d00ea4dd31177445dcc4282afd669a33cb6..9997026b44b2caebcb36c1666e9797fa48045c74 100644 (file)
@@ -387,7 +387,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
 
        if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
                sk_tx_queue_clear(sk);
-               rcu_assign_pointer(sk->sk_dst_cache, NULL);
+               RCU_INIT_POINTER(sk->sk_dst_cache, NULL);
                dst_release(dst);
                return NULL;
        }
@@ -1158,7 +1158,7 @@ static void __sk_free(struct sock *sk)
                                       atomic_read(&sk->sk_wmem_alloc) == 0);
        if (filter) {
                sk_filter_uncharge(sk, filter);
-               rcu_assign_pointer(sk->sk_filter, NULL);
+               RCU_INIT_POINTER(sk->sk_filter, NULL);
        }
 
        sock_disable_timestamp(sk, SOCK_TIMESTAMP);
index 0462040fc818f9a624eaa73fc8428ba91ebea9b0..67164bb6ae4def6423e404286990bcdb99867388 100644 (file)
@@ -85,7 +85,6 @@ static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 
 static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
 {
-       struct dccp_sock *dp = dccp_sk(sk);
        u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->tx_cwnd, 2);
 
        /*
@@ -98,14 +97,33 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
                DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio);
                val = max_ratio;
        }
-       if (val > DCCPF_ACK_RATIO_MAX)
-               val = DCCPF_ACK_RATIO_MAX;
+       dccp_feat_signal_nn_change(sk, DCCPF_ACK_RATIO,
+                                  min_t(u32, val, DCCPF_ACK_RATIO_MAX));
+}
 
-       if (val == dp->dccps_l_ack_ratio)
-               return;
+static void ccid2_check_l_ack_ratio(struct sock *sk)
+{
+       struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
 
-       ccid2_pr_debug("changing local ack ratio to %u\n", val);
-       dp->dccps_l_ack_ratio = val;
+       /*
+        * After a loss, idle period, application limited period, or RTO we
+        * need to check that the ack ratio is still less than the congestion
+        * window. Otherwise, we will send an entire congestion window of
+        * packets and got no response because we haven't sent ack ratio
+        * packets yet.
+        * If the ack ratio does need to be reduced, we reduce it to half of
+        * the congestion window (or 1 if that's zero) instead of to the
+        * congestion window. This prevents problems if one ack is lost.
+        */
+       if (dccp_feat_nn_get(sk, DCCPF_ACK_RATIO) > hc->tx_cwnd)
+               ccid2_change_l_ack_ratio(sk, hc->tx_cwnd/2 ? : 1U);
+}
+
+static void ccid2_change_l_seq_window(struct sock *sk, u64 val)
+{
+       dccp_feat_signal_nn_change(sk, DCCPF_SEQUENCE_WINDOW,
+                                  clamp_val(val, DCCPF_SEQ_WMIN,
+                                                 DCCPF_SEQ_WMAX));
 }
 
 static void ccid2_hc_tx_rto_expire(unsigned long data)
@@ -187,6 +205,8 @@ static void ccid2_cwnd_application_limited(struct sock *sk, const u32 now)
        }
        hc->tx_cwnd_used  = 0;
        hc->tx_cwnd_stamp = now;
+
+       ccid2_check_l_ack_ratio(sk);
 }
 
 /* This borrows the code of tcp_cwnd_restart() */
@@ -205,6 +225,8 @@ static void ccid2_cwnd_restart(struct sock *sk, const u32 now)
 
        hc->tx_cwnd_stamp = now;
        hc->tx_cwnd_used  = 0;
+
+       ccid2_check_l_ack_ratio(sk);
 }
 
 static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
@@ -405,17 +427,37 @@ static void ccid2_new_ack(struct sock *sk, struct ccid2_seq *seqp,
                          unsigned int *maxincr)
 {
        struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
-
-       if (hc->tx_cwnd < hc->tx_ssthresh) {
-               if (*maxincr > 0 && ++hc->tx_packets_acked == 2) {
+       struct dccp_sock *dp = dccp_sk(sk);
+       int r_seq_used = hc->tx_cwnd / dp->dccps_l_ack_ratio;
+
+       if (hc->tx_cwnd < dp->dccps_l_seq_win &&
+           r_seq_used < dp->dccps_r_seq_win) {
+               if (hc->tx_cwnd < hc->tx_ssthresh) {
+                       if (*maxincr > 0 && ++hc->tx_packets_acked >= 2) {
+                               hc->tx_cwnd += 1;
+                               *maxincr    -= 1;
+                               hc->tx_packets_acked = 0;
+                       }
+               } else if (++hc->tx_packets_acked >= hc->tx_cwnd) {
                        hc->tx_cwnd += 1;
-                       *maxincr    -= 1;
                        hc->tx_packets_acked = 0;
                }
-       } else if (++hc->tx_packets_acked >= hc->tx_cwnd) {
-                       hc->tx_cwnd += 1;
-                       hc->tx_packets_acked = 0;
        }
+
+       /*
+        * Adjust the local sequence window and the ack ratio to allow about
+        * 5 times the number of packets in the network (RFC 4340 7.5.2)
+        */
+       if (r_seq_used * CCID2_WIN_CHANGE_FACTOR >= dp->dccps_r_seq_win)
+               ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio * 2);
+       else if (r_seq_used * CCID2_WIN_CHANGE_FACTOR < dp->dccps_r_seq_win/2)
+               ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio / 2 ? : 1U);
+
+       if (hc->tx_cwnd * CCID2_WIN_CHANGE_FACTOR >= dp->dccps_l_seq_win)
+               ccid2_change_l_seq_window(sk, dp->dccps_l_seq_win * 2);
+       else if (hc->tx_cwnd * CCID2_WIN_CHANGE_FACTOR < dp->dccps_l_seq_win/2)
+               ccid2_change_l_seq_window(sk, dp->dccps_l_seq_win / 2);
+
        /*
         * FIXME: RTT is sampled several times per acknowledgment (for each
         * entry in the Ack Vector), instead of once per Ack (as in TCP SACK).
@@ -441,9 +483,7 @@ static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
        hc->tx_cwnd      = hc->tx_cwnd / 2 ? : 1U;
        hc->tx_ssthresh  = max(hc->tx_cwnd, 2U);
 
-       /* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
-       if (dccp_sk(sk)->dccps_l_ack_ratio > hc->tx_cwnd)
-               ccid2_change_l_ack_ratio(sk, hc->tx_cwnd);
+       ccid2_check_l_ack_ratio(sk);
 }
 
 static int ccid2_hc_tx_parse_options(struct sock *sk, u8 packet_type,
@@ -494,8 +534,16 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                        if (hc->tx_rpdupack >= NUMDUPACK) {
                                hc->tx_rpdupack = -1; /* XXX lame */
                                hc->tx_rpseq    = 0;
-
+#ifdef __CCID2_COPES_GRACEFULLY_WITH_ACK_CONGESTION_CONTROL__
+                               /*
+                                * FIXME: Ack Congestion Control is broken; in
+                                * the current state instabilities occurred with
+                                * Ack Ratios greater than 1; causing hang-ups
+                                * and long RTO timeouts. This needs to be fixed
+                                * before opening up dynamic changes. -- gerrit
+                                */
                                ccid2_change_l_ack_ratio(sk, 2 * dp->dccps_l_ack_ratio);
+#endif
                        }
                }
        }
index f585d330e1e55cba3e41c80a082a4431804b0167..18c97543e522a6b9a5c8a3c817d4b40224adde48 100644 (file)
@@ -43,6 +43,12 @@ struct ccid2_seq {
 #define CCID2_SEQBUF_LEN 1024
 #define CCID2_SEQBUF_MAX 128
 
+/*
+ * Multiple of congestion window to keep the sequence window at
+ * (RFC 4340 7.5.2)
+ */
+#define CCID2_WIN_CHANGE_FACTOR 5
+
 /**
  * struct ccid2_hc_tx_sock - CCID2 TX half connection
  * @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
index 5fdb072290178a2a7b1d4b9b64fb80cbe02a465e..583490aaf56f4914f8922fcf025730678ba1030b 100644 (file)
@@ -474,6 +474,7 @@ static inline int dccp_ack_pending(const struct sock *sk)
        return dccp_ackvec_pending(sk) || inet_csk_ack_scheduled(sk);
 }
 
+extern int  dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val);
 extern int  dccp_feat_finalise_settings(struct dccp_sock *dp);
 extern int  dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq);
 extern int  dccp_feat_insert_opts(struct dccp_sock*, struct dccp_request_sock*,
index 568def9527224d662bb3928b2a4258aafd2e0cfa..23cea0ee31015d4988ce0456be919f1a24326b79 100644 (file)
@@ -12,6 +12,7 @@
  *  -----------
  *  o Feature negotiation is coordinated with connection setup (as in TCP), wild
  *    changes of parameters of an established connection are not supported.
+ *  o Changing non-negotiable (NN) values is supported in state OPEN/PARTOPEN.
  *  o All currently known SP features have 1-byte quantities. If in the future
  *    extensions of RFCs 4340..42 define features with item lengths larger than
  *    one byte, a feature-specific extension of the code will be required.
@@ -343,6 +344,20 @@ static int __dccp_feat_activate(struct sock *sk, const int idx,
        return dccp_feat_table[idx].activation_hdlr(sk, val, rx);
 }
 
+/**
+ * dccp_feat_activate  -  Activate feature value on socket
+ * @sk: fully connected DCCP socket (after handshake is complete)
+ * @feat_num: feature to activate, one of %dccp_feature_numbers
+ * @local: whether local (1) or remote (0) @feat_num is meant
+ * @fval: the value (SP or NN) to activate, or NULL to use the default value
+ * For general use this function is preferable over __dccp_feat_activate().
+ */
+static int dccp_feat_activate(struct sock *sk, u8 feat_num, bool local,
+                             dccp_feat_val const *fval)
+{
+       return __dccp_feat_activate(sk, dccp_feat_index(feat_num), local, fval);
+}
+
 /* Test for "Req'd" feature (RFC 4340, 6.4) */
 static inline int dccp_feat_must_be_understood(u8 feat_num)
 {
@@ -650,11 +665,22 @@ int dccp_feat_insert_opts(struct dccp_sock *dp, struct dccp_request_sock *dreq,
                        return -1;
                if (pos->needs_mandatory && dccp_insert_option_mandatory(skb))
                        return -1;
-               /*
-                * Enter CHANGING after transmitting the Change option (6.6.2).
-                */
-               if (pos->state == FEAT_INITIALISING)
-                       pos->state = FEAT_CHANGING;
+
+               if (skb->sk->sk_state == DCCP_OPEN &&
+                   (opt == DCCPO_CONFIRM_R || opt == DCCPO_CONFIRM_L)) {
+                       /*
+                        * Confirms don't get retransmitted (6.6.3) once the
+                        * connection is in state OPEN
+                        */
+                       dccp_feat_list_pop(pos);
+               } else {
+                       /*
+                        * Enter CHANGING after transmitting the Change
+                        * option (6.6.2).
+                        */
+                       if (pos->state == FEAT_INITIALISING)
+                               pos->state = FEAT_CHANGING;
+               }
        }
        return 0;
 }
@@ -730,6 +756,70 @@ int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
                                  0, list, len);
 }
 
+/**
+ * dccp_feat_nn_get  -  Query current/pending value of NN feature
+ * @sk: DCCP socket of an established connection
+ * @feat: NN feature number from %dccp_feature_numbers
+ * For a known NN feature, returns value currently being negotiated, or
+ * current (confirmed) value if no negotiation is going on.
+ */
+u64 dccp_feat_nn_get(struct sock *sk, u8 feat)
+{
+       if (dccp_feat_type(feat) == FEAT_NN) {
+               struct dccp_sock *dp = dccp_sk(sk);
+               struct dccp_feat_entry *entry;
+
+               entry = dccp_feat_list_lookup(&dp->dccps_featneg, feat, 1);
+               if (entry != NULL)
+                       return entry->val.nn;
+
+               switch (feat) {
+               case DCCPF_ACK_RATIO:
+                       return dp->dccps_l_ack_ratio;
+               case DCCPF_SEQUENCE_WINDOW:
+                       return dp->dccps_l_seq_win;
+               }
+       }
+       DCCP_BUG("attempt to look up unsupported feature %u", feat);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dccp_feat_nn_get);
+
+/**
+ * dccp_feat_signal_nn_change  -  Update NN values for an established connection
+ * @sk: DCCP socket of an established connection
+ * @feat: NN feature number from %dccp_feature_numbers
+ * @nn_val: the new value to use
+ * This function is used to communicate NN updates out-of-band.
+ */
+int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val)
+{
+       struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
+       dccp_feat_val fval = { .nn = nn_val };
+       struct dccp_feat_entry *entry;
+
+       if (sk->sk_state != DCCP_OPEN && sk->sk_state != DCCP_PARTOPEN)
+               return 0;
+
+       if (dccp_feat_type(feat) != FEAT_NN ||
+           !dccp_feat_is_valid_nn_val(feat, nn_val))
+               return -EINVAL;
+
+       if (nn_val == dccp_feat_nn_get(sk, feat))
+               return 0;       /* already set or negotiation under way */
+
+       entry = dccp_feat_list_lookup(fn, feat, 1);
+       if (entry != NULL) {
+               dccp_pr_debug("Clobbering existing NN entry %llu -> %llu\n",
+                             (unsigned long long)entry->val.nn,
+                             (unsigned long long)nn_val);
+               dccp_feat_list_pop(entry);
+       }
+
+       inet_csk_schedule_ack(sk);
+       return dccp_feat_push_change(fn, feat, 1, 0, &fval);
+}
+EXPORT_SYMBOL_GPL(dccp_feat_signal_nn_change);
 
 /*
  *     Tracking features whose value depend on the choice of CCID
@@ -1186,6 +1276,100 @@ confirmation_failed:
                            : DCCP_RESET_CODE_OPTION_ERROR;
 }
 
+/**
+ * dccp_feat_handle_nn_established  -  Fast-path reception of NN options
+ * @sk:                socket of an established DCCP connection
+ * @mandatory: whether @opt was preceded by a Mandatory option
+ * @opt:       %DCCPO_CHANGE_L | %DCCPO_CONFIRM_R (NN only)
+ * @feat:      NN number, one of %dccp_feature_numbers
+ * @val:       NN value
+ * @len:       length of @val in bytes
+ * This function combines the functionality of change_recv/confirm_recv, with
+ * the following differences (reset codes are the same):
+ *    - cleanup after receiving the Confirm;
+ *    - values are directly activated after successful parsing;
+ *    - deliberately restricted to NN features.
+ * The restriction to NN features is essential since SP features can have non-
+ * predictable outcomes (depending on the remote configuration), and are inter-
+ * dependent (CCIDs for instance cause further dependencies).
+ */
+static u8 dccp_feat_handle_nn_established(struct sock *sk, u8 mandatory, u8 opt,
+                                         u8 feat, u8 *val, u8 len)
+{
+       struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
+       const bool local = (opt == DCCPO_CONFIRM_R);
+       struct dccp_feat_entry *entry;
+       u8 type = dccp_feat_type(feat);
+       dccp_feat_val fval;
+
+       dccp_feat_print_opt(opt, feat, val, len, mandatory);
+
+       /* Ignore non-mandatory unknown and non-NN features */
+       if (type == FEAT_UNKNOWN) {
+               if (local && !mandatory)
+                       return 0;
+               goto fast_path_unknown;
+       } else if (type != FEAT_NN) {
+               return 0;
+       }
+
+       /*
+        * We don't accept empty Confirms, since in fast-path feature
+        * negotiation the values are enabled immediately after sending
+        * the Change option.
+        * Empty Changes on the other hand are invalid (RFC 4340, 6.1).
+        */
+       if (len == 0 || len > sizeof(fval.nn))
+               goto fast_path_unknown;
+
+       if (opt == DCCPO_CHANGE_L) {
+               fval.nn = dccp_decode_value_var(val, len);
+               if (!dccp_feat_is_valid_nn_val(feat, fval.nn))
+                       goto fast_path_unknown;
+
+               if (dccp_feat_push_confirm(fn, feat, local, &fval) ||
+                   dccp_feat_activate(sk, feat, local, &fval))
+                       return DCCP_RESET_CODE_TOO_BUSY;
+
+               /* set the `Ack Pending' flag to piggyback a Confirm */
+               inet_csk_schedule_ack(sk);
+
+       } else if (opt == DCCPO_CONFIRM_R) {
+               entry = dccp_feat_list_lookup(fn, feat, local);
+               if (entry == NULL || entry->state != FEAT_CHANGING)
+                       return 0;
+
+               fval.nn = dccp_decode_value_var(val, len);
+               /*
+                * Just ignore a value that doesn't match our current value.
+                * If the option changes twice within two RTTs, then at least
+                * one CONFIRM will be received for the old value after a
+                * new CHANGE was sent.
+                */
+               if (fval.nn != entry->val.nn)
+                       return 0;
+
+               /* Only activate after receiving the Confirm option (6.6.1). */
+               dccp_feat_activate(sk, feat, local, &fval);
+
+               /* It has been confirmed - so remove the entry */
+               dccp_feat_list_pop(entry);
+
+       } else {
+               DCCP_WARN("Received illegal option %u\n", opt);
+               goto fast_path_failed;
+       }
+       return 0;
+
+fast_path_unknown:
+       if (!mandatory)
+               return dccp_push_empty_confirm(fn, feat, local);
+
+fast_path_failed:
+       return mandatory ? DCCP_RESET_CODE_MANDATORY_ERROR
+                        : DCCP_RESET_CODE_OPTION_ERROR;
+}
+
 /**
  * dccp_feat_parse_options  -  Process Feature-Negotiation Options
  * @sk: for general use and used by the client during connection setup
@@ -1221,6 +1405,14 @@ int dccp_feat_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
                        return dccp_feat_confirm_recv(fn, mandatory, opt, feat,
                                                      val, len, server);
                }
+               break;
+       /*
+        *      Support for exchanging NN options on an established connection.
+        */
+       case DCCP_OPEN:
+       case DCCP_PARTOPEN:
+               return dccp_feat_handle_nn_established(sk, mandatory, opt, feat,
+                                                      val, len);
        }
        return 0;       /* ignore FN options in all other states */
 }
index e56a4e5e634e61a2b0239c513c021f789e00f32c..90b957d34d2602987d49175ef483af3463f9c523 100644 (file)
@@ -129,6 +129,7 @@ extern int  dccp_feat_clone_list(struct list_head const *, struct list_head *);
 
 extern void dccp_encode_value_var(const u64 value, u8 *to, const u8 len);
 extern u64  dccp_decode_value_var(const u8 *bf, const u8 len);
+extern u64  dccp_feat_nn_get(struct sock *sk, u8 feat);
 
 extern int  dccp_insert_option_mandatory(struct sk_buff *skb);
 extern int  dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat,
index 152975d942d9a59a7c26756d0f22419b9e298425..e742f90a6858879aa075a0900230abf533eb89d3 100644 (file)
@@ -184,7 +184,6 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
        dp->dccps_rate_last     = jiffies;
        dp->dccps_role          = DCCP_ROLE_UNDEFINED;
        dp->dccps_service       = DCCP_SERVICE_CODE_IS_ABSENT;
-       dp->dccps_l_ack_ratio   = dp->dccps_r_ack_ratio = 1;
        dp->dccps_tx_qlen       = sysctl_dccp_tx_qlen;
 
        dccp_init_xmit_timers(sk);
index ba4faceec405b45a43a6bff918f218a38717d7a3..2ab16e12520c525db2a84f0bb80eb4857f55f217 100644 (file)
@@ -388,7 +388,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
        }
 
        ifa->ifa_next = dn_db->ifa_list;
-       rcu_assign_pointer(dn_db->ifa_list, ifa);
+       RCU_INIT_POINTER(dn_db->ifa_list, ifa);
 
        dn_ifaddr_notify(RTM_NEWADDR, ifa);
        blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
@@ -1093,7 +1093,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
 
        memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
 
-       rcu_assign_pointer(dev->dn_ptr, dn_db);
+       RCU_INIT_POINTER(dev->dn_ptr, dn_db);
        dn_db->dev = dev;
        init_timer(&dn_db->timer);
 
@@ -1101,7 +1101,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
 
        dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table);
        if (!dn_db->neigh_parms) {
-               rcu_assign_pointer(dev->dn_ptr, NULL);
+               RCU_INIT_POINTER(dev->dn_ptr, NULL);
                kfree(dn_db);
                return NULL;
        }
index 0a47b6c37038b5f6c12a918789497a6609686fb0..56cf9b8e1c7cd46ce0a6250cdff41dfbc41728d7 100644 (file)
@@ -301,7 +301,6 @@ static const struct net_device_ops dsa_netdev_ops = {
        .ndo_start_xmit         = dsa_xmit,
        .ndo_change_rx_flags    = dsa_slave_change_rx_flags,
        .ndo_set_rx_mode        = dsa_slave_set_rx_mode,
-       .ndo_set_multicast_list = dsa_slave_set_rx_mode,
        .ndo_set_mac_address    = dsa_slave_set_mac_address,
        .ndo_do_ioctl           = dsa_slave_ioctl,
 };
@@ -314,7 +313,6 @@ static const struct net_device_ops edsa_netdev_ops = {
        .ndo_start_xmit         = edsa_xmit,
        .ndo_change_rx_flags    = dsa_slave_change_rx_flags,
        .ndo_set_rx_mode        = dsa_slave_set_rx_mode,
-       .ndo_set_multicast_list = dsa_slave_set_rx_mode,
        .ndo_set_mac_address    = dsa_slave_set_mac_address,
        .ndo_do_ioctl           = dsa_slave_ioctl,
 };
@@ -327,7 +325,6 @@ static const struct net_device_ops trailer_netdev_ops = {
        .ndo_start_xmit         = trailer_xmit,
        .ndo_change_rx_flags    = dsa_slave_change_rx_flags,
        .ndo_set_rx_mode        = dsa_slave_set_rx_mode,
-       .ndo_set_multicast_list = dsa_slave_set_rx_mode,
        .ndo_set_mac_address    = dsa_slave_set_mac_address,
        .ndo_do_ioctl           = dsa_slave_ioctl,
 };
index bc19bd06dd006f548282e25f33c7d6ef056a54ac..c6b5092f29a15511bb7c69f37a86dca2c538a164 100644 (file)
@@ -258,7 +258,7 @@ static struct in_device *inetdev_init(struct net_device *dev)
                ip_mc_up(in_dev);
 
        /* we can receive as soon as ip_ptr is set -- do this last */
-       rcu_assign_pointer(dev->ip_ptr, in_dev);
+       RCU_INIT_POINTER(dev->ip_ptr, in_dev);
 out:
        return in_dev;
 out_kfree:
@@ -291,7 +291,7 @@ static void inetdev_destroy(struct in_device *in_dev)
                inet_free_ifa(ifa);
        }
 
-       rcu_assign_pointer(dev->ip_ptr, NULL);
+       RCU_INIT_POINTER(dev->ip_ptr, NULL);
 
        devinet_sysctl_unregister(in_dev);
        neigh_parms_release(&arp_tbl, in_dev->arp_parms);
@@ -1175,7 +1175,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
        switch (event) {
        case NETDEV_REGISTER:
                printk(KERN_DEBUG "inetdev_event: bug\n");
-               rcu_assign_pointer(dev->ip_ptr, NULL);
+               RCU_INIT_POINTER(dev->ip_ptr, NULL);
                break;
        case NETDEV_UP:
                if (!inetdev_valid_mtu(dev->mtu))
index de9e2978476f18a2377699b7e7aba8484368928f..89d6f71a6a99faeec6c93a3ab0f5e48dad5e0e0e 100644 (file)
@@ -204,7 +204,7 @@ static inline struct tnode *node_parent_rcu(const struct rt_trie_node *node)
        return (struct tnode *)(parent & ~NODE_TYPE_MASK);
 }
 
-/* Same as rcu_assign_pointer
+/* Same as RCU_INIT_POINTER
  * but that macro() assumes that value is a pointer.
  */
 static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr)
@@ -528,7 +528,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *
        if (n)
                node_set_parent(n, tn);
 
-       rcu_assign_pointer(tn->child[i], n);
+       RCU_INIT_POINTER(tn->child[i], n);
 }
 
 #define MAX_WORK 10
@@ -1014,7 +1014,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn)
 
                tp = node_parent((struct rt_trie_node *) tn);
                if (!tp)
-                       rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
+                       RCU_INIT_POINTER(t->trie, (struct rt_trie_node *)tn);
 
                tnode_free_flush();
                if (!tp)
@@ -1026,7 +1026,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn)
        if (IS_TNODE(tn))
                tn = (struct tnode *)resize(t, (struct tnode *)tn);
 
-       rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
+       RCU_INIT_POINTER(t->trie, (struct rt_trie_node *)tn);
        tnode_free_flush();
 }
 
@@ -1163,7 +1163,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
                        put_child(t, (struct tnode *)tp, cindex,
                                  (struct rt_trie_node *)tn);
                } else {
-                       rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
+                       RCU_INIT_POINTER(t->trie, (struct rt_trie_node *)tn);
                        tp = tn;
                }
        }
@@ -1621,7 +1621,7 @@ static void trie_leaf_remove(struct trie *t, struct leaf *l)
                put_child(t, (struct tnode *)tp, cindex, NULL);
                trie_rebalance(t, tp);
        } else
-               rcu_assign_pointer(t->trie, NULL);
+               RCU_INIT_POINTER(t->trie, NULL);
 
        free_leaf(l);
 }
index dbfc21de3479a3299a795b4bb58abb1eaae53ef3..8cb1ebb7cd7462b2b70c447b56d1693562b8027a 100644 (file)
@@ -34,7 +34,7 @@ int gre_add_protocol(const struct gre_protocol *proto, u8 version)
        if (gre_proto[version])
                goto err_out_unlock;
 
-       rcu_assign_pointer(gre_proto[version], proto);
+       RCU_INIT_POINTER(gre_proto[version], proto);
        spin_unlock(&gre_proto_lock);
        return 0;
 
@@ -54,7 +54,7 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version)
        if (rcu_dereference_protected(gre_proto[version],
                        lockdep_is_held(&gre_proto_lock)) != proto)
                goto err_out_unlock;
-       rcu_assign_pointer(gre_proto[version], NULL);
+       RCU_INIT_POINTER(gre_proto[version], NULL);
        spin_unlock(&gre_proto_lock);
        synchronize_rcu();
        return 0;
index 283c0a26e03f9ba2e3e0532638b6810fb4f7f349..ce57bdee14cb62b9584882a8a5af7aeb756f93bf 100644 (file)
@@ -1009,7 +1009,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
 
        /* Checking for IFF_MULTICAST here is WRONG-WRONG-WRONG.
           We will get multicast token leakage, when IFF_MULTICAST
-          is changed. This check should be done in dev->set_multicast_list
+          is changed. This check should be done in ndo_set_rx_mode
           routine. Something sort of:
           if (dev->mc_list && dev->flags&IFF_MULTICAST) { do it; }
           --ANK
@@ -1242,7 +1242,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
 
        im->next_rcu = in_dev->mc_list;
        in_dev->mc_count++;
-       rcu_assign_pointer(in_dev->mc_list, im);
+       RCU_INIT_POINTER(in_dev->mc_list, im);
 
 #ifdef CONFIG_IP_MULTICAST
        igmpv3_del_delrec(in_dev, im->multiaddr);
@@ -1813,7 +1813,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
        iml->next_rcu = inet->mc_list;
        iml->sflist = NULL;
        iml->sfmode = MCAST_EXCLUDE;
-       rcu_assign_pointer(inet->mc_list, iml);
+       RCU_INIT_POINTER(inet->mc_list, iml);
        ip_mc_inc_group(in_dev, addr);
        err = 0;
 done:
@@ -1835,7 +1835,7 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
        }
        err = ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,
                        iml->sfmode, psf->sl_count, psf->sl_addr, 0);
-       rcu_assign_pointer(iml->sflist, NULL);
+       RCU_INIT_POINTER(iml->sflist, NULL);
        /* decrease mem now to avoid the memleak warning */
        atomic_sub(IP_SFLSIZE(psf->sl_max), &sk->sk_omem_alloc);
        kfree_rcu(psf, rcu);
@@ -2000,7 +2000,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
                        atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
                        kfree_rcu(psl, rcu);
                }
-               rcu_assign_pointer(pmc->sflist, newpsl);
+               RCU_INIT_POINTER(pmc->sflist, newpsl);
                psl = newpsl;
        }
        rv = 1; /* > 0 for insert logic below if sl_count is 0 */
@@ -2103,7 +2103,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
        } else
                (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
                        0, NULL, 0);
-       rcu_assign_pointer(pmc->sflist, newpsl);
+       RCU_INIT_POINTER(pmc->sflist, newpsl);
        pmc->sfmode = msf->imsf_fmode;
        err = 0;
 done:
index 378b20b7ca6e7401c9c4041635606b5a2526ccb6..065effd8349a81689828927c84142a778aebb650 100644 (file)
@@ -231,7 +231,7 @@ static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t)
             (iter = rtnl_dereference(*tp)) != NULL;
             tp = &iter->next) {
                if (t == iter) {
-                       rcu_assign_pointer(*tp, t->next);
+                       RCU_INIT_POINTER(*tp, t->next);
                        break;
                }
        }
@@ -241,8 +241,8 @@ static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t)
 {
        struct ip_tunnel __rcu **tp = ipip_bucket(ipn, t);
 
-       rcu_assign_pointer(t->next, rtnl_dereference(*tp));
-       rcu_assign_pointer(*tp, t);
+       RCU_INIT_POINTER(t->next, rtnl_dereference(*tp));
+       RCU_INIT_POINTER(*tp, t);
 }
 
 static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
@@ -301,7 +301,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
        struct ipip_net *ipn = net_generic(net, ipip_net_id);
 
        if (dev == ipn->fb_tunnel_dev)
-               rcu_assign_pointer(ipn->tunnels_wc[0], NULL);
+               RCU_INIT_POINTER(ipn->tunnels_wc[0], NULL);
        else
                ipip_tunnel_unlink(ipn, netdev_priv(dev));
        dev_put(dev);
@@ -791,7 +791,7 @@ static int __net_init ipip_fb_tunnel_init(struct net_device *dev)
                return -ENOMEM;
 
        dev_hold(dev);
-       rcu_assign_pointer(ipn->tunnels_wc[0], tunnel);
+       RCU_INIT_POINTER(ipn->tunnels_wc[0], tunnel);
        return 0;
 }
 
index 58e87915797651ae14cf9634a40b5d9382b42720..6164e982e0ef3da61c91863523ab277d1e52668a 100644 (file)
@@ -1176,7 +1176,7 @@ static void mrtsock_destruct(struct sock *sk)
        ipmr_for_each_table(mrt, net) {
                if (sk == rtnl_dereference(mrt->mroute_sk)) {
                        IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
-                       rcu_assign_pointer(mrt->mroute_sk, NULL);
+                       RCU_INIT_POINTER(mrt->mroute_sk, NULL);
                        mroute_clean_tables(mrt);
                }
        }
@@ -1203,7 +1203,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
                return -ENOENT;
 
        if (optname != MRT_INIT) {
-               if (sk != rcu_dereference_raw(mrt->mroute_sk) &&
+               if (sk != rcu_access_pointer(mrt->mroute_sk) &&
                    !capable(CAP_NET_ADMIN))
                        return -EACCES;
        }
@@ -1224,13 +1224,13 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
 
                ret = ip_ra_control(sk, 1, mrtsock_destruct);
                if (ret == 0) {
-                       rcu_assign_pointer(mrt->mroute_sk, sk);
+                       RCU_INIT_POINTER(mrt->mroute_sk, sk);
                        IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
                }
                rtnl_unlock();
                return ret;
        case MRT_DONE:
-               if (sk != rcu_dereference_raw(mrt->mroute_sk))
+               if (sk != rcu_access_pointer(mrt->mroute_sk))
                        return -EACCES;
                return ip_ra_control(sk, 0, NULL);
        case MRT_ADD_VIF:
index 703f366fd2358a3dd32c813700511ffb5129f351..7b22382ff0e99c9f37dd32fed4545a0258cc88d6 100644 (file)
@@ -70,14 +70,14 @@ static unsigned int help(struct sk_buff *skb,
 
 static void __exit nf_nat_amanda_fini(void)
 {
-       rcu_assign_pointer(nf_nat_amanda_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_amanda_hook, NULL);
        synchronize_rcu();
 }
 
 static int __init nf_nat_amanda_init(void)
 {
        BUG_ON(nf_nat_amanda_hook != NULL);
-       rcu_assign_pointer(nf_nat_amanda_hook, help);
+       RCU_INIT_POINTER(nf_nat_amanda_hook, help);
        return 0;
 }
 
index 3346de5d94d009ffe3466ce61f1103d5f66a5ca2..447bc5cfdc6c83703215db60a9ea631ef46774c8 100644 (file)
@@ -514,7 +514,7 @@ int nf_nat_protocol_register(const struct nf_nat_protocol *proto)
                ret = -EBUSY;
                goto out;
        }
-       rcu_assign_pointer(nf_nat_protos[proto->protonum], proto);
+       RCU_INIT_POINTER(nf_nat_protos[proto->protonum], proto);
  out:
        spin_unlock_bh(&nf_nat_lock);
        return ret;
@@ -525,7 +525,7 @@ EXPORT_SYMBOL(nf_nat_protocol_register);
 void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
 {
        spin_lock_bh(&nf_nat_lock);
-       rcu_assign_pointer(nf_nat_protos[proto->protonum],
+       RCU_INIT_POINTER(nf_nat_protos[proto->protonum],
                           &nf_nat_unknown_protocol);
        spin_unlock_bh(&nf_nat_lock);
        synchronize_rcu();
@@ -736,10 +736,10 @@ static int __init nf_nat_init(void)
        /* Sew in builtin protocols. */
        spin_lock_bh(&nf_nat_lock);
        for (i = 0; i < MAX_IP_NAT_PROTO; i++)
-               rcu_assign_pointer(nf_nat_protos[i], &nf_nat_unknown_protocol);
-       rcu_assign_pointer(nf_nat_protos[IPPROTO_TCP], &nf_nat_protocol_tcp);
-       rcu_assign_pointer(nf_nat_protos[IPPROTO_UDP], &nf_nat_protocol_udp);
-       rcu_assign_pointer(nf_nat_protos[IPPROTO_ICMP], &nf_nat_protocol_icmp);
+               RCU_INIT_POINTER(nf_nat_protos[i], &nf_nat_unknown_protocol);
+       RCU_INIT_POINTER(nf_nat_protos[IPPROTO_TCP], &nf_nat_protocol_tcp);
+       RCU_INIT_POINTER(nf_nat_protos[IPPROTO_UDP], &nf_nat_protocol_udp);
+       RCU_INIT_POINTER(nf_nat_protos[IPPROTO_ICMP], &nf_nat_protocol_icmp);
        spin_unlock_bh(&nf_nat_lock);
 
        /* Initialize fake conntrack so that NAT will skip it */
@@ -748,12 +748,12 @@ static int __init nf_nat_init(void)
        l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
 
        BUG_ON(nf_nat_seq_adjust_hook != NULL);
-       rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
+       RCU_INIT_POINTER(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
        BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
-       rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
+       RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook,
                           nfnetlink_parse_nat_setup);
        BUG_ON(nf_ct_nat_offset != NULL);
-       rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset);
+       RCU_INIT_POINTER(nf_ct_nat_offset, nf_nat_get_offset);
        return 0;
 
  cleanup_extend:
@@ -766,9 +766,9 @@ static void __exit nf_nat_cleanup(void)
        unregister_pernet_subsys(&nf_nat_net_ops);
        nf_ct_l3proto_put(l3proto);
        nf_ct_extend_unregister(&nat_extend);
-       rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
-       rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
-       rcu_assign_pointer(nf_ct_nat_offset, NULL);
+       RCU_INIT_POINTER(nf_nat_seq_adjust_hook, NULL);
+       RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL);
+       RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
        synchronize_net();
 }
 
index dc73abb3fe27ecea0537ab8fa2a5e029435fb783..e462a957d0805c324fa3db0bdd8d8a317b629f59 100644 (file)
@@ -113,14 +113,14 @@ out:
 
 static void __exit nf_nat_ftp_fini(void)
 {
-       rcu_assign_pointer(nf_nat_ftp_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_ftp_hook, NULL);
        synchronize_rcu();
 }
 
 static int __init nf_nat_ftp_init(void)
 {
        BUG_ON(nf_nat_ftp_hook != NULL);
-       rcu_assign_pointer(nf_nat_ftp_hook, nf_nat_ftp);
+       RCU_INIT_POINTER(nf_nat_ftp_hook, nf_nat_ftp);
        return 0;
 }
 
index 790f3160e0121c19ed5f2bef07388656ae7310a6..b9a1136addbdbca5bf6f95d10bcb789e2cb4036d 100644 (file)
@@ -581,30 +581,30 @@ static int __init init(void)
        BUG_ON(nat_callforwarding_hook != NULL);
        BUG_ON(nat_q931_hook != NULL);
 
-       rcu_assign_pointer(set_h245_addr_hook, set_h245_addr);
-       rcu_assign_pointer(set_h225_addr_hook, set_h225_addr);
-       rcu_assign_pointer(set_sig_addr_hook, set_sig_addr);
-       rcu_assign_pointer(set_ras_addr_hook, set_ras_addr);
-       rcu_assign_pointer(nat_rtp_rtcp_hook, nat_rtp_rtcp);
-       rcu_assign_pointer(nat_t120_hook, nat_t120);
-       rcu_assign_pointer(nat_h245_hook, nat_h245);
-       rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding);
-       rcu_assign_pointer(nat_q931_hook, nat_q931);
+       RCU_INIT_POINTER(set_h245_addr_hook, set_h245_addr);
+       RCU_INIT_POINTER(set_h225_addr_hook, set_h225_addr);
+       RCU_INIT_POINTER(set_sig_addr_hook, set_sig_addr);
+       RCU_INIT_POINTER(set_ras_addr_hook, set_ras_addr);
+       RCU_INIT_POINTER(nat_rtp_rtcp_hook, nat_rtp_rtcp);
+       RCU_INIT_POINTER(nat_t120_hook, nat_t120);
+       RCU_INIT_POINTER(nat_h245_hook, nat_h245);
+       RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding);
+       RCU_INIT_POINTER(nat_q931_hook, nat_q931);
        return 0;
 }
 
 /****************************************************************************/
 static void __exit fini(void)
 {
-       rcu_assign_pointer(set_h245_addr_hook, NULL);
-       rcu_assign_pointer(set_h225_addr_hook, NULL);
-       rcu_assign_pointer(set_sig_addr_hook, NULL);
-       rcu_assign_pointer(set_ras_addr_hook, NULL);
-       rcu_assign_pointer(nat_rtp_rtcp_hook, NULL);
-       rcu_assign_pointer(nat_t120_hook, NULL);
-       rcu_assign_pointer(nat_h245_hook, NULL);
-       rcu_assign_pointer(nat_callforwarding_hook, NULL);
-       rcu_assign_pointer(nat_q931_hook, NULL);
+       RCU_INIT_POINTER(set_h245_addr_hook, NULL);
+       RCU_INIT_POINTER(set_h225_addr_hook, NULL);
+       RCU_INIT_POINTER(set_sig_addr_hook, NULL);
+       RCU_INIT_POINTER(set_ras_addr_hook, NULL);
+       RCU_INIT_POINTER(nat_rtp_rtcp_hook, NULL);
+       RCU_INIT_POINTER(nat_t120_hook, NULL);
+       RCU_INIT_POINTER(nat_h245_hook, NULL);
+       RCU_INIT_POINTER(nat_callforwarding_hook, NULL);
+       RCU_INIT_POINTER(nat_q931_hook, NULL);
        synchronize_rcu();
 }
 
index 535e1a80235688480bb9b58d2492291183e7703a..979ae165f4eff97f98bddb7659c70a9b70156d13 100644 (file)
@@ -75,14 +75,14 @@ static unsigned int help(struct sk_buff *skb,
 
 static void __exit nf_nat_irc_fini(void)
 {
-       rcu_assign_pointer(nf_nat_irc_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_irc_hook, NULL);
        synchronize_rcu();
 }
 
 static int __init nf_nat_irc_init(void)
 {
        BUG_ON(nf_nat_irc_hook != NULL);
-       rcu_assign_pointer(nf_nat_irc_hook, help);
+       RCU_INIT_POINTER(nf_nat_irc_hook, help);
        return 0;
 }
 
index 4c060038d29fd5811b259dbf70204d51cef41339..3e8284ba46b8eb6274f7aa84f2b314142e31b837 100644 (file)
@@ -282,25 +282,25 @@ static int __init nf_nat_helper_pptp_init(void)
        nf_nat_need_gre();
 
        BUG_ON(nf_nat_pptp_hook_outbound != NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_outbound, pptp_outbound_pkt);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_outbound, pptp_outbound_pkt);
 
        BUG_ON(nf_nat_pptp_hook_inbound != NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_inbound, pptp_inbound_pkt);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_inbound, pptp_inbound_pkt);
 
        BUG_ON(nf_nat_pptp_hook_exp_gre != NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_exp_gre, pptp_exp_gre);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_exp_gre, pptp_exp_gre);
 
        BUG_ON(nf_nat_pptp_hook_expectfn != NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_expectfn, pptp_nat_expected);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_expectfn, pptp_nat_expected);
        return 0;
 }
 
 static void __exit nf_nat_helper_pptp_fini(void)
 {
-       rcu_assign_pointer(nf_nat_pptp_hook_expectfn, NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_exp_gre, NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_inbound, NULL);
-       rcu_assign_pointer(nf_nat_pptp_hook_outbound, NULL);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_expectfn, NULL);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_exp_gre, NULL);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_inbound, NULL);
+       RCU_INIT_POINTER(nf_nat_pptp_hook_outbound, NULL);
        synchronize_rcu();
 }
 
index e40cf7816fdbb4e0088efd200a46cbd3a9041ed2..78844d9208f161d209f161af7d1509a691995dd1 100644 (file)
@@ -528,13 +528,13 @@ err1:
 
 static void __exit nf_nat_sip_fini(void)
 {
-       rcu_assign_pointer(nf_nat_sip_hook, NULL);
-       rcu_assign_pointer(nf_nat_sip_seq_adjust_hook, NULL);
-       rcu_assign_pointer(nf_nat_sip_expect_hook, NULL);
-       rcu_assign_pointer(nf_nat_sdp_addr_hook, NULL);
-       rcu_assign_pointer(nf_nat_sdp_port_hook, NULL);
-       rcu_assign_pointer(nf_nat_sdp_session_hook, NULL);
-       rcu_assign_pointer(nf_nat_sdp_media_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sip_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sip_expect_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sdp_addr_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
        synchronize_rcu();
 }
 
@@ -547,13 +547,13 @@ static int __init nf_nat_sip_init(void)
        BUG_ON(nf_nat_sdp_port_hook != NULL);
        BUG_ON(nf_nat_sdp_session_hook != NULL);
        BUG_ON(nf_nat_sdp_media_hook != NULL);
-       rcu_assign_pointer(nf_nat_sip_hook, ip_nat_sip);
-       rcu_assign_pointer(nf_nat_sip_seq_adjust_hook, ip_nat_sip_seq_adjust);
-       rcu_assign_pointer(nf_nat_sip_expect_hook, ip_nat_sip_expect);
-       rcu_assign_pointer(nf_nat_sdp_addr_hook, ip_nat_sdp_addr);
-       rcu_assign_pointer(nf_nat_sdp_port_hook, ip_nat_sdp_port);
-       rcu_assign_pointer(nf_nat_sdp_session_hook, ip_nat_sdp_session);
-       rcu_assign_pointer(nf_nat_sdp_media_hook, ip_nat_sdp_media);
+       RCU_INIT_POINTER(nf_nat_sip_hook, ip_nat_sip);
+       RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, ip_nat_sip_seq_adjust);
+       RCU_INIT_POINTER(nf_nat_sip_expect_hook, ip_nat_sip_expect);
+       RCU_INIT_POINTER(nf_nat_sdp_addr_hook, ip_nat_sdp_addr);
+       RCU_INIT_POINTER(nf_nat_sdp_port_hook, ip_nat_sdp_port);
+       RCU_INIT_POINTER(nf_nat_sdp_session_hook, ip_nat_sdp_session);
+       RCU_INIT_POINTER(nf_nat_sdp_media_hook, ip_nat_sdp_media);
        return 0;
 }
 
index 076b7c8c4aa4b608b5a65bdd4ea9b14994b3899f..d1cb412c18e02665db35e95021f29ecae38bf35c 100644 (file)
@@ -1310,7 +1310,7 @@ static int __init nf_nat_snmp_basic_init(void)
        int ret = 0;
 
        BUG_ON(nf_nat_snmp_hook != NULL);
-       rcu_assign_pointer(nf_nat_snmp_hook, help);
+       RCU_INIT_POINTER(nf_nat_snmp_hook, help);
 
        ret = nf_conntrack_helper_register(&snmp_trap_helper);
        if (ret < 0) {
@@ -1322,7 +1322,7 @@ static int __init nf_nat_snmp_basic_init(void)
 
 static void __exit nf_nat_snmp_basic_fini(void)
 {
-       rcu_assign_pointer(nf_nat_snmp_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
        nf_conntrack_helper_unregister(&snmp_trap_helper);
 }
 
index a6e606e8482071f143f82c18d42eee9a57bc68d3..92900482edea3c469168bcdeed43e9a8eb58dc54 100644 (file)
@@ -284,7 +284,7 @@ static int __init nf_nat_standalone_init(void)
 
 #ifdef CONFIG_XFRM
        BUG_ON(ip_nat_decode_session != NULL);
-       rcu_assign_pointer(ip_nat_decode_session, nat_decode_session);
+       RCU_INIT_POINTER(ip_nat_decode_session, nat_decode_session);
 #endif
        ret = nf_nat_rule_init();
        if (ret < 0) {
@@ -302,7 +302,7 @@ static int __init nf_nat_standalone_init(void)
        nf_nat_rule_cleanup();
  cleanup_decode_session:
 #ifdef CONFIG_XFRM
-       rcu_assign_pointer(ip_nat_decode_session, NULL);
+       RCU_INIT_POINTER(ip_nat_decode_session, NULL);
        synchronize_net();
 #endif
        return ret;
@@ -313,7 +313,7 @@ static void __exit nf_nat_standalone_fini(void)
        nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
        nf_nat_rule_cleanup();
 #ifdef CONFIG_XFRM
-       rcu_assign_pointer(ip_nat_decode_session, NULL);
+       RCU_INIT_POINTER(ip_nat_decode_session, NULL);
        synchronize_net();
 #endif
        /* Conntrack caches are unregistered in nf_conntrack_cleanup */
index 7274a43c7a12f08210d09a14bb677450f598e246..a2901bf829c09165ef9bc56b6627e6d2511d66ee 100644 (file)
@@ -36,14 +36,14 @@ static unsigned int help(struct sk_buff *skb,
 
 static void __exit nf_nat_tftp_fini(void)
 {
-       rcu_assign_pointer(nf_nat_tftp_hook, NULL);
+       RCU_INIT_POINTER(nf_nat_tftp_hook, NULL);
        synchronize_rcu();
 }
 
 static int __init nf_nat_tftp_init(void)
 {
        BUG_ON(nf_nat_tftp_hook != NULL);
-       rcu_assign_pointer(nf_nat_tftp_hook, help);
+       RCU_INIT_POINTER(nf_nat_tftp_hook, help);
        return 0;
 }
 
index 075212e41b839347dcaa04caca43ee49a914f88e..2c21d3be891bb9ee13f9d33c1e60084aaa0f783c 100644 (file)
@@ -324,7 +324,7 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
        struct rtable *r = NULL;
 
        for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
-               if (!rcu_dereference_raw(rt_hash_table[st->bucket].chain))
+               if (!rcu_access_pointer(rt_hash_table[st->bucket].chain))
                        continue;
                rcu_read_lock_bh();
                r = rcu_dereference_bh(rt_hash_table[st->bucket].chain);
@@ -350,7 +350,7 @@ static struct rtable *__rt_cache_get_next(struct seq_file *seq,
                do {
                        if (--st->bucket < 0)
                                return NULL;
-               } while (!rcu_dereference_raw(rt_hash_table[st->bucket].chain));
+               } while (!rcu_access_pointer(rt_hash_table[st->bucket].chain));
                rcu_read_lock_bh();
                r = rcu_dereference_bh(rt_hash_table[st->bucket].chain);
        }
@@ -761,7 +761,7 @@ static void rt_do_flush(struct net *net, int process_context)
 
                if (process_context && need_resched())
                        cond_resched();
-               rth = rcu_dereference_raw(rt_hash_table[i].chain);
+               rth = rcu_access_pointer(rt_hash_table[i].chain);
                if (!rth)
                        continue;
 
index 1c12b8ec849dcff6b5363338a42ce00e06d9246a..b3f26114b03e6f2c59f014dbbe965c05367275ab 100644 (file)
@@ -1578,7 +1578,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 #endif
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
                        rsk = sk;
                        goto reset;
@@ -1595,7 +1595,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
                        goto discard;
 
                if (nsk != sk) {
-                       sock_rps_save_rxhash(nsk, skb->rxhash);
+                       sock_rps_save_rxhash(nsk, skb);
                        if (tcp_child_process(sk, nsk, skb)) {
                                rsk = nsk;
                                goto reset;
@@ -1603,7 +1603,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
                        return 0;
                }
        } else
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
 
        if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
                rsk = sk;
index 1b5a19340a95ac073ab374776408c81cce9e9c4c..ebaa96bd346475dd550baadc9e32dd7a4e5d8ef6 100644 (file)
@@ -1267,7 +1267,7 @@ int udp_disconnect(struct sock *sk, int flags)
        sk->sk_state = TCP_CLOSE;
        inet->inet_daddr = 0;
        inet->inet_dport = 0;
-       sock_rps_save_rxhash(sk, 0);
+       sock_rps_reset_rxhash(sk);
        sk->sk_bound_dev_if = 0;
        if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
                inet_reset_saddr(sk);
@@ -1355,7 +1355,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        int rc;
 
        if (inet_sk(sk)->inet_daddr)
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
 
        rc = ip_queue_rcv_skb(sk, skb);
        if (rc < 0) {
@@ -1461,10 +1461,9 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
                }
        }
 
-       if (rcu_dereference_raw(sk->sk_filter)) {
-               if (udp_lib_checksum_complete(skb))
-                       goto drop;
-       }
+       if (rcu_access_pointer(sk->sk_filter) &&
+           udp_lib_checksum_complete(skb))
+               goto drop;
 
 
        if (sk_rcvqueues_full(sk, skb))
index f012ebd87b4338181f76d3154165eb1f41cd0ba4..8f1e5be26d912ed7f93d43cd763b2fe6de8c9a40 100644 (file)
@@ -428,7 +428,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
        ndev->tstamp = jiffies;
        addrconf_sysctl_register(ndev);
        /* protected by rtnl_lock */
-       rcu_assign_pointer(dev->ip6_ptr, ndev);
+       RCU_INIT_POINTER(dev->ip6_ptr, ndev);
 
        /* Join all-node multicast group */
        ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes);
@@ -824,12 +824,13 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
 {
        struct inet6_dev *idev = ifp->idev;
        struct in6_addr addr, *tmpaddr;
-       unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age;
+       unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_tstamp, age;
        unsigned long regen_advance;
        int tmp_plen;
        int ret = 0;
        int max_addresses;
        u32 addr_flags;
+       unsigned long now = jiffies;
 
        write_lock(&idev->lock);
        if (ift) {
@@ -874,7 +875,7 @@ retry:
                goto out;
        }
        memcpy(&addr.s6_addr[8], idev->rndid, 8);
-       age = (jiffies - ifp->tstamp) / HZ;
+       age = (now - ifp->tstamp) / HZ;
        tmp_valid_lft = min_t(__u32,
                              ifp->valid_lft,
                              idev->cnf.temp_valid_lft + age);
@@ -884,7 +885,6 @@ retry:
                                 idev->cnf.max_desync_factor);
        tmp_plen = ifp->prefix_len;
        max_addresses = idev->cnf.max_addresses;
-       tmp_cstamp = ifp->cstamp;
        tmp_tstamp = ifp->tstamp;
        spin_unlock_bh(&ifp->lock);
 
@@ -929,7 +929,7 @@ retry:
        ift->ifpub = ifp;
        ift->valid_lft = tmp_valid_lft;
        ift->prefered_lft = tmp_prefered_lft;
-       ift->cstamp = tmp_cstamp;
+       ift->cstamp = now;
        ift->tstamp = tmp_tstamp;
        spin_unlock_bh(&ift->lock);
 
@@ -1999,25 +1999,50 @@ ok:
 #ifdef CONFIG_IPV6_PRIVACY
                        read_lock_bh(&in6_dev->lock);
                        /* update all temporary addresses in the list */
-                       list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) {
-                               /*
-                                * When adjusting the lifetimes of an existing
-                                * temporary address, only lower the lifetimes.
-                                * Implementations must not increase the
-                                * lifetimes of an existing temporary address
-                                * when processing a Prefix Information Option.
-                                */
+                       list_for_each_entry(ift, &in6_dev->tempaddr_list,
+                                           tmp_list) {
+                               int age, max_valid, max_prefered;
+
                                if (ifp != ift->ifpub)
                                        continue;
 
+                               /*
+                                * RFC 4941 section 3.3:
+                                * If a received option will extend the lifetime
+                                * of a public address, the lifetimes of
+                                * temporary addresses should be extended,
+                                * subject to the overall constraint that no
+                                * temporary addresses should ever remain
+                                * "valid" or "preferred" for a time longer than
+                                * (TEMP_VALID_LIFETIME) or
+                                * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR),
+                                * respectively.
+                                */
+                               age = (now - ift->cstamp) / HZ;
+                               max_valid = in6_dev->cnf.temp_valid_lft - age;
+                               if (max_valid < 0)
+                                       max_valid = 0;
+
+                               max_prefered = in6_dev->cnf.temp_prefered_lft -
+                                              in6_dev->cnf.max_desync_factor -
+                                              age;
+                               if (max_prefered < 0)
+                                       max_prefered = 0;
+
+                               if (valid_lft > max_valid)
+                                       valid_lft = max_valid;
+
+                               if (prefered_lft > max_prefered)
+                                       prefered_lft = max_prefered;
+
                                spin_lock(&ift->lock);
                                flags = ift->flags;
-                               if (ift->valid_lft > valid_lft &&
-                                   ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ)
-                                       ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ;
-                               if (ift->prefered_lft > prefered_lft &&
-                                   ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ)
-                                       ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ;
+                               ift->valid_lft = valid_lft;
+                               ift->prefered_lft = prefered_lft;
+                               ift->tstamp = now;
+                               if (prefered_lft > 0)
+                                       ift->flags &= ~IFA_F_DEPRECATED;
+
                                spin_unlock(&ift->lock);
                                if (!(flags&IFA_F_TENTATIVE))
                                        ipv6_ifa_notify(0, ift);
@@ -2025,9 +2050,11 @@ ok:
 
                        if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) {
                                /*
-                                * When a new public address is created as described in [ADDRCONF],
-                                * also create a new temporary address. Also create a temporary
-                                * address if it's enabled but no temporary address currently exists.
+                                * When a new public address is created as
+                                * described in [ADDRCONF], also create a new
+                                * temporary address. Also create a temporary
+                                * address if it's enabled but no temporary
+                                * address currently exists.
                                 */
                                read_unlock_bh(&in6_dev->lock);
                                ipv6_create_tempaddr(ifp, NULL);
@@ -2706,7 +2733,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
                idev->dead = 1;
 
                /* protected by rtnl_lock */
-               rcu_assign_pointer(dev->ip6_ptr, NULL);
+               RCU_INIT_POINTER(dev->ip6_ptr, NULL);
 
                /* Step 1.5: remove snmp6 entry */
                snmp6_unregister_dev(idev);
index 79a485e8a700c75b1ff13da4af82daced2e329eb..1318de4c3e8df2a418a828b4d249da7f68b9f76d 100644 (file)
@@ -273,12 +273,12 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        __u16 dstbuf;
 #endif
-       struct dst_entry *dst;
+       struct dst_entry *dst = skb_dst(skb);
 
        if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
            !pskb_may_pull(skb, (skb_transport_offset(skb) +
                                 ((skb_transport_header(skb)[1] + 1) << 3)))) {
-               IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
+               IP6_INC_STATS_BH(dev_net(dst->dev), ip6_dst_idev(dst),
                                 IPSTATS_MIB_INHDRERRORS);
                kfree_skb(skb);
                return -1;
@@ -289,9 +289,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
        dstbuf = opt->dst1;
 #endif
 
-       dst = dst_clone(skb_dst(skb));
        if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
-               dst_release(dst);
                skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
                opt = IP6CB(skb);
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
@@ -304,7 +302,6 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
 
        IP6_INC_STATS_BH(dev_net(dst->dev),
                         ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
-       dst_release(dst);
        return -1;
 }
 
index 11900417b1cc0daea102552858a07a1efb179e67..2b59154c65d3127f065803b209a584cd81651783 100644 (file)
@@ -490,7 +490,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
                goto out_dst_release;
        }
 
-       idev = in6_dev_get(skb->dev);
+       rcu_read_lock();
+       idev = __in6_dev_get(skb->dev);
 
        err = ip6_append_data(sk, icmpv6_getfrag, &msg,
                              len + sizeof(struct icmp6hdr),
@@ -500,19 +501,16 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
        if (err) {
                ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
                ip6_flush_pending_frames(sk);
-               goto out_put;
+       } else {
+               err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
+                                                len + sizeof(struct icmp6hdr));
        }
-       err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr));
-
-out_put:
-       if (likely(idev != NULL))
-               in6_dev_put(idev);
+       rcu_read_unlock();
 out_dst_release:
        dst_release(dst);
 out:
        icmpv6_xmit_unlock(sk);
 }
-
 EXPORT_SYMBOL(icmpv6_send);
 
 static void icmpv6_echo_reply(struct sk_buff *skb)
@@ -569,7 +567,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        if (hlimit < 0)
                hlimit = ip6_dst_hoplimit(dst);
 
-       idev = in6_dev_get(skb->dev);
+       idev = __in6_dev_get(skb->dev);
 
        msg.skb = skb;
        msg.offset = 0;
@@ -583,13 +581,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        if (err) {
                ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
                ip6_flush_pending_frames(sk);
-               goto out_put;
+       } else {
+               err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
+                                                skb->len + sizeof(struct icmp6hdr));
        }
-       err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
-
-out_put:
-       if (likely(idev != NULL))
-               in6_dev_put(idev);
        dst_release(dst);
 out:
        icmpv6_xmit_unlock(sk);
index 8a58e8cf6646b2bbe886bde46cdb72c7b548822a..2916200f90c1d21541e43012c5346929831b89c9 100644 (file)
@@ -211,6 +211,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
        struct flowi6 fl6;
        struct dst_entry *dst;
        struct in6_addr *final_p, final;
+       int res;
 
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_proto = sk->sk_protocol;
@@ -241,12 +242,14 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
                __inet6_csk_dst_store(sk, dst, NULL, NULL);
        }
 
-       skb_dst_set(skb, dst_clone(dst));
+       rcu_read_lock();
+       skb_dst_set_noref(skb, dst);
 
        /* Restore final destination back after routing done */
        ipv6_addr_copy(&fl6.daddr, &np->daddr);
 
-       return ip6_xmit(sk, skb, &fl6, np->opt);
+       res = ip6_xmit(sk, skb, &fl6, np->opt);
+       rcu_read_unlock();
+       return res;
 }
-
 EXPORT_SYMBOL_GPL(inet6_csk_xmit);
index 0bc98886c383c93c79e81a3cd7c4bfe220502b58..694d70a8a0eef34074b31bc926a4956b4d5f2a31 100644 (file)
@@ -218,8 +218,8 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
 {
        struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms);
 
-       rcu_assign_pointer(t->next , rtnl_dereference(*tp));
-       rcu_assign_pointer(*tp, t);
+       RCU_INIT_POINTER(t->next , rtnl_dereference(*tp));
+       RCU_INIT_POINTER(*tp, t);
 }
 
 /**
@@ -237,7 +237,7 @@ ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
             (iter = rtnl_dereference(*tp)) != NULL;
             tp = &iter->next) {
                if (t == iter) {
-                       rcu_assign_pointer(*tp, t->next);
+                       RCU_INIT_POINTER(*tp, t->next);
                        break;
                }
        }
@@ -350,7 +350,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
        if (dev == ip6n->fb_tnl_dev)
-               rcu_assign_pointer(ip6n->tnls_wc[0], NULL);
+               RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
        else
                ip6_tnl_unlink(ip6n, t);
        ip6_tnl_dst_reset(t);
@@ -889,7 +889,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        struct net_device_stats *stats = &t->dev->stats;
        struct ipv6hdr *ipv6h = ipv6_hdr(skb);
        struct ipv6_tel_txoption opt;
-       struct dst_entry *dst;
+       struct dst_entry *dst, *ndst = NULL;
        struct net_device *tdev;
        int mtu;
        unsigned int max_headroom = sizeof(struct ipv6hdr);
@@ -897,19 +897,19 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        int err = -1;
        int pkt_len;
 
-       if ((dst = ip6_tnl_dst_check(t)) != NULL)
-               dst_hold(dst);
-       else {
-               dst = ip6_route_output(net, NULL, fl6);
+       dst = ip6_tnl_dst_check(t);
+       if (!dst) {
+               ndst = ip6_route_output(net, NULL, fl6);
 
-               if (dst->error)
+               if (ndst->error)
                        goto tx_err_link_failure;
-               dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0);
-               if (IS_ERR(dst)) {
-                       err = PTR_ERR(dst);
-                       dst = NULL;
+               ndst = xfrm_lookup(net, ndst, flowi6_to_flowi(fl6), NULL, 0);
+               if (IS_ERR(ndst)) {
+                       err = PTR_ERR(ndst);
+                       ndst = NULL;
                        goto tx_err_link_failure;
                }
+               dst = ndst;
        }
 
        tdev = dst->dev;
@@ -955,7 +955,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
                skb = new_skb;
        }
        skb_dst_drop(skb);
-       skb_dst_set(skb, dst_clone(dst));
+       skb_dst_set_noref(skb, dst);
 
        skb->transport_header = skb->network_header;
 
@@ -987,13 +987,14 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
                stats->tx_errors++;
                stats->tx_aborted_errors++;
        }
-       ip6_tnl_dst_store(t, dst);
+       if (ndst)
+               ip6_tnl_dst_store(t, ndst);
        return 0;
 tx_err_link_failure:
        stats->tx_carrier_errors++;
        dst_link_failure(skb);
 tx_err_dst_release:
-       dst_release(dst);
+       dst_release(ndst);
        return err;
 }
 
@@ -1439,7 +1440,7 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
 
        t->parms.proto = IPPROTO_IPV6;
        dev_hold(dev);
-       rcu_assign_pointer(ip6n->tnls_wc[0], t);
+       RCU_INIT_POINTER(ip6n->tnls_wc[0], t);
        return 0;
 }
 
index 9cb191ecaba8e7992834242364c745287157c317..147ede38ab484e7447516c0499900a592b235a15 100644 (file)
@@ -913,7 +913,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
 }
 
 static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
-                   char __user *optval, int __user *optlen)
+                   char __user *optval, int __user *optlen, unsigned flags)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        int len;
@@ -962,7 +962,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 
                msg.msg_control = optval;
                msg.msg_controllen = len;
-               msg.msg_flags = 0;
+               msg.msg_flags = flags;
 
                lock_sock(sk);
                skb = np->pktoptions;
@@ -1222,7 +1222,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
        if(level != SOL_IPV6)
                return -ENOPROTOOPT;
 
-       err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
+       err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0);
 #ifdef CONFIG_NETFILTER
        /* we need to exclude all possible ENOPROTOOPTs except default case */
        if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
@@ -1264,7 +1264,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
                return compat_mc_getsockopt(sk, level, optname, optval, optlen,
                        ipv6_getsockopt);
 
-       err = do_ipv6_getsockopt(sk, level, optname, optval, optlen);
+       err = do_ipv6_getsockopt(sk, level, optname, optval, optlen,
+                                MSG_CMSG_COMPAT);
 #ifdef CONFIG_NETFILTER
        /* we need to exclude all possible ENOPROTOOPTs except default case */
        if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) {
index 9da6e02eaaebffdb47949ff0c0fbf43dc1b9a208..1f52dd2576312bd33e242d445eb5510f993f529d 100644 (file)
@@ -533,7 +533,8 @@ void ndisc_send_skb(struct sk_buff *skb,
 
        skb_dst_set(skb, dst);
 
-       idev = in6_dev_get(dst->dev);
+       rcu_read_lock();
+       idev = __in6_dev_get(dst->dev);
        IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
        err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
@@ -543,8 +544,7 @@ void ndisc_send_skb(struct sk_buff *skb,
                ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
        }
 
-       if (likely(idev != NULL))
-               in6_dev_put(idev);
+       rcu_read_unlock();
 }
 
 EXPORT_SYMBOL(ndisc_send_skb);
@@ -1039,7 +1039,7 @@ static void ndisc_recv_rs(struct sk_buff *skb)
        if (skb->len < sizeof(*rs_msg))
                return;
 
-       idev = in6_dev_get(skb->dev);
+       idev = __in6_dev_get(skb->dev);
        if (!idev) {
                if (net_ratelimit())
                        ND_PRINTK1("ICMP6 RS: can't find in6 device\n");
@@ -1080,7 +1080,7 @@ static void ndisc_recv_rs(struct sk_buff *skb)
                neigh_release(neigh);
        }
 out:
-       in6_dev_put(idev);
+       return;
 }
 
 static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
@@ -1179,7 +1179,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
         *      set the RA_RECV flag in the interface
         */
 
-       in6_dev = in6_dev_get(skb->dev);
+       in6_dev = __in6_dev_get(skb->dev);
        if (in6_dev == NULL) {
                ND_PRINTK0(KERN_ERR
                           "ICMPv6 RA: can't find inet6 device for %s.\n",
@@ -1188,7 +1188,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
        }
 
        if (!ndisc_parse_options(opt, optlen, &ndopts)) {
-               in6_dev_put(in6_dev);
                ND_PRINTK2(KERN_WARNING
                           "ICMP6 RA: invalid ND options\n");
                return;
@@ -1255,7 +1254,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
                        ND_PRINTK0(KERN_ERR
                                   "ICMPv6 RA: %s() failed to add default route.\n",
                                   __func__);
-                       in6_dev_put(in6_dev);
                        return;
                }
 
@@ -1265,7 +1263,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
                                   "ICMPv6 RA: %s() got default router without neighbour.\n",
                                   __func__);
                        dst_release(&rt->dst);
-                       in6_dev_put(in6_dev);
                        return;
                }
                neigh->flags |= NTF_ROUTER;
@@ -1422,7 +1419,6 @@ out:
                dst_release(&rt->dst);
        else if (neigh)
                neigh_release(neigh);
-       in6_dev_put(in6_dev);
 }
 
 static void ndisc_redirect_rcv(struct sk_buff *skb)
@@ -1481,13 +1477,11 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
                return;
        }
 
-       in6_dev = in6_dev_get(skb->dev);
+       in6_dev = __in6_dev_get(skb->dev);
        if (!in6_dev)
                return;
-       if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects) {
-               in6_dev_put(in6_dev);
+       if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects)
                return;
-       }
 
        /* RFC2461 8.1:
         *      The IP source address of the Redirect MUST be the same as the current
@@ -1497,7 +1491,6 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
        if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
                ND_PRINTK2(KERN_WARNING
                           "ICMPv6 Redirect: invalid ND options\n");
-               in6_dev_put(in6_dev);
                return;
        }
        if (ndopts.nd_opts_tgt_lladdr) {
@@ -1506,7 +1499,6 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
                if (!lladdr) {
                        ND_PRINTK2(KERN_WARNING
                                   "ICMPv6 Redirect: invalid link-layer address length\n");
-                       in6_dev_put(in6_dev);
                        return;
                }
        }
@@ -1518,7 +1510,6 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
                             on_link);
                neigh_release(neigh);
        }
-       in6_dev_put(in6_dev);
 }
 
 void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
@@ -1651,7 +1642,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                                             csum_partial(icmph, len, 0));
 
        skb_dst_set(buff, dst);
-       idev = in6_dev_get(dst->dev);
+       rcu_read_lock();
+       idev = __in6_dev_get(dst->dev);
        IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
        err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
                      dst_output);
@@ -1660,8 +1652,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
        }
 
-       if (likely(idev != NULL))
-               in6_dev_put(idev);
+       rcu_read_unlock();
        return;
 
 release:
index 6a79f3081bdb1b7922b4e36d472afbc46efb5361..f34902f1ba33956ef0413580519f203026a07213 100644 (file)
@@ -130,14 +130,14 @@ static mh_filter_t __rcu *mh_filter __read_mostly;
 
 int rawv6_mh_filter_register(mh_filter_t filter)
 {
-       rcu_assign_pointer(mh_filter, filter);
+       RCU_INIT_POINTER(mh_filter, filter);
        return 0;
 }
 EXPORT_SYMBOL(rawv6_mh_filter_register);
 
 int rawv6_mh_filter_unregister(mh_filter_t filter)
 {
-       rcu_assign_pointer(mh_filter, NULL);
+       RCU_INIT_POINTER(mh_filter, NULL);
        synchronize_rcu();
        return 0;
 }
@@ -372,9 +372,9 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
        read_unlock(&raw_v6_hashinfo.lock);
 }
 
-static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
+static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
-       if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) &&
+       if ((raw6_sk(sk)->checksum || rcu_access_pointer(sk->sk_filter)) &&
            skb_checksum_complete(skb)) {
                atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
index 07bf1085458f24ee1b8f9487c150158dd587675f..a7a18602a046e1ffe5f0f00883844459802f4a25 100644 (file)
@@ -182,7 +182,7 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
             (iter = rtnl_dereference(*tp)) != NULL;
             tp = &iter->next) {
                if (t == iter) {
-                       rcu_assign_pointer(*tp, t->next);
+                       RCU_INIT_POINTER(*tp, t->next);
                        break;
                }
        }
@@ -192,8 +192,8 @@ static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
 {
        struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t);
 
-       rcu_assign_pointer(t->next, rtnl_dereference(*tp));
-       rcu_assign_pointer(*tp, t);
+       RCU_INIT_POINTER(t->next, rtnl_dereference(*tp));
+       RCU_INIT_POINTER(*tp, t);
 }
 
 static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
@@ -391,7 +391,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
        p->addr = a->addr;
        p->flags = a->flags;
        t->prl_count++;
-       rcu_assign_pointer(t->prl, p);
+       RCU_INIT_POINTER(t->prl, p);
 out:
        return err;
 }
@@ -474,7 +474,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
        struct sit_net *sitn = net_generic(net, sit_net_id);
 
        if (dev == sitn->fb_tunnel_dev) {
-               rcu_assign_pointer(sitn->tunnels_wc[0], NULL);
+               RCU_INIT_POINTER(sitn->tunnels_wc[0], NULL);
        } else {
                ipip6_tunnel_unlink(sitn, netdev_priv(dev));
                ipip6_tunnel_del_prl(netdev_priv(dev), NULL);
@@ -672,6 +672,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
        if (skb->protocol != htons(ETH_P_IPV6))
                goto tx_error;
 
+       if (tos == 1)
+               tos = ipv6_get_dsfield(iph6);
+
        /* ISATAP (RFC4214) - must come before 6to4 */
        if (dev->priv_flags & IFF_ISATAP) {
                struct neighbour *neigh = NULL;
@@ -1173,7 +1176,7 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
        if (!dev->tstats)
                return -ENOMEM;
        dev_hold(dev);
-       rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
+       RCU_INIT_POINTER(sitn->tunnels_wc[0], tunnel);
        return 0;
 }
 
index d1fb63f4aeb76351bd55d8c6bfa8cf0e8e20c60f..44a5859535b5512c841959688c2e71a6298ca6b7 100644 (file)
@@ -1628,7 +1628,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
                opt_skb = skb_clone(skb, GFP_ATOMIC);
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
                        goto reset;
                if (opt_skb)
@@ -1650,7 +1650,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
                 * the new socket..
                 */
                if(nsk != sk) {
-                       sock_rps_save_rxhash(nsk, skb->rxhash);
+                       sock_rps_save_rxhash(nsk, skb);
                        if (tcp_child_process(sk, nsk, skb))
                                goto reset;
                        if (opt_skb)
@@ -1658,7 +1658,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
                        return 0;
                }
        } else
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
 
        if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len))
                goto reset;
index 29213b51c4998e09a79f60fd534015269da54570..35bbdc42241e5ee249be4a096eac2051f5caedcd 100644 (file)
@@ -509,7 +509,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        int is_udplite = IS_UDPLITE(sk);
 
        if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
-               sock_rps_save_rxhash(sk, skb->rxhash);
+               sock_rps_save_rxhash(sk, skb);
 
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
                goto drop;
@@ -533,7 +533,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                }
        }
 
-       if (rcu_dereference_raw(sk->sk_filter)) {
+       if (rcu_access_pointer(sk->sk_filter)) {
                if (udp_lib_checksum_complete(skb))
                        goto drop;
        }
index e8d5f4405d687fbbedfcfab78c9da213084b5059..d14152e866d9d8bdb96adaad512a4f6ff78907ed 100644 (file)
@@ -50,7 +50,7 @@ static const struct net_device_ops irlan_eth_netdev_ops = {
        .ndo_open               = irlan_eth_open,
        .ndo_stop               = irlan_eth_close,
        .ndo_start_xmit         = irlan_eth_xmit,
-       .ndo_set_multicast_list = irlan_eth_set_multicast_list,
+       .ndo_set_rx_mode        = irlan_eth_set_multicast_list,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
 };
index 16ce9cd4f39e53fb34a6c5935aaafb5bd5fbe392..497fbe732defd6504c8e7a4ce2a023553b35e7f0 100644 (file)
@@ -1,15 +1,17 @@
 config IUCV
-       tristate "IUCV support (S390 - z/VM only)"
        depends on S390
+       def_tristate y if S390
+       prompt "IUCV support (S390 - z/VM only)"
        help
          Select this option if you want to use inter-user communication
          under VM or VIF. If you run on z/VM, say "Y" to enable a fast
          communication link between VM guests.
 
 config AFIUCV
-       tristate "AF_IUCV support (S390 - z/VM only)"
-       depends on IUCV
+       depends on S390
+       def_tristate m if QETH_L3 || IUCV
+       prompt "AF_IUCV Socket support (S390 - z/VM and HiperSockets transport)"
        help
-         Select this option if you want to use inter-user communication under
-         VM or VIF sockets. If you run on z/VM, say "Y" to enable a fast
-         communication link between VM guests.
+         Select this option if you want to use AF_IUCV socket applications
+         based on z/VM inter-user communication vehicle or based on
+         HiperSockets.
index e2013e434d03a5758ae2c269b7beafa3987c1c8f..c39f3a43cd80992df62f393928020207e6676f8c 100644 (file)
 #include <asm/cpcmd.h>
 #include <linux/kmod.h>
 
-#include <net/iucv/iucv.h>
 #include <net/iucv/af_iucv.h>
 
-#define VERSION "1.1"
+#define VERSION "1.2"
 
 static char iucv_userid[80];
 
@@ -42,6 +41,8 @@ static struct proto iucv_proto = {
        .obj_size       = sizeof(struct iucv_sock),
 };
 
+static struct iucv_interface *pr_iucv;
+
 /* special AF_IUCV IPRM messages */
 static const u8 iprm_shutdown[8] =
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
@@ -90,6 +91,12 @@ do {                                                                 \
 static void iucv_sock_kill(struct sock *sk);
 static void iucv_sock_close(struct sock *sk);
 
+static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+       struct packet_type *pt, struct net_device *orig_dev);
+static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
+                  struct sk_buff *skb, u8 flags);
+static void afiucv_hs_callback_txnotify(struct sk_buff *, enum iucv_tx_notify);
+
 /* Call Back functions */
 static void iucv_callback_rx(struct iucv_path *, struct iucv_message *);
 static void iucv_callback_txdone(struct iucv_path *, struct iucv_message *);
@@ -165,7 +172,7 @@ static int afiucv_pm_freeze(struct device *dev)
                case IUCV_CLOSING:
                case IUCV_CONNECTED:
                        if (iucv->path) {
-                               err = iucv_path_sever(iucv->path, NULL);
+                               err = pr_iucv->path_sever(iucv->path, NULL);
                                iucv_path_free(iucv->path);
                                iucv->path = NULL;
                        }
@@ -229,7 +236,7 @@ static const struct dev_pm_ops afiucv_pm_ops = {
 static struct device_driver af_iucv_driver = {
        .owner = THIS_MODULE,
        .name = "afiucv",
-       .bus  = &iucv_bus,
+       .bus  = NULL,
        .pm   = &afiucv_pm_ops,
 };
 
@@ -294,7 +301,11 @@ static inline int iucv_below_msglim(struct sock *sk)
 
        if (sk->sk_state != IUCV_CONNECTED)
                return 1;
-       return (skb_queue_len(&iucv->send_skb_q) < iucv->path->msglim);
+       if (iucv->transport == AF_IUCV_TRANS_IUCV)
+               return (skb_queue_len(&iucv->send_skb_q) < iucv->path->msglim);
+       else
+               return ((atomic_read(&iucv->msg_sent) < iucv->msglimit_peer) &&
+                       (atomic_read(&iucv->pendings) <= 0));
 }
 
 /**
@@ -312,6 +323,79 @@ static void iucv_sock_wake_msglim(struct sock *sk)
        rcu_read_unlock();
 }
 
+/**
+ * afiucv_hs_send() - send a message through HiperSockets transport
+ */
+static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
+                  struct sk_buff *skb, u8 flags)
+{
+       struct net *net = sock_net(sock);
+       struct iucv_sock *iucv = iucv_sk(sock);
+       struct af_iucv_trans_hdr *phs_hdr;
+       struct sk_buff *nskb;
+       int err, confirm_recv = 0;
+
+       memset(skb->head, 0, ETH_HLEN);
+       phs_hdr = (struct af_iucv_trans_hdr *)skb_push(skb,
+                                       sizeof(struct af_iucv_trans_hdr));
+       skb_reset_mac_header(skb);
+       skb_reset_network_header(skb);
+       skb_push(skb, ETH_HLEN);
+       skb_reset_mac_header(skb);
+       memset(phs_hdr, 0, sizeof(struct af_iucv_trans_hdr));
+
+       phs_hdr->magic = ETH_P_AF_IUCV;
+       phs_hdr->version = 1;
+       phs_hdr->flags = flags;
+       if (flags == AF_IUCV_FLAG_SYN)
+               phs_hdr->window = iucv->msglimit;
+       else if ((flags == AF_IUCV_FLAG_WIN) || !flags) {
+               confirm_recv = atomic_read(&iucv->msg_recv);
+               phs_hdr->window = confirm_recv;
+               if (confirm_recv)
+                       phs_hdr->flags = phs_hdr->flags | AF_IUCV_FLAG_WIN;
+       }
+       memcpy(phs_hdr->destUserID, iucv->dst_user_id, 8);
+       memcpy(phs_hdr->destAppName, iucv->dst_name, 8);
+       memcpy(phs_hdr->srcUserID, iucv->src_user_id, 8);
+       memcpy(phs_hdr->srcAppName, iucv->src_name, 8);
+       ASCEBC(phs_hdr->destUserID, sizeof(phs_hdr->destUserID));
+       ASCEBC(phs_hdr->destAppName, sizeof(phs_hdr->destAppName));
+       ASCEBC(phs_hdr->srcUserID, sizeof(phs_hdr->srcUserID));
+       ASCEBC(phs_hdr->srcAppName, sizeof(phs_hdr->srcAppName));
+       if (imsg)
+               memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message));
+
+       rcu_read_lock();
+       skb->dev = dev_get_by_index_rcu(net, sock->sk_bound_dev_if);
+       rcu_read_unlock();
+       if (!skb->dev)
+               return -ENODEV;
+       if (!(skb->dev->flags & IFF_UP))
+               return -ENETDOWN;
+       if (skb->len > skb->dev->mtu) {
+               if (sock->sk_type == SOCK_SEQPACKET)
+                       return -EMSGSIZE;
+               else
+                       skb_trim(skb, skb->dev->mtu);
+       }
+       skb->protocol = ETH_P_AF_IUCV;
+       skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF;
+       nskb = skb_clone(skb, GFP_ATOMIC);
+       if (!nskb)
+               return -ENOMEM;
+       skb_queue_tail(&iucv->send_skb_q, nskb);
+       err = dev_queue_xmit(skb);
+       if (err) {
+               skb_unlink(nskb, &iucv->send_skb_q);
+               kfree_skb(nskb);
+       } else {
+               atomic_sub(confirm_recv, &iucv->msg_recv);
+               WARN_ON(atomic_read(&iucv->msg_recv) < 0);
+       }
+       return err;
+}
+
 /* Timers */
 static void iucv_sock_timeout(unsigned long arg)
 {
@@ -380,6 +464,8 @@ static void iucv_sock_close(struct sock *sk)
        unsigned char user_data[16];
        struct iucv_sock *iucv = iucv_sk(sk);
        unsigned long timeo;
+       int err, blen;
+       struct sk_buff *skb;
 
        iucv_sock_clear_timer(sk);
        lock_sock(sk);
@@ -390,6 +476,20 @@ static void iucv_sock_close(struct sock *sk)
                break;
 
        case IUCV_CONNECTED:
+               if (iucv->transport == AF_IUCV_TRANS_HIPER) {
+                       /* send fin */
+                       blen = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
+                       skb = sock_alloc_send_skb(sk, blen, 1, &err);
+                       if (skb) {
+                               skb_reserve(skb,
+                                       sizeof(struct af_iucv_trans_hdr) +
+                                       ETH_HLEN);
+                               err = afiucv_hs_send(NULL, sk, skb,
+                                                    AF_IUCV_FLAG_FIN);
+                       }
+                       sk->sk_state = IUCV_DISCONN;
+                       sk->sk_state_change(sk);
+               }
        case IUCV_DISCONN:
                sk->sk_state = IUCV_CLOSING;
                sk->sk_state_change(sk);
@@ -412,7 +512,7 @@ static void iucv_sock_close(struct sock *sk)
                        low_nmcpy(user_data, iucv->src_name);
                        high_nmcpy(user_data, iucv->dst_name);
                        ASCEBC(user_data, sizeof(user_data));
-                       iucv_path_sever(iucv->path, user_data);
+                       pr_iucv->path_sever(iucv->path, user_data);
                        iucv_path_free(iucv->path);
                        iucv->path = NULL;
                }
@@ -444,23 +544,33 @@ static void iucv_sock_init(struct sock *sk, struct sock *parent)
 static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
 {
        struct sock *sk;
+       struct iucv_sock *iucv;
 
        sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto);
        if (!sk)
                return NULL;
+       iucv = iucv_sk(sk);
 
        sock_init_data(sock, sk);
-       INIT_LIST_HEAD(&iucv_sk(sk)->accept_q);
-       spin_lock_init(&iucv_sk(sk)->accept_q_lock);
-       skb_queue_head_init(&iucv_sk(sk)->send_skb_q);
-       INIT_LIST_HEAD(&iucv_sk(sk)->message_q.list);
-       spin_lock_init(&iucv_sk(sk)->message_q.lock);
-       skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q);
-       iucv_sk(sk)->send_tag = 0;
-       iucv_sk(sk)->flags = 0;
-       iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT;
-       iucv_sk(sk)->path = NULL;
-       memset(&iucv_sk(sk)->src_user_id , 0, 32);
+       INIT_LIST_HEAD(&iucv->accept_q);
+       spin_lock_init(&iucv->accept_q_lock);
+       skb_queue_head_init(&iucv->send_skb_q);
+       INIT_LIST_HEAD(&iucv->message_q.list);
+       spin_lock_init(&iucv->message_q.lock);
+       skb_queue_head_init(&iucv->backlog_skb_q);
+       iucv->send_tag = 0;
+       atomic_set(&iucv->pendings, 0);
+       iucv->flags = 0;
+       iucv->msglimit = 0;
+       atomic_set(&iucv->msg_sent, 0);
+       atomic_set(&iucv->msg_recv, 0);
+       iucv->path = NULL;
+       iucv->sk_txnotify = afiucv_hs_callback_txnotify;
+       memset(&iucv->src_user_id , 0, 32);
+       if (pr_iucv)
+               iucv->transport = AF_IUCV_TRANS_IUCV;
+       else
+               iucv->transport = AF_IUCV_TRANS_HIPER;
 
        sk->sk_destruct = iucv_sock_destruct;
        sk->sk_sndtimeo = IUCV_CONN_TIMEOUT;
@@ -591,7 +701,9 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
        struct sockaddr_iucv *sa = (struct sockaddr_iucv *) addr;
        struct sock *sk = sock->sk;
        struct iucv_sock *iucv;
-       int err;
+       int err = 0;
+       struct net_device *dev;
+       char uid[9];
 
        /* Verify the input sockaddr */
        if (!addr || addr->sa_family != AF_IUCV)
@@ -610,19 +722,46 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
                err = -EADDRINUSE;
                goto done_unlock;
        }
-       if (iucv->path) {
-               err = 0;
+       if (iucv->path)
                goto done_unlock;
-       }
 
        /* Bind the socket */
-       memcpy(iucv->src_name, sa->siucv_name, 8);
 
-       /* Copy the user id */
-       memcpy(iucv->src_user_id, iucv_userid, 8);
-       sk->sk_state = IUCV_BOUND;
-       err = 0;
+       if (pr_iucv)
+               if (!memcmp(sa->siucv_user_id, iucv_userid, 8))
+                       goto vm_bind; /* VM IUCV transport */
 
+       /* try hiper transport */
+       memcpy(uid, sa->siucv_user_id, sizeof(uid));
+       ASCEBC(uid, 8);
+       rcu_read_lock();
+       for_each_netdev_rcu(&init_net, dev) {
+               if (!memcmp(dev->perm_addr, uid, 8)) {
+                       memcpy(iucv->src_name, sa->siucv_name, 8);
+                       memcpy(iucv->src_user_id, sa->siucv_user_id, 8);
+                       sock->sk->sk_bound_dev_if = dev->ifindex;
+                       sk->sk_state = IUCV_BOUND;
+                       iucv->transport = AF_IUCV_TRANS_HIPER;
+                       if (!iucv->msglimit)
+                               iucv->msglimit = IUCV_HIPER_MSGLIM_DEFAULT;
+                       rcu_read_unlock();
+                       goto done_unlock;
+               }
+       }
+       rcu_read_unlock();
+vm_bind:
+       if (pr_iucv) {
+               /* use local userid for backward compat */
+               memcpy(iucv->src_name, sa->siucv_name, 8);
+               memcpy(iucv->src_user_id, iucv_userid, 8);
+               sk->sk_state = IUCV_BOUND;
+               iucv->transport = AF_IUCV_TRANS_IUCV;
+               if (!iucv->msglimit)
+                       iucv->msglimit = IUCV_QUEUELEN_DEFAULT;
+               goto done_unlock;
+       }
+       /* found no dev to bind */
+       err = -ENODEV;
 done_unlock:
        /* Release the socket list lock */
        write_unlock_bh(&iucv_sk_list.lock);
@@ -658,45 +797,44 @@ static int iucv_sock_autobind(struct sock *sk)
 
        memcpy(&iucv->src_name, name, 8);
 
+       if (!iucv->msglimit)
+               iucv->msglimit = IUCV_QUEUELEN_DEFAULT;
+
        return err;
 }
 
-/* Connect an unconnected socket */
-static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
-                            int alen, int flags)
+static int afiucv_hs_connect(struct socket *sock)
 {
-       struct sockaddr_iucv *sa = (struct sockaddr_iucv *) addr;
        struct sock *sk = sock->sk;
-       struct iucv_sock *iucv;
-       unsigned char user_data[16];
-       int err;
-
-       if (addr->sa_family != AF_IUCV || alen < sizeof(struct sockaddr_iucv))
-               return -EINVAL;
-
-       if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND)
-               return -EBADFD;
-
-       if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET)
-               return -EINVAL;
+       struct sk_buff *skb;
+       int blen = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN;
+       int err = 0;
 
-       if (sk->sk_state == IUCV_OPEN) {
-               err = iucv_sock_autobind(sk);
-               if (unlikely(err))
-                       return err;
+       /* send syn */
+       skb = sock_alloc_send_skb(sk, blen, 1, &err);
+       if (!skb) {
+               err = -ENOMEM;
+               goto done;
        }
+       skb->dev = NULL;
+       skb_reserve(skb, blen);
+       err = afiucv_hs_send(NULL, sk, skb, AF_IUCV_FLAG_SYN);
+done:
+       return err;
+}
 
-       lock_sock(sk);
-
-       /* Set the destination information */
-       memcpy(iucv_sk(sk)->dst_user_id, sa->siucv_user_id, 8);
-       memcpy(iucv_sk(sk)->dst_name, sa->siucv_name, 8);
+static int afiucv_path_connect(struct socket *sock, struct sockaddr *addr)
+{
+       struct sockaddr_iucv *sa = (struct sockaddr_iucv *) addr;
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned char user_data[16];
+       int err;
 
        high_nmcpy(user_data, sa->siucv_name);
-       low_nmcpy(user_data, iucv_sk(sk)->src_name);
+       low_nmcpy(user_data, iucv->src_name);
        ASCEBC(user_data, sizeof(user_data));
 
-       iucv = iucv_sk(sk);
        /* Create path. */
        iucv->path = iucv_path_alloc(iucv->msglimit,
                                     IUCV_IPRMDATA, GFP_KERNEL);
@@ -704,8 +842,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
                err = -ENOMEM;
                goto done;
        }
-       err = iucv_path_connect(iucv->path, &af_iucv_handler,
-                               sa->siucv_user_id, NULL, user_data, sk);
+       err = pr_iucv->path_connect(iucv->path, &af_iucv_handler,
+                                   sa->siucv_user_id, NULL, user_data,
+                                   sk);
        if (err) {
                iucv_path_free(iucv->path);
                iucv->path = NULL;
@@ -724,21 +863,62 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
                        err = -ECONNREFUSED;
                        break;
                }
-               goto done;
        }
+done:
+       return err;
+}
 
-       if (sk->sk_state != IUCV_CONNECTED) {
+/* Connect an unconnected socket */
+static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
+                            int alen, int flags)
+{
+       struct sockaddr_iucv *sa = (struct sockaddr_iucv *) addr;
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       int err;
+
+       if (addr->sa_family != AF_IUCV || alen < sizeof(struct sockaddr_iucv))
+               return -EINVAL;
+
+       if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND)
+               return -EBADFD;
+
+       if (sk->sk_state == IUCV_OPEN &&
+           iucv->transport == AF_IUCV_TRANS_HIPER)
+               return -EBADFD; /* explicit bind required */
+
+       if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET)
+               return -EINVAL;
+
+       if (sk->sk_state == IUCV_OPEN) {
+               err = iucv_sock_autobind(sk);
+               if (unlikely(err))
+                       return err;
+       }
+
+       lock_sock(sk);
+
+       /* Set the destination information */
+       memcpy(iucv->dst_user_id, sa->siucv_user_id, 8);
+       memcpy(iucv->dst_name, sa->siucv_name, 8);
+
+       if (iucv->transport == AF_IUCV_TRANS_HIPER)
+               err = afiucv_hs_connect(sock);
+       else
+               err = afiucv_path_connect(sock, addr);
+       if (err)
+               goto done;
+
+       if (sk->sk_state != IUCV_CONNECTED)
                err = iucv_sock_wait(sk, iucv_sock_in_state(sk, IUCV_CONNECTED,
                                                            IUCV_DISCONN),
                                     sock_sndtimeo(sk, flags & O_NONBLOCK));
-       }
 
-       if (sk->sk_state == IUCV_DISCONN) {
+       if (sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_CLOSED)
                err = -ECONNREFUSED;
-       }
 
-       if (err) {
-               iucv_path_sever(iucv->path, NULL);
+       if (err && iucv->transport == AF_IUCV_TRANS_IUCV) {
+               pr_iucv->path_sever(iucv->path, NULL);
                iucv_path_free(iucv->path);
                iucv->path = NULL;
        }
@@ -833,20 +1013,21 @@ static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
 {
        struct sockaddr_iucv *siucv = (struct sockaddr_iucv *) addr;
        struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
 
        addr->sa_family = AF_IUCV;
        *len = sizeof(struct sockaddr_iucv);
 
        if (peer) {
-               memcpy(siucv->siucv_user_id, iucv_sk(sk)->dst_user_id, 8);
-               memcpy(siucv->siucv_name, &iucv_sk(sk)->dst_name, 8);
+               memcpy(siucv->siucv_user_id, iucv->dst_user_id, 8);
+               memcpy(siucv->siucv_name, iucv->dst_name, 8);
        } else {
-               memcpy(siucv->siucv_user_id, iucv_sk(sk)->src_user_id, 8);
-               memcpy(siucv->siucv_name, iucv_sk(sk)->src_name, 8);
+               memcpy(siucv->siucv_user_id, iucv->src_user_id, 8);
+               memcpy(siucv->siucv_name, iucv->src_name, 8);
        }
        memset(&siucv->siucv_port, 0, sizeof(siucv->siucv_port));
        memset(&siucv->siucv_addr, 0, sizeof(siucv->siucv_addr));
-       memset(siucv->siucv_nodeid, 0, sizeof(siucv->siucv_nodeid));
+       memset(&siucv->siucv_nodeid, 0, sizeof(siucv->siucv_nodeid));
 
        return 0;
 }
@@ -871,7 +1052,7 @@ static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg,
 
        memcpy(prmdata, (void *) skb->data, skb->len);
        prmdata[7] = 0xff - (u8) skb->len;
-       return iucv_message_send(path, msg, IUCV_IPRMDATA, 0,
+       return pr_iucv->message_send(path, msg, IUCV_IPRMDATA, 0,
                                 (void *) prmdata, 8);
 }
 
@@ -960,9 +1141,16 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
         * this is fine for SOCK_SEQPACKET (unless we want to support
         * segmented records using the MSG_EOR flag), but
         * for SOCK_STREAM we might want to improve it in future */
-       skb = sock_alloc_send_skb(sk, len, noblock, &err);
+       if (iucv->transport == AF_IUCV_TRANS_HIPER)
+               skb = sock_alloc_send_skb(sk,
+                       len + sizeof(struct af_iucv_trans_hdr) + ETH_HLEN,
+                       noblock, &err);
+       else
+               skb = sock_alloc_send_skb(sk, len, noblock, &err);
        if (!skb)
                goto out;
+       if (iucv->transport == AF_IUCV_TRANS_HIPER)
+               skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN);
        if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
                err = -EFAULT;
                goto fail;
@@ -983,6 +1171,15 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        /* increment and save iucv message tag for msg_completion cbk */
        txmsg.tag = iucv->send_tag++;
        memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
+       if (iucv->transport == AF_IUCV_TRANS_HIPER) {
+               atomic_inc(&iucv->msg_sent);
+               err = afiucv_hs_send(&txmsg, sk, skb, 0);
+               if (err) {
+                       atomic_dec(&iucv->msg_sent);
+                       goto fail;
+               }
+               goto release;
+       }
        skb_queue_tail(&iucv->send_skb_q, skb);
 
        if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags)
@@ -999,13 +1196,13 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                /* this error should never happen since the
                 * IUCV_IPRMDATA path flag is set... sever path */
                if (err == 0x15) {
-                       iucv_path_sever(iucv->path, NULL);
+                       pr_iucv->path_sever(iucv->path, NULL);
                        skb_unlink(skb, &iucv->send_skb_q);
                        err = -EPIPE;
                        goto fail;
                }
        } else
-               err = iucv_message_send(iucv->path, &txmsg, 0, 0,
+               err = pr_iucv->message_send(iucv->path, &txmsg, 0, 0,
                                        (void *) skb->data, skb->len);
        if (err) {
                if (err == 3) {
@@ -1023,6 +1220,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                goto fail;
        }
 
+release:
        release_sock(sk);
        return len;
 
@@ -1095,8 +1293,9 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                        skb->len = 0;
                }
        } else {
-               rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA,
-                                         skb->data, len, NULL);
+               rc = pr_iucv->message_receive(path, msg,
+                                             msg->flags & IUCV_IPRMDATA,
+                                             skb->data, len, NULL);
                if (rc) {
                        kfree_skb(skb);
                        return;
@@ -1110,7 +1309,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                        kfree_skb(skb);
                        skb = NULL;
                        if (rc) {
-                               iucv_path_sever(path, NULL);
+                               pr_iucv->path_sever(path, NULL);
                                return;
                        }
                        skb = skb_dequeue(&iucv_sk(sk)->backlog_skb_q);
@@ -1154,7 +1353,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct iucv_sock *iucv = iucv_sk(sk);
        unsigned int copied, rlen;
-       struct sk_buff *skb, *rskb, *cskb;
+       struct sk_buff *skb, *rskb, *cskb, *sskb;
+       int blen;
        int err = 0;
 
        if ((sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_SEVERED) &&
@@ -1179,7 +1379,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        copied = min_t(unsigned int, rlen, len);
 
        cskb = skb;
-       if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) {
+       if (skb_copy_datagram_iovec(cskb, 0, msg->msg_iov, copied)) {
                if (!(flags & MSG_PEEK))
                        skb_queue_head(&sk->sk_receive_queue, skb);
                return -EFAULT;
@@ -1217,6 +1417,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                }
 
                kfree_skb(skb);
+               atomic_inc(&iucv->msg_recv);
 
                /* Queue backlog skbs */
                spin_lock_bh(&iucv->message_q.lock);
@@ -1233,6 +1434,24 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                if (skb_queue_empty(&iucv->backlog_skb_q)) {
                        if (!list_empty(&iucv->message_q.list))
                                iucv_process_message_q(sk);
+                       if (atomic_read(&iucv->msg_recv) >=
+                                                       iucv->msglimit / 2) {
+                               /* send WIN to peer */
+                               blen = sizeof(struct af_iucv_trans_hdr) +
+                                       ETH_HLEN;
+                               sskb = sock_alloc_send_skb(sk, blen, 1, &err);
+                               if (sskb) {
+                                       skb_reserve(sskb,
+                                               sizeof(struct af_iucv_trans_hdr)
+                                               + ETH_HLEN);
+                                       err = afiucv_hs_send(NULL, sk, sskb,
+                                                            AF_IUCV_FLAG_WIN);
+                               }
+                               if (err) {
+                                       sk->sk_state = IUCV_DISCONN;
+                                       sk->sk_state_change(sk);
+                               }
+                       }
                }
                spin_unlock_bh(&iucv->message_q.lock);
        }
@@ -1327,8 +1546,8 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
        if (how == SEND_SHUTDOWN || how == SHUTDOWN_MASK) {
                txmsg.class = 0;
                txmsg.tag = 0;
-               err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0,
-                                       (void *) iprm_shutdown, 8);
+               err = pr_iucv->message_send(iucv->path, &txmsg, IUCV_IPRMDATA,
+                                       0, (void *) iprm_shutdown, 8);
                if (err) {
                        switch (err) {
                        case 1:
@@ -1345,7 +1564,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
        }
 
        if (how == RCV_SHUTDOWN || how == SHUTDOWN_MASK) {
-               err = iucv_path_quiesce(iucv_sk(sk)->path, NULL);
+               err = pr_iucv->path_quiesce(iucv->path, NULL);
                if (err)
                        err = -ENOTCONN;
 
@@ -1372,7 +1591,7 @@ static int iucv_sock_release(struct socket *sock)
 
        /* Unregister with IUCV base support */
        if (iucv_sk(sk)->path) {
-               iucv_path_sever(iucv_sk(sk)->path, NULL);
+               pr_iucv->path_sever(iucv_sk(sk)->path, NULL);
                iucv_path_free(iucv_sk(sk)->path);
                iucv_sk(sk)->path = NULL;
        }
@@ -1514,14 +1733,14 @@ static int iucv_callback_connreq(struct iucv_path *path,
        high_nmcpy(user_data, iucv->dst_name);
        ASCEBC(user_data, sizeof(user_data));
        if (sk->sk_state != IUCV_LISTEN) {
-               err = iucv_path_sever(path, user_data);
+               err = pr_iucv->path_sever(path, user_data);
                iucv_path_free(path);
                goto fail;
        }
 
        /* Check for backlog size */
        if (sk_acceptq_is_full(sk)) {
-               err = iucv_path_sever(path, user_data);
+               err = pr_iucv->path_sever(path, user_data);
                iucv_path_free(path);
                goto fail;
        }
@@ -1529,7 +1748,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
        /* Create the new socket */
        nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
        if (!nsk) {
-               err = iucv_path_sever(path, user_data);
+               err = pr_iucv->path_sever(path, user_data);
                iucv_path_free(path);
                goto fail;
        }
@@ -1553,9 +1772,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
        /* set message limit for path based on msglimit of accepting socket */
        niucv->msglimit = iucv->msglimit;
        path->msglim = iucv->msglimit;
-       err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk);
+       err = pr_iucv->path_accept(path, &af_iucv_handler, nuser_data, nsk);
        if (err) {
-               err = iucv_path_sever(path, user_data);
+               err = pr_iucv->path_sever(path, user_data);
                iucv_path_free(path);
                iucv_sock_kill(nsk);
                goto fail;
@@ -1589,7 +1808,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
        int len;
 
        if (sk->sk_shutdown & RCV_SHUTDOWN) {
-               iucv_message_reject(path, msg);
+               pr_iucv->message_reject(path, msg);
                return;
        }
 
@@ -1692,6 +1911,389 @@ static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
        bh_unlock_sock(sk);
 }
 
+/***************** HiperSockets transport callbacks ********************/
+static void afiucv_swap_src_dest(struct sk_buff *skb)
+{
+       struct af_iucv_trans_hdr *trans_hdr =
+                               (struct af_iucv_trans_hdr *)skb->data;
+       char tmpID[8];
+       char tmpName[8];
+
+       ASCEBC(trans_hdr->destUserID, sizeof(trans_hdr->destUserID));
+       ASCEBC(trans_hdr->destAppName, sizeof(trans_hdr->destAppName));
+       ASCEBC(trans_hdr->srcUserID, sizeof(trans_hdr->srcUserID));
+       ASCEBC(trans_hdr->srcAppName, sizeof(trans_hdr->srcAppName));
+       memcpy(tmpID, trans_hdr->srcUserID, 8);
+       memcpy(tmpName, trans_hdr->srcAppName, 8);
+       memcpy(trans_hdr->srcUserID, trans_hdr->destUserID, 8);
+       memcpy(trans_hdr->srcAppName, trans_hdr->destAppName, 8);
+       memcpy(trans_hdr->destUserID, tmpID, 8);
+       memcpy(trans_hdr->destAppName, tmpName, 8);
+       skb_push(skb, ETH_HLEN);
+       memset(skb->data, 0, ETH_HLEN);
+}
+
+/**
+ * afiucv_hs_callback_syn - react on received SYN
+ **/
+static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb)
+{
+       struct sock *nsk;
+       struct iucv_sock *iucv, *niucv;
+       struct af_iucv_trans_hdr *trans_hdr;
+       int err;
+
+       iucv = iucv_sk(sk);
+       trans_hdr = (struct af_iucv_trans_hdr *)skb->data;
+       if (!iucv) {
+               /* no sock - connection refused */
+               afiucv_swap_src_dest(skb);
+               trans_hdr->flags = AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_FIN;
+               err = dev_queue_xmit(skb);
+               goto out;
+       }
+
+       nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
+       bh_lock_sock(sk);
+       if ((sk->sk_state != IUCV_LISTEN) ||
+           sk_acceptq_is_full(sk) ||
+           !nsk) {
+               /* error on server socket - connection refused */
+               if (nsk)
+                       sk_free(nsk);
+               afiucv_swap_src_dest(skb);
+               trans_hdr->flags = AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_FIN;
+               err = dev_queue_xmit(skb);
+               bh_unlock_sock(sk);
+               goto out;
+       }
+
+       niucv = iucv_sk(nsk);
+       iucv_sock_init(nsk, sk);
+       niucv->transport = AF_IUCV_TRANS_HIPER;
+       niucv->msglimit = iucv->msglimit;
+       if (!trans_hdr->window)
+               niucv->msglimit_peer = IUCV_HIPER_MSGLIM_DEFAULT;
+       else
+               niucv->msglimit_peer = trans_hdr->window;
+       memcpy(niucv->dst_name, trans_hdr->srcAppName, 8);
+       memcpy(niucv->dst_user_id, trans_hdr->srcUserID, 8);
+       memcpy(niucv->src_name, iucv->src_name, 8);
+       memcpy(niucv->src_user_id, iucv->src_user_id, 8);
+       nsk->sk_bound_dev_if = sk->sk_bound_dev_if;
+       afiucv_swap_src_dest(skb);
+       trans_hdr->flags = AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_ACK;
+       trans_hdr->window = niucv->msglimit;
+       /* if receiver acks the xmit connection is established */
+       err = dev_queue_xmit(skb);
+       if (!err) {
+               iucv_accept_enqueue(sk, nsk);
+               nsk->sk_state = IUCV_CONNECTED;
+               sk->sk_data_ready(sk, 1);
+       } else
+               iucv_sock_kill(nsk);
+       bh_unlock_sock(sk);
+
+out:
+       return NET_RX_SUCCESS;
+}
+
+/**
+ * afiucv_hs_callback_synack() - react on received SYN-ACK
+ **/
+static int afiucv_hs_callback_synack(struct sock *sk, struct sk_buff *skb)
+{
+       struct iucv_sock *iucv = iucv_sk(sk);
+       struct af_iucv_trans_hdr *trans_hdr =
+                                       (struct af_iucv_trans_hdr *)skb->data;
+
+       if (!iucv)
+               goto out;
+       if (sk->sk_state != IUCV_BOUND)
+               goto out;
+       bh_lock_sock(sk);
+       iucv->msglimit_peer = trans_hdr->window;
+       sk->sk_state = IUCV_CONNECTED;
+       sk->sk_state_change(sk);
+       bh_unlock_sock(sk);
+out:
+       kfree_skb(skb);
+       return NET_RX_SUCCESS;
+}
+
+/**
+ * afiucv_hs_callback_synfin() - react on received SYN_FIN
+ **/
+static int afiucv_hs_callback_synfin(struct sock *sk, struct sk_buff *skb)
+{
+       struct iucv_sock *iucv = iucv_sk(sk);
+
+       if (!iucv)
+               goto out;
+       if (sk->sk_state != IUCV_BOUND)
+               goto out;
+       bh_lock_sock(sk);
+       sk->sk_state = IUCV_DISCONN;
+       sk->sk_state_change(sk);
+       bh_unlock_sock(sk);
+out:
+       kfree_skb(skb);
+       return NET_RX_SUCCESS;
+}
+
+/**
+ * afiucv_hs_callback_fin() - react on received FIN
+ **/
+static int afiucv_hs_callback_fin(struct sock *sk, struct sk_buff *skb)
+{
+       struct iucv_sock *iucv = iucv_sk(sk);
+
+       /* other end of connection closed */
+       if (iucv) {
+               bh_lock_sock(sk);
+               if (!list_empty(&iucv->accept_q))
+                       sk->sk_state = IUCV_SEVERED;
+               else
+                       sk->sk_state = IUCV_DISCONN;
+               sk->sk_state_change(sk);
+               bh_unlock_sock(sk);
+       }
+       kfree_skb(skb);
+       return NET_RX_SUCCESS;
+}
+
+/**
+ * afiucv_hs_callback_win() - react on received WIN
+ **/
+static int afiucv_hs_callback_win(struct sock *sk, struct sk_buff *skb)
+{
+       struct iucv_sock *iucv = iucv_sk(sk);
+       struct af_iucv_trans_hdr *trans_hdr =
+                                       (struct af_iucv_trans_hdr *)skb->data;
+
+       if (!iucv)
+               return NET_RX_SUCCESS;
+
+       if (sk->sk_state != IUCV_CONNECTED)
+               return NET_RX_SUCCESS;
+
+       atomic_sub(trans_hdr->window, &iucv->msg_sent);
+       iucv_sock_wake_msglim(sk);
+       return NET_RX_SUCCESS;
+}
+
+/**
+ * afiucv_hs_callback_rx() - react on received data
+ **/
+static int afiucv_hs_callback_rx(struct sock *sk, struct sk_buff *skb)
+{
+       struct iucv_sock *iucv = iucv_sk(sk);
+
+       if (!iucv) {
+               kfree_skb(skb);
+               return NET_RX_SUCCESS;
+       }
+
+       if (sk->sk_state != IUCV_CONNECTED) {
+               kfree_skb(skb);
+               return NET_RX_SUCCESS;
+       }
+
+               /* write stuff from iucv_msg to skb cb */
+       if (skb->len <= sizeof(struct af_iucv_trans_hdr)) {
+               kfree_skb(skb);
+               return NET_RX_SUCCESS;
+       }
+       skb_pull(skb, sizeof(struct af_iucv_trans_hdr));
+       skb_reset_transport_header(skb);
+       skb_reset_network_header(skb);
+       spin_lock(&iucv->message_q.lock);
+       if (skb_queue_empty(&iucv->backlog_skb_q)) {
+               if (sock_queue_rcv_skb(sk, skb)) {
+                       /* handle rcv queue full */
+                       skb_queue_tail(&iucv->backlog_skb_q, skb);
+               }
+       } else
+               skb_queue_tail(&iucv_sk(sk)->backlog_skb_q, skb);
+       spin_unlock(&iucv->message_q.lock);
+       return NET_RX_SUCCESS;
+}
+
+/**
+ * afiucv_hs_rcv() - base function for arriving data through HiperSockets
+ *                   transport
+ *                   called from netif RX softirq
+ **/
+static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
+       struct packet_type *pt, struct net_device *orig_dev)
+{
+       struct hlist_node *node;
+       struct sock *sk;
+       struct iucv_sock *iucv;
+       struct af_iucv_trans_hdr *trans_hdr;
+       char nullstring[8];
+       int err = 0;
+
+       skb_pull(skb, ETH_HLEN);
+       trans_hdr = (struct af_iucv_trans_hdr *)skb->data;
+       EBCASC(trans_hdr->destAppName, sizeof(trans_hdr->destAppName));
+       EBCASC(trans_hdr->destUserID, sizeof(trans_hdr->destUserID));
+       EBCASC(trans_hdr->srcAppName, sizeof(trans_hdr->srcAppName));
+       EBCASC(trans_hdr->srcUserID, sizeof(trans_hdr->srcUserID));
+       memset(nullstring, 0, sizeof(nullstring));
+       iucv = NULL;
+       sk = NULL;
+       read_lock(&iucv_sk_list.lock);
+       sk_for_each(sk, node, &iucv_sk_list.head) {
+               if (trans_hdr->flags == AF_IUCV_FLAG_SYN) {
+                       if ((!memcmp(&iucv_sk(sk)->src_name,
+                                    trans_hdr->destAppName, 8)) &&
+                           (!memcmp(&iucv_sk(sk)->src_user_id,
+                                    trans_hdr->destUserID, 8)) &&
+                           (!memcmp(&iucv_sk(sk)->dst_name, nullstring, 8)) &&
+                           (!memcmp(&iucv_sk(sk)->dst_user_id,
+                                    nullstring, 8))) {
+                               iucv = iucv_sk(sk);
+                               break;
+                       }
+               } else {
+                       if ((!memcmp(&iucv_sk(sk)->src_name,
+                                    trans_hdr->destAppName, 8)) &&
+                           (!memcmp(&iucv_sk(sk)->src_user_id,
+                                    trans_hdr->destUserID, 8)) &&
+                           (!memcmp(&iucv_sk(sk)->dst_name,
+                                    trans_hdr->srcAppName, 8)) &&
+                           (!memcmp(&iucv_sk(sk)->dst_user_id,
+                                    trans_hdr->srcUserID, 8))) {
+                               iucv = iucv_sk(sk);
+                               break;
+                       }
+               }
+       }
+       read_unlock(&iucv_sk_list.lock);
+       if (!iucv)
+               sk = NULL;
+
+       /* no sock
+       how should we send with no sock
+       1) send without sock no send rc checking?
+       2) introduce default sock to handle this cases
+
+        SYN -> send SYN|ACK in good case, send SYN|FIN in bad case
+        data -> send FIN
+        SYN|ACK, SYN|FIN, FIN -> no action? */
+
+       switch (trans_hdr->flags) {
+       case AF_IUCV_FLAG_SYN:
+               /* connect request */
+               err = afiucv_hs_callback_syn(sk, skb);
+               break;
+       case (AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_ACK):
+               /* connect request confirmed */
+               err = afiucv_hs_callback_synack(sk, skb);
+               break;
+       case (AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_FIN):
+               /* connect request refused */
+               err = afiucv_hs_callback_synfin(sk, skb);
+               break;
+       case (AF_IUCV_FLAG_FIN):
+               /* close request */
+               err = afiucv_hs_callback_fin(sk, skb);
+               break;
+       case (AF_IUCV_FLAG_WIN):
+               err = afiucv_hs_callback_win(sk, skb);
+               if (skb->len > sizeof(struct af_iucv_trans_hdr))
+                       err = afiucv_hs_callback_rx(sk, skb);
+               else
+                       kfree(skb);
+               break;
+       case 0:
+               /* plain data frame */
+               err = afiucv_hs_callback_rx(sk, skb);
+               break;
+       default:
+               ;
+       }
+
+       return err;
+}
+
+/**
+ * afiucv_hs_callback_txnotify() - handle send notifcations from HiperSockets
+ *                                 transport
+ **/
+static void afiucv_hs_callback_txnotify(struct sk_buff *skb,
+                                       enum iucv_tx_notify n)
+{
+       struct sock *isk = skb->sk;
+       struct sock *sk = NULL;
+       struct iucv_sock *iucv = NULL;
+       struct sk_buff_head *list;
+       struct sk_buff *list_skb;
+       struct sk_buff *this = NULL;
+       unsigned long flags;
+       struct hlist_node *node;
+
+       read_lock(&iucv_sk_list.lock);
+       sk_for_each(sk, node, &iucv_sk_list.head)
+               if (sk == isk) {
+                       iucv = iucv_sk(sk);
+                       break;
+               }
+       read_unlock(&iucv_sk_list.lock);
+
+       if (!iucv)
+               return;
+
+       bh_lock_sock(sk);
+       list = &iucv->send_skb_q;
+       list_skb = list->next;
+       if (skb_queue_empty(list))
+               goto out_unlock;
+
+       spin_lock_irqsave(&list->lock, flags);
+       while (list_skb != (struct sk_buff *)list) {
+               if (skb_shinfo(list_skb) == skb_shinfo(skb)) {
+                       this = list_skb;
+                       switch (n) {
+                       case TX_NOTIFY_OK:
+                               __skb_unlink(this, list);
+                               iucv_sock_wake_msglim(sk);
+                               kfree_skb(this);
+                               break;
+                       case TX_NOTIFY_PENDING:
+                               atomic_inc(&iucv->pendings);
+                               break;
+                       case TX_NOTIFY_DELAYED_OK:
+                               __skb_unlink(this, list);
+                               atomic_dec(&iucv->pendings);
+                               if (atomic_read(&iucv->pendings) <= 0)
+                                       iucv_sock_wake_msglim(sk);
+                               kfree_skb(this);
+                               break;
+                       case TX_NOTIFY_UNREACHABLE:
+                       case TX_NOTIFY_DELAYED_UNREACHABLE:
+                       case TX_NOTIFY_TPQFULL: /* not yet used */
+                       case TX_NOTIFY_GENERALERROR:
+                       case TX_NOTIFY_DELAYED_GENERALERROR:
+                               __skb_unlink(this, list);
+                               kfree_skb(this);
+                               if (!list_empty(&iucv->accept_q))
+                                       sk->sk_state = IUCV_SEVERED;
+                               else
+                                       sk->sk_state = IUCV_DISCONN;
+                               sk->sk_state_change(sk);
+                               break;
+                       }
+                       break;
+               }
+               list_skb = list_skb->next;
+       }
+       spin_unlock_irqrestore(&list->lock, flags);
+
+out_unlock:
+       bh_unlock_sock(sk);
+}
 static const struct proto_ops iucv_sock_ops = {
        .family         = PF_IUCV,
        .owner          = THIS_MODULE,
@@ -1718,71 +2320,104 @@ static const struct net_proto_family iucv_sock_family_ops = {
        .create = iucv_sock_create,
 };
 
-static int __init afiucv_init(void)
+static struct packet_type iucv_packet_type = {
+       .type = cpu_to_be16(ETH_P_AF_IUCV),
+       .func = afiucv_hs_rcv,
+};
+
+static int afiucv_iucv_init(void)
 {
        int err;
 
-       if (!MACHINE_IS_VM) {
-               pr_err("The af_iucv module cannot be loaded"
-                      " without z/VM\n");
-               err = -EPROTONOSUPPORT;
-               goto out;
-       }
-       cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err);
-       if (unlikely(err)) {
-               WARN_ON(err);
-               err = -EPROTONOSUPPORT;
-               goto out;
-       }
-
-       err = iucv_register(&af_iucv_handler, 0);
+       err = pr_iucv->iucv_register(&af_iucv_handler, 0);
        if (err)
                goto out;
-       err = proto_register(&iucv_proto, 0);
-       if (err)
-               goto out_iucv;
-       err = sock_register(&iucv_sock_family_ops);
-       if (err)
-               goto out_proto;
        /* establish dummy device */
+       af_iucv_driver.bus = pr_iucv->bus;
        err = driver_register(&af_iucv_driver);
        if (err)
-               goto out_sock;
+               goto out_iucv;
        af_iucv_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
        if (!af_iucv_dev) {
                err = -ENOMEM;
                goto out_driver;
        }
        dev_set_name(af_iucv_dev, "af_iucv");
-       af_iucv_dev->bus = &iucv_bus;
-       af_iucv_dev->parent = iucv_root;
+       af_iucv_dev->bus = pr_iucv->bus;
+       af_iucv_dev->parent = pr_iucv->root;
        af_iucv_dev->release = (void (*)(struct device *))kfree;
        af_iucv_dev->driver = &af_iucv_driver;
        err = device_register(af_iucv_dev);
        if (err)
                goto out_driver;
-
        return 0;
 
 out_driver:
        driver_unregister(&af_iucv_driver);
+out_iucv:
+       pr_iucv->iucv_unregister(&af_iucv_handler, 0);
+out:
+       return err;
+}
+
+static int __init afiucv_init(void)
+{
+       int err;
+
+       if (MACHINE_IS_VM) {
+               cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err);
+               if (unlikely(err)) {
+                       WARN_ON(err);
+                       err = -EPROTONOSUPPORT;
+                       goto out;
+               }
+
+               pr_iucv = try_then_request_module(symbol_get(iucv_if), "iucv");
+               if (!pr_iucv) {
+                       printk(KERN_WARNING "iucv_if lookup failed\n");
+                       memset(&iucv_userid, 0, sizeof(iucv_userid));
+               }
+       } else {
+               memset(&iucv_userid, 0, sizeof(iucv_userid));
+               pr_iucv = NULL;
+       }
+
+       err = proto_register(&iucv_proto, 0);
+       if (err)
+               goto out;
+       err = sock_register(&iucv_sock_family_ops);
+       if (err)
+               goto out_proto;
+
+       if (pr_iucv) {
+               err = afiucv_iucv_init();
+               if (err)
+                       goto out_sock;
+       }
+       dev_add_pack(&iucv_packet_type);
+       return 0;
+
 out_sock:
        sock_unregister(PF_IUCV);
 out_proto:
        proto_unregister(&iucv_proto);
-out_iucv:
-       iucv_unregister(&af_iucv_handler, 0);
 out:
+       if (pr_iucv)
+               symbol_put(iucv_if);
        return err;
 }
 
 static void __exit afiucv_exit(void)
 {
-       device_unregister(af_iucv_dev);
-       driver_unregister(&af_iucv_driver);
+       if (pr_iucv) {
+               device_unregister(af_iucv_dev);
+               driver_unregister(&af_iucv_driver);
+               pr_iucv->iucv_unregister(&af_iucv_handler, 0);
+               symbol_put(iucv_if);
+       }
+       dev_remove_pack(&iucv_packet_type);
        sock_unregister(PF_IUCV);
        proto_unregister(&iucv_proto);
-       iucv_unregister(&af_iucv_handler, 0);
 }
 
 module_init(afiucv_init);
@@ -1793,3 +2428,4 @@ MODULE_DESCRIPTION("IUCV Sockets ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_NETPROTO(PF_IUCV);
+
index 075a3808aa4005cdbea5aca59430a1e7970c0cad..403be43b793d737a73cf68a3eee8222fb996c535 100644 (file)
@@ -1974,6 +1974,27 @@ out:
        return rc;
 }
 
+struct iucv_interface iucv_if = {
+       .message_receive = iucv_message_receive,
+       .__message_receive = __iucv_message_receive,
+       .message_reply = iucv_message_reply,
+       .message_reject = iucv_message_reject,
+       .message_send = iucv_message_send,
+       .__message_send = __iucv_message_send,
+       .message_send2way = iucv_message_send2way,
+       .message_purge = iucv_message_purge,
+       .path_accept = iucv_path_accept,
+       .path_connect = iucv_path_connect,
+       .path_quiesce = iucv_path_quiesce,
+       .path_resume = iucv_path_resume,
+       .path_sever = iucv_path_sever,
+       .iucv_register = iucv_register,
+       .iucv_unregister = iucv_unregister,
+       .bus = NULL,
+       .root = NULL,
+};
+EXPORT_SYMBOL(iucv_if);
+
 /**
  * iucv_init
  *
@@ -2038,6 +2059,8 @@ static int __init iucv_init(void)
        rc = bus_register(&iucv_bus);
        if (rc)
                goto out_reboot;
+       iucv_if.root = iucv_root;
+       iucv_if.bus = &iucv_bus;
        return 0;
 
 out_reboot:
index fd1aaf2a4a6c47eae03cd40c469055d86be12a14..9b5bd8cafc201a361e907f325d1d762472062411 100644 (file)
@@ -69,7 +69,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
        if (!tid_rx)
                return;
 
-       rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], NULL);
+       RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL);
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
@@ -340,7 +340,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
        status = WLAN_STATUS_SUCCESS;
 
        /* activate it for RX */
-       rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
+       RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
 
        if (timeout)
                mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout));
index c8be8eff70daa5595b823c8648a1261153fe71b1..018108d1a2fd5079d16a04edb030520aca0d7d8b 100644 (file)
@@ -128,7 +128,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
        memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
        bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
        bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
-       bar_control |= (u16)(tid << 12);
+       bar_control |= (u16)(tid << IEEE80211_BAR_CTRL_TID_INFO_SHIFT);
        bar->control = cpu_to_le16(bar_control);
        bar->start_seq_num = cpu_to_le16(ssn);
 
@@ -777,18 +777,14 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
 #endif
-
+       /*
+        * IEEE 802.11-2007 7.3.1.14:
+        * In an ADDBA Response frame, when the Status Code field
+        * is set to 0, the Buffer Size subfield is set to a value
+        * of at least 1.
+        */
        if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
-                       == WLAN_STATUS_SUCCESS) {
-               /*
-                * IEEE 802.11-2007 7.3.1.14:
-                * In an ADDBA Response frame, when the Status Code field
-                * is set to 0, the Buffer Size subfield is set to a value
-                * of at least 1.
-                */
-               if (!buf_size)
-                       goto out;
-
+                       == WLAN_STATUS_SUCCESS && buf_size) {
                if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
                                     &tid_tx->state)) {
                        /* ignore duplicate response */
index 3d1b091d9b2ece8d632537a443867939db80706b..a589addf6ce1db3a3b2880f496f1318888e2ff56 100644 (file)
@@ -62,7 +62,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
 
        if (type == NL80211_IFTYPE_AP_VLAN &&
            params && params->use_4addr == 0)
-               rcu_assign_pointer(sdata->u.vlan.sta, NULL);
+               RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
        else if (type == NL80211_IFTYPE_STATION &&
                 params && params->use_4addr >= 0)
                sdata->u.mgd.use_4addr = params->use_4addr;
@@ -542,7 +542,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
 
        sdata->vif.bss_conf.dtim_period = new->dtim_period;
 
-       rcu_assign_pointer(sdata->u.ap.beacon, new);
+       RCU_INIT_POINTER(sdata->u.ap.beacon, new);
 
        synchronize_rcu();
 
@@ -594,7 +594,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
        if (!old)
                return -ENOENT;
 
-       rcu_assign_pointer(sdata->u.ap.beacon, NULL);
+       RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
        synchronize_rcu();
        kfree(old);
 
@@ -857,7 +857,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
                                return -EBUSY;
                        }
 
-                       rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
+                       RCU_INIT_POINTER(vlansdata->u.vlan.sta, sta);
                }
 
                sta->sdata = vlansdata;
@@ -1898,33 +1898,6 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 
        *cookie = (unsigned long) skb;
 
-       if (is_offchan && local->ops->offchannel_tx) {
-               int ret;
-
-               IEEE80211_SKB_CB(skb)->band = chan->band;
-
-               mutex_lock(&local->mtx);
-
-               if (local->hw_offchan_tx_cookie) {
-                       mutex_unlock(&local->mtx);
-                       return -EBUSY;
-               }
-
-               /* TODO: bitrate control, TX processing? */
-               ret = drv_offchannel_tx(local, skb, chan, channel_type, wait);
-
-               if (ret == 0)
-                       local->hw_offchan_tx_cookie = *cookie;
-               mutex_unlock(&local->mtx);
-
-               /*
-                * Allow driver to return 1 to indicate it wants to have the
-                * frame transmitted with a remain_on_channel + regular TX.
-                */
-               if (ret != 1)
-                       return ret;
-       }
-
        if (is_offchan && local->ops->remain_on_channel) {
                unsigned int duration;
                int ret;
@@ -2011,18 +1984,6 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 
        mutex_lock(&local->mtx);
 
-       if (local->ops->offchannel_tx_cancel_wait &&
-           local->hw_offchan_tx_cookie == cookie) {
-               ret = drv_offchannel_tx_cancel_wait(local);
-
-               if (!ret)
-                       local->hw_offchan_tx_cookie = 0;
-
-               mutex_unlock(&local->mtx);
-
-               return ret;
-       }
-
        if (local->ops->cancel_remain_on_channel) {
                cookie ^= 2;
                ret = ieee80211_cancel_remain_on_channel_hw(local, cookie);
index 1425380983f7055980245d2dede8aa1bfeddf116..9001ff331f0a6efa6c6e1234a7975e4f255d775e 100644 (file)
@@ -590,37 +590,6 @@ static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
        return ret;
 }
 
-static inline int drv_offchannel_tx(struct ieee80211_local *local,
-                                   struct sk_buff *skb,
-                                   struct ieee80211_channel *chan,
-                                   enum nl80211_channel_type channel_type,
-                                   unsigned int wait)
-{
-       int ret;
-
-       might_sleep();
-
-       trace_drv_offchannel_tx(local, skb, chan, channel_type, wait);
-       ret = local->ops->offchannel_tx(&local->hw, skb, chan,
-                                       channel_type, wait);
-       trace_drv_return_int(local, ret);
-
-       return ret;
-}
-
-static inline int drv_offchannel_tx_cancel_wait(struct ieee80211_local *local)
-{
-       int ret;
-
-       might_sleep();
-
-       trace_drv_offchannel_tx_cancel_wait(local);
-       ret = local->ops->offchannel_tx_cancel_wait(&local->hw);
-       trace_drv_return_int(local, ret);
-
-       return ret;
-}
-
 static inline int drv_set_ringparam(struct ieee80211_local *local,
                                    u32 tx, u32 rx)
 {
index 56c24cabf26d3cb6552f157320e1e782acff16cf..4f9235b18a03231b643e9b4425b98f0f51fe8186 100644 (file)
@@ -84,7 +84,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        drv_reset_tsf(local);
 
        skb = ifibss->skb;
-       rcu_assign_pointer(ifibss->presp, NULL);
+       RCU_INIT_POINTER(ifibss->presp, NULL);
        synchronize_rcu();
        skb->data = skb->head;
        skb->len = 0;
@@ -184,7 +184,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                *pos++ = 0; /* U-APSD no in use */
        }
 
-       rcu_assign_pointer(ifibss->presp, skb);
+       RCU_INIT_POINTER(ifibss->presp, skb);
 
        sdata->vif.bss_conf.beacon_int = beacon_int;
        sdata->vif.bss_conf.basic_rates = basic_rates;
@@ -995,7 +995,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
        kfree(sdata->u.ibss.ie);
        skb = rcu_dereference_protected(sdata->u.ibss.presp,
                                        lockdep_is_held(&sdata->u.ibss.mtx));
-       rcu_assign_pointer(sdata->u.ibss.presp, NULL);
+       RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
        sdata->vif.bss_conf.ibss_joined = false;
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
                                                BSS_CHANGED_IBSS);
index 400c09bea63904e933900b27c4dd244c41819b38..ea7419050846b42ea6bf8ef44ac6803281ec9346 100644 (file)
@@ -1002,7 +1002,6 @@ struct ieee80211_local {
        unsigned int hw_roc_duration;
        u32 hw_roc_cookie;
        bool hw_roc_for_tx;
-       unsigned long hw_offchan_tx_cookie;
 
        /* dummy netdev for use w/ NAPI */
        struct net_device napi_dev;
@@ -1022,69 +1021,6 @@ struct ieee80211_ra_tid {
        u16 tid;
 };
 
-/* Parsed Information Elements */
-struct ieee802_11_elems {
-       u8 *ie_start;
-       size_t total_len;
-
-       /* pointers to IEs */
-       u8 *ssid;
-       u8 *supp_rates;
-       u8 *fh_params;
-       u8 *ds_params;
-       u8 *cf_params;
-       struct ieee80211_tim_ie *tim;
-       u8 *ibss_params;
-       u8 *challenge;
-       u8 *wpa;
-       u8 *rsn;
-       u8 *erp_info;
-       u8 *ext_supp_rates;
-       u8 *wmm_info;
-       u8 *wmm_param;
-       struct ieee80211_ht_cap *ht_cap_elem;
-       struct ieee80211_ht_info *ht_info_elem;
-       struct ieee80211_meshconf_ie *mesh_config;
-       u8 *mesh_id;
-       u8 *peer_link;
-       u8 *preq;
-       u8 *prep;
-       u8 *perr;
-       struct ieee80211_rann_ie *rann;
-       u8 *ch_switch_elem;
-       u8 *country_elem;
-       u8 *pwr_constr_elem;
-       u8 *quiet_elem;         /* first quite element */
-       u8 *timeout_int;
-
-       /* length of them, respectively */
-       u8 ssid_len;
-       u8 supp_rates_len;
-       u8 fh_params_len;
-       u8 ds_params_len;
-       u8 cf_params_len;
-       u8 tim_len;
-       u8 ibss_params_len;
-       u8 challenge_len;
-       u8 wpa_len;
-       u8 rsn_len;
-       u8 erp_info_len;
-       u8 ext_supp_rates_len;
-       u8 wmm_info_len;
-       u8 wmm_param_len;
-       u8 mesh_id_len;
-       u8 peer_link_len;
-       u8 preq_len;
-       u8 prep_len;
-       u8 perr_len;
-       u8 ch_switch_elem_len;
-       u8 country_elem_len;
-       u8 pwr_constr_elem_len;
-       u8 quiet_elem_len;
-       u8 num_of_quiet_elem;   /* can be more the one */
-       u8 timeout_int_len;
-};
-
 static inline struct ieee80211_local *hw_to_local(
        struct ieee80211_hw *hw)
 {
index 556e7e6ddf0a6b26dda29a33c00ee6c4d0ffed5b..d10dc4df60b6daaca6b327db18871438d9f9ed82 100644 (file)
@@ -456,7 +456,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                                                 BSS_CHANGED_BEACON_ENABLED);
 
                /* remove beacon */
-               rcu_assign_pointer(sdata->u.ap.beacon, NULL);
+               RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
                synchronize_rcu();
                kfree(old_beacon);
 
@@ -645,7 +645,7 @@ static const struct net_device_ops ieee80211_dataif_ops = {
        .ndo_stop               = ieee80211_stop,
        .ndo_uninit             = ieee80211_teardown_sdata,
        .ndo_start_xmit         = ieee80211_subif_start_xmit,
-       .ndo_set_multicast_list = ieee80211_set_multicast_list,
+       .ndo_set_rx_mode        = ieee80211_set_multicast_list,
        .ndo_change_mtu         = ieee80211_change_mtu,
        .ndo_set_mac_address    = ieee80211_change_mac,
        .ndo_select_queue       = ieee80211_netdev_select_queue,
@@ -689,7 +689,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
        .ndo_stop               = ieee80211_stop,
        .ndo_uninit             = ieee80211_teardown_sdata,
        .ndo_start_xmit         = ieee80211_monitor_start_xmit,
-       .ndo_set_multicast_list = ieee80211_set_multicast_list,
+       .ndo_set_rx_mode        = ieee80211_set_multicast_list,
        .ndo_change_mtu         = ieee80211_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_select_queue       = ieee80211_monitor_select_queue,
index 866f269183cf9a1532f317e3b9f52bc437a98213..68c8bd0471f5bd77a8c12b3344f310feb5b18d76 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/bitmap.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/inetdevice.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
@@ -608,6 +608,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        local->hw.max_rates = 1;
        local->hw.max_report_rates = 0;
        local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
+       local->hw.max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
        local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
        local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
        local->user_power_level = -1;
@@ -1012,7 +1013,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
        cancel_work_sync(&local->reconfig_filter);
 
        ieee80211_clear_tx_pending(local);
-       sta_info_stop(local);
        rate_control_deinitialize(local);
 
        if (skb_queue_len(&local->skb_queue) ||
@@ -1024,6 +1024,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
        destroy_workqueue(local->workqueue);
        wiphy_unregister(local->hw.wiphy);
+       sta_info_stop(local);
        ieee80211_wep_free(local);
        ieee80211_led_exit(local);
        kfree(local->int_scan_req);
index 29e9980c8e60c6b704c99ec213308d64c6864a8b..ecdde6ce4df0a8727dea8198e8d47235ae0700f0 100644 (file)
 #include "ieee80211_i.h"
 #include "mesh.h"
 
-#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
-#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
-#define IEEE80211_MESH_RANN_INTERVAL        (1 * HZ)
-
 #define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01
 #define MESHCONF_CAPAB_FORWARDING    0x08
 
 int mesh_allocated;
 static struct kmem_cache *rm_cache;
 
+#ifdef CONFIG_MAC80211_MESH
+bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
+{
+       return (mgmt->u.action.u.mesh_action.action_code ==
+                       WLAN_MESH_ACTION_HWMP_PATH_SELECTION);
+}
+#else
+bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
+{ return false; }
+#endif
+
 void ieee80211s_init(void)
 {
        mesh_pathtbl_init();
@@ -204,36 +211,185 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
        return 0;
 }
 
-void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+int
+mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       u8 *pos, neighbors;
+       u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie);
+
+       if (skb_tailroom(skb) < 2 + meshconf_len)
+               return -ENOMEM;
+
+       pos = skb_put(skb, 2 + meshconf_len);
+       *pos++ = WLAN_EID_MESH_CONFIG;
+       *pos++ = meshconf_len;
+
+       /* Active path selection protocol ID */
+       *pos++ = ifmsh->mesh_pp_id;
+       /* Active path selection metric ID   */
+       *pos++ = ifmsh->mesh_pm_id;
+       /* Congestion control mode identifier */
+       *pos++ = ifmsh->mesh_cc_id;
+       /* Synchronization protocol identifier */
+       *pos++ = ifmsh->mesh_sp_id;
+       /* Authentication Protocol identifier */
+       *pos++ = ifmsh->mesh_auth_id;
+       /* Mesh Formation Info - number of neighbors */
+       neighbors = atomic_read(&ifmsh->mshstats.estab_plinks);
+       /* Number of neighbor mesh STAs or 15 whichever is smaller */
+       neighbors = (neighbors > 15) ? 15 : neighbors;
+       *pos++ = neighbors << 1;
+       /* Mesh capability */
+       ifmsh->accepting_plinks = mesh_plink_availables(sdata);
+       *pos = MESHCONF_CAPAB_FORWARDING;
+       *pos++ |= ifmsh->accepting_plinks ?
+           MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
+       *pos++ = 0x00;
+
+       return 0;
+}
+
+int
+mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       u8 *pos;
+
+       if (skb_tailroom(skb) < 2 + ifmsh->mesh_id_len)
+               return -ENOMEM;
+
+       pos = skb_put(skb, 2 + ifmsh->mesh_id_len);
+       *pos++ = WLAN_EID_MESH_ID;
+       *pos++ = ifmsh->mesh_id_len;
+       if (ifmsh->mesh_id_len)
+               memcpy(pos, ifmsh->mesh_id, ifmsh->mesh_id_len);
+
+       return 0;
+}
+
+int
+mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       u8 offset, len;
+       const u8 *data;
+
+       if (!ifmsh->ie || !ifmsh->ie_len)
+               return 0;
+
+       /* fast-forward to vendor IEs */
+       offset = ieee80211_ie_split_vendor(ifmsh->ie, ifmsh->ie_len, 0);
+
+       if (offset) {
+               len = ifmsh->ie_len - offset;
+               data = ifmsh->ie + offset;
+               if (skb_tailroom(skb) < len)
+                       return -ENOMEM;
+               memcpy(skb_put(skb, len), data, len);
+       }
+
+       return 0;
+}
+
+int
+mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       u8 len = 0;
+       const u8 *data;
+
+       if (!ifmsh->ie || !ifmsh->ie_len)
+               return 0;
+
+       /* find RSN IE */
+       data = ifmsh->ie;
+       while (data < ifmsh->ie + ifmsh->ie_len) {
+               if (*data == WLAN_EID_RSN) {
+                       len = data[1] + 2;
+                       break;
+               }
+               data++;
+       }
+
+       if (len) {
+               if (skb_tailroom(skb) < len)
+                       return -ENOMEM;
+               memcpy(skb_put(skb, len), data, len);
+       }
+
+       return 0;
+}
+
+int
+mesh_add_srates_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
-       u8 *pos;
-       int len, i, rate;
-       u8 neighbors;
+       int rate;
+       u8 i, rates, *pos;
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-       len = sband->n_bitrates;
-       if (len > 8)
-               len = 8;
-       pos = skb_put(skb, len + 2);
+       rates = sband->n_bitrates;
+       if (rates > 8)
+               rates = 8;
+
+       if (skb_tailroom(skb) < rates + 2)
+               return -ENOMEM;
+
+       pos = skb_put(skb, rates + 2);
        *pos++ = WLAN_EID_SUPP_RATES;
-       *pos++ = len;
-       for (i = 0; i < len; i++) {
+       *pos++ = rates;
+       for (i = 0; i < rates; i++) {
                rate = sband->bitrates[i].bitrate;
                *pos++ = (u8) (rate / 5);
        }
 
-       if (sband->n_bitrates > len) {
-               pos = skb_put(skb, sband->n_bitrates - len + 2);
+       return 0;
+}
+
+int
+mesh_add_ext_srates_ie(struct sk_buff *skb,
+                      struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_supported_band *sband;
+       int rate;
+       u8 i, exrates, *pos;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+       exrates = sband->n_bitrates;
+       if (exrates > 8)
+               exrates -= 8;
+       else
+               exrates = 0;
+
+       if (skb_tailroom(skb) < exrates + 2)
+               return -ENOMEM;
+
+       if (exrates) {
+               pos = skb_put(skb, exrates + 2);
                *pos++ = WLAN_EID_EXT_SUPP_RATES;
-               *pos++ = sband->n_bitrates - len;
-               for (i = len; i < sband->n_bitrates; i++) {
+               *pos++ = exrates;
+               for (i = 8; i < sband->n_bitrates; i++) {
                        rate = sband->bitrates[i].bitrate;
                        *pos++ = (u8) (rate / 5);
                }
        }
+       return 0;
+}
 
+int mesh_add_ds_params_ie(struct sk_buff *skb,
+                         struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_supported_band *sband;
+       u8 *pos;
+
+       if (skb_tailroom(skb) < 3)
+               return -ENOMEM;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
        if (sband->band == IEEE80211_BAND_2GHZ) {
                pos = skb_put(skb, 2 + 1);
                *pos++ = WLAN_EID_DS_PARAMS;
@@ -241,53 +397,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
                *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq);
        }
 
-       pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len);
-       *pos++ = WLAN_EID_MESH_ID;
-       *pos++ = sdata->u.mesh.mesh_id_len;
-       if (sdata->u.mesh.mesh_id_len)
-               memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len);
-
-       pos = skb_put(skb, 2 + sizeof(struct ieee80211_meshconf_ie));
-       *pos++ = WLAN_EID_MESH_CONFIG;
-       *pos++ = sizeof(struct ieee80211_meshconf_ie);
-
-       /* Active path selection protocol ID */
-       *pos++ = sdata->u.mesh.mesh_pp_id;
-
-       /* Active path selection metric ID   */
-       *pos++ = sdata->u.mesh.mesh_pm_id;
-
-       /* Congestion control mode identifier */
-       *pos++ = sdata->u.mesh.mesh_cc_id;
-
-       /* Synchronization protocol identifier */
-       *pos++ = sdata->u.mesh.mesh_sp_id;
-
-       /* Authentication Protocol identifier */
-       *pos++ = sdata->u.mesh.mesh_auth_id;
-
-       /* Mesh Formation Info - number of neighbors */
-       neighbors = atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
-       /* Number of neighbor mesh STAs or 15 whichever is smaller */
-       neighbors = (neighbors > 15) ? 15 : neighbors;
-       *pos++ = neighbors << 1;
-
-       /* Mesh capability */
-       sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata);
-       *pos = MESHCONF_CAPAB_FORWARDING;
-       *pos++ |= sdata->u.mesh.accepting_plinks ?
-           MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
-       *pos++ = 0x00;
-
-       if (sdata->u.mesh.ie) {
-               int len = sdata->u.mesh.ie_len;
-               const u8 *data = sdata->u.mesh.ie;
-               if (skb_tailroom(skb) > len)
-                       memcpy(skb_put(skb, len), data, len);
-       }
+       return 0;
 }
 
-
 static void ieee80211_mesh_path_timer(unsigned long data)
 {
        struct ieee80211_sub_if_data *sdata =
@@ -557,11 +669,18 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
                                          struct ieee80211_rx_status *rx_status)
 {
        switch (mgmt->u.action.category) {
-       case WLAN_CATEGORY_MESH_ACTION:
-               mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
+       case WLAN_CATEGORY_SELF_PROTECTED:
+               switch (mgmt->u.action.u.self_prot.action_code) {
+               case WLAN_SP_MESH_PEERING_OPEN:
+               case WLAN_SP_MESH_PEERING_CLOSE:
+               case WLAN_SP_MESH_PEERING_CONFIRM:
+                       mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
+                       break;
+               }
                break;
-       case WLAN_CATEGORY_MESH_PATH_SEL:
-               mesh_rx_path_sel_frame(sdata, mgmt, len);
+       case WLAN_CATEGORY_MESH_ACTION:
+               if (mesh_action_is_path_sel(mgmt))
+                       mesh_rx_path_sel_frame(sdata, mgmt, len);
                break;
        }
 }
index 249e733362e7b9bf4d48714800ba7da48273832d..3c7d0f8b376a0b9ca5b267bffab970a84b50bbb4 100644 (file)
@@ -166,6 +166,9 @@ struct mesh_rmc {
        u32 idx_mask;
 };
 
+#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
+#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
+#define IEEE80211_MESH_RANN_INTERVAL        (1 * HZ)
 
 #define MESH_DEFAULT_BEACON_INTERVAL           1000    /* in 1024 us units */
 
@@ -177,14 +180,6 @@ struct mesh_rmc {
 /* Maximum number of paths per interface */
 #define MESH_MAX_MPATHS                1024
 
-/* Pending ANA approval */
-#define MESH_PATH_SEL_ACTION   0
-
-/* PERR reason codes */
-#define PEER_RCODE_UNSPECIFIED  11
-#define PERR_RCODE_NO_ROUTE     12
-#define PERR_RCODE_DEST_UNREACH 13
-
 /* Public interfaces */
 /* Various */
 int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
@@ -199,6 +194,20 @@ bool mesh_matches_local(struct ieee802_11_elems *ie,
 void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
 void mesh_mgmt_ies_add(struct sk_buff *skb,
                struct ieee80211_sub_if_data *sdata);
+int mesh_add_meshconf_ie(struct sk_buff *skb,
+                        struct ieee80211_sub_if_data *sdata);
+int mesh_add_meshid_ie(struct sk_buff *skb,
+                      struct ieee80211_sub_if_data *sdata);
+int mesh_add_rsn_ie(struct sk_buff *skb,
+                   struct ieee80211_sub_if_data *sdata);
+int mesh_add_vendor_ies(struct sk_buff *skb,
+                       struct ieee80211_sub_if_data *sdata);
+int mesh_add_srates_ie(struct sk_buff *skb,
+                      struct ieee80211_sub_if_data *sdata);
+int mesh_add_ext_srates_ie(struct sk_buff *skb,
+                          struct ieee80211_sub_if_data *sdata);
+int mesh_add_ds_params_ie(struct sk_buff *skb,
+                         struct ieee80211_sub_if_data *sdata);
 void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
 void ieee80211s_init(void);
@@ -262,6 +271,7 @@ void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
 void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
 void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
 
+bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
 extern int mesh_paths_generation;
 
 #ifdef CONFIG_MAC80211_MESH
index 3460108810d5ea60930d87d15d1057187a427bb2..9c3c0b86a740bfdd0bf611d3fe35d8b44d841683 100644 (file)
@@ -68,12 +68,12 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
 #define PREP_IE_FLAGS(x)       PREQ_IE_FLAGS(x)
 #define PREP_IE_HOPCOUNT(x)    PREQ_IE_HOPCOUNT(x)
 #define PREP_IE_TTL(x)         PREQ_IE_TTL(x)
-#define PREP_IE_ORIG_ADDR(x)   (x + 3)
-#define PREP_IE_ORIG_SN(x)     u32_field_get(x, 9, 0)
+#define PREP_IE_ORIG_ADDR(x)   (AE_F_SET(x) ? x + 27 : x + 21)
+#define PREP_IE_ORIG_SN(x)     u32_field_get(x, 27, AE_F_SET(x))
 #define PREP_IE_LIFETIME(x)    u32_field_get(x, 13, AE_F_SET(x))
 #define PREP_IE_METRIC(x)      u32_field_get(x, 17, AE_F_SET(x))
-#define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
-#define PREP_IE_TARGET_SN(x)   u32_field_get(x, 27, AE_F_SET(x))
+#define PREP_IE_TARGET_ADDR(x) (x + 3)
+#define PREP_IE_TARGET_SN(x)   u32_field_get(x, 9, 0)
 
 #define PERR_IE_TTL(x)         (*(x))
 #define PERR_IE_TARGET_FLAGS(x)        (*(x + 2))
@@ -132,8 +132,9 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
        /* BSSID == SA */
        memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
-       mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL;
-       mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
+       mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
+       mgmt->u.action.u.mesh_action.action_code =
+                                       WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
 
        switch (action) {
        case MPATH_PREQ:
@@ -163,29 +164,37 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
        *pos++ = flags;
        *pos++ = hop_count;
        *pos++ = ttl;
-       if (action == MPATH_PREQ) {
-               memcpy(pos, &preq_id, 4);
+       if (action == MPATH_PREP) {
+               memcpy(pos, target, ETH_ALEN);
+               pos += ETH_ALEN;
+               memcpy(pos, &target_sn, 4);
                pos += 4;
-       }
-       memcpy(pos, orig_addr, ETH_ALEN);
-       pos += ETH_ALEN;
-       memcpy(pos, &orig_sn, 4);
-       pos += 4;
-       if (action != MPATH_RANN) {
-               memcpy(pos, &lifetime, 4);
+       } else {
+               if (action == MPATH_PREQ) {
+                       memcpy(pos, &preq_id, 4);
+                       pos += 4;
+               }
+               memcpy(pos, orig_addr, ETH_ALEN);
+               pos += ETH_ALEN;
+               memcpy(pos, &orig_sn, 4);
                pos += 4;
        }
+       memcpy(pos, &lifetime, 4);      /* interval for RANN */
+       pos += 4;
        memcpy(pos, &metric, 4);
        pos += 4;
        if (action == MPATH_PREQ) {
-               /* destination count */
-               *pos++ = 1;
+               *pos++ = 1; /* destination count */
                *pos++ = target_flags;
-       }
-       if (action != MPATH_RANN) {
                memcpy(pos, target, ETH_ALEN);
                pos += ETH_ALEN;
                memcpy(pos, &target_sn, 4);
+               pos += 4;
+       } else if (action == MPATH_PREP) {
+               memcpy(pos, orig_addr, ETH_ALEN);
+               pos += ETH_ALEN;
+               memcpy(pos, &orig_sn, 4);
+               pos += 4;
        }
 
        ieee80211_tx_skb(sdata, skb);
@@ -224,9 +233,11 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
 
        memcpy(mgmt->da, ra, ETH_ALEN);
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
-       /* BSSID is left zeroed, wildcard value */
-       mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL;
-       mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
+       /* BSSID == SA */
+       memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+       mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
+       mgmt->u.action.u.mesh_action.action_code =
+                                       WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
        ie_len = 15;
        pos = skb_put(skb, 2 + ie_len);
        *pos++ = WLAN_EID_PERR;
@@ -449,7 +460,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 
                if (fresh_info) {
                        mesh_path_assign_nexthop(mpath, sta);
-                       mpath->flags &= ~MESH_PATH_SN_VALID;
                        mpath->metric = last_hop_metric;
                        mpath->exp_time = time_after(mpath->exp_time, exp_time)
                                          ?  mpath->exp_time : exp_time;
@@ -684,6 +694,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        u8 ttl, flags, hopcount;
        u8 *orig_addr;
        u32 orig_sn, metric;
+       u32 interval = cpu_to_le32(IEEE80211_MESH_RANN_INTERVAL);
 
        ttl = rann->rann_ttl;
        if (ttl <= 1) {
@@ -716,7 +727,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
                                       cpu_to_le32(orig_sn),
                                       0, NULL, 0, broadcast_addr,
-                                      hopcount, ttl, 0,
+                                      hopcount, ttl, interval,
                                       cpu_to_le32(metric + mpath->metric),
                                       0, sdata);
                mpath->sn = orig_sn;
@@ -792,9 +803,9 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
                return;
        }
 
-       spin_lock(&ifmsh->mesh_preq_queue_lock);
+       spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
        if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) {
-               spin_unlock(&ifmsh->mesh_preq_queue_lock);
+               spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
                kfree(preq_node);
                if (printk_ratelimit())
                        mhwmp_dbg("PREQ node queue full\n");
@@ -806,7 +817,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
 
        list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
        ++ifmsh->preq_queue_len;
-       spin_unlock(&ifmsh->mesh_preq_queue_lock);
+       spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
 
        if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
                ieee80211_queue_work(&sdata->local->hw, &sdata->work);
@@ -1007,10 +1018,11 @@ void
 mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       u32 interval = cpu_to_le32(IEEE80211_MESH_RANN_INTERVAL);
 
        mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr,
                               cpu_to_le32(++ifmsh->sn),
                               0, NULL, 0, broadcast_addr,
                               0, sdata->u.mesh.mshcfg.element_ttl,
-                              0, 0, 0, sdata);
+                              interval, 0, 0, sdata);
 }
index 068ee65182547e0f825a404768a2c72b8c8b7a7d..a2871d898da56123156371b92d70c91bfb4c663a 100644 (file)
@@ -539,6 +539,7 @@ void mesh_plink_broken(struct sta_info *sta)
        struct hlist_node *p;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        int i;
+       __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
 
        rcu_read_lock();
        tbl = rcu_dereference(mesh_paths);
@@ -553,8 +554,7 @@ void mesh_plink_broken(struct sta_info *sta)
                        spin_unlock_bh(&mpath->state_lock);
                        mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
                                        mpath->dst, cpu_to_le32(mpath->sn),
-                                       cpu_to_le16(PERR_RCODE_DEST_UNREACH),
-                                       bcast, sdata);
+                                       reason, bcast, sdata);
                } else
                spin_unlock_bh(&mpath->state_lock);
        }
@@ -699,6 +699,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct mesh_path *mpath;
        u32 sn = 0;
+       __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
 
        if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) {
                u8 *ra, *da;
@@ -709,8 +710,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
                if (mpath)
                        sn = ++mpath->sn;
                mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data,
-                                  cpu_to_le32(sn),
-                                  cpu_to_le16(PERR_RCODE_NO_ROUTE), ra, sdata);
+                                  cpu_to_le32(sn), reason, ra, sdata);
        }
 
        kfree_skb(skb);
@@ -843,6 +843,6 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
 void mesh_pathtbl_unregister(void)
 {
        /* no need for locking during exit path */
-       mesh_table_free(rcu_dereference_raw(mesh_paths), true);
-       mesh_table_free(rcu_dereference_raw(mpp_paths), true);
+       mesh_table_free(rcu_dereference_protected(mesh_paths, 1), true);
+       mesh_table_free(rcu_dereference_protected(mpp_paths, 1), true);
 }
index f4adc0917888d61f6ea033063af41b4c41f60f40..1a00d0f701c36f64c3c6b99589044ae9b945a346 100644 (file)
 #define mpl_dbg(fmt, args...)  do { (void)(0); } while (0)
 #endif
 
-#define PLINK_GET_LLID(p) (p + 4)
-#define PLINK_GET_PLID(p) (p + 6)
+#define PLINK_GET_LLID(p) (p + 2)
+#define PLINK_GET_PLID(p) (p + 4)
 
 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
                                jiffies + HZ * t / 1000))
 
-/* Peer link cancel reasons, all subject to ANA approval */
-#define MESH_LINK_CANCELLED                    2
-#define MESH_MAX_NEIGHBORS                     3
-#define MESH_CAPABILITY_POLICY_VIOLATION       4
-#define MESH_CLOSE_RCVD                                5
-#define MESH_MAX_RETRIES                       6
-#define MESH_CONFIRM_TIMEOUT                   7
-#define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS 8
-#define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE        9
-#define MESH_SECURITY_FAILED_VERIFICATION      10
-
 #define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
 #define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
 #define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
 #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
 #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
 
-enum plink_frame_type {
-       PLINK_OPEN = 1,
-       PLINK_CONFIRM,
-       PLINK_CLOSE
-};
-
 enum plink_event {
        PLINK_UNDEFINED,
        OPN_ACPT,
@@ -157,16 +140,16 @@ void mesh_plink_deactivate(struct sta_info *sta)
 }
 
 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
-               enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
-               __le16 reason) {
+               enum ieee80211_self_protected_actioncode action,
+               u8 *da, __le16 llid, __le16 plid, __le16 reason) {
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
                        sdata->u.mesh.ie_len);
        struct ieee80211_mgmt *mgmt;
        bool include_plid = false;
-       static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
+       int ie_len = 4;
+       u16 peering_proto = 0;
        u8 *pos;
-       int ie_len;
 
        if (!skb)
                return -1;
@@ -175,63 +158,75 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
         * common action part (1)
         */
        mgmt = (struct ieee80211_mgmt *)
-               skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action));
-       memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action));
+               skb_put(skb, 25 + sizeof(mgmt->u.action.u.self_prot));
+       memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.self_prot));
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                          IEEE80211_STYPE_ACTION);
        memcpy(mgmt->da, da, ETH_ALEN);
        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
        memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
-       mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
-       mgmt->u.action.u.plink_action.action_code = action;
-
-       if (action == PLINK_CLOSE)
-               mgmt->u.action.u.plink_action.aux = reason;
-       else {
-               mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0);
-               if (action == PLINK_CONFIRM) {
-                       pos = skb_put(skb, 4);
-                       /* two-byte status code followed by two-byte AID */
-                       memset(pos, 0, 2);
+       mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
+       mgmt->u.action.u.self_prot.action_code = action;
+
+       if (action != WLAN_SP_MESH_PEERING_CLOSE) {
+               /* capability info */
+               pos = skb_put(skb, 2);
+               memset(pos, 0, 2);
+               if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
+                       /* AID */
+                       pos = skb_put(skb, 2);
                        memcpy(pos + 2, &plid, 2);
                }
-               mesh_mgmt_ies_add(skb, sdata);
+               if (mesh_add_srates_ie(skb, sdata) ||
+                   mesh_add_ext_srates_ie(skb, sdata) ||
+                   mesh_add_rsn_ie(skb, sdata) ||
+                   mesh_add_meshid_ie(skb, sdata) ||
+                   mesh_add_meshconf_ie(skb, sdata))
+                       return -1;
+       } else {        /* WLAN_SP_MESH_PEERING_CLOSE */
+               if (mesh_add_meshid_ie(skb, sdata))
+                       return -1;
        }
 
-       /* Add Peer Link Management element */
+       /* Add Mesh Peering Management element */
        switch (action) {
-       case PLINK_OPEN:
-               ie_len = 6;
+       case WLAN_SP_MESH_PEERING_OPEN:
                break;
-       case PLINK_CONFIRM:
-               ie_len = 8;
+       case WLAN_SP_MESH_PEERING_CONFIRM:
+               ie_len += 2;
                include_plid = true;
                break;
-       case PLINK_CLOSE:
-       default:
-               if (!plid)
-                       ie_len = 8;
-               else {
-                       ie_len = 10;
+       case WLAN_SP_MESH_PEERING_CLOSE:
+               if (plid) {
+                       ie_len += 2;
                        include_plid = true;
                }
+               ie_len += 2;    /* reason code */
                break;
+       default:
+               return -EINVAL;
        }
 
+       if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
+               return -ENOMEM;
+
        pos = skb_put(skb, 2 + ie_len);
-       *pos++ = WLAN_EID_PEER_LINK;
+       *pos++ = WLAN_EID_PEER_MGMT;
        *pos++ = ie_len;
-       memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto));
-       pos += 4;
+       memcpy(pos, &peering_proto, 2);
+       pos += 2;
        memcpy(pos, &llid, 2);
+       pos += 2;
        if (include_plid) {
-               pos += 2;
                memcpy(pos, &plid, 2);
-       }
-       if (action == PLINK_CLOSE) {
                pos += 2;
+       }
+       if (action == WLAN_SP_MESH_PEERING_CLOSE) {
                memcpy(pos, &reason, 2);
+               pos += 2;
        }
+       if (mesh_add_vendor_ies(skb, sdata))
+               return -1;
 
        ieee80211_tx_skb(sdata, skb);
        return 0;
@@ -322,21 +317,21 @@ static void mesh_plink_timer(unsigned long data)
                        ++sta->plink_retries;
                        mod_plink_timer(sta, sta->plink_timeout);
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid,
-                                           0, 0);
+                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
+                                           sta->sta.addr, llid, 0, 0);
                        break;
                }
-               reason = cpu_to_le16(MESH_MAX_RETRIES);
+               reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
                /* fall through on else */
        case NL80211_PLINK_CNF_RCVD:
                /* confirm timer */
                if (!reason)
-                       reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
+                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
                sta->plink_state = NL80211_PLINK_HOLDING;
                mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
                spin_unlock_bh(&sta->lock);
-               mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
-                                   reason);
+               mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                                   sta->sta.addr, llid, plid, reason);
                break;
        case NL80211_PLINK_HOLDING:
                /* holding timer */
@@ -396,7 +391,7 @@ int mesh_plink_open(struct sta_info *sta)
        mpl_dbg("Mesh plink: starting establishment with %pM\n",
                sta->sta.addr);
 
-       return mesh_plink_frame_tx(sdata, PLINK_OPEN,
+       return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
                                   sta->sta.addr, llid, 0, 0);
 }
 
@@ -422,7 +417,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        struct ieee802_11_elems elems;
        struct sta_info *sta;
        enum plink_event event;
-       enum plink_frame_type ftype;
+       enum ieee80211_self_protected_actioncode ftype;
        size_t baselen;
        bool deactivated, matches_local = true;
        u8 ie_len;
@@ -449,14 +444,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                return;
        }
 
-       baseaddr = mgmt->u.action.u.plink_action.variable;
-       baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
-       if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
+       baseaddr = mgmt->u.action.u.self_prot.variable;
+       baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
+       if (mgmt->u.action.u.self_prot.action_code ==
+                                               WLAN_SP_MESH_PEERING_CONFIRM) {
                baseaddr += 4;
                baselen += 4;
        }
        ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
-       if (!elems.peer_link) {
+       if (!elems.peering) {
                mpl_dbg("Mesh plink: missing necessary peer link ie\n");
                return;
        }
@@ -466,31 +462,34 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                return;
        }
 
-       ftype = mgmt->u.action.u.plink_action.action_code;
-       ie_len = elems.peer_link_len;
-       if ((ftype == PLINK_OPEN && ie_len != 6) ||
-           (ftype == PLINK_CONFIRM && ie_len != 8) ||
-           (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) {
+       ftype = mgmt->u.action.u.self_prot.action_code;
+       ie_len = elems.peering_len;
+       if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
+           (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
+           (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
+                                                       && ie_len != 8)) {
                mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
                    ftype, ie_len);
                return;
        }
 
-       if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
+       if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
+                               (!elems.mesh_id || !elems.mesh_config)) {
                mpl_dbg("Mesh plink: missing necessary ie\n");
                return;
        }
        /* Note the lines below are correct, the llid in the frame is the plid
         * from the point of view of this host.
         */
-       memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
-       if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10))
-               memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
+       memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
+       if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
+           (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
+               memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
 
        rcu_read_lock();
 
        sta = sta_info_get(sdata, mgmt->sa);
-       if (!sta && ftype != PLINK_OPEN) {
+       if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
                mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
                rcu_read_unlock();
                return;
@@ -509,30 +508,30 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 
        /* Now we will figure out the appropriate event... */
        event = PLINK_UNDEFINED;
-       if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
+       if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
+           (!mesh_matches_local(&elems, sdata))) {
                matches_local = false;
                switch (ftype) {
-               case PLINK_OPEN:
+               case WLAN_SP_MESH_PEERING_OPEN:
                        event = OPN_RJCT;
                        break;
-               case PLINK_CONFIRM:
+               case WLAN_SP_MESH_PEERING_CONFIRM:
                        event = CNF_RJCT;
                        break;
-               case PLINK_CLOSE:
-                       /* avoid warning */
+               default:
                        break;
                }
        }
 
        if (!sta && !matches_local) {
                rcu_read_unlock();
-               reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+               reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                llid = 0;
-               mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
-                                   plid, reason);
+               mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                                   mgmt->sa, llid, plid, reason);
                return;
        } else if (!sta) {
-               /* ftype == PLINK_OPEN */
+               /* ftype == WLAN_SP_MESH_PEERING_OPEN */
                u32 rates;
 
                rcu_read_unlock();
@@ -557,21 +556,21 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        } else if (matches_local) {
                spin_lock_bh(&sta->lock);
                switch (ftype) {
-               case PLINK_OPEN:
+               case WLAN_SP_MESH_PEERING_OPEN:
                        if (!mesh_plink_free_count(sdata) ||
                            (sta->plid && sta->plid != plid))
                                event = OPN_IGNR;
                        else
                                event = OPN_ACPT;
                        break;
-               case PLINK_CONFIRM:
+               case WLAN_SP_MESH_PEERING_CONFIRM:
                        if (!mesh_plink_free_count(sdata) ||
                            (sta->llid != llid || sta->plid != plid))
                                event = CNF_IGNR;
                        else
                                event = CNF_ACPT;
                        break;
-               case PLINK_CLOSE:
+               case WLAN_SP_MESH_PEERING_CLOSE:
                        if (sta->plink_state == NL80211_PLINK_ESTAB)
                                /* Do not check for llid or plid. This does not
                                 * follow the standard but since multiple plinks
@@ -620,10 +619,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        sta->llid = llid;
                        mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid,
-                                           0, 0);
-                       mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr,
-                                           llid, plid, 0);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_OPEN,
+                                           sta->sta.addr, llid, 0, 0);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CONFIRM,
+                                           sta->sta.addr, llid, plid, 0);
                        break;
                default:
                        spin_unlock_bh(&sta->lock);
@@ -635,10 +636,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                switch (event) {
                case OPN_RJCT:
                case CNF_RJCT:
-                       reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                case CLS_ACPT:
                        if (!reason)
-                               reason = cpu_to_le16(MESH_CLOSE_RCVD);
+                               reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
                        sta->reason = reason;
                        sta->plink_state = NL80211_PLINK_HOLDING;
                        if (!mod_plink_timer(sta,
@@ -647,8 +648,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 
                        llid = sta->llid;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
-                                           plid, reason);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CLOSE,
+                                           sta->sta.addr, llid, plid, reason);
                        break;
                case OPN_ACPT:
                        /* retry timer is left untouched */
@@ -656,8 +658,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        sta->plid = plid;
                        llid = sta->llid;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
-                                           plid, 0);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CONFIRM,
+                                           sta->sta.addr, llid, plid, 0);
                        break;
                case CNF_ACPT:
                        sta->plink_state = NL80211_PLINK_CNF_RCVD;
@@ -677,10 +680,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                switch (event) {
                case OPN_RJCT:
                case CNF_RJCT:
-                       reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                case CLS_ACPT:
                        if (!reason)
-                               reason = cpu_to_le16(MESH_CLOSE_RCVD);
+                               reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
                        sta->reason = reason;
                        sta->plink_state = NL80211_PLINK_HOLDING;
                        if (!mod_plink_timer(sta,
@@ -689,14 +692,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 
                        llid = sta->llid;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
-                                           plid, reason);
+                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                                           sta->sta.addr, llid, plid, reason);
                        break;
                case OPN_ACPT:
                        llid = sta->llid;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
-                                           plid, 0);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CONFIRM,
+                                           sta->sta.addr, llid, plid, 0);
                        break;
                case CNF_ACPT:
                        del_timer(&sta->plink_timer);
@@ -717,10 +721,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                switch (event) {
                case OPN_RJCT:
                case CNF_RJCT:
-                       reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
+                       reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
                case CLS_ACPT:
                        if (!reason)
-                               reason = cpu_to_le16(MESH_CLOSE_RCVD);
+                               reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
                        sta->reason = reason;
                        sta->plink_state = NL80211_PLINK_HOLDING;
                        if (!mod_plink_timer(sta,
@@ -729,8 +733,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 
                        llid = sta->llid;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
-                                           plid, reason);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CLOSE,
+                                           sta->sta.addr, llid, plid, reason);
                        break;
                case OPN_ACPT:
                        del_timer(&sta->plink_timer);
@@ -740,8 +745,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
                        mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
                                sta->sta.addr);
-                       mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
-                                           plid, 0);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CONFIRM,
+                                           sta->sta.addr, llid, plid, 0);
                        break;
                default:
                        spin_unlock_bh(&sta->lock);
@@ -752,7 +758,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        case NL80211_PLINK_ESTAB:
                switch (event) {
                case CLS_ACPT:
-                       reason = cpu_to_le16(MESH_CLOSE_RCVD);
+                       reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
                        sta->reason = reason;
                        deactivated = __mesh_plink_deactivate(sta);
                        sta->plink_state = NL80211_PLINK_HOLDING;
@@ -761,14 +767,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        spin_unlock_bh(&sta->lock);
                        if (deactivated)
                                ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
-                       mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
-                                           plid, reason);
+                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                                           sta->sta.addr, llid, plid, reason);
                        break;
                case OPN_ACPT:
                        llid = sta->llid;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
-                                           plid, 0);
+                       mesh_plink_frame_tx(sdata,
+                                           WLAN_SP_MESH_PEERING_CONFIRM,
+                                           sta->sta.addr, llid, plid, 0);
                        break;
                default:
                        spin_unlock_bh(&sta->lock);
@@ -790,8 +797,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        llid = sta->llid;
                        reason = sta->reason;
                        spin_unlock_bh(&sta->lock);
-                       mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr,
-                                           llid, plid, reason);
+                       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                                           sta->sta.addr, llid, plid, reason);
                        break;
                default:
                        spin_unlock_bh(&sta->lock);
index d6470c7fd6ce34cd226632a30fac0e0be6c7f71f..9604abc61a596fa40830019afb4bd8f04b757d96 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/crc32.h>
 #include <linux/slab.h>
 #include <net/mac80211.h>
index 66a1eeb279c697f1fc11f0bc0ef17f5fbcd0d40b..21588386a30207598d9d565841f8f4caaaa08d50 100644 (file)
@@ -608,7 +608,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
                return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
 
        info->flags |= mi->tx_flags;
-       sample_idx = minstrel_get_sample_rate(mp, mi);
+
+       /* Don't use EAPOL frames for sampling on non-mrr hw */
+       if (mp->hw->max_rates == 1 &&
+           txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
+               sample_idx = -1;
+       else
+               sample_idx = minstrel_get_sample_rate(mp, mi);
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        /* use fixed index if set */
index fe2c2a7177930b2f7df8c42d81eac9987956c761..c4453fdd6e11f4dc82926b32fd51ce37cd1b149d 100644 (file)
@@ -2220,12 +2220,29 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        goto handled;
                }
                break;
+       case WLAN_CATEGORY_SELF_PROTECTED:
+               switch (mgmt->u.action.u.self_prot.action_code) {
+               case WLAN_SP_MESH_PEERING_OPEN:
+               case WLAN_SP_MESH_PEERING_CLOSE:
+               case WLAN_SP_MESH_PEERING_CONFIRM:
+                       if (!ieee80211_vif_is_mesh(&sdata->vif))
+                               goto invalid;
+                       if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
+                               /* userspace handles this frame */
+                               break;
+                       goto queue;
+               case WLAN_SP_MGK_INFORM:
+               case WLAN_SP_MGK_ACK:
+                       if (!ieee80211_vif_is_mesh(&sdata->vif))
+                               goto invalid;
+                       break;
+               }
+               break;
        case WLAN_CATEGORY_MESH_ACTION:
                if (!ieee80211_vif_is_mesh(&sdata->vif))
                        break;
-               goto queue;
-       case WLAN_CATEGORY_MESH_PATH_SEL:
-               if (!mesh_path_sel_is_hwmp(sdata))
+               if (mesh_action_is_path_sel(mgmt) &&
+                 (!mesh_path_sel_is_hwmp(sdata)))
                        break;
                goto queue;
        }
index 6f09eca011123de5dac20d3fed5f6712200fd112..beefb0afefa1fbbab3a1efea44ff19f099ebc40a 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <net/sch_generic.h>
 #include <linux/slab.h>
 #include <net/mac80211.h>
index 3db78b696c5ce4d6c844a4c0e81e4d3d7e32059a..0bdbf3b8f28b466648f2c5c38b2204f0fc042580 100644 (file)
@@ -72,7 +72,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
        if (!s)
                return -ENOENT;
        if (s == sta) {
-               rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
+               RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)],
                                   s->hnext);
                return 0;
        }
@@ -82,7 +82,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
                s = rcu_dereference_protected(s->hnext,
                                        lockdep_is_held(&local->sta_lock));
        if (rcu_access_pointer(s->hnext)) {
-               rcu_assign_pointer(s->hnext, sta->hnext);
+               RCU_INIT_POINTER(s->hnext, sta->hnext);
                return 0;
        }
 
@@ -184,7 +184,7 @@ static void sta_info_hash_add(struct ieee80211_local *local,
                              struct sta_info *sta)
 {
        sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)];
-       rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
+       RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
 }
 
 static void sta_unblock(struct work_struct *wk)
@@ -330,6 +330,7 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async)
        ieee80211_sta_debugfs_add(sta);
        rate_control_add_sta_debugfs(sta);
 
+       memset(&sinfo, 0, sizeof(sinfo));
        sinfo.filled = 0;
        sinfo.generation = local->sta_generation;
        cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
@@ -672,7 +673,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
        local->sta_generation++;
 
        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-               rcu_assign_pointer(sdata->u.vlan.sta, NULL);
+               RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
 
        if (sta->uploaded) {
                if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
index 1658efaa2e8eef4b042ec05ffd875cbd0d3c6ec1..e51bd2a1a0735de0adfff2566c5f1d6b584ef6de 100644 (file)
@@ -187,6 +187,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        int rates_idx = -1;
        bool send_to_cooked;
        bool acked;
+       struct ieee80211_bar *bar;
+       u16 tid;
 
        for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
                if (info->status.rates[i].idx < 0) {
@@ -243,6 +245,22 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                                           tid, ssn);
                }
 
+               if (!acked && ieee80211_is_back_req(fc)) {
+                       /*
+                        * BAR failed, let's tear down the BA session as a
+                        * last resort as some STAs (Intel 5100 on Windows)
+                        * can get stuck when the BA window isn't flushed
+                        * correctly.
+                        */
+                       bar = (struct ieee80211_bar *) skb->data;
+                       if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) {
+                               tid = (bar->control &
+                                      IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
+                                     IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
+                               ieee80211_stop_tx_ba_session(&sta->sta, tid);
+                       }
+               }
+
                if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
                        ieee80211_handle_filtered_frame(local, sta, skb);
                        rcu_read_unlock();
@@ -345,9 +363,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                        local->hw_roc_skb_for_status = NULL;
                }
 
-               if (cookie == local->hw_offchan_tx_cookie)
-                       local->hw_offchan_tx_cookie = 0;
-
                cfg80211_mgmt_tx_status(
                        skb->dev, cookie, skb->data, skb->len,
                        !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
index 8cb0d2d0ac69a72229dbf2bdf376959ed9737eb6..01072639666fb77bccceda47aad242c6ec241405 100644 (file)
@@ -1608,7 +1608,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
        struct ieee80211_radiotap_header *prthdr =
                (struct ieee80211_radiotap_header *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr;
        u16 len_rthdr;
+       u8 *payload;
 
        /*
         * Frame injection is not allowed if beaconing is not allowed
@@ -1659,6 +1661,24 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
        skb_set_network_header(skb, len_rthdr);
        skb_set_transport_header(skb, len_rthdr);
 
+       /*
+        * Initialize skb->protocol if the injected frame is a data frame
+        * carrying a rfc1042 header
+        */
+       if (skb->len > len_rthdr + 2) {
+               hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
+               if (ieee80211_is_data(hdr->frame_control) &&
+                   skb->len >= len_rthdr +
+                               ieee80211_hdrlen(hdr->frame_control) +
+                               sizeof(rfc1042_header) + 2) {
+                       payload = (u8 *)hdr +
+                                 ieee80211_hdrlen(hdr->frame_control);
+                       if (compare_ether_addr(payload, rfc1042_header) == 0)
+                               skb->protocol = cpu_to_be16((payload[6] << 8) |
+                                                           payload[7]);
+               }
+       }
+
        memset(info, 0, sizeof(*info));
 
        info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
@@ -2275,13 +2295,23 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
                mgmt->u.beacon.beacon_int =
                        cpu_to_le16(sdata->vif.bss_conf.beacon_int);
-               mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
+               mgmt->u.beacon.capab_info |= cpu_to_le16(
+                       sdata->u.mesh.security ? WLAN_CAPABILITY_PRIVACY : 0);
 
                pos = skb_put(skb, 2);
                *pos++ = WLAN_EID_SSID;
                *pos++ = 0x0;
 
-               mesh_mgmt_ies_add(skb, sdata);
+               if (mesh_add_srates_ie(skb, sdata) ||
+                   mesh_add_ds_params_ie(skb, sdata) ||
+                   mesh_add_ext_srates_ie(skb, sdata) ||
+                   mesh_add_rsn_ie(skb, sdata) ||
+                   mesh_add_meshid_ie(skb, sdata) ||
+                   mesh_add_meshconf_ie(skb, sdata) ||
+                   mesh_add_vendor_ies(skb, sdata)) {
+                       pr_err("o11s: couldn't add ies!\n");
+                       goto out;
+               }
        } else {
                WARN_ON(1);
                goto out;
index ddeb1b9983833006e414c3b42b0cf8b986f86fea..ce916ff6ef089d54b0e98f31126e054f88b86992 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <linux/bitmap.h>
-#include <linux/crc32.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
 #include <net/rtnetlink.h>
@@ -573,172 +572,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
        ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
 }
 
-u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
-                              struct ieee802_11_elems *elems,
-                              u64 filter, u32 crc)
-{
-       size_t left = len;
-       u8 *pos = start;
-       bool calc_crc = filter != 0;
-
-       memset(elems, 0, sizeof(*elems));
-       elems->ie_start = start;
-       elems->total_len = len;
-
-       while (left >= 2) {
-               u8 id, elen;
-
-               id = *pos++;
-               elen = *pos++;
-               left -= 2;
-
-               if (elen > left)
-                       break;
-
-               if (calc_crc && id < 64 && (filter & (1ULL << id)))
-                       crc = crc32_be(crc, pos - 2, elen + 2);
-
-               switch (id) {
-               case WLAN_EID_SSID:
-                       elems->ssid = pos;
-                       elems->ssid_len = elen;
-                       break;
-               case WLAN_EID_SUPP_RATES:
-                       elems->supp_rates = pos;
-                       elems->supp_rates_len = elen;
-                       break;
-               case WLAN_EID_FH_PARAMS:
-                       elems->fh_params = pos;
-                       elems->fh_params_len = elen;
-                       break;
-               case WLAN_EID_DS_PARAMS:
-                       elems->ds_params = pos;
-                       elems->ds_params_len = elen;
-                       break;
-               case WLAN_EID_CF_PARAMS:
-                       elems->cf_params = pos;
-                       elems->cf_params_len = elen;
-                       break;
-               case WLAN_EID_TIM:
-                       if (elen >= sizeof(struct ieee80211_tim_ie)) {
-                               elems->tim = (void *)pos;
-                               elems->tim_len = elen;
-                       }
-                       break;
-               case WLAN_EID_IBSS_PARAMS:
-                       elems->ibss_params = pos;
-                       elems->ibss_params_len = elen;
-                       break;
-               case WLAN_EID_CHALLENGE:
-                       elems->challenge = pos;
-                       elems->challenge_len = elen;
-                       break;
-               case WLAN_EID_VENDOR_SPECIFIC:
-                       if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
-                           pos[2] == 0xf2) {
-                               /* Microsoft OUI (00:50:F2) */
-
-                               if (calc_crc)
-                                       crc = crc32_be(crc, pos - 2, elen + 2);
-
-                               if (pos[3] == 1) {
-                                       /* OUI Type 1 - WPA IE */
-                                       elems->wpa = pos;
-                                       elems->wpa_len = elen;
-                               } else if (elen >= 5 && pos[3] == 2) {
-                                       /* OUI Type 2 - WMM IE */
-                                       if (pos[4] == 0) {
-                                               elems->wmm_info = pos;
-                                               elems->wmm_info_len = elen;
-                                       } else if (pos[4] == 1) {
-                                               elems->wmm_param = pos;
-                                               elems->wmm_param_len = elen;
-                                       }
-                               }
-                       }
-                       break;
-               case WLAN_EID_RSN:
-                       elems->rsn = pos;
-                       elems->rsn_len = elen;
-                       break;
-               case WLAN_EID_ERP_INFO:
-                       elems->erp_info = pos;
-                       elems->erp_info_len = elen;
-                       break;
-               case WLAN_EID_EXT_SUPP_RATES:
-                       elems->ext_supp_rates = pos;
-                       elems->ext_supp_rates_len = elen;
-                       break;
-               case WLAN_EID_HT_CAPABILITY:
-                       if (elen >= sizeof(struct ieee80211_ht_cap))
-                               elems->ht_cap_elem = (void *)pos;
-                       break;
-               case WLAN_EID_HT_INFORMATION:
-                       if (elen >= sizeof(struct ieee80211_ht_info))
-                               elems->ht_info_elem = (void *)pos;
-                       break;
-               case WLAN_EID_MESH_ID:
-                       elems->mesh_id = pos;
-                       elems->mesh_id_len = elen;
-                       break;
-               case WLAN_EID_MESH_CONFIG:
-                       if (elen >= sizeof(struct ieee80211_meshconf_ie))
-                               elems->mesh_config = (void *)pos;
-                       break;
-               case WLAN_EID_PEER_LINK:
-                       elems->peer_link = pos;
-                       elems->peer_link_len = elen;
-                       break;
-               case WLAN_EID_PREQ:
-                       elems->preq = pos;
-                       elems->preq_len = elen;
-                       break;
-               case WLAN_EID_PREP:
-                       elems->prep = pos;
-                       elems->prep_len = elen;
-                       break;
-               case WLAN_EID_PERR:
-                       elems->perr = pos;
-                       elems->perr_len = elen;
-                       break;
-               case WLAN_EID_RANN:
-                       if (elen >= sizeof(struct ieee80211_rann_ie))
-                               elems->rann = (void *)pos;
-                       break;
-               case WLAN_EID_CHANNEL_SWITCH:
-                       elems->ch_switch_elem = pos;
-                       elems->ch_switch_elem_len = elen;
-                       break;
-               case WLAN_EID_QUIET:
-                       if (!elems->quiet_elem) {
-                               elems->quiet_elem = pos;
-                               elems->quiet_elem_len = elen;
-                       }
-                       elems->num_of_quiet_elem++;
-                       break;
-               case WLAN_EID_COUNTRY:
-                       elems->country_elem = pos;
-                       elems->country_elem_len = elen;
-                       break;
-               case WLAN_EID_PWR_CONSTRAINT:
-                       elems->pwr_constr_elem = pos;
-                       elems->pwr_constr_elem_len = elen;
-                       break;
-               case WLAN_EID_TIMEOUT_INTERVAL:
-                       elems->timeout_int = pos;
-                       elems->timeout_int_len = elen;
-                       break;
-               default:
-                       break;
-               }
-
-               left -= elen;
-               pos += elen;
-       }
-
-       return crc;
-}
-
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
@@ -1205,6 +1038,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                             struct ieee80211_sub_if_data,
                                             u.ap);
 
+                       memset(&sta->sta.drv_priv, 0, hw->sta_data_size);
                        WARN_ON(drv_sta_add(local, sdata, &sta->sta));
                }
        }
index 899b71c0ff5d0a4c8004e5c8a3cef27aa3a173cc..3346829ea07f09e28107c4b227d8b5d5763be30b 100644 (file)
@@ -37,7 +37,7 @@ int nf_register_afinfo(const struct nf_afinfo *afinfo)
        err = mutex_lock_interruptible(&afinfo_mutex);
        if (err < 0)
                return err;
-       rcu_assign_pointer(nf_afinfo[afinfo->family], afinfo);
+       RCU_INIT_POINTER(nf_afinfo[afinfo->family], afinfo);
        mutex_unlock(&afinfo_mutex);
        return 0;
 }
@@ -46,7 +46,7 @@ EXPORT_SYMBOL_GPL(nf_register_afinfo);
 void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
 {
        mutex_lock(&afinfo_mutex);
-       rcu_assign_pointer(nf_afinfo[afinfo->family], NULL);
+       RCU_INIT_POINTER(nf_afinfo[afinfo->family], NULL);
        mutex_unlock(&afinfo_mutex);
        synchronize_rcu();
 }
index f7af8b866017040600fb842d9441ff4fa9912fc7..5acfaf59a9c3c26547f001d453ebd9a00a912f77 100644 (file)
@@ -779,7 +779,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
                if (exp->helper) {
                        help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
                        if (help)
-                               rcu_assign_pointer(help->helper, exp->helper);
+                               RCU_INIT_POINTER(help->helper, exp->helper);
                }
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
@@ -1317,7 +1317,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
 void nf_conntrack_cleanup(struct net *net)
 {
        if (net_eq(net, &init_net))
-               rcu_assign_pointer(ip_ct_attach, NULL);
+               RCU_INIT_POINTER(ip_ct_attach, NULL);
 
        /* This makes sure all current packets have passed through
           netfilter framework.  Roll on, two-stage module
@@ -1327,7 +1327,7 @@ void nf_conntrack_cleanup(struct net *net)
        nf_conntrack_cleanup_net(net);
 
        if (net_eq(net, &init_net)) {
-               rcu_assign_pointer(nf_ct_destroy, NULL);
+               RCU_INIT_POINTER(nf_ct_destroy, NULL);
                nf_conntrack_cleanup_init_net();
        }
 }
@@ -1576,11 +1576,11 @@ int nf_conntrack_init(struct net *net)
 
        if (net_eq(net, &init_net)) {
                /* For use by REJECT target */
-               rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
-               rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
+               RCU_INIT_POINTER(ip_ct_attach, nf_conntrack_attach);
+               RCU_INIT_POINTER(nf_ct_destroy, destroy_conntrack);
 
                /* Howto get NAT offsets */
-               rcu_assign_pointer(nf_ct_nat_offset, NULL);
+               RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
        }
        return 0;
 
index 63a1b915a7e40e4871f14dad9170b542aaf9a75a..3add994390596231802aed21169e570313d797bb 100644 (file)
@@ -94,7 +94,7 @@ int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
                ret = -EBUSY;
                goto out_unlock;
        }
-       rcu_assign_pointer(nf_conntrack_event_cb, new);
+       RCU_INIT_POINTER(nf_conntrack_event_cb, new);
        mutex_unlock(&nf_ct_ecache_mutex);
        return ret;
 
@@ -112,7 +112,7 @@ void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
        notify = rcu_dereference_protected(nf_conntrack_event_cb,
                                           lockdep_is_held(&nf_ct_ecache_mutex));
        BUG_ON(notify != new);
-       rcu_assign_pointer(nf_conntrack_event_cb, NULL);
+       RCU_INIT_POINTER(nf_conntrack_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
@@ -129,7 +129,7 @@ int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
                ret = -EBUSY;
                goto out_unlock;
        }
-       rcu_assign_pointer(nf_expect_event_cb, new);
+       RCU_INIT_POINTER(nf_expect_event_cb, new);
        mutex_unlock(&nf_ct_ecache_mutex);
        return ret;
 
@@ -147,7 +147,7 @@ void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
        notify = rcu_dereference_protected(nf_expect_event_cb,
                                           lockdep_is_held(&nf_ct_ecache_mutex));
        BUG_ON(notify != new);
-       rcu_assign_pointer(nf_expect_event_cb, NULL);
+       RCU_INIT_POINTER(nf_expect_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
index 05ecdc281a53da8b7e524ca80fdd7c85e882302b..4605c947dcc49e751478aaffb816e17470998185 100644 (file)
@@ -169,7 +169,7 @@ int nf_ct_extend_register(struct nf_ct_ext_type *type)
           before updating alloc_size */
        type->alloc_size = ALIGN(sizeof(struct nf_ct_ext), type->align)
                           + type->len;
-       rcu_assign_pointer(nf_ct_ext_types[type->id], type);
+       RCU_INIT_POINTER(nf_ct_ext_types[type->id], type);
        update_alloc_size(type);
 out:
        mutex_unlock(&nf_ct_ext_type_mutex);
@@ -181,7 +181,7 @@ EXPORT_SYMBOL_GPL(nf_ct_extend_register);
 void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
 {
        mutex_lock(&nf_ct_ext_type_mutex);
-       rcu_assign_pointer(nf_ct_ext_types[type->id], NULL);
+       RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL);
        update_alloc_size(type);
        mutex_unlock(&nf_ct_ext_type_mutex);
        rcu_barrier(); /* Wait for completion of call_rcu()'s */
index 1bdfea3579552e2ab1048bffb392ba469d0673c1..93c4bdbfc1ae52da32a1e466ca9ca881665041bb 100644 (file)
@@ -131,7 +131,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
                helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
        if (helper == NULL) {
                if (help)
-                       rcu_assign_pointer(help->helper, NULL);
+                       RCU_INIT_POINTER(help->helper, NULL);
                goto out;
        }
 
@@ -145,7 +145,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
                memset(&help->help, 0, sizeof(help->help));
        }
 
-       rcu_assign_pointer(help->helper, helper);
+       RCU_INIT_POINTER(help->helper, helper);
 out:
        return ret;
 }
@@ -162,7 +162,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
                        lockdep_is_held(&nf_conntrack_lock)
                        ) == me) {
                nf_conntrack_event(IPCT_HELPER, ct);
-               rcu_assign_pointer(help->helper, NULL);
+               RCU_INIT_POINTER(help->helper, NULL);
        }
        return 0;
 }
index 7dec88a1755b9fddcd1fb9d03c66fd54c396eac6..e58aa9b1fe8a043226c4bc7ee90f5145a7adc316 100644 (file)
@@ -1125,7 +1125,7 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
                if (help && help->helper) {
                        /* we had a helper before ... */
                        nf_ct_remove_expectations(ct);
-                       rcu_assign_pointer(help->helper, NULL);
+                       RCU_INIT_POINTER(help->helper, NULL);
                }
 
                return 0;
@@ -1163,7 +1163,7 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
                return -EOPNOTSUPP;
        }
 
-       rcu_assign_pointer(help->helper, helper);
+       RCU_INIT_POINTER(help->helper, helper);
 
        return 0;
 }
@@ -1386,7 +1386,7 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
                        }
 
                        /* not in hash table yet so not strictly necessary */
-                       rcu_assign_pointer(help->helper, helper);
+                       RCU_INIT_POINTER(help->helper, helper);
                }
        } else {
                /* try an implicit helper assignation */
index 20714edf6cd2a16699100380b90f77f305898162..ce0c406f58a8b645cc4500c85dfad2008d0db70d 100644 (file)
@@ -55,7 +55,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
                llog = rcu_dereference_protected(nf_loggers[pf],
                                                 lockdep_is_held(&nf_log_mutex));
                if (llog == NULL)
-                       rcu_assign_pointer(nf_loggers[pf], logger);
+                       RCU_INIT_POINTER(nf_loggers[pf], logger);
        }
 
        mutex_unlock(&nf_log_mutex);
@@ -74,7 +74,7 @@ void nf_log_unregister(struct nf_logger *logger)
                c_logger = rcu_dereference_protected(nf_loggers[i],
                                                     lockdep_is_held(&nf_log_mutex));
                if (c_logger == logger)
-                       rcu_assign_pointer(nf_loggers[i], NULL);
+                       RCU_INIT_POINTER(nf_loggers[i], NULL);
                list_del(&logger->list[i]);
        }
        mutex_unlock(&nf_log_mutex);
@@ -92,7 +92,7 @@ int nf_log_bind_pf(u_int8_t pf, const struct nf_logger *logger)
                mutex_unlock(&nf_log_mutex);
                return -ENOENT;
        }
-       rcu_assign_pointer(nf_loggers[pf], logger);
+       RCU_INIT_POINTER(nf_loggers[pf], logger);
        mutex_unlock(&nf_log_mutex);
        return 0;
 }
@@ -103,7 +103,7 @@ void nf_log_unbind_pf(u_int8_t pf)
        if (pf >= ARRAY_SIZE(nf_loggers))
                return;
        mutex_lock(&nf_log_mutex);
-       rcu_assign_pointer(nf_loggers[pf], NULL);
+       RCU_INIT_POINTER(nf_loggers[pf], NULL);
        mutex_unlock(&nf_log_mutex);
 }
 EXPORT_SYMBOL(nf_log_unbind_pf);
@@ -250,7 +250,7 @@ static int nf_log_proc_dostring(ctl_table *table, int write,
                        mutex_unlock(&nf_log_mutex);
                        return -ENOENT;
                }
-               rcu_assign_pointer(nf_loggers[tindex], logger);
+               RCU_INIT_POINTER(nf_loggers[tindex], logger);
                mutex_unlock(&nf_log_mutex);
        } else {
                mutex_lock(&nf_log_mutex);
index 84d0fd47636a19cbc5c16b0f3847f131e58ed876..99ffd2885088fc3606270984386713b959b75285 100644 (file)
@@ -40,7 +40,7 @@ int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
        else if (old)
                ret = -EBUSY;
        else {
-               rcu_assign_pointer(queue_handler[pf], qh);
+               RCU_INIT_POINTER(queue_handler[pf], qh);
                ret = 0;
        }
        mutex_unlock(&queue_handler_mutex);
@@ -65,7 +65,7 @@ int nf_unregister_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
                return -EINVAL;
        }
 
-       rcu_assign_pointer(queue_handler[pf], NULL);
+       RCU_INIT_POINTER(queue_handler[pf], NULL);
        mutex_unlock(&queue_handler_mutex);
 
        synchronize_rcu();
@@ -84,7 +84,7 @@ void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)
                                queue_handler[pf],
                                lockdep_is_held(&queue_handler_mutex)
                                ) == qh)
-                       rcu_assign_pointer(queue_handler[pf], NULL);
+                       RCU_INIT_POINTER(queue_handler[pf], NULL);
        }
        mutex_unlock(&queue_handler_mutex);
 
index 1905976b5135ec1d8157f251809498c70605c704..c879c1a2370e46829c442095b98a58ce705d78b3 100644 (file)
@@ -59,7 +59,7 @@ int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
                nfnl_unlock();
                return -EBUSY;
        }
-       rcu_assign_pointer(subsys_table[n->subsys_id], n);
+       RCU_INIT_POINTER(subsys_table[n->subsys_id], n);
        nfnl_unlock();
 
        return 0;
@@ -210,7 +210,7 @@ static int __net_init nfnetlink_net_init(struct net *net)
        if (!nfnl)
                return -ENOMEM;
        net->nfnl_stash = nfnl;
-       rcu_assign_pointer(net->nfnl, nfnl);
+       RCU_INIT_POINTER(net->nfnl, nfnl);
        return 0;
 }
 
@@ -219,7 +219,7 @@ static void __net_exit nfnetlink_net_exit_batch(struct list_head *net_exit_list)
        struct net *net;
 
        list_for_each_entry(net, net_exit_list, exit_list)
-               rcu_assign_pointer(net->nfnl, NULL);
+               RCU_INIT_POINTER(net->nfnl, NULL);
        synchronize_net();
        list_for_each_entry(net, net_exit_list, exit_list)
                netlink_kernel_release(net->nfnl_stash);
index 7d8083cde34f4019d6f1d0e10835a9d87cc69b03..3f905e5370c28eed56d3d1404917114b973c1b0b 100644 (file)
@@ -282,7 +282,7 @@ int __init netlbl_domhsh_init(u32 size)
                INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);
 
        spin_lock(&netlbl_domhsh_lock);
-       rcu_assign_pointer(netlbl_domhsh, hsh_tbl);
+       RCU_INIT_POINTER(netlbl_domhsh, hsh_tbl);
        spin_unlock(&netlbl_domhsh_lock);
 
        return 0;
@@ -330,7 +330,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
                                    &rcu_dereference(netlbl_domhsh)->tbl[bkt]);
                } else {
                        INIT_LIST_HEAD(&entry->list);
-                       rcu_assign_pointer(netlbl_domhsh_def, entry);
+                       RCU_INIT_POINTER(netlbl_domhsh_def, entry);
                }
 
                if (entry->type == NETLBL_NLTYPE_ADDRSELECT) {
@@ -451,7 +451,7 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
                if (entry != rcu_dereference(netlbl_domhsh_def))
                        list_del_rcu(&entry->list);
                else
-                       rcu_assign_pointer(netlbl_domhsh_def, NULL);
+                       RCU_INIT_POINTER(netlbl_domhsh_def, NULL);
        } else
                ret_val = -ENOENT;
        spin_unlock(&netlbl_domhsh_lock);
index e6e823656f9dd1cdba6b37a846e52563cb6828d9..e251c2c88521dac541700d7ce1b318ae9f5f23b6 100644 (file)
@@ -354,7 +354,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
                INIT_LIST_HEAD(&iface->list);
                if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
                        goto add_iface_failure;
-               rcu_assign_pointer(netlbl_unlhsh_def, iface);
+               RCU_INIT_POINTER(netlbl_unlhsh_def, iface);
        }
        spin_unlock(&netlbl_unlhsh_lock);
 
@@ -621,7 +621,7 @@ static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface)
        if (iface->ifindex > 0)
                list_del_rcu(&iface->list);
        else
-               rcu_assign_pointer(netlbl_unlhsh_def, NULL);
+               RCU_INIT_POINTER(netlbl_unlhsh_def, NULL);
        spin_unlock(&netlbl_unlhsh_lock);
 
        call_rcu(&iface->rcu, netlbl_unlhsh_free_iface);
@@ -1449,7 +1449,7 @@ int __init netlbl_unlabel_init(u32 size)
 
        rcu_read_lock();
        spin_lock(&netlbl_unlhsh_lock);
-       rcu_assign_pointer(netlbl_unlhsh, hsh_tbl);
+       RCU_INIT_POINTER(netlbl_unlhsh, hsh_tbl);
        spin_unlock(&netlbl_unlhsh_lock);
        rcu_read_unlock();
 
index 0a4db0211da08416dc23bc55bfb5b203809bbd34..4330db99fabff3457e34c504aad8785fad38cb7f 100644 (file)
@@ -1578,7 +1578,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
                new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
                if (!new)
                        return -ENOMEM;
-               old = rcu_dereference_raw(tbl->listeners);
+               old = rcu_dereference_protected(tbl->listeners, 1);
                memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
                rcu_assign_pointer(tbl->listeners, new);
 
index c6fffd946d42e4dc44b818a7b194b3a92274aa2e..bf10ea8fbbf95bd349d0f69f18527a524d5d3a9c 100644 (file)
@@ -480,7 +480,7 @@ int __init_or_module phonet_proto_register(unsigned int protocol,
        if (proto_tab[protocol])
                err = -EBUSY;
        else
-               rcu_assign_pointer(proto_tab[protocol], pp);
+               RCU_INIT_POINTER(proto_tab[protocol], pp);
        mutex_unlock(&proto_tab_lock);
 
        return err;
@@ -491,7 +491,7 @@ void phonet_proto_unregister(unsigned int protocol, struct phonet_protocol *pp)
 {
        mutex_lock(&proto_tab_lock);
        BUG_ON(proto_tab[protocol] != pp);
-       rcu_assign_pointer(proto_tab[protocol], NULL);
+       RCU_INIT_POINTER(proto_tab[protocol], NULL);
        mutex_unlock(&proto_tab_lock);
        synchronize_rcu();
        proto_unregister(pp->prot);
index d2df8f33160bd1db3e659a9e9dc83f1b879e44bb..c5827614376bd18c668a99d76b1b61f4b9f57011 100644 (file)
@@ -276,7 +276,7 @@ static void phonet_route_autodel(struct net_device *dev)
        mutex_lock(&pnn->routes.lock);
        for (i = 0; i < 64; i++)
                if (dev == pnn->routes.table[i]) {
-                       rcu_assign_pointer(pnn->routes.table[i], NULL);
+                       RCU_INIT_POINTER(pnn->routes.table[i], NULL);
                        set_bit(i, deleted);
                }
        mutex_unlock(&pnn->routes.lock);
@@ -390,7 +390,7 @@ int phonet_route_add(struct net_device *dev, u8 daddr)
        daddr = daddr >> 2;
        mutex_lock(&routes->lock);
        if (routes->table[daddr] == NULL) {
-               rcu_assign_pointer(routes->table[daddr], dev);
+               RCU_INIT_POINTER(routes->table[daddr], dev);
                dev_hold(dev);
                err = 0;
        }
@@ -406,7 +406,7 @@ int phonet_route_del(struct net_device *dev, u8 daddr)
        daddr = daddr >> 2;
        mutex_lock(&routes->lock);
        if (dev == routes->table[daddr])
-               rcu_assign_pointer(routes->table[daddr], NULL);
+               RCU_INIT_POINTER(routes->table[daddr], NULL);
        else
                dev = NULL;
        mutex_unlock(&routes->lock);
index ab07711cf2f40e161cd0602678ce3b4555ab68b3..676d18dc75b76fb4cb036c8465f9a29a6697389d 100644 (file)
@@ -679,7 +679,7 @@ int pn_sock_bind_res(struct sock *sk, u8 res)
        mutex_lock(&resource_mutex);
        if (pnres.sk[res] == NULL) {
                sock_hold(sk);
-               rcu_assign_pointer(pnres.sk[res], sk);
+               RCU_INIT_POINTER(pnres.sk[res], sk);
                ret = 0;
        }
        mutex_unlock(&resource_mutex);
@@ -695,7 +695,7 @@ int pn_sock_unbind_res(struct sock *sk, u8 res)
 
        mutex_lock(&resource_mutex);
        if (pnres.sk[res] == sk) {
-               rcu_assign_pointer(pnres.sk[res], NULL);
+               RCU_INIT_POINTER(pnres.sk[res], NULL);
                ret = 0;
        }
        mutex_unlock(&resource_mutex);
@@ -714,7 +714,7 @@ void pn_sock_unbind_all_res(struct sock *sk)
        mutex_lock(&resource_mutex);
        for (res = 0; res < 256; res++) {
                if (pnres.sk[res] == sk) {
-                       rcu_assign_pointer(pnres.sk[res], NULL);
+                       RCU_INIT_POINTER(pnres.sk[res], NULL);
                        match++;
                }
        }
index 102fc212cd64093726dffa311ba41716d2cc0250..e051398fdf6baf4834bbe21bf13deac081594148 100644 (file)
@@ -196,8 +196,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
 
        skb2->skb_iif = skb->dev->ifindex;
        skb2->dev = dev;
-       dev_queue_xmit(skb2);
-       err = 0;
+       err = dev_queue_xmit(skb2);
 
 out:
        if (err) {
index 24a77400b65e4e8fd63f825144bdc4891b5fced9..2517e11a53008ec397582c67c4cff0c52cd18d16 100644 (file)
@@ -2470,7 +2470,7 @@ int sock_register(const struct net_proto_family *ops)
                                      lockdep_is_held(&net_family_lock)))
                err = -EEXIST;
        else {
-               rcu_assign_pointer(net_families[ops->family], ops);
+               RCU_INIT_POINTER(net_families[ops->family], ops);
                err = 0;
        }
        spin_unlock(&net_family_lock);
@@ -2498,7 +2498,7 @@ void sock_unregister(int family)
        BUG_ON(family < 0 || family >= NPROTO);
 
        spin_lock(&net_family_lock);
-       rcu_assign_pointer(net_families[family], NULL);
+       RCU_INIT_POINTER(net_families[family], NULL);
        spin_unlock(&net_family_lock);
 
        synchronize_rcu();
index 364eb45e989d6c4fbdc70c182c032cb59b6270b3..d4132754cbe1555370866ed26bb9b26831355915 100644 (file)
@@ -122,7 +122,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
        if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
                return;
        gss_get_ctx(ctx);
-       rcu_assign_pointer(gss_cred->gc_ctx, ctx);
+       RCU_INIT_POINTER(gss_cred->gc_ctx, ctx);
        set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
        smp_mb__before_clear_bit();
        clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
@@ -970,7 +970,7 @@ gss_destroy_nullcred(struct rpc_cred *cred)
        struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
        struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
 
-       rcu_assign_pointer(gss_cred->gc_ctx, NULL);
+       RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
        call_rcu(&cred->cr_rcu, gss_free_cred_callback);
        if (ctx)
                gss_put_ctx(ctx);
index 645437cfc464d505a3673870f8c0a6eb73287535..c14865172da70d0fd04918f503d0714042ec5e64 100644 (file)
@@ -616,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy)
        if (res)
                goto out_rm_dev;
 
+       rtnl_lock();
+       rdev->wiphy.registered = true;
+       rtnl_unlock();
        return 0;
 
 out_rm_dev:
@@ -647,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
+       rtnl_lock();
+       rdev->wiphy.registered = false;
+       rtnl_unlock();
+
        rfkill_unregister(rdev->rfkill);
 
        /* protect the device list */
index 3268fac5ab22d3551d6c1573f55a2f2fd9fd23e5..a55c27b75ee5667a7046ad54855f8ddd90c57b05 100644 (file)
@@ -41,6 +41,11 @@ struct lib80211_crypto_alg {
 static LIST_HEAD(lib80211_crypto_algs);
 static DEFINE_SPINLOCK(lib80211_crypto_lock);
 
+static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
+                                         int force);
+static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info);
+static void lib80211_crypt_deinit_handler(unsigned long data);
+
 const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
 {
        const char *s = ssid;
@@ -111,7 +116,8 @@ void lib80211_crypt_info_free(struct lib80211_crypt_info *info)
 }
 EXPORT_SYMBOL(lib80211_crypt_info_free);
 
-void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force)
+static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
+                                         int force)
 {
        struct lib80211_crypt_data *entry, *next;
        unsigned long flags;
@@ -131,10 +137,9 @@ void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force)
        }
        spin_unlock_irqrestore(info->lock, flags);
 }
-EXPORT_SYMBOL(lib80211_crypt_deinit_entries);
 
 /* After this, crypt_deinit_list won't accept new members */
-void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
+static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
 {
        unsigned long flags;
 
@@ -142,9 +147,8 @@ void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
        info->crypt_quiesced = 1;
        spin_unlock_irqrestore(info->lock, flags);
 }
-EXPORT_SYMBOL(lib80211_crypt_quiescing);
 
-void lib80211_crypt_deinit_handler(unsigned long data)
+static void lib80211_crypt_deinit_handler(unsigned long data)
 {
        struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
        unsigned long flags;
@@ -160,7 +164,6 @@ void lib80211_crypt_deinit_handler(unsigned long data)
        }
        spin_unlock_irqrestore(info->lock, flags);
 }
-EXPORT_SYMBOL(lib80211_crypt_deinit_handler);
 
 void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
                                    struct lib80211_crypt_data **crypt)
index e83e7fee3bc032def174d7741e6e419d693d2401..2aa6a2189842982b199272438951583f97ee23bd 100644 (file)
 #include "nl80211.h"
 #include "reg.h"
 
+static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type);
+static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
+                                  struct genl_info *info,
+                                  struct cfg80211_crypto_settings *settings,
+                                  int cipher_limit);
+
 static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
                            struct genl_info *info);
 static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
@@ -178,6 +184,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
        [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
        [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
+       [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
+       [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
+                                        .len = IEEE80211_MAX_DATA_LEN },
+       [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
+                                        .len = IEEE80211_MAX_DATA_LEN },
 };
 
 /* policy for the key attributes */
@@ -871,8 +882,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
                            dev->wiphy.max_remain_on_channel_duration);
 
-       /* for now at least assume all drivers have it */
-       if (dev->ops->mgmt_tx)
+       if (dev->ops->mgmt_tx_cancel_wait)
                NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
 
        if (mgmt_stypes) {
@@ -1985,7 +1995,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
        struct beacon_parameters params;
        int haveinfo = 0, err;
 
-       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
+           !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
+           !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
+           !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
                return -EINVAL;
 
        if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
@@ -2011,6 +2024,49 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
                if (err)
                        return err;
 
+               /*
+                * In theory, some of these attributes could be required for
+                * NEW_BEACON, but since they were not used when the command was
+                * originally added, keep them optional for old user space
+                * programs to work with drivers that do not need the additional
+                * information.
+                */
+               if (info->attrs[NL80211_ATTR_SSID]) {
+                       params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+                       params.ssid_len =
+                               nla_len(info->attrs[NL80211_ATTR_SSID]);
+                       if (params.ssid_len == 0 ||
+                           params.ssid_len > IEEE80211_MAX_SSID_LEN)
+                               return -EINVAL;
+               }
+
+               if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
+                       params.hidden_ssid = nla_get_u32(
+                               info->attrs[NL80211_ATTR_HIDDEN_SSID]);
+                       if (params.hidden_ssid !=
+                           NL80211_HIDDEN_SSID_NOT_IN_USE &&
+                           params.hidden_ssid !=
+                           NL80211_HIDDEN_SSID_ZERO_LEN &&
+                           params.hidden_ssid !=
+                           NL80211_HIDDEN_SSID_ZERO_CONTENTS)
+                               return -EINVAL;
+               }
+
+               params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
+
+               if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+                       params.auth_type = nla_get_u32(
+                               info->attrs[NL80211_ATTR_AUTH_TYPE]);
+                       if (!nl80211_valid_auth_type(params.auth_type))
+                               return -EINVAL;
+               } else
+                       params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+
+               err = nl80211_crypto_settings(rdev, info, &params.crypto,
+                                             NL80211_MAX_NR_CIPHER_SUITES);
+               if (err)
+                       return err;
+
                call = rdev->ops->add_beacon;
                break;
        case NL80211_CMD_SET_BEACON:
@@ -2041,6 +2097,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
        if (!haveinfo)
                return -EINVAL;
 
+       if (info->attrs[NL80211_ATTR_IE]) {
+               params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
+               params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+       }
+
+       if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
+               params.proberesp_ies =
+                       nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
+               params.proberesp_ies_len =
+                       nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
+       }
+
+       if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
+               params.assocresp_ies =
+                       nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
+               params.assocresp_ies_len =
+                       nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
+       }
+
        err = call(&rdev->wiphy, dev, &params);
        if (!err && params.interval)
                wdev->beacon_interval = params.interval;
@@ -2237,6 +2312,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
        }
        nla_nest_end(msg, sinfoattr);
 
+       if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+               NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+                       sinfo->assoc_req_ies);
+
        return genlmsg_end(msg, hdr);
 
  nla_put_failure:
@@ -2264,6 +2343,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
        }
 
        while (1) {
+               memset(&sinfo, 0, sizeof(sinfo));
                err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
                                             mac_addr, &sinfo);
                if (err == -ENOENT)
index 02751dbc5a97fab55abdefb9936dfc24c2d4ef22..9f3aa5cabdefec4102d2c3f5bca167c62cbc8bdf 100644 (file)
 #include "nl80211.h"
 
 #ifdef CONFIG_CFG80211_REG_DEBUG
-#define REG_DBG_PRINT(format, args...) \
-       do { \
-               printk(KERN_DEBUG pr_fmt(format), ##args);      \
-       } while (0)
+#define REG_DBG_PRINT(format, args...)                 \
+       printk(KERN_DEBUG pr_fmt(format), ##args)
 #else
 #define REG_DBG_PRINT(args...)
 #endif
@@ -890,7 +888,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
            wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
                REG_DBG_PRINT("Ignoring regulatory request %s "
                              "since the driver uses its own custom "
-                             "regulatory domain ",
+                             "regulatory domain\n",
                              reg_initiator_name(initiator));
                return true;
        }
@@ -904,7 +902,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
            !is_world_regdom(last_request->alpha2)) {
                REG_DBG_PRINT("Ignoring regulatory request %s "
                              "since the driver requires its own regulatory "
-                             "domain to be set first",
+                             "domain to be set first\n",
                              reg_initiator_name(initiator));
                return true;
        }
@@ -1474,7 +1472,7 @@ static void reg_process_pending_hints(void)
        /* When last_request->processed becomes true this will be rescheduled */
        if (last_request && !last_request->processed) {
                REG_DBG_PRINT("Pending regulatory request, waiting "
-                             "for it to be processed...");
+                             "for it to be processed...\n");
                goto out;
        }
 
@@ -2187,7 +2185,7 @@ out:
 static void reg_timeout_work(struct work_struct *work)
 {
        REG_DBG_PRINT("Timeout while waiting for CRDA to reply, "
-                     "restoring regulatory settings");
+                     "restoring regulatory settings\n");
        restore_regulatory_settings(true);
 }
 
index 2936cb809152cd77451147c22045924396026bbc..b0f0039669536164f0f9d67147030f3f43c8a0a0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/etherdevice.h>
 #include <net/arp.h>
 #include <net/cfg80211.h>
+#include <net/cfg80211-wext.h>
 #include <net/iw_handler.h>
 #include "core.h"
 #include "nl80211.h"
index c6e4ca6a7d2e0b1fcc6e450b1255a0140ae64cff..ff574597a8544030ef18b2e2186354ef46511bc3 100644 (file)
@@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
 
        if (rdev->ops->suspend) {
                rtnl_lock();
-               ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
+               if (rdev->wiphy.registered)
+                       ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
                rtnl_unlock();
        }
 
@@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev)
 
        if (rdev->ops->resume) {
                rtnl_lock();
-               ret = rdev->ops->resume(&rdev->wiphy);
+               if (rdev->wiphy.registered)
+                       ret = rdev->ops->resume(&rdev->wiphy);
                rtnl_unlock();
        }
 
index be75a3a0424eccdf31b895f8cb7e23eddb566a5b..eef82f79554dba1fdce02daddcee9178635716e3 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/bitops.h>
 #include <linux/etherdevice.h>
 #include <linux/slab.h>
+#include <linux/crc32.h>
 #include <net/cfg80211.h>
 #include <net/ip.h>
 #include "core.h"
@@ -1044,3 +1045,170 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
 
        return 0;
 }
+
+u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
+                              struct ieee802_11_elems *elems,
+                              u64 filter, u32 crc)
+{
+       size_t left = len;
+       u8 *pos = start;
+       bool calc_crc = filter != 0;
+
+       memset(elems, 0, sizeof(*elems));
+       elems->ie_start = start;
+       elems->total_len = len;
+
+       while (left >= 2) {
+               u8 id, elen;
+
+               id = *pos++;
+               elen = *pos++;
+               left -= 2;
+
+               if (elen > left)
+                       break;
+
+               if (calc_crc && id < 64 && (filter & (1ULL << id)))
+                       crc = crc32_be(crc, pos - 2, elen + 2);
+
+               switch (id) {
+               case WLAN_EID_SSID:
+                       elems->ssid = pos;
+                       elems->ssid_len = elen;
+                       break;
+               case WLAN_EID_SUPP_RATES:
+                       elems->supp_rates = pos;
+                       elems->supp_rates_len = elen;
+                       break;
+               case WLAN_EID_FH_PARAMS:
+                       elems->fh_params = pos;
+                       elems->fh_params_len = elen;
+                       break;
+               case WLAN_EID_DS_PARAMS:
+                       elems->ds_params = pos;
+                       elems->ds_params_len = elen;
+                       break;
+               case WLAN_EID_CF_PARAMS:
+                       elems->cf_params = pos;
+                       elems->cf_params_len = elen;
+                       break;
+               case WLAN_EID_TIM:
+                       if (elen >= sizeof(struct ieee80211_tim_ie)) {
+                               elems->tim = (void *)pos;
+                               elems->tim_len = elen;
+                       }
+                       break;
+               case WLAN_EID_IBSS_PARAMS:
+                       elems->ibss_params = pos;
+                       elems->ibss_params_len = elen;
+                       break;
+               case WLAN_EID_CHALLENGE:
+                       elems->challenge = pos;
+                       elems->challenge_len = elen;
+                       break;
+               case WLAN_EID_VENDOR_SPECIFIC:
+                       if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
+                           pos[2] == 0xf2) {
+                               /* Microsoft OUI (00:50:F2) */
+
+                               if (calc_crc)
+                                       crc = crc32_be(crc, pos - 2, elen + 2);
+
+                               if (pos[3] == 1) {
+                                       /* OUI Type 1 - WPA IE */
+                                       elems->wpa = pos;
+                                       elems->wpa_len = elen;
+                               } else if (elen >= 5 && pos[3] == 2) {
+                                       /* OUI Type 2 - WMM IE */
+                                       if (pos[4] == 0) {
+                                               elems->wmm_info = pos;
+                                               elems->wmm_info_len = elen;
+                                       } else if (pos[4] == 1) {
+                                               elems->wmm_param = pos;
+                                               elems->wmm_param_len = elen;
+                                       }
+                               }
+                       }
+                       break;
+               case WLAN_EID_RSN:
+                       elems->rsn = pos;
+                       elems->rsn_len = elen;
+                       break;
+               case WLAN_EID_ERP_INFO:
+                       elems->erp_info = pos;
+                       elems->erp_info_len = elen;
+                       break;
+               case WLAN_EID_EXT_SUPP_RATES:
+                       elems->ext_supp_rates = pos;
+                       elems->ext_supp_rates_len = elen;
+                       break;
+               case WLAN_EID_HT_CAPABILITY:
+                       if (elen >= sizeof(struct ieee80211_ht_cap))
+                               elems->ht_cap_elem = (void *)pos;
+                       break;
+               case WLAN_EID_HT_INFORMATION:
+                       if (elen >= sizeof(struct ieee80211_ht_info))
+                               elems->ht_info_elem = (void *)pos;
+                       break;
+               case WLAN_EID_MESH_ID:
+                       elems->mesh_id = pos;
+                       elems->mesh_id_len = elen;
+                       break;
+               case WLAN_EID_MESH_CONFIG:
+                       if (elen >= sizeof(struct ieee80211_meshconf_ie))
+                               elems->mesh_config = (void *)pos;
+                       break;
+               case WLAN_EID_PEER_MGMT:
+                       elems->peering = pos;
+                       elems->peering_len = elen;
+                       break;
+               case WLAN_EID_PREQ:
+                       elems->preq = pos;
+                       elems->preq_len = elen;
+                       break;
+               case WLAN_EID_PREP:
+                       elems->prep = pos;
+                       elems->prep_len = elen;
+                       break;
+               case WLAN_EID_PERR:
+                       elems->perr = pos;
+                       elems->perr_len = elen;
+                       break;
+               case WLAN_EID_RANN:
+                       if (elen >= sizeof(struct ieee80211_rann_ie))
+                               elems->rann = (void *)pos;
+                       break;
+               case WLAN_EID_CHANNEL_SWITCH:
+                       elems->ch_switch_elem = pos;
+                       elems->ch_switch_elem_len = elen;
+                       break;
+               case WLAN_EID_QUIET:
+                       if (!elems->quiet_elem) {
+                               elems->quiet_elem = pos;
+                               elems->quiet_elem_len = elen;
+                       }
+                       elems->num_of_quiet_elem++;
+                       break;
+               case WLAN_EID_COUNTRY:
+                       elems->country_elem = pos;
+                       elems->country_elem_len = elen;
+                       break;
+               case WLAN_EID_PWR_CONSTRAINT:
+                       elems->pwr_constr_elem = pos;
+                       elems->pwr_constr_elem_len = elen;
+                       break;
+               case WLAN_EID_TIMEOUT_INTERVAL:
+                       elems->timeout_int = pos;
+                       elems->timeout_int_len = elen;
+                       break;
+               default:
+                       break;
+               }
+
+               left -= elen;
+               pos += elen;
+       }
+
+       return crc;
+}
+EXPORT_SYMBOL(ieee802_11_parse_elems_crc);
index 0bf169bb770ed695b9829b234511ba0ce576cb58..62f121d1d9cbdb833d27990fc36b58f2e3ab22aa 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
+#include <net/cfg80211-wext.h>
 #include "wext-compat.h"
 #include "core.h"
 
@@ -363,9 +364,9 @@ int cfg80211_wext_giwfrag(struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
 
-int cfg80211_wext_siwretry(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *retry, char *extra)
+static int cfg80211_wext_siwretry(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *retry, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -402,7 +403,6 @@ int cfg80211_wext_siwretry(struct net_device *dev,
 
        return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
 
 int cfg80211_wext_giwretry(struct net_device *dev,
                           struct iw_request_info *info,
@@ -593,9 +593,9 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
        return err;
 }
 
-int cfg80211_wext_siwencode(struct net_device *dev,
-                           struct iw_request_info *info,
-                           struct iw_point *erq, char *keybuf)
+static int cfg80211_wext_siwencode(struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  struct iw_point *erq, char *keybuf)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -652,11 +652,10 @@ int cfg80211_wext_siwencode(struct net_device *dev,
                                       wdev->wext.default_key == -1,
                                       idx, &params);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode);
 
-int cfg80211_wext_siwencodeext(struct net_device *dev,
-                              struct iw_request_info *info,
-                              struct iw_point *erq, char *extra)
+static int cfg80211_wext_siwencodeext(struct net_device *dev,
+                                     struct iw_request_info *info,
+                                     struct iw_point *erq, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -744,11 +743,10 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
                        ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
                        idx, &params);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
 
-int cfg80211_wext_giwencode(struct net_device *dev,
-                           struct iw_request_info *info,
-                           struct iw_point *erq, char *keybuf)
+static int cfg80211_wext_giwencode(struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  struct iw_point *erq, char *keybuf)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        int idx;
@@ -782,11 +780,10 @@ int cfg80211_wext_giwencode(struct net_device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
 
-int cfg80211_wext_siwfreq(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_freq *wextfreq, char *extra)
+static int cfg80211_wext_siwfreq(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_freq *wextfreq, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -815,11 +812,10 @@ int cfg80211_wext_siwfreq(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
 
-int cfg80211_wext_giwfreq(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_freq *freq, char *extra)
+static int cfg80211_wext_giwfreq(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_freq *freq, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -836,11 +832,10 @@ int cfg80211_wext_giwfreq(struct net_device *dev,
                return 0;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
 
-int cfg80211_wext_siwtxpower(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *data, char *extra)
+static int cfg80211_wext_siwtxpower(struct net_device *dev,
+                                   struct iw_request_info *info,
+                                   union iwreq_data *data, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -889,11 +884,10 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
 
        return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm));
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower);
 
-int cfg80211_wext_giwtxpower(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *data, char *extra)
+static int cfg80211_wext_giwtxpower(struct net_device *dev,
+                                   struct iw_request_info *info,
+                                   union iwreq_data *data, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -919,7 +913,6 @@ int cfg80211_wext_giwtxpower(struct net_device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
 
 static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
                                 s32 auth_alg)
@@ -1070,9 +1063,9 @@ static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
        return 0;
 }
 
-int cfg80211_wext_siwauth(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *data, char *extra)
+static int cfg80211_wext_siwauth(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *data, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1102,21 +1095,19 @@ int cfg80211_wext_siwauth(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth);
 
-int cfg80211_wext_giwauth(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *data, char *extra)
+static int cfg80211_wext_giwauth(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *data, char *extra)
 {
        /* XXX: what do we need? */
 
        return -EOPNOTSUPP;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
 
-int cfg80211_wext_siwpower(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *wrq, char *extra)
+static int cfg80211_wext_siwpower(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *wrq, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1160,11 +1151,10 @@ int cfg80211_wext_siwpower(struct net_device *dev,
        return 0;
 
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
 
-int cfg80211_wext_giwpower(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_param *wrq, char *extra)
+static int cfg80211_wext_giwpower(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *wrq, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1172,7 +1162,6 @@ int cfg80211_wext_giwpower(struct net_device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
 
 static int cfg80211_wds_wext_siwap(struct net_device *dev,
                                   struct iw_request_info *info,
@@ -1218,9 +1207,9 @@ static int cfg80211_wds_wext_giwap(struct net_device *dev,
        return 0;
 }
 
-int cfg80211_wext_siwrate(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *rate, char *extra)
+static int cfg80211_wext_siwrate(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *rate, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1268,11 +1257,10 @@ int cfg80211_wext_siwrate(struct net_device *dev,
 
        return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
 
-int cfg80211_wext_giwrate(struct net_device *dev,
-                         struct iw_request_info *info,
-                         struct iw_param *rate, char *extra)
+static int cfg80211_wext_giwrate(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *rate, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1308,10 +1296,9 @@ int cfg80211_wext_giwrate(struct net_device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);
 
 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
-struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
+static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1376,11 +1363,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
 
        return &wstats;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
 
-int cfg80211_wext_siwap(struct net_device *dev,
-                       struct iw_request_info *info,
-                       struct sockaddr *ap_addr, char *extra)
+static int cfg80211_wext_siwap(struct net_device *dev,
+                              struct iw_request_info *info,
+                              struct sockaddr *ap_addr, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1395,11 +1381,10 @@ int cfg80211_wext_siwap(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
 
-int cfg80211_wext_giwap(struct net_device *dev,
-                       struct iw_request_info *info,
-                       struct sockaddr *ap_addr, char *extra)
+static int cfg80211_wext_giwap(struct net_device *dev,
+                              struct iw_request_info *info,
+                              struct sockaddr *ap_addr, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1414,11 +1399,10 @@ int cfg80211_wext_giwap(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
 
-int cfg80211_wext_siwessid(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *ssid)
+static int cfg80211_wext_siwessid(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_point *data, char *ssid)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1431,11 +1415,10 @@ int cfg80211_wext_siwessid(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
 
-int cfg80211_wext_giwessid(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *ssid)
+static int cfg80211_wext_giwessid(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_point *data, char *ssid)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1451,11 +1434,10 @@ int cfg80211_wext_giwessid(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
 
-int cfg80211_wext_siwpmksa(struct net_device *dev,
-                          struct iw_request_info *info,
-                          struct iw_point *data, char *extra)
+static int cfg80211_wext_siwpmksa(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_point *data, char *extra)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1493,7 +1475,6 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
                return -EOPNOTSUPP;
        }
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa);
 
 static const iw_handler cfg80211_handlers[] = {
        [IW_IOCTL_IDX(SIOCGIWNAME)]     = (iw_handler) cfg80211_wext_giwname,
index 20b3daef69643586d2508deca0f1f52c1ebe6ac0..5d766b0118e81969ff4f24c59b88bffdaa6496ff 100644 (file)
@@ -42,6 +42,14 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
                               struct iw_request_info *info,
                               struct iw_point *data, char *ssid);
 
+int cfg80211_wext_siwmlme(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_point *data, char *extra);
+int cfg80211_wext_siwgenie(struct net_device *dev,
+                          struct iw_request_info *info,
+                          struct iw_point *data, char *extra);
+
+
 int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq);
 
 
index 6fffe62d7c25b27cc9c6d6bc58635aa91f333e9f..0d4b8c3033ff53bba23ef5dd5620922d3f0a2faf 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/if_arp.h>
 #include <linux/slab.h>
 #include <net/cfg80211.h>
+#include <net/cfg80211-wext.h>
 #include "wext-compat.h"
 #include "nl80211.h"
 
@@ -365,7 +366,6 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
        wdev_unlock(wdev);
        return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
 
 int cfg80211_wext_siwmlme(struct net_device *dev,
                          struct iw_request_info *info,
@@ -402,4 +402,3 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
 
        return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
index 0256b8a0a7cf36b3f7f37c9645c71d724398d930..d0a42df5160ef7abb50a5554f80c40839ed1ad86 100644 (file)
@@ -2927,7 +2927,7 @@ static int __net_init xfrm_user_net_init(struct net *net)
        if (nlsk == NULL)
                return -ENOMEM;
        net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
-       rcu_assign_pointer(net->xfrm.nlsk, nlsk);
+       RCU_INIT_POINTER(net->xfrm.nlsk, nlsk);
        return 0;
 }
 
@@ -2935,7 +2935,7 @@ static void __net_exit xfrm_user_net_exit(struct list_head *net_exit_list)
 {
        struct net *net;
        list_for_each_entry(net, net_exit_list, exit_list)
-               rcu_assign_pointer(net->xfrm.nlsk, NULL);
+               RCU_INIT_POINTER(net->xfrm.nlsk, NULL);
        synchronize_net();
        list_for_each_entry(net, net_exit_list, exit_list)
                netlink_kernel_release(net->xfrm.nlsk_stash);
index 82d2eb285b705daac83e5c690620a7500ba5f1f9..ba573fe7c74d5bfe0495372931ebff69406f35c2 100644 (file)
@@ -33,17 +33,9 @@ silentoldconfig: $(obj)/conf
        $(Q)mkdir -p include/generated
        $< --$@ $(Kconfig)
 
-# if no path is given, then use src directory to find file
-ifdef LSMOD
-LSMOD_F := $(LSMOD)
-ifeq ($(findstring /,$(LSMOD)),)
-  LSMOD_F := $(objtree)/$(LSMOD)
-endif
-endif
-
-localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
+localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        $(Q)mkdir -p include/generated
-       $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
+       $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
        $(Q)if [ -f .config ]; then                                     \
                        cmp -s .tmp.config .config ||                   \
                        (mv -f .config .config.old.1;                   \
@@ -56,22 +48,6 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        fi
        $(Q)rm -f .tmp.config
 
-localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
-       $(Q)mkdir -p include/generated
-       $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
-       $(Q)sed -i s/=m/=y/ .tmp.config
-       $(Q)if [ -f .config ]; then                                     \
-                       cmp -s .tmp.config .config ||                   \
-                       (mv -f .config .config.old.1;                   \
-                        mv -f .tmp.config .config;                     \
-                        $(obj)/conf --silentoldconfig $(Kconfig);      \
-                        mv -f .config.old.1 .config.old)               \
-       else                                                            \
-                       mv -f .tmp.config .config;                      \
-                       $(obj)/conf --silentoldconfig $(Kconfig);       \
-       fi
-       $(Q)rm -f .tmp.config
-
 # Create new linux.pot file
 # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
 # The symlink is used to repair a deficiency in arch/um
index d66008639a43f46e60235dee932558a6c4d00223..8c2a97e60fafa701331949152261d162541482a1 100644 (file)
@@ -10,8 +10,7 @@
 
 #include "lkc.h"
 
-static const char nohelp_text[] = N_(
-       "There is no help available for this option.\n");
+static const char nohelp_text[] = "There is no help available for this option.";
 
 struct menu rootmenu;
 static struct menu **last_entry_ptr;
@@ -595,16 +594,14 @@ struct gstr get_relations_str(struct symbol **sym_arr)
 void menu_get_ext_help(struct menu *menu, struct gstr *help)
 {
        struct symbol *sym = menu->sym;
+       const char *help_text = nohelp_text;
 
        if (menu_has_help(menu)) {
-               if (sym->name) {
+               if (sym->name)
                        str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
-                       str_append(help, _(menu_get_help(menu)));
-                       str_append(help, "\n");
-               }
-       } else {
-               str_append(help, nohelp_text);
+               help_text = menu_get_help(menu);
        }
+       str_printf(help, "%s\n", _(help_text));
        if (sym)
                get_symbol_str(help, sym);
 }
index 39ca1f1640eaf6f27cdaa0ce5a9399b42ee89e4e..b113c50209e3913123288ccfa61708d663e6cb18 100644 (file)
@@ -182,8 +182,6 @@ setmod_text[] = N_(
 "This feature depends on another which\n"
 "has been configured as a module.\n"
 "As a result, this feature will be built as a module."),
-nohelp_text[] = N_(
-"There is no help available for this option.\n"),
 load_config_text[] = N_(
 "Enter the name of the configuration file you wish to load.\n"
 "Accept the name shown to restore the configuration you\n"
index a4fe923c01315205e3038b3da5b3514c6d134291..ec7afce4c88d3155d95c454915b5efb249568548 100644 (file)
@@ -43,6 +43,7 @@
 #    make oldconfig
 #
 use strict;
+use Getopt::Long;
 
 my $config = ".config";
 
@@ -112,10 +113,17 @@ sub find_config {
 
 find_config;
 
+# Parse options
+my $localmodconfig = 0;
+my $localyesconfig = 0;
+
+GetOptions("localmodconfig" => \$localmodconfig,
+          "localyesconfig" => \$localyesconfig);
+
 # Get the build source and top level Kconfig file (passed in)
 my $ksource = $ARGV[0];
 my $kconfig = $ARGV[1];
-my $lsmod_file = $ARGV[2];
+my $lsmod_file = $ENV{'LSMOD'};
 
 my @makefiles = `find $ksource -name Makefile 2>/dev/null`;
 chomp @makefiles;
@@ -296,7 +304,11 @@ my %modules;
 
 if (defined($lsmod_file)) {
     if ( ! -f $lsmod_file) {
-       die "$lsmod_file not found";
+       if ( -f $ENV{'objtree'}."/".$lsmod_file) {
+           $lsmod_file = $ENV{'objtree'}."/".$lsmod_file;
+       } else {
+               die "$lsmod_file not found";
+       }
     }
     if ( -x $lsmod_file) {
        # the file is executable, run it
@@ -421,7 +433,11 @@ while(<CIN>) {
 
     if (/^(CONFIG.*)=(m|y)/) {
        if (defined($configs{$1})) {
-           $setconfigs{$1} = $2;
+           if ($localyesconfig) {
+               $setconfigs{$1} = 'y';
+           } else {
+               $setconfigs{$1} = $2;
+           }
        } elsif ($2 eq "m") {
            print "# $1 is not set\n";
            next;
index e0f08b52e4ab440933c9f72120092b8bcd527b46..22847a8890813658890491cf4d835457202a2ec1 100644 (file)
@@ -186,7 +186,7 @@ source security/smack/Kconfig
 source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 
-source security/integrity/ima/Kconfig
+source security/integrity/Kconfig
 
 choice
        prompt "Default security module"
index 8bb0fe9e1ca94e68cac077196fad183975955d95..a5e502f8a05bcf9285a6924a37ad431bb55c6bb4 100644 (file)
@@ -24,5 +24,5 @@ obj-$(CONFIG_SECURITY_APPARMOR)               += apparmor/built-in.o
 obj-$(CONFIG_CGROUP_DEVICE)            += device_cgroup.o
 
 # Object integrity file lists
-subdir-$(CONFIG_IMA)                   += integrity/ima
-obj-$(CONFIG_IMA)                      += integrity/ima/built-in.o
+subdir-$(CONFIG_INTEGRITY)             += integrity
+obj-$(CONFIG_INTEGRITY)                        += integrity/built-in.o
index a93b3b73307991c69738bc0dab712e56330ba932..ee4f8486e5f563dff63c13278a1258e43e2b7859 100644 (file)
@@ -332,7 +332,8 @@ int cap_inode_killpriv(struct dentry *dentry)
  */
 static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps,
                                          struct linux_binprm *bprm,
-                                         bool *effective)
+                                         bool *effective,
+                                         bool *has_cap)
 {
        struct cred *new = bprm->cred;
        unsigned i;
@@ -341,6 +342,9 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps,
        if (caps->magic_etc & VFS_CAP_FLAGS_EFFECTIVE)
                *effective = true;
 
+       if (caps->magic_etc & VFS_CAP_REVISION_MASK)
+               *has_cap = true;
+
        CAP_FOR_EACH_U32(i) {
                __u32 permitted = caps->permitted.cap[i];
                __u32 inheritable = caps->inheritable.cap[i];
@@ -424,7 +428,7 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
  * its xattrs and, if present, apply them to the proposed credentials being
  * constructed by execve().
  */
-static int get_file_caps(struct linux_binprm *bprm, bool *effective)
+static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap)
 {
        struct dentry *dentry;
        int rc = 0;
@@ -450,7 +454,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective)
                goto out;
        }
 
-       rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective);
+       rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_cap);
        if (rc == -EINVAL)
                printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
                       __func__, rc, bprm->filename);
@@ -475,11 +479,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
 {
        const struct cred *old = current_cred();
        struct cred *new = bprm->cred;
-       bool effective;
+       bool effective, has_cap = false;
        int ret;
 
        effective = false;
-       ret = get_file_caps(bprm, &effective);
+       ret = get_file_caps(bprm, &effective, &has_cap);
        if (ret < 0)
                return ret;
 
@@ -489,7 +493,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
                 * for a setuid root binary run by a non-root user.  Do set it
                 * for a root user just to cause least surprise to an admin.
                 */
-               if (effective && new->uid != 0 && new->euid == 0) {
+               if (has_cap && new->uid != 0 && new->euid == 0) {
                        warn_setuid_and_fcaps_mixed(bprm->filename);
                        goto skip;
                }
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
new file mode 100644 (file)
index 0000000..4bf00ac
--- /dev/null
@@ -0,0 +1,7 @@
+#
+config INTEGRITY
+       def_bool y
+       depends on IMA || EVM
+
+source security/integrity/ima/Kconfig
+source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
new file mode 100644 (file)
index 0000000..0ae44ae
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for caching inode integrity data (iint)
+#
+
+obj-$(CONFIG_INTEGRITY) += integrity.o
+
+integrity-y := iint.o
+
+subdir-$(CONFIG_IMA)                   += ima
+obj-$(CONFIG_IMA)                      += ima/built-in.o
+subdir-$(CONFIG_EVM)                   += evm
+obj-$(CONFIG_EVM)                      += evm/built-in.o
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig
new file mode 100644 (file)
index 0000000..884617d
--- /dev/null
@@ -0,0 +1,14 @@
+config EVM
+       boolean "EVM support"
+       depends on SECURITY && KEYS && TCG_TPM
+       select CRYPTO_HMAC
+       select CRYPTO_MD5
+       select CRYPTO_SHA1
+       select ENCRYPTED_KEYS
+       select TRUSTED_KEYS
+       default n
+       help
+         EVM protects a file's security extended attributes against
+         integrity attacks.
+
+         If you are unsure how to answer this question, answer N.
diff --git a/security/integrity/evm/Makefile b/security/integrity/evm/Makefile
new file mode 100644 (file)
index 0000000..0787d26
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for building the Extended Verification Module(EVM)
+#
+obj-$(CONFIG_EVM) += evm.o
+
+evm-y := evm_main.o evm_crypto.o evm_secfs.o
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
new file mode 100644 (file)
index 0000000..d320f51
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005-2010 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * File: evm.h
+ *
+ */
+#include <linux/xattr.h>
+#include <linux/security.h>
+#include "../integrity.h"
+
+extern int evm_initialized;
+extern char *evm_hmac;
+
+extern struct crypto_shash *hmac_tfm;
+
+/* List of EVM protected security xattrs */
+extern char *evm_config_xattrnames[];
+
+extern int evm_init_key(void);
+extern int evm_update_evmxattr(struct dentry *dentry,
+                              const char *req_xattr_name,
+                              const char *req_xattr_value,
+                              size_t req_xattr_value_len);
+extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
+                        const char *req_xattr_value,
+                        size_t req_xattr_value_len, char *digest);
+extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
+                        char *hmac_val);
+extern int evm_init_secfs(void);
+extern void evm_cleanup_secfs(void);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
new file mode 100644 (file)
index 0000000..5dd5b14
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2005-2010 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * File: evm_crypto.c
+ *      Using root's kernel master key (kmk), calculate the HMAC
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/xattr.h>
+#include <keys/encrypted-type.h>
+#include <crypto/hash.h>
+#include "evm.h"
+
+#define EVMKEY "evm-key"
+#define MAX_KEY_SIZE 128
+static unsigned char evmkey[MAX_KEY_SIZE];
+static int evmkey_len = MAX_KEY_SIZE;
+
+struct crypto_shash *hmac_tfm;
+
+static struct shash_desc *init_desc(void)
+{
+       int rc;
+       struct shash_desc *desc;
+
+       if (hmac_tfm == NULL) {
+               hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
+               if (IS_ERR(hmac_tfm)) {
+                       pr_err("Can not allocate %s (reason: %ld)\n",
+                              evm_hmac, PTR_ERR(hmac_tfm));
+                       rc = PTR_ERR(hmac_tfm);
+                       hmac_tfm = NULL;
+                       return ERR_PTR(rc);
+               }
+       }
+
+       desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm),
+                       GFP_KERNEL);
+       if (!desc)
+               return ERR_PTR(-ENOMEM);
+
+       desc->tfm = hmac_tfm;
+       desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+       rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len);
+       if (rc)
+               goto out;
+       rc = crypto_shash_init(desc);
+out:
+       if (rc) {
+               kfree(desc);
+               return ERR_PTR(rc);
+       }
+       return desc;
+}
+
+/* Protect against 'cutting & pasting' security.evm xattr, include inode
+ * specific info.
+ *
+ * (Additional directory/file metadata needs to be added for more complete
+ * protection.)
+ */
+static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
+                         char *digest)
+{
+       struct h_misc {
+               unsigned long ino;
+               __u32 generation;
+               uid_t uid;
+               gid_t gid;
+               umode_t mode;
+       } hmac_misc;
+
+       memset(&hmac_misc, 0, sizeof hmac_misc);
+       hmac_misc.ino = inode->i_ino;
+       hmac_misc.generation = inode->i_generation;
+       hmac_misc.uid = inode->i_uid;
+       hmac_misc.gid = inode->i_gid;
+       hmac_misc.mode = inode->i_mode;
+       crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
+       crypto_shash_final(desc, digest);
+}
+
+/*
+ * Calculate the HMAC value across the set of protected security xattrs.
+ *
+ * Instead of retrieving the requested xattr, for performance, calculate
+ * the hmac using the requested xattr value. Don't alloc/free memory for
+ * each xattr, but attempt to re-use the previously allocated memory.
+ */
+int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
+                 const char *req_xattr_value, size_t req_xattr_value_len,
+                 char *digest)
+{
+       struct inode *inode = dentry->d_inode;
+       struct shash_desc *desc;
+       char **xattrname;
+       size_t xattr_size = 0;
+       char *xattr_value = NULL;
+       int error;
+       int size;
+
+       if (!inode->i_op || !inode->i_op->getxattr)
+               return -EOPNOTSUPP;
+       desc = init_desc();
+       if (IS_ERR(desc))
+               return PTR_ERR(desc);
+
+       error = -ENODATA;
+       for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
+               if ((req_xattr_name && req_xattr_value)
+                   && !strcmp(*xattrname, req_xattr_name)) {
+                       error = 0;
+                       crypto_shash_update(desc, (const u8 *)req_xattr_value,
+                                            req_xattr_value_len);
+                       continue;
+               }
+               size = vfs_getxattr_alloc(dentry, *xattrname,
+                                         &xattr_value, xattr_size, GFP_NOFS);
+               if (size == -ENOMEM) {
+                       error = -ENOMEM;
+                       goto out;
+               }
+               if (size < 0)
+                       continue;
+
+               error = 0;
+               xattr_size = size;
+               crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
+       }
+       hmac_add_misc(desc, inode, digest);
+
+out:
+       kfree(xattr_value);
+       kfree(desc);
+       return error;
+}
+
+/*
+ * Calculate the hmac and update security.evm xattr
+ *
+ * Expects to be called with i_mutex locked.
+ */
+int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
+                       const char *xattr_value, size_t xattr_value_len)
+{
+       struct inode *inode = dentry->d_inode;
+       struct evm_ima_xattr_data xattr_data;
+       int rc = 0;
+
+       rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
+                          xattr_value_len, xattr_data.digest);
+       if (rc == 0) {
+               xattr_data.type = EVM_XATTR_HMAC;
+               rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
+                                          &xattr_data,
+                                          sizeof(xattr_data), 0);
+       }
+       else if (rc == -ENODATA)
+               rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
+       return rc;
+}
+
+int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
+                 char *hmac_val)
+{
+       struct shash_desc *desc;
+
+       desc = init_desc();
+       if (IS_ERR(desc)) {
+               printk(KERN_INFO "init_desc failed\n");
+               return PTR_ERR(desc);
+       }
+
+       crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
+       hmac_add_misc(desc, inode, hmac_val);
+       kfree(desc);
+       return 0;
+}
+
+/*
+ * Get the key from the TPM for the SHA1-HMAC
+ */
+int evm_init_key(void)
+{
+       struct key *evm_key;
+       struct encrypted_key_payload *ekp;
+       int rc = 0;
+
+       evm_key = request_key(&key_type_encrypted, EVMKEY, NULL);
+       if (IS_ERR(evm_key))
+               return -ENOENT;
+
+       down_read(&evm_key->sem);
+       ekp = evm_key->payload.data;
+       if (ekp->decrypted_datalen > MAX_KEY_SIZE) {
+               rc = -EINVAL;
+               goto out;
+       }
+       memcpy(evmkey, ekp->decrypted_data, ekp->decrypted_datalen);
+out:
+       /* burn the original key contents */
+       memset(ekp->decrypted_data, 0, ekp->decrypted_datalen);
+       up_read(&evm_key->sem);
+       key_put(evm_key);
+       return rc;
+}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
new file mode 100644 (file)
index 0000000..f0127e5
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2005-2010 IBM Corporation
+ *
+ * Author:
+ * Mimi Zohar <zohar@us.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * File: evm_main.c
+ *     implements evm_inode_setxattr, evm_inode_post_setxattr,
+ *     evm_inode_removexattr, and evm_verifyxattr
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/xattr.h>
+#include <linux/integrity.h>
+#include <linux/evm.h>
+#include <crypto/hash.h>
+#include "evm.h"
+
+int evm_initialized;
+
+char *evm_hmac = "hmac(sha1)";
+
+char *evm_config_xattrnames[] = {
+#ifdef CONFIG_SECURITY_SELINUX
+       XATTR_NAME_SELINUX,
+#endif
+#ifdef CONFIG_SECURITY_SMACK
+       XATTR_NAME_SMACK,
+#endif
+       XATTR_NAME_CAPS,
+       NULL
+};
+
+static int evm_fixmode;
+static int __init evm_set_fixmode(char *str)
+{
+       if (strncmp(str, "fix", 3) == 0)
+               evm_fixmode = 1;
+       return 0;
+}
+__setup("evm=", evm_set_fixmode);
+
+/*
+ * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
+ *
+ * Compute the HMAC on the dentry's protected set of extended attributes
+ * and compare it against the stored security.evm xattr.
+ *
+ * For performance:
+ * - use the previoulsy retrieved xattr value and length to calculate the
+ *   HMAC.)
+ * - cache the verification result in the iint, when available.
+ *
+ * Returns integrity status
+ */
+static enum integrity_status evm_verify_hmac(struct dentry *dentry,
+                                            const char *xattr_name,
+                                            char *xattr_value,
+                                            size_t xattr_value_len,
+                                            struct integrity_iint_cache *iint)
+{
+       struct evm_ima_xattr_data xattr_data;
+       enum integrity_status evm_status;
+       int rc;
+
+       if (iint && iint->evm_status == INTEGRITY_PASS)
+               return iint->evm_status;
+
+       /* if status is not PASS, try to check again - against -ENOMEM */
+
+       rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
+                          xattr_value_len, xattr_data.digest);
+       if (rc < 0)
+               goto err_out;
+
+       xattr_data.type = EVM_XATTR_HMAC;
+       rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data,
+                          sizeof xattr_data, GFP_NOFS);
+       if (rc < 0)
+               goto err_out;
+       evm_status = INTEGRITY_PASS;
+       goto out;
+
+err_out:
+       switch (rc) {
+       case -ENODATA:          /* file not labelled */
+               evm_status = INTEGRITY_NOLABEL;
+               break;
+       default:
+               evm_status = INTEGRITY_FAIL;
+       }
+out:
+       if (iint)
+               iint->evm_status = evm_status;
+       return evm_status;
+}
+
+static int evm_protected_xattr(const char *req_xattr_name)
+{
+       char **xattrname;
+       int namelen;
+       int found = 0;
+
+       namelen = strlen(req_xattr_name);
+       for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
+               if ((strlen(*xattrname) == namelen)
+                   && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) {
+                       found = 1;
+                       break;
+               }
+               if (strncmp(req_xattr_name,
+                           *xattrname + XATTR_SECURITY_PREFIX_LEN,
+                           strlen(req_xattr_name)) == 0) {
+                       found = 1;
+                       break;
+               }
+       }
+       return found;
+}
+
+/**
+ * evm_verifyxattr - verify the integrity of the requested xattr
+ * @dentry: object of the verify xattr
+ * @xattr_name: requested xattr
+ * @xattr_value: requested xattr value
+ * @xattr_value_len: requested xattr value length
+ *
+ * Calculate the HMAC for the given dentry and verify it against the stored
+ * security.evm xattr. For performance, use the xattr value and length
+ * previously retrieved to calculate the HMAC.
+ *
+ * Returns the xattr integrity status.
+ *
+ * This function requires the caller to lock the inode's i_mutex before it
+ * is executed.
+ */
+enum integrity_status evm_verifyxattr(struct dentry *dentry,
+                                     const char *xattr_name,
+                                     void *xattr_value, size_t xattr_value_len,
+                                     struct integrity_iint_cache *iint)
+{
+       if (!evm_initialized || !evm_protected_xattr(xattr_name))
+               return INTEGRITY_UNKNOWN;
+
+       if (!iint) {
+               iint = integrity_iint_find(dentry->d_inode);
+               if (!iint)
+                       return INTEGRITY_UNKNOWN;
+       }
+       return evm_verify_hmac(dentry, xattr_name, xattr_value,
+                                xattr_value_len, iint);
+}
+EXPORT_SYMBOL_GPL(evm_verifyxattr);
+
+/*
+ * evm_protect_xattr - protect the EVM extended attribute
+ *
+ * Prevent security.evm from being modified or removed.
+ */
+static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
+                            const void *xattr_value, size_t xattr_value_len)
+{
+       if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+       }
+       return 0;
+}
+
+/*
+ * evm_verify_current_integrity - verify the dentry's metadata integrity
+ * @dentry: pointer to the affected dentry
+ *
+ * Verify and return the dentry's metadata integrity. The exceptions are
+ * before EVM is initialized or in 'fix' mode.
+ */
+static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
+{
+       struct inode *inode = dentry->d_inode;
+
+       if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode)
+               return 0;
+       return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
+}
+
+/**
+ * evm_inode_setxattr - protect the EVM extended attribute
+ * @dentry: pointer to the affected dentry
+ * @xattr_name: pointer to the affected extended attribute name
+ * @xattr_value: pointer to the new extended attribute value
+ * @xattr_value_len: pointer to the new extended attribute value length
+ *
+ * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
+ * the current value is valid.
+ */
+int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
+                      const void *xattr_value, size_t xattr_value_len)
+{
+
+       enum integrity_status evm_status;
+       int ret;
+
+       ret = evm_protect_xattr(dentry, xattr_name, xattr_value,
+                               xattr_value_len);
+       if (ret)
+               return ret;
+       evm_status = evm_verify_current_integrity(dentry);
+       return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+}
+
+/**
+ * evm_inode_removexattr - protect the EVM extended attribute
+ * @dentry: pointer to the affected dentry
+ * @xattr_name: pointer to the affected extended attribute name
+ *
+ * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
+ * the current value is valid.
+ */
+int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
+{
+       enum integrity_status evm_status;
+       int ret;
+
+       ret = evm_protect_xattr(dentry, xattr_name, NULL, 0);
+       if (ret)
+               return ret;
+       evm_status = evm_verify_current_integrity(dentry);
+       return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+}
+
+/**
+ * evm_inode_post_setxattr - update 'security.evm' to reflect the changes
+ * @dentry: pointer to the affected dentry
+ * @xattr_name: pointer to the affected extended attribute name
+ * @xattr_value: pointer to the new extended attribute value
+ * @xattr_value_len: pointer to the new extended attribute value length
+ *
+ * Update the HMAC stored in 'security.evm' to reflect the change.
+ *
+ * No need to take the i_mutex lock here, as this function is called from
+ * __vfs_setxattr_noperm().  The caller of which has taken the inode's
+ * i_mutex lock.
+ */
+void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
+                            const void *xattr_value, size_t xattr_value_len)
+{
+       if (!evm_initialized || !evm_protected_xattr(xattr_name))
+               return;
+
+       evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
+       return;
+}
+
+/**
+ * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
+ * @dentry: pointer to the affected dentry
+ * @xattr_name: pointer to the affected extended attribute name
+ *
+ * Update the HMAC stored in 'security.evm' to reflect removal of the xattr.
+ */
+void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
+{
+       struct inode *inode = dentry->d_inode;
+
+       if (!evm_initialized || !evm_protected_xattr(xattr_name))
+               return;
+
+       mutex_lock(&inode->i_mutex);
+       evm_update_evmxattr(dentry, xattr_name, NULL, 0);
+       mutex_unlock(&inode->i_mutex);
+       return;
+}
+
+/**
+ * evm_inode_setattr - prevent updating an invalid EVM extended attribute
+ * @dentry: pointer to the affected dentry
+ */
+int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
+{
+       unsigned int ia_valid = attr->ia_valid;
+       enum integrity_status evm_status;
+
+       if (ia_valid & ~(ATTR_MODE | ATTR_UID | ATTR_GID))
+               return 0;
+       evm_status = evm_verify_current_integrity(dentry);
+       return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+}
+
+/**
+ * evm_inode_post_setattr - update 'security.evm' after modifying metadata
+ * @dentry: pointer to the affected dentry
+ * @ia_valid: for the UID and GID status
+ *
+ * For now, update the HMAC stored in 'security.evm' to reflect UID/GID
+ * changes.
+ *
+ * This function is called from notify_change(), which expects the caller
+ * to lock the inode's i_mutex.
+ */
+void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
+{
+       if (!evm_initialized)
+               return;
+
+       if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
+               evm_update_evmxattr(dentry, NULL, NULL, 0);
+       return;
+}
+
+/*
+ * evm_inode_init_security - initializes security.evm
+ */
+int evm_inode_init_security(struct inode *inode,
+                                const struct xattr *lsm_xattr,
+                                struct xattr *evm_xattr)
+{
+       struct evm_ima_xattr_data *xattr_data;
+       int rc;
+
+       if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name))
+               return 0;
+
+       xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
+       if (!xattr_data)
+               return -ENOMEM;
+
+       xattr_data->type = EVM_XATTR_HMAC;
+       rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
+       if (rc < 0)
+               goto out;
+
+       evm_xattr->value = xattr_data;
+       evm_xattr->value_len = sizeof(*xattr_data);
+       evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
+       return 0;
+out:
+       kfree(xattr_data);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(evm_inode_init_security);
+
+static int __init init_evm(void)
+{
+       int error;
+
+       error = evm_init_secfs();
+       if (error < 0) {
+               printk(KERN_INFO "EVM: Error registering secfs\n");
+               goto err;
+       }
+err:
+       return error;
+}
+
+static void __exit cleanup_evm(void)
+{
+       evm_cleanup_secfs();
+       if (hmac_tfm)
+               crypto_free_shash(hmac_tfm);
+}
+
+/*
+ * evm_display_config - list the EVM protected security extended attributes
+ */
+static int __init evm_display_config(void)
+{
+       char **xattrname;
+
+       for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++)
+               printk(KERN_INFO "EVM: %s\n", *xattrname);
+       return 0;
+}
+
+pure_initcall(evm_display_config);
+late_initcall(init_evm);
+
+MODULE_DESCRIPTION("Extended Verification Module");
+MODULE_LICENSE("GPL");
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
new file mode 100644 (file)
index 0000000..ac76299
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * File: evm_secfs.c
+ *     - Used to signal when key is on keyring
+ *     - Get the key and enable EVM
+ */
+
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include "evm.h"
+
+static struct dentry *evm_init_tpm;
+
+/**
+ * evm_read_key - read() for <securityfs>/evm
+ *
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @count: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t evm_read_key(struct file *filp, char __user *buf,
+                           size_t count, loff_t *ppos)
+{
+       char temp[80];
+       ssize_t rc;
+
+       if (*ppos != 0)
+               return 0;
+
+       sprintf(temp, "%d", evm_initialized);
+       rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
+
+       return rc;
+}
+
+/**
+ * evm_write_key - write() for <securityfs>/evm
+ * @file: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * Used to signal that key is on the kernel key ring.
+ * - get the integrity hmac key from the kernel key ring
+ * - create list of hmac protected extended attributes
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t evm_write_key(struct file *file, const char __user *buf,
+                            size_t count, loff_t *ppos)
+{
+       char temp[80];
+       int i, error;
+
+       if (!capable(CAP_SYS_ADMIN) || evm_initialized)
+               return -EPERM;
+
+       if (count >= sizeof(temp) || count == 0)
+               return -EINVAL;
+
+       if (copy_from_user(temp, buf, count) != 0)
+               return -EFAULT;
+
+       temp[count] = '\0';
+
+       if ((sscanf(temp, "%d", &i) != 1) || (i != 1))
+               return -EINVAL;
+
+       error = evm_init_key();
+       if (!error) {
+               evm_initialized = 1;
+               pr_info("EVM: initialized\n");
+       } else
+               pr_err("EVM: initialization failed\n");
+       return count;
+}
+
+static const struct file_operations evm_key_ops = {
+       .read           = evm_read_key,
+       .write          = evm_write_key,
+};
+
+int __init evm_init_secfs(void)
+{
+       int error = 0;
+
+       evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP,
+                                             NULL, NULL, &evm_key_ops);
+       if (!evm_init_tpm || IS_ERR(evm_init_tpm))
+               error = -EFAULT;
+       return error;
+}
+
+void __exit evm_cleanup_secfs(void)
+{
+       if (evm_init_tpm)
+               securityfs_remove(evm_init_tpm);
+}
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
new file mode 100644 (file)
index 0000000..0a23e07
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2008 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * File: integrity_iint.c
+ *     - implements the integrity hooks: integrity_inode_alloc,
+ *       integrity_inode_free
+ *     - cache integrity information associated with an inode
+ *       using a rbtree tree.
+ */
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/rbtree.h>
+#include "integrity.h"
+
+static struct rb_root integrity_iint_tree = RB_ROOT;
+static DEFINE_SPINLOCK(integrity_iint_lock);
+static struct kmem_cache *iint_cache __read_mostly;
+
+int iint_initialized;
+
+/*
+ * __integrity_iint_find - return the iint associated with an inode
+ */
+static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
+{
+       struct integrity_iint_cache *iint;
+       struct rb_node *n = integrity_iint_tree.rb_node;
+
+       assert_spin_locked(&integrity_iint_lock);
+
+       while (n) {
+               iint = rb_entry(n, struct integrity_iint_cache, rb_node);
+
+               if (inode < iint->inode)
+                       n = n->rb_left;
+               else if (inode > iint->inode)
+                       n = n->rb_right;
+               else
+                       break;
+       }
+       if (!n)
+               return NULL;
+
+       return iint;
+}
+
+/*
+ * integrity_iint_find - return the iint associated with an inode
+ */
+struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
+{
+       struct integrity_iint_cache *iint;
+
+       if (!IS_IMA(inode))
+               return NULL;
+
+       spin_lock(&integrity_iint_lock);
+       iint = __integrity_iint_find(inode);
+       spin_unlock(&integrity_iint_lock);
+
+       return iint;
+}
+
+static void iint_free(struct integrity_iint_cache *iint)
+{
+       iint->version = 0;
+       iint->flags = 0UL;
+       kmem_cache_free(iint_cache, iint);
+}
+
+/**
+ * integrity_inode_alloc - allocate an iint associated with an inode
+ * @inode: pointer to the inode
+ */
+int integrity_inode_alloc(struct inode *inode)
+{
+       struct rb_node **p;
+       struct rb_node *new_node, *parent = NULL;
+       struct integrity_iint_cache *new_iint, *test_iint;
+       int rc;
+
+       new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
+       if (!new_iint)
+               return -ENOMEM;
+
+       new_iint->inode = inode;
+       new_node = &new_iint->rb_node;
+
+       mutex_lock(&inode->i_mutex);    /* i_flags */
+       spin_lock(&integrity_iint_lock);
+
+       p = &integrity_iint_tree.rb_node;
+       while (*p) {
+               parent = *p;
+               test_iint = rb_entry(parent, struct integrity_iint_cache,
+                                    rb_node);
+               rc = -EEXIST;
+               if (inode < test_iint->inode)
+                       p = &(*p)->rb_left;
+               else if (inode > test_iint->inode)
+                       p = &(*p)->rb_right;
+               else
+                       goto out_err;
+       }
+
+       inode->i_flags |= S_IMA;
+       rb_link_node(new_node, parent, p);
+       rb_insert_color(new_node, &integrity_iint_tree);
+
+       spin_unlock(&integrity_iint_lock);
+       mutex_unlock(&inode->i_mutex);  /* i_flags */
+
+       return 0;
+out_err:
+       spin_unlock(&integrity_iint_lock);
+       mutex_unlock(&inode->i_mutex);  /* i_flags */
+       iint_free(new_iint);
+
+       return rc;
+}
+
+/**
+ * integrity_inode_free - called on security_inode_free
+ * @inode: pointer to the inode
+ *
+ * Free the integrity information(iint) associated with an inode.
+ */
+void integrity_inode_free(struct inode *inode)
+{
+       struct integrity_iint_cache *iint;
+
+       if (!IS_IMA(inode))
+               return;
+
+       spin_lock(&integrity_iint_lock);
+       iint = __integrity_iint_find(inode);
+       rb_erase(&iint->rb_node, &integrity_iint_tree);
+       spin_unlock(&integrity_iint_lock);
+
+       iint_free(iint);
+}
+
+static void init_once(void *foo)
+{
+       struct integrity_iint_cache *iint = foo;
+
+       memset(iint, 0, sizeof *iint);
+       iint->version = 0;
+       iint->flags = 0UL;
+       mutex_init(&iint->mutex);
+       iint->evm_status = INTEGRITY_UNKNOWN;
+}
+
+static int __init integrity_iintcache_init(void)
+{
+       iint_cache =
+           kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
+                             0, SLAB_PANIC, init_once);
+       iint_initialized = 1;
+       return 0;
+}
+security_initcall(integrity_iintcache_init);
index b6ecfd4d8d784ebad9c9f85ebed091b94690c3b3..19c053b823035a48bc2e47f735bdf125aad8384e 100644 (file)
@@ -3,6 +3,7 @@
 config IMA
        bool "Integrity Measurement Architecture(IMA)"
        depends on SECURITY
+       select INTEGRITY
        select SECURITYFS
        select CRYPTO
        select CRYPTO_HMAC
index 787c4cb916cd6bf5e82c851467a5445a39e4e5db..5690c021de8fbc2b069d622634a33841a0498bff 100644 (file)
@@ -6,4 +6,4 @@
 obj-$(CONFIG_IMA) += ima.o
 
 ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
-        ima_policy.o ima_iint.o ima_audit.o
+        ima_policy.o ima_audit.o
index 08408bd71462b2395f419647ae057950d879a231..29d97af5e9a4d3c4a16abfae8c26d8aaaebee618 100644 (file)
 #include <linux/tpm.h>
 #include <linux/audit.h>
 
+#include "../integrity.h"
+
 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
 
 /* digest size for IMA, fits SHA1 or MD5 */
-#define IMA_DIGEST_SIZE                20
+#define IMA_DIGEST_SIZE                SHA1_DIGEST_SIZE
 #define IMA_EVENT_NAME_LEN_MAX 255
 
 #define IMA_HASH_BITS 9
@@ -96,34 +98,21 @@ static inline unsigned long ima_hash_key(u8 *digest)
        return hash_long(*digest, IMA_HASH_BITS);
 }
 
-/* iint cache flags */
-#define IMA_MEASURED           0x01
-
-/* integrity data associated with an inode */
-struct ima_iint_cache {
-       struct rb_node rb_node; /* rooted in ima_iint_tree */
-       struct inode *inode;    /* back pointer to inode in question */
-       u64 version;            /* track inode changes */
-       unsigned char flags;
-       u8 digest[IMA_DIGEST_SIZE];
-       struct mutex mutex;     /* protects: version, flags, digest */
-};
-
 /* LIM API function definitions */
 int ima_must_measure(struct inode *inode, int mask, int function);
-int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file);
-void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
+int ima_collect_measurement(struct integrity_iint_cache *iint,
+                           struct file *file);
+void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
                           const unsigned char *filename);
 int ima_store_template(struct ima_template_entry *entry, int violation,
                       struct inode *inode);
-void ima_template_show(struct seq_file *m, void *e,
-                      enum ima_show_type show);
+void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
 
 /* rbtree tree calls to lookup, insert, delete
  * integrity data associated with an inode.
  */
-struct ima_iint_cache *ima_iint_insert(struct inode *inode);
-struct ima_iint_cache *ima_iint_find(struct inode *inode);
+struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
+struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 
 /* IMA policy related functions */
 enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
index da36d2c085a4ff732967a273fe41423da0ae1b46..0d50df04ccc469f6cab0e68323b7de9d915ca09e 100644 (file)
@@ -126,7 +126,8 @@ int ima_must_measure(struct inode *inode, int mask, int function)
  *
  * Return 0 on success, error code otherwise
  */
-int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
+int ima_collect_measurement(struct integrity_iint_cache *iint,
+                           struct file *file)
 {
        int result = -EEXIST;
 
@@ -156,8 +157,8 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
  *
  * Must be called with iint->mutex held.
  */
-void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
-                          const unsigned char *filename)
+void ima_store_measurement(struct integrity_iint_cache *iint,
+                          struct file *file, const unsigned char *filename)
 {
        const char *op = "add_template_measure";
        const char *audit_cause = "ENOMEM";
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
deleted file mode 100644 (file)
index 4ae7304..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2008 IBM Corporation
- *
- * Authors:
- * Mimi Zohar <zohar@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- * File: ima_iint.c
- *     - implements the IMA hooks: ima_inode_alloc, ima_inode_free
- *     - cache integrity information associated with an inode
- *       using a rbtree tree.
- */
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/rbtree.h>
-#include "ima.h"
-
-static struct rb_root ima_iint_tree = RB_ROOT;
-static DEFINE_SPINLOCK(ima_iint_lock);
-static struct kmem_cache *iint_cache __read_mostly;
-
-int iint_initialized = 0;
-
-/*
- * __ima_iint_find - return the iint associated with an inode
- */
-static struct ima_iint_cache *__ima_iint_find(struct inode *inode)
-{
-       struct ima_iint_cache *iint;
-       struct rb_node *n = ima_iint_tree.rb_node;
-
-       assert_spin_locked(&ima_iint_lock);
-
-       while (n) {
-               iint = rb_entry(n, struct ima_iint_cache, rb_node);
-
-               if (inode < iint->inode)
-                       n = n->rb_left;
-               else if (inode > iint->inode)
-                       n = n->rb_right;
-               else
-                       break;
-       }
-       if (!n)
-               return NULL;
-
-       return iint;
-}
-
-/*
- * ima_iint_find - return the iint associated with an inode
- */
-struct ima_iint_cache *ima_iint_find(struct inode *inode)
-{
-       struct ima_iint_cache *iint;
-
-       if (!IS_IMA(inode))
-               return NULL;
-
-       spin_lock(&ima_iint_lock);
-       iint = __ima_iint_find(inode);
-       spin_unlock(&ima_iint_lock);
-
-       return iint;
-}
-
-static void iint_free(struct ima_iint_cache *iint)
-{
-       iint->version = 0;
-       iint->flags = 0UL;
-       kmem_cache_free(iint_cache, iint);
-}
-
-/**
- * ima_inode_alloc - allocate an iint associated with an inode
- * @inode: pointer to the inode
- */
-int ima_inode_alloc(struct inode *inode)
-{
-       struct rb_node **p;
-       struct rb_node *new_node, *parent = NULL;
-       struct ima_iint_cache *new_iint, *test_iint;
-       int rc;
-
-       new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
-       if (!new_iint)
-               return -ENOMEM;
-
-       new_iint->inode = inode;
-       new_node = &new_iint->rb_node;
-
-       mutex_lock(&inode->i_mutex); /* i_flags */
-       spin_lock(&ima_iint_lock);
-
-       p = &ima_iint_tree.rb_node;
-       while (*p) {
-               parent = *p;
-               test_iint = rb_entry(parent, struct ima_iint_cache, rb_node);
-
-               rc = -EEXIST;
-               if (inode < test_iint->inode)
-                       p = &(*p)->rb_left;
-               else if (inode > test_iint->inode)
-                       p = &(*p)->rb_right;
-               else
-                       goto out_err;
-       }
-
-       inode->i_flags |= S_IMA;
-       rb_link_node(new_node, parent, p);
-       rb_insert_color(new_node, &ima_iint_tree);
-
-       spin_unlock(&ima_iint_lock);
-       mutex_unlock(&inode->i_mutex); /* i_flags */
-
-       return 0;
-out_err:
-       spin_unlock(&ima_iint_lock);
-       mutex_unlock(&inode->i_mutex); /* i_flags */
-       iint_free(new_iint);
-
-       return rc;
-}
-
-/**
- * ima_inode_free - called on security_inode_free
- * @inode: pointer to the inode
- *
- * Free the integrity information(iint) associated with an inode.
- */
-void ima_inode_free(struct inode *inode)
-{
-       struct ima_iint_cache *iint;
-
-       if (!IS_IMA(inode))
-               return;
-
-       spin_lock(&ima_iint_lock);
-       iint = __ima_iint_find(inode);
-       rb_erase(&iint->rb_node, &ima_iint_tree);
-       spin_unlock(&ima_iint_lock);
-
-       iint_free(iint);
-}
-
-static void init_once(void *foo)
-{
-       struct ima_iint_cache *iint = foo;
-
-       memset(iint, 0, sizeof *iint);
-       iint->version = 0;
-       iint->flags = 0UL;
-       mutex_init(&iint->mutex);
-}
-
-static int __init ima_iintcache_init(void)
-{
-       iint_cache =
-           kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
-                             SLAB_PANIC, init_once);
-       iint_initialized = 1;
-       return 0;
-}
-security_initcall(ima_iintcache_init);
index 26b46ff7466353bcf8fbe58545bd8ab6c2f0e384..42dc27007fdda90801b104207444b8e3e5e41351 100644 (file)
@@ -82,7 +82,7 @@ out:
                                  "open_writers");
 }
 
-static void ima_check_last_writer(struct ima_iint_cache *iint,
+static void ima_check_last_writer(struct integrity_iint_cache *iint,
                                  struct inode *inode,
                                  struct file *file)
 {
@@ -105,12 +105,12 @@ static void ima_check_last_writer(struct ima_iint_cache *iint,
 void ima_file_free(struct file *file)
 {
        struct inode *inode = file->f_dentry->d_inode;
-       struct ima_iint_cache *iint;
+       struct integrity_iint_cache *iint;
 
        if (!iint_initialized || !S_ISREG(inode->i_mode))
                return;
 
-       iint = ima_iint_find(inode);
+       iint = integrity_iint_find(inode);
        if (!iint)
                return;
 
@@ -121,7 +121,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
                               int mask, int function)
 {
        struct inode *inode = file->f_dentry->d_inode;
-       struct ima_iint_cache *iint;
+       struct integrity_iint_cache *iint;
        int rc = 0;
 
        if (!ima_initialized || !S_ISREG(inode->i_mode))
@@ -131,9 +131,9 @@ static int process_measurement(struct file *file, const unsigned char *filename,
        if (rc != 0)
                return rc;
 retry:
-       iint = ima_iint_find(inode);
+       iint = integrity_iint_find(inode);
        if (!iint) {
-               rc = ima_inode_alloc(inode);
+               rc = integrity_inode_alloc(inode);
                if (!rc || rc == -EEXIST)
                        goto retry;
                return rc;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
new file mode 100644 (file)
index 0000000..880bbee
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009-2010 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/integrity.h>
+#include <crypto/sha.h>
+
+/* iint cache flags */
+#define IMA_MEASURED           0x01
+
+enum evm_ima_xattr_type {
+       IMA_XATTR_DIGEST = 0x01,
+       EVM_XATTR_HMAC,
+       EVM_IMA_XATTR_DIGSIG,
+};
+
+struct evm_ima_xattr_data {
+       u8 type;
+       u8 digest[SHA1_DIGEST_SIZE];
+}  __attribute__((packed));
+
+/* integrity data associated with an inode */
+struct integrity_iint_cache {
+       struct rb_node rb_node; /* rooted in integrity_iint_tree */
+       struct inode *inode;    /* back pointer to inode in question */
+       u64 version;            /* track inode changes */
+       unsigned char flags;
+       u8 digest[SHA1_DIGEST_SIZE];
+       struct mutex mutex;     /* protects: version, flags, digest */
+       enum integrity_status evm_status;
+};
+
+/* rbtree tree calls to lookup, insert, delete
+ * integrity data associated with an inode.
+ */
+struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
+struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
index 89df6b5f203c534c64fffd3fc0547f611dedebea..bf4d8da5a79502f626a849473e4af18e229eb074 100644 (file)
@@ -1,6 +1,6 @@
 /* Key garbage collector
  *
- * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2011 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -10,6 +10,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/security.h>
 #include <keys/keyring-type.h>
 #include "internal.h"
 
 unsigned key_gc_delay = 5 * 60;
 
 /*
- * Reaper
+ * Reaper for unused keys.
+ */
+static void key_garbage_collector(struct work_struct *work);
+DECLARE_WORK(key_gc_work, key_garbage_collector);
+
+/*
+ * Reaper for links from keyrings to dead keys.
  */
 static void key_gc_timer_func(unsigned long);
-static void key_garbage_collector(struct work_struct *);
 static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0);
-static DECLARE_WORK(key_gc_work, key_garbage_collector);
-static key_serial_t key_gc_cursor; /* the last key the gc considered */
-static bool key_gc_again;
-static unsigned long key_gc_executing;
+
 static time_t key_gc_next_run = LONG_MAX;
-static time_t key_gc_new_timer;
+static struct key_type *key_gc_dead_keytype;
+
+static unsigned long key_gc_flags;
+#define KEY_GC_KEY_EXPIRED     0       /* A key expired and needs unlinking */
+#define KEY_GC_REAP_KEYTYPE    1       /* A keytype is being unregistered */
+#define KEY_GC_REAPING_KEYTYPE 2       /* Cleared when keytype reaped */
+
+
+/*
+ * Any key whose type gets unregistered will be re-typed to this if it can't be
+ * immediately unlinked.
+ */
+struct key_type key_type_dead = {
+       .name = "dead",
+};
 
 /*
  * Schedule a garbage collection run.
@@ -42,31 +60,75 @@ void key_schedule_gc(time_t gc_at)
 
        kenter("%ld", gc_at - now);
 
-       if (gc_at <= now) {
-               schedule_work(&key_gc_work);
+       if (gc_at <= now || test_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) {
+               kdebug("IMMEDIATE");
+               queue_work(system_nrt_wq, &key_gc_work);
        } else if (gc_at < key_gc_next_run) {
+               kdebug("DEFERRED");
+               key_gc_next_run = gc_at;
                expires = jiffies + (gc_at - now) * HZ;
                mod_timer(&key_gc_timer, expires);
        }
 }
 
 /*
- * The garbage collector timer kicked off
+ * Some key's cleanup time was met after it expired, so we need to get the
+ * reaper to go through a cycle finding expired keys.
  */
 static void key_gc_timer_func(unsigned long data)
 {
        kenter("");
        key_gc_next_run = LONG_MAX;
-       schedule_work(&key_gc_work);
+       set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags);
+       queue_work(system_nrt_wq, &key_gc_work);
+}
+
+/*
+ * wait_on_bit() sleep function for uninterruptible waiting
+ */
+static int key_gc_wait_bit(void *flags)
+{
+       schedule();
+       return 0;
+}
+
+/*
+ * Reap keys of dead type.
+ *
+ * We use three flags to make sure we see three complete cycles of the garbage
+ * collector: the first to mark keys of that type as being dead, the second to
+ * collect dead links and the third to clean up the dead keys.  We have to be
+ * careful as there may already be a cycle in progress.
+ *
+ * The caller must be holding key_types_sem.
+ */
+void key_gc_keytype(struct key_type *ktype)
+{
+       kenter("%s", ktype->name);
+
+       key_gc_dead_keytype = ktype;
+       set_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
+       smp_mb();
+       set_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags);
+
+       kdebug("schedule");
+       queue_work(system_nrt_wq, &key_gc_work);
+
+       kdebug("sleep");
+       wait_on_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE, key_gc_wait_bit,
+                   TASK_UNINTERRUPTIBLE);
+
+       key_gc_dead_keytype = NULL;
+       kleave("");
 }
 
 /*
  * Garbage collect pointers from a keyring.
  *
- * Return true if we altered the keyring.
+ * Not called with any locks held.  The keyring's key struct will not be
+ * deallocated under us as only our caller may deallocate it.
  */
-static bool key_gc_keyring(struct key *keyring, time_t limit)
-       __releases(key_serial_lock)
+static void key_gc_keyring(struct key *keyring, time_t limit)
 {
        struct keyring_list *klist;
        struct key *key;
@@ -93,130 +155,234 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
 unlock_dont_gc:
        rcu_read_unlock();
 dont_gc:
-       kleave(" = false");
-       return false;
+       kleave(" [no gc]");
+       return;
 
 do_gc:
        rcu_read_unlock();
-       key_gc_cursor = keyring->serial;
-       key_get(keyring);
-       spin_unlock(&key_serial_lock);
+
        keyring_gc(keyring, limit);
-       key_put(keyring);
-       kleave(" = true");
-       return true;
+       kleave(" [gc]");
 }
 
 /*
- * Garbage collector for keys.  This involves scanning the keyrings for dead,
- * expired and revoked keys that have overstayed their welcome
+ * Garbage collect an unreferenced, detached key
  */
-static void key_garbage_collector(struct work_struct *work)
+static noinline void key_gc_unused_key(struct key *key)
 {
-       struct rb_node *rb;
-       key_serial_t cursor;
-       struct key *key, *xkey;
-       time_t new_timer = LONG_MAX, limit, now;
-
-       now = current_kernel_time().tv_sec;
-       kenter("[%x,%ld]", key_gc_cursor, key_gc_new_timer - now);
-
-       if (test_and_set_bit(0, &key_gc_executing)) {
-               key_schedule_gc(current_kernel_time().tv_sec + 1);
-               kleave(" [busy; deferring]");
-               return;
+       key_check(key);
+
+       security_key_free(key);
+
+       /* deal with the user's key tracking and quota */
+       if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
+               spin_lock(&key->user->lock);
+               key->user->qnkeys--;
+               key->user->qnbytes -= key->quotalen;
+               spin_unlock(&key->user->lock);
        }
 
-       limit = now;
+       atomic_dec(&key->user->nkeys);
+       if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
+               atomic_dec(&key->user->nikeys);
+
+       key_user_put(key->user);
+
+       /* now throw away the key memory */
+       if (key->type->destroy)
+               key->type->destroy(key);
+
+       kfree(key->description);
+
+#ifdef KEY_DEBUGGING
+       key->magic = KEY_DEBUG_MAGIC_X;
+#endif
+       kmem_cache_free(key_jar, key);
+}
+
+/*
+ * Garbage collector for unused keys.
+ *
+ * This is done in process context so that we don't have to disable interrupts
+ * all over the place.  key_put() schedules this rather than trying to do the
+ * cleanup itself, which means key_put() doesn't have to sleep.
+ */
+static void key_garbage_collector(struct work_struct *work)
+{
+       static u8 gc_state;             /* Internal persistent state */
+#define KEY_GC_REAP_AGAIN      0x01    /* - Need another cycle */
+#define KEY_GC_REAPING_LINKS   0x02    /* - We need to reap links */
+#define KEY_GC_SET_TIMER       0x04    /* - We need to restart the timer */
+#define KEY_GC_REAPING_DEAD_1  0x10    /* - We need to mark dead keys */
+#define KEY_GC_REAPING_DEAD_2  0x20    /* - We need to reap dead key links */
+#define KEY_GC_REAPING_DEAD_3  0x40    /* - We need to reap dead keys */
+#define KEY_GC_FOUND_DEAD_KEY  0x80    /* - We found at least one dead key */
+
+       struct rb_node *cursor;
+       struct key *key;
+       time_t new_timer, limit;
+
+       kenter("[%lx,%x]", key_gc_flags, gc_state);
+
+       limit = current_kernel_time().tv_sec;
        if (limit > key_gc_delay)
                limit -= key_gc_delay;
        else
                limit = key_gc_delay;
 
+       /* Work out what we're going to be doing in this pass */
+       gc_state &= KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2;
+       gc_state <<= 1;
+       if (test_and_clear_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags))
+               gc_state |= KEY_GC_REAPING_LINKS | KEY_GC_SET_TIMER;
+
+       if (test_and_clear_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags))
+               gc_state |= KEY_GC_REAPING_DEAD_1;
+       kdebug("new pass %x", gc_state);
+
+       new_timer = LONG_MAX;
+
+       /* As only this function is permitted to remove things from the key
+        * serial tree, if cursor is non-NULL then it will always point to a
+        * valid node in the tree - even if lock got dropped.
+        */
        spin_lock(&key_serial_lock);
+       cursor = rb_first(&key_serial_tree);
 
-       if (unlikely(RB_EMPTY_ROOT(&key_serial_tree))) {
-               spin_unlock(&key_serial_lock);
-               clear_bit(0, &key_gc_executing);
-               return;
-       }
+continue_scanning:
+       while (cursor) {
+               key = rb_entry(cursor, struct key, serial_node);
+               cursor = rb_next(cursor);
 
-       cursor = key_gc_cursor;
-       if (cursor < 0)
-               cursor = 0;
-       if (cursor > 0)
-               new_timer = key_gc_new_timer;
-       else
-               key_gc_again = false;
-
-       /* find the first key above the cursor */
-       key = NULL;
-       rb = key_serial_tree.rb_node;
-       while (rb) {
-               xkey = rb_entry(rb, struct key, serial_node);
-               if (cursor < xkey->serial) {
-                       key = xkey;
-                       rb = rb->rb_left;
-               } else if (cursor > xkey->serial) {
-                       rb = rb->rb_right;
-               } else {
-                       rb = rb_next(rb);
-                       if (!rb)
-                               goto reached_the_end;
-                       key = rb_entry(rb, struct key, serial_node);
-                       break;
+               if (atomic_read(&key->usage) == 0)
+                       goto found_unreferenced_key;
+
+               if (unlikely(gc_state & KEY_GC_REAPING_DEAD_1)) {
+                       if (key->type == key_gc_dead_keytype) {
+                               gc_state |= KEY_GC_FOUND_DEAD_KEY;
+                               set_bit(KEY_FLAG_DEAD, &key->flags);
+                               key->perm = 0;
+                               goto skip_dead_key;
+                       }
+               }
+
+               if (gc_state & KEY_GC_SET_TIMER) {
+                       if (key->expiry > limit && key->expiry < new_timer) {
+                               kdebug("will expire %x in %ld",
+                                      key_serial(key), key->expiry - limit);
+                               new_timer = key->expiry;
+                       }
                }
-       }
 
-       if (!key)
-               goto reached_the_end;
+               if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2))
+                       if (key->type == key_gc_dead_keytype)
+                               gc_state |= KEY_GC_FOUND_DEAD_KEY;
 
-       /* trawl through the keys looking for keyrings */
-       for (;;) {
-               if (key->expiry > limit && key->expiry < new_timer) {
-                       kdebug("will expire %x in %ld",
-                              key_serial(key), key->expiry - limit);
-                       new_timer = key->expiry;
+               if ((gc_state & KEY_GC_REAPING_LINKS) ||
+                   unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
+                       if (key->type == &key_type_keyring)
+                               goto found_keyring;
                }
 
-               if (key->type == &key_type_keyring &&
-                   key_gc_keyring(key, limit))
-                       /* the gc had to release our lock so that the keyring
-                        * could be modified, so we have to get it again */
-                       goto gc_released_our_lock;
+               if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3))
+                       if (key->type == key_gc_dead_keytype)
+                               goto destroy_dead_key;
 
-               rb = rb_next(&key->serial_node);
-               if (!rb)
-                       goto reached_the_end;
-               key = rb_entry(rb, struct key, serial_node);
+       skip_dead_key:
+               if (spin_is_contended(&key_serial_lock) || need_resched())
+                       goto contended;
        }
 
-gc_released_our_lock:
-       kdebug("gc_released_our_lock");
-       key_gc_new_timer = new_timer;
-       key_gc_again = true;
-       clear_bit(0, &key_gc_executing);
-       schedule_work(&key_gc_work);
-       kleave(" [continue]");
-       return;
-
-       /* when we reach the end of the run, we set the timer for the next one */
-reached_the_end:
-       kdebug("reached_the_end");
+contended:
        spin_unlock(&key_serial_lock);
-       key_gc_new_timer = new_timer;
-       key_gc_cursor = 0;
-       clear_bit(0, &key_gc_executing);
-
-       if (key_gc_again) {
-               /* there may have been a key that expired whilst we were
-                * scanning, so if we discarded any links we should do another
-                * scan */
-               new_timer = now + 1;
-               key_schedule_gc(new_timer);
-       } else if (new_timer < LONG_MAX) {
+
+maybe_resched:
+       if (cursor) {
+               cond_resched();
+               spin_lock(&key_serial_lock);
+               goto continue_scanning;
+       }
+
+       /* We've completed the pass.  Set the timer if we need to and queue a
+        * new cycle if necessary.  We keep executing cycles until we find one
+        * where we didn't reap any keys.
+        */
+       kdebug("pass complete");
+
+       if (gc_state & KEY_GC_SET_TIMER && new_timer != (time_t)LONG_MAX) {
                new_timer += key_gc_delay;
                key_schedule_gc(new_timer);
        }
-       kleave(" [end]");
+
+       if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
+               /* Make sure everyone revalidates their keys if we marked a
+                * bunch as being dead and make sure all keyring ex-payloads
+                * are destroyed.
+                */
+               kdebug("dead sync");
+               synchronize_rcu();
+       }
+
+       if (unlikely(gc_state & (KEY_GC_REAPING_DEAD_1 |
+                                KEY_GC_REAPING_DEAD_2))) {
+               if (!(gc_state & KEY_GC_FOUND_DEAD_KEY)) {
+                       /* No remaining dead keys: short circuit the remaining
+                        * keytype reap cycles.
+                        */
+                       kdebug("dead short");
+                       gc_state &= ~(KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2);
+                       gc_state |= KEY_GC_REAPING_DEAD_3;
+               } else {
+                       gc_state |= KEY_GC_REAP_AGAIN;
+               }
+       }
+
+       if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3)) {
+               kdebug("dead wake");
+               smp_mb();
+               clear_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
+               wake_up_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE);
+       }
+
+       if (gc_state & KEY_GC_REAP_AGAIN)
+               queue_work(system_nrt_wq, &key_gc_work);
+       kleave(" [end %x]", gc_state);
+       return;
+
+       /* We found an unreferenced key - once we've removed it from the tree,
+        * we can safely drop the lock.
+        */
+found_unreferenced_key:
+       kdebug("unrefd key %d", key->serial);
+       rb_erase(&key->serial_node, &key_serial_tree);
+       spin_unlock(&key_serial_lock);
+
+       key_gc_unused_key(key);
+       gc_state |= KEY_GC_REAP_AGAIN;
+       goto maybe_resched;
+
+       /* We found a keyring and we need to check the payload for links to
+        * dead or expired keys.  We don't flag another reap immediately as we
+        * have to wait for the old payload to be destroyed by RCU before we
+        * can reap the keys to which it refers.
+        */
+found_keyring:
+       spin_unlock(&key_serial_lock);
+       kdebug("scan keyring %d", key->serial);
+       key_gc_keyring(key, limit);
+       goto maybe_resched;
+
+       /* We found a dead key that is still referenced.  Reset its type and
+        * destroy its payload with its semaphore held.
+        */
+destroy_dead_key:
+       spin_unlock(&key_serial_lock);
+       kdebug("destroy key %d", key->serial);
+       down_write(&key->sem);
+       key->type = &key_type_dead;
+       if (key_gc_dead_keytype->destroy)
+               key_gc_dead_keytype->destroy(key);
+       memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
+       up_write(&key->sem);
+       goto maybe_resched;
 }
index f375152a2500b1d747d7128517430d2401f3a4ce..c7a7caec4830b33e414ac7fa3b665633b853a080 100644 (file)
@@ -31,6 +31,7 @@
        no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__)
 #endif
 
+extern struct key_type key_type_dead;
 extern struct key_type key_type_user;
 
 /*****************************************************************************/
@@ -75,6 +76,7 @@ extern unsigned key_quota_maxbytes;
 #define KEYQUOTA_LINK_BYTES    4               /* a link in a keyring is worth 4 bytes */
 
 
+extern struct kmem_cache *key_jar;
 extern struct rb_root key_serial_tree;
 extern spinlock_t key_serial_lock;
 extern struct mutex key_construction_mutex;
@@ -146,9 +148,11 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
 
 extern long join_session_keyring(const char *name);
 
+extern struct work_struct key_gc_work;
 extern unsigned key_gc_delay;
 extern void keyring_gc(struct key *keyring, time_t limit);
 extern void key_schedule_gc(time_t expiry_at);
+extern void key_gc_keytype(struct key_type *ktype);
 
 extern int key_task_permission(const key_ref_t key_ref,
                               const struct cred *cred,
index f7f9d93f08d98df064104630c3f91ce4fb2aaab9..4414abddcb5bfd6951d168018990c6df2567b901 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/user_namespace.h>
 #include "internal.h"
 
-static struct kmem_cache       *key_jar;
+struct kmem_cache *key_jar;
 struct rb_root         key_serial_tree; /* tree of keys indexed by serial */
 DEFINE_SPINLOCK(key_serial_lock);
 
@@ -36,17 +36,9 @@ unsigned int key_quota_maxbytes = 20000;     /* general key space quota */
 static LIST_HEAD(key_types_list);
 static DECLARE_RWSEM(key_types_sem);
 
-static void key_cleanup(struct work_struct *work);
-static DECLARE_WORK(key_cleanup_task, key_cleanup);
-
 /* We serialise key instantiation and link */
 DEFINE_MUTEX(key_construction_mutex);
 
-/* Any key who's type gets unegistered will be re-typed to this */
-static struct key_type key_type_dead = {
-       .name           = "dead",
-};
-
 #ifdef KEY_DEBUGGING
 void __key_check(const struct key *key)
 {
@@ -591,71 +583,6 @@ int key_reject_and_link(struct key *key,
 }
 EXPORT_SYMBOL(key_reject_and_link);
 
-/*
- * Garbage collect keys in process context so that we don't have to disable
- * interrupts all over the place.
- *
- * key_put() schedules this rather than trying to do the cleanup itself, which
- * means key_put() doesn't have to sleep.
- */
-static void key_cleanup(struct work_struct *work)
-{
-       struct rb_node *_n;
-       struct key *key;
-
-go_again:
-       /* look for a dead key in the tree */
-       spin_lock(&key_serial_lock);
-
-       for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
-               key = rb_entry(_n, struct key, serial_node);
-
-               if (atomic_read(&key->usage) == 0)
-                       goto found_dead_key;
-       }
-
-       spin_unlock(&key_serial_lock);
-       return;
-
-found_dead_key:
-       /* we found a dead key - once we've removed it from the tree, we can
-        * drop the lock */
-       rb_erase(&key->serial_node, &key_serial_tree);
-       spin_unlock(&key_serial_lock);
-
-       key_check(key);
-
-       security_key_free(key);
-
-       /* deal with the user's key tracking and quota */
-       if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
-               spin_lock(&key->user->lock);
-               key->user->qnkeys--;
-               key->user->qnbytes -= key->quotalen;
-               spin_unlock(&key->user->lock);
-       }
-
-       atomic_dec(&key->user->nkeys);
-       if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
-               atomic_dec(&key->user->nikeys);
-
-       key_user_put(key->user);
-
-       /* now throw away the key memory */
-       if (key->type->destroy)
-               key->type->destroy(key);
-
-       kfree(key->description);
-
-#ifdef KEY_DEBUGGING
-       key->magic = KEY_DEBUG_MAGIC_X;
-#endif
-       kmem_cache_free(key_jar, key);
-
-       /* there may, of course, be more than one key to destroy */
-       goto go_again;
-}
-
 /**
  * key_put - Discard a reference to a key.
  * @key: The key to discard a reference from.
@@ -670,7 +597,7 @@ void key_put(struct key *key)
                key_check(key);
 
                if (atomic_dec_and_test(&key->usage))
-                       schedule_work(&key_cleanup_task);
+                       queue_work(system_nrt_wq, &key_gc_work);
        }
 }
 EXPORT_SYMBOL(key_put);
@@ -1048,49 +975,11 @@ EXPORT_SYMBOL(register_key_type);
  */
 void unregister_key_type(struct key_type *ktype)
 {
-       struct rb_node *_n;
-       struct key *key;
-
        down_write(&key_types_sem);
-
-       /* withdraw the key type */
        list_del_init(&ktype->link);
-
-       /* mark all the keys of this type dead */
-       spin_lock(&key_serial_lock);
-
-       for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
-               key = rb_entry(_n, struct key, serial_node);
-
-               if (key->type == ktype) {
-                       key->type = &key_type_dead;
-                       set_bit(KEY_FLAG_DEAD, &key->flags);
-               }
-       }
-
-       spin_unlock(&key_serial_lock);
-
-       /* make sure everyone revalidates their keys */
-       synchronize_rcu();
-
-       /* we should now be able to destroy the payloads of all the keys of
-        * this type with impunity */
-       spin_lock(&key_serial_lock);
-
-       for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
-               key = rb_entry(_n, struct key, serial_node);
-
-               if (key->type == ktype) {
-                       if (ktype->destroy)
-                               ktype->destroy(key);
-                       memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
-               }
-       }
-
-       spin_unlock(&key_serial_lock);
-       up_write(&key_types_sem);
-
-       key_schedule_gc(0);
+       downgrade_write(&key_types_sem);
+       key_gc_keytype(ktype);
+       up_read(&key_types_sem);
 }
 EXPORT_SYMBOL(unregister_key_type);
 
index 30e242f7bd0ec413bca908f1a0fdc5398b00a124..37a7f3b28852e098f57ab1cd98eb2eccdad5c7c5 100644 (file)
@@ -860,8 +860,7 @@ void __key_link(struct key *keyring, struct key *key,
 
        kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
 
-       klist = rcu_dereference_protected(keyring->payload.subscriptions,
-                                         rwsem_is_locked(&keyring->sem));
+       klist = rcu_dereference_locked_keyring(keyring);
 
        atomic_inc(&key->usage);
 
index a3063eb3dc232a16eab45161e28f0c88fc642841..1068cb1939b3122ca857b042ac0df9d304cda6a7 100644 (file)
@@ -270,7 +270,7 @@ static int install_session_keyring(struct key *keyring)
        if (!new)
                return -ENOMEM;
 
-       ret = install_session_keyring_to_cred(new, NULL);
+       ret = install_session_keyring_to_cred(new, keyring);
        if (ret < 0) {
                abort_creds(new);
                return ret;
@@ -589,12 +589,22 @@ try_again:
                        ret = install_user_keyrings();
                        if (ret < 0)
                                goto error;
-                       ret = install_session_keyring(
-                               cred->user->session_keyring);
+                       if (lflags & KEY_LOOKUP_CREATE)
+                               ret = join_session_keyring(NULL);
+                       else
+                               ret = install_session_keyring(
+                                       cred->user->session_keyring);
 
                        if (ret < 0)
                                goto error;
                        goto reget_creds;
+               } else if (cred->tgcred->session_keyring ==
+                          cred->user->session_keyring &&
+                          lflags & KEY_LOOKUP_CREATE) {
+                       ret = join_session_keyring(NULL);
+                       if (ret < 0)
+                               goto error;
+                       goto reget_creds;
                }
 
                rcu_read_lock();
index 0e4fccfef12cb495fcf059a4dc964e3b45ee136c..a6328421a0551bef7439247e3cda3588fcd30d20 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/security.h>
+#include <linux/integrity.h>
 #include <linux/ima.h>
+#include <linux/evm.h>
+
+#define MAX_LSM_EVM_XATTR      2
 
 /* Boot-time LSM user choice */
 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -334,20 +338,57 @@ int security_inode_alloc(struct inode *inode)
 
 void security_inode_free(struct inode *inode)
 {
-       ima_inode_free(inode);
+       integrity_inode_free(inode);
        security_ops->inode_free_security(inode);
 }
 
 int security_inode_init_security(struct inode *inode, struct inode *dir,
-                                const struct qstr *qstr, char **name,
-                                void **value, size_t *len)
+                                const struct qstr *qstr,
+                                const initxattrs initxattrs, void *fs_data)
+{
+       struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1];
+       struct xattr *lsm_xattr, *evm_xattr, *xattr;
+       int ret;
+
+       if (unlikely(IS_PRIVATE(inode)))
+               return -EOPNOTSUPP;
+
+       memset(new_xattrs, 0, sizeof new_xattrs);
+       if (!initxattrs)
+               return security_ops->inode_init_security(inode, dir, qstr,
+                                                        NULL, NULL, NULL);
+       lsm_xattr = new_xattrs;
+       ret = security_ops->inode_init_security(inode, dir, qstr,
+                                               &lsm_xattr->name,
+                                               &lsm_xattr->value,
+                                               &lsm_xattr->value_len);
+       if (ret)
+               goto out;
+
+       evm_xattr = lsm_xattr + 1;
+       ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr);
+       if (ret)
+               goto out;
+       ret = initxattrs(inode, new_xattrs, fs_data);
+out:
+       for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+               kfree(xattr->name);
+               kfree(xattr->value);
+       }
+       return (ret == -EOPNOTSUPP) ? 0 : ret;
+}
+EXPORT_SYMBOL(security_inode_init_security);
+
+int security_old_inode_init_security(struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr, char **name,
+                                    void **value, size_t *len)
 {
        if (unlikely(IS_PRIVATE(inode)))
                return -EOPNOTSUPP;
        return security_ops->inode_init_security(inode, dir, qstr, name, value,
                                                 len);
 }
-EXPORT_SYMBOL(security_inode_init_security);
+EXPORT_SYMBOL(security_old_inode_init_security);
 
 #ifdef CONFIG_SECURITY_PATH
 int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
@@ -523,9 +564,14 @@ int security_inode_permission(struct inode *inode, int mask)
 
 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
 {
+       int ret;
+
        if (unlikely(IS_PRIVATE(dentry->d_inode)))
                return 0;
-       return security_ops->inode_setattr(dentry, attr);
+       ret = security_ops->inode_setattr(dentry, attr);
+       if (ret)
+               return ret;
+       return evm_inode_setattr(dentry, attr);
 }
 EXPORT_SYMBOL_GPL(security_inode_setattr);
 
@@ -539,9 +585,14 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
 int security_inode_setxattr(struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags)
 {
+       int ret;
+
        if (unlikely(IS_PRIVATE(dentry->d_inode)))
                return 0;
-       return security_ops->inode_setxattr(dentry, name, value, size, flags);
+       ret = security_ops->inode_setxattr(dentry, name, value, size, flags);
+       if (ret)
+               return ret;
+       return evm_inode_setxattr(dentry, name, value, size);
 }
 
 void security_inode_post_setxattr(struct dentry *dentry, const char *name,
@@ -550,6 +601,7 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
        if (unlikely(IS_PRIVATE(dentry->d_inode)))
                return;
        security_ops->inode_post_setxattr(dentry, name, value, size, flags);
+       evm_inode_post_setxattr(dentry, name, value, size);
 }
 
 int security_inode_getxattr(struct dentry *dentry, const char *name)
@@ -568,9 +620,14 @@ int security_inode_listxattr(struct dentry *dentry)
 
 int security_inode_removexattr(struct dentry *dentry, const char *name)
 {
+       int ret;
+
        if (unlikely(IS_PRIVATE(dentry->d_inode)))
                return 0;
-       return security_ops->inode_removexattr(dentry, name);
+       ret = security_ops->inode_removexattr(dentry, name);
+       if (ret)
+               return ret;
+       return evm_inode_removexattr(dentry, name);
 }
 
 int security_inode_need_killpriv(struct dentry *dentry)
index ae135fbbbe955b922c0fe3dbe6d8d158dc6fa9d1..5295b5caaa21f54435c4f4b05ef2248651e4d8b9 100644 (file)
@@ -660,7 +660,7 @@ static int tomoyo_gc_thread(void *unused)
        static DEFINE_MUTEX(tomoyo_gc_mutex);
        if (!mutex_trylock(&tomoyo_gc_mutex))
                goto out;
-       daemonize("GC for TOMOYO");
+
        do {
                tomoyo_collect_entry();
                if (list_empty(&tomoyo_gc_list))
index 1c6be91dfb9887ea1b3634735858e27757c42e21..c74e228731ed8ffb36788f5443581dbd0d4fdae2 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/file.h>
 #include <linux/slab.h>
 #include <linux/time.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
 #include <linux/uio.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
index 440030818db70c88c582d0047790baed074297c9..cd094ecaca3befb440ad1dea44b279fdfbca7930 100644 (file)
@@ -51,7 +51,6 @@ struct isight {
        struct fw_unit *unit;
        struct fw_device *device;
        u64 audio_base;
-       struct fw_address_handler iris_handler;
        struct snd_pcm_substream *pcm;
        struct mutex mutex;
        struct iso_packets_buffer buffer;
index a9823fad85c2d9ecaf0bbc2bfd0ad13d3e254796..77dd0a13aecc40f59ac9361f241f376a61173934 100644 (file)
@@ -23,12 +23,15 @@ config SND_SGI_HAL2
 
 
 config SND_AU1X00
-       tristate "Au1x00 AC97 Port Driver"
+       tristate "Au1x00 AC97 Port Driver (DEPRECATED)"
        depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500
        select SND_PCM
        select SND_AC97_CODEC
        help
          ALSA Sound driver for the Au1x00's AC97 port.
 
+         Newer drivers for ASoC are available, please do not use
+         this driver as it will be removed in the future.
+
 endif  # SND_MIPS
 
index 87365d5ea2a9e6cb561667a453232917157ef97a..f928d663472322f00d0f7fdb835e6bf589bd65f7 100644 (file)
@@ -6,6 +6,9 @@ snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
 snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
 snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
 
+# for trace-points
+CFLAGS_hda_codec.o := -I$(src)
+
 snd-hda-codec-realtek-objs :=  patch_realtek.o
 snd-hda-codec-cmedia-objs :=   patch_cmedia.o
 snd-hda-codec-analog-objs :=   patch_analog.o
index 21ec2cb100b06e9c289b69eecc3f3ff6ceb32ebe..3b5170b9700f03b0c49d47ef0842e17a1eef1dd7 100644 (file)
@@ -7,9 +7,6 @@
 enum {
        ALC260_AUTO,
        ALC260_BASIC,
-       ALC260_HP,
-       ALC260_HP_DC7600,
-       ALC260_HP_3013,
        ALC260_FUJITSU_S702X,
        ALC260_ACER,
        ALC260_WILL,
@@ -142,8 +139,6 @@ static const struct hda_channel_mode alc260_modes[1] = {
 /* Mixer combinations
  *
  * basic: base_output + input + pc_beep + capture
- * HP: base_output + input + capture_alt
- * HP_3013: hp_3013 + input + capture
  * fujitsu: fujitsu + capture
  * acer: acer + capture
  */
@@ -170,145 +165,6 @@ static const struct snd_kcontrol_new alc260_input_mixer[] = {
        { } /* end */
 };
 
-/* update HP, line and mono out pins according to the master switch */
-static void alc260_hp_master_update(struct hda_codec *codec)
-{
-       update_speakers(codec);
-}
-
-static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
-                                  struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       *ucontrol->value.integer.value = !spec->master_mute;
-       return 0;
-}
-
-static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
-                                  struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       struct alc_spec *spec = codec->spec;
-       int val = !*ucontrol->value.integer.value;
-
-       if (val == spec->master_mute)
-               return 0;
-       spec->master_mute = val;
-       alc260_hp_master_update(codec);
-       return 1;
-}
-
-static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
-               .info = snd_ctl_boolean_mono_info,
-               .get = alc260_hp_master_sw_get,
-               .put = alc260_hp_master_sw_put,
-       },
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
-                             HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct hda_verb alc260_hp_unsol_verbs[] = {
-       {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {},
-};
-
-static void alc260_hp_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x0f;
-       spec->autocfg.speaker_pins[0] = 0x10;
-       spec->autocfg.speaker_pins[1] = 0x11;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-}
-
-static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
-               .info = snd_ctl_boolean_mono_info,
-               .get = alc260_hp_master_sw_get,
-               .put = alc260_hp_master_sw_put,
-       },
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
-       HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-static void alc260_hp_3013_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x10;
-       spec->autocfg.speaker_pins[1] = 0x11;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-}
-
-static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
-       .ops = &snd_hda_bind_vol,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
-       HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
-       HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {},
-};
-
-static void alc260_hp_3012_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x10;
-       spec->autocfg.speaker_pins[0] = 0x0f;
-       spec->autocfg.speaker_pins[1] = 0x11;
-       spec->autocfg.speaker_pins[2] = 0x15;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-}
-
 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
  */
@@ -480,106 +336,6 @@ static const struct hda_verb alc260_init_verbs[] = {
        { }
 };
 
-#if 0 /* should be identical with alc260_init_verbs? */
-static const struct hda_verb alc260_hp_init_verbs[] = {
-       /* Headphone and output */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
-       /* mono output */
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       /* Mic1 (rear panel) pin widget for input and vref at 80% */
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       /* Mic2 (front panel) pin widget for input and vref at 80% */
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       /* Line In pin widget for input */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       /* Line-2 pin widget for output */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       /* CD pin widget for input */
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       /* unmute amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-       /* set connection select to line in (default select for this ADC) */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* unmute Line-Out mixer amp left and right (volume = 0) */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-       /* mute pin widget amp left and right (no gain on this amp) */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-       /* unmute HP mixer amp left and right (volume = 0) */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-       /* mute pin widget amp left and right (no gain on this amp) */
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
-        * Line In 2 = 0x03
-        */
-       /* mute analog inputs */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-       /* Unmute Front out path */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       /* Unmute Headphone out path */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       /* Unmute Mono out path */
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       { }
-};
-#endif
-
-static const struct hda_verb alc260_hp_3013_init_verbs[] = {
-       /* Line out and output */
-       {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       /* mono output */
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       /* Mic1 (rear panel) pin widget for input and vref at 80% */
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       /* Mic2 (front panel) pin widget for input and vref at 80% */
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       /* Line In pin widget for input */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       /* Headphone pin widget for output */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
-       /* CD pin widget for input */
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       /* unmute amp left and right */
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-       /* set connection select to line in (default select for this ADC) */
-       {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* unmute Line-Out mixer amp left and right (volume = 0) */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-       /* mute pin widget amp left and right (no gain on this amp) */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-       /* unmute HP mixer amp left and right (volume = 0) */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-       /* mute pin widget amp left and right (no gain on this amp) */
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
-        * Line In 2 = 0x03
-        */
-       /* mute analog inputs */
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-       /* Unmute Front out path */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       /* Unmute Headphone out path */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       /* Unmute Mono out path */
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       { }
-};
-
 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
  * audio = 0x16, internal speaker = 0x10.
@@ -1093,9 +849,6 @@ static const struct hda_verb alc260_test_init_verbs[] = {
  */
 static const char * const alc260_models[ALC260_MODEL_LAST] = {
        [ALC260_BASIC]          = "basic",
-       [ALC260_HP]             = "hp",
-       [ALC260_HP_3013]        = "hp-3013",
-       [ALC260_HP_DC7600]      = "hp-dc7600",
        [ALC260_FUJITSU_S702X]  = "fujitsu",
        [ALC260_ACER]           = "acer",
        [ALC260_WILL]           = "will",
@@ -1112,15 +865,6 @@ static const struct snd_pci_quirk alc260_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
        SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
        SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
-       SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
-       SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
-       SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
-       SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
-       SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
-       SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
-       SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
-       SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
-       SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
        SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
        SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
        SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
@@ -1144,54 +888,6 @@ static const struct alc_config_preset alc260_presets[] = {
                .channel_mode = alc260_modes,
                .input_mux = &alc260_capture_source,
        },
-       [ALC260_HP] = {
-               .mixers = { alc260_hp_output_mixer,
-                           alc260_input_mixer },
-               .init_verbs = { alc260_init_verbs,
-                               alc260_hp_unsol_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
-               .adc_nids = alc260_adc_nids_alt,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .input_mux = &alc260_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc260_hp_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC260_HP_DC7600] = {
-               .mixers = { alc260_hp_dc7600_mixer,
-                           alc260_input_mixer },
-               .init_verbs = { alc260_init_verbs,
-                               alc260_hp_dc7600_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
-               .adc_nids = alc260_adc_nids_alt,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .input_mux = &alc260_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc260_hp_3012_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC260_HP_3013] = {
-               .mixers = { alc260_hp_3013_mixer,
-                           alc260_input_mixer },
-               .init_verbs = { alc260_hp_3013_init_verbs,
-                               alc260_hp_3013_unsol_verbs },
-               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
-               .dac_nids = alc260_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
-               .adc_nids = alc260_adc_nids_alt,
-               .num_channel_mode = ARRAY_SIZE(alc260_modes),
-               .channel_mode = alc260_modes,
-               .input_mux = &alc260_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc260_hp_3013_setup,
-               .init_hook = alc_inithook,
-       },
        [ALC260_FUJITSU_S702X] = {
                .mixers = { alc260_fujitsu_mixer },
                .init_verbs = { alc260_fujitsu_init_verbs },
index 8d2097d776422e52fab49fe6140a79a6f8f2286f..c37e0c2939b639463bda169ebd79cf4d06d45f78 100644 (file)
@@ -10,13 +10,7 @@ enum {
        ALC262_HIPPO,
        ALC262_HIPPO_1,
        ALC262_FUJITSU,
-       ALC262_HP_BPC,
-       ALC262_HP_BPC_D7000_WL,
-       ALC262_HP_BPC_D7000_WF,
-       ALC262_HP_TC_T5735,
-       ALC262_HP_RP5700,
        ALC262_BENQ_ED8,
-       ALC262_SONY_ASSAMD,
        ALC262_BENQ_T31,
        ALC262_ULTRA,
        ALC262_LENOVO_3000,
@@ -66,164 +60,35 @@ static const struct snd_kcontrol_new alc262_base_mixer[] = {
        { } /* end */
 };
 
-/* update HP, line and mono-out pins according to the master switch */
-#define alc262_hp_master_update                alc260_hp_master_update
-
-static void alc262_hp_bpc_setup(struct hda_codec *codec)
+/* bind hp and internal speaker mute (with plug check) as master switch */
+static void alc262_hippo_master_update(struct hda_codec *codec)
 {
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.speaker_pins[0] = 0x16;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
+       update_speakers(codec);
 }
 
-static void alc262_hp_wildwest_setup(struct hda_codec *codec)
+static int alc262_hippo_master_sw_get(struct snd_kcontrol *kcontrol,
+                                     struct snd_ctl_elem_value *ucontrol)
 {
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x16;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
+       *ucontrol->value.integer.value = !spec->master_mute;
+       return 0;
 }
 
-#define alc262_hp_master_sw_get                alc260_hp_master_sw_get
-#define alc262_hp_master_sw_put                alc260_hp_master_sw_put
-
-#define ALC262_HP_MASTER_SWITCH                                        \
-       {                                                       \
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
-               .name = "Master Playback Switch",               \
-               .info = snd_ctl_boolean_mono_info,              \
-               .get = alc262_hp_master_sw_get,                 \
-               .put = alc262_hp_master_sw_put,                 \
-       }, \
-       {                                                       \
-               .iface = NID_MAPPING,                           \
-               .name = "Master Playback Switch",               \
-               .private_value = 0x15 | (0x16 << 8) | (0x1b << 16),     \
-       }
-
-
-static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
-       ALC262_HP_MASTER_SWITCH,
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
-                             HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
-                           HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
-       HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
-       ALC262_HP_MASTER_SWITCH,
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
-                             HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
-                           HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
-       HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       { } /* end */
-};
-
-/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc262_hp_t5735_setup(struct hda_codec *codec)
+static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
 {
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct alc_spec *spec = codec->spec;
+       int val = !*ucontrol->value.integer.value;
 
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
+       if (val == spec->master_mute)
+               return 0;
+       spec->master_mute = val;
+       alc262_hippo_master_update(codec);
+       return 1;
 }
 
-static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct hda_verb alc262_hp_t5735_verbs[] = {
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       { }
-};
-
-static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct hda_verb alc262_hp_rp5700_verbs[] = {
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
-       {}
-};
-
-static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
-       .num_items = 1,
-       .items = {
-               { "Line", 0x1 },
-       },
-};
-
-/* bind hp and internal speaker mute (with plug check) as master switch */
-#define alc262_hippo_master_update     alc262_hp_master_update
-#define alc262_hippo_master_sw_get     alc262_hp_master_sw_get
-#define alc262_hippo_master_sw_put     alc262_hp_master_sw_put
-
 #define ALC262_HIPPO_MASTER_SWITCH                             \
        {                                                       \
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
@@ -239,6 +104,9 @@ static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
                             (SUBDEV_SPEAKER(0) << 16), \
        }
 
+#define alc262_hp_master_sw_get                alc262_hippo_master_sw_get
+#define alc262_hp_master_sw_put                alc262_hippo_master_sw_put
+
 static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
        ALC262_HIPPO_MASTER_SWITCH,
        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -571,27 +439,6 @@ static const struct hda_input_mux alc262_fujitsu_capture_source = {
        },
 };
 
-static const struct hda_input_mux alc262_HP_capture_source = {
-       .num_items = 5,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x1 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-               { "AUX IN", 0x6 },
-       },
-};
-
-static const struct hda_input_mux alc262_HP_D7000_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x2 },
-               { "Line", 0x1 },
-               { "CD", 0x4 },
-       },
-};
-
 static void alc262_fujitsu_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -817,206 +664,6 @@ static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
        { } /* end */
 };
 
-static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
-       /*
-        * Unmute ADC0-2 and set the default input to mic-in
-        */
-       {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
-        * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for
-        * front panel mic (mic 2)
-        */
-       /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
-        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
-
-       /*
-        * Set up output mixers (0x0c - 0x0e)
-        */
-       /* set vol=0 to output mixers */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* set up input amps for analog loopback */
-       /* Amp Indices: DAC = 0, mixer = 1 */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-
-
-       /* FIXME: use matrix-type input source selection */
-       /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
-       /* Input mixer1: only unmute Mic */
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
-       /* Input mixer2 */
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
-       /* Input mixer3 */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
-
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-
-       { }
-};
-
-static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
-       /*
-        * Unmute ADC0-2 and set the default input to mic-in
-        */
-       {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
-        * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front
-        * panel mic (mic 2)
-        */
-       /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
-       /*
-        * Set up output mixers (0x0c - 0x0e)
-        */
-       /* set vol=0 to output mixers */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* set up input amps for analog loopback */
-       /* Amp Indices: DAC = 0, mixer = 1 */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
-
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-
-       /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
-       {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-       {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
-
-       /* FIXME: use matrix-type input source selection */
-       /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
-       /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
-        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
-       /* Input mixer2 */
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
-        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
-       /* Input mixer3 */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
-        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
-
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-
-       { }
-};
-
 static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
 
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Front Speaker */
@@ -1042,13 +689,8 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = {
        [ALC262_HIPPO]          = "hippo",
        [ALC262_HIPPO_1]        = "hippo_1",
        [ALC262_FUJITSU]        = "fujitsu",
-       [ALC262_HP_BPC]         = "hp-bpc",
-       [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
-       [ALC262_HP_TC_T5735]    = "hp-tc-t5735",
-       [ALC262_HP_RP5700]      = "hp-rp5700",
        [ALC262_BENQ_ED8]       = "benq",
        [ALC262_BENQ_T31]       = "benq-t31",
-       [ALC262_SONY_ASSAMD]    = "sony-assamd",
        [ALC262_TOSHIBA_S06]    = "toshiba-s06",
        [ALC262_TOSHIBA_RX1]    = "toshiba-rx1",
        [ALC262_ULTRA]          = "ultra",
@@ -1061,41 +703,6 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = {
 static const struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
        SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
-       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
-                          ALC262_HP_BPC),
-       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
-                          ALC262_HP_BPC),
-       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
-                          ALC262_HP_BPC),
-       SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
-                          ALC262_AUTO),
-       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
-                          ALC262_HP_BPC),
-       SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
-       SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
-       SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
-       SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
-       SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
-       SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
-       SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
-       SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
-       SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
-       SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
-       SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
-       SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
-                     ALC262_HP_TC_T5735),
-       SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
-       SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
-       SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
-       SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
-       SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
-       SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
-       SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
-       SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
-#if 0 /* disable the quirk since model=auto works better in recent versions */
-       SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
-                          ALC262_SONY_ASSAMD),
-#endif
        SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
                      ALC262_TOSHIBA_RX1),
        SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
@@ -1166,68 +773,6 @@ static const struct alc_config_preset alc262_presets[] = {
                .setup = alc262_fujitsu_setup,
                .init_hook = alc_inithook,
        },
-       [ALC262_HP_BPC] = {
-               .mixers = { alc262_HP_BPC_mixer },
-               .init_verbs = { alc262_HP_BPC_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
-               .dac_nids = alc262_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_HP_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc262_hp_bpc_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC262_HP_BPC_D7000_WF] = {
-               .mixers = { alc262_HP_BPC_WildWest_mixer },
-               .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
-               .dac_nids = alc262_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_HP_D7000_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc262_hp_wildwest_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC262_HP_BPC_D7000_WL] = {
-               .mixers = { alc262_HP_BPC_WildWest_mixer,
-                           alc262_HP_BPC_WildWest_option_mixer },
-               .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
-               .dac_nids = alc262_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_HP_D7000_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc262_hp_wildwest_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC262_HP_TC_T5735] = {
-               .mixers = { alc262_hp_t5735_mixer },
-               .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
-               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
-               .dac_nids = alc262_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc262_hp_t5735_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC262_HP_RP5700] = {
-               .mixers = { alc262_hp_rp5700_mixer },
-               .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
-               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
-               .dac_nids = alc262_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_hp_rp5700_capture_source,
-        },
        [ALC262_BENQ_ED8] = {
                .mixers = { alc262_base_mixer },
                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
@@ -1238,19 +783,6 @@ static const struct alc_config_preset alc262_presets[] = {
                .channel_mode = alc262_modes,
                .input_mux = &alc262_capture_source,
        },
-       [ALC262_SONY_ASSAMD] = {
-               .mixers = { alc262_sony_mixer },
-               .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
-               .num_dacs = ARRAY_SIZE(alc262_dac_nids),
-               .dac_nids = alc262_dac_nids,
-               .hp_nid = 0x02,
-               .num_channel_mode = ARRAY_SIZE(alc262_modes),
-               .channel_mode = alc262_modes,
-               .input_mux = &alc262_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc262_hippo_setup,
-               .init_hook = alc_inithook,
-       },
        [ALC262_BENQ_T31] = {
                .mixers = { alc262_benq_t31_mixer },
                .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c
deleted file mode 100644 (file)
index 2e5876c..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * ALC267/ALC268 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC268 models */
-enum {
-       ALC268_AUTO,
-       ALC267_QUANTA_IL1,
-       ALC268_3ST,
-       ALC268_TOSHIBA,
-       ALC268_ACER,
-       ALC268_ACER_DMIC,
-       ALC268_ACER_ASPIRE_ONE,
-       ALC268_DELL,
-       ALC268_ZEPTO,
-#ifdef CONFIG_SND_DEBUG
-       ALC268_TEST,
-#endif
-       ALC268_MODEL_LAST /* last tag */
-};
-
-/*
- *  ALC268 channel source setting (2 channel)
- */
-#define ALC268_DIGOUT_NID      ALC880_DIGOUT_NID
-#define alc268_modes           alc260_modes
-
-static const hda_nid_t alc268_dac_nids[2] = {
-       /* front, hp */
-       0x02, 0x03
-};
-
-static const hda_nid_t alc268_adc_nids[2] = {
-       /* ADC0-1 */
-       0x08, 0x07
-};
-
-static const hda_nid_t alc268_adc_nids_alt[1] = {
-       /* ADC0 */
-       0x08
-};
-
-static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
-
-static const struct snd_kcontrol_new alc268_base_mixer[] = {
-       /* output mixer control */
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
-       { }
-};
-
-static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
-       /* output mixer control */
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
-       ALC262_HIPPO_MASTER_SWITCH,
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
-       { }
-};
-
-static const struct hda_verb alc268_eapd_verbs[] = {
-       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
-       { }
-};
-
-/* Toshiba specific */
-static const struct hda_verb alc268_toshiba_verbs[] = {
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       { } /* end */
-};
-
-/* Acer specific */
-/* bind volumes of both NID 0x02 and 0x03 */
-static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
-       .ops = &snd_hda_bind_vol,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static void alc268_acer_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x15;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_AMP;
-}
-
-#define alc268_acer_master_sw_get      alc262_hp_master_sw_get
-#define alc268_acer_master_sw_put      alc262_hp_master_sw_put
-
-static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
-       /* output mixer control */
-       HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
-               .info = snd_ctl_boolean_mono_info,
-               .get = alc268_acer_master_sw_get,
-               .put = alc268_acer_master_sw_put,
-       },
-       HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
-       { }
-};
-
-static const struct snd_kcontrol_new alc268_acer_mixer[] = {
-       /* output mixer control */
-       HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
-               .info = snd_ctl_boolean_mono_info,
-               .get = alc268_acer_master_sw_get,
-               .put = alc268_acer_master_sw_put,
-       },
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
-       { }
-};
-
-static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
-       /* output mixer control */
-       HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
-               .info = snd_ctl_boolean_mono_info,
-               .get = alc268_acer_master_sw_get,
-               .put = alc268_acer_master_sw_put,
-       },
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
-       { }
-};
-
-static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
-       { }
-};
-
-static const struct hda_verb alc268_acer_verbs[] = {
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       { }
-};
-
-/* unsolicited event for HP jack sensing */
-#define alc268_toshiba_setup           alc262_hippo_setup
-
-static void alc268_acer_lc_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_AMP;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x12;
-       spec->auto_mic = 1;
-}
-
-static const struct snd_kcontrol_new alc268_dell_mixer[] = {
-       /* output mixer control */
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       { }
-};
-
-static const struct hda_verb alc268_dell_verbs[] = {
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
-       { }
-};
-
-/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc268_dell_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-}
-
-static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       { }
-};
-
-static const struct hda_verb alc267_quanta_il1_verbs[] = {
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
-       { }
-};
-
-static void alc267_quanta_il1_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-}
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc268_base_init_verbs[] = {
-       /* Unmute DAC0-1 and set vol = 0 */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /*
-        * Set up output mixers (0x0c - 0x0e)
-        */
-       /* set vol=0 to output mixers */
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-       /* set PCBEEP vol = 0, mute connections */
-       {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-       /* Unmute Selector 23h,24h and set the default input to mic-in */
-
-       {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       { }
-};
-
-/* only for model=test */
-#ifdef CONFIG_SND_DEBUG
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc268_volume_init_verbs[] = {
-       /* set output DAC */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       { }
-};
-#endif /* CONFIG_SND_DEBUG */
-
-static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
-       _DEFINE_CAPSRC(1),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc268_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
-       _DEFINE_CAPSRC(2),
-       { } /* end */
-};
-
-static const struct hda_input_mux alc268_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x1 },
-               { "Line", 0x2 },
-               { "CD", 0x3 },
-       },
-};
-
-static const struct hda_input_mux alc268_acer_capture_source = {
-       .num_items = 3,
-       .items = {
-               { "Mic", 0x0 },
-               { "Internal Mic", 0x1 },
-               { "Line", 0x2 },
-       },
-};
-
-static const struct hda_input_mux alc268_acer_dmic_capture_source = {
-       .num_items = 3,
-       .items = {
-               { "Mic", 0x0 },
-               { "Internal Mic", 0x6 },
-               { "Line", 0x2 },
-       },
-};
-
-#ifdef CONFIG_SND_DEBUG
-static const struct snd_kcontrol_new alc268_test_mixer[] = {
-       /* Volume widgets */
-       HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-       HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
-       HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
-       HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
-       HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
-       HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
-       HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
-       HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
-       /* The below appears problematic on some hardwares */
-       /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
-       HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
-
-       /* Modes for retasking pin widgets */
-       ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
-       ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
-
-       /* Controls for GPIO pins, assuming they are configured as outputs */
-       ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
-       ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
-       ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
-       ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
-
-       /* Switches to allow the digital SPDIF output pin to be enabled.
-        * The ALC268 does not have an SPDIF input.
-        */
-       ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
-
-       /* A switch allowing EAPD to be enabled.  Some laptops seem to use
-        * this output to turn on an external amplifier.
-        */
-       ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
-       ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
-
-       { } /* end */
-};
-#endif
-
-/*
- * configuration and preset
- */
-static const char * const alc268_models[ALC268_MODEL_LAST] = {
-       [ALC267_QUANTA_IL1]     = "quanta-il1",
-       [ALC268_3ST]            = "3stack",
-       [ALC268_TOSHIBA]        = "toshiba",
-       [ALC268_ACER]           = "acer",
-       [ALC268_ACER_DMIC]      = "acer-dmic",
-       [ALC268_ACER_ASPIRE_ONE]        = "acer-aspire",
-       [ALC268_DELL]           = "dell",
-       [ALC268_ZEPTO]          = "zepto",
-#ifdef CONFIG_SND_DEBUG
-       [ALC268_TEST]           = "test",
-#endif
-       [ALC268_AUTO]           = "auto",
-};
-
-static const struct snd_pci_quirk alc268_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
-       SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
-       SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
-       SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
-       SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
-       SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
-                                               ALC268_ACER_ASPIRE_ONE),
-       SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
-       SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
-       SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
-                       "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
-       /* almost compatible with toshiba but with optional digital outs;
-        * auto-probing seems working fine
-        */
-       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
-                          ALC268_AUTO),
-       SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
-       SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
-       SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
-       SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
-       {}
-};
-
-/* Toshiba laptops have no unique PCI SSID but only codec SSID */
-static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
-       SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
-       SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
-                          ALC268_TOSHIBA),
-       {}
-};
-
-static const struct alc_config_preset alc268_presets[] = {
-       [ALC267_QUANTA_IL1] = {
-               .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
-               .cap_mixer = alc268_capture_nosrc_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc267_quanta_il1_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc267_quanta_il1_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC268_3ST] = {
-               .mixers = { alc268_base_mixer, alc268_beep_mixer },
-               .cap_mixer = alc268_capture_alt_mixer,
-               .init_verbs = { alc268_base_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-                .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x03,
-               .dig_out_nid = ALC268_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .input_mux = &alc268_capture_source,
-       },
-       [ALC268_TOSHIBA] = {
-               .mixers = { alc268_toshiba_mixer, alc268_beep_mixer },
-               .cap_mixer = alc268_capture_alt_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_toshiba_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .input_mux = &alc268_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc268_toshiba_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC268_ACER] = {
-               .mixers = { alc268_acer_mixer, alc268_beep_mixer },
-               .cap_mixer = alc268_capture_alt_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_acer_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x02,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .input_mux = &alc268_acer_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc268_acer_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC268_ACER_DMIC] = {
-               .mixers = { alc268_acer_dmic_mixer, alc268_beep_mixer },
-               .cap_mixer = alc268_capture_alt_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_acer_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x02,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .input_mux = &alc268_acer_dmic_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc268_acer_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC268_ACER_ASPIRE_ONE] = {
-               .mixers = { alc268_acer_aspire_one_mixer, alc268_beep_mixer},
-               .cap_mixer = alc268_capture_nosrc_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_acer_aspire_one_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc268_acer_lc_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC268_DELL] = {
-               .mixers = { alc268_dell_mixer, alc268_beep_mixer},
-               .cap_mixer = alc268_capture_nosrc_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_dell_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x02,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc268_dell_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC268_ZEPTO] = {
-               .mixers = { alc268_base_mixer, alc268_beep_mixer },
-               .cap_mixer = alc268_capture_alt_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_toshiba_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x03,
-               .dig_out_nid = ALC268_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .input_mux = &alc268_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc268_toshiba_setup,
-               .init_hook = alc_inithook,
-       },
-#ifdef CONFIG_SND_DEBUG
-       [ALC268_TEST] = {
-               .mixers = { alc268_test_mixer },
-               .cap_mixer = alc268_capture_mixer,
-               .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
-                               alc268_volume_init_verbs,
-                               alc268_beep_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc268_dac_nids),
-               .dac_nids = alc268_dac_nids,
-               .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
-               .adc_nids = alc268_adc_nids_alt,
-               .capsrc_nids = alc268_capsrc_nids,
-               .hp_nid = 0x03,
-               .dig_out_nid = ALC268_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc268_modes),
-               .channel_mode = alc268_modes,
-               .input_mux = &alc268_capture_source,
-       },
-#endif
-};
-
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c
deleted file mode 100644 (file)
index 5ac0e21..0000000
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * ALC269/ALC270/ALC275/ALC276 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC269 models */
-enum {
-       ALC269_AUTO,
-       ALC269_BASIC,
-       ALC269_QUANTA_FL1,
-       ALC269_AMIC,
-       ALC269_DMIC,
-       ALC269VB_AMIC,
-       ALC269VB_DMIC,
-       ALC269_FUJITSU,
-       ALC269_LIFEBOOK,
-       ALC271_ACER,
-       ALC269_MODEL_LAST /* last tag */
-};
-
-/*
- *  ALC269 channel source setting (2 channel)
- */
-#define ALC269_DIGOUT_NID      ALC880_DIGOUT_NID
-
-#define alc269_dac_nids                alc260_dac_nids
-
-static const hda_nid_t alc269_adc_nids[1] = {
-       /* ADC1 */
-       0x08,
-};
-
-static const hda_nid_t alc269_capsrc_nids[1] = {
-       0x23,
-};
-
-static const hda_nid_t alc269vb_adc_nids[1] = {
-       /* ADC1 */
-       0x09,
-};
-
-static const hda_nid_t alc269vb_capsrc_nids[1] = {
-       0x22,
-};
-
-#define alc269_modes           alc260_modes
-#define alc269_capture_source  alc880_lg_lw_capture_source
-
-static const struct snd_kcontrol_new alc269_base_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
-       /* output mixer control */
-       HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_AMP_FLAG,
-               .info = snd_hda_mixer_amp_switch_info,
-               .get = snd_hda_mixer_amp_switch_get,
-               .put = alc268_acer_master_sw_put,
-               .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-       },
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       { }
-};
-
-static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
-       /* output mixer control */
-       HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .subdevice = HDA_SUBDEV_AMP_FLAG,
-               .info = snd_hda_mixer_amp_switch_info,
-               .get = snd_hda_mixer_amp_switch_get,
-               .put = alc268_acer_master_sw_put,
-               .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-       },
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
-       HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
-       { }
-};
-
-static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc269_asus_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-/* capture mixer elements */
-static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       { } /* end */
-};
-
-/* FSC amilo */
-#define alc269_fujitsu_mixer   alc269_laptop_mixer
-
-static const struct hda_verb alc269_quanta_fl1_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       { }
-};
-
-static const struct hda_verb alc269_lifebook_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       { }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
-{
-       alc_hp_automute(codec);
-
-       snd_hda_codec_write(codec, 0x20, 0,
-                       AC_VERB_SET_COEF_INDEX, 0x0c);
-       snd_hda_codec_write(codec, 0x20, 0,
-                       AC_VERB_SET_PROC_COEF, 0x680);
-
-       snd_hda_codec_write(codec, 0x20, 0,
-                       AC_VERB_SET_COEF_INDEX, 0x0c);
-       snd_hda_codec_write(codec, 0x20, 0,
-                       AC_VERB_SET_PROC_COEF, 0x480);
-}
-
-#define alc269_lifebook_speaker_automute \
-       alc269_quanta_fl1_speaker_automute
-
-static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
-{
-       unsigned int present_laptop;
-       unsigned int present_dock;
-
-       present_laptop  = snd_hda_jack_detect(codec, 0x18);
-       present_dock    = snd_hda_jack_detect(codec, 0x1b);
-
-       /* Laptop mic port overrides dock mic port, design decision */
-       if (present_dock)
-               snd_hda_codec_write(codec, 0x23, 0,
-                               AC_VERB_SET_CONNECT_SEL, 0x3);
-       if (present_laptop)
-               snd_hda_codec_write(codec, 0x23, 0,
-                               AC_VERB_SET_CONNECT_SEL, 0x0);
-       if (!present_dock && !present_laptop)
-               snd_hda_codec_write(codec, 0x23, 0,
-                               AC_VERB_SET_CONNECT_SEL, 0x1);
-}
-
-static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
-                                   unsigned int res)
-{
-       switch (res >> 26) {
-       case ALC_HP_EVENT:
-               alc269_quanta_fl1_speaker_automute(codec);
-               break;
-       case ALC_MIC_EVENT:
-               alc_mic_automute(codec);
-               break;
-       }
-}
-
-static void alc269_lifebook_unsol_event(struct hda_codec *codec,
-                                       unsigned int res)
-{
-       if ((res >> 26) == ALC_HP_EVENT)
-               alc269_lifebook_speaker_automute(codec);
-       if ((res >> 26) == ALC_MIC_EVENT)
-               alc269_lifebook_mic_autoswitch(codec);
-}
-
-static void alc269_quanta_fl1_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
-{
-       alc269_quanta_fl1_speaker_automute(codec);
-       alc_mic_automute(codec);
-}
-
-static void alc269_lifebook_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.hp_pins[1] = 0x1a;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-}
-
-static void alc269_lifebook_init_hook(struct hda_codec *codec)
-{
-       alc269_lifebook_speaker_automute(codec);
-       alc269_lifebook_mic_autoswitch(codec);
-}
-
-static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc271_acer_dmic_verbs[] = {
-       {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
-       {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x22, AC_VERB_SET_CONNECT_SEL, 6},
-       { }
-};
-
-static void alc269_laptop_amic_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-static void alc269_laptop_dmic_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x12;
-       spec->auto_mic = 1;
-}
-
-static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x12;
-       spec->auto_mic = 1;
-}
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc269_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /*
-        * Set up output mixers (0x02 - 0x03)
-        */
-       /* set vol=0 to output mixers */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* set up input amps for analog loopback */
-       /* Amp Indices: DAC = 0, mixer = 1 */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* FIXME: use Mux-type input source selection */
-       /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
-       /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
-       {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* set EAPD */
-       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-       { }
-};
-
-static const struct hda_verb alc269vb_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /*
-        * Set up output mixers (0x02 - 0x03)
-        */
-       /* set vol=0 to output mixers */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* set up input amps for analog loopback */
-       /* Amp Indices: DAC = 0, mixer = 1 */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* FIXME: use Mux-type input source selection */
-       /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
-       /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
-       {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* set EAPD */
-       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-       { }
-};
-
-/*
- * configuration and preset
- */
-static const char * const alc269_models[ALC269_MODEL_LAST] = {
-       [ALC269_BASIC]                  = "basic",
-       [ALC269_QUANTA_FL1]             = "quanta",
-       [ALC269_AMIC]                   = "laptop-amic",
-       [ALC269_DMIC]                   = "laptop-dmic",
-       [ALC269_FUJITSU]                = "fujitsu",
-       [ALC269_LIFEBOOK]               = "lifebook",
-       [ALC269_AUTO]                   = "auto",
-};
-
-static const struct snd_pci_quirk alc269_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
-       SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
-       SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
-                     ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
-       SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
-       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
-       SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
-       SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
-       SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
-       SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
-       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
-       SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
-       SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
-       {}
-};
-
-static const struct alc_config_preset alc269_presets[] = {
-       [ALC269_BASIC] = {
-               .mixers = { alc269_base_mixer },
-               .init_verbs = { alc269_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .input_mux = &alc269_capture_source,
-       },
-       [ALC269_QUANTA_FL1] = {
-               .mixers = { alc269_quanta_fl1_mixer },
-               .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .input_mux = &alc269_capture_source,
-               .unsol_event = alc269_quanta_fl1_unsol_event,
-               .setup = alc269_quanta_fl1_setup,
-               .init_hook = alc269_quanta_fl1_init_hook,
-       },
-       [ALC269_AMIC] = {
-               .mixers = { alc269_laptop_mixer },
-               .cap_mixer = alc269_laptop_analog_capture_mixer,
-               .init_verbs = { alc269_init_verbs,
-                               alc269_laptop_amic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc269_laptop_amic_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC269_DMIC] = {
-               .mixers = { alc269_laptop_mixer },
-               .cap_mixer = alc269_laptop_digital_capture_mixer,
-               .init_verbs = { alc269_init_verbs,
-                               alc269_laptop_dmic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc269_laptop_dmic_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC269VB_AMIC] = {
-               .mixers = { alc269vb_laptop_mixer },
-               .cap_mixer = alc269vb_laptop_analog_capture_mixer,
-               .init_verbs = { alc269vb_init_verbs,
-                               alc269vb_laptop_amic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc269vb_laptop_amic_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC269VB_DMIC] = {
-               .mixers = { alc269vb_laptop_mixer },
-               .cap_mixer = alc269vb_laptop_digital_capture_mixer,
-               .init_verbs = { alc269vb_init_verbs,
-                               alc269vb_laptop_dmic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc269vb_laptop_dmic_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC269_FUJITSU] = {
-               .mixers = { alc269_fujitsu_mixer },
-               .cap_mixer = alc269_laptop_digital_capture_mixer,
-               .init_verbs = { alc269_init_verbs,
-                               alc269_laptop_dmic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc269_laptop_dmic_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC269_LIFEBOOK] = {
-               .mixers = { alc269_lifebook_mixer },
-               .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .hp_nid = 0x03,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .input_mux = &alc269_capture_source,
-               .unsol_event = alc269_lifebook_unsol_event,
-               .setup = alc269_lifebook_setup,
-               .init_hook = alc269_lifebook_init_hook,
-       },
-       [ALC271_ACER] = {
-               .mixers = { alc269_asus_mixer },
-               .cap_mixer = alc269vb_laptop_digital_capture_mixer,
-               .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
-               .num_dacs = ARRAY_SIZE(alc269_dac_nids),
-               .dac_nids = alc269_dac_nids,
-               .adc_nids = alc262_dmic_adc_nids,
-               .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
-               .capsrc_nids = alc262_dmic_capsrc_nids,
-               .num_channel_mode = ARRAY_SIZE(alc269_modes),
-               .channel_mode = alc269_modes,
-               .input_mux = &alc269_capture_source,
-               .dig_out_nid = ALC880_DIGOUT_NID,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc269vb_laptop_dmic_setup,
-               .init_hook = alc_inithook,
-       },
-};
-
index e69a6ea3083a28de5ae7d7f8b21c259b9dbf38c2..f5b4c9d883e8d2dfef7f034b2288c67ba5efb054 100644 (file)
@@ -10,25 +10,11 @@ enum {
        ALC662_3ST_6ch_DIG,
        ALC662_3ST_6ch,
        ALC662_5ST_DIG,
-       ALC662_LENOVO_101E,
-       ALC662_ASUS_EEEPC_P701,
        ALC662_ASUS_EEEPC_EP20,
        ALC663_ASUS_M51VA,
        ALC663_ASUS_G71V,
        ALC663_ASUS_H13,
        ALC663_ASUS_G50V,
-       ALC662_ECS,
-       ALC663_ASUS_MODE1,
-       ALC662_ASUS_MODE2,
-       ALC663_ASUS_MODE3,
-       ALC663_ASUS_MODE4,
-       ALC663_ASUS_MODE5,
-       ALC663_ASUS_MODE6,
-       ALC663_ASUS_MODE7,
-       ALC663_ASUS_MODE8,
-       ALC272_DELL,
-       ALC272_DELL_ZM1,
-       ALC272_SAMSUNG_NC10,
        ALC662_MODEL_LAST,
 };
 
@@ -87,30 +73,6 @@ static const struct hda_input_mux alc663_capture_source = {
        },
 };
 
-#if 0 /* set to 1 for testing other input sources below */
-static const struct hda_input_mux alc272_nc10_capture_source = {
-       .num_items = 16,
-       .items = {
-               { "Autoselect Mic", 0x0 },
-               { "Internal Mic", 0x1 },
-               { "In-0x02", 0x2 },
-               { "In-0x03", 0x3 },
-               { "In-0x04", 0x4 },
-               { "In-0x05", 0x5 },
-               { "In-0x06", 0x6 },
-               { "In-0x07", 0x7 },
-               { "In-0x08", 0x8 },
-               { "In-0x09", 0x9 },
-               { "In-0x0a", 0x0a },
-               { "In-0x0b", 0x0b },
-               { "In-0x0c", 0x0c },
-               { "In-0x0d", 0x0d },
-               { "In-0x0e", 0x0e },
-               { "In-0x0f", 0x0f },
-       },
-};
-#endif
-
 /*
  * 2ch mode
  */
@@ -236,33 +198,6 @@ static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
        { } /* end */
 };
 
-static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       ALC262_HIPPO_MASTER_SWITCH,
-
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
 static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
        ALC262_HIPPO_MASTER_SWITCH,
        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
@@ -303,97 +238,6 @@ static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
        { } /* end */
 };
 
-static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
-       HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
-       HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-
-       { } /* end */
-};
-
-static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
-       HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
-       HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
-       .ops = &snd_hda_bind_vol,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
-       HDA_BIND_VOL("Master Playback Volume",
-                               &alc663_asus_two_bind_master_vol),
-       HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
-       HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
-       HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
 static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -422,52 +266,6 @@ static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
        { } /* end */
 };
 
-static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
-               HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
-               0
-       },
-};
-
-static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
-       HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
-       HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
-       HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
-       HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
-       HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
-       HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
-       HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
-       HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-
 static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -535,18 +333,6 @@ static const struct hda_verb alc662_eapd_init_verbs[] = {
        { }
 };
 
-static const struct hda_verb alc662_sue_init_verbs[] = {
-       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
 /* Set Unsolicited Event*/
 static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -567,72 +353,6 @@ static const struct hda_verb alc663_m51va_init_verbs[] = {
        {}
 };
 
-static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x0},   /* Headphone */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},   /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
 static const struct hda_verb alc663_g71v_init_verbs[] = {
        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
        /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
@@ -658,118 +378,6 @@ static const struct hda_verb alc663_g50v_init_verbs[] = {
        {}
 };
 
-static const struct hda_verb alc662_ecs_init_verbs[] = {
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc272_dell_init_verbs[] = {
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc663_mode7_init_verbs[] = {
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
-       {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct hda_verb alc663_mode8_init_verbs[] = {
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {}
-};
-
-static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
-       HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
-       { } /* end */
-};
-
-static void alc662_lenovo_101e_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.line_out_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x15;
-       spec->automute = 1;
-       spec->detect_line = 1;
-       spec->automute_lines = 1;
-       spec->automute_mode = ALC_AUTOMUTE_AMP;
-}
-
-static void alc662_eeepc_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       alc262_hippo1_setup(codec);
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -793,124 +401,6 @@ static void alc663_m51va_setup(struct hda_codec *codec)
        spec->auto_mic = 1;
 }
 
-/* ***************** Mode1 ******************************/
-static void alc663_mode1_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode2 ******************************/
-static void alc662_mode2_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode3 ******************************/
-static void alc663_mode3_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode4 ******************************/
-static void alc663_mode4_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[1] = 0x16;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute_mixer_nid[1] = 0x0e;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode5 ******************************/
-static void alc663_mode5_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[1] = 0x16;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute_mixer_nid[1] = 0x0e;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode6 ******************************/
-static void alc663_mode6_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute_mixer_nid[0] = 0x0c;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_MIXER;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode7 ******************************/
-static void alc663_mode7_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x17;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x19;
-       spec->auto_mic = 1;
-}
-
-/* ***************** Mode8 ******************************/
-static void alc663_mode8_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x21;
-       spec->autocfg.hp_pins[1] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[0] = 0x17;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_PIN;
-       spec->ext_mic_pin = 0x18;
-       spec->int_mic_pin = 0x12;
-       spec->auto_mic = 1;
-}
-
 static void alc663_g71v_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -928,38 +418,6 @@ static void alc663_g71v_setup(struct hda_codec *codec)
 
 #define alc663_g50v_setup      alc663_m51va_setup
 
-static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
-       HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       ALC262_HIPPO_MASTER_SWITCH,
-
-       HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
-       /* Master Playback automatically created from Speaker and Headphone */
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
-
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       { } /* end */
-};
-
-
 /*
  * configuration and preset
  */
@@ -968,107 +426,33 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = {
        [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
        [ALC662_3ST_6ch]        = "3stack-6ch",
        [ALC662_5ST_DIG]        = "5stack-dig",
-       [ALC662_LENOVO_101E]    = "lenovo-101e",
-       [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
        [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
-       [ALC662_ECS] = "ecs",
        [ALC663_ASUS_M51VA] = "m51va",
        [ALC663_ASUS_G71V] = "g71v",
        [ALC663_ASUS_H13] = "h13",
        [ALC663_ASUS_G50V] = "g50v",
-       [ALC663_ASUS_MODE1] = "asus-mode1",
-       [ALC662_ASUS_MODE2] = "asus-mode2",
-       [ALC663_ASUS_MODE3] = "asus-mode3",
-       [ALC663_ASUS_MODE4] = "asus-mode4",
-       [ALC663_ASUS_MODE5] = "asus-mode5",
-       [ALC663_ASUS_MODE6] = "asus-mode6",
-       [ALC663_ASUS_MODE7] = "asus-mode7",
-       [ALC663_ASUS_MODE8] = "asus-mode8",
-       [ALC272_DELL]           = "dell",
-       [ALC272_DELL_ZM1]       = "dell-zm1",
-       [ALC272_SAMSUNG_NC10]   = "samsung-nc10",
        [ALC662_AUTO]           = "auto",
 };
 
 static const struct snd_pci_quirk alc662_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
-       SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
-       SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
-       SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
-       SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
-       SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
-       SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
-       SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
-       SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
-       SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
-       SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
-       SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
        SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
-       SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
-       SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
-       SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
        SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
-       /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
-       SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
-       SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
-       SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
-       SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
-       SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
-       /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
-       SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
        SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
-       SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
-       SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
        SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
-       SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
        SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
-       SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
        SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
                      ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
-       SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
                      ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
-       SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
        SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
                                        ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
                           ALC663_ASUS_H13),
-       SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
        {}
 };
 
@@ -1117,33 +501,6 @@ static const struct alc_config_preset alc662_presets[] = {
                .channel_mode = alc662_5stack_modes,
                .input_mux = &alc662_capture_source,
        },
-       [ALC662_LENOVO_101E] = {
-               .mixers = { alc662_lenovo_101e_mixer },
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc662_sue_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .dac_nids = alc662_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .input_mux = &alc662_lenovo_101e_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc662_lenovo_101e_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC662_ASUS_EEEPC_P701] = {
-               .mixers = { alc662_eeepc_p701_mixer },
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc662_eeepc_sue_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .dac_nids = alc662_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc662_eeepc_setup,
-               .init_hook = alc_inithook,
-       },
        [ALC662_ASUS_EEEPC_EP20] = {
                .mixers = { alc662_eeepc_ep20_mixer,
                            alc662_chmode_mixer },
@@ -1159,19 +516,6 @@ static const struct alc_config_preset alc662_presets[] = {
                .setup = alc662_eeepc_ep20_setup,
                .init_hook = alc_inithook,
        },
-       [ALC662_ECS] = {
-               .mixers = { alc662_ecs_mixer },
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc662_ecs_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .dac_nids = alc662_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc662_eeepc_setup,
-               .init_hook = alc_inithook,
-       },
        [ALC663_ASUS_M51VA] = {
                .mixers = { alc663_m51va_mixer },
                .init_verbs = { alc662_init_verbs,
@@ -1228,181 +572,4 @@ static const struct alc_config_preset alc662_presets[] = {
                .setup = alc663_g50v_setup,
                .init_hook = alc_inithook,
        },
-       [ALC663_ASUS_MODE1] = {
-               .mixers = { alc663_m51va_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_21jd_amic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode1_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC662_ASUS_MODE2] = {
-               .mixers = { alc662_1bjd_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc662_1bjd_amic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc662_mode2_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC663_ASUS_MODE3] = {
-               .mixers = { alc663_two_hp_m1_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_two_hp_amic_m1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode3_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC663_ASUS_MODE4] = {
-               .mixers = { alc663_asus_21jd_clfe_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_21jd_amic_init_verbs},
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode4_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC663_ASUS_MODE5] = {
-               .mixers = { alc663_asus_15jd_clfe_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_15jd_amic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode5_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC663_ASUS_MODE6] = {
-               .mixers = { alc663_two_hp_m2_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_two_hp_amic_m2_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode6_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC663_ASUS_MODE7] = {
-               .mixers = { alc663_mode7_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_mode7_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode7_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC663_ASUS_MODE8] = {
-               .mixers = { alc663_mode8_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_mode8_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
-               .hp_nid = 0x03,
-               .dac_nids = alc662_dac_nids,
-               .dig_out_nid = ALC662_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode8_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC272_DELL] = {
-               .mixers = { alc663_m51va_mixer },
-               .cap_mixer = alc272_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc272_dell_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc272_dac_nids),
-               .dac_nids = alc272_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .adc_nids = alc272_adc_nids,
-               .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
-               .capsrc_nids = alc272_capsrc_nids,
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_m51va_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC272_DELL_ZM1] = {
-               .mixers = { alc663_m51va_mixer },
-               .cap_mixer = alc662_auto_capture_mixer,
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc272_dell_zm1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc272_dac_nids),
-               .dac_nids = alc272_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .adc_nids = alc662_adc_nids,
-               .num_adc_nids = 1,
-               .capsrc_nids = alc662_capsrc_nids,
-               .channel_mode = alc662_3ST_2ch_modes,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_m51va_setup,
-               .init_hook = alc_inithook,
-       },
-       [ALC272_SAMSUNG_NC10] = {
-               .mixers = { alc272_nc10_mixer },
-               .init_verbs = { alc662_init_verbs,
-                               alc662_eapd_init_verbs,
-                               alc663_21jd_amic_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc272_dac_nids),
-               .dac_nids = alc272_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
-               .channel_mode = alc662_3ST_2ch_modes,
-               /*.input_mux = &alc272_nc10_capture_source,*/
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc663_mode4_setup,
-               .init_hook = alc_inithook,
-       },
 };
-
-
diff --git a/sound/pci/hda/alc680_quirks.c b/sound/pci/hda/alc680_quirks.c
deleted file mode 100644 (file)
index 0eeb227..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * ALC680 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC680 models */
-enum {
-       ALC680_AUTO,
-       ALC680_BASE,
-       ALC680_MODEL_LAST,
-};
-
-#define ALC680_DIGIN_NID       ALC880_DIGIN_NID
-#define ALC680_DIGOUT_NID      ALC880_DIGOUT_NID
-#define alc680_modes           alc260_modes
-
-static const hda_nid_t alc680_dac_nids[3] = {
-       /* Lout1, Lout2, hp */
-       0x02, 0x03, 0x04
-};
-
-static const hda_nid_t alc680_adc_nids[3] = {
-       /* ADC0-2 */
-       /* DMIC, MIC, Line-in*/
-       0x07, 0x08, 0x09
-};
-
-/*
- * Analog capture ADC cgange
- */
-static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
-{
-       static hda_nid_t pins[] = {0x18, 0x19};
-       static hda_nid_t adcs[] = {0x08, 0x09};
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(pins); i++) {
-               if (!is_jack_detectable(codec, pins[i]))
-                       continue;
-               if (snd_hda_jack_detect(codec, pins[i]))
-                       return adcs[i];
-       }
-       return 0x07;
-}
-
-static void alc680_rec_autoswitch(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       hda_nid_t nid = alc680_get_cur_adc(codec);
-       if (spec->cur_adc && nid != spec->cur_adc) {
-               __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
-               spec->cur_adc = nid;
-               snd_hda_codec_setup_stream(codec, nid,
-                                          spec->cur_adc_stream_tag, 0,
-                                          spec->cur_adc_format);
-       }
-}
-
-static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
-                                     struct hda_codec *codec,
-                                     unsigned int stream_tag,
-                                     unsigned int format,
-                                     struct snd_pcm_substream *substream)
-{
-       struct alc_spec *spec = codec->spec;
-       hda_nid_t nid = alc680_get_cur_adc(codec);
-
-       spec->cur_adc = nid;
-       spec->cur_adc_stream_tag = stream_tag;
-       spec->cur_adc_format = format;
-       snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
-       return 0;
-}
-
-static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
-                                     struct hda_codec *codec,
-                                     struct snd_pcm_substream *substream)
-{
-       struct alc_spec *spec = codec->spec;
-       snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
-       spec->cur_adc = 0;
-       return 0;
-}
-
-static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
-       .substreams = 1, /* can be overridden */
-       .channels_min = 2,
-       .channels_max = 2,
-       /* NID is set in alc_build_pcms */
-       .ops = {
-               .prepare = alc680_capture_pcm_prepare,
-               .cleanup = alc680_capture_pcm_cleanup
-       },
-};
-
-static const struct snd_kcontrol_new alc680_base_mixer[] = {
-       /* output mixer control */
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
-       { }
-};
-
-static const struct hda_bind_ctls alc680_bind_cap_vol = {
-       .ops = &snd_hda_bind_vol,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
-               HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
-               HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
-               0
-       },
-};
-
-static const struct hda_bind_ctls alc680_bind_cap_switch = {
-       .ops = &snd_hda_bind_sw,
-       .values = {
-               HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
-               HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
-               HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
-               0
-       },
-};
-
-static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
-       HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
-       HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
-       { } /* end */
-};
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc680_init_verbs[] = {
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-       {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT   | AC_USRSP_EN},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT  | AC_USRSP_EN},
-       {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT  | AC_USRSP_EN},
-
-       { }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc680_base_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x16;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->autocfg.speaker_pins[1] = 0x15;
-       spec->autocfg.num_inputs = 2;
-       spec->autocfg.inputs[0].pin = 0x18;
-       spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
-       spec->autocfg.inputs[1].pin = 0x19;
-       spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_AMP;
-}
-
-static void alc680_unsol_event(struct hda_codec *codec,
-                                          unsigned int res)
-{
-       if ((res >> 26) == ALC_HP_EVENT)
-               alc_hp_automute(codec);
-       if ((res >> 26) == ALC_MIC_EVENT)
-               alc680_rec_autoswitch(codec);
-}
-
-static void alc680_inithook(struct hda_codec *codec)
-{
-       alc_hp_automute(codec);
-       alc680_rec_autoswitch(codec);
-}
-
-/*
- * configuration and preset
- */
-static const char * const alc680_models[ALC680_MODEL_LAST] = {
-       [ALC680_BASE]           = "base",
-       [ALC680_AUTO]           = "auto",
-};
-
-static const struct snd_pci_quirk alc680_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
-       {}
-};
-
-static const struct alc_config_preset alc680_presets[] = {
-       [ALC680_BASE] = {
-               .mixers = { alc680_base_mixer },
-               .cap_mixer =  alc680_master_capture_mixer,
-               .init_verbs = { alc680_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc680_dac_nids),
-               .dac_nids = alc680_dac_nids,
-               .dig_out_nid = ALC680_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc680_modes),
-               .channel_mode = alc680_modes,
-               .unsol_event = alc680_unsol_event,
-               .setup = alc680_base_setup,
-               .init_hook = alc680_inithook,
-
-       },
-};
diff --git a/sound/pci/hda/alc861_quirks.c b/sound/pci/hda/alc861_quirks.c
deleted file mode 100644 (file)
index d719ec6..0000000
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * ALC660/ALC861 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC861 models */
-enum {
-       ALC861_AUTO,
-       ALC861_3ST,
-       ALC660_3ST,
-       ALC861_3ST_DIG,
-       ALC861_6ST_DIG,
-       ALC861_UNIWILL_M31,
-       ALC861_TOSHIBA,
-       ALC861_ASUS,
-       ALC861_ASUS_LAPTOP,
-       ALC861_MODEL_LAST,
-};
-
-/*
- *  ALC861 channel source setting (2/6 channel selection for 3-stack)
- */
-
-/*
- * set the path ways for 2 channel output
- * need to set the codec line out and mic 1 pin widgets to inputs
- */
-static const struct hda_verb alc861_threestack_ch2_init[] = {
-       /* set pin widget 1Ah (line in) for input */
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* set pin widget 18h (mic1/2) for input, for mic also enable
-        * the vref
-        */
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
-#if 0
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
-#endif
-       { } /* end */
-};
-/*
- * 6ch mode
- * need to set the codec line out and mic 1 pin widgets to outputs
- */
-static const struct hda_verb alc861_threestack_ch6_init[] = {
-       /* set pin widget 1Ah (line in) for output (Back Surround)*/
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       /* set pin widget 18h (mic1) for output (CLFE)*/
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-
-       { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
-
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
-#if 0
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
-#endif
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc861_threestack_modes[2] = {
-       { 2, alc861_threestack_ch2_init },
-       { 6, alc861_threestack_ch6_init },
-};
-/* Set mic1 as input and unmute the mixer */
-static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
-       { } /* end */
-};
-/* Set mic1 as output and mute mixer */
-static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
-       { 2, alc861_uniwill_m31_ch2_init },
-       { 4, alc861_uniwill_m31_ch4_init },
-};
-
-/* Set mic1 and line-in as input and unmute the mixer */
-static const struct hda_verb alc861_asus_ch2_init[] = {
-       /* set pin widget 1Ah (line in) for input */
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* set pin widget 18h (mic1/2) for input, for mic also enable
-        * the vref
-        */
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
-#if 0
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
-#endif
-       { } /* end */
-};
-/* Set mic1 nad line-in as output and mute mixer */
-static const struct hda_verb alc861_asus_ch6_init[] = {
-       /* set pin widget 1Ah (line in) for output (Back Surround)*/
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
-       /* set pin widget 18h (mic1) for output (CLFE)*/
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
-       { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
-
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
-#if 0
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
-#endif
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc861_asus_modes[2] = {
-       { 2, alc861_asus_ch2_init },
-       { 6, alc861_asus_ch6_init },
-};
-
-/* patch-ALC861 */
-
-static const struct snd_kcontrol_new alc861_base_mixer[] = {
-        /* output mixer control */
-       HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
-
-        /*Input mixer control */
-       /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
-          HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
-
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
-        /* output mixer control */
-       HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
-       /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
-
-       /* Input mixer control */
-       /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
-          HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
-
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-                .private_value = ARRAY_SIZE(alc861_threestack_modes),
-       },
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
-        /* output mixer control */
-       HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
-
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
-        /* output mixer control */
-       HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
-       /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
-
-       /* Input mixer control */
-       /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
-          HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
-
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
-       },
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc861_asus_mixer[] = {
-        /* output mixer control */
-       HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
-
-       /* Input mixer control */
-       HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
-
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-                .private_value = ARRAY_SIZE(alc861_asus_modes),
-       },
-       { }
-};
-
-/* additional mixer */
-static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
-       { }
-};
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc861_base_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       /* port-A for surround (rear panel) */
-       { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-B for mic-in (rear panel) with vref */
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-C for line-in (rear panel) */
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* port-D for Front */
-       { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-E for HP out (front panel) */
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
-       /* route front PCM to HP */
-       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-F for mic-in (front panel) with vref */
-       { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-G for CLFE (rear panel) */
-       { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-H for side (rear panel) */
-       { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* CD-in */
-       { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* route front mic to ADC1*/
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Unmute DAC0~3 & spdif out*/
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* Unmute Mixer 14 (mic) 1c (Line in)*/
-       {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       /* Unmute Stereo Mixer 15 */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
-
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /* hp used DAC 3 (Front) */
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
-        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-
-       { }
-};
-
-static const struct hda_verb alc861_threestack_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       /* port-A for surround (rear panel) */
-       { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       /* port-B for mic-in (rear panel) with vref */
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-C for line-in (rear panel) */
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* port-D for Front */
-       { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-E for HP out (front panel) */
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
-       /* route front PCM to HP */
-       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-F for mic-in (front panel) with vref */
-       { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-G for CLFE (rear panel) */
-       { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       /* port-H for side (rear panel) */
-       { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       /* CD-in */
-       { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* route front mic to ADC1*/
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       /* Unmute DAC0~3 & spdif out*/
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* Unmute Mixer 14 (mic) 1c (Line in)*/
-       {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       /* Unmute Stereo Mixer 15 */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
-
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /* hp used DAC 3 (Front) */
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
-        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       { }
-};
-
-static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       /* port-A for surround (rear panel) */
-       { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       /* port-B for mic-in (rear panel) with vref */
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-C for line-in (rear panel) */
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* port-D for Front */
-       { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-E for HP out (front panel) */
-       /* this has to be set to VREF80 */
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* route front PCM to HP */
-       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-F for mic-in (front panel) with vref */
-       { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-G for CLFE (rear panel) */
-       { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       /* port-H for side (rear panel) */
-       { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       /* CD-in */
-       { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* route front mic to ADC1*/
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       /* Unmute DAC0~3 & spdif out*/
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       /* Unmute Mixer 14 (mic) 1c (Line in)*/
-       {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       /* Unmute Stereo Mixer 15 */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
-
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /* hp used DAC 3 (Front) */
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
-        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       { }
-};
-
-static const struct hda_verb alc861_asus_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       /* port-A for surround (rear panel)
-        * according to codec#0 this is the HP jack
-        */
-       { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
-       /* route front PCM to HP */
-       { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
-       /* port-B for mic-in (rear panel) with vref */
-       { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-C for line-in (rear panel) */
-       { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* port-D for Front */
-       { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-E for HP out (front panel) */
-       /* this has to be set to VREF80 */
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* route front PCM to HP */
-       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
-       /* port-F for mic-in (front panel) with vref */
-       { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       /* port-G for CLFE (rear panel) */
-       { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       /* port-H for side (rear panel) */
-       { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       /* CD-in */
-       { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* route front mic to ADC1*/
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       /* Unmute DAC0~3 & spdif out*/
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Unmute Mixer 14 (mic) 1c (Line in)*/
-       {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-
-       /* Unmute Stereo Mixer 15 */
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
-
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /* hp used DAC 3 (Front) */
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       { }
-};
-
-/* additional init verbs for ASUS laptops */
-static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
-       { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
-       { }
-};
-
-static const struct hda_verb alc861_toshiba_init_verbs[] = {
-       {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-
-       { }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc861_toshiba_automute(struct hda_codec *codec)
-{
-       unsigned int present = snd_hda_jack_detect(codec, 0x0f);
-
-       snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
-                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-       snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
-                                HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
-}
-
-static void alc861_toshiba_unsol_event(struct hda_codec *codec,
-                                      unsigned int res)
-{
-       if ((res >> 26) == ALC_HP_EVENT)
-               alc861_toshiba_automute(codec);
-}
-
-#define ALC861_DIGOUT_NID      0x07
-
-static const struct hda_channel_mode alc861_8ch_modes[1] = {
-       { 8, NULL }
-};
-
-static const hda_nid_t alc861_dac_nids[4] = {
-       /* front, surround, clfe, side */
-       0x03, 0x06, 0x05, 0x04
-};
-
-static const hda_nid_t alc660_dac_nids[3] = {
-       /* front, clfe, surround */
-       0x03, 0x05, 0x06
-};
-
-static const hda_nid_t alc861_adc_nids[1] = {
-       /* ADC0-2 */
-       0x08,
-};
-
-static const struct hda_input_mux alc861_capture_source = {
-       .num_items = 5,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x3 },
-               { "Line", 0x1 },
-               { "CD", 0x4 },
-               { "Mixer", 0x5 },
-       },
-};
-
-/*
- * configuration and preset
- */
-static const char * const alc861_models[ALC861_MODEL_LAST] = {
-       [ALC861_3ST]            = "3stack",
-       [ALC660_3ST]            = "3stack-660",
-       [ALC861_3ST_DIG]        = "3stack-dig",
-       [ALC861_6ST_DIG]        = "6stack-dig",
-       [ALC861_UNIWILL_M31]    = "uniwill-m31",
-       [ALC861_TOSHIBA]        = "toshiba",
-       [ALC861_ASUS]           = "asus",
-       [ALC861_ASUS_LAPTOP]    = "asus-laptop",
-       [ALC861_AUTO]           = "auto",
-};
-
-static const struct snd_pci_quirk alc861_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
-       SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
-       SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
-       SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
-       SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
-       SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
-       SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
-       /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
-        *        Any other models that need this preset?
-        */
-       /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
-       SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
-       SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
-       SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
-       SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
-       SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
-       /* FIXME: the below seems conflict */
-       /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
-       SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
-       SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
-       {}
-};
-
-static const struct alc_config_preset alc861_presets[] = {
-       [ALC861_3ST] = {
-               .mixers = { alc861_3ST_mixer },
-               .init_verbs = { alc861_threestack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
-               .channel_mode = alc861_threestack_modes,
-               .need_dac_fix = 1,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-       [ALC861_3ST_DIG] = {
-               .mixers = { alc861_base_mixer },
-               .init_verbs = { alc861_threestack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .dig_out_nid = ALC861_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
-               .channel_mode = alc861_threestack_modes,
-               .need_dac_fix = 1,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-       [ALC861_6ST_DIG] = {
-               .mixers = { alc861_base_mixer },
-               .init_verbs = { alc861_base_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .dig_out_nid = ALC861_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
-               .channel_mode = alc861_8ch_modes,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-       [ALC660_3ST] = {
-               .mixers = { alc861_3ST_mixer },
-               .init_verbs = { alc861_threestack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc660_dac_nids),
-               .dac_nids = alc660_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
-               .channel_mode = alc861_threestack_modes,
-               .need_dac_fix = 1,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-       [ALC861_UNIWILL_M31] = {
-               .mixers = { alc861_uniwill_m31_mixer },
-               .init_verbs = { alc861_uniwill_m31_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .dig_out_nid = ALC861_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
-               .channel_mode = alc861_uniwill_m31_modes,
-               .need_dac_fix = 1,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-       [ALC861_TOSHIBA] = {
-               .mixers = { alc861_toshiba_mixer },
-               .init_verbs = { alc861_base_init_verbs,
-                               alc861_toshiba_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
-               .channel_mode = alc883_3ST_2ch_modes,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-               .unsol_event = alc861_toshiba_unsol_event,
-               .init_hook = alc861_toshiba_automute,
-       },
-       [ALC861_ASUS] = {
-               .mixers = { alc861_asus_mixer },
-               .init_verbs = { alc861_asus_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .dig_out_nid = ALC861_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
-               .channel_mode = alc861_asus_modes,
-               .need_dac_fix = 1,
-               .hp_nid = 0x06,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-       [ALC861_ASUS_LAPTOP] = {
-               .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
-               .init_verbs = { alc861_asus_init_verbs,
-                               alc861_asus_laptop_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861_dac_nids),
-               .dac_nids = alc861_dac_nids,
-               .dig_out_nid = ALC861_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
-               .channel_mode = alc883_3ST_2ch_modes,
-               .need_dac_fix = 1,
-               .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
-               .adc_nids = alc861_adc_nids,
-               .input_mux = &alc861_capture_source,
-       },
-};
-
diff --git a/sound/pci/hda/alc861vd_quirks.c b/sound/pci/hda/alc861vd_quirks.c
deleted file mode 100644 (file)
index 8f28450..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * ALC660-VD/ALC861-VD quirk models
- * included by patch_realtek.c
- */
-
-/* ALC861-VD models */
-enum {
-       ALC861VD_AUTO,
-       ALC660VD_3ST,
-       ALC660VD_3ST_DIG,
-       ALC660VD_ASUS_V1S,
-       ALC861VD_3ST,
-       ALC861VD_3ST_DIG,
-       ALC861VD_6ST_DIG,
-       ALC861VD_LENOVO,
-       ALC861VD_DALLAS,
-       ALC861VD_HP,
-       ALC861VD_MODEL_LAST,
-};
-
-#define ALC861VD_DIGOUT_NID    0x06
-
-static const hda_nid_t alc861vd_dac_nids[4] = {
-       /* front, surr, clfe, side surr */
-       0x02, 0x03, 0x04, 0x05
-};
-
-/* dac_nids for ALC660vd are in a different order - according to
- * Realtek's driver.
- * This should probably result in a different mixer for 6stack models
- * of ALC660vd codecs, but for now there is only 3stack mixer
- * - and it is the same as in 861vd.
- * adc_nids in ALC660vd are (is) the same as in 861vd
- */
-static const hda_nid_t alc660vd_dac_nids[3] = {
-       /* front, rear, clfe, rear_surr */
-       0x02, 0x04, 0x03
-};
-
-static const hda_nid_t alc861vd_adc_nids[1] = {
-       /* ADC0 */
-       0x09,
-};
-
-static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
-
-/* input MUX */
-/* FIXME: should be a matrix-type input source selection */
-static const struct hda_input_mux alc861vd_capture_source = {
-       .num_items = 4,
-       .items = {
-               { "Mic", 0x0 },
-               { "Front Mic", 0x1 },
-               { "Line", 0x2 },
-               { "CD", 0x4 },
-       },
-};
-
-static const struct hda_input_mux alc861vd_dallas_capture_source = {
-       .num_items = 2,
-       .items = {
-               { "Mic", 0x0 },
-               { "Internal Mic", 0x1 },
-       },
-};
-
-static const struct hda_input_mux alc861vd_hp_capture_source = {
-       .num_items = 2,
-       .items = {
-               { "Front Mic", 0x0 },
-               { "ATAPI Mic", 0x1 },
-       },
-};
-
-/*
- * 2ch mode
- */
-static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
-       { 2, NULL }
-};
-
-/*
- * 6ch mode
- */
-static const struct hda_verb alc861vd_6stack_ch6_init[] = {
-       { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
-       { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { } /* end */
-};
-
-/*
- * 8ch mode
- */
-static const struct hda_verb alc861vd_6stack_ch8_init[] = {
-       { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       { } /* end */
-};
-
-static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
-       { 6, alc861vd_6stack_ch6_init },
-       { 8, alc861vd_6stack_ch8_init },
-};
-
-static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Channel Mode",
-               .info = alc_ch_mode_info,
-               .get = alc_ch_mode_get,
-               .put = alc_ch_mode_put,
-       },
-       { } /* end */
-};
-
-/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
- *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
- */
-static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-
-       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
-                               HDA_OUTPUT),
-       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
-                               HDA_OUTPUT),
-       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
-
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-
-       { } /* end */
-};
-
-static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
-       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-
-       { } /* end */
-};
-
-/* Pin assignment: Speaker=0x14, HP = 0x15,
- *                 Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
- */
-static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
-       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-       { } /* end */
-};
-
-/* Pin assignment: Speaker=0x14, Line-out = 0x15,
- *                 Front Mic=0x18, ATAPI Mic = 0x19,
- */
-static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-
-       { } /* end */
-};
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc861vd_volume_init_verbs[] = {
-       /*
-        * Unmute ADC0 and set the default input to mic-in
-        */
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-       /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
-        * the analog-loopback mixer widget
-        */
-       /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-
-       /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
-
-       /*
-        * Set up output mixers (0x02 - 0x05)
-        */
-       /* set vol=0 to output mixers */
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       /* set up input amps for analog loopback */
-       /* Amp Indices: DAC = 0, mixer = 1 */
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-       { }
-};
-
-/*
- * 3-stack pin configuration:
- * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
- */
-static const struct hda_verb alc861vd_3stack_init_verbs[] = {
-       /*
-        * Set pin mode and muting
-        */
-       /* set front pin widgets 0x14 for output */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Mic (rear) pin: input vref at 80% */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Front Mic pin: input vref at 80% */
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Line In pin: input */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Line-2 In: Headphone output (output 0 - 0x0c) */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* CD pin widget for input */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-/*
- * 6-stack pin configuration:
- */
-static const struct hda_verb alc861vd_6stack_init_verbs[] = {
-       /*
-        * Set pin mode and muting
-        */
-       /* set front pin widgets 0x14 for output */
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-       /* Rear Pin: output 1 (0x0d) */
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-       /* CLFE Pin: output 2 (0x0e) */
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
-       /* Side Pin: output 3 (0x0f) */
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
-
-       /* Mic (rear) pin: input vref at 80% */
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Front Mic pin: input vref at 80% */
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Line In pin: input */
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       /* Line-2 In: Headphone output (output 0 - 0x0c) */
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* CD pin widget for input */
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       { }
-};
-
-static const struct hda_verb alc861vd_eapd_verbs[] = {
-       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
-       { }
-};
-
-static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
-       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-       {}
-};
-
-static void alc861vd_lenovo_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x1b;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_AMP;
-}
-
-static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
-{
-       alc_hp_automute(codec);
-       alc88x_simple_mic_automute(codec);
-}
-
-static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
-                                       unsigned int res)
-{
-       switch (res >> 26) {
-       case ALC_MIC_EVENT:
-               alc88x_simple_mic_automute(codec);
-               break;
-       default:
-               alc_sku_unsol_event(codec, res);
-               break;
-       }
-}
-
-static const struct hda_verb alc861vd_dallas_verbs[] = {
-       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-       {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-       {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-
-       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-
-       { } /* end */
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc861vd_dallas_setup(struct hda_codec *codec)
-{
-       struct alc_spec *spec = codec->spec;
-
-       spec->autocfg.hp_pins[0] = 0x15;
-       spec->autocfg.speaker_pins[0] = 0x14;
-       spec->automute = 1;
-       spec->automute_mode = ALC_AUTOMUTE_AMP;
-}
-
-/*
- * configuration and preset
- */
-static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
-       [ALC660VD_3ST]          = "3stack-660",
-       [ALC660VD_3ST_DIG]      = "3stack-660-digout",
-       [ALC660VD_ASUS_V1S]     = "asus-v1s",
-       [ALC861VD_3ST]          = "3stack",
-       [ALC861VD_3ST_DIG]      = "3stack-digout",
-       [ALC861VD_6ST_DIG]      = "6stack-digout",
-       [ALC861VD_LENOVO]       = "lenovo",
-       [ALC861VD_DALLAS]       = "dallas",
-       [ALC861VD_HP]           = "hp",
-       [ALC861VD_AUTO]         = "auto",
-};
-
-static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
-       SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
-       SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
-       SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
-       /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
-       SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
-       SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
-       SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
-       SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
-       /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
-       SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
-       SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
-       SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
-       SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
-       SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
-       SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
-       {}
-};
-
-static const struct alc_config_preset alc861vd_presets[] = {
-       [ALC660VD_3ST] = {
-               .mixers = { alc861vd_3st_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                                alc861vd_3stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
-               .dac_nids = alc660vd_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_capture_source,
-       },
-       [ALC660VD_3ST_DIG] = {
-               .mixers = { alc861vd_3st_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                                alc861vd_3stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
-               .dac_nids = alc660vd_dac_nids,
-               .dig_out_nid = ALC861VD_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_capture_source,
-       },
-       [ALC861VD_3ST] = {
-               .mixers = { alc861vd_3st_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                                alc861vd_3stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
-               .dac_nids = alc861vd_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_capture_source,
-       },
-       [ALC861VD_3ST_DIG] = {
-               .mixers = { alc861vd_3st_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                                alc861vd_3stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
-               .dac_nids = alc861vd_dac_nids,
-               .dig_out_nid = ALC861VD_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_capture_source,
-       },
-       [ALC861VD_6ST_DIG] = {
-               .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                               alc861vd_6stack_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
-               .dac_nids = alc861vd_dac_nids,
-               .dig_out_nid = ALC861VD_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
-               .channel_mode = alc861vd_6stack_modes,
-               .input_mux = &alc861vd_capture_source,
-       },
-       [ALC861VD_LENOVO] = {
-               .mixers = { alc861vd_lenovo_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                               alc861vd_3stack_init_verbs,
-                               alc861vd_eapd_verbs,
-                               alc861vd_lenovo_unsol_verbs },
-               .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
-               .dac_nids = alc660vd_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_capture_source,
-               .unsol_event = alc861vd_lenovo_unsol_event,
-               .setup = alc861vd_lenovo_setup,
-               .init_hook = alc861vd_lenovo_init_hook,
-       },
-       [ALC861VD_DALLAS] = {
-               .mixers = { alc861vd_dallas_mixer },
-               .init_verbs = { alc861vd_dallas_verbs },
-               .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
-               .dac_nids = alc861vd_dac_nids,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_dallas_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc861vd_dallas_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC861VD_HP] = {
-               .mixers = { alc861vd_hp_mixer },
-               .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
-               .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
-               .dac_nids = alc861vd_dac_nids,
-               .dig_out_nid = ALC861VD_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_hp_capture_source,
-               .unsol_event = alc_sku_unsol_event,
-               .setup = alc861vd_dallas_setup,
-               .init_hook = alc_hp_automute,
-       },
-       [ALC660VD_ASUS_V1S] = {
-               .mixers = { alc861vd_lenovo_mixer },
-               .init_verbs = { alc861vd_volume_init_verbs,
-                               alc861vd_3stack_init_verbs,
-                               alc861vd_eapd_verbs,
-                               alc861vd_lenovo_unsol_verbs },
-               .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
-               .dac_nids = alc660vd_dac_nids,
-               .dig_out_nid = ALC861VD_DIGOUT_NID,
-               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
-               .channel_mode = alc861vd_3stack_2ch_modes,
-               .input_mux = &alc861vd_capture_source,
-               .unsol_event = alc861vd_lenovo_unsol_event,
-               .setup = alc861vd_lenovo_setup,
-               .init_hook = alc861vd_lenovo_init_hook,
-       },
-};
-
index 3e7850c238c314113d47330ecb2aa2d3d59982f3..5a8ecdebf37d54d4045e126d999c2382eb0a6641 100644 (file)
@@ -34,6 +34,9 @@
 #include "hda_beep.h"
 #include <sound/hda_hwdep.h>
 
+#define CREATE_TRACE_POINTS
+#include "hda_trace.h"
+
 /*
  * vendor / preset table
  */
@@ -208,15 +211,19 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
  again:
        snd_hda_power_up(codec);
        mutex_lock(&bus->cmd_mutex);
+       trace_hda_send_cmd(codec, cmd);
        err = bus->ops.command(bus, cmd);
-       if (!err && res)
+       if (!err && res) {
                *res = bus->ops.get_response(bus, codec->addr);
+               trace_hda_get_response(codec, *res);
+       }
        mutex_unlock(&bus->cmd_mutex);
        snd_hda_power_down(codec);
        if (res && *res == -1 && bus->rirb_error) {
                if (bus->response_reset) {
                        snd_printd("hda_codec: resetting BUS due to "
                                   "fatal communication error\n");
+                       trace_hda_bus_reset(bus);
                        bus->ops.bus_reset(bus);
                }
                goto again;
@@ -603,6 +610,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
        struct hda_bus_unsolicited *unsol;
        unsigned int wp;
 
+       trace_hda_unsol_event(bus, res, res_ex);
        unsol = bus->unsol;
        if (!unsol)
                return 0;
@@ -1684,6 +1692,29 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
 }
 EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
 
+/**
+ * snd_hda_override_pin_caps - Override the pin capabilities
+ * @codec: the CODEC
+ * @nid: the NID to override
+ * @caps: the capability bits to set
+ *
+ * Override the cached PIN capabilitiy bits value by the given one.
+ *
+ * Returns zero if successful or a negative error code.
+ */
+int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
+                             unsigned int caps)
+{
+       struct hda_amp_info *info;
+       info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid));
+       if (!info)
+               return -ENOMEM;
+       info->amp_caps = caps;
+       info->head.val |= INFO_AMP_CAPS;
+       return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps);
+
 /**
  * snd_hda_pin_sense - execute pin sense measurement
  * @codec: the CODEC to sense
@@ -4083,6 +4114,7 @@ static void hda_power_work(struct work_struct *work)
                return;
        }
 
+       trace_hda_power_down(codec);
        hda_call_codec_suspend(codec);
        if (bus->ops.pm_notify)
                bus->ops.pm_notify(bus);
@@ -4121,6 +4153,7 @@ void snd_hda_power_up(struct hda_codec *codec)
        if (codec->power_on || codec->power_transition)
                return;
 
+       trace_hda_power_up(codec);
        snd_hda_update_power_acct(codec);
        codec->power_on = 1;
        codec->power_jiffies = jiffies;
@@ -4533,6 +4566,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
                snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
                                           0, format);
        /* extra outputs copied from front */
+       for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
+               if (!mout->no_share_stream && mout->hp_out_nid[i])
+                       snd_hda_codec_setup_stream(codec,
+                                                  mout->hp_out_nid[i],
+                                                  stream_tag, 0, format);
        for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
                if (!mout->no_share_stream && mout->extra_out_nid[i])
                        snd_hda_codec_setup_stream(codec,
@@ -4565,6 +4603,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
                snd_hda_codec_cleanup_stream(codec, nids[i]);
        if (mout->hp_nid)
                snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
+       for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
+               if (mout->hp_out_nid[i])
+                       snd_hda_codec_cleanup_stream(codec,
+                                                    mout->hp_out_nid[i]);
        for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
                if (mout->extra_out_nid[i])
                        snd_hda_codec_cleanup_stream(codec,
@@ -4662,12 +4704,13 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
  * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
  * respectively.
  */
-int snd_hda_parse_pin_def_config(struct hda_codec *codec,
-                                struct auto_pin_cfg *cfg,
-                                const hda_nid_t *ignore_nids)
+int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
+                            struct auto_pin_cfg *cfg,
+                            const hda_nid_t *ignore_nids,
+                            unsigned int cond_flags)
 {
        hda_nid_t nid, end_nid;
-       short seq, assoc_line_out, assoc_speaker;
+       short seq, assoc_line_out;
        short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
        short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
        short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
@@ -4678,7 +4721,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
        memset(sequences_line_out, 0, sizeof(sequences_line_out));
        memset(sequences_speaker, 0, sizeof(sequences_speaker));
        memset(sequences_hp, 0, sizeof(sequences_hp));
-       assoc_line_out = assoc_speaker = 0;
+       assoc_line_out = 0;
 
        end_nid = codec->start_nid + codec->num_nodes;
        for (nid = codec->start_nid; nid < end_nid; nid++) {
@@ -4730,16 +4773,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
                case AC_JACK_SPEAKER:
                        seq = get_defcfg_sequence(def_conf);
                        assoc = get_defcfg_association(def_conf);
-                       if (!assoc)
-                               continue;
-                       if (!assoc_speaker)
-                               assoc_speaker = assoc;
-                       else if (assoc_speaker != assoc)
-                               continue;
                        if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
                                continue;
                        cfg->speaker_pins[cfg->speaker_outs] = nid;
-                       sequences_speaker[cfg->speaker_outs] = seq;
+                       sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq;
                        cfg->speaker_outs++;
                        break;
                case AC_JACK_HP_OUT:
@@ -4788,7 +4825,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
         * If no line-out is defined but multiple HPs are found,
         * some of them might be the real line-outs.
         */
-       if (!cfg->line_outs && cfg->hp_outs > 1) {
+       if (!cfg->line_outs && cfg->hp_outs > 1 &&
+           !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) {
                int i = 0;
                while (i < cfg->hp_outs) {
                        /* The real HPs should have the sequence 0x0f */
@@ -4825,7 +4863,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
         * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
         * as a primary output
         */
-       if (!cfg->line_outs) {
+       if (!cfg->line_outs &&
+           !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) {
                if (cfg->speaker_outs) {
                        cfg->line_outs = cfg->speaker_outs;
                        memcpy(cfg->line_out_pins, cfg->speaker_pins,
@@ -4895,7 +4934,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
 
        return 0;
 }
-EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
+EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg);
 
 int snd_hda_get_input_pin_attr(unsigned int def_conf)
 {
index be6982289c0d17cc06d19be8335fdb3a7b284d56..2a8bed94d4fa934bbee04465e2f4524d446865b0 100644 (file)
@@ -116,6 +116,11 @@ module_param(power_save_controller, bool, 0644);
 MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
 #endif
 
+static int align_buffer_size = 1;
+module_param(align_buffer_size, bool, 0644);
+MODULE_PARM_DESC(align_buffer_size,
+               "Force buffer and period sizes to be multiple of 128 bytes.");
+
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{Intel, ICH6M},"
@@ -481,6 +486,7 @@ enum {
 #define AZX_DCAPS_NO_64BIT     (1 << 18)       /* No 64bit address */
 #define AZX_DCAPS_SYNC_WRITE   (1 << 19)       /* sync each cmd write */
 #define AZX_DCAPS_OLD_SSYNC    (1 << 20)       /* Old SSYNC reg for ICH */
+#define AZX_DCAPS_BUFSIZE      (1 << 21)       /* no buffer size alignment */
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -1599,6 +1605,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        unsigned long flags;
        int err;
+       int buff_step;
 
        mutex_lock(&chip->open_mutex);
        azx_dev = azx_assign_device(chip, substream);
@@ -1613,10 +1620,25 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
        runtime->hw.rates = hinfo->rates;
        snd_pcm_limit_hw_rates(runtime);
        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+       if (align_buffer_size)
+               /* constrain buffer sizes to be multiple of 128
+                  bytes. This is more efficient in terms of memory
+                  access but isn't required by the HDA spec and
+                  prevents users from specifying exact period/buffer
+                  sizes. For example for 44.1kHz, a period size set
+                  to 20ms will be rounded to 19.59ms. */
+               buff_step = 128;
+       else
+               /* Don't enforce steps on buffer sizes, still need to
+                  be multiple of 4 bytes (HDA spec). Tested on Intel
+                  HDA controllers, may not work on all devices where
+                  option needs to be disabled */
+               buff_step = 4;
+
        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-                                  128);
+                                  buff_step);
        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
-                                  128);
+                                  buff_step);
        snd_hda_power_up(apcm->codec);
        err = hinfo->ops.open(hinfo, apcm->codec, substream);
        if (err < 0) {
@@ -2616,6 +2638,10 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
                gcap &= ~ICH6_GCAP_64OK;
        }
 
+       /* disable buffer size rounding to 128-byte multiples if supported */
+       if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
+               align_buffer_size = 0;
+
        /* allow 64bit DMA address if supported by H/W */
        if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
                pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
@@ -2817,37 +2843,49 @@ static void __devexit azx_remove(struct pci_dev *pci)
 static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        /* CPT */
        { PCI_DEVICE(0x8086, 0x1c20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE },
        /* PBG */
        { PCI_DEVICE(0x8086, 0x1d20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE},
        /* Panther Point */
        { PCI_DEVICE(0x8086, 0x1e20),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE},
        /* SCH */
        { PCI_DEVICE(0x8086, 0x811b),
-         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
+         .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
+         AZX_DCAPS_BUFSIZE},
        { PCI_DEVICE(0x8086, 0x2668),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH6 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH6 */
        { PCI_DEVICE(0x8086, 0x27d8),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH7 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH7 */
        { PCI_DEVICE(0x8086, 0x269a),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ESB2 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ESB2 */
        { PCI_DEVICE(0x8086, 0x284b),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH8 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH8 */
        { PCI_DEVICE(0x8086, 0x293e),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH9 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH9 */
        { PCI_DEVICE(0x8086, 0x293f),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH9 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH9 */
        { PCI_DEVICE(0x8086, 0x3a3e),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH10 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH10 */
        { PCI_DEVICE(0x8086, 0x3a6e),
-         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH10 */
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
+         AZX_DCAPS_BUFSIZE },  /* ICH10 */
        /* Generic Intel */
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
          .class_mask = 0xffffff,
-         .driver_data = AZX_DRIVER_ICH },
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
        /* ATI SB 450/600/700/800/900 */
        { PCI_DEVICE(0x1002, 0x437b),
          .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
index 2e7ac31afa8df9b320c0e263c1754df5620c7357..aaefa7c81e6830e33e9d82c9da6d8f6e2dd0f9f7 100644 (file)
@@ -267,11 +267,14 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
 enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
 enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
 
+#define HDA_MAX_OUTS   5
+
 struct hda_multi_out {
        int num_dacs;           /* # of DACs, must be more than 1 */
        const hda_nid_t *dac_nids;      /* DAC list */
        hda_nid_t hp_nid;       /* optional DAC for HP, 0 when not exists */
-       hda_nid_t extra_out_nid[3];     /* optional DACs, 0 when not exists */
+       hda_nid_t hp_out_nid[HDA_MAX_OUTS];     /* DACs for multiple HPs */
+       hda_nid_t extra_out_nid[HDA_MAX_OUTS];  /* other (e.g. speaker) DACs */
        hda_nid_t dig_out_nid;  /* digital out audio widget */
        const hda_nid_t *slave_dig_outs;
        int max_channels;       /* currently supported analog channels */
@@ -385,7 +388,7 @@ enum {
        AUTO_PIN_HP_OUT
 };
 
-#define AUTO_CFG_MAX_OUTS      5
+#define AUTO_CFG_MAX_OUTS      HDA_MAX_OUTS
 #define AUTO_CFG_MAX_INS       8
 
 struct auto_pin_cfg_item {
@@ -443,9 +446,18 @@ struct auto_pin_cfg {
 #define get_defcfg_device(cfg) \
        ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
 
-int snd_hda_parse_pin_def_config(struct hda_codec *codec,
-                                struct auto_pin_cfg *cfg,
-                                const hda_nid_t *ignore_nids);
+/* bit-flags for snd_hda_parse_pin_def_config() behavior */
+#define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */
+#define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */
+
+int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
+                            struct auto_pin_cfg *cfg,
+                            const hda_nid_t *ignore_nids,
+                            unsigned int cond_flags);
+
+/* older function */
+#define snd_hda_parse_pin_def_config(codec, cfg, ignore) \
+       snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0)
 
 /* amp values */
 #define AMP_IN_MUTE(idx)       (0x7080 | ((idx)<<8))
@@ -492,6 +504,8 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
 int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
                              unsigned int caps);
 u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
+int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
+                             unsigned int caps);
 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
 
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h
new file mode 100644 (file)
index 0000000..9884871
--- /dev/null
@@ -0,0 +1,117 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hda
+#define TRACE_INCLUDE_FILE hda_trace
+
+#if !defined(_TRACE_HDA_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_HDA_H
+
+#include <linux/tracepoint.h>
+
+struct hda_bus;
+struct hda_codec;
+
+DECLARE_EVENT_CLASS(hda_cmd,
+
+       TP_PROTO(struct hda_codec *codec, unsigned int val),
+
+       TP_ARGS(codec, val),
+
+       TP_STRUCT__entry(
+               __field( unsigned int, card )
+               __field( unsigned int, addr )
+               __field( unsigned int, val )
+       ),
+
+       TP_fast_assign(
+               __entry->card = (codec)->bus->card->number;
+               __entry->addr = (codec)->addr;
+               __entry->val = (val);
+       ),
+
+       TP_printk("[%d:%d] val=%x", __entry->card, __entry->addr, __entry->val)
+);
+
+DEFINE_EVENT(hda_cmd, hda_send_cmd,
+       TP_PROTO(struct hda_codec *codec, unsigned int val),
+       TP_ARGS(codec, val)
+);
+
+DEFINE_EVENT(hda_cmd, hda_get_response,
+       TP_PROTO(struct hda_codec *codec, unsigned int val),
+       TP_ARGS(codec, val)
+);
+
+TRACE_EVENT(hda_bus_reset,
+
+       TP_PROTO(struct hda_bus *bus),
+
+       TP_ARGS(bus),
+
+       TP_STRUCT__entry(
+               __field( unsigned int, card )
+       ),
+
+       TP_fast_assign(
+               __entry->card = (bus)->card->number;
+       ),
+
+       TP_printk("[%d]", __entry->card)
+);
+
+DECLARE_EVENT_CLASS(hda_power,
+
+       TP_PROTO(struct hda_codec *codec),
+
+       TP_ARGS(codec),
+
+       TP_STRUCT__entry(
+               __field( unsigned int, card )
+               __field( unsigned int, addr )
+       ),
+
+       TP_fast_assign(
+               __entry->card = (codec)->bus->card->number;
+               __entry->addr = (codec)->addr;
+       ),
+
+       TP_printk("[%d:%d]", __entry->card, __entry->addr)
+);
+
+DEFINE_EVENT(hda_power, hda_power_down,
+       TP_PROTO(struct hda_codec *codec),
+       TP_ARGS(codec)
+);
+
+DEFINE_EVENT(hda_power, hda_power_up,
+       TP_PROTO(struct hda_codec *codec),
+       TP_ARGS(codec)
+);
+
+TRACE_EVENT(hda_unsol_event,
+
+       TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
+
+       TP_ARGS(bus, res, res_ex),
+
+       TP_STRUCT__entry(
+               __field( unsigned int, card )
+               __field( u32, res )
+               __field( u32, res_ex )
+       ),
+
+       TP_fast_assign(
+               __entry->card = (bus)->card->number;
+               __entry->res = res;
+               __entry->res_ex = res_ex;
+       ),
+
+       TP_printk("[%d] res=%x, res_ex=%x", __entry->card,
+                 __entry->res, __entry->res_ex)
+);
+
+#endif /* _TRACE_HDA_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
index 502fc94994531118926bd8846befcd39a1d55325..4c462c3d6462c58ffa5b621c3f58c2e17a453772 100644 (file)
@@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
 
 #define MAX_AUTO_DACS  5
 
+#define DAC_SLAVE_FLAG 0x8000  /* filled dac is a slave */
+
 /* fill analog DAC list from the widget tree */
 static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
 {
@@ -3379,6 +3381,8 @@ static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
                filled[nums].pin = pins[i];
                filled[nums].type = type;
                filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
+               if (!filled[nums].dac && i > 0 && filled[0].dac)
+                       filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
                nums++;
        }
        return nums;
@@ -3407,7 +3411,7 @@ static void cx_auto_parse_output(struct hda_codec *codec)
        /* fill multiout struct */
        for (i = 0; i < nums; i++) {
                hda_nid_t dac = spec->dac_info[i].dac;
-               if (!dac)
+               if (!dac || (dac & DAC_SLAVE_FLAG))
                        continue;
                switch (spec->dac_info[i].type) {
                case AUTO_PIN_LINE_OUT:
@@ -4035,6 +4039,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
                nid = spec->dac_info[i].dac;
                if (!nid)
                        nid = spec->multiout.dac_nids[0];
+               else if (nid & DAC_SLAVE_FLAG)
+                       nid &= ~DAC_SLAVE_FLAG;
                select_connection(codec, spec->dac_info[i].pin, nid);
        }
        if (spec->auto_mute) {
@@ -4191,7 +4197,8 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
        for (i = 0; i < spec->dac_info_filled; i++) {
                const char *label;
                int idx, type;
-               if (!spec->dac_info[i].dac)
+               hda_nid_t dac = spec->dac_info[i].dac;
+               if (!dac || (dac & DAC_SLAVE_FLAG))
                        continue;
                type = spec->dac_info[i].type;
                if (type == AUTO_PIN_LINE_OUT)
@@ -4211,7 +4218,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
                        idx = num_spk++;
                        break;
                }
-               err = try_add_pb_volume(codec, spec->dac_info[i].dac,
+               err = try_add_pb_volume(codec, dac,
                                        spec->dac_info[i].pin,
                                        label, idx);
                if (err < 0)
index fcb11af9ad24f76a489f35472933238075b7bad5..50fd550974880a065310776616bace5adaeb513e 100644 (file)
@@ -159,6 +159,7 @@ struct alc_spec {
        void (*power_hook)(struct hda_codec *codec);
 #endif
        void (*shutup)(struct hda_codec *codec);
+       void (*automute_hook)(struct hda_codec *codec);
 
        /* for pin sensing */
        unsigned int jack_present: 1;
@@ -176,6 +177,7 @@ struct alc_spec {
        unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
        unsigned int single_input_src:1;
        unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
+       unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
 
        /* auto-mute control */
        int automute_mode;
@@ -202,6 +204,9 @@ struct alc_spec {
        /* multi-io */
        int multi_ios;
        struct alc_multi_io multi_io[4];
+
+       /* bind volumes */
+       struct snd_array bind_ctls;
 };
 
 #define ALC_MODEL_AUTO         0       /* common for all chips */
@@ -560,17 +565,26 @@ static void update_speakers(struct hda_codec *codec)
                    spec->autocfg.line_out_pins, on, false);
 }
 
+static void call_update_speakers(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       if (spec->automute_hook)
+               spec->automute_hook(codec);
+       else
+               update_speakers(codec);
+}
+
 /* standard HP-automute helper */
 static void alc_hp_automute(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
 
-       if (!spec->automute)
-               return;
        spec->jack_present =
                detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
                             spec->autocfg.hp_pins);
-       update_speakers(codec);
+       if (!spec->automute)
+               return;
+       call_update_speakers(codec);
 }
 
 /* standard line-out-automute helper */
@@ -578,12 +592,12 @@ static void alc_line_automute(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
 
-       if (!spec->automute || !spec->detect_line)
-               return;
        spec->line_jack_present =
                detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
                             spec->autocfg.line_out_pins);
-       update_speakers(codec);
+       if (!spec->automute || !spec->detect_line)
+               return;
+       call_update_speakers(codec);
 }
 
 #define get_connection_index(codec, mux, nid) \
@@ -840,7 +854,7 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
        default:
                return -EINVAL;
        }
-       update_speakers(codec);
+       call_update_speakers(codec);
        return 1;
 }
 
@@ -2361,6 +2375,18 @@ static void alc_free_kctls(struct hda_codec *codec)
        snd_array_free(&spec->kctls);
 }
 
+static void alc_free_bind_ctls(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       if (spec->bind_ctls.list) {
+               struct hda_bind_ctls **ctl = spec->bind_ctls.list;
+               int i;
+               for (i = 0; i < spec->bind_ctls.used; i++)
+                       kfree(ctl[i]);
+       }
+       snd_array_free(&spec->bind_ctls);
+}
+
 static void alc_free(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -2371,6 +2397,7 @@ static void alc_free(struct hda_codec *codec)
        alc_shutup(codec);
        snd_hda_input_jack_free(codec);
        alc_free_kctls(codec);
+       alc_free_bind_ctls(codec);
        kfree(spec);
        snd_hda_detach_beep_device(codec);
 }
@@ -2441,11 +2468,15 @@ enum {
        ALC_CTL_WIDGET_VOL,
        ALC_CTL_WIDGET_MUTE,
        ALC_CTL_BIND_MUTE,
+       ALC_CTL_BIND_VOL,
+       ALC_CTL_BIND_SW,
 };
 static const struct snd_kcontrol_new alc_control_templates[] = {
        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
        HDA_CODEC_MUTE(NULL, 0, 0, 0),
        HDA_BIND_MUTE(NULL, 0, 0, 0),
+       HDA_BIND_VOL(NULL, 0),
+       HDA_BIND_SW(NULL, 0),
 };
 
 /* add dynamic controls */
@@ -2486,13 +2517,14 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val)                   \
        add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
 
+static const char * const channel_name[4] = {
+       "Front", "Surround", "CLFE", "Side"
+};
+
 static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
                                        bool can_be_master, int *index)
 {
        struct auto_pin_cfg *cfg = &spec->autocfg;
-       static const char * const chname[4] = {
-               "Front", "Surround", NULL /*CLFE*/, "Side"
-       };
 
        *index = 0;
        if (cfg->line_outs == 1 && !spec->multi_ios &&
@@ -2515,7 +2547,10 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
                        return "PCM";
                break;
        }
-       return chname[ch];
+       if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name)))
+               return "PCM";
+
+       return channel_name[ch];
 }
 
 /* create input playback/capture controls for the given pin */
@@ -2779,7 +2814,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
                if (found_in_nid_list(nid, spec->multiout.dac_nids,
                                      spec->multiout.num_dacs))
                        continue;
-               if (spec->multiout.hp_nid == nid)
+               if (spec->multiout.hp_out_nid[0] == nid)
                        continue;
                if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
                                      ARRAY_SIZE(spec->multiout.extra_out_nid)))
@@ -2808,7 +2843,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
  again:
        /* set num_dacs once to full for alc_auto_look_for_dac() */
        spec->multiout.num_dacs = cfg->line_outs;
-       spec->multiout.hp_nid = 0;
+       spec->multiout.hp_out_nid[0] = 0;
        spec->multiout.extra_out_nid[0] = 0;
        memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
        spec->multiout.dac_nids = spec->private_dac_nids;
@@ -2819,7 +2854,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
                        spec->private_dac_nids[i] =
                                get_dac_if_single(codec, cfg->line_out_pins[i]);
                if (cfg->hp_outs)
-                       spec->multiout.hp_nid =
+                       spec->multiout.hp_out_nid[0] =
                                get_dac_if_single(codec, cfg->hp_pins[0]);
                if (cfg->speaker_outs)
                        spec->multiout.extra_out_nid[0] =
@@ -2851,8 +2886,8 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
                                sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
        }
 
-       if (cfg->hp_outs && !spec->multiout.hp_nid)
-               spec->multiout.hp_nid =
+       if (cfg->hp_outs && !spec->multiout.hp_out_nid[0])
+               spec->multiout.hp_out_nid[0] =
                        alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
        if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
                spec->multiout.extra_out_nid[0] =
@@ -2861,6 +2896,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
        return 0;
 }
 
+/* fill in the dac_nids table for surround speakers, etc */
+static int alc_auto_fill_extra_dacs(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       const struct auto_pin_cfg *cfg = &spec->autocfg;
+       int i;
+
+       if (cfg->speaker_outs < 2 || !spec->multiout.extra_out_nid[0])
+               return 0;
+
+       for (i = 1; i < cfg->speaker_outs; i++)
+               spec->multiout.extra_out_nid[i] =
+                       get_dac_if_single(codec, cfg->speaker_pins[i]);
+       for (i = 1; i < cfg->speaker_outs; i++) {
+               if (spec->multiout.extra_out_nid[i])
+                       continue;
+               spec->multiout.extra_out_nid[i] =
+                       alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
+       }
+       return 0;
+}
+
 static int alc_auto_add_vol_ctl(struct hda_codec *codec,
                              const char *pfx, int cidx,
                              hda_nid_t nid, unsigned int chs)
@@ -2983,16 +3040,13 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
        return 0;
 }
 
-/* add playback controls for speaker and HP outputs */
 static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
-                                       hda_nid_t dac, const char *pfx)
+                                    hda_nid_t dac, const char *pfx)
 {
        struct alc_spec *spec = codec->spec;
        hda_nid_t sw, vol;
        int err;
 
-       if (!pin)
-               return 0;
        if (!dac) {
                /* the corresponding DAC is already occupied */
                if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
@@ -3013,20 +3067,108 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
        return 0;
 }
 
+static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
+                                         unsigned int nums,
+                                         struct hda_ctl_ops *ops)
+{
+       struct alc_spec *spec = codec->spec;
+       struct hda_bind_ctls **ctlp, *ctl;
+       snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
+       ctlp = snd_array_new(&spec->bind_ctls);
+       if (!ctlp)
+               return NULL;
+       ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL);
+       *ctlp = ctl;
+       if (ctl)
+               ctl->ops = ops;
+       return ctl;
+}
+
+/* add playback controls for speaker and HP outputs */
+static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
+                                     const hda_nid_t *pins,
+                                     const hda_nid_t *dacs,
+                                     const char *pfx)
+{
+       struct alc_spec *spec = codec->spec;
+       struct hda_bind_ctls *ctl;
+       char name[32];
+       int i, n, err;
+
+       if (!num_pins || !pins[0])
+               return 0;
+
+       if (num_pins == 1)
+               return alc_auto_create_extra_out(codec, *pins, *dacs, pfx);
+
+       if (dacs[num_pins - 1]) {
+               /* OK, we have a multi-output system with individual volumes */
+               for (i = 0; i < num_pins; i++) {
+                       snprintf(name, sizeof(name), "%s %s",
+                                pfx, channel_name[i]);
+                       err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
+                                                       name);
+                       if (err < 0)
+                               return err;
+               }
+               return 0;
+       }
+
+       /* Let's create a bind-controls */
+       ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
+       if (!ctl)
+               return -ENOMEM;
+       n = 0;
+       for (i = 0; i < num_pins; i++) {
+               if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP)
+                       ctl->values[n++] =
+                               HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT);
+       }
+       if (n) {
+               snprintf(name, sizeof(name), "%s Playback Switch", pfx);
+               err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl);
+               if (err < 0)
+                       return err;
+       }
+
+       ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
+       if (!ctl)
+               return -ENOMEM;
+       n = 0;
+       for (i = 0; i < num_pins; i++) {
+               hda_nid_t vol;
+               if (!pins[i] || !dacs[i])
+                       continue;
+               vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]);
+               if (vol)
+                       ctl->values[n++] =
+                               HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
+       }
+       if (n) {
+               snprintf(name, sizeof(name), "%s Playback Volume", pfx);
+               err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
 static int alc_auto_create_hp_out(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
-                                        spec->multiout.hp_nid,
-                                        "Headphone");
+       return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs,
+                                         spec->autocfg.hp_pins,
+                                         spec->multiout.hp_out_nid,
+                                         "Headphone");
 }
 
 static int alc_auto_create_speaker_out(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
-                                        spec->multiout.extra_out_nid[0],
-                                        "Speaker");
+       return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs,
+                                         spec->autocfg.speaker_pins,
+                                         spec->multiout.extra_out_nid,
+                                         "Speaker");
 }
 
 static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
@@ -3083,16 +3225,35 @@ static void alc_auto_init_multi_out(struct hda_codec *codec)
 static void alc_auto_init_extra_out(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       hda_nid_t pin;
+       int i;
+       hda_nid_t pin, dac;
 
-       pin = spec->autocfg.hp_pins[0];
-       if (pin)
-               alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
-                                                 spec->multiout.hp_nid);
-       pin = spec->autocfg.speaker_pins[0];
-       if (pin)
-               alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
-                                       spec->multiout.extra_out_nid[0]);
+       for (i = 0; i < spec->autocfg.speaker_outs; i++) {
+               pin = spec->autocfg.hp_pins[i];
+               if (!pin)
+                       break;
+               dac = spec->multiout.hp_out_nid[i];
+               if (!dac) {
+                       if (i > 0 && spec->multiout.hp_out_nid[0])
+                               dac = spec->multiout.hp_out_nid[0];
+                       else
+                               dac = spec->multiout.dac_nids[0];
+               }
+               alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
+       }
+       for (i = 0; i < spec->autocfg.speaker_outs; i++) {
+               pin = spec->autocfg.speaker_pins[i];
+               if (!pin)
+                       break;
+               dac = spec->multiout.extra_out_nid[i];
+               if (!dac) {
+                       if (i > 0 && spec->multiout.extra_out_nid[0])
+                               dac = spec->multiout.extra_out_nid[0];
+                       else
+                               dac = spec->multiout.dac_nids[0];
+               }
+               alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
+       }
 }
 
 /*
@@ -3217,27 +3378,13 @@ static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
        .put = alc_auto_ch_mode_put,
 };
 
-static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
-                                          int (*fill_dac)(struct hda_codec *))
+static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
        unsigned int location, defcfg;
        int num_pins;
 
-       if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
-               /* use HP as primary out */
-               cfg->speaker_outs = cfg->line_outs;
-               memcpy(cfg->speaker_pins, cfg->line_out_pins,
-                      sizeof(cfg->speaker_pins));
-               cfg->line_outs = cfg->hp_outs;
-               memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
-               cfg->hp_outs = 0;
-               memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
-               cfg->line_out_type = AUTO_PIN_HP_OUT;
-               if (fill_dac)
-                       fill_dac(codec);
-       }
        if (cfg->line_outs != 1 ||
            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
                return 0;
@@ -3542,27 +3689,44 @@ static int alc_parse_auto_config(struct hda_codec *codec,
                                 const hda_nid_t *ssid_nids)
 {
        struct alc_spec *spec = codec->spec;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
        int err;
 
-       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-                                          ignore_nids);
+       err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
+                                      spec->parse_flags);
        if (err < 0)
                return err;
-       if (!spec->autocfg.line_outs) {
-               if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
+       if (!cfg->line_outs) {
+               if (cfg->dig_outs || cfg->dig_in_pin) {
                        spec->multiout.max_channels = 2;
                        spec->no_analog = 1;
                        goto dig_only;
                }
                return 0; /* can't find valid BIOS pin config */
        }
+
+       if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs > 0) {
+               /* use HP as primary out */
+               cfg->speaker_outs = cfg->line_outs;
+               memcpy(cfg->speaker_pins, cfg->line_out_pins,
+                      sizeof(cfg->speaker_pins));
+               cfg->line_outs = cfg->hp_outs;
+               memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
+               cfg->hp_outs = 0;
+               memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+               cfg->line_out_type = AUTO_PIN_HP_OUT;
+       }
+
        err = alc_auto_fill_dac_nids(codec);
        if (err < 0)
                return err;
-       err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
+       err = alc_auto_add_multi_channel_mode(codec);
        if (err < 0)
                return err;
-       err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
+       err = alc_auto_fill_extra_dacs(codec);
+       if (err < 0)
+               return err;
+       err = alc_auto_create_multi_out_ctls(codec, cfg);
        if (err < 0)
                return err;
        err = alc_auto_create_hp_out(codec);
@@ -4224,14 +4388,9 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc268_quirks.c"
-#endif
-
 static int patch_alc268(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int board_config;
        int i, has_beep, err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4242,39 +4401,13 @@ static int patch_alc268(struct hda_codec *codec)
 
        /* ALC268 has no aa-loopback mixer */
 
-       board_config = alc_board_config(codec, ALC268_MODEL_LAST,
-                                       alc268_models, alc268_cfg_tbl);
-
-       if (board_config < 0)
-               board_config = alc_board_codec_sid_config(codec,
-                       ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
-
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc268_parse_auto_config(codec);
-               if (err < 0) {
-                       alc_free(codec);
-                       return err;
-               }
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using base mode...\n");
-                       board_config = ALC268_3ST;
-               }
-#endif
+       /* automatic parse from the BIOS config */
+       err = alc268_parse_auto_config(codec);
+       if (err < 0) {
+               alc_free(codec);
+               return err;
        }
 
-       if (board_config != ALC_MODEL_AUTO)
-               setup_preset(codec, &alc268_presets[board_config]);
-
        has_beep = 0;
        for (i = 0; i < spec->num_mixers; i++) {
                if (spec->mixers[i] == alc268_beep_mixer) {
@@ -4310,8 +4443,7 @@ static int patch_alc268(struct hda_codec *codec)
        spec->vmaster_nid = 0x02;
 
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
+       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
 
        alc_init_jacks(codec);
@@ -4502,6 +4634,30 @@ static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
        alc_write_coef_idx(codec, 0x07, coef | 0x80);
 }
 
+static void alc269_quanta_automute(struct hda_codec *codec)
+{
+       update_speakers(codec);
+
+       snd_hda_codec_write(codec, 0x20, 0,
+                       AC_VERB_SET_COEF_INDEX, 0x0c);
+       snd_hda_codec_write(codec, 0x20, 0,
+                       AC_VERB_SET_PROC_COEF, 0x680);
+
+       snd_hda_codec_write(codec, 0x20, 0,
+                       AC_VERB_SET_COEF_INDEX, 0x0c);
+       snd_hda_codec_write(codec, 0x20, 0,
+                       AC_VERB_SET_PROC_COEF, 0x480);
+}
+
+static void alc269_fixup_quanta_mute(struct hda_codec *codec,
+                                    const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       if (action != ALC_FIXUP_ACT_PROBE)
+               return;
+       spec->automute_hook = alc269_quanta_automute;
+}
+
 enum {
        ALC269_FIXUP_SONY_VAIO,
        ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -4513,6 +4669,12 @@ enum {
        ALC271_FIXUP_DMIC,
        ALC269_FIXUP_PCM_44K,
        ALC269_FIXUP_STEREO_DMIC,
+       ALC269_FIXUP_QUANTA_MUTE,
+       ALC269_FIXUP_LIFEBOOK,
+       ALC269_FIXUP_AMIC,
+       ALC269_FIXUP_DMIC,
+       ALC269VB_FIXUP_AMIC,
+       ALC269VB_FIXUP_DMIC,
 };
 
 static const struct alc_fixup alc269_fixups[] = {
@@ -4579,6 +4741,60 @@ static const struct alc_fixup alc269_fixups[] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc269_fixup_stereo_dmic,
        },
+       [ALC269_FIXUP_QUANTA_MUTE] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc269_fixup_quanta_mute,
+       },
+       [ALC269_FIXUP_LIFEBOOK] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x1a, 0x2101103f }, /* dock line-out */
+                       { 0x1b, 0x23a11040 }, /* dock mic-in */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_QUANTA_MUTE
+       },
+       [ALC269_FIXUP_AMIC] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x15, 0x0121401f }, /* HP out */
+                       { 0x18, 0x01a19c20 }, /* mic */
+                       { 0x19, 0x99a3092f }, /* int-mic */
+                       { }
+               },
+       },
+       [ALC269_FIXUP_DMIC] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x12, 0x99a3092f }, /* int-mic */
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x15, 0x0121401f }, /* HP out */
+                       { 0x18, 0x01a19c20 }, /* mic */
+                       { }
+               },
+       },
+       [ALC269VB_FIXUP_AMIC] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x18, 0x01a19c20 }, /* mic */
+                       { 0x19, 0x99a3092f }, /* int-mic */
+                       { 0x21, 0x0121401f }, /* HP out */
+                       { }
+               },
+       },
+       [ALC269_FIXUP_DMIC] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x12, 0x99a3092f }, /* int-mic */
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x18, 0x01a19c20 }, /* mic */
+                       { 0x21, 0x0121401f }, /* HP out */
+                       { }
+               },
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -4594,13 +4810,71 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
        SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+
+#if 1
+       /* Below is a quirk table taken from the old code.
+        * Basically the device should work as is without the fixup table.
+        * If BIOS doesn't give a proper info, enable the corresponding
+        * fixup entry.
+        */ 
+       SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
+                     ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
+       SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
+       SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
+#endif
+       {}
+};
+
+static const struct alc_model_fixup alc269_fixup_models[] = {
+       {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
+       {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
        {}
 };
 
@@ -4649,14 +4923,9 @@ static int alc269_fill_coef(struct hda_codec *codec)
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc269_quirks.c"
-#endif
-
 static int patch_alc269(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int board_config, coef;
        int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4670,6 +4939,7 @@ static int patch_alc269(struct hda_codec *codec)
        alc_auto_parse_customize_define(codec);
 
        if (codec->vendor_id == 0x10ec0269) {
+               unsigned int coef;
                spec->codec_variant = ALC269_TYPE_ALC269VA;
                coef = alc_read_coef_idx(codec, 0);
                if ((coef & 0x00f0) == 0x0010) {
@@ -4702,40 +4972,17 @@ static int patch_alc269(struct hda_codec *codec)
                alc269_fill_coef(codec);
        }
 
-       board_config = alc_board_config(codec, ALC269_MODEL_LAST,
-                                       alc269_models, alc269_cfg_tbl);
+       alc_pick_fixup(codec, alc269_fixup_models,
+                      alc269_fixup_tbl, alc269_fixups);
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
-               alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc269_parse_auto_config(codec);
-               if (err < 0) {
-                       alc_free(codec);
-                       return err;
-               }
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using base mode...\n");
-                       board_config = ALC269_BASIC;
-               }
-#endif
+       /* automatic parse from the BIOS config */
+       err = alc269_parse_auto_config(codec);
+       if (err < 0) {
+               alc_free(codec);
+               return err;
        }
 
-       if (board_config != ALC_MODEL_AUTO)
-               setup_preset(codec, &alc269_presets[board_config]);
-
        if (!spec->no_analog && !spec->adc_nids) {
                alc_auto_fill_adc_caps(codec);
                alc_rebuild_imux_for_auto_mic(codec);
@@ -4762,8 +5009,7 @@ static int patch_alc269(struct hda_codec *codec)
 #ifdef CONFIG_PM
        codec->patch_ops.resume = alc269_resume;
 #endif
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
+       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc269_shutup;
 
        alc_init_jacks(codec);
@@ -4822,14 +5068,9 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc861_quirks.c"
-#endif
-
 static int patch_alc861(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int board_config;
        int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4840,40 +5081,16 @@ static int patch_alc861(struct hda_codec *codec)
 
        spec->mixer_nid = 0x15;
 
-        board_config = alc_board_config(codec, ALC861_MODEL_LAST,
-                                       alc861_models, alc861_cfg_tbl);
+       alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
-               alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc861_parse_auto_config(codec);
-               if (err < 0) {
-                       alc_free(codec);
-                       return err;
-               }
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using base mode...\n");
-                  board_config = ALC861_3ST_DIG;
-               }
-#endif
+       /* automatic parse from the BIOS config */
+       err = alc861_parse_auto_config(codec);
+       if (err < 0) {
+               alc_free(codec);
+               return err;
        }
 
-       if (board_config != ALC_MODEL_AUTO)
-               setup_preset(codec, &alc861_presets[board_config]);
-
        if (!spec->no_analog && !spec->adc_nids) {
                alc_auto_fill_adc_caps(codec);
                alc_rebuild_imux_for_auto_mic(codec);
@@ -4897,13 +5114,9 @@ static int patch_alc861(struct hda_codec *codec)
        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC_MODEL_AUTO) {
-               spec->init_hook = alc_auto_init_std;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-               spec->power_hook = alc_power_eapd;
-#endif
-       }
+       spec->init_hook = alc_auto_init_std;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
+       spec->power_hook = alc_power_eapd;
        if (!spec->loopback.amplist)
                spec->loopback.amplist = alc861_loopbacks;
 #endif
@@ -4930,24 +5143,41 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
 }
 
 enum {
-       ALC660VD_FIX_ASUS_GPIO1
+       ALC660VD_FIX_ASUS_GPIO1,
+       ALC861VD_FIX_DALLAS,
 };
 
-/* reset GPIO1 */
+/* exclude VREF80 */
+static void alc861vd_fixup_dallas(struct hda_codec *codec,
+                                 const struct alc_fixup *fix, int action)
+{
+       if (action == ALC_FIXUP_ACT_PRE_PROBE) {
+               snd_hda_override_pin_caps(codec, 0x18, 0x00001714);
+               snd_hda_override_pin_caps(codec, 0x19, 0x0000171c);
+       }
+}
+
 static const struct alc_fixup alc861vd_fixups[] = {
        [ALC660VD_FIX_ASUS_GPIO1] = {
                .type = ALC_FIXUP_VERBS,
                .v.verbs = (const struct hda_verb[]) {
+                       /* reset GPIO1 */
                        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
                        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
                        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
                        { }
                }
        },
+       [ALC861VD_FIX_DALLAS] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc861vd_fixup_dallas,
+       },
 };
 
 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
+       SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
        {}
 };
 
@@ -4959,14 +5189,10 @@ static const struct hda_verb alc660vd_eapd_verbs[] = {
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc861vd_quirks.c"
-#endif
-
 static int patch_alc861vd(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int err, board_config;
+       int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
@@ -4976,40 +5202,16 @@ static int patch_alc861vd(struct hda_codec *codec)
 
        spec->mixer_nid = 0x0b;
 
-       board_config = alc_board_config(codec, ALC861VD_MODEL_LAST,
-                                       alc861vd_models, alc861vd_cfg_tbl);
+       alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
+       alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
-               alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc861vd_parse_auto_config(codec);
-               if (err < 0) {
-                       alc_free(codec);
-                       return err;
-               }
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using base mode...\n");
-                       board_config = ALC861VD_3ST;
-               }
-#endif
+       /* automatic parse from the BIOS config */
+       err = alc861vd_parse_auto_config(codec);
+       if (err < 0) {
+               alc_free(codec);
+               return err;
        }
 
-       if (board_config != ALC_MODEL_AUTO)
-               setup_preset(codec, &alc861vd_presets[board_config]);
-
        if (codec->vendor_id == 0x10ec0660) {
                /* always turn on EAPD */
                add_verb(spec, alc660vd_eapd_verbs);
@@ -5039,8 +5241,7 @@ static int patch_alc861vd(struct hda_codec *codec)
 
        codec->patch_ops = alc_patch_ops;
 
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
+       spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        if (!spec->loopback.amplist)
@@ -5105,6 +5306,14 @@ enum {
        ALC662_FIXUP_CZC_P10T,
        ALC662_FIXUP_SKU_IGNORE,
        ALC662_FIXUP_HP_RP5800,
+       ALC662_FIXUP_ASUS_MODE1,
+       ALC662_FIXUP_ASUS_MODE2,
+       ALC662_FIXUP_ASUS_MODE3,
+       ALC662_FIXUP_ASUS_MODE4,
+       ALC662_FIXUP_ASUS_MODE5,
+       ALC662_FIXUP_ASUS_MODE6,
+       ALC662_FIXUP_ASUS_MODE7,
+       ALC662_FIXUP_ASUS_MODE8,
 };
 
 static const struct alc_fixup alc662_fixups[] = {
@@ -5146,22 +5355,194 @@ static const struct alc_fixup alc662_fixups[] = {
                .chained = true,
                .chain_id = ALC662_FIXUP_SKU_IGNORE
        },
+       [ALC662_FIXUP_ASUS_MODE1] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x18, 0x01a19c20 }, /* mic */
+                       { 0x19, 0x99a3092f }, /* int-mic */
+                       { 0x21, 0x0121401f }, /* HP out */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE2] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x18, 0x01a19820 }, /* mic */
+                       { 0x19, 0x99a3092f }, /* int-mic */
+                       { 0x1b, 0x0121401f }, /* HP out */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE3] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x15, 0x0121441f }, /* HP */
+                       { 0x18, 0x01a19840 }, /* mic */
+                       { 0x19, 0x99a3094f }, /* int-mic */
+                       { 0x21, 0x01211420 }, /* HP2 */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE4] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x16, 0x99130111 }, /* speaker */
+                       { 0x18, 0x01a19840 }, /* mic */
+                       { 0x19, 0x99a3094f }, /* int-mic */
+                       { 0x21, 0x0121441f }, /* HP */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE5] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x15, 0x0121441f }, /* HP */
+                       { 0x16, 0x99130111 }, /* speaker */
+                       { 0x18, 0x01a19840 }, /* mic */
+                       { 0x19, 0x99a3094f }, /* int-mic */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE6] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x15, 0x01211420 }, /* HP2 */
+                       { 0x18, 0x01a19840 }, /* mic */
+                       { 0x19, 0x99a3094f }, /* int-mic */
+                       { 0x1b, 0x0121441f }, /* HP */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE7] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x17, 0x99130111 }, /* speaker */
+                       { 0x18, 0x01a19840 }, /* mic */
+                       { 0x19, 0x99a3094f }, /* int-mic */
+                       { 0x1b, 0x01214020 }, /* HP */
+                       { 0x21, 0x0121401f }, /* HP */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
+       [ALC662_FIXUP_ASUS_MODE8] = {
+               .type = ALC_FIXUP_PINS,
+               .v.pins = (const struct alc_pincfg[]) {
+                       { 0x14, 0x99130110 }, /* speaker */
+                       { 0x12, 0x99a30970 }, /* int-mic */
+                       { 0x15, 0x01214020 }, /* HP */
+                       { 0x17, 0x99130111 }, /* speaker */
+                       { 0x18, 0x01a19840 }, /* mic */
+                       { 0x21, 0x0121401f }, /* HP */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC662_FIXUP_SKU_IGNORE
+       },
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
+       SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
+
+#if 0
+       /* Below is a quirk table taken from the old code.
+        * Basically the device should work as is without the fixup table.
+        * If BIOS doesn't give a proper info, enable the corresponding
+        * fixup entry.
+        */ 
+       SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
+       SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
+       SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
+       SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
+       SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
+       SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
+       SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
+       SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
+#endif
        {}
 };
 
 static const struct alc_model_fixup alc662_fixup_models[] = {
        {.id = ALC272_FIXUP_MARIO, .name = "mario"},
+       {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
+       {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
+       {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
+       {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
+       {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
+       {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
+       {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
+       {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
        {}
 };
 
@@ -5186,6 +5567,9 @@ static int patch_alc662(struct hda_codec *codec)
 
        spec->mixer_nid = 0x0b;
 
+       /* handle multiple HPs as is */
+       spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
+
        alc_auto_parse_customize_define(codec);
 
        alc_fix_pll_init(codec, 0x20, 0x04, 15);
@@ -5316,14 +5700,9 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc680_quirks.c"
-#endif
-
 static int patch_alc680(struct hda_codec *codec)
 {
        struct alc_spec *spec;
-       int board_config;
        int err;
 
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5334,43 +5713,11 @@ static int patch_alc680(struct hda_codec *codec)
 
        /* ALC680 has no aa-loopback mixer */
 
-       board_config = alc_board_config(codec, ALC680_MODEL_LAST,
-                                       alc680_models, alc680_cfg_tbl);
-
-       if (board_config < 0) {
-               printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-                      codec->chip_name);
-               board_config = ALC_MODEL_AUTO;
-       }
-
-       if (board_config == ALC_MODEL_AUTO) {
-               /* automatic parse from the BIOS config */
-               err = alc680_parse_auto_config(codec);
-               if (err < 0) {
-                       alc_free(codec);
-                       return err;
-               }
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               else if (!err) {
-                       printk(KERN_INFO
-                              "hda_codec: Cannot set up configuration "
-                              "from BIOS.  Using base mode...\n");
-                       board_config = ALC680_BASE;
-               }
-#endif
-       }
-
-       if (board_config != ALC_MODEL_AUTO) {
-               setup_preset(codec, &alc680_presets[board_config]);
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-               spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
-#endif
-       }
-
-       if (!spec->no_analog && !spec->adc_nids) {
-               alc_auto_fill_adc_caps(codec);
-               alc_rebuild_imux_for_auto_mic(codec);
-               alc_remove_invalid_adc_nids(codec);
+       /* automatic parse from the BIOS config */
+       err = alc680_parse_auto_config(codec);
+       if (err < 0) {
+               alc_free(codec);
+               return err;
        }
 
        if (!spec->no_analog && !spec->cap_mixer)
@@ -5379,8 +5726,7 @@ static int patch_alc680(struct hda_codec *codec)
        spec->vmaster_nid = 0x02;
 
        codec->patch_ops = alc_patch_ops;
-       if (board_config == ALC_MODEL_AUTO)
-               spec->init_hook = alc_auto_init_std;
+       spec->init_hook = alc_auto_init_std;
 
        return 0;
 }
index 32d096c98f5bc2f6f1ca45e3261b1faed3e2e629..8433aa7c3d754064f9e0b57cae437277161f09f5 100644 (file)
@@ -1074,6 +1074,7 @@ static const struct oxygen_model model_xonar_st = {
        .device_config = PLAYBACK_0_TO_I2S |
                         PLAYBACK_1_TO_SPDIF |
                         CAPTURE_0_FROM_I2S_2 |
+                        CAPTURE_1_FROM_SPDIF |
                         AC97_FMIC_SWITCH,
        .dac_channels_pcm = 2,
        .dac_channels_mixer = 2,
index 493e3946756f9e30cecbb700d96cc48bea3df94e..214110d6a2bf3b77d2ac6a178036676e7e5e3149 100644 (file)
@@ -1241,10 +1241,30 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
        return rate;
 }
 
+/* return latency in samples per period */
+static int hdspm_get_latency(struct hdspm *hdspm)
+{
+       int n;
+
+       n = hdspm_decode_latency(hdspm->control_register);
+
+       /* Special case for new RME cards with 32 samples period size.
+        * The three latency bits in the control register
+        * (HDSP_LatencyMask) encode latency values of 64 samples as
+        * 0, 128 samples as 1 ... 4096 samples as 6. For old cards, 7
+        * denotes 8192 samples, but on new cards like RayDAT or AIO,
+        * it corresponds to 32 samples.
+        */
+       if ((7 == n) && (RayDAT == hdspm->io_type || AIO == hdspm->io_type))
+               n = -1;
+
+       return 1 << (n + 6);
+}
+
 /* Latency function */
 static inline void hdspm_compute_period_size(struct hdspm *hdspm)
 {
-       hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
+       hdspm->period_bytes = 4 * hdspm_get_latency(hdspm);
 }
 
 
@@ -1303,12 +1323,27 @@ static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
 
        spin_lock_irq(&s->lock);
 
-       frames >>= 7;
-       n = 0;
-       while (frames) {
-               n++;
-               frames >>= 1;
+       if (32 == frames) {
+               /* Special case for new RME cards like RayDAT/AIO which
+                * support period sizes of 32 samples. Since latency is
+                * encoded in the three bits of HDSP_LatencyMask, we can only
+                * have values from 0 .. 7. While 0 still means 64 samples and
+                * 6 represents 4096 samples on all cards, 7 represents 8192
+                * on older cards and 32 samples on new cards.
+                *
+                * In other words, period size in samples is calculated by
+                * 2^(n+6) with n ranging from 0 .. 7.
+                */
+               n = 7;
+       } else {
+               frames >>= 7;
+               n = 0;
+               while (frames) {
+                       n++;
+                       frames >>= 1;
+               }
        }
+
        s->control_register &= ~HDSPM_LatencyMask;
        s->control_register |= hdspm_encode_latency(n);
 
@@ -4801,8 +4836,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
 
        snd_iprintf(buffer, "--- Settings ---\n");
 
-       x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
-                                                       HDSPM_LatencyMask));
+       x = hdspm_get_latency(hdspm);
 
        snd_iprintf(buffer,
                "Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -4965,8 +4999,7 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
 
        snd_iprintf(buffer, "--- Settings ---\n");
 
-       x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
-                               HDSPM_LatencyMask));
+       x = hdspm_get_latency(hdspm);
 
        snd_iprintf(buffer,
                    "Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -5672,19 +5705,6 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static unsigned int period_sizes_old[] = {
-       64, 128, 256, 512, 1024, 2048, 4096
-};
-
-static unsigned int period_sizes_new[] = {
-       32, 64, 128, 256, 512, 1024, 2048, 4096
-};
-
-/* RayDAT and AIO always have a buffer of 16384 samples per channel */
-static unsigned int raydat_aio_buffer_sizes[] = {
-       16384
-};
-
 static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
        .info = (SNDRV_PCM_INFO_MMAP |
                 SNDRV_PCM_INFO_MMAP_VALID |
@@ -5703,8 +5723,8 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
        .channels_max = HDSPM_MAX_CHANNELS,
        .buffer_bytes_max =
            HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
-       .period_bytes_min = (64 * 4),
-       .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
+       .period_bytes_min = (32 * 4),
+       .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
        .periods_min = 2,
        .periods_max = 512,
        .fifo_size = 0
@@ -5728,31 +5748,13 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
        .channels_max = HDSPM_MAX_CHANNELS,
        .buffer_bytes_max =
            HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
-       .period_bytes_min = (64 * 4),
-       .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
+       .period_bytes_min = (32 * 4),
+       .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
        .periods_min = 2,
        .periods_max = 512,
        .fifo_size = 0
 };
 
-static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = {
-       .count = ARRAY_SIZE(period_sizes_old),
-       .list = period_sizes_old,
-       .mask = 0
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = {
-       .count = ARRAY_SIZE(period_sizes_new),
-       .list = period_sizes_new,
-       .mask = 0
-};
-
-static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = {
-       .count = ARRAY_SIZE(raydat_aio_buffer_sizes),
-       .list = raydat_aio_buffer_sizes,
-       .mask = 0
-};
-
 static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
                                           struct snd_pcm_hw_rule *rule)
 {
@@ -5953,26 +5955,29 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
        spin_unlock_irq(&hdspm->lock);
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+       snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
 
        switch (hdspm->io_type) {
        case AIO:
        case RayDAT:
-               snd_pcm_hw_constraint_list(runtime, 0,
-                               SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                               &hw_constraints_period_sizes_new);
-               snd_pcm_hw_constraint_list(runtime, 0,
-                               SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
-                               &hw_constraints_raydat_io_buffer);
-
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            32, 4096);
+               /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+                                            16384, 16384);
                break;
 
        default:
-               snd_pcm_hw_constraint_list(runtime, 0,
-                               SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                               &hw_constraints_period_sizes_old);
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            64, 8192);
+               break;
        }
 
        if (AES32 == hdspm->io_type) {
+               runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                &hdspm_hw_constraints_aes32_sample_rates);
        } else {
@@ -6025,24 +6030,28 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
        spin_unlock_irq(&hdspm->lock);
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+       snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+
        switch (hdspm->io_type) {
        case AIO:
        case RayDAT:
-         snd_pcm_hw_constraint_list(runtime, 0,
-                                    SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                                    &hw_constraints_period_sizes_new);
-         snd_pcm_hw_constraint_list(runtime, 0,
-                                    SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
-                                    &hw_constraints_raydat_io_buffer);
-         break;
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            32, 4096);
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+                                            16384, 16384);
+               break;
 
        default:
-         snd_pcm_hw_constraint_list(runtime, 0,
-                                    SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                                    &hw_constraints_period_sizes_old);
+               snd_pcm_hw_constraint_minmax(runtime,
+                                            SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                            64, 8192);
+               break;
        }
 
        if (AES32 == hdspm->io_type) {
+               runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                &hdspm_hw_constraints_aes32_sample_rates);
        } else {
index 8224db5f0434ffa7c16b93899f06401ae7c9ed3b..1381db853ef0f8b5d875c6ba220de0f90476add5 100644 (file)
@@ -7,6 +7,8 @@ menuconfig SND_SOC
        select SND_PCM
        select AC97_BUS if SND_SOC_AC97_BUS
        select SND_JACK if INPUT=y || INPUT=SND
+       select REGMAP_I2C if I2C
+       select REGMAP_SPI if SPI_MASTER
        ---help---
 
          If you want ASoC support, you should say Y here and also to the
@@ -51,6 +53,7 @@ source "sound/soc/nuc900/Kconfig"
 source "sound/soc/omap/Kconfig"
 source "sound/soc/kirkwood/Kconfig"
 source "sound/soc/mid-x86/Kconfig"
+source "sound/soc/mxs/Kconfig"
 source "sound/soc/pxa/Kconfig"
 source "sound/soc/samsung/Kconfig"
 source "sound/soc/s6000/Kconfig"
index 4f913876f3324e0e29fa297560cfce2ec3b84bd4..9ea8ac827adc37327d955acd30a7639b571030d3 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC) += fsl/
 obj-$(CONFIG_SND_SOC)   += imx/
 obj-$(CONFIG_SND_SOC)  += jz4740/
 obj-$(CONFIG_SND_SOC)  += mid-x86/
+obj-$(CONFIG_SND_SOC)  += mxs/
 obj-$(CONFIG_SND_SOC)  += nuc900/
 obj-$(CONFIG_SND_SOC)  += omap/
 obj-$(CONFIG_SND_SOC)  += kirkwood/
index 4b67140fdec3cb8e98b8ecc39dc54c8e8160ea86..6d592546e8fcc2bd2a0ea343baf929f0a930762f 100644 (file)
@@ -18,10 +18,38 @@ config SND_SOC_AU1XPSC_AC97
        select SND_AC97_CODEC
        select SND_SOC_AC97_BUS
 
+##
+## Au1000/1500/1100 DMA + AC97C/I2SC
+##
+config SND_SOC_AU1XAUDIO
+       tristate "SoC Audio for Au1000/Au1500/Au1100"
+       depends on MIPS_ALCHEMY
+       help
+         This is a driver set for the AC97 unit and the
+         old DMA controller as found on the Au1000/Au1500/Au1100 chips.
+
+config SND_SOC_AU1XAC97C
+       tristate
+       select AC97_BUS
+       select SND_AC97_CODEC
+       select SND_SOC_AC97_BUS
+
+config SND_SOC_AU1XI2SC
+       tristate
+
 
 ##
 ## Boards
 ##
+config SND_SOC_DB1000
+       tristate "DB1000 Audio support"
+       depends on SND_SOC_AU1XAUDIO
+       select SND_SOC_AU1XAC97C
+       select SND_SOC_AC97_CODEC
+       help
+         Select this option to enable AC97 audio on the early DB1x00 series
+         of boards (DB1000/DB1500/DB1100).
+
 config SND_SOC_DB1200
        tristate "DB1200 AC97+I2S audio support"
        depends on SND_SOC_AU1XPSC
index 16873076e8c44044a803076eff2cfabcd53cc000..920710514ea07baaaa734fb55fefe1a96ca92215 100644 (file)
@@ -3,11 +3,21 @@ snd-soc-au1xpsc-dbdma-objs := dbdma2.o
 snd-soc-au1xpsc-i2s-objs := psc-i2s.o
 snd-soc-au1xpsc-ac97-objs := psc-ac97.o
 
+# Au1000/1500/1100 Audio units
+snd-soc-au1x-dma-objs := dma.o
+snd-soc-au1x-ac97c-objs := ac97c.o
+snd-soc-au1x-i2sc-objs := i2sc.o
+
 obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o
 obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
 obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
+obj-$(CONFIG_SND_SOC_AU1XAUDIO) += snd-soc-au1x-dma.o
+obj-$(CONFIG_SND_SOC_AU1XAC97C) += snd-soc-au1x-ac97c.o
+obj-$(CONFIG_SND_SOC_AU1XI2SC) += snd-soc-au1x-i2sc.o
 
 # Boards
+snd-soc-db1000-objs := db1000.o
 snd-soc-db1200-objs := db1200.o
 
+obj-$(CONFIG_SND_SOC_DB1000) += snd-soc-db1000.o
 obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
new file mode 100644 (file)
index 0000000..13802ff
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Au1000/Au1500/Au1100 AC97C controller driver for ASoC
+ *
+ * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
+ *
+ * based on the old ALSA driver originally written by
+ *                     Charles Eidsness <charles@cooper-street.com>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include "psc.h"
+
+/* register offsets and bits */
+#define AC97_CONFIG    0x00
+#define AC97_STATUS    0x04
+#define AC97_DATA      0x08
+#define AC97_CMDRESP   0x0c
+#define AC97_ENABLE    0x10
+
+#define CFG_RC(x)      (((x) & 0x3ff) << 13)   /* valid rx slots mask */
+#define CFG_XS(x)      (((x) & 0x3ff) << 3)    /* valid tx slots mask */
+#define CFG_SG         (1 << 2)        /* sync gate */
+#define CFG_SN         (1 << 1)        /* sync control */
+#define CFG_RS         (1 << 0)        /* acrst# control */
+#define STAT_XU                (1 << 11)       /* tx underflow */
+#define STAT_XO                (1 << 10)       /* tx overflow */
+#define STAT_RU                (1 << 9)        /* rx underflow */
+#define STAT_RO                (1 << 8)        /* rx overflow */
+#define STAT_RD                (1 << 7)        /* codec ready */
+#define STAT_CP                (1 << 6)        /* command pending */
+#define STAT_TE                (1 << 4)        /* tx fifo empty */
+#define STAT_TF                (1 << 3)        /* tx fifo full */
+#define STAT_RE                (1 << 1)        /* rx fifo empty */
+#define STAT_RF                (1 << 0)        /* rx fifo full */
+#define CMD_SET_DATA(x)        (((x) & 0xffff) << 16)
+#define CMD_GET_DATA(x)        ((x) & 0xffff)
+#define CMD_READ       (1 << 7)
+#define CMD_WRITE      (0 << 7)
+#define CMD_IDX(x)     ((x) & 0x7f)
+#define EN_D           (1 << 1)        /* DISable bit */
+#define EN_CE          (1 << 0)        /* clock enable bit */
+
+/* how often to retry failed codec register reads/writes */
+#define AC97_RW_RETRIES        5
+
+#define AC97_RATES     \
+       SNDRV_PCM_RATE_CONTINUOUS
+
+#define AC97_FMTS      \
+       (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE)
+
+/* instance data. There can be only one, MacLeod!!!!, fortunately there IS only
+ * once AC97C on early Alchemy chips. The newer ones aren't so lucky.
+ */
+static struct au1xpsc_audio_data *ac97c_workdata;
+#define ac97_to_ctx(x)         ac97c_workdata
+
+static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
+{
+       return __raw_readl(ctx->mmio + reg);
+}
+
+static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
+{
+       __raw_writel(v, ctx->mmio + reg);
+       wmb();
+}
+
+static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
+                                         unsigned short r)
+{
+       struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
+       unsigned int tmo, retry;
+       unsigned long data;
+
+       data = ~0;
+       retry = AC97_RW_RETRIES;
+       do {
+               mutex_lock(&ctx->lock);
+
+               tmo = 5;
+               while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
+                       udelay(21);     /* wait an ac97 frame time */
+               if (!tmo) {
+                       pr_debug("ac97rd timeout #1\n");
+                       goto next;
+               }
+
+               WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);
+
+               /* stupid errata: data is only valid for 21us, so
+                * poll, Forrest, poll...
+                */
+               tmo = 0x10000;
+               while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
+                       asm volatile ("nop");
+               data = RD(ctx, AC97_CMDRESP);
+
+               if (!tmo)
+                       pr_debug("ac97rd timeout #2\n");
+
+next:
+               mutex_unlock(&ctx->lock);
+       } while (--retry && !tmo);
+
+       pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);
+
+       return retry ? data & 0xffff : 0xffff;
+}
+
+static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r,
+                                unsigned short v)
+{
+       struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
+       unsigned int tmo, retry;
+
+       retry = AC97_RW_RETRIES;
+       do {
+               mutex_lock(&ctx->lock);
+
+               for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
+                       udelay(21);
+               if (!tmo) {
+                       pr_debug("ac97wr timeout #1\n");
+                       goto next;
+               }
+
+               WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v));
+
+               for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
+                       udelay(21);
+               if (!tmo)
+                       pr_debug("ac97wr timeout #2\n");
+next:
+               mutex_unlock(&ctx->lock);
+       } while (--retry && !tmo);
+
+       pr_debug("AC97WR %04x %04x %d\n", r, v, retry);
+}
+
+static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+       struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
+
+       WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN);
+       msleep(20);
+       WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG);
+       WR(ctx, AC97_CONFIG, ctx->cfg);
+}
+
+static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+       struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
+       int i;
+
+       WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS);
+       msleep(500);
+       WR(ctx, AC97_CONFIG, ctx->cfg);
+
+       /* wait for codec ready */
+       i = 50;
+       while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i)
+               msleep(20);
+       if (!i)
+               printk(KERN_ERR "ac97c: codec not ready after cold reset\n");
+}
+
+/* AC97 controller operations */
+struct snd_ac97_bus_ops soc_ac97_ops = {
+       .read           = au1xac97c_ac97_read,
+       .write          = au1xac97c_ac97_write,
+       .reset          = au1xac97c_ac97_cold_reset,
+       .warm_reset     = au1xac97c_ac97_warm_reset,
+};
+EXPORT_SYMBOL_GPL(soc_ac97_ops);       /* globals be gone! */
+
+static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
+                                struct snd_soc_dai *dai)
+{
+       struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
+       snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
+       return 0;
+}
+
+static struct snd_soc_dai_ops alchemy_ac97c_ops = {
+       .startup                = alchemy_ac97c_startup,
+};
+
+static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
+{
+       return ac97c_workdata ? 0 : -ENODEV;
+}
+
+static struct snd_soc_dai_driver au1xac97c_dai_driver = {
+       .name                   = "alchemy-ac97c",
+       .ac97_control           = 1,
+       .probe                  = au1xac97c_dai_probe,
+       .playback = {
+               .rates          = AC97_RATES,
+               .formats        = AC97_FMTS,
+               .channels_min   = 2,
+               .channels_max   = 2,
+       },
+       .capture = {
+               .rates          = AC97_RATES,
+               .formats        = AC97_FMTS,
+               .channels_min   = 2,
+               .channels_max   = 2,
+       },
+       .ops                    = &alchemy_ac97c_ops,
+};
+
+static int __devinit au1xac97c_drvprobe(struct platform_device *pdev)
+{
+       int ret;
+       struct resource *r;
+       struct au1xpsc_audio_data *ctx;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       mutex_init(&ctx->lock);
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               ret = -ENODEV;
+               goto out0;
+       }
+
+       ret = -EBUSY;
+       if (!request_mem_region(r->start, resource_size(r), pdev->name))
+               goto out0;
+
+       ctx->mmio = ioremap_nocache(r->start, resource_size(r));
+       if (!ctx->mmio)
+               goto out1;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!r)
+               goto out1;
+       ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (!r)
+               goto out1;
+       ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
+
+       /* switch it on */
+       WR(ctx, AC97_ENABLE, EN_D | EN_CE);
+       WR(ctx, AC97_ENABLE, EN_CE);
+
+       ctx->cfg = CFG_RC(3) | CFG_XS(3);
+       WR(ctx, AC97_CONFIG, ctx->cfg);
+
+       platform_set_drvdata(pdev, ctx);
+
+       ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver);
+       if (ret)
+               goto out1;
+
+       ac97c_workdata = ctx;
+       return 0;
+
+out1:
+       release_mem_region(r->start, resource_size(r));
+out0:
+       kfree(ctx);
+       return ret;
+}
+
+static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
+{
+       struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
+       struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       snd_soc_unregister_dai(&pdev->dev);
+
+       WR(ctx, AC97_ENABLE, EN_D);     /* clock off, disable */
+
+       iounmap(ctx->mmio);
+       release_mem_region(r->start, resource_size(r));
+       kfree(ctx);
+
+       ac97c_workdata = NULL;  /* MDEV */
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int au1xac97c_drvsuspend(struct device *dev)
+{
+       struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
+
+       WR(ctx, AC97_ENABLE, EN_D);     /* clock off, disable */
+
+       return 0;
+}
+
+static int au1xac97c_drvresume(struct device *dev)
+{
+       struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
+
+       WR(ctx, AC97_ENABLE, EN_D | EN_CE);
+       WR(ctx, AC97_ENABLE, EN_CE);
+       WR(ctx, AC97_CONFIG, ctx->cfg);
+
+       return 0;
+}
+
+static const struct dev_pm_ops au1xpscac97_pmops = {
+       .suspend        = au1xac97c_drvsuspend,
+       .resume         = au1xac97c_drvresume,
+};
+
+#define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops)
+
+#else
+
+#define AU1XPSCAC97_PMOPS NULL
+
+#endif
+
+static struct platform_driver au1xac97c_driver = {
+       .driver = {
+               .name   = "alchemy-ac97c",
+               .owner  = THIS_MODULE,
+               .pm     = AU1XPSCAC97_PMOPS,
+       },
+       .probe          = au1xac97c_drvprobe,
+       .remove         = __devexit_p(au1xac97c_drvremove),
+};
+
+static int __init au1xac97c_load(void)
+{
+       ac97c_workdata = NULL;
+       return platform_driver_register(&au1xac97c_driver);
+}
+
+static void __exit au1xac97c_unload(void)
+{
+       platform_driver_unregister(&au1xac97c_driver);
+}
+
+module_init(au1xac97c_load);
+module_exit(au1xac97c_unload);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
+MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
new file mode 100644 (file)
index 0000000..127477a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * DB1000/DB1500/DB1100 ASoC audio fabric support code.
+ *
+ * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "psc.h"
+
+static struct snd_soc_dai_link db1000_ac97_dai = {
+       .name           = "AC97",
+       .stream_name    = "AC97 HiFi",
+       .codec_dai_name = "ac97-hifi",
+       .cpu_dai_name   = "alchemy-ac97c",
+       .platform_name  = "alchemy-pcm-dma.0",
+       .codec_name     = "ac97-codec",
+};
+
+static struct snd_soc_card db1000_ac97 = {
+       .name           = "DB1000_AC97",
+       .dai_link       = &db1000_ac97_dai,
+       .num_links      = 1,
+};
+
+static int __devinit db1000_audio_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &db1000_ac97;
+       card->dev = &pdev->dev;
+       return snd_soc_register_card(card);
+}
+
+static int __devexit db1000_audio_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       snd_soc_unregister_card(card);
+       return 0;
+}
+
+static struct platform_driver db1000_audio_driver = {
+       .driver = {
+               .name   = "db1000-audio",
+               .owner  = THIS_MODULE,
+               .pm     = &snd_soc_pm_ops,
+       },
+       .probe          = db1000_audio_probe,
+       .remove         = __devexit_p(db1000_audio_remove),
+};
+
+static int __init db1000_audio_load(void)
+{
+       return platform_driver_register(&db1000_audio_driver);
+}
+
+static void __exit db1000_audio_unload(void)
+{
+       platform_driver_unregister(&db1000_audio_driver);
+}
+
+module_init(db1000_audio_load);
+module_exit(db1000_audio_unload);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
+MODULE_AUTHOR("Manuel Lauss");
index 1d3e258c9ea8ec861cf19c88a9bd7c99e5384940..289312c14b99bf62d13355e7ae5e585bf297991f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DB1200 ASoC audio fabric support code.
  *
- * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com>
+ * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com>
  *
  */
 
 #include "../codecs/wm8731.h"
 #include "psc.h"
 
+static struct platform_device_id db1200_pids[] = {
+       {
+               .name           = "db1200-ac97",
+               .driver_data    = 0,
+       }, {
+               .name           = "db1200-i2s",
+               .driver_data    = 1,
+       },
+       {},
+};
+
 /*-------------------------  AC97 PART  ---------------------------*/
 
 static struct snd_soc_dai_link db1200_ac97_dai = {
@@ -89,36 +100,47 @@ static struct snd_soc_card db1200_i2s_machine = {
 
 /*-------------------------  COMMON PART  ---------------------------*/
 
-static struct platform_device *db1200_asoc_dev;
+static struct snd_soc_card *db1200_cards[] __devinitdata = {
+       &db1200_ac97_machine,
+       &db1200_i2s_machine,
+};
 
-static int __init db1200_audio_load(void)
+static int __devinit db1200_audio_probe(struct platform_device *pdev)
 {
-       int ret;
+       const struct platform_device_id *pid = platform_get_device_id(pdev);
+       struct snd_soc_card *card;
 
-       ret = -ENOMEM;
-       db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */
-       if (!db1200_asoc_dev)
-               goto out;
+       card = db1200_cards[pid->driver_data];
+       card->dev = &pdev->dev;
+       return snd_soc_register_card(card);
+}
 
-       /* DB1200 board setup set PSC1MUX to preferred audio device */
-       if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX)
-               platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine);
-       else
-               platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine);
+static int __devexit db1200_audio_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       snd_soc_unregister_card(card);
+       return 0;
+}
 
-       ret = platform_device_add(db1200_asoc_dev);
+static struct platform_driver db1200_audio_driver = {
+       .driver = {
+               .name   = "db1200-ac97",
+               .owner  = THIS_MODULE,
+               .pm     = &snd_soc_pm_ops,
+       },
+       .id_table       = db1200_pids,
+       .probe          = db1200_audio_probe,
+       .remove         = __devexit_p(db1200_audio_remove),
+};
 
-       if (ret) {
-               platform_device_put(db1200_asoc_dev);
-               db1200_asoc_dev = NULL;
-       }
-out:
-       return ret;
+static int __init db1200_audio_load(void)
+{
+       return platform_driver_register(&db1200_audio_driver);
 }
 
 static void __exit db1200_audio_unload(void)
 {
-       platform_device_unregister(db1200_asoc_dev);
+       platform_driver_unregister(&db1200_audio_driver);
 }
 
 module_init(db1200_audio_load);
index 20bb53a837b152b7e207dfc691d59a76222d221f..d7d04e26eee504524f7952c86825b44c5d7a4fa7 100644 (file)
@@ -169,7 +169,7 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
 
        au1x_pcm_dbdma_free(pcd);
 
-       if (stype == PCM_RX)
+       if (stype == SNDRV_PCM_STREAM_CAPTURE)
                pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id,
                                        DSCR_CMD0_ALWAYS,
                                        au1x_pcm_dmarx_cb, (void *)pcd);
@@ -198,7 +198,7 @@ static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream
        struct snd_soc_pcm_runtime *rtd = ss->private_data;
        struct au1xpsc_audio_dmadata *pcd =
                                snd_soc_platform_get_drvdata(rtd->platform);
-       return &pcd[SUBSTREAM_TYPE(ss)];
+       return &pcd[ss->stream];
 }
 
 static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -212,7 +212,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                goto out;
 
-       stype = SUBSTREAM_TYPE(substream);
+       stype = substream->stream;
        pcd = to_dmadata(substream);
 
        DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d "
@@ -255,7 +255,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream)
 
        au1xxx_dbdma_reset(pcd->ddma_chan);
 
-       if (SUBSTREAM_TYPE(substream) == PCM_RX) {
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
                au1x_pcm_queue_rx(pcd);
                au1x_pcm_queue_rx(pcd);
        } else {
@@ -293,6 +293,16 @@ au1xpsc_pcm_pointer(struct snd_pcm_substream *substream)
 
 static int au1xpsc_pcm_open(struct snd_pcm_substream *substream)
 {
+       struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream);
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       int stype = substream->stream, *dmaids;
+
+       dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+       if (!dmaids)
+               return -ENODEV; /* whoa, has ordering changed? */
+
+       pcd->ddma_id = dmaids[stype];
+
        snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware);
        return 0;
 }
@@ -340,36 +350,18 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = {
 static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
 {
        struct au1xpsc_audio_dmadata *dmadata;
-       struct resource *r;
        int ret;
 
        dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL);
        if (!dmadata)
                return -ENOMEM;
 
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!r) {
-               ret = -ENODEV;
-               goto out1;
-       }
-       dmadata[PCM_TX].ddma_id = r->start;
-
-       /* RX DMA */
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (!r) {
-               ret = -ENODEV;
-               goto out1;
-       }
-       dmadata[PCM_RX].ddma_id = r->start;
-
        platform_set_drvdata(pdev, dmadata);
 
        ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
-       if (!ret)
-               return ret;
+       if (ret)
+               kfree(dmadata);
 
-out1:
-       kfree(dmadata);
        return ret;
 }
 
@@ -405,57 +397,6 @@ static void __exit au1xpsc_audio_dbdma_unload(void)
 module_init(au1xpsc_audio_dbdma_load);
 module_exit(au1xpsc_audio_dbdma_unload);
 
-
-struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
-{
-       struct resource *res, *r;
-       struct platform_device *pd;
-       int id[2];
-       int ret;
-
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!r)
-               return NULL;
-       id[0] = r->start;
-
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (!r)
-               return NULL;
-       id[1] = r->start;
-
-       res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
-       if (!res)
-               return NULL;
-
-       res[0].start = res[0].end = id[0];
-       res[1].start = res[1].end = id[1];
-       res[0].flags = res[1].flags = IORESOURCE_DMA;
-
-       pd = platform_device_alloc("au1xpsc-pcm", pdev->id);
-       if (!pd)
-               goto out;
-
-       pd->resource = res;
-       pd->num_resources = 2;
-
-       ret = platform_device_add(pd);
-       if (!ret)
-               return pd;
-
-       platform_device_put(pd);
-out:
-       kfree(res);
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
-
-void au1xpsc_pcm_destroy(struct platform_device *dmapd)
-{
-       if (dmapd)
-               platform_device_unregister(dmapd);
-}
-EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
 MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
new file mode 100644 (file)
index 0000000..7aa5b76
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * Au1000/Au1500/Au1100 Audio DMA support.
+ *
+ * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
+ *
+ * copied almost verbatim from the old ALSA driver, written by
+ *                     Charles Eidsness <charles@cooper-street.com>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
+
+#include "psc.h"
+
+#define ALCHEMY_PCM_FMTS                                       \
+       (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_U8 |        \
+        SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |    \
+        SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |    \
+        SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |    \
+        SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE |    \
+        0)
+
+struct pcm_period {
+       u32 start;
+       u32 relative_end;       /* relative to start of buffer */
+       struct pcm_period *next;
+};
+
+struct audio_stream {
+       struct snd_pcm_substream *substream;
+       int dma;
+       struct pcm_period *buffer;
+       unsigned int period_size;
+       unsigned int periods;
+};
+
+struct alchemy_pcm_ctx {
+       struct audio_stream stream[2];  /* playback & capture */
+};
+
+static void au1000_release_dma_link(struct audio_stream *stream)
+{
+       struct pcm_period *pointer;
+       struct pcm_period *pointer_next;
+
+       stream->period_size = 0;
+       stream->periods = 0;
+       pointer = stream->buffer;
+       if (!pointer)
+               return;
+       do {
+               pointer_next = pointer->next;
+               kfree(pointer);
+               pointer = pointer_next;
+       } while (pointer != stream->buffer);
+       stream->buffer = NULL;
+}
+
+static int au1000_setup_dma_link(struct audio_stream *stream,
+                                unsigned int period_bytes,
+                                unsigned int periods)
+{
+       struct snd_pcm_substream *substream = stream->substream;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct pcm_period *pointer;
+       unsigned long dma_start;
+       int i;
+
+       dma_start = virt_to_phys(runtime->dma_area);
+
+       if (stream->period_size == period_bytes &&
+           stream->periods == periods)
+               return 0; /* not changed */
+
+       au1000_release_dma_link(stream);
+
+       stream->period_size = period_bytes;
+       stream->periods = periods;
+
+       stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL);
+       if (!stream->buffer)
+               return -ENOMEM;
+       pointer = stream->buffer;
+       for (i = 0; i < periods; i++) {
+               pointer->start = (u32)(dma_start + (i * period_bytes));
+               pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
+               if (i < periods - 1) {
+                       pointer->next = kmalloc(sizeof(struct pcm_period),
+                                               GFP_KERNEL);
+                       if (!pointer->next) {
+                               au1000_release_dma_link(stream);
+                               return -ENOMEM;
+                       }
+                       pointer = pointer->next;
+               }
+       }
+       pointer->next = stream->buffer;
+       return 0;
+}
+
+static void au1000_dma_stop(struct audio_stream *stream)
+{
+       if (stream->buffer)
+               disable_dma(stream->dma);
+}
+
+static void au1000_dma_start(struct audio_stream *stream)
+{
+       if (!stream->buffer)
+               return;
+
+       init_dma(stream->dma);
+       if (get_dma_active_buffer(stream->dma) == 0) {
+               clear_dma_done0(stream->dma);
+               set_dma_addr0(stream->dma, stream->buffer->start);
+               set_dma_count0(stream->dma, stream->period_size >> 1);
+               set_dma_addr1(stream->dma, stream->buffer->next->start);
+               set_dma_count1(stream->dma, stream->period_size >> 1);
+       } else {
+               clear_dma_done1(stream->dma);
+               set_dma_addr1(stream->dma, stream->buffer->start);
+               set_dma_count1(stream->dma, stream->period_size >> 1);
+               set_dma_addr0(stream->dma, stream->buffer->next->start);
+               set_dma_count0(stream->dma, stream->period_size >> 1);
+       }
+       enable_dma_buffers(stream->dma);
+       start_dma(stream->dma);
+}
+
+static irqreturn_t au1000_dma_interrupt(int irq, void *ptr)
+{
+       struct audio_stream *stream = (struct audio_stream *)ptr;
+       struct snd_pcm_substream *substream = stream->substream;
+
+       switch (get_dma_buffer_done(stream->dma)) {
+       case DMA_D0:
+               stream->buffer = stream->buffer->next;
+               clear_dma_done0(stream->dma);
+               set_dma_addr0(stream->dma, stream->buffer->next->start);
+               set_dma_count0(stream->dma, stream->period_size >> 1);
+               enable_dma_buffer0(stream->dma);
+               break;
+       case DMA_D1:
+               stream->buffer = stream->buffer->next;
+               clear_dma_done1(stream->dma);
+               set_dma_addr1(stream->dma, stream->buffer->next->start);
+               set_dma_count1(stream->dma, stream->period_size >> 1);
+               enable_dma_buffer1(stream->dma);
+               break;
+       case (DMA_D0 | DMA_D1):
+               pr_debug("DMA %d missed interrupt.\n", stream->dma);
+               au1000_dma_stop(stream);
+               au1000_dma_start(stream);
+               break;
+       case (~DMA_D0 & ~DMA_D1):
+               pr_debug("DMA %d empty irq.\n", stream->dma);
+       }
+       snd_pcm_period_elapsed(substream);
+       return IRQ_HANDLED;
+}
+
+static const struct snd_pcm_hardware alchemy_pcm_hardware = {
+       .info             = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+                           SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
+       .formats          = ALCHEMY_PCM_FMTS,
+       .rates            = SNDRV_PCM_RATE_8000_192000,
+       .rate_min         = SNDRV_PCM_RATE_8000,
+       .rate_max         = SNDRV_PCM_RATE_192000,
+       .channels_min     = 2,
+       .channels_max     = 2,
+       .period_bytes_min = 1024,
+       .period_bytes_max = 16 * 1024 - 1,
+       .periods_min      = 4,
+       .periods_max      = 255,
+       .buffer_bytes_max = 128 * 1024,
+       .fifo_size        = 16,
+};
+
+static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
+{
+       struct snd_soc_pcm_runtime *rtd = ss->private_data;
+       return snd_soc_platform_get_drvdata(rtd->platform);
+}
+
+static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
+{
+       struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss);
+       return &(ctx->stream[ss->stream]);
+}
+
+static int alchemy_pcm_open(struct snd_pcm_substream *substream)
+{
+       struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       int *dmaids, s = substream->stream;
+       char *name;
+
+       dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+       if (!dmaids)
+               return -ENODEV; /* whoa, has ordering changed? */
+
+       /* DMA setup */
+       name = (s == SNDRV_PCM_STREAM_PLAYBACK) ? "audio-tx" : "audio-rx";
+       ctx->stream[s].dma = request_au1000_dma(dmaids[s], name,
+                                       au1000_dma_interrupt, IRQF_DISABLED,
+                                       &ctx->stream[s]);
+       set_dma_mode(ctx->stream[s].dma,
+                    get_dma_mode(ctx->stream[s].dma) & ~DMA_NC);
+
+       ctx->stream[s].substream = substream;
+       ctx->stream[s].buffer = NULL;
+       snd_soc_set_runtime_hwparams(substream, &alchemy_pcm_hardware);
+
+       return 0;
+}
+
+static int alchemy_pcm_close(struct snd_pcm_substream *substream)
+{
+       struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream);
+       int stype = substream->stream;
+
+       ctx->stream[stype].substream = NULL;
+       free_au1000_dma(ctx->stream[stype].dma);
+
+       return 0;
+}
+
+static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream,
+                                struct snd_pcm_hw_params *hw_params)
+{
+       struct audio_stream *stream = ss_to_as(substream);
+       int err;
+
+       err = snd_pcm_lib_malloc_pages(substream,
+                                      params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
+       err = au1000_setup_dma_link(stream,
+                                   params_period_bytes(hw_params),
+                                   params_periods(hw_params));
+       if (err)
+               snd_pcm_lib_free_pages(substream);
+
+       return err;
+}
+
+static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+       struct audio_stream *stream = ss_to_as(substream);
+       au1000_release_dma_link(stream);
+       return snd_pcm_lib_free_pages(substream);
+}
+
+static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct audio_stream *stream = ss_to_as(substream);
+       int err = 0;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               au1000_dma_start(stream);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               au1000_dma_stop(stream);
+               break;
+       default:
+               err = -EINVAL;
+               break;
+       }
+       return err;
+}
+
+static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss)
+{
+       struct audio_stream *stream = ss_to_as(ss);
+       long location;
+
+       location = get_dma_residue(stream->dma);
+       location = stream->buffer->relative_end - location;
+       if (location == -1)
+               location = 0;
+       return bytes_to_frames(ss->runtime, location);
+}
+
+static struct snd_pcm_ops alchemy_pcm_ops = {
+       .open                   = alchemy_pcm_open,
+       .close                  = alchemy_pcm_close,
+       .ioctl                  = snd_pcm_lib_ioctl,
+       .hw_params              = alchemy_pcm_hw_params,
+       .hw_free                = alchemy_pcm_hw_free,
+       .trigger                = alchemy_pcm_trigger,
+       .pointer                = alchemy_pcm_pointer,
+};
+
+static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm)
+{
+       snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_pcm *pcm = rtd->pcm;
+
+       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+               snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1);
+
+       return 0;
+}
+
+struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
+       .ops            = &alchemy_pcm_ops,
+       .pcm_new        = alchemy_pcm_new,
+       .pcm_free       = alchemy_pcm_free_dma_buffers,
+};
+
+static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
+{
+       struct alchemy_pcm_ctx *ctx;
+       int ret;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, ctx);
+
+       ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
+       if (ret)
+               kfree(ctx);
+
+       return ret;
+}
+
+static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
+{
+       struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev);
+
+       snd_soc_unregister_platform(&pdev->dev);
+       kfree(ctx);
+
+       return 0;
+}
+
+static struct platform_driver alchemy_pcmdma_driver = {
+       .driver = {
+               .name   = "alchemy-pcm-dma",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = alchemy_pcm_drvprobe,
+       .remove         = __devexit_p(alchemy_pcm_drvremove),
+};
+
+static int __init alchemy_pcmdma_load(void)
+{
+       return platform_driver_register(&alchemy_pcmdma_driver);
+}
+
+static void __exit alchemy_pcmdma_unload(void)
+{
+       platform_driver_unregister(&alchemy_pcmdma_driver);
+}
+
+module_init(alchemy_pcmdma_load);
+module_exit(alchemy_pcmdma_unload);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
+MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
new file mode 100644 (file)
index 0000000..19e0d2a
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Au1000/Au1500/Au1100 I2S controller driver for ASoC
+ *
+ * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
+ *
+ * Note: clock supplied to the I2S controller must be 256x samplerate.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include "psc.h"
+
+#define I2S_RXTX       0x00
+#define I2S_CFG                0x04
+#define I2S_ENABLE     0x08
+
+#define CFG_XU         (1 << 25)       /* tx underflow */
+#define CFG_XO         (1 << 24)
+#define CFG_RU         (1 << 23)
+#define CFG_RO         (1 << 22)
+#define CFG_TR         (1 << 21)
+#define CFG_TE         (1 << 20)
+#define CFG_TF         (1 << 19)
+#define CFG_RR         (1 << 18)
+#define CFG_RF         (1 << 17)
+#define CFG_ICK                (1 << 12)       /* clock invert */
+#define CFG_PD         (1 << 11)       /* set to make I2SDIO INPUT */
+#define CFG_LB         (1 << 10)       /* loopback */
+#define CFG_IC         (1 << 9)        /* word select invert */
+#define CFG_FM_I2S     (0 << 7)        /* I2S format */
+#define CFG_FM_LJ      (1 << 7)        /* left-justified */
+#define CFG_FM_RJ      (2 << 7)        /* right-justified */
+#define CFG_FM_MASK    (3 << 7)
+#define CFG_TN         (1 << 6)        /* tx fifo en */
+#define CFG_RN         (1 << 5)        /* rx fifo en */
+#define CFG_SZ_8       (0x08)
+#define CFG_SZ_16      (0x10)
+#define CFG_SZ_18      (0x12)
+#define CFG_SZ_20      (0x14)
+#define CFG_SZ_24      (0x18)
+#define CFG_SZ_MASK    (0x1f)
+#define EN_D           (1 << 1)        /* DISable */
+#define EN_CE          (1 << 0)        /* clock enable */
+
+/* only limited by clock generator and board design */
+#define AU1XI2SC_RATES \
+       SNDRV_PCM_RATE_CONTINUOUS
+
+#define AU1XI2SC_FMTS \
+       (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |            \
+       SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |     \
+       SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |     \
+       SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE |   \
+       SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE |   \
+       SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE |   \
+       SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE |   \
+       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |     \
+       SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE |     \
+       0)
+
+static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
+{
+       return __raw_readl(ctx->mmio + reg);
+}
+
+static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
+{
+       __raw_writel(v, ctx->mmio + reg);
+       wmb();
+}
+
+static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+       struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned long c;
+       int ret;
+
+       ret = -EINVAL;
+       c = ctx->cfg;
+
+       c &= ~CFG_FM_MASK;
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               c |= CFG_FM_I2S;
+               break;
+       case SND_SOC_DAIFMT_MSB:
+               c |= CFG_FM_RJ;
+               break;
+       case SND_SOC_DAIFMT_LSB:
+               c |= CFG_FM_LJ;
+               break;
+       default:
+               goto out;
+       }
+
+       c &= ~(CFG_IC | CFG_ICK);               /* IB-IF */
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               c |= CFG_IC | CFG_ICK;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               c |= CFG_IC;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               c |= CFG_ICK;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               break;
+       default:
+               goto out;
+       }
+
+       /* I2S controller only supports master */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:    /* CODEC slave */
+               break;
+       default:
+               goto out;
+       }
+
+       ret = 0;
+       ctx->cfg = c;
+out:
+       return ret;
+}
+
+static int au1xi2s_trigger(struct snd_pcm_substream *substream,
+                          int cmd, struct snd_soc_dai *dai)
+{
+       struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
+       int stype = SUBSTREAM_TYPE(substream);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+               /* power up */
+               WR(ctx, I2S_ENABLE, EN_D | EN_CE);
+               WR(ctx, I2S_ENABLE, EN_CE);
+               ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN;
+               WR(ctx, I2S_CFG, ctx->cfg);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+               ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN);
+               WR(ctx, I2S_CFG, ctx->cfg);
+               WR(ctx, I2S_ENABLE, EN_D);              /* power off */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned long msbits_to_reg(int msbits)
+{
+       switch (msbits) {
+       case 8:
+               return CFG_SZ_8;
+       case 16:
+               return CFG_SZ_16;
+       case 18:
+               return CFG_SZ_18;
+       case 20:
+               return CFG_SZ_20;
+       case 24:
+               return CFG_SZ_24;
+       }
+       return 0;
+}
+
+static int au1xi2s_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params,
+                            struct snd_soc_dai *dai)
+{
+       struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
+       unsigned long v;
+
+       v = msbits_to_reg(params->msbits);
+       if (!v)
+               return -EINVAL;
+
+       ctx->cfg &= ~CFG_SZ_MASK;
+       ctx->cfg |= v;
+       return 0;
+}
+
+static int au1xi2s_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
+{
+       struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
+       snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
+       return 0;
+}
+
+static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
+       .startup        = au1xi2s_startup,
+       .trigger        = au1xi2s_trigger,
+       .hw_params      = au1xi2s_hw_params,
+       .set_fmt        = au1xi2s_set_fmt,
+};
+
+static struct snd_soc_dai_driver au1xi2s_dai_driver = {
+       .symmetric_rates        = 1,
+       .playback = {
+               .rates          = AU1XI2SC_RATES,
+               .formats        = AU1XI2SC_FMTS,
+               .channels_min   = 2,
+               .channels_max   = 2,
+       },
+       .capture = {
+               .rates          = AU1XI2SC_RATES,
+               .formats        = AU1XI2SC_FMTS,
+               .channels_min   = 2,
+               .channels_max   = 2,
+       },
+       .ops = &au1xi2s_dai_ops,
+};
+
+static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
+{
+       int ret;
+       struct resource *r;
+       struct au1xpsc_audio_data *ctx;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               ret = -ENODEV;
+               goto out0;
+       }
+
+       ret = -EBUSY;
+       if (!request_mem_region(r->start, resource_size(r), pdev->name))
+               goto out0;
+
+       ctx->mmio = ioremap_nocache(r->start, resource_size(r));
+       if (!ctx->mmio)
+               goto out1;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!r)
+               goto out1;
+       ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (!r)
+               goto out1;
+       ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
+
+       platform_set_drvdata(pdev, ctx);
+
+       ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
+       if (ret)
+               goto out1;
+
+       return 0;
+
+out1:
+       release_mem_region(r->start, resource_size(r));
+out0:
+       kfree(ctx);
+       return ret;
+}
+
+static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
+{
+       struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
+       struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       snd_soc_unregister_dai(&pdev->dev);
+
+       WR(ctx, I2S_ENABLE, EN_D);      /* clock off, disable */
+
+       iounmap(ctx->mmio);
+       release_mem_region(r->start, resource_size(r));
+       kfree(ctx);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int au1xi2s_drvsuspend(struct device *dev)
+{
+       struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
+
+       WR(ctx, I2S_ENABLE, EN_D);      /* clock off, disable */
+
+       return 0;
+}
+
+static int au1xi2s_drvresume(struct device *dev)
+{
+       return 0;
+}
+
+static const struct dev_pm_ops au1xi2sc_pmops = {
+       .suspend        = au1xi2s_drvsuspend,
+       .resume         = au1xi2s_drvresume,
+};
+
+#define AU1XI2SC_PMOPS (&au1xi2sc_pmops)
+
+#else
+
+#define AU1XI2SC_PMOPS NULL
+
+#endif
+
+static struct platform_driver au1xi2s_driver = {
+       .driver = {
+               .name   = "alchemy-i2sc",
+               .owner  = THIS_MODULE,
+               .pm     = AU1XI2SC_PMOPS,
+       },
+       .probe          = au1xi2s_drvprobe,
+       .remove         = __devexit_p(au1xi2s_drvremove),
+};
+
+static int __init au1xi2s_load(void)
+{
+       return platform_driver_register(&au1xi2s_driver);
+}
+
+static void __exit au1xi2s_unload(void)
+{
+       platform_driver_unregister(&au1xi2s_driver);
+}
+
+module_init(au1xi2s_load);
+module_exit(au1xi2s_unload);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
+MODULE_AUTHOR("Manuel Lauss");
index d0db66f24a00cc0ce68f622161bef3b4155a7c82..172eefd38b2d411008fa527d5f66f92ebd8a55da 100644 (file)
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
 
 #define AC97PCR_START(stype)   \
-       ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
 #define AC97PCR_STOP(stype)    \
-       ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
 #define AC97PCR_CLRFIFO(stype) \
-       ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
 
 #define AC97STAT_BUSY(stype)   \
-       ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
 
 /* instance data. There can be only one, MacLeod!!!! */
 static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
@@ -215,7 +215,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
 {
        struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
        unsigned long r, ro, stat;
-       int chans, t, stype = SUBSTREAM_TYPE(substream);
+       int chans, t, stype = substream->stream;
 
        chans = params_channels(params);
 
@@ -235,7 +235,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
                r |= PSC_AC97CFG_SET_LEN(params->msbits);
 
                /* channels: enable slots for front L/R channel */
-               if (stype == PCM_TX) {
+               if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
                        r &= ~PSC_AC97CFG_TXSLOT_MASK;
                        r |= PSC_AC97CFG_TXSLOT_ENA(3);
                        r |= PSC_AC97CFG_TXSLOT_ENA(4);
@@ -294,7 +294,7 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
                                int cmd, struct snd_soc_dai *dai)
 {
        struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
-       int ret, stype = SUBSTREAM_TYPE(substream);
+       int ret, stype = substream->stream;
 
        ret = 0;
 
@@ -324,12 +324,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
        return ret;
 }
 
+static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
+       snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
+       return 0;
+}
+
 static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
 {
        return au1xpsc_ac97_workdata ? 0 : -ENODEV;
 }
 
 static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
+       .startup        = au1xpsc_ac97_startup,
        .trigger        = au1xpsc_ac97_trigger,
        .hw_params      = au1xpsc_ac97_hw_params,
 };
@@ -379,6 +388,16 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
        if (!wd->mmio)
                goto out1;
 
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!r)
+               goto out2;
+       wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (!r)
+               goto out2;
+       wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
+
        /* configuration: max dma trigger threshold, enable ac97 */
        wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
                  PSC_AC97CFG_DE_ENABLE;
@@ -401,15 +420,13 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
 
        ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
        if (ret)
-               goto out1;
+               goto out2;
 
-       wd->dmapd = au1xpsc_pcm_add(pdev);
-       if (wd->dmapd) {
-               au1xpsc_ac97_workdata = wd;
-               return 0;
-       }
+       au1xpsc_ac97_workdata = wd;
+       return 0;
 
-       snd_soc_unregister_dai(&pdev->dev);
+out2:
+       iounmap(wd->mmio);
 out1:
        release_mem_region(r->start, resource_size(r));
 out0:
@@ -422,9 +439,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
        struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
        struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       if (wd->dmapd)
-               au1xpsc_pcm_destroy(wd->dmapd);
-
        snd_soc_unregister_dai(&pdev->dev);
 
        /* disable PSC completely */
index fca091276320930e7f8abd230556dabbc392e2d7..7c5ae920544fd136b1620867ced48948021912ab 100644 (file)
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
 
 #define I2SSTAT_BUSY(stype)    \
-       ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB)
 #define I2SPCR_START(stype)    \
-       ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TS : PSC_I2SPCR_RS)
 #define I2SPCR_STOP(stype)     \
-       ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TP : PSC_I2SPCR_RP)
 #define I2SPCR_CLRFIFO(stype)  \
-       ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
+       ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TC : PSC_I2SPCR_RC)
 
 
 static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
@@ -240,7 +240,7 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                               struct snd_soc_dai *dai)
 {
        struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
-       int ret, stype = SUBSTREAM_TYPE(substream);
+       int ret, stype = substream->stream;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -257,7 +257,16 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
        return ret;
 }
 
+static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
+{
+       struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
+       snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
+       return 0;
+}
+
 static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
+       .startup        = au1xpsc_i2s_startup,
        .trigger        = au1xpsc_i2s_trigger,
        .hw_params      = au1xpsc_i2s_hw_params,
        .set_fmt        = au1xpsc_i2s_set_fmt,
@@ -304,6 +313,16 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
        if (!wd->mmio)
                goto out1;
 
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!r)
+               goto out2;
+       wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = r->start;
+
+       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (!r)
+               goto out2;
+       wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = r->start;
+
        /* preserve PSC clock source set up by platform (dev.platform_data
         * is already occupied by soc layer)
         */
@@ -330,15 +349,11 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
        platform_set_drvdata(pdev, wd);
 
        ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
-       if (ret)
-               goto out1;
-
-       /* finally add the DMA device for this PSC */
-       wd->dmapd = au1xpsc_pcm_add(pdev);
-       if (wd->dmapd)
+       if (!ret)
                return 0;
 
-       snd_soc_unregister_dai(&pdev->dev);
+out2:
+       iounmap(wd->mmio);
 out1:
        release_mem_region(r->start, resource_size(r));
 out0:
@@ -351,9 +366,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
        struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
        struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       if (wd->dmapd)
-               au1xpsc_pcm_destroy(wd->dmapd);
-
        snd_soc_unregister_dai(&pdev->dev);
 
        au_writel(0, I2S_CFG(wd));
index b30eadd422a7fb7aee4856e671d491d769d2c6ac..b16b2e02e0c9dec6dac5450ab922255059ee2283 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Au12x0/Au1550 PSC ALSA ASoC audio support.
+ * Alchemy ALSA ASoC audio support.
  *
- * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
+ * (c) 2007-2011 MSC Vertriebsges.m.b.H.,
  *     Manuel Lauss <manuel.lauss@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
 #ifndef _AU1X_PCM_H
 #define _AU1X_PCM_H
 
-/* DBDMA helpers */
-extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
-extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
-
 struct au1xpsc_audio_data {
        void __iomem *mmio;
 
@@ -27,15 +23,9 @@ struct au1xpsc_audio_data {
 
        unsigned long pm[2];
        struct mutex lock;
-       struct platform_device *dmapd;
+       int dmaids[2];
 };
 
-#define PCM_TX 0
-#define PCM_RX 1
-
-#define SUBSTREAM_TYPE(substream) \
-       ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX)
-
 /* easy access macros */
 #define PSC_CTRL(x)    ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET)
 #define PSC_SEL(x)     ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET)
index fe9d548a683705ae1627a7b4a005ca5adfb760cd..9f6bc55fc399301c60dd4603e17642cb92f26d9b 100644 (file)
@@ -27,6 +27,19 @@ config SND_SOC_BFIN_EVAL_ADAU1701
          board connected to one of the Blackfin evaluation boards like the
          BF5XX-STAMP or BF5XX-EZKIT.
 
+config SND_SOC_BFIN_EVAL_ADAU1373
+       tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
+       depends on SND_BF5XX_I2S && I2C
+       select SND_BF5XX_SOC_I2S
+       select SND_SOC_ADAU1373
+       help
+         Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
+         board connected to one of the Blackfin evaluation boards like the
+         BF5XX-STAMP or BF5XX-EZKIT.
+
+         Note: This driver assumes that first ADAU1373 DAI is connected to the
+         first SPORT port on the BF5XX board.
+
 config SND_SOC_BFIN_EVAL_ADAV80X
        tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
        depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
index 6018bf52a234f9592ae1b00d34243c83e9d113f4..1bf86ccaa8de2071f0bcce1bdec796a870eaa3e6 100644 (file)
@@ -21,6 +21,7 @@ snd-ad1980-objs := bf5xx-ad1980.o
 snd-ssm2602-objs := bf5xx-ssm2602.o
 snd-ad73311-objs := bf5xx-ad73311.o
 snd-ad193x-objs := bf5xx-ad193x.o
+snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
 snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
 snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
 
@@ -29,5 +30,6 @@ obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
 obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
 obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
 obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
+obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
 obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
 obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
index d6651c033cb711a35c69dcde2320c213e50a5f5b..a118a0fb9d818ebd65dad18bfc0c3459d625d565 100644 (file)
@@ -56,7 +56,7 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_rate(params)) {
        case 48000:
-               clk = 12288000;
+               clk = 24576000;
                break;
        }
 
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
new file mode 100644 (file)
index 0000000..8df2a3b
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
+ * evaluation boards.
+ *
+ * Copyright 2011 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "../codecs/adau1373.h"
+
+static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
+       SND_SOC_DAPM_LINE("Line In1", NULL),
+       SND_SOC_DAPM_LINE("Line In2", NULL),
+       SND_SOC_DAPM_LINE("Line In3", NULL),
+       SND_SOC_DAPM_LINE("Line In4", NULL),
+
+       SND_SOC_DAPM_LINE("Line Out1", NULL),
+       SND_SOC_DAPM_LINE("Line Out2", NULL),
+       SND_SOC_DAPM_LINE("Stereo Out", NULL),
+       SND_SOC_DAPM_HP("Headphone", NULL),
+       SND_SOC_DAPM_HP("Earpiece", NULL),
+       SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
+       { "AIN1L", NULL, "Line In1" },
+       { "AIN1R", NULL, "Line In1" },
+       { "AIN2L", NULL, "Line In2" },
+       { "AIN2R", NULL, "Line In2" },
+       { "AIN3L", NULL, "Line In3" },
+       { "AIN3R", NULL, "Line In3" },
+       { "AIN4L", NULL, "Line In4" },
+       { "AIN4R", NULL, "Line In4" },
+
+       /* MICBIAS can be connected via a jumper to the line-in jack, since w
+          don't know which one is going to be used, just power both. */
+       { "Line In1", NULL, "MICBIAS1" },
+       { "Line In2", NULL, "MICBIAS1" },
+       { "Line In3", NULL, "MICBIAS1" },
+       { "Line In4", NULL, "MICBIAS1" },
+       { "Line In1", NULL, "MICBIAS2" },
+       { "Line In2", NULL, "MICBIAS2" },
+       { "Line In3", NULL, "MICBIAS2" },
+       { "Line In4", NULL, "MICBIAS2" },
+
+       { "Line Out1", NULL, "LOUT1L" },
+       { "Line Out1", NULL, "LOUT1R" },
+       { "Line Out2", NULL, "LOUT2L" },
+       { "Line Out2", NULL, "LOUT2R" },
+       { "Headphone", NULL, "HPL" },
+       { "Headphone", NULL, "HPR" },
+       { "Earpiece", NULL, "EP" },
+       { "Speaker", NULL, "SPKL" },
+       { "Stereo Out", NULL, "SPKR" },
+};
+
+static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       int ret;
+       int pll_rate;
+
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+                       SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+       if (ret)
+               return ret;
+
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+                       SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
+       if (ret)
+               return ret;
+
+       switch (params_rate(params)) {
+       case 48000:
+       case 8000:
+       case 12000:
+       case 16000:
+       case 24000:
+       case 32000:
+               pll_rate = 48000 * 1024;
+               break;
+       case 44100:
+       case 7350:
+       case 11025:
+       case 14700:
+       case 22050:
+       case 29400:
+               pll_rate = 44100 * 1024;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
+                       ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
+       if (ret)
+               return ret;
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
+                       SND_SOC_CLOCK_IN);
+
+       return ret;
+}
+
+static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       unsigned int pll_rate = 48000 * 1024;
+       int ret;
+
+       ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
+                       ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
+       if (ret)
+               return ret;
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
+                       SND_SOC_CLOCK_IN);
+
+       return ret;
+}
+static struct snd_soc_ops bfin_eval_adau1373_ops = {
+       .hw_params = bfin_eval_adau1373_hw_params,
+};
+
+static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
+       .name = "adau1373",
+       .stream_name = "adau1373",
+       .cpu_dai_name = "bfin-i2s.0",
+       .codec_dai_name = "adau1373-aif1",
+       .platform_name = "bfin-i2s-pcm-audio",
+       .codec_name = "adau1373.0-001a",
+       .ops = &bfin_eval_adau1373_ops,
+       .init = bfin_eval_adau1373_codec_init,
+};
+
+static struct snd_soc_card bfin_eval_adau1373 = {
+       .name = "bfin-eval-adau1373",
+       .dai_link = &bfin_eval_adau1373_dai,
+       .num_links = 1,
+
+       .dapm_widgets           = bfin_eval_adau1373_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
+       .dapm_routes            = bfin_eval_adau1373_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
+};
+
+static int bfin_eval_adau1373_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &bfin_eval_adau1373;
+
+       card->dev = &pdev->dev;
+
+       return snd_soc_register_card(&bfin_eval_adau1373);
+}
+
+static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+       snd_soc_unregister_card(card);
+
+       return 0;
+}
+
+static struct platform_driver bfin_eval_adau1373_driver = {
+       .driver = {
+               .name = "bfin-eval-adau1373",
+               .owner = THIS_MODULE,
+               .pm = &snd_soc_pm_ops,
+       },
+       .probe = bfin_eval_adau1373_probe,
+       .remove = __devexit_p(bfin_eval_adau1373_remove),
+};
+
+static int __init bfin_eval_adau1373_init(void)
+{
+       return platform_driver_register(&bfin_eval_adau1373_driver);
+}
+module_init(bfin_eval_adau1373_init);
+
+static void __exit bfin_eval_adau1373_exit(void)
+{
+       platform_driver_unregister(&bfin_eval_adau1373_driver);
+}
+module_exit(bfin_eval_adau1373_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bfin-eval-adau1373");
index 665d9240c4ae46e7005a46484598333052a752d3..71b46c8f70d784ad89b17ba7bd80358914c11f82 100644 (file)
@@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
        select SND_SOC_AD1980 if SND_SOC_AC97_BUS
        select SND_SOC_AD73311
+       select SND_SOC_ADAU1373 if I2C
        select SND_SOC_ADAV80X
        select SND_SOC_ADS117X
        select SND_SOC_AK4104 if SPI_MASTER
@@ -139,6 +140,9 @@ config SND_SOC_ADAU1701
        select SIGMA
        tristate
 
+config SND_SOC_ADAU1373
+       tristate
+
 config SND_SOC_ADAV80X
        tristate
 
index 5119a7e2c1a843b438ebed2865723f836c60b152..70c1769acd1530e68535e60b0d90781e77581517 100644 (file)
@@ -5,6 +5,7 @@ snd-soc-ad193x-objs := ad193x.o
 snd-soc-ad1980-objs := ad1980.o
 snd-soc-ad73311-objs := ad73311.o
 snd-soc-adau1701-objs := adau1701.o
+snd-soc-adau1373-objs := adau1373.o
 snd-soc-adav80x-objs := adav80x.o
 snd-soc-ads117x-objs := ads117x.o
 snd-soc-ak4104-objs := ak4104.o
@@ -100,6 +101,7 @@ obj-$(CONFIG_SND_SOC_AD1836)        += snd-soc-ad1836.o
 obj-$(CONFIG_SND_SOC_AD193X)   += snd-soc-ad193x.o
 obj-$(CONFIG_SND_SOC_AD1980)   += snd-soc-ad1980.o
 obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
+obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
 obj-$(CONFIG_SND_SOC_ADAU1701)  += snd-soc-adau1701.o
 obj-$(CONFIG_SND_SOC_ADAV80X)  += snd-soc-adav80x.o
 obj-$(CONFIG_SND_SOC_ADS117X)  += snd-soc-ads117x.o
index 2374ca5ffe68bacc6c37db16be249858fb17fad2..eedb6f5e5823499919e14611db21a747a2a023b6 100644 (file)
@@ -27,11 +27,6 @@ struct ad193x_priv {
        int sysclk;
 };
 
-/* ad193x register cache & default register settings */
-static const u8 ad193x_reg[AD193X_NUM_REGS] = {
-       0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
-};
-
 /*
  * AD193X volume/mute/de-emphasis etc. controls
  */
@@ -307,7 +302,8 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
        snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
 
        reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
-       reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
+       reg = (reg & (~AD193X_DAC_WORD_LEN_MASK))
+               | (word_len << AD193X_DAC_WORD_LEN_SHFT);
        snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
 
        reg = snd_soc_read(codec, AD193X_ADC_CTRL1);
@@ -389,9 +385,6 @@ static int ad193x_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
        .probe =        ad193x_probe,
-       .reg_cache_default = ad193x_reg,
-       .reg_cache_size = AD193X_NUM_REGS,
-       .reg_word_size = sizeof(u16),
 };
 
 #if defined(CONFIG_SPI_MASTER)
index 9747b54978775cd43fe5d5af4f0234670ba2ff2f..cccc2e8e5fbd3e830a3a402ed565a2c981ad7f2b 100644 (file)
@@ -34,7 +34,8 @@
 #define AD193X_DAC_LEFT_HIGH    (1 << 3)
 #define AD193X_DAC_BCLK_INV     (1 << 7)
 #define AD193X_DAC_CTRL2        0x804
-#define AD193X_DAC_WORD_LEN_MASK       0xC
+#define AD193X_DAC_WORD_LEN_SHFT        3
+#define AD193X_DAC_WORD_LEN_MASK        0x18
 #define AD193X_DAC_MASTER_MUTE  1
 #define AD193X_DAC_CHNL_MUTE    0x805
 #define AD193X_DACL1_MUTE       0
@@ -63,7 +64,7 @@
 #define AD193X_ADC_CTRL1        0x80f
 #define AD193X_ADC_SERFMT_MASK         0x60
 #define AD193X_ADC_SERFMT_STEREO       (0 << 5)
-#define AD193X_ADC_SERFMT_TDM          (1 << 2)
+#define AD193X_ADC_SERFMT_TDM          (1 << 5)
 #define AD193X_ADC_SERFMT_AUX          (2 << 5)
 #define AD193X_ADC_WORD_LEN_MASK       0x3
 #define AD193X_ADC_CTRL2        0x810
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
new file mode 100644 (file)
index 0000000..2aa40c3
--- /dev/null
@@ -0,0 +1,1414 @@
+/*
+ * Analog Devices ADAU1373 Audio Codec drive
+ *
+ * Copyright 2011 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/gcd.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/adau1373.h>
+
+#include "adau1373.h"
+
+struct adau1373_dai {
+       unsigned int clk_src;
+       unsigned int sysclk;
+       bool enable_src;
+       bool master;
+};
+
+struct adau1373 {
+       struct adau1373_dai dais[3];
+};
+
+#define ADAU1373_INPUT_MODE    0x00
+#define ADAU1373_AINL_CTRL(x)  (0x01 + (x) * 2)
+#define ADAU1373_AINR_CTRL(x)  (0x02 + (x) * 2)
+#define ADAU1373_LLINE_OUT(x)  (0x9 + (x) * 2)
+#define ADAU1373_RLINE_OUT(x)  (0xa + (x) * 2)
+#define ADAU1373_LSPK_OUT      0x0d
+#define ADAU1373_RSPK_OUT      0x0e
+#define ADAU1373_LHP_OUT       0x0f
+#define ADAU1373_RHP_OUT       0x10
+#define ADAU1373_ADC_GAIN      0x11
+#define ADAU1373_LADC_MIXER    0x12
+#define ADAU1373_RADC_MIXER    0x13
+#define ADAU1373_LLINE1_MIX    0x14
+#define ADAU1373_RLINE1_MIX    0x15
+#define ADAU1373_LLINE2_MIX    0x16
+#define ADAU1373_RLINE2_MIX    0x17
+#define ADAU1373_LSPK_MIX      0x18
+#define ADAU1373_RSPK_MIX      0x19
+#define ADAU1373_LHP_MIX       0x1a
+#define ADAU1373_RHP_MIX       0x1b
+#define ADAU1373_EP_MIX                0x1c
+#define ADAU1373_HP_CTRL       0x1d
+#define ADAU1373_HP_CTRL2      0x1e
+#define ADAU1373_LS_CTRL       0x1f
+#define ADAU1373_EP_CTRL       0x21
+#define ADAU1373_MICBIAS_CTRL1 0x22
+#define ADAU1373_MICBIAS_CTRL2 0x23
+#define ADAU1373_OUTPUT_CTRL   0x24
+#define ADAU1373_PWDN_CTRL1    0x25
+#define ADAU1373_PWDN_CTRL2    0x26
+#define ADAU1373_PWDN_CTRL3    0x27
+#define ADAU1373_DPLL_CTRL(x)  (0x28 + (x) * 7)
+#define ADAU1373_PLL_CTRL1(x)  (0x29 + (x) * 7)
+#define ADAU1373_PLL_CTRL2(x)  (0x2a + (x) * 7)
+#define ADAU1373_PLL_CTRL3(x)  (0x2b + (x) * 7)
+#define ADAU1373_PLL_CTRL4(x)  (0x2c + (x) * 7)
+#define ADAU1373_PLL_CTRL5(x)  (0x2d + (x) * 7)
+#define ADAU1373_PLL_CTRL6(x)  (0x2e + (x) * 7)
+#define ADAU1373_PLL_CTRL7(x)  (0x2f + (x) * 7)
+#define ADAU1373_HEADDECT      0x36
+#define ADAU1373_ADC_DAC_STATUS        0x37
+#define ADAU1373_ADC_CTRL      0x3c
+#define ADAU1373_DAI(x)                (0x44 + (x))
+#define ADAU1373_CLK_SRC_DIV(x)        (0x40 + (x) * 2)
+#define ADAU1373_BCLKDIV(x)    (0x47 + (x))
+#define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2)
+#define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2)
+#define ADAU1373_DEEMP_CTRL    0x50
+#define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x))
+#define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x))
+#define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x))
+#define ADAU1373_DAI_PBL_VOL(x)        (0x62 + (x) * 2)
+#define ADAU1373_DAI_PBR_VOL(x)        (0x63 + (x) * 2)
+#define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2)
+#define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2)
+#define ADAU1373_DAC1_PBL_VOL  0x6e
+#define ADAU1373_DAC1_PBR_VOL  0x6f
+#define ADAU1373_DAC2_PBL_VOL  0x70
+#define ADAU1373_DAC2_PBR_VOL  0x71
+#define ADAU1373_ADC_RECL_VOL  0x72
+#define ADAU1373_ADC_RECR_VOL  0x73
+#define ADAU1373_DMIC_RECL_VOL 0x74
+#define ADAU1373_DMIC_RECR_VOL 0x75
+#define ADAU1373_VOL_GAIN1     0x76
+#define ADAU1373_VOL_GAIN2     0x77
+#define ADAU1373_VOL_GAIN3     0x78
+#define ADAU1373_HPF_CTRL      0x7d
+#define ADAU1373_BASS1         0x7e
+#define ADAU1373_BASS2         0x7f
+#define ADAU1373_DRC(x)                (0x80 + (x) * 0x10)
+#define ADAU1373_3D_CTRL1      0xc0
+#define ADAU1373_3D_CTRL2      0xc1
+#define ADAU1373_FDSP_SEL1     0xdc
+#define ADAU1373_FDSP_SEL2     0xdd
+#define ADAU1373_FDSP_SEL3     0xde
+#define ADAU1373_FDSP_SEL4     0xdf
+#define ADAU1373_DIGMICCTRL    0xe2
+#define ADAU1373_DIGEN         0xeb
+#define ADAU1373_SOFT_RESET    0xff
+
+
+#define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1)
+#define ADAU1373_PLL_CTRL6_PLL_EN      BIT(0)
+
+#define ADAU1373_DAI_INVERT_BCLK       BIT(7)
+#define ADAU1373_DAI_MASTER            BIT(6)
+#define ADAU1373_DAI_INVERT_LRCLK      BIT(4)
+#define ADAU1373_DAI_WLEN_16           0x0
+#define ADAU1373_DAI_WLEN_20           0x4
+#define ADAU1373_DAI_WLEN_24           0x8
+#define ADAU1373_DAI_WLEN_32           0xc
+#define ADAU1373_DAI_WLEN_MASK         0xc
+#define ADAU1373_DAI_FORMAT_RIGHT_J    0x0
+#define ADAU1373_DAI_FORMAT_LEFT_J     0x1
+#define ADAU1373_DAI_FORMAT_I2S                0x2
+#define ADAU1373_DAI_FORMAT_DSP                0x3
+
+#define ADAU1373_BCLKDIV_SOURCE                BIT(5)
+#define ADAU1373_BCLKDIV_32            0x03
+#define ADAU1373_BCLKDIV_64            0x02
+#define ADAU1373_BCLKDIV_128           0x01
+#define ADAU1373_BCLKDIV_256           0x00
+
+#define ADAU1373_ADC_CTRL_PEAK_DETECT  BIT(0)
+#define ADAU1373_ADC_CTRL_RESET                BIT(1)
+#define ADAU1373_ADC_CTRL_RESET_FORCE  BIT(2)
+
+#define ADAU1373_OUTPUT_CTRL_LDIFF     BIT(3)
+#define ADAU1373_OUTPUT_CTRL_LNFBEN    BIT(2)
+
+#define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0)
+
+#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4
+#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2
+
+static const uint8_t adau1373_default_regs[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */
+       0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */
+       0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
+       0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */
+       0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
+       0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */
+       0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */
+       0x00, 0x1f, 0x0f, 0x00, 0x00,
+};
+
+static const unsigned int adau1373_out_tlv[] = {
+       TLV_DB_RANGE_HEAD(4),
+       0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
+       8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
+       16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
+       24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
+};
+
+static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0);
+static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1);
+static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1);
+
+static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0);
+static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0);
+static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0);
+
+static const char *adau1373_fdsp_sel_text[] = {
+       "None",
+       "Channel 1",
+       "Channel 2",
+       "Channel 3",
+       "Channel 4",
+       "Channel 5",
+};
+
+static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum,
+       ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum,
+       ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum,
+       ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum,
+       ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum,
+       ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text);
+
+static const char *adau1373_hpf_cutoff_text[] = {
+       "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz",
+       "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz",
+       "800Hz",
+};
+
+static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum,
+       ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text);
+
+static const char *adau1373_bass_lpf_cutoff_text[] = {
+       "801Hz", "1001Hz",
+};
+
+static const char *adau1373_bass_clip_level_text[] = {
+       "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875",
+};
+
+static const unsigned int adau1373_bass_clip_level_values[] = {
+       1, 2, 3, 4, 5, 6, 7,
+};
+
+static const char *adau1373_bass_hpf_cutoff_text[] = {
+       "158Hz", "232Hz", "347Hz", "520Hz",
+};
+
+static const unsigned int adau1373_bass_tlv[] = {
+       TLV_DB_RANGE_HEAD(4),
+       0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
+       3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
+       5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
+};
+
+static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum,
+       ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text);
+
+static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum,
+       ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text,
+       adau1373_bass_clip_level_values);
+
+static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum,
+       ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text);
+
+static const char *adau1373_3d_level_text[] = {
+       "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%",
+       "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%",
+       "80%", "86.67", "99.33%", "100%"
+};
+
+static const char *adau1373_3d_cutoff_text[] = {
+       "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs",
+       "0.16875 fs", "0.27083 fs"
+};
+
+static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum,
+       ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum,
+       ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text);
+
+static const unsigned int adau1373_3d_tlv[] = {
+       TLV_DB_RANGE_HEAD(2),
+       0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+       1, 7, TLV_DB_LINEAR_ITEM(-1800, -120),
+};
+
+static const char *adau1373_lr_mux_text[] = {
+       "Mute",
+       "Right Channel (L+R)",
+       "Left Channel (L+R)",
+       "Stereo",
+};
+
+static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum,
+       ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum,
+       ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text);
+static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum,
+       ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text);
+
+static const struct snd_kcontrol_new adau1373_controls[] = {
+       SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0),
+               ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
+       SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1),
+               ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
+       SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2),
+               ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
+
+       SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL,
+               ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
+       SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL,
+               ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
+
+       SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0),
+               ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv),
+       SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1),
+               ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv),
+       SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2),
+               ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv),
+
+       SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL,
+               ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL,
+               ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv),
+
+       SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0),
+               ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv),
+       SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT,
+               ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv),
+       SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT,
+               ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv),
+
+       SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0),
+               ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv),
+       SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1),
+               ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv),
+       SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2),
+               ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv),
+       SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3),
+               ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv),
+
+       SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0,
+               adau1373_ep_tlv),
+
+       SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3,
+               1, 0, adau1373_gain_boost_tlv),
+       SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1,
+               1, 0, adau1373_gain_boost_tlv),
+
+       SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4,
+               1, 0, adau1373_input_boost_tlv),
+       SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5,
+               1, 0, adau1373_input_boost_tlv),
+       SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6,
+               1, 0, adau1373_input_boost_tlv),
+       SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7,
+               1, 0, adau1373_input_boost_tlv),
+
+       SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3,
+               1, 0, adau1373_speaker_boost_tlv),
+
+       SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum),
+       SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum),
+
+       SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum),
+       SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0),
+       SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum),
+
+       SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum),
+       SOC_VALUE_ENUM("Bass Clip Level Threshold",
+           adau1373_bass_clip_level_enum),
+       SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum),
+       SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0),
+       SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0,
+           adau1373_bass_tlv),
+       SOC_ENUM("Bass Channel", adau1373_bass_channel_enum),
+
+       SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum),
+       SOC_ENUM("3D Level", adau1373_3d_level_enum),
+       SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0),
+       SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0,
+               adau1373_3d_tlv),
+       SOC_ENUM("3D Channel", adau1373_bass_channel_enum),
+
+       SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new adau1373_lineout2_controls[] = {
+       SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1),
+               ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv),
+       SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum),
+};
+
+static const struct snd_kcontrol_new adau1373_drc_controls[] = {
+       SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum),
+       SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum),
+       SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum),
+};
+
+static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       unsigned int pll_id = w->name[3] - '1';
+       unsigned int val;
+
+       if (SND_SOC_DAPM_EVENT_ON(event))
+               val = ADAU1373_PLL_CTRL6_PLL_EN;
+       else
+               val = 0;
+
+       snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
+               ADAU1373_PLL_CTRL6_PLL_EN, val);
+
+       if (SND_SOC_DAPM_EVENT_ON(event))
+               mdelay(5);
+
+       return 0;
+}
+
+static const char *adau1373_decimator_text[] = {
+       "ADC",
+       "DMIC1",
+};
+
+static const struct soc_enum adau1373_decimator_enum =
+       SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text);
+
+static const struct snd_kcontrol_new adau1373_decimator_mux =
+       SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum);
+
+static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = {
+       SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0),
+       SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0),
+       SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0),
+       SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0),
+       SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = {
+       SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0),
+       SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0),
+       SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0),
+       SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0),
+       SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0),
+};
+
+#define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \
+const struct snd_kcontrol_new _name[] = { \
+       SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \
+       SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \
+       SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \
+       SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \
+       SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \
+       SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \
+       SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \
+       SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \
+}
+
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls,
+       ADAU1373_LLINE1_MIX);
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls,
+       ADAU1373_RLINE1_MIX);
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls,
+       ADAU1373_LLINE2_MIX);
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls,
+       ADAU1373_RLINE2_MIX);
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls,
+       ADAU1373_LSPK_MIX);
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls,
+       ADAU1373_RSPK_MIX);
+static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls,
+       ADAU1373_EP_MIX);
+
+static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0),
+       SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0),
+       SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0),
+       SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0),
+       SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0),
+       SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0),
+       SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0),
+       SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0),
+       SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0),
+       SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0),
+       SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0),
+};
+
+#define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \
+const struct snd_kcontrol_new _name[] = { \
+       SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \
+       SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \
+       SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \
+       SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \
+       SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \
+       SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \
+       SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \
+}
+
+static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls,
+       ADAU1373_DIN_MIX_CTRL(0));
+static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls,
+       ADAU1373_DIN_MIX_CTRL(1));
+static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls,
+       ADAU1373_DIN_MIX_CTRL(2));
+static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls,
+       ADAU1373_DIN_MIX_CTRL(3));
+static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls,
+       ADAU1373_DIN_MIX_CTRL(4));
+
+#define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \
+const struct snd_kcontrol_new _name[] = { \
+       SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \
+       SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \
+       SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \
+       SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \
+       SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \
+}
+
+static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls,
+       ADAU1373_DOUT_MIX_CTRL(0));
+static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls,
+       ADAU1373_DOUT_MIX_CTRL(1));
+static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls,
+       ADAU1373_DOUT_MIX_CTRL(2));
+static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls,
+       ADAU1373_DOUT_MIX_CTRL(3));
+static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls,
+       ADAU1373_DOUT_MIX_CTRL(4));
+
+static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
+       /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that
+        * doesn't seem to be the case. */
+       SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0),
+       SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0),
+
+       SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0),
+       SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0),
+
+       SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0,
+               &adau1373_decimator_mux),
+
+       SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0),
+
+       SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0),
+       SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0),
+       SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0),
+       SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0),
+
+       SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_left_adc_mixer_controls),
+       SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_right_adc_mixer_controls),
+
+       SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0,
+               adau1373_left_line2_mixer_controls),
+       SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0,
+               adau1373_right_line2_mixer_controls),
+       SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0,
+               adau1373_left_line1_mixer_controls),
+       SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0,
+               adau1373_right_line1_mixer_controls),
+
+       SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0,
+               adau1373_ep_mixer_controls),
+       SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0,
+               adau1373_left_spk_mixer_controls),
+       SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0,
+               adau1373_right_spk_mixer_controls),
+       SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_left_hp_mixer_controls),
+       SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_right_hp_mixer_controls),
+       SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0,
+               NULL, 0),
+
+       SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0,
+           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0,
+           NULL, 0),
+
+       SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
+
+       SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dsp_channel1_mixer_controls),
+       SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dsp_channel2_mixer_controls),
+       SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dsp_channel3_mixer_controls),
+       SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dsp_channel4_mixer_controls),
+       SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dsp_channel5_mixer_controls),
+
+       SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_aif1_mixer_controls),
+       SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_aif2_mixer_controls),
+       SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_aif3_mixer_controls),
+       SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dac1_mixer_controls),
+       SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0,
+               adau1373_dac2_mixer_controls),
+
+       SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
+               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event,
+               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0),
+
+       SND_SOC_DAPM_INPUT("AIN1L"),
+       SND_SOC_DAPM_INPUT("AIN1R"),
+       SND_SOC_DAPM_INPUT("AIN2L"),
+       SND_SOC_DAPM_INPUT("AIN2R"),
+       SND_SOC_DAPM_INPUT("AIN3L"),
+       SND_SOC_DAPM_INPUT("AIN3R"),
+       SND_SOC_DAPM_INPUT("AIN4L"),
+       SND_SOC_DAPM_INPUT("AIN4R"),
+
+       SND_SOC_DAPM_INPUT("DMIC1DAT"),
+       SND_SOC_DAPM_INPUT("DMIC2DAT"),
+
+       SND_SOC_DAPM_OUTPUT("LOUT1L"),
+       SND_SOC_DAPM_OUTPUT("LOUT1R"),
+       SND_SOC_DAPM_OUTPUT("LOUT2L"),
+       SND_SOC_DAPM_OUTPUT("LOUT2R"),
+       SND_SOC_DAPM_OUTPUT("HPL"),
+       SND_SOC_DAPM_OUTPUT("HPR"),
+       SND_SOC_DAPM_OUTPUT("SPKL"),
+       SND_SOC_DAPM_OUTPUT("SPKR"),
+       SND_SOC_DAPM_OUTPUT("EP"),
+};
+
+static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
+       struct snd_soc_dapm_widget *sink)
+{
+       struct snd_soc_codec *codec = source->codec;
+       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       unsigned int dai;
+       const char *clk;
+
+       dai = sink->name[3] - '1';
+
+       if (!adau1373->dais[dai].master)
+               return 0;
+
+       if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1)
+               clk = "SYSCLK1";
+       else
+               clk = "SYSCLK2";
+
+       return strcmp(source->name, clk) == 0;
+}
+
+static int adau1373_check_src(struct snd_soc_dapm_widget *source,
+       struct snd_soc_dapm_widget *sink)
+{
+       struct snd_soc_codec *codec = source->codec;
+       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       unsigned int dai;
+
+       dai = sink->name[3] - '1';
+
+       return adau1373->dais[dai].enable_src;
+}
+
+#define DSP_CHANNEL_MIXER_ROUTES(_sink) \
+       { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \
+       { _sink, "DMIC2 Switch", "DMIC2" }, \
+       { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \
+       { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \
+       { _sink, "AIF1 Switch", "AIF1 IN" }, \
+       { _sink, "AIF2 Switch", "AIF2 IN" }, \
+       { _sink, "AIF3 Switch", "AIF3 IN" }
+
+#define DSP_OUTPUT_MIXER_ROUTES(_sink) \
+       { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \
+       { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \
+       { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \
+       { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \
+       { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" }
+
+#define LEFT_OUTPUT_MIXER_ROUTES(_sink) \
+       { _sink, "Right DAC2 Switch", "Right DAC2" }, \
+       { _sink, "Left DAC2 Switch", "Left DAC2" }, \
+       { _sink, "Right DAC1 Switch", "Right DAC1" }, \
+       { _sink, "Left DAC1 Switch", "Left DAC1" }, \
+       { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
+       { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
+       { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
+       { _sink, "Input 4 Bypass Switch", "IN4PGA" }
+
+#define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \
+       { _sink, "Right DAC2 Switch", "Right DAC2" }, \
+       { _sink, "Left DAC2 Switch", "Left DAC2" }, \
+       { _sink, "Right DAC1 Switch", "Right DAC1" }, \
+       { _sink, "Left DAC1 Switch", "Left DAC1" }, \
+       { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \
+       { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \
+       { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \
+       { _sink, "Input 4 Bypass Switch", "IN4PGA" }
+
+static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
+       { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" },
+       { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" },
+       { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" },
+       { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" },
+       { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" },
+
+       { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" },
+       { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" },
+       { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" },
+       { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" },
+       { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" },
+
+       { "Left ADC", NULL, "Left ADC Mixer" },
+       { "Right ADC", NULL, "Right ADC Mixer" },
+
+       { "Decimator Mux", "ADC", "Left ADC" },
+       { "Decimator Mux", "ADC", "Right ADC" },
+       { "Decimator Mux", "DMIC1", "DMIC1" },
+
+       DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"),
+       DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"),
+       DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"),
+       DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"),
+       DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"),
+
+       DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"),
+       DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"),
+       DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"),
+       DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"),
+       DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"),
+
+       { "AIF1 OUT", NULL, "AIF1 Mixer" },
+       { "AIF2 OUT", NULL, "AIF2 Mixer" },
+       { "AIF3 OUT", NULL, "AIF3 Mixer" },
+       { "Left DAC1", NULL, "DAC1 Mixer" },
+       { "Right DAC1", NULL, "DAC1 Mixer" },
+       { "Left DAC2", NULL, "DAC2 Mixer" },
+       { "Right DAC2", NULL, "DAC2 Mixer" },
+
+       LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"),
+       RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"),
+       LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"),
+       RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"),
+       LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"),
+       RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"),
+
+       { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" },
+       { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" },
+       { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
+       { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
+       { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
+       { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
+       { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" },
+       { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" },
+       { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" },
+       { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" },
+       { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" },
+       { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" },
+
+       { "Left Headphone Mixer", NULL, "Headphone Enable" },
+       { "Right Headphone Mixer", NULL, "Headphone Enable" },
+
+       { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" },
+       { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" },
+       { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" },
+       { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" },
+       { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" },
+       { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" },
+       { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" },
+       { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" },
+
+       { "LOUT1L", NULL, "Left Lineout1 Mixer" },
+       { "LOUT1R", NULL, "Right Lineout1 Mixer" },
+       { "LOUT2L", NULL, "Left Lineout2 Mixer" },
+       { "LOUT2R", NULL, "Right Lineout2 Mixer" },
+       { "SPKL", NULL, "Left Speaker Mixer" },
+       { "SPKR", NULL, "Right Speaker Mixer" },
+       { "HPL", NULL, "Left Headphone Mixer" },
+       { "HPR", NULL, "Right Headphone Mixer" },
+       { "EP", NULL, "Earpiece Mixer" },
+
+       { "IN1PGA", NULL, "AIN1L" },
+       { "IN2PGA", NULL, "AIN2L" },
+       { "IN3PGA", NULL, "AIN3L" },
+       { "IN4PGA", NULL, "AIN4L" },
+       { "IN1PGA", NULL, "AIN1R" },
+       { "IN2PGA", NULL, "AIN2R" },
+       { "IN3PGA", NULL, "AIN3R" },
+       { "IN4PGA", NULL, "AIN4R" },
+
+       { "SYSCLK1", NULL, "PLL1" },
+       { "SYSCLK2", NULL, "PLL2" },
+
+       { "Left DAC1", NULL, "SYSCLK1" },
+       { "Right DAC1", NULL, "SYSCLK1" },
+       { "Left DAC2", NULL, "SYSCLK1" },
+       { "Right DAC2", NULL, "SYSCLK1" },
+       { "Left ADC", NULL, "SYSCLK1" },
+       { "Right ADC", NULL, "SYSCLK1" },
+
+       { "DSP", NULL, "SYSCLK1" },
+
+       { "AIF1 Mixer", NULL, "DSP" },
+       { "AIF2 Mixer", NULL, "DSP" },
+       { "AIF3 Mixer", NULL, "DSP" },
+       { "DAC1 Mixer", NULL, "DSP" },
+       { "DAC2 Mixer", NULL, "DSP" },
+       { "DAC1 Mixer", NULL, "Playback Engine A" },
+       { "DAC2 Mixer", NULL, "Playback Engine B" },
+       { "Left ADC Mixer", NULL, "Recording Engine A" },
+       { "Right ADC Mixer", NULL, "Recording Engine A" },
+
+       { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
+       { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
+       { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk },
+       { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
+       { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
+       { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk },
+
+       { "AIF1 IN", NULL, "AIF1 CLK" },
+       { "AIF1 OUT", NULL, "AIF1 CLK" },
+       { "AIF2 IN", NULL, "AIF2 CLK" },
+       { "AIF2 OUT", NULL, "AIF2 CLK" },
+       { "AIF3 IN", NULL, "AIF3 CLK" },
+       { "AIF3 OUT", NULL, "AIF3 CLK" },
+       { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src },
+       { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src },
+       { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src },
+       { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src },
+       { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src },
+       { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src },
+
+       { "DMIC1", NULL, "DMIC1DAT" },
+       { "DMIC1", NULL, "SYSCLK1" },
+       { "DMIC1", NULL, "Recording Engine A" },
+       { "DMIC2", NULL, "DMIC2DAT" },
+       { "DMIC2", NULL, "SYSCLK1" },
+       { "DMIC2", NULL, "Recording Engine B" },
+};
+
+static int adau1373_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
+       unsigned int div;
+       unsigned int freq;
+       unsigned int ctrl;
+
+       freq = adau1373_dai->sysclk;
+
+       if (freq % params_rate(params) != 0)
+               return -EINVAL;
+
+       switch (freq / params_rate(params)) {
+       case 1024: /* sysclk / 256 */
+               div = 0;
+               break;
+       case 1536: /* 2/3 sysclk / 256 */
+               div = 1;
+               break;
+       case 2048: /* 1/2 sysclk / 256 */
+               div = 2;
+               break;
+       case 3072: /* 1/3 sysclk / 256 */
+               div = 3;
+               break;
+       case 4096: /* 1/4 sysclk / 256 */
+               div = 4;
+               break;
+       case 6144: /* 1/6 sysclk / 256 */
+               div = 5;
+               break;
+       case 5632: /* 2/11 sysclk / 256 */
+               div = 6;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       adau1373_dai->enable_src = (div != 0);
+
+       snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
+               ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64);
+
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               ctrl = ADAU1373_DAI_WLEN_16;
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               ctrl = ADAU1373_DAI_WLEN_20;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               ctrl = ADAU1373_DAI_WLEN_24;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               ctrl = ADAU1373_DAI_WLEN_32;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
+                       ADAU1373_DAI_WLEN_MASK, ctrl);
+}
+
+static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
+       unsigned int ctrl;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               ctrl = ADAU1373_DAI_MASTER;
+               adau1373_dai->master = true;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               ctrl = 0;
+               adau1373_dai->master = true;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               ctrl |= ADAU1373_DAI_FORMAT_I2S;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               ctrl |= ADAU1373_DAI_FORMAT_LEFT_J;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               ctrl |= ADAU1373_DAI_FORMAT_DSP;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               ctrl |= ADAU1373_DAI_INVERT_BCLK;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               ctrl |= ADAU1373_DAI_INVERT_LRCLK;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       snd_soc_update_bits(codec, ADAU1373_DAI(dai->id),
+               ~ADAU1373_DAI_WLEN_MASK, ctrl);
+
+       return 0;
+}
+
+static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
+       int clk_id, unsigned int freq, int dir)
+{
+       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
+
+       switch (clk_id) {
+       case ADAU1373_CLK_SRC_PLL1:
+       case ADAU1373_CLK_SRC_PLL2:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       adau1373_dai->sysclk = freq;
+       adau1373_dai->clk_src = clk_id;
+
+       snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id),
+               ADAU1373_BCLKDIV_SOURCE, clk_id << 5);
+
+       return 0;
+}
+
+static const struct snd_soc_dai_ops adau1373_dai_ops = {
+       .hw_params      = adau1373_hw_params,
+       .set_sysclk     = adau1373_set_dai_sysclk,
+       .set_fmt        = adau1373_set_dai_fmt,
+};
+
+#define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver adau1373_dai_driver[] = {
+       {
+               .id = 0,
+               .name = "adau1373-aif1",
+               .playback = {
+                       .stream_name = "AIF1 Playback",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = SNDRV_PCM_RATE_8000_48000,
+                       .formats = ADAU1373_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "AIF1 Capture",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = SNDRV_PCM_RATE_8000_48000,
+                       .formats = ADAU1373_FORMATS,
+               },
+               .ops = &adau1373_dai_ops,
+               .symmetric_rates = 1,
+       },
+       {
+               .id = 1,
+               .name = "adau1373-aif2",
+               .playback = {
+                       .stream_name = "AIF2 Playback",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = SNDRV_PCM_RATE_8000_48000,
+                       .formats = ADAU1373_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "AIF2 Capture",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = SNDRV_PCM_RATE_8000_48000,
+                       .formats = ADAU1373_FORMATS,
+               },
+               .ops = &adau1373_dai_ops,
+               .symmetric_rates = 1,
+       },
+       {
+               .id = 2,
+               .name = "adau1373-aif3",
+               .playback = {
+                       .stream_name = "AIF3 Playback",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = SNDRV_PCM_RATE_8000_48000,
+                       .formats = ADAU1373_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "AIF3 Capture",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = SNDRV_PCM_RATE_8000_48000,
+                       .formats = ADAU1373_FORMATS,
+               },
+               .ops = &adau1373_dai_ops,
+               .symmetric_rates = 1,
+       },
+};
+
+static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
+       int source, unsigned int freq_in, unsigned int freq_out)
+{
+       unsigned int dpll_div = 0;
+       unsigned int x, r, n, m, i, j, mode;
+
+       switch (pll_id) {
+       case ADAU1373_PLL1:
+       case ADAU1373_PLL2:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (source) {
+       case ADAU1373_PLL_SRC_BCLK1:
+       case ADAU1373_PLL_SRC_BCLK2:
+       case ADAU1373_PLL_SRC_BCLK3:
+       case ADAU1373_PLL_SRC_LRCLK1:
+       case ADAU1373_PLL_SRC_LRCLK2:
+       case ADAU1373_PLL_SRC_LRCLK3:
+       case ADAU1373_PLL_SRC_MCLK1:
+       case ADAU1373_PLL_SRC_MCLK2:
+       case ADAU1373_PLL_SRC_GPIO1:
+       case ADAU1373_PLL_SRC_GPIO2:
+       case ADAU1373_PLL_SRC_GPIO3:
+       case ADAU1373_PLL_SRC_GPIO4:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (freq_in < 7813 || freq_in > 27000000)
+               return -EINVAL;
+
+       if (freq_out < 45158000 || freq_out > 49152000)
+               return -EINVAL;
+
+       /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the
+        * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */
+       while (freq_in < 8000000) {
+               freq_in *= 2;
+               dpll_div++;
+       }
+
+       if (freq_out % freq_in != 0) {
+               /* fout = fin * (r + (n/m)) / x */
+               x = DIV_ROUND_UP(freq_in, 13500000);
+               freq_in /= x;
+               r = freq_out / freq_in;
+               i = freq_out % freq_in;
+               j = gcd(i, freq_in);
+               n = i / j;
+               m = freq_in / j;
+               x--;
+               mode = 1;
+       } else {
+               /* fout = fin / r */
+               r = freq_out / freq_in;
+               n = 0;
+               m = 0;
+               x = 0;
+               mode = 0;
+       }
+
+       if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff)
+               return -EINVAL;
+
+       if (dpll_div) {
+               dpll_div = 11 - dpll_div;
+               snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
+                       ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0);
+       } else {
+               snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id),
+                       ADAU1373_PLL_CTRL6_DPLL_BYPASS,
+                       ADAU1373_PLL_CTRL6_DPLL_BYPASS);
+       }
+
+       snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id),
+               (source << 4) | dpll_div);
+       snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff);
+       snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff);
+       snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff);
+       snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff);
+       snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id),
+               (r << 3) | (x << 1) | mode);
+
+       /* Set sysclk to pll_rate / 4 */
+       snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
+
+       return 0;
+}
+
+static void adau1373_load_drc_settings(struct snd_soc_codec *codec,
+       unsigned int nr, uint8_t *drc)
+{
+       unsigned int i;
+
+       for (i = 0; i < ADAU1373_DRC_SIZE; ++i)
+               snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]);
+}
+
+static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
+{
+       switch (micbias) {
+       case ADAU1373_MICBIAS_2_9V:
+       case ADAU1373_MICBIAS_2_2V:
+       case ADAU1373_MICBIAS_2_6V:
+       case ADAU1373_MICBIAS_1_8V:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
+static int adau1373_probe(struct snd_soc_codec *codec)
+{
+       struct adau1373_platform_data *pdata = codec->dev->platform_data;
+       bool lineout_differential = false;
+       unsigned int val;
+       int ret;
+       int i;
+
+       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+       if (ret) {
+               dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
+
+       codec->dapm.idle_bias_off = true;
+
+       if (pdata) {
+               if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
+                       return -EINVAL;
+
+               if (!adau1373_valid_micbias(pdata->micbias1) ||
+                       !adau1373_valid_micbias(pdata->micbias2))
+                       return -EINVAL;
+
+               for (i = 0; i < pdata->num_drc; ++i) {
+                       adau1373_load_drc_settings(codec, i,
+                               pdata->drc_setting[i]);
+               }
+
+               snd_soc_add_controls(codec, adau1373_drc_controls,
+                       pdata->num_drc);
+
+               val = 0;
+               for (i = 0; i < 4; ++i) {
+                       if (pdata->input_differential[i])
+                               val |= BIT(i);
+               }
+               snd_soc_write(codec, ADAU1373_INPUT_MODE, val);
+
+               val = 0;
+               if (pdata->lineout_differential)
+                       val |= ADAU1373_OUTPUT_CTRL_LDIFF;
+               if (pdata->lineout_ground_sense)
+                       val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
+               snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val);
+
+               lineout_differential = pdata->lineout_differential;
+
+               snd_soc_write(codec, ADAU1373_EP_CTRL,
+                       (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
+                       (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
+       }
+
+       if (!lineout_differential) {
+               snd_soc_add_controls(codec, adau1373_lineout2_controls,
+                       ARRAY_SIZE(adau1373_lineout2_controls));
+       }
+
+       snd_soc_write(codec, ADAU1373_ADC_CTRL,
+           ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT);
+
+       return 0;
+}
+
+static int adau1373_set_bias_level(struct snd_soc_codec *codec,
+       enum snd_soc_bias_level level)
+{
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
+                       ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN);
+               break;
+       case SND_SOC_BIAS_OFF:
+               snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3,
+                       ADAU1373_PWDN_CTRL3_PWR_EN, 0);
+               break;
+       }
+       codec->dapm.bias_level = level;
+       return 0;
+}
+
+static int adau1373_remove(struct snd_soc_codec *codec)
+{
+       adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+       return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
+}
+
+static int adau1373_resume(struct snd_soc_codec *codec)
+{
+       adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_cache_sync(codec);
+
+       return 0;
+}
+
+static struct snd_soc_codec_driver adau1373_codec_driver = {
+       .probe =        adau1373_probe,
+       .remove =       adau1373_remove,
+       .suspend =      adau1373_suspend,
+       .resume =       adau1373_resume,
+       .set_bias_level = adau1373_set_bias_level,
+       .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
+       .reg_cache_default = adau1373_default_regs,
+       .reg_word_size = sizeof(uint8_t),
+
+       .set_pll = adau1373_set_pll,
+
+       .controls = adau1373_controls,
+       .num_controls = ARRAY_SIZE(adau1373_controls),
+       .dapm_widgets = adau1373_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
+       .dapm_routes = adau1373_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
+};
+
+static int __devinit adau1373_i2c_probe(struct i2c_client *client,
+       const struct i2c_device_id *id)
+{
+       struct adau1373 *adau1373;
+       int ret;
+
+       adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL);
+       if (!adau1373)
+               return -ENOMEM;
+
+       dev_set_drvdata(&client->dev, adau1373);
+
+       ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
+                       adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
+       if (ret < 0)
+               kfree(adau1373);
+
+       return ret;
+}
+
+static int __devexit adau1373_i2c_remove(struct i2c_client *client)
+{
+       snd_soc_unregister_codec(&client->dev);
+       kfree(dev_get_drvdata(&client->dev));
+       return 0;
+}
+
+static const struct i2c_device_id adau1373_i2c_id[] = {
+       { "adau1373", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id);
+
+static struct i2c_driver adau1373_i2c_driver = {
+       .driver = {
+               .name = "adau1373",
+               .owner = THIS_MODULE,
+       },
+       .probe = adau1373_i2c_probe,
+       .remove = __devexit_p(adau1373_i2c_remove),
+       .id_table = adau1373_i2c_id,
+};
+
+static int __init adau1373_init(void)
+{
+       return i2c_add_driver(&adau1373_i2c_driver);
+}
+module_init(adau1373_init);
+
+static void __exit adau1373_exit(void)
+{
+       i2c_del_driver(&adau1373_i2c_driver);
+}
+module_exit(adau1373_exit);
+
+MODULE_DESCRIPTION("ASoC ADAU1373 driver");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h
new file mode 100644 (file)
index 0000000..c6ab553
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __ADAU1373_H__
+#define __ADAU1373_H__
+
+enum adau1373_pll_src {
+       ADAU1373_PLL_SRC_MCLK1 = 0,
+       ADAU1373_PLL_SRC_BCLK1 = 1,
+       ADAU1373_PLL_SRC_BCLK2 = 2,
+       ADAU1373_PLL_SRC_BCLK3 = 3,
+       ADAU1373_PLL_SRC_LRCLK1 = 4,
+       ADAU1373_PLL_SRC_LRCLK2 = 5,
+       ADAU1373_PLL_SRC_LRCLK3 = 6,
+       ADAU1373_PLL_SRC_GPIO1 = 7,
+       ADAU1373_PLL_SRC_GPIO2 = 8,
+       ADAU1373_PLL_SRC_GPIO3 = 9,
+       ADAU1373_PLL_SRC_GPIO4 = 10,
+       ADAU1373_PLL_SRC_MCLK2 = 11,
+};
+
+enum adau1373_pll {
+       ADAU1373_PLL1 = 0,
+       ADAU1373_PLL2 = 1,
+};
+
+enum adau1373_clk_src {
+       ADAU1373_CLK_SRC_PLL1 = 0,
+       ADAU1373_CLK_SRC_PLL2 = 1,
+};
+
+#endif
index 7e4066e131e64ac95ed0eee06bb470a4ee23a6f2..91130fbc6913e534e37d188109eb03a1801acfae 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/consumer.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
 #include <sound/pcm.h>
@@ -1436,10 +1437,17 @@ static const struct i2c_device_id sgtl5000_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
 
+static const struct of_device_id sgtl5000_dt_ids[] = {
+       { .compatible = "fsl,sgtl5000", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids);
+
 static struct i2c_driver sgtl5000_i2c_driver = {
        .driver = {
                   .name = "sgtl5000",
                   .owner = THIS_MODULE,
+                  .of_match_table = sgtl5000_dt_ids,
                   },
        .probe = sgtl5000_i2c_probe,
        .remove = __devexit_p(sgtl5000_i2c_remove),
index 409d89d1f34c26fb44b58d979256541d798a5dc1..5c7def3979c0ad3d876e95cdbcf9bee65a85e4f2 100644 (file)
@@ -524,13 +524,17 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
        rate = params_rate(params);
        pr_debug("rate: %u\n", rate);
        for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
-               if (interpolation_ratios[i].fs == rate)
+               if (interpolation_ratios[i].fs == rate) {
                        ir = interpolation_ratios[i].ir;
+                       break;
+               }
        if (ir < 0)
                return -EINVAL;
        for (i = 0; mclk_ratios[ir][i].ratio; i++)
-               if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk)
+               if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
                        mcs = mclk_ratios[ir][i].mcs;
+                       break;
+               }
        if (mcs < 0)
                return -EINVAL;
 
@@ -808,6 +812,7 @@ static int sta32x_remove(struct snd_soc_codec *codec)
 {
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
 
+       sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
        regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 
@@ -857,6 +862,7 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
        ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
        if (ret != 0) {
                dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
+               kfree(sta32x);
                return ret;
        }
 
@@ -866,18 +872,8 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
 static __devexit int sta32x_i2c_remove(struct i2c_client *client)
 {
        struct sta32x_priv *sta32x = i2c_get_clientdata(client);
-       struct snd_soc_codec *codec = sta32x->codec;
-
-       if (codec)
-               sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-       regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-
-       if (codec) {
-               snd_soc_unregister_codec(&client->dev);
-               snd_soc_codec_set_drvdata(codec, NULL);
-       }
 
+       snd_soc_unregister_codec(&client->dev);
        kfree(sta32x);
        return 0;
 }
index bcc208967917f149956985e7c8f5c290a1506aad..4523c4cec02ba5b07d4a568704d57ba0285b568d 100644 (file)
@@ -56,8 +56,26 @@ static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
 };
 
 static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
-                                     const struct i2c_device_id *id)
+                                     const struct i2c_device_id *i2c_id)
 {
+       int id, board, rev;
+
+       board = i2c_smbus_read_byte_data(i2c, 0);
+       if (board < 0) {
+               dev_err(&i2c->dev, "Failed to read ID: %d\n", board);
+               return board;
+       }
+
+       id = (board & 0xfe) >> 2;
+       rev = board & 0x3;
+
+       if (id != 1) {
+               dev_err(&i2c->dev, "Unknown board ID %d\n", id);
+               return -ENODEV;
+       }
+
+       dev_info(&i2c->dev, "revision %d\n", rev + 1);
+
        return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
                                      &wm1250_ev1_dai, 1);
 }
index db0dced7484384637f910efeaeb200211e4ce60b..55a4c830e111372f7e67768076debf56275fc3cd 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -598,6 +599,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
        .reg_cache_default =wm8510_reg,
 };
 
+static const struct of_device_id wm8510_of_match[] = {
+       { .compatible = "wlf,wm8510" },
+       { },
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8510_spi_probe(struct spi_device *spi)
 {
@@ -628,6 +634,7 @@ static struct spi_driver wm8510_spi_driver = {
        .driver = {
                .name   = "wm8510",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8510_of_match,
        },
        .probe          = wm8510_spi_probe,
        .remove         = __devexit_p(wm8510_spi_remove),
@@ -671,6 +678,7 @@ static struct i2c_driver wm8510_i2c_driver = {
        .driver = {
                .name = "wm8510-codec",
                .owner = THIS_MODULE,
+               .of_match_table = wm8510_of_match,
        },
        .probe =    wm8510_i2c_probe,
        .remove =   __devexit_p(wm8510_i2c_remove),
index 4fd4d8dca0fc0af31439371fbab9040794162095..5355a7a944f7cd3f0b3217e4c8ffb824dbe43029 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -84,7 +85,7 @@ static const char *wm8523_zd_count_text[] = {
 static const struct soc_enum wm8523_zc_count =
        SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
 
-static const struct snd_kcontrol_new wm8523_snd_controls[] = {
+static const struct snd_kcontrol_new wm8523_controls[] = {
 SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
                 0, 448, 0, dac_tlv),
 SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
@@ -101,22 +102,11 @@ SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
 SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
 };
 
-static const struct snd_soc_dapm_route intercon[] = {
+static const struct snd_soc_dapm_route wm8523_dapm_routes[] = {
        { "LINEVOUTL", NULL, "DAC" },
        { "LINEVOUTR", NULL, "DAC" },
 };
 
-static int wm8523_add_widgets(struct snd_soc_codec *codec)
-{
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
-                                 ARRAY_SIZE(wm8523_dapm_widgets));
-       snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
-       return 0;
-}
-
 static struct {
        int value;
        int ratio;
@@ -479,10 +469,6 @@ static int wm8523_probe(struct snd_soc_codec *codec)
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
 
-       snd_soc_add_controls(codec, wm8523_snd_controls,
-                            ARRAY_SIZE(wm8523_snd_controls));
-       wm8523_add_widgets(codec);
-
        return 0;
 
 err_enable:
@@ -512,6 +498,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
        .reg_word_size = sizeof(u16),
        .reg_cache_default = wm8523_reg,
        .volatile_register = wm8523_volatile_register,
+
+       .controls = wm8523_controls,
+       .num_controls = ARRAY_SIZE(wm8523_controls),
+       .dapm_widgets = wm8523_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
+       .dapm_routes = wm8523_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
+};
+
+static const struct of_device_id wm8523_of_match[] = {
+       { .compatible = "wlf,wm8523" },
+       { },
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -551,8 +549,9 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
 
 static struct i2c_driver wm8523_i2c_driver = {
        .driver = {
-               .name = "wm8523-codec",
+               .name = "wm8523",
                .owner = THIS_MODULE,
+               .of_match_table = wm8523_of_match,
        },
        .probe =    wm8523_i2c_probe,
        .remove =   __devexit_p(wm8523_i2c_remove),
index 4bbc0a79f01edf0139f6c1d10c587a82ff778fa9..4664c3a76c78967daf05cdb6c8bb0d67d91aad9e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -907,6 +908,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
        .reg_cache_default = wm8580_reg,
 };
 
+static const struct of_device_id wm8580_of_match[] = {
+       { .compatible = "wlf,wm8580" },
+       { },
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static int wm8580_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
@@ -943,8 +949,9 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
 
 static struct i2c_driver wm8580_i2c_driver = {
        .driver = {
-               .name = "wm8580-codec",
+               .name = "wm8580",
                .owner = THIS_MODULE,
+               .of_match_table = wm8580_of_match,
        },
        .probe =    wm8580_i2c_probe,
        .remove =   wm8580_i2c_remove,
index a537e4af6ae74efe7950d6a1806ee3942118a834..8457d3cb59622555a46c7af944ac844a56eaa24c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -414,6 +415,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
        .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
 };
 
+static const struct of_device_id wm8711_of_match[] = {
+       { .compatible = "wlf,wm8711", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, wm8711_of_match);
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8711_spi_probe(struct spi_device *spi)
 {
@@ -443,8 +450,9 @@ static int __devexit wm8711_spi_remove(struct spi_device *spi)
 
 static struct spi_driver wm8711_spi_driver = {
        .driver = {
-               .name   = "wm8711-codec",
+               .name   = "wm8711",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8711_of_match,
        },
        .probe          = wm8711_spi_probe,
        .remove         = __devexit_p(wm8711_spi_remove),
@@ -487,8 +495,9 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
 
 static struct i2c_driver wm8711_i2c_driver = {
        .driver = {
-               .name = "wm8711-codec",
+               .name = "wm8711",
                .owner = THIS_MODULE,
+               .of_match_table = wm8711_of_match,
        },
        .probe =    wm8711_i2c_probe,
        .remove =   __devexit_p(wm8711_i2c_remove),
index 86d4718d3a76055e46c1982e526855905c871ac9..04b027efd5c003df25769eb92e3ff7a74317a975 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -269,6 +270,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
        .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
 };
 
+static const struct of_device_id wm8728_of_match[] = {
+       { .compatible = "wlf,wm8728", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, wm8728_of_match);
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8728_spi_probe(struct spi_device *spi)
 {
@@ -298,8 +305,9 @@ static int __devexit wm8728_spi_remove(struct spi_device *spi)
 
 static struct spi_driver wm8728_spi_driver = {
        .driver = {
-               .name   = "wm8728-codec",
+               .name   = "wm8728",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8728_of_match,
        },
        .probe          = wm8728_spi_probe,
        .remove         = __devexit_p(wm8728_spi_remove),
@@ -342,8 +350,9 @@ MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
 
 static struct i2c_driver wm8728_i2c_driver = {
        .driver = {
-               .name = "wm8728-codec",
+               .name = "wm8728",
                .owner = THIS_MODULE,
+               .of_match_table = wm8728_of_match,
        },
        .probe =    wm8728_i2c_probe,
        .remove =   __devexit_p(wm8728_i2c_remove),
index 76b4361e9b8042c112a32b14b290304e17761604..f76b6fc6766a1f6e8e855801823ffb7c2c8221f0 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -607,6 +608,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
        .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
 };
 
+static const struct of_device_id wm8731_of_match[] = {
+       { .compatible = "wlf,wm8731", },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, wm8731_of_match);
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8731_spi_probe(struct spi_device *spi)
 {
@@ -638,6 +646,7 @@ static struct spi_driver wm8731_spi_driver = {
        .driver = {
                .name   = "wm8731",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8731_of_match,
        },
        .probe          = wm8731_spi_probe,
        .remove         = __devexit_p(wm8731_spi_remove),
@@ -682,6 +691,7 @@ static struct i2c_driver wm8731_i2c_driver = {
        .driver = {
                .name = "wm8731",
                .owner = THIS_MODULE,
+               .of_match_table = wm8731_of_match,
        },
        .probe =    wm8731_i2c_probe,
        .remove =   __devexit_p(wm8731_i2c_remove),
index 30c67d06a9043988f1a84ed6f4780b7c2502dbc3..f6aef58845c2dc31880529cdaa9510a96735e334 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -634,6 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
        .reg_cache_default = wm8737_reg,
 };
 
+static const struct of_device_id wm8737_of_match[] = {
+       { .compatible = "wlf,wm8737", },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, wm8737_of_match);
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
@@ -673,6 +681,7 @@ static struct i2c_driver wm8737_i2c_driver = {
        .driver = {
                .name = "wm8737",
                .owner = THIS_MODULE,
+               .of_match_table = wm8737_of_match,
        },
        .probe =    wm8737_i2c_probe,
        .remove =   __devexit_p(wm8737_i2c_remove),
@@ -711,6 +720,7 @@ static struct spi_driver wm8737_spi_driver = {
        .driver = {
                .name   = "wm8737",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8737_of_match,
        },
        .probe          = wm8737_spi_probe,
        .remove         = __devexit_p(wm8737_spi_remove),
index 25af901fe8133029e7efe35914c07e02105e4085..78c9e5ab3fa54cf35c20e23b2218ccae1ccbe69b 100644 (file)
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -422,17 +424,35 @@ static int wm8741_probe(struct snd_soc_codec *codec)
 {
        struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
        int ret = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
+               wm8741->supplies[i].supply = wm8741_supply_names[i];
+
+       ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
+                                wm8741->supplies);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+               goto err;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
+                                   wm8741->supplies);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               goto err_get;
+       }
 
        ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
+               goto err_enable;
        }
 
        ret = wm8741_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
-               return ret;
+               goto err_enable;
        }
 
        /* Change some default settings - latch VU */
@@ -451,58 +471,61 @@ static int wm8741_probe(struct snd_soc_codec *codec)
 
        dev_dbg(codec->dev, "Successful registration\n");
        return ret;
+
+err_enable:
+       regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
+err_get:
+       regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
+err:
+       return ret;
+}
+
+static int wm8741_remove(struct snd_soc_codec *codec)
+{
+       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+
+       regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
+       regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
+
+       return 0;
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
        .probe =        wm8741_probe,
+       .remove =       wm8741_remove,
        .resume =       wm8741_resume,
        .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
        .reg_word_size = sizeof(u16),
        .reg_cache_default = wm8741_reg_defaults,
 };
 
+static const struct of_device_id wm8741_of_match[] = {
+       { .compatible = "wlf,wm8741", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, wm8741_of_match);
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static int wm8741_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct wm8741_priv *wm8741;
-       int ret, i;
+       int ret;
 
        wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
        if (wm8741 == NULL)
                return -ENOMEM;
 
-       for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
-               wm8741->supplies[i].supply = wm8741_supply_names[i];
-
-       ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
-                                wm8741->supplies);
-       if (ret != 0) {
-               dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
-               goto err;
-       }
-
-       ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
-                                   wm8741->supplies);
-       if (ret != 0) {
-               dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
-               goto err_get;
-       }
-
        i2c_set_clientdata(i2c, wm8741);
        wm8741->control_type = SND_SOC_I2C;
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8741, &wm8741_dai, 1);
-       if (ret < 0)
-               goto err_enable;
-       return ret;
+       ret = snd_soc_register_codec(&i2c->dev,
+                                    &soc_codec_dev_wm8741, &wm8741_dai, 1);
+       if (ret != 0)
+               goto err;
 
-err_enable:
-       regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
+       return ret;
 
-err_get:
-       regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
 err:
        kfree(wm8741);
        return ret;
@@ -510,10 +533,7 @@ err:
 
 static int wm8741_i2c_remove(struct i2c_client *client)
 {
-       struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
-
        snd_soc_unregister_codec(&client->dev);
-       regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
        kfree(i2c_get_clientdata(client));
        return 0;
 }
@@ -526,8 +546,9 @@ MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
 
 static struct i2c_driver wm8741_i2c_driver = {
        .driver = {
-               .name = "wm8741-codec",
+               .name = "wm8741",
                .owner = THIS_MODULE,
+               .of_match_table = wm8741_of_match,
        },
        .probe =    wm8741_i2c_probe,
        .remove =   wm8741_i2c_remove,
@@ -535,6 +556,44 @@ static struct i2c_driver wm8741_i2c_driver = {
 };
 #endif
 
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8741_spi_probe(struct spi_device *spi)
+{
+       struct wm8741_priv *wm8741;
+       int ret;
+
+       wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
+       if (wm8741 == NULL)
+               return -ENOMEM;
+
+       wm8741->control_type = SND_SOC_SPI;
+       spi_set_drvdata(spi, wm8741);
+
+       ret = snd_soc_register_codec(&spi->dev,
+                       &soc_codec_dev_wm8741, &wm8741_dai, 1);
+       if (ret < 0)
+               kfree(wm8741);
+       return ret;
+}
+
+static int __devexit wm8741_spi_remove(struct spi_device *spi)
+{
+       snd_soc_unregister_codec(&spi->dev);
+       kfree(spi_get_drvdata(spi));
+       return 0;
+}
+
+static struct spi_driver wm8741_spi_driver = {
+       .driver = {
+               .name   = "wm8741",
+               .owner  = THIS_MODULE,
+               .of_match_table = wm8741_of_match,
+       },
+       .probe          = wm8741_spi_probe,
+       .remove         = __devexit_p(wm8741_spi_remove),
+};
+#endif /* CONFIG_SPI_MASTER */
+
 static int __init wm8741_modinit(void)
 {
        int ret = 0;
@@ -544,6 +603,13 @@ static int __init wm8741_modinit(void)
        if (ret != 0)
                pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
 #endif
+#if defined(CONFIG_SPI_MASTER)
+       ret = spi_register_driver(&wm8741_spi_driver);
+       if (ret != 0) {
+               printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",
+                      ret);
+       }
+#endif
 
        return ret;
 }
@@ -551,6 +617,9 @@ module_init(wm8741_modinit);
 
 static void __exit wm8741_exit(void)
 {
+#if defined(CONFIG_SPI_MASTER)
+       spi_unregister_driver(&wm8741_spi_driver);
+#endif
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
        i2c_del_driver(&wm8741_i2c_driver);
 #endif
index d0003cc3bcd66cf16336bec69cc0f75b4de97a56..15f03721ec6ff3fd23da9117cd40453e328e0d9b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -751,6 +752,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
        .reg_cache_default = wm8750_reg,
 };
 
+static const struct of_device_id wm8750_of_match[] = {
+       { .compatible = "wlf,wm8750", },
+       { .compatible = "wlf,wm8987", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, wm8750_of_match);
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8750_spi_probe(struct spi_device *spi)
 {
@@ -787,8 +795,9 @@ MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
 
 static struct spi_driver wm8750_spi_driver = {
        .driver = {
-               .name   = "wm8750-codec",
+               .name   = "wm8750",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8750_of_match,
        },
        .id_table       = wm8750_spi_ids,
        .probe          = wm8750_spi_probe,
@@ -833,8 +842,9 @@ MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
 
 static struct i2c_driver wm8750_i2c_driver = {
        .driver = {
-               .name = "wm8750-codec",
+               .name = "wm8750",
                .owner = THIS_MODULE,
+               .of_match_table = wm8750_of_match,
        },
        .probe =    wm8750_i2c_probe,
        .remove =   __devexit_p(wm8750_i2c_remove),
index ffa2ffe5ec11aa92ef6c4e55073aae275dc169cc..fe04a101d657a6536cd2ca59c62bf0382dc08768 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
@@ -1490,6 +1491,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
        .reg_cache_default = wm8753_reg,
 };
 
+static const struct of_device_id wm8753_of_match[] = {
+       { .compatible = "wlf,wm8753", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, wm8753_of_match);
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8753_spi_probe(struct spi_device *spi)
 {
@@ -1519,8 +1526,9 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
 
 static struct spi_driver wm8753_spi_driver = {
        .driver = {
-               .name   = "wm8753-codec",
+               .name   = "wm8753",
                .owner  = THIS_MODULE,
+               .of_match_table = wm8753_of_match,
        },
        .probe          = wm8753_spi_probe,
        .remove         = __devexit_p(wm8753_spi_remove),
@@ -1563,8 +1571,9 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
 
 static struct i2c_driver wm8753_i2c_driver = {
        .driver = {
-               .name = "wm8753-codec",
+               .name = "wm8753",
                .owner = THIS_MODULE,
+               .of_match_table = wm8753_of_match,
        },
        .probe =    wm8753_i2c_probe,
        .remove =   __devexit_p(wm8753_i2c_remove),
index 60d740ebeb5bb8b7502dd93b5b2ece605407d70a..8e397b286aa3568b1c1475e8dd3920cdae4d1cee 100644 (file)
@@ -63,6 +63,8 @@ struct wm8962_priv {
        int fll_fref;
        int fll_fout;
 
+       u16 dsp2_ena;
+
        struct delayed_work mic_work;
        struct snd_soc_jack *jack;
 
@@ -837,7 +839,7 @@ static const struct wm8962_reg_access {
        [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40    - SPKOUTL volume */
        [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41    - SPKOUTR volume */
 
-       [47] = { 0x000F, 0x0000, 0x0000 }, /* R47    - Thermal Shutdown Status */
+       [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47    - Thermal Shutdown Status */
        [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48    - Additional Control (4) */
        [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49    - Class D Control 1 */
        [51] = { 0x0047, 0x0047, 0x0000 }, /* R51    - Class D Control 2 */
@@ -965,7 +967,7 @@ static const struct wm8962_reg_access {
        [584] = { 0x002D, 0x002D, 0x0000 }, /* R584   - IRQ Debounce */
        [586] = { 0xC000, 0xC000, 0x0000 }, /* R586   -  MICINT Source Pol */
        [768] = { 0x0001, 0x0001, 0x0000 }, /* R768   - DSP2 Power Management */
-       [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037  - DSP2_ExecControl */
+       [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037  - DSP2_ExecControl */
        [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096  - Write Sequencer 0 */
        [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097  - Write Sequencer 1 */
        [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098  - Write Sequencer 2 */
@@ -1986,6 +1988,122 @@ static const unsigned int classd_tlv[] = {
 };
 static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
 
+static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
+{
+       return 0;
+}
+
+static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
+{
+       u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME);
+       u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME);
+       u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1);
+
+       /* Mute the ADCs and DACs */
+       snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0);
+       snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU);
+       snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
+                           WM8962_DAC_MUTE, WM8962_DAC_MUTE);
+
+       snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val);
+
+       /* Restore the ADCs and DACs */
+       snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl);
+       snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr);
+       snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
+                           WM8962_DAC_MUTE, dac);
+
+       return 0;
+}
+
+static int wm8962_dsp2_start(struct snd_soc_codec *codec)
+{
+       struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+
+       wm8962_dsp2_write_config(codec);
+
+       snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR);
+
+       wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
+
+       return 0;
+}
+
+static int wm8962_dsp2_stop(struct snd_soc_codec *codec)
+{
+       wm8962_dsp2_set_enable(codec, 0);
+
+       snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP);
+
+       return 0;
+}
+
+#define WM8962_DSP2_ENABLE(xname, xshift) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+       .info = wm8962_dsp2_ena_info, \
+       .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \
+       .private_value = xshift }
+
+static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 1;
+
+       return 0;
+}
+
+static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *ucontrol)
+{
+       int shift = kcontrol->private_value;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+
+       ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift);
+
+       return 0;
+}
+
+static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *ucontrol)
+{
+       int shift = kcontrol->private_value;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+       int old = wm8962->dsp2_ena;
+       int ret = 0;
+       int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) &
+               WM8962_DSP2_ENA;
+
+       mutex_lock(&codec->mutex);
+
+       if (ucontrol->value.integer.value[0])
+               wm8962->dsp2_ena |= 1 << shift;
+       else
+               wm8962->dsp2_ena &= ~(1 << shift);
+
+       if (wm8962->dsp2_ena == old)
+               goto out;
+
+       ret = 1;
+
+       if (dsp2_running) {
+               if (wm8962->dsp2_ena)
+                       wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena);
+               else
+                       wm8962_dsp2_stop(codec);
+       }
+
+out:
+       mutex_unlock(&codec->mutex);
+
+       return ret;
+}
+
 /* The VU bits for the headphones are in a different register to the mute
  * bits and only take effect on the PGA if it is actually powered.
  */
@@ -2049,6 +2167,14 @@ static const char *cap_hpf_mode_text[] = {
 static const struct soc_enum cap_hpf_mode =
        SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
 
+
+static const char *cap_lhpf_mode_text[] = {
+       "LPF", "HPF"
+};
+
+static const struct soc_enum cap_lhpf_mode =
+       SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text);
+
 static const struct snd_kcontrol_new wm8962_snd_controls[] = {
 SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
 
@@ -2077,6 +2203,8 @@ SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
 SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
 SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
 SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
+SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0),
+SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
 
 SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
                 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
@@ -2134,6 +2262,11 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
                 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
 SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
                 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
+
+WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
+WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
+WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
+WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
 };
 
 static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2221,6 +2354,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                if (fll) {
+                       try_wait_for_completion(&wm8962->fll_lock);
+
                        snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
                                            WM8962_FLL_ENA, WM8962_FLL_ENA);
                        if (wm8962->irq) {
@@ -2393,6 +2528,31 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
        }
 }
 
+static int dsp2_event(struct snd_soc_dapm_widget *w,
+                     struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               if (wm8962->dsp2_ena)
+                       wm8962_dsp2_start(codec);
+               break;
+
+       case SND_SOC_DAPM_PRE_PMD:
+               if (wm8962->dsp2_ena)
+                       wm8962_dsp2_stop(codec);
+               break;
+
+       default:
+               BUG();
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static const char *st_text[] = { "None", "Right", "Left" };
 
 static const struct soc_enum str_enum =
@@ -2515,6 +2675,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
 SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
                    SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
+                     WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
+                     SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
                   inpgal, ARRAY_SIZE(inpgal)),
@@ -2610,11 +2773,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
        { "ADCL", NULL, "TOCLK" },
        { "ADCL", NULL, "MIXINL" },
        { "ADCL", NULL, "DMIC" },
+       { "ADCL", NULL, "DSP2" },
 
        { "ADCR", NULL, "SYSCLK" },
        { "ADCR", NULL, "TOCLK" },
        { "ADCR", NULL, "MIXINR" },
        { "ADCR", NULL, "DMIC" },
+       { "ADCR", NULL, "DSP2" },
 
        { "STL", "Left", "ADCL" },
        { "STL", "Right", "ADCR" },
@@ -2626,11 +2791,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
        { "DACL", NULL, "TOCLK" },
        { "DACL", NULL, "Beep" },
        { "DACL", NULL, "STL" },
+       { "DACL", NULL, "DSP2" },
 
        { "DACR", NULL, "SYSCLK" },
        { "DACR", NULL, "TOCLK" },
        { "DACR", NULL, "Beep" },
        { "DACR", NULL, "STR" },
+       { "DACR", NULL, "DSP2" },
 
        { "HPMIXL", "IN4L Switch", "IN4L" },
        { "HPMIXL", "IN4R Switch", "IN4R" },
@@ -2927,10 +3094,6 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
                                            WM8962_BIAS_ENA | 0x180);
 
                        msleep(5);
-
-                       snd_soc_update_bits(codec, WM8962_CLOCKING2,
-                                           WM8962_CLKREG_OVD,
-                                           WM8962_CLKREG_OVD);
                }
 
                /* VMID 2*250k */
@@ -3288,6 +3451,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
        snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
 
+       try_wait_for_completion(&wm8962->fll_lock);
+
        snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
                            WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
                            WM8962_FLL_ENA, fll1);
@@ -3403,12 +3568,16 @@ static irqreturn_t wm8962_irq(int irq, void *data)
        struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
        int mask;
        int active;
+       int reg;
 
        mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
 
        active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
        active &= ~mask;
 
+       if (!active)
+               return IRQ_NONE;
+
        /* Acknowledge the interrupts */
        snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
 
@@ -3420,9 +3589,21 @@ static irqreturn_t wm8962_irq(int irq, void *data)
        if (active & WM8962_FIFOS_ERR_EINT)
                dev_err(codec->dev, "FIFO error\n");
 
-       if (active & WM8962_TEMP_SHUT_EINT)
+       if (active & WM8962_TEMP_SHUT_EINT) {
                dev_crit(codec->dev, "Thermal shutdown\n");
 
+               reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS);
+
+               if (reg & WM8962_TEMP_ERR_HP)
+                       dev_crit(codec->dev, "Headphone thermal error\n");
+               if (reg & WM8962_TEMP_WARN_HP)
+                       dev_crit(codec->dev, "Headphone thermal warning\n");
+               if (reg & WM8962_TEMP_ERR_SPK)
+                       dev_crit(codec->dev, "Speaker thermal error\n");
+               if (reg & WM8962_TEMP_WARN_SPK)
+                       dev_crit(codec->dev, "Speaker thermal warning\n");
+       }
+
        if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
                dev_dbg(codec->dev, "Microphone event detected\n");
 
@@ -3868,6 +4049,10 @@ static int wm8962_probe(struct snd_soc_codec *codec)
         */
        snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
 
+       /* Ensure we have soft control over all registers */
+       snd_soc_update_bits(codec, WM8962_CLOCKING2,
+                           WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
+
        regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 
        if (pdata) {
index 6e85b8869af7171882d5476137ed63004402bef1..eec8e143511665a538c6950a4f679ad217aad827 100644 (file)
@@ -847,6 +847,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
                    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, NULL, 0),
 
 SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0),
 SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0),
@@ -880,6 +881,9 @@ SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
 };
 
 static const struct snd_soc_dapm_route routes[] = {
+       { "MICBIAS1", NULL, "VMID" },
+       { "MICBIAS2", NULL, "VMID" },
+
        { "ADCL", NULL, "CLK_SYS" },
        { "ADCL", NULL, "CLK_DSP" },
        { "ADCR", NULL, "CLK_SYS" },
@@ -1433,7 +1437,8 @@ static int wm8993_probe(struct snd_soc_codec *codec)
        int ret, i, val;
 
        wm8993->hubs_data.hp_startup_mode = 1;
-       wm8993->hubs_data.dcs_codes = -2;
+       wm8993->hubs_data.dcs_codes_l = -2;
+       wm8993->hubs_data.dcs_codes_r = -2;
        wm8993->hubs_data.series_startup = 1;
 
        ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
index a87adbd05ee11151535bb3231122655c0c226525..df5a8b9a250f47362cc8e03a0f65e8486d5fe188 100644 (file)
@@ -1073,8 +1073,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
        { 0x0000, 0x0000 }, /* R1069 */
        { 0x0000, 0x0000 }, /* R1070 */
        { 0x0000, 0x0000 }, /* R1071 */
-       { 0x0000, 0x0000 }, /* R1072 */
-       { 0x0000, 0x0000 }, /* R1073 */
+       { 0x006F, 0x006F }, /* R1072  - AIF1 DAC1 Noise Gate */
+       { 0x006F, 0x006F }, /* R1073  - AIF1 DAC2 Noise Gate */
        { 0x0000, 0x0000 }, /* R1074 */
        { 0x0000, 0x0000 }, /* R1075 */
        { 0x0000, 0x0000 }, /* R1076 */
@@ -1329,7 +1329,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
        { 0x0000, 0x0000 }, /* R1325 */
        { 0x0000, 0x0000 }, /* R1326 */
        { 0x0000, 0x0000 }, /* R1327 */
-       { 0x0000, 0x0000 }, /* R1328 */
+       { 0x006F, 0x006F }, /* R1328  - AIF2 DAC Noise Gate */
        { 0x0000, 0x0000 }, /* R1329 */
        { 0x0000, 0x0000 }, /* R1330 */
        { 0x0000, 0x0000 }, /* R1331 */
@@ -1635,8 +1635,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
        0x0000,     /* R58    - MICBIAS */
        0x000D,     /* R59    - LDO 1 */
        0x0003,     /* R60    - LDO 2 */
-       0x0000,     /* R61 */
-       0x0000,     /* R62 */
+       0x0039,     /* R61    - MICBIAS1 */
+       0x0039,     /* R62    - MICBIAS2 */
        0x0000,     /* R63 */
        0x0000,     /* R64 */
        0x0000,     /* R65 */
@@ -2646,8 +2646,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
        0x0000,     /* R1069 */
        0x0000,     /* R1070 */
        0x0000,     /* R1071 */
-       0x0000,     /* R1072 */
-       0x0000,     /* R1073 */
+       0x0068,     /* R1072  - AIF1 DAC1 Noise Gate */
+       0x0068,     /* R1073  - AIF1 DAC2 Noise Gate */
        0x0000,     /* R1074 */
        0x0000,     /* R1075 */
        0x0000,     /* R1076 */
@@ -2902,7 +2902,7 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
        0x0000,     /* R1325 */
        0x0000,     /* R1326 */
        0x0000,     /* R1327 */
-       0x0000,     /* R1328 */
+       0x0068,     /* R1328  - AIF2 DAC Noise Gate */
        0x0000,     /* R1329 */
        0x0000,     /* R1330 */
        0x0000,     /* R1331 */
index b393f9fac97a5e75a8bc1b44cb3c6f898482cad3..e5372675123d32ea070b3edc91a2a8fd0e626cfd 100644 (file)
@@ -107,6 +107,7 @@ static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
        case WM8994_LDO_2:
        case WM8958_DSP2_EXECCONTROL:
        case WM8958_MIC_DETECT_3:
+       case WM8994_DC_SERVO_4E:
                return 1;
        default:
                return 0;
@@ -281,6 +282,7 @@ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
 static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
 static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
 static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
 
 #define WM8994_DRC_SWITCH(xname, reg, shift) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -660,8 +662,45 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
               eq_tlv),
 };
 
+static const char *wm8958_ng_text[] = {
+       "30ms", "125ms", "250ms", "500ms",
+};
+
+static const struct soc_enum wm8958_aif1dac1_ng_hold =
+       SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE,
+                       WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text);
+
+static const struct soc_enum wm8958_aif1dac2_ng_hold =
+       SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE,
+                       WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text);
+
+static const struct soc_enum wm8958_aif2dac_ng_hold =
+       SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE,
+                       WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text);
+
 static const struct snd_kcontrol_new wm8958_snd_controls[] = {
 SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
+
+SOC_SINGLE("AIF1DAC1 Noise Gate Switch", WM8958_AIF1_DAC1_NOISE_GATE,
+          WM8958_AIF1DAC1_NG_ENA_SHIFT, 1, 0),
+SOC_ENUM("AIF1DAC1 Noise Gate Hold Time", wm8958_aif1dac1_ng_hold),
+SOC_SINGLE_TLV("AIF1DAC1 Noise Gate Threshold Volume",
+              WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1DAC1_NG_THR_SHIFT,
+              7, 1, ng_tlv),
+
+SOC_SINGLE("AIF1DAC2 Noise Gate Switch", WM8958_AIF1_DAC2_NOISE_GATE,
+          WM8958_AIF1DAC2_NG_ENA_SHIFT, 1, 0),
+SOC_ENUM("AIF1DAC2 Noise Gate Hold Time", wm8958_aif1dac2_ng_hold),
+SOC_SINGLE_TLV("AIF1DAC2 Noise Gate Threshold Volume",
+              WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1DAC2_NG_THR_SHIFT,
+              7, 1, ng_tlv),
+
+SOC_SINGLE("AIF2DAC Noise Gate Switch", WM8958_AIF2_DAC_NOISE_GATE,
+          WM8958_AIF2DAC_NG_ENA_SHIFT, 1, 0),
+SOC_ENUM("AIF2DAC Noise Gate Hold Time", wm8958_aif2dac_ng_hold),
+SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume",
+              WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2DAC_NG_THR_SHIFT,
+              7, 1, ng_tlv),
 };
 
 static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -681,6 +720,97 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static void vmid_reference(struct snd_soc_codec *codec)
+{
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+       wm8994->vmid_refcount++;
+
+       dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
+               wm8994->vmid_refcount);
+
+       if (wm8994->vmid_refcount == 1) {
+               /* Startup bias, VMID ramp & buffer */
+               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                   WM8994_STARTUP_BIAS_ENA |
+                                   WM8994_VMID_BUF_ENA |
+                                   WM8994_VMID_RAMP_MASK,
+                                   WM8994_STARTUP_BIAS_ENA |
+                                   WM8994_VMID_BUF_ENA |
+                                   (0x11 << WM8994_VMID_RAMP_SHIFT));
+
+               /* Main bias enable, VMID=2x40k */
+               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+                                   WM8994_BIAS_ENA |
+                                   WM8994_VMID_SEL_MASK,
+                                   WM8994_BIAS_ENA | 0x2);
+
+               msleep(20);
+       }
+}
+
+static void vmid_dereference(struct snd_soc_codec *codec)
+{
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+       wm8994->vmid_refcount--;
+
+       dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n",
+               wm8994->vmid_refcount);
+
+       if (wm8994->vmid_refcount == 0) {
+               /* Switch over to startup biases */
+               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                   WM8994_BIAS_SRC |
+                                   WM8994_STARTUP_BIAS_ENA |
+                                   WM8994_VMID_BUF_ENA |
+                                   WM8994_VMID_RAMP_MASK,
+                                   WM8994_BIAS_SRC |
+                                   WM8994_STARTUP_BIAS_ENA |
+                                   WM8994_VMID_BUF_ENA |
+                                   (1 << WM8994_VMID_RAMP_SHIFT));
+
+               /* Disable main biases */
+               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+                                   WM8994_BIAS_ENA |
+                                   WM8994_VMID_SEL_MASK, 0);
+
+               /* Discharge line */
+               snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+                                   WM8994_LINEOUT1_DISCH |
+                                   WM8994_LINEOUT2_DISCH,
+                                   WM8994_LINEOUT1_DISCH |
+                                   WM8994_LINEOUT2_DISCH);
+
+               msleep(5);
+
+               /* Switch off startup biases */
+               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                   WM8994_BIAS_SRC |
+                                   WM8994_STARTUP_BIAS_ENA |
+                                   WM8994_VMID_BUF_ENA |
+                                   WM8994_VMID_RAMP_MASK, 0);
+       }
+}
+
+static int vmid_event(struct snd_soc_dapm_widget *w,
+                     struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               vmid_reference(codec);
+               break;
+
+       case SND_SOC_DAPM_POST_PMD:
+               vmid_dereference(codec);
+               break;
+       }
+
+       return 0;
+}
+
 static void wm8994_update_class_w(struct snd_soc_codec *codec)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1208,6 +1338,8 @@ SND_SOC_DAPM_INPUT("Clock"),
 
 SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
                      SND_SOC_DAPM_PRE_PMU),
+SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
+                   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
                    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -1525,6 +1657,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
 static const struct snd_soc_dapm_route wm8994_intercon[] = {
        { "AIF2DACL", NULL, "AIF2DAC Mux" },
        { "AIF2DACR", NULL, "AIF2DAC Mux" },
+       { "MICBIAS1", NULL, "VMID" },
+       { "MICBIAS2", NULL, "VMID" },
 };
 
 static const struct snd_soc_dapm_route wm8958_intercon[] = {
@@ -1629,10 +1763,12 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
                          unsigned int freq_in, unsigned int freq_out)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+       struct wm8994 *control = codec->control_data;
        int reg_offset, ret;
        struct fll_div fll;
        u16 reg, aif1, aif2;
        unsigned long timeout;
+       bool was_enabled;
 
        aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
                & WM8994_AIF1CLK_ENA;
@@ -1653,6 +1789,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
                return -EINVAL;
        }
 
+       reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset);
+       was_enabled = reg & WM8994_FLL1_ENA;
+
        switch (src) {
        case 0:
                /* Allow no source specification when stopping */
@@ -1719,6 +1858,21 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 
        /* Enable (with fractional mode if required) */
        if (freq_out) {
+               /* Enable VMID if we need it */
+               if (!was_enabled) {
+                       switch (control->type) {
+                       case WM8994:
+                               vmid_reference(codec);
+                               break;
+                       case WM8958:
+                               if (wm8994->revision < 1)
+                                       vmid_reference(codec);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
                if (fll.k)
                        reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
                else
@@ -1736,6 +1890,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
                } else {
                        msleep(5);
                }
+       } else {
+               if (was_enabled) {
+                       switch (control->type) {
+                       case WM8994:
+                               vmid_dereference(codec);
+                               break;
+                       case WM8958:
+                               if (wm8994->revision < 1)
+                                       vmid_dereference(codec);
+                               break;
+                       default:
+                               break;
+                       }
+               }
        }
 
        wm8994->fll[id].in = freq_in;
@@ -1852,9 +2020,6 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_PREPARE:
-               /* VMID=2x40k */
-               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                   WM8994_VMID_SEL_MASK, 0x2);
                break;
 
        case SND_SOC_BIAS_STANDBY:
@@ -1896,65 +2061,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
                                            WM8994_LINEOUT2_DISCH,
                                            WM8994_LINEOUT1_DISCH |
                                            WM8994_LINEOUT2_DISCH);
-
-                       /* Startup bias, VMID ramp & buffer */
-                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                           WM8994_STARTUP_BIAS_ENA |
-                                           WM8994_VMID_BUF_ENA |
-                                           WM8994_VMID_RAMP_MASK,
-                                           WM8994_STARTUP_BIAS_ENA |
-                                           WM8994_VMID_BUF_ENA |
-                                           (0x11 << WM8994_VMID_RAMP_SHIFT));
-
-                       /* Main bias enable, VMID=2x40k */
-                       snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                           WM8994_BIAS_ENA |
-                                           WM8994_VMID_SEL_MASK,
-                                           WM8994_BIAS_ENA | 0x2);
-
-                       msleep(20);
                }
 
-               /* VMID=2x500k */
-               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                   WM8994_VMID_SEL_MASK, 0x4);
 
                break;
 
        case SND_SOC_BIAS_OFF:
                if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
-                       /* Switch over to startup biases */
-                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                           WM8994_BIAS_SRC |
-                                           WM8994_STARTUP_BIAS_ENA |
-                                           WM8994_VMID_BUF_ENA |
-                                           WM8994_VMID_RAMP_MASK,
-                                           WM8994_BIAS_SRC |
-                                           WM8994_STARTUP_BIAS_ENA |
-                                           WM8994_VMID_BUF_ENA |
-                                           (1 << WM8994_VMID_RAMP_SHIFT));
-
-                       /* Disable main biases */
-                       snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                           WM8994_BIAS_ENA |
-                                           WM8994_VMID_SEL_MASK, 0);
-
-                       /* Discharge line */
-                       snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
-                                           WM8994_LINEOUT1_DISCH |
-                                           WM8994_LINEOUT2_DISCH,
-                                           WM8994_LINEOUT1_DISCH |
-                                           WM8994_LINEOUT2_DISCH);
-
-                       msleep(5);
-
-                       /* Switch off startup biases */
-                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                           WM8994_BIAS_SRC |
-                                           WM8994_STARTUP_BIAS_ENA |
-                                           WM8994_VMID_BUF_ENA |
-                                           WM8994_VMID_RAMP_MASK, 0);
-
                        wm8994->cur_fw = NULL;
 
                        pm_runtime_put(codec->dev);
@@ -2384,6 +2497,21 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
        return snd_soc_update_bits(codec, reg, mask, val);
 }
 
+static int wm8994_aif2_probe(struct snd_soc_dai *dai)
+{
+       struct snd_soc_codec *codec = dai->codec;
+
+       /* Disable the pulls on the AIF if we're using it to save power. */
+       snd_soc_update_bits(codec, WM8994_GPIO_3,
+                           WM8994_GPN_PU | WM8994_GPN_PD, 0);
+       snd_soc_update_bits(codec, WM8994_GPIO_4,
+                           WM8994_GPN_PU | WM8994_GPN_PD, 0);
+       snd_soc_update_bits(codec, WM8994_GPIO_5,
+                           WM8994_GPN_PU | WM8994_GPN_PD, 0);
+
+       return 0;
+}
+
 #define WM8994_RATES SNDRV_PCM_RATE_8000_96000
 
 #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -2451,6 +2579,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
                        .rates = WM8994_RATES,
                        .formats = WM8994_FORMATS,
                },
+               .probe = wm8994_aif2_probe,
                .ops = &wm8994_aif2_dai_ops,
        },
        {
@@ -2916,6 +3045,24 @@ static irqreturn_t wm8994_fifo_error(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static irqreturn_t wm8994_temp_warn(int irq, void *data)
+{
+       struct snd_soc_codec *codec = data;
+
+       dev_err(codec->dev, "Thermal warning\n");
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t wm8994_temp_shut(int irq, void *data)
+{
+       struct snd_soc_codec *codec = data;
+
+       dev_crit(codec->dev, "Thermal shutdown\n");
+
+       return IRQ_HANDLED;
+}
+
 static int wm8994_codec_probe(struct snd_soc_codec *codec)
 {
        struct wm8994 *control;
@@ -2972,13 +3119,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                switch (wm8994->revision) {
                case 2:
                case 3:
-                       wm8994->hubs.dcs_codes = -5;
+                       wm8994->hubs.dcs_codes_l = -5;
+                       wm8994->hubs.dcs_codes_r = -5;
                        wm8994->hubs.hp_startup_mode = 1;
                        wm8994->hubs.dcs_readback_mode = 1;
                        wm8994->hubs.series_startup = 1;
                        break;
                default:
-                       wm8994->hubs.dcs_readback_mode = 1;
+                       wm8994->hubs.dcs_readback_mode = 2;
                        break;
                }
                break;
@@ -2993,6 +3141,10 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 
        wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
                           wm8994_fifo_error, "FIFO error", codec);
+       wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN,
+                          wm8994_temp_warn, "Thermal warning", codec);
+       wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT,
+                          wm8994_temp_shut, "Thermal shutdown", codec);
 
        ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
                                 wm_hubs_dcs_done, "DC servo done",
@@ -3257,6 +3409,8 @@ err_irq:
        wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
                        &wm8994->hubs);
        wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
+       wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
+       wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
 err:
        kfree(wm8994);
        return ret;
@@ -3279,6 +3433,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
        wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
                        &wm8994->hubs);
        wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
+       wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec);
+       wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec);
 
        switch (control->type) {
        case WM8994:
index 1ab2266039f7ca80b023f212888c1c7f8398bf94..f4f1355efc82ec9708e24993525d65aad9b54e1b 100644 (file)
@@ -83,6 +83,8 @@ struct wm8994_priv {
        struct completion fll_locked[2];
        bool fll_locked_irq;
 
+       int vmid_refcount;
+
        int dac_rates[2];
        int lrclk_shared[2];
 
index ab8e9d1aaff0a0194138cb08a06a806ea8e0559e..73a15888263b1c7af233af3e98f71ea746042633 100644 (file)
@@ -982,21 +982,18 @@ SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
                      SND_SOC_DAPM_POST_PMU),
 
 SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),
 SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),
 SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
 
 SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
 SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
 
-SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
-SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
-SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
-SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
-
-SND_SOC_DAPM_PGA("IN1L", WM8996_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN1R", WM8996_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN2L", WM8996_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("IN2R", WM8996_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
+SND_SOC_DAPM_MUX("IN1L Mux", WM8996_POWER_MANAGEMENT_7, 2, 0, &in1_mux),
+SND_SOC_DAPM_MUX("IN1R Mux", WM8996_POWER_MANAGEMENT_7, 3, 0, &in1_mux),
+SND_SOC_DAPM_MUX("IN2L Mux", WM8996_POWER_MANAGEMENT_7, 6, 0, &in2_mux),
+SND_SOC_DAPM_MUX("IN2R Mux", WM8996_POWER_MANAGEMENT_7, 7, 0, &in2_mux),
 
 SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
@@ -1142,7 +1139,9 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
        { "Charge Pump", NULL, "SYSCLK" },
 
        { "MICB1", NULL, "LDO2" },
+       { "MICB1", NULL, "MICB1 Audio" },
        { "MICB2", NULL, "LDO2" },
+       { "MICB2", NULL, "MICB2 Audio" },
 
        { "IN1L PGA", NULL, "IN2LN" },
        { "IN1L PGA", NULL, "IN2LP" },
@@ -1213,6 +1212,16 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
        { "AIF2RX0", NULL, "AIFCLK" },
        { "AIF2RX1", NULL, "AIFCLK" },
 
+       { "AIF1TX0", NULL, "AIFCLK" },
+       { "AIF1TX1", NULL, "AIFCLK" },
+       { "AIF1TX2", NULL, "AIFCLK" },
+       { "AIF1TX3", NULL, "AIFCLK" },
+       { "AIF1TX4", NULL, "AIFCLK" },
+       { "AIF1TX5", NULL, "AIFCLK" },
+
+       { "AIF2TX0", NULL, "AIFCLK" },
+       { "AIF2TX1", NULL, "AIFCLK" },
+
        { "DSP1RXL", NULL, "SYSDSPCLK" },
        { "DSP1RXR", NULL, "SYSDSPCLK" },
        { "DSP2RXL", NULL, "SYSDSPCLK" },
@@ -2106,6 +2115,9 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 
        snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
 
+       /* Clear any pending completions (eg, from failed startups) */
+       try_wait_for_completion(&wm8996->fll_lock);
+
        snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
                            WM8996_FLL_ENA, WM8996_FLL_ENA);
 
@@ -2404,6 +2416,9 @@ static irqreturn_t wm8996_irq(int irq, void *data)
        }
        irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK);
 
+       if (!irq_val)
+               return IRQ_NONE;
+
        snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val);
 
        if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {
@@ -2422,10 +2437,7 @@ static irqreturn_t wm8996_irq(int irq, void *data)
        if (irq_val & WM8996_MICD_EINT)
                wm8996_micd(codec);
 
-       if (irq_val)
-               return IRQ_HANDLED;
-       else
-               return IRQ_NONE;
+       return IRQ_HANDLED;
 }
 
 static irqreturn_t wm8996_edge_irq(int irq, void *data)
index e763c54c55dc32d5e2b97da5c9bfcd364558adaa..ca8ce03510f4ee460da84d12596c6f54ca1e5522 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/wm8994/registers.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -116,14 +117,23 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
 {
        struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
        s8 offset;
-       u16 reg, reg_l, reg_r, dcs_cfg;
+       u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
+
+       switch (hubs->dcs_readback_mode) {
+       case 2:
+               dcs_reg = WM8994_DC_SERVO_4E;
+               break;
+       default:
+               dcs_reg = WM8993_DC_SERVO_3;
+               break;
+       }
 
        /* If we're using a digital only path and have a previously
         * callibrated DC servo offset stored then use that. */
        if (hubs->class_w && hubs->class_w_dcs) {
                dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
                        hubs->class_w_dcs);
-               snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs);
+               snd_soc_write(codec, dcs_reg, hubs->class_w_dcs);
                wait_for_dc_servo(codec,
                                  WM8993_DCS_TRIG_DAC_WR_0 |
                                  WM8993_DCS_TRIG_DAC_WR_1);
@@ -154,8 +164,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
                reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
                        & WM8993_DCS_INTEG_CHAN_1_MASK;
                break;
+       case 2:
        case 1:
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+               reg = snd_soc_read(codec, dcs_reg);
                reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
                        >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
                reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
@@ -168,24 +179,25 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
        dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
 
        /* Apply correction to DC servo result */
-       if (hubs->dcs_codes) {
-               dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
-                       hubs->dcs_codes);
+       if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
+               dev_dbg(codec->dev,
+                       "Applying %d/%d code DC servo correction\n",
+                       hubs->dcs_codes_l, hubs->dcs_codes_r);
 
                /* HPOUT1R */
                offset = reg_r;
-               offset += hubs->dcs_codes;
+               offset += hubs->dcs_codes_r;
                dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
                /* HPOUT1L */
                offset = reg_l;
-               offset += hubs->dcs_codes;
+               offset += hubs->dcs_codes_l;
                dcs_cfg |= (u8)offset;
 
                dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
 
                /* Do it */
-               snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
+               snd_soc_write(codec, dcs_reg, dcs_cfg);
                wait_for_dc_servo(codec,
                                  WM8993_DCS_TRIG_DAC_WR_0 |
                                  WM8993_DCS_TRIG_DAC_WR_1);
@@ -217,7 +229,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
 
        /* If we're applying an offset correction then updating the
         * callibration would be likely to introduce further offsets. */
-       if (hubs->dcs_codes || hubs->no_series_update)
+       if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
                return ret;
 
        /* Only need to do this if the outputs are active */
@@ -699,6 +711,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
        { "IN1L PGA", "IN1LP Switch", "IN1LP" },
        { "IN1L PGA", "IN1LN Switch", "IN1LN" },
 
+       { "IN1L PGA", NULL, "VMID" },
+       { "IN1R PGA", NULL, "VMID" },
+       { "IN2L PGA", NULL, "VMID" },
+       { "IN2R PGA", NULL, "VMID" },
+
        { "IN1R PGA", "IN1RP Switch", "IN1RP" },
        { "IN1R PGA", "IN1RN Switch", "IN1RN" },
 
@@ -716,12 +733,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
        { "MIXINL", NULL, "Direct Voice" },
        { "MIXINL", NULL, "IN1LP" },
        { "MIXINL", NULL, "Left Output Mixer" },
+       { "MIXINL", NULL, "VMID" },
 
        { "MIXINR", "IN1R Switch", "IN1R PGA" },
        { "MIXINR", "IN2R Switch", "IN2R PGA" },
        { "MIXINR", NULL, "Direct Voice" },
        { "MIXINR", NULL, "IN1RP" },
        { "MIXINR", NULL, "Right Output Mixer" },
+       { "MIXINR", NULL, "VMID" },
 
        { "ADCL", NULL, "MIXINL" },
        { "ADCR", NULL, "MIXINR" },
@@ -752,6 +771,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
        { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
        { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
 
+       { "Earpiece Driver", NULL, "VMID" },
        { "Earpiece Driver", NULL, "Earpiece Mixer" },
        { "HPOUT2N", NULL, "Earpiece Driver" },
        { "HPOUT2P", NULL, "Earpiece Driver" },
@@ -774,9 +794,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
        { "SPKR Boost", "SPKR Switch", "SPKR" },
        { "SPKR Boost", "SPKL Switch", "SPKL" },
 
+       { "SPKL Driver", NULL, "VMID" },
        { "SPKL Driver", NULL, "SPKL Boost" },
        { "SPKL Driver", NULL, "CLK_SYS" },
 
+       { "SPKR Driver", NULL, "VMID" },
        { "SPKR Driver", NULL, "SPKR Boost" },
        { "SPKR Driver", NULL, "CLK_SYS" },
 
@@ -790,12 +812,18 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
 
        { "Headphone PGA", NULL, "Left Headphone Mux" },
        { "Headphone PGA", NULL, "Right Headphone Mux" },
+       { "Headphone PGA", NULL, "VMID" },
        { "Headphone PGA", NULL, "CLK_SYS" },
        { "Headphone PGA", NULL, "Headphone Supply" },
 
        { "HPOUT1L", NULL, "Headphone PGA" },
        { "HPOUT1R", NULL, "Headphone PGA" },
 
+       { "LINEOUT1N Driver", NULL, "VMID" },
+       { "LINEOUT1P Driver", NULL, "VMID" },
+       { "LINEOUT2N Driver", NULL, "VMID" },
+       { "LINEOUT2P Driver", NULL, "VMID" },
+
        { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
        { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
        { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
index 676b1252ab910559a07bc3738051a67e60e765c8..c674c7a502a64e1d02889edfa839522686afdf9b 100644 (file)
@@ -23,7 +23,8 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
 
 /* This *must* be the first element of the codec->private_data struct */
 struct wm_hubs_data {
-       int dcs_codes;
+       int dcs_codes_l;
+       int dcs_codes_r;
        int dcs_readback_mode;
        int hp_startup_mode;
        int series_startup;
index 56efa0c1c9a9c746b70e19e9d3bc966adea0edeb..099614e16651bb78c78e0c805aa56c72c97fe9e9 100644 (file)
@@ -385,14 +385,14 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                err = -ENODEV;
-               goto fail;
+               goto fail_free_info;
        }
 
        info->mem = request_mem_region(res->start, resource_size(res),
                                       pdev->name);
        if (!info->mem) {
                err = -EBUSY;
-               goto fail;
+               goto fail_free_info;
        }
 
        info->regs = ioremap(info->mem->start, resource_size(info->mem));
@@ -435,6 +435,7 @@ fail_unmap_mem:
        iounmap(info->regs);
 fail_release_mem:
        release_mem_region(info->mem->start, resource_size(info->mem));
+fail_free_info:
        kfree(info);
 fail:
        return err;
index 732208c8c0b40c8c3e673ff3c6efd0a071b99e94..ef15402a3bc4948311c69b4b69da9ebd7055ee58 100644 (file)
@@ -297,7 +297,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
 static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_card *card = rtd->card->snd_card;
-       struct snd_soc_dai *dai = rtd->cpu_dai;
        struct snd_pcm *pcm = rtd->pcm;
        static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
        int ret;
@@ -879,10 +878,12 @@ static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
                 * assume that device_node pointers are a valid comparison.
                 */
                np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
+               of_node_put(np);
                if (np == dma_channel_np)
                        return ssi_np;
 
                np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
+               of_node_put(np);
                if (np == dma_channel_np)
                        return ssi_np;
        }
index d48afea5d93d91c5b95d718768a239683c4f05d3..06ac2b92faf33926a174b111a09daa0eee45ddf7 100644 (file)
@@ -289,16 +289,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
         */
        if (!ssi_private->playback && !ssi_private->capture) {
                struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-               int ret;
-
-               /* The 'name' should not have any slashes in it. */
-               ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
-                                 ssi_private->name, ssi_private);
-               if (ret < 0) {
-                       dev_err(substream->pcm->card->dev,
-                               "could not claim irq %u\n", ssi_private->irq);
-                       return ret;
-               }
 
                /*
                 * Section 16.5 of the MPC8610 reference manual says that the
@@ -522,15 +512,12 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
        ssi_private->second_stream = NULL;
 
        /*
-        * If this is the last active substream, disable the SSI and release
-        * the IRQ.
+        * If this is the last active substream, disable the SSI.
         */
        if (!ssi_private->playback && !ssi_private->capture) {
                struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
 
                clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
-
-               free_irq(ssi_private->irq, ssi_private);
        }
 }
 
@@ -675,17 +662,30 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
        ret = of_address_to_resource(np, 0, &res);
        if (ret) {
                dev_err(&pdev->dev, "could not determine device resources\n");
-               kfree(ssi_private);
-               return ret;
+               goto error_kmalloc;
        }
        ssi_private->ssi = of_iomap(np, 0);
        if (!ssi_private->ssi) {
                dev_err(&pdev->dev, "could not map device resources\n");
-               kfree(ssi_private);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto error_kmalloc;
        }
        ssi_private->ssi_phys = res.start;
+
        ssi_private->irq = irq_of_parse_and_map(np, 0);
+       if (ssi_private->irq == NO_IRQ) {
+               dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
+               ret = -ENXIO;
+               goto error_iomap;
+       }
+
+       /* The 'name' should not have any slashes in it. */
+       ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
+                         ssi_private);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
+               goto error_irqmap;
+       }
 
        /* Are the RX and the TX clocks locked? */
        if (of_find_property(np, "fsl,ssi-asynchronous", NULL))
@@ -711,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
        if (ret) {
                dev_err(&pdev->dev, "could not create sysfs %s file\n",
                        ssi_private->dev_attr.attr.name);
-               goto error;
+               goto error_irq;
        }
 
        /* Register with ASoC */
@@ -720,7 +720,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
        ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
        if (ret) {
                dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
-               goto error;
+               goto error_dev;
        }
 
        /* Trigger the machine driver's probe function.  The platform driver
@@ -741,18 +741,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
        if (IS_ERR(ssi_private->pdev)) {
                ret = PTR_ERR(ssi_private->pdev);
                dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
-               goto error;
+               goto error_dai;
        }
 
        return 0;
 
-error:
+error_dai:
        snd_soc_unregister_dai(&pdev->dev);
+
+error_dev:
        dev_set_drvdata(&pdev->dev, NULL);
-       if (dev_attr)
-               device_remove_file(&pdev->dev, dev_attr);
+       device_remove_file(&pdev->dev, dev_attr);
+
+error_irq:
+       free_irq(ssi_private->irq, ssi_private);
+
+error_irqmap:
        irq_dispose_mapping(ssi_private->irq);
+
+error_iomap:
        iounmap(ssi_private->ssi);
+
+error_kmalloc:
        kfree(ssi_private);
 
        return ret;
@@ -766,6 +776,9 @@ static int fsl_ssi_remove(struct platform_device *pdev)
        snd_soc_unregister_dai(&pdev->dev);
        device_remove_file(&pdev->dev, &ssi_private->dev_attr);
 
+       free_irq(ssi_private->irq, ssi_private);
+       irq_dispose_mapping(ssi_private->irq);
+
        kfree(ssi_private);
        dev_set_drvdata(&pdev->dev, NULL);
 
index a19297959587fb422f3efbbe207bc47b500f0168..358f0baaf71b2df230295cda7ccf9f4df2fa901a 100644 (file)
@@ -345,8 +345,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
        }
 
        machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
-       if (!machine_data)
-               return -ENOMEM;
+       if (!machine_data) {
+               ret = -ENOMEM;
+               goto error_alloc;
+       }
 
        machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
        machine_data->dai[0].ops = &mpc8610_hpcd_ops;
@@ -494,7 +496,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
        ret = platform_device_add(sound_device);
        if (ret) {
                dev_err(&pdev->dev, "platform device add failed\n");
-               goto error;
+               goto error_sound;
        }
        dev_set_drvdata(&pdev->dev, sound_device);
 
@@ -502,14 +504,12 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
 
        return 0;
 
+error_sound:
+       platform_device_unregister(sound_device);
 error:
-       of_node_put(codec_np);
-
-       if (sound_device)
-               platform_device_unregister(sound_device);
-
        kfree(machine_data);
-
+error_alloc:
+       of_node_put(codec_np);
        return ret;
 }
 
index 8fa4d5f8eda1deff7c854cb557a199364fc4ce84..fcb862eb0c73420e1c3ecb65c240e8ed2a2569f2 100644 (file)
@@ -297,8 +297,10 @@ static int get_dma_channel(struct device_node *ssi_np,
         * dai->platform name should already point to an allocated buffer.
         */
        ret = of_address_to_resource(dma_channel_np, 0, &res);
-       if (ret)
+       if (ret) {
+               of_node_put(dma_channel_np);
                return ret;
+       }
        snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
                 (unsigned long long) res.start, dma_channel_np->name);
 
index a33fc51f363be864ad2385e434dce97c409b5991..8f16cd37c2af9e74388ae8ebe2f23bce1405f82a 100644 (file)
@@ -424,7 +424,7 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
        if (!priv->mem) {
                dev_err(&pdev->dev, "request_mem_region failed\n");
                err = -EBUSY;
-               goto error;
+               goto error_alloc;
        }
 
        priv->io = ioremap(priv->mem->start, SZ_16K);
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
new file mode 100644 (file)
index 0000000..e4ba8d5
--- /dev/null
@@ -0,0 +1,20 @@
+menuconfig SND_MXS_SOC
+       tristate "SoC Audio for Freescale MXS CPUs"
+       depends on ARCH_MXS
+       select SND_PCM
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the MXS SAIF interface.
+
+
+if SND_MXS_SOC
+
+config SND_SOC_MXS_SGTL5000
+       tristate "SoC Audio support for i.MX boards with sgtl5000"
+       depends on I2C
+       select SND_SOC_SGTL5000
+       help
+         Say Y if you want to add support for SoC audio on an MXS board with
+         a sgtl5000 codec.
+
+endif  # SND_MXS_SOC
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile
new file mode 100644 (file)
index 0000000..565b5b5
--- /dev/null
@@ -0,0 +1,10 @@
+# MXS Platform Support
+snd-soc-mxs-objs := mxs-saif.o
+snd-soc-mxs-pcm-objs := mxs-pcm.o
+
+obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o snd-soc-mxs-pcm.o
+
+# i.MX Machine Support
+snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o
+
+obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
new file mode 100644 (file)
index 0000000..dea5aa4
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Based on sound/soc/imx/imx-pcm-dma-mx2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <mach/dma.h>
+#include "mxs-pcm.h"
+
+static struct snd_pcm_hardware snd_mxs_hardware = {
+       .info                   = SNDRV_PCM_INFO_MMAP |
+                                 SNDRV_PCM_INFO_MMAP_VALID |
+                                 SNDRV_PCM_INFO_PAUSE |
+                                 SNDRV_PCM_INFO_RESUME |
+                                 SNDRV_PCM_INFO_INTERLEAVED,
+       .formats                = SNDRV_PCM_FMTBIT_S16_LE |
+                                 SNDRV_PCM_FMTBIT_S20_3LE |
+                                 SNDRV_PCM_FMTBIT_S24_LE,
+       .channels_min           = 2,
+       .channels_max           = 2,
+       .period_bytes_min       = 32,
+       .period_bytes_max       = 8192,
+       .periods_min            = 1,
+       .periods_max            = 52,
+       .buffer_bytes_max       = 64 * 1024,
+       .fifo_size              = 32,
+
+};
+
+static void audio_dma_irq(void *data)
+{
+       struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+
+       iprtd->offset += iprtd->period_bytes;
+       iprtd->offset %= iprtd->period_bytes * iprtd->periods;
+       snd_pcm_period_elapsed(substream);
+}
+
+static bool filter(struct dma_chan *chan, void *param)
+{
+       struct mxs_pcm_runtime_data *iprtd = param;
+       struct mxs_pcm_dma_params *dma_params = iprtd->dma_params;
+
+       if (!mxs_dma_is_apbx(chan))
+               return false;
+
+       if (chan->chan_id != dma_params->chan_num)
+               return false;
+
+       chan->private = &iprtd->dma_data;
+
+       return true;
+}
+
+static int mxs_dma_alloc(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+       dma_cap_mask_t mask;
+
+       iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+       iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq;
+       iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
+       if (!iprtd->dma_chan)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+       unsigned long dma_addr;
+       struct dma_chan *chan;
+       int ret;
+
+       ret = mxs_dma_alloc(substream, params);
+       if (ret)
+               return ret;
+       chan = iprtd->dma_chan;
+
+       iprtd->size = params_buffer_bytes(params);
+       iprtd->periods = params_periods(params);
+       iprtd->period_bytes = params_period_bytes(params);
+       iprtd->offset = 0;
+       iprtd->period_time = HZ / (params_rate(params) /
+                       params_period_size(params));
+
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+       dma_addr = runtime->dma_addr;
+
+       iprtd->buf = substream->dma_buffer.area;
+
+       iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
+                       iprtd->period_bytes * iprtd->periods,
+                       iprtd->period_bytes,
+                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+                       DMA_TO_DEVICE : DMA_FROM_DEVICE);
+       if (!iprtd->desc) {
+               dev_err(&chan->dev->device, "cannot prepare slave dma\n");
+               return -EINVAL;
+       }
+
+       iprtd->desc->callback = audio_dma_irq;
+       iprtd->desc->callback_param = substream;
+
+       return 0;
+}
+
+static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+
+       if (iprtd->dma_chan) {
+               dma_release_channel(iprtd->dma_chan);
+               iprtd->dma_chan = NULL;
+       }
+
+       return 0;
+}
+
+static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               dmaengine_submit(iprtd->desc);
+
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               dmaengine_terminate_all(iprtd->dma_chan);
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static snd_pcm_uframes_t snd_mxs_pcm_pointer(
+               struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+
+       return bytes_to_frames(substream->runtime, iprtd->offset);
+}
+
+static int snd_mxs_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd;
+       int ret;
+
+       iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
+       if (iprtd == NULL)
+               return -ENOMEM;
+       runtime->private_data = iprtd;
+
+       ret = snd_pcm_hw_constraint_integer(substream->runtime,
+                       SNDRV_PCM_HW_PARAM_PERIODS);
+       if (ret < 0) {
+               kfree(iprtd);
+               return ret;
+       }
+
+       snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
+
+       return 0;
+}
+
+static int snd_mxs_close(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+
+       kfree(iprtd);
+
+       return 0;
+}
+
+static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
+               struct vm_area_struct *vma)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+                                       runtime->dma_area,
+                                       runtime->dma_addr,
+                                       runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops mxs_pcm_ops = {
+       .open           = snd_mxs_open,
+       .close          = snd_mxs_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = snd_mxs_pcm_hw_params,
+       .hw_free        = snd_mxs_pcm_hw_free,
+       .trigger        = snd_mxs_pcm_trigger,
+       .pointer        = snd_mxs_pcm_pointer,
+       .mmap           = snd_mxs_pcm_mmap,
+};
+
+static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+{
+       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+       struct snd_dma_buffer *buf = &substream->dma_buffer;
+       size_t size = snd_mxs_hardware.buffer_bytes_max;
+
+       buf->dev.type = SNDRV_DMA_TYPE_DEV;
+       buf->dev.dev = pcm->card->dev;
+       buf->private_data = NULL;
+       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+                                          &buf->addr, GFP_KERNEL);
+       if (!buf->area)
+               return -ENOMEM;
+       buf->bytes = size;
+
+       return 0;
+}
+
+static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32);
+static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_card *card = rtd->card->snd_card;
+       struct snd_pcm *pcm = rtd->pcm;
+       int ret = 0;
+
+       if (!card->dev->dma_mask)
+               card->dev->dma_mask = &mxs_pcm_dmamask;
+       if (!card->dev->coherent_dma_mask)
+               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+               ret = mxs_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_PLAYBACK);
+               if (ret)
+                       goto out;
+       }
+
+       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+               ret = mxs_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_CAPTURE);
+               if (ret)
+                       goto out;
+       }
+
+out:
+       return ret;
+}
+
+static void mxs_pcm_free(struct snd_pcm *pcm)
+{
+       struct snd_pcm_substream *substream;
+       struct snd_dma_buffer *buf;
+       int stream;
+
+       for (stream = 0; stream < 2; stream++) {
+               substream = pcm->streams[stream].substream;
+               if (!substream)
+                       continue;
+
+               buf = &substream->dma_buffer;
+               if (!buf->area)
+                       continue;
+
+               dma_free_writecombine(pcm->card->dev, buf->bytes,
+                                     buf->area, buf->addr);
+               buf->area = NULL;
+       }
+}
+
+static struct snd_soc_platform_driver mxs_soc_platform = {
+       .ops            = &mxs_pcm_ops,
+       .pcm_new        = mxs_pcm_new,
+       .pcm_free       = mxs_pcm_free,
+};
+
+static int __devinit mxs_soc_platform_probe(struct platform_device *pdev)
+{
+       return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform);
+}
+
+static int __devexit mxs_soc_platform_remove(struct platform_device *pdev)
+{
+       snd_soc_unregister_platform(&pdev->dev);
+
+       return 0;
+}
+
+static struct platform_driver mxs_pcm_driver = {
+       .driver = {
+               .name = "mxs-pcm-audio",
+               .owner = THIS_MODULE,
+       },
+       .probe = mxs_soc_platform_probe,
+       .remove = __devexit_p(mxs_soc_platform_remove),
+};
+
+static int __init snd_mxs_pcm_init(void)
+{
+       return platform_driver_register(&mxs_pcm_driver);
+}
+module_init(snd_mxs_pcm_init);
+
+static void __exit snd_mxs_pcm_exit(void)
+{
+       platform_driver_unregister(&mxs_pcm_driver);
+}
+module_exit(snd_mxs_pcm_exit);
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
new file mode 100644 (file)
index 0000000..f55ac4f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _MXS_PCM_H
+#define _MXS_PCM_H
+
+#include <mach/dma.h>
+
+struct mxs_pcm_dma_params {
+       int chan_irq;
+       int chan_num;
+};
+
+struct mxs_pcm_runtime_data {
+       int period_bytes;
+       int periods;
+       int dma;
+       unsigned long offset;
+       unsigned long size;
+       void *buf;
+       int period_time;
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *dma_chan;
+       struct mxs_dma_data dma_data;
+       struct mxs_pcm_dma_params *dma_params;
+};
+
+#endif
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
new file mode 100644 (file)
index 0000000..af5734f
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <mach/dma.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/mxs.h>
+
+#include "mxs-saif.h"
+
+static struct mxs_saif *mxs_saif[2];
+
+static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+                       int clk_id, unsigned int freq, int dir)
+{
+       struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+
+       switch (clk_id) {
+       case MXS_SAIF_MCLK:
+               saif->mclk = freq;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * Set SAIF clock and MCLK
+ */
+static int mxs_saif_set_clk(struct mxs_saif *saif,
+                                 unsigned int mclk,
+                                 unsigned int rate)
+{
+       u32 scr;
+       int ret;
+
+       scr = __raw_readl(saif->base + SAIF_CTRL);
+       scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE;
+       scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
+
+       /*
+        * Set SAIF clock
+        *
+        * The SAIF clock should be either 384*fs or 512*fs.
+        * If MCLK is used, the SAIF clk ratio need to match mclk ratio.
+        *  For 32x mclk, set saif clk as 512*fs.
+        *  For 48x mclk, set saif clk as 384*fs.
+        *
+        * If MCLK is not used, we just set saif clk to 512*fs.
+        */
+       if (saif->mclk_in_use) {
+               if (mclk % 32 == 0) {
+                       scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
+                       ret = clk_set_rate(saif->clk, 512 * rate);
+               } else if (mclk % 48 == 0) {
+                       scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE;
+                       ret = clk_set_rate(saif->clk, 384 * rate);
+               } else {
+                       /* SAIF MCLK should be either 32x or 48x */
+                       return -EINVAL;
+               }
+       } else {
+               ret = clk_set_rate(saif->clk, 512 * rate);
+               scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
+       }
+
+       if (ret)
+               return ret;
+
+       if (!saif->mclk_in_use) {
+               __raw_writel(scr, saif->base + SAIF_CTRL);
+               return 0;
+       }
+
+       /*
+        * Program the over-sample rate for MCLK output
+        *
+        * The available MCLK range is 32x, 48x... 512x. The rate
+        * could be from 8kHz to 192kH.
+        */
+       switch (mclk / rate) {
+       case 32:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4);
+               break;
+       case 64:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
+               break;
+       case 128:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
+               break;
+       case 256:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
+               break;
+       case 512:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
+               break;
+       case 48:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3);
+               break;
+       case 96:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2);
+               break;
+       case 192:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1);
+               break;
+       case 384:
+               scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       __raw_writel(scr, saif->base + SAIF_CTRL);
+
+       return 0;
+}
+
+/*
+ * Put and disable MCLK.
+ */
+int mxs_saif_put_mclk(unsigned int saif_id)
+{
+       struct mxs_saif *saif = mxs_saif[saif_id];
+       u32 stat;
+
+       if (!saif)
+               return -EINVAL;
+
+       stat = __raw_readl(saif->base + SAIF_STAT);
+       if (stat & BM_SAIF_STAT_BUSY) {
+               dev_err(saif->dev, "error: busy\n");
+               return -EBUSY;
+       }
+
+       clk_disable(saif->clk);
+
+       /* disable MCLK output */
+       __raw_writel(BM_SAIF_CTRL_CLKGATE,
+               saif->base + SAIF_CTRL + MXS_SET_ADDR);
+       __raw_writel(BM_SAIF_CTRL_RUN,
+               saif->base + SAIF_CTRL + MXS_CLR_ADDR);
+
+       saif->mclk_in_use = 0;
+       return 0;
+}
+
+/*
+ * Get MCLK and set clock rate, then enable it
+ *
+ * This interface is used for codecs who are using MCLK provided
+ * by saif.
+ */
+int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
+                                       unsigned int rate)
+{
+       struct mxs_saif *saif = mxs_saif[saif_id];
+       u32 stat;
+       int ret;
+
+       if (!saif)
+               return -EINVAL;
+
+       /* Clear Reset */
+       __raw_writel(BM_SAIF_CTRL_SFTRST,
+               saif->base + SAIF_CTRL + MXS_CLR_ADDR);
+
+       /* FIXME: need clear clk gate for register r/w */
+       __raw_writel(BM_SAIF_CTRL_CLKGATE,
+               saif->base + SAIF_CTRL + MXS_CLR_ADDR);
+
+       stat = __raw_readl(saif->base + SAIF_STAT);
+       if (stat & BM_SAIF_STAT_BUSY) {
+               dev_err(saif->dev, "error: busy\n");
+               return -EBUSY;
+       }
+
+       saif->mclk_in_use = 1;
+       ret = mxs_saif_set_clk(saif, mclk, rate);
+       if (ret)
+               return ret;
+
+       ret = clk_enable(saif->clk);
+       if (ret)
+               return ret;
+
+       /* enable MCLK output */
+       __raw_writel(BM_SAIF_CTRL_RUN,
+               saif->base + SAIF_CTRL + MXS_SET_ADDR);
+
+       return 0;
+}
+
+/*
+ * SAIF DAI format configuration.
+ * Should only be called when port is inactive.
+ */
+static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+       u32 scr, stat;
+       u32 scr0;
+       struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+
+       stat = __raw_readl(saif->base + SAIF_STAT);
+       if (stat & BM_SAIF_STAT_BUSY) {
+               dev_err(cpu_dai->dev, "error: busy\n");
+               return -EBUSY;
+       }
+
+       scr0 = __raw_readl(saif->base + SAIF_CTRL);
+       scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \
+               & ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY;
+       scr = 0;
+
+       /* DAI mode */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               /* data frame low 1clk before data */
+               scr |= BM_SAIF_CTRL_DELAY;
+               scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               /* data frame high with data */
+               scr &= ~BM_SAIF_CTRL_DELAY;
+               scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
+               scr &= ~BM_SAIF_CTRL_JUSTIFY;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* DAI clock inversion */
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_IB_IF:
+               scr |= BM_SAIF_CTRL_BITCLK_EDGE;
+               scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               scr |= BM_SAIF_CTRL_BITCLK_EDGE;
+               scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
+               scr |= BM_SAIF_CTRL_LRCLK_POLARITY;
+               break;
+       case SND_SOC_DAIFMT_NB_NF:
+               scr &= ~BM_SAIF_CTRL_BITCLK_EDGE;
+               scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY;
+               break;
+       }
+
+       /*
+        * Note: We simply just support master mode since SAIF TX can only
+        * work as master.
+        */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               scr &= ~BM_SAIF_CTRL_SLAVE_MODE;
+               __raw_writel(scr | scr0, saif->base + SAIF_CTRL);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int mxs_saif_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *cpu_dai)
+{
+       struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+       snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param);
+
+       /* clear error status to 0 for each re-open */
+       saif->fifo_underrun = 0;
+       saif->fifo_overrun = 0;
+
+       /* Clear Reset for normal operations */
+       __raw_writel(BM_SAIF_CTRL_SFTRST,
+               saif->base + SAIF_CTRL + MXS_CLR_ADDR);
+
+       /* clear clock gate */
+       __raw_writel(BM_SAIF_CTRL_CLKGATE,
+               saif->base + SAIF_CTRL + MXS_CLR_ADDR);
+
+       return 0;
+}
+
+/*
+ * Should only be called when port is inactive.
+ * although can be called multiple times by upper layers.
+ */
+static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params,
+                            struct snd_soc_dai *cpu_dai)
+{
+       struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 scr, stat;
+       int ret;
+
+       /* mclk should already be set */
+       if (!saif->mclk && saif->mclk_in_use) {
+               dev_err(cpu_dai->dev, "set mclk first\n");
+               return -EINVAL;
+       }
+
+       stat = __raw_readl(saif->base + SAIF_STAT);
+       if (stat & BM_SAIF_STAT_BUSY) {
+               dev_err(cpu_dai->dev, "error: busy\n");
+               return -EBUSY;
+       }
+
+       /*
+        * Set saif clk based on sample rate.
+        * If mclk is used, we also set mclk, if not, saif->mclk is
+        * default 0, means not used.
+        */
+       ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params));
+       if (ret) {
+               dev_err(cpu_dai->dev, "unable to get proper clk\n");
+               return ret;
+       }
+
+       scr = __raw_readl(saif->base + SAIF_CTRL);
+
+       scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
+       scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               scr |= BF_SAIF_CTRL_WORD_LENGTH(0);
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               scr |= BF_SAIF_CTRL_WORD_LENGTH(4);
+               scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               scr |= BF_SAIF_CTRL_WORD_LENGTH(8);
+               scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Tx/Rx config */
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               /* enable TX mode */
+               scr &= ~BM_SAIF_CTRL_READ_MODE;
+       } else {
+               /* enable RX mode */
+               scr |= BM_SAIF_CTRL_READ_MODE;
+       }
+
+       __raw_writel(scr, saif->base + SAIF_CTRL);
+       return 0;
+}
+
+static int mxs_saif_prepare(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *cpu_dai)
+{
+       struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+
+       /* enable FIFO error irqs */
+       __raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN,
+               saif->base + SAIF_CTRL + MXS_SET_ADDR);
+
+       return 0;
+}
+
+static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
+                               struct snd_soc_dai *cpu_dai)
+{
+       struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               dev_dbg(cpu_dai->dev, "start\n");
+
+               clk_enable(saif->clk);
+               if (!saif->mclk_in_use)
+                       __raw_writel(BM_SAIF_CTRL_RUN,
+                               saif->base + SAIF_CTRL + MXS_SET_ADDR);
+
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       /*
+                        * write a data to saif data register to trigger
+                        * the transfer
+                        */
+                       __raw_writel(0, saif->base + SAIF_DATA);
+               } else {
+                       /*
+                        * read a data from saif data register to trigger
+                        * the receive
+                        */
+                       __raw_readl(saif->base + SAIF_DATA);
+               }
+
+               dev_dbg(cpu_dai->dev, "CTRL 0x%x STAT 0x%x\n",
+                       __raw_readl(saif->base + SAIF_CTRL),
+                       __raw_readl(saif->base + SAIF_STAT));
+
+               break;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               dev_dbg(cpu_dai->dev, "stop\n");
+
+               clk_disable(saif->clk);
+               if (!saif->mclk_in_use)
+                       __raw_writel(BM_SAIF_CTRL_RUN,
+                               saif->base + SAIF_CTRL + MXS_CLR_ADDR);
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+#define MXS_SAIF_RATES         SNDRV_PCM_RATE_8000_192000
+#define MXS_SAIF_FORMATS \
+       (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+       SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops mxs_saif_dai_ops = {
+       .startup = mxs_saif_startup,
+       .trigger = mxs_saif_trigger,
+       .prepare = mxs_saif_prepare,
+       .hw_params = mxs_saif_hw_params,
+       .set_sysclk = mxs_saif_set_dai_sysclk,
+       .set_fmt = mxs_saif_set_dai_fmt,
+};
+
+static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
+{
+       struct mxs_saif *saif = dev_get_drvdata(dai->dev);
+
+       snd_soc_dai_set_drvdata(dai, saif);
+
+       return 0;
+}
+
+static struct snd_soc_dai_driver mxs_saif_dai = {
+       .name = "mxs-saif",
+       .probe = mxs_saif_dai_probe,
+       .playback = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = MXS_SAIF_RATES,
+               .formats = MXS_SAIF_FORMATS,
+       },
+       .capture = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = MXS_SAIF_RATES,
+               .formats = MXS_SAIF_FORMATS,
+       },
+       .ops = &mxs_saif_dai_ops,
+};
+
+static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
+{
+       struct mxs_saif *saif = dev_id;
+       unsigned int stat;
+
+       stat = __raw_readl(saif->base + SAIF_STAT);
+       if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ |
+                       BM_SAIF_STAT_FIFO_OVERFLOW_IRQ)))
+               return IRQ_NONE;
+
+       if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) {
+               dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun);
+               __raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ,
+                               saif->base + SAIF_STAT + MXS_CLR_ADDR);
+       }
+
+       if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) {
+               dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun);
+               __raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ,
+                               saif->base + SAIF_STAT + MXS_CLR_ADDR);
+       }
+
+       dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n",
+              __raw_readl(saif->base + SAIF_CTRL),
+              __raw_readl(saif->base + SAIF_STAT));
+
+       return IRQ_HANDLED;
+}
+
+static int mxs_saif_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct mxs_saif *saif;
+       int ret = 0;
+
+       if (pdev->id >= ARRAY_SIZE(mxs_saif))
+               return -EINVAL;
+
+       saif = kzalloc(sizeof(*saif), GFP_KERNEL);
+       if (!saif)
+               return -ENOMEM;
+
+       mxs_saif[pdev->id] = saif;
+
+       saif->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(saif->clk)) {
+               ret = PTR_ERR(saif->clk);
+               dev_err(&pdev->dev, "Cannot get the clock: %d\n",
+                       ret);
+               goto failed_clk;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               dev_err(&pdev->dev, "failed to get io resource: %d\n",
+                       ret);
+               goto failed_get_resource;
+       }
+
+       if (!request_mem_region(res->start, resource_size(res), "mxs-saif")) {
+               dev_err(&pdev->dev, "request_mem_region failed\n");
+               ret = -EBUSY;
+               goto failed_get_resource;
+       }
+
+       saif->base = ioremap(res->start, resource_size(res));
+       if (!saif->base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENODEV;
+               goto failed_ioremap;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!res) {
+               ret = -ENODEV;
+               dev_err(&pdev->dev, "failed to get dma resource: %d\n",
+                       ret);
+               goto failed_ioremap;
+       }
+       saif->dma_param.chan_num = res->start;
+
+       saif->irq = platform_get_irq(pdev, 0);
+       if (saif->irq < 0) {
+               ret = saif->irq;
+               dev_err(&pdev->dev, "failed to get irq resource: %d\n",
+                       ret);
+               goto failed_get_irq1;
+       }
+
+       saif->dev = &pdev->dev;
+       ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request irq\n");
+               goto failed_get_irq1;
+       }
+
+       saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
+       if (saif->dma_param.chan_irq < 0) {
+               ret = saif->dma_param.chan_irq;
+               dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
+                       ret);
+               goto failed_get_irq2;
+       }
+
+       platform_set_drvdata(pdev, saif);
+
+       ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
+       if (ret) {
+               dev_err(&pdev->dev, "register DAI failed\n");
+               goto failed_register;
+       }
+
+       saif->soc_platform_pdev = platform_device_alloc(
+                                       "mxs-pcm-audio", pdev->id);
+       if (!saif->soc_platform_pdev) {
+               ret = -ENOMEM;
+               goto failed_pdev_alloc;
+       }
+
+       platform_set_drvdata(saif->soc_platform_pdev, saif);
+       ret = platform_device_add(saif->soc_platform_pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to add soc platform device\n");
+               goto failed_pdev_add;
+       }
+
+       return 0;
+
+failed_pdev_add:
+       platform_device_put(saif->soc_platform_pdev);
+failed_pdev_alloc:
+       snd_soc_unregister_dai(&pdev->dev);
+failed_register:
+failed_get_irq2:
+       free_irq(saif->irq, saif);
+failed_get_irq1:
+       iounmap(saif->base);
+failed_ioremap:
+       release_mem_region(res->start, resource_size(res));
+failed_get_resource:
+       clk_put(saif->clk);
+failed_clk:
+       kfree(saif);
+
+       return ret;
+}
+
+static int __devexit mxs_saif_remove(struct platform_device *pdev)
+{
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct mxs_saif *saif = platform_get_drvdata(pdev);
+
+       platform_device_unregister(saif->soc_platform_pdev);
+
+       snd_soc_unregister_dai(&pdev->dev);
+
+       iounmap(saif->base);
+       release_mem_region(res->start, resource_size(res));
+       free_irq(saif->irq, saif);
+
+       clk_put(saif->clk);
+       kfree(saif);
+
+       return 0;
+}
+
+static struct platform_driver mxs_saif_driver = {
+       .probe = mxs_saif_probe,
+       .remove = __devexit_p(mxs_saif_remove),
+
+       .driver = {
+               .name = "mxs-saif",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init mxs_saif_init(void)
+{
+       return platform_driver_register(&mxs_saif_driver);
+}
+
+static void __exit mxs_saif_exit(void)
+{
+       platform_driver_unregister(&mxs_saif_driver);
+}
+
+module_init(mxs_saif_init);
+module_exit(mxs_saif_exit);
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXS ASoC SAIF driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h
new file mode 100644 (file)
index 0000000..0e2ff8c
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#ifndef _MXS_SAIF_H
+#define _MXS_SAIF_H
+
+#define SAIF_CTRL      0x0
+#define SAIF_STAT      0x10
+#define SAIF_DATA      0x20
+#define SAIF_VERSION   0X30
+
+/* SAIF_CTRL */
+#define BM_SAIF_CTRL_SFTRST            0x80000000
+#define BM_SAIF_CTRL_CLKGATE           0x40000000
+#define BP_SAIF_CTRL_BITCLK_MULT_RATE  27
+#define BM_SAIF_CTRL_BITCLK_MULT_RATE  0x38000000
+#define BF_SAIF_CTRL_BITCLK_MULT_RATE(v) \
+               (((v) << 27) & BM_SAIF_CTRL_BITCLK_MULT_RATE)
+#define BM_SAIF_CTRL_BITCLK_BASE_RATE  0x04000000
+#define BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN 0x02000000
+#define BM_SAIF_CTRL_FIFO_SERVICE_IRQ_EN       0x01000000
+#define BP_SAIF_CTRL_RSRVD2            21
+#define BM_SAIF_CTRL_RSRVD2            0x00E00000
+
+#define BP_SAIF_CTRL_DMAWAIT_COUNT     16
+#define BM_SAIF_CTRL_DMAWAIT_COUNT     0x001F0000
+#define BF_SAIF_CTRL_DMAWAIT_COUNT(v) \
+               (((v) << 16) & BM_SAIF_CTRL_DMAWAIT_COUNT)
+#define BP_SAIF_CTRL_CHANNEL_NUM_SELECT 14
+#define BM_SAIF_CTRL_CHANNEL_NUM_SELECT 0x0000C000
+#define BF_SAIF_CTRL_CHANNEL_NUM_SELECT(v) \
+               (((v) << 14) & BM_SAIF_CTRL_CHANNEL_NUM_SELECT)
+#define BM_SAIF_CTRL_LRCLK_PULSE       0x00002000
+#define BM_SAIF_CTRL_BIT_ORDER         0x00001000
+#define BM_SAIF_CTRL_DELAY             0x00000800
+#define BM_SAIF_CTRL_JUSTIFY           0x00000400
+#define BM_SAIF_CTRL_LRCLK_POLARITY    0x00000200
+#define BM_SAIF_CTRL_BITCLK_EDGE       0x00000100
+#define BP_SAIF_CTRL_WORD_LENGTH       4
+#define BM_SAIF_CTRL_WORD_LENGTH       0x000000F0
+#define BF_SAIF_CTRL_WORD_LENGTH(v) \
+               (((v) << 4) & BM_SAIF_CTRL_WORD_LENGTH)
+#define BM_SAIF_CTRL_BITCLK_48XFS_ENABLE       0x00000008
+#define BM_SAIF_CTRL_SLAVE_MODE                0x00000004
+#define BM_SAIF_CTRL_READ_MODE         0x00000002
+#define BM_SAIF_CTRL_RUN               0x00000001
+
+/* SAIF_STAT */
+#define BM_SAIF_STAT_PRESENT           0x80000000
+#define BP_SAIF_STAT_RSRVD2            17
+#define BM_SAIF_STAT_RSRVD2            0x7FFE0000
+#define BF_SAIF_STAT_RSRVD2(v) \
+               (((v) << 17) & BM_SAIF_STAT_RSRVD2)
+#define BM_SAIF_STAT_DMA_PREQ          0x00010000
+#define BP_SAIF_STAT_RSRVD1            7
+#define BM_SAIF_STAT_RSRVD1            0x0000FF80
+#define BF_SAIF_STAT_RSRVD1(v) \
+               (((v) << 7) & BM_SAIF_STAT_RSRVD1)
+
+#define BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ 0x00000040
+#define BM_SAIF_STAT_FIFO_OVERFLOW_IRQ 0x00000020
+#define BM_SAIF_STAT_FIFO_SERVICE_IRQ  0x00000010
+#define BP_SAIF_STAT_RSRVD0            1
+#define BM_SAIF_STAT_RSRVD0            0x0000000E
+#define BF_SAIF_STAT_RSRVD0(v) \
+               (((v) << 1) & BM_SAIF_STAT_RSRVD0)
+#define BM_SAIF_STAT_BUSY              0x00000001
+
+/* SAFI_DATA */
+#define BP_SAIF_DATA_PCM_RIGHT         16
+#define BM_SAIF_DATA_PCM_RIGHT         0xFFFF0000
+#define BF_SAIF_DATA_PCM_RIGHT(v) \
+               (((v) << 16) & BM_SAIF_DATA_PCM_RIGHT)
+#define BP_SAIF_DATA_PCM_LEFT          0
+#define BM_SAIF_DATA_PCM_LEFT          0x0000FFFF
+#define BF_SAIF_DATA_PCM_LEFT(v)       \
+               (((v) << 0) & BM_SAIF_DATA_PCM_LEFT)
+
+/* SAIF_VERSION */
+#define BP_SAIF_VERSION_MAJOR          24
+#define BM_SAIF_VERSION_MAJOR          0xFF000000
+#define BF_SAIF_VERSION_MAJOR(v) \
+               (((v) << 24) & BM_SAIF_VERSION_MAJOR)
+#define BP_SAIF_VERSION_MINOR          16
+#define BM_SAIF_VERSION_MINOR          0x00FF0000
+#define BF_SAIF_VERSION_MINOR(v) \
+               (((v) << 16) & BM_SAIF_VERSION_MINOR)
+#define BP_SAIF_VERSION_STEP           0
+#define BM_SAIF_VERSION_STEP           0x0000FFFF
+#define BF_SAIF_VERSION_STEP(v) \
+               (((v) << 0) & BM_SAIF_VERSION_STEP)
+
+#define MXS_SAIF_MCLK          0
+
+#include "mxs-pcm.h"
+
+struct mxs_saif {
+       struct device *dev;
+       struct clk *clk;
+       unsigned int mclk;
+       unsigned int mclk_in_use;
+       void __iomem *base;
+       int irq;
+       struct mxs_pcm_dma_params dma_param;
+
+       struct platform_device *soc_platform_pdev;
+       u32 fifo_underrun;
+       u32 fifo_overrun;
+};
+
+extern int mxs_saif_put_mclk(unsigned int saif_id);
+extern int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
+                                       unsigned int rate);
+#endif
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
new file mode 100644 (file)
index 0000000..7fbeaec
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/soc-dapm.h>
+#include <asm/mach-types.h>
+
+#include "../codecs/sgtl5000.h"
+#include "mxs-saif.h"
+
+static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       unsigned int rate = params_rate(params);
+       u32 dai_format, mclk;
+       int ret;
+
+       /* sgtl5000 does not support 512*rate when in 96000 fs */
+       switch (rate) {
+       case 96000:
+               mclk = 256 * rate;
+               break;
+       default:
+               mclk = 512 * rate;
+               break;
+       }
+
+       /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */
+       if (mclk < 8000000 || mclk > 27000000)
+               return -EINVAL;
+
+       /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */
+       ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0);
+       if (ret)
+               return ret;
+
+       /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */
+       ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0);
+       if (ret)
+               return ret;
+
+       /* set codec to slave mode */
+       dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS;
+
+       /* set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
+       if (ret)
+               return ret;
+
+       /* set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_ops mxs_sgtl5000_hifi_ops = {
+       .hw_params = mxs_sgtl5000_hw_params,
+};
+
+static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
+       {
+               .name           = "HiFi Tx",
+               .stream_name    = "HiFi Playback",
+               .codec_dai_name = "sgtl5000",
+               .codec_name     = "sgtl5000.0-000a",
+               .cpu_dai_name   = "mxs-saif.0",
+               .platform_name  = "mxs-pcm-audio.0",
+               .ops            = &mxs_sgtl5000_hifi_ops,
+       }, {
+               .name           = "HiFi Rx",
+               .stream_name    = "HiFi Capture",
+               .codec_dai_name = "sgtl5000",
+               .codec_name     = "sgtl5000.0-000a",
+               .cpu_dai_name   = "mxs-saif.1",
+               .platform_name  = "mxs-pcm-audio.1",
+               .ops            = &mxs_sgtl5000_hifi_ops,
+       },
+};
+
+static struct snd_soc_card mxs_sgtl5000 = {
+       .name           = "mxs_sgtl5000",
+       .dai_link       = mxs_sgtl5000_dai,
+       .num_links      = ARRAY_SIZE(mxs_sgtl5000_dai),
+};
+
+static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &mxs_sgtl5000;
+       int ret;
+
+       /*
+        * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
+        * The Sgtl5000 sysclk is derived from saif0 mclk and it's range
+        * should be >= 8MHz and <= 27M.
+        */
+       ret = mxs_saif_get_mclk(0, 44100 * 256, 44100);
+       if (ret)
+               return ret;
+
+       card->dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+
+       ret = snd_soc_register_card(card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+                       ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+       mxs_saif_put_mclk(0);
+
+       snd_soc_unregister_card(card);
+
+       return 0;
+}
+
+static struct platform_driver mxs_sgtl5000_audio_driver = {
+       .driver = {
+               .name = "mxs-sgtl5000",
+               .owner = THIS_MODULE,
+       },
+       .probe = mxs_sgtl5000_probe,
+       .remove = __devexit_p(mxs_sgtl5000_remove),
+};
+
+static int __init mxs_sgtl5000_init(void)
+{
+       return platform_driver_register(&mxs_sgtl5000_audio_driver);
+}
+module_init(mxs_sgtl5000_init);
+
+static void __exit mxs_sgtl5000_exit(void)
+{
+       platform_driver_unregister(&mxs_sgtl5000_audio_driver);
+}
+module_exit(mxs_sgtl5000_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
+MODULE_LICENSE("GPL");
index d589ef14e917e95648b91daede2c53eae079e6a5..e46d5516e000c65e1c05894cb7d84076aab34d8e 100644 (file)
@@ -318,7 +318,6 @@ static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
 static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_card *card = rtd->card->snd_card;
-       struct snd_soc_dai *dai = rtd->cpu_dai;
        struct snd_pcm *pcm = rtd->pcm;
 
        if (!card->dev->dma_mask)
index 30fe0d0efe1c7b5d290d5f247d271f6231340cf1..0aa475f92efaac9f01ad36d7fc2d334acdc1d0df 100644 (file)
@@ -514,7 +514,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
        }
 
        /* Set codec bias level */
-       ams_delta_set_bias_level(card, SND_SOC_BIAS_STANDBY);
+       ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY);
 
        /* Add hook switch - can be used to control the codec from userspace
         * even if line discipline fails */
@@ -649,7 +649,9 @@ static void __exit ams_delta_module_exit(void)
                        ams_delta_hook_switch_gpios);
 
        /* Keep modem power on */
-       ams_delta_set_bias_level(&ams_delta_audio_card, SND_SOC_BIAS_STANDBY);
+       ams_delta_set_bias_level(&ams_delta_audio_card,
+                                &ams_delta_audio_card.rtd[0].codec->dapm,
+                                SND_SOC_BIAS_STANDBY);
 
        platform_device_unregister(cx20442_platform_device);
        platform_device_unregister(ams_delta_audio_platform_device);
index b253d864868a558001dd9e6e90b0e33d739a254d..ce920e3cfea1ff58e825236da133250831239a25 100644 (file)
@@ -312,7 +312,7 @@ static struct snd_soc_dai_link spitz_dai = {
        .cpu_dai_name = "pxa2xx-i2s",
        .codec_dai_name = "wm8750-hifi",
        .platform_name = "pxa-pcm-audio",
-       .codec_name = "wm8750-codec.0-001b",
+       .codec_name = "wm8750.0-001b",
        .init = spitz_wm8750_init,
        .ops = &spitz_ops,
 };
index d69d9fc32233f0f8935920fc4fb68dcb4e03f9f2..4b81ffd87566eeda0cb6b4f7ed53b52b9050a936 100644 (file)
@@ -198,7 +198,7 @@ static struct snd_soc_dai_link z2_dai = {
        .cpu_dai_name   = "pxa2xx-i2s",
        .codec_dai_name = "wm8750-hifi",
        .platform_name = "pxa-pcm-audio",
-       .codec_name     = "wm8750-codec.0-001b",
+       .codec_name     = "wm8750.0-001b",
        .init           = z2_wm8750_init,
        .ops            = &z2_ops,
 };
index 80c85fd64e1aac4311502e2688f1f64da09fbf67..55efc2bdf0bd0a4fd73f938299764222601a5014 100644 (file)
@@ -446,7 +446,6 @@ static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
 static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_card *card = runtime->card->snd_card;
-       struct snd_soc_dai *dai = runtime->cpu_dai;
        struct snd_pcm *pcm = runtime->pcm;
        struct s6000_pcm_dma_params *params;
        int res;
index 241f55d0066070b299159c0f92f6f8836fed4ad5..c6c65892294e4bf8cee9829a1c6fb456e522aebd 100644 (file)
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/types.h>
 #include <linux/gpio.h>
 
 #include <sound/soc.h>
index 14eb6ea69e7c50f71791be271f17d5fd5c33f27f..ed8f13a29c859660afc4142ca1b945577f441506 100644 (file)
@@ -131,7 +131,7 @@ static struct snd_soc_dai_link jive_dai = {
        .cpu_dai_name   = "s3c2412-i2s",
        .codec_dai_name = "wm8750-hifi",
        .platform_name  = "samsung-audio",
-       .codec_name     = "wm8750-codec.0-001a",
+       .codec_name     = "wm8750.0-001a",
        .init           = jive_wm8750_init,
        .ops            = &jive_ops,
 };
index 1e574a5d440d0610e77d68c1d9582a2765719d01..bc8c1676459f781b56b28e5fbcadd9ad7732f4a4 100644 (file)
@@ -17,6 +17,7 @@
  *
  */
 
+#include <linux/types.h>
 #include <linux/gpio.h>
 
 #include <sound/soc.h>
index 0a2c4f22303811b55921452f783ae485fefb3bdd..bbd14768ecd3dafc559ecee6ddfff34d855cf2c5 100644 (file)
@@ -207,7 +207,7 @@ static struct snd_soc_dai_link smartq_dai[] = {
                .cpu_dai_name   = "samsung-i2s.0",
                .codec_dai_name = "wm8750-hifi",
                .platform_name  = "samsung-audio",
-               .codec_name     = "wm8750-codec.0-0x1a",
+               .codec_name     = "wm8750.0-0x1a",
                .init           = smartq_wm8987_init,
                .ops            = &smartq_hifi_ops,
        },
index 3d26f6607aa47aa97cc6798ac0d10cb14276a0ae..20deecf3b243ad38a7f1b1c44512c59c33de5bb6 100644 (file)
@@ -210,7 +210,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
                .cpu_dai_name = "samsung-i2s.0",
                .codec_dai_name = "wm8580-hifi-playback",
                .platform_name = "samsung-audio",
-               .codec_name = "wm8580-codec.0-001b",
+               .codec_name = "wm8580.0-001b",
                .init = smdk_wm8580_init_paifrx,
                .ops = &smdk_ops,
        },
@@ -220,7 +220,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
                .cpu_dai_name = "samsung-i2s.0",
                .codec_dai_name = "wm8580-hifi-capture",
                .platform_name = "samsung-audio",
-               .codec_name = "wm8580-codec.0-001b",
+               .codec_name = "wm8580.0-001b",
                .init = smdk_wm8580_init_paiftx,
                .ops = &smdk_ops,
        },
@@ -230,7 +230,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
                .cpu_dai_name = "samsung-i2s.x",
                .codec_dai_name = "wm8580-hifi-playback",
                .platform_name = "samsung-audio",
-               .codec_name = "wm8580-codec.0-001b",
+               .codec_name = "wm8580.0-001b",
                .init = smdk_wm8580_init_paifrx,
                .ops = &smdk_ops,
        },
index 0d12092df164bde51c8d6f28ad6488c227c745d8..4b9c73477ce0d9e875256e4985ff78f70d5056ca 100644 (file)
@@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
                .cpu_dai_name = "samsung-pcm.0",
                .codec_dai_name = "wm8580-hifi-playback",
                .platform_name = "samsung-audio",
-               .codec_name = "wm8580-codec.0-001b",
+               .codec_name = "wm8580.0-001b",
                .ops = &smdk_wm8580_pcm_ops,
        }, {
                .name = "WM8580 PAIF PCM TX",
@@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = {
                .cpu_dai_name = "samsung-pcm.0",
                .codec_dai_name = "wm8580-hifi-capture",
                .platform_name = "samsung-audio",
-               .codec_name = "wm8580-codec.0-001b",
+               .codec_name = "wm8580.0-001b",
                .ops = &smdk_wm8580_pcm_ops,
        },
 };
index 590e9274b06285428f25a25104e524ccddb0d304..bfed1ff7093fe703620d4ebae6683523de098e68 100644 (file)
@@ -125,10 +125,6 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = {
                .pin = "Headset Mic",
                .mask = SND_JACK_MICROPHONE,
        },
-       {
-               .pin = "Headphone",
-               .mask = SND_JACK_HEADPHONE,
-       },
 };
 
 /* Default the headphone selection to active high */
@@ -252,6 +248,7 @@ static const struct snd_kcontrol_new controls[] = {
        SOC_DAPM_PIN_SWITCH("Main AMIC"),
        SOC_DAPM_PIN_SWITCH("WM1250 Input"),
        SOC_DAPM_PIN_SWITCH("WM1250 Output"),
+       SOC_DAPM_PIN_SWITCH("Headphone"),
 };
 
 static struct snd_soc_dapm_widget widgets[] = {
index 0b9eb5f7ec4cdb02656f8b94fe0506fbc8b49626..3820a6b057dc98fa168172b1dc9c0858c6565061 100644 (file)
@@ -23,18 +23,21 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
        struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
        int ret;
 
+       if (dapm->dev != codec_dai->dev)
+               return 0;
+
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
                if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
                        ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
                                                  WM8962_FLL_MCLK, 32768,
-                                                 44100 * 256);
+                                                 44100 * 512);
                        if (ret < 0)
                                pr_err("Failed to start FLL: %d\n", ret);
 
                        ret = snd_soc_dai_set_sysclk(codec_dai,
                                                     WM8962_SYSCLK_FLL,
-                                                    44100 * 256,
+                                                    44100 * 512,
                                                     SND_SOC_CLOCK_IN);
                        if (ret < 0) {
                                pr_err("Failed to set SYSCLK: %d\n", ret);
@@ -57,6 +60,9 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
        struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
        int ret;
 
+       if (dapm->dev != codec_dai->dev)
+               return 0;
+
        switch (level) {
        case SND_SOC_BIAS_STANDBY:
                ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
index d9f8aded51f370116007b37cbf195dc3269f62a8..fdfd4881c9d1db42189aa112fbdeff630263329a 100644 (file)
@@ -548,9 +548,6 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
 
 static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
 {
-       const struct snd_soc_codec_driver *codec_drv;
-
-       codec_drv = codec->driver;
        return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
 }
 
@@ -868,10 +865,6 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
 
 static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
 {
-       const struct snd_soc_codec_driver *codec_drv;
-
-       codec_drv = codec->driver;
-
        if (codec->reg_def_copy)
                codec->reg_cache = kmemdup(codec->reg_def_copy,
                                           codec->reg_size, GFP_KERNEL);
index 83ad8ca274903cff750166606c613db1c5f79df0..fd173f6be18d3639540a862b129812fd14f6778a 100644 (file)
@@ -105,7 +105,7 @@ static int format_register_str(struct snd_soc_codec *codec,
        if (wordsize + regsize + 2 + 1 != len)
                return -EINVAL;
 
-       ret = snd_soc_read(codec , reg);
+       ret = snd_soc_read(codec, reg);
        if (ret < 0) {
                memset(regbuf, 'X', regsize);
                regbuf[regsize] = '\0';
@@ -956,6 +956,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
                snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
                                          driver->num_dapm_widgets);
 
+       codec->dapm.idle_bias_off = driver->idle_bias_off;
+
        if (driver->probe) {
                ret = driver->probe(codec);
                if (ret < 0) {
@@ -1913,7 +1915,7 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
 
        if (prefix) {
                name_len = strlen(long_name) + strlen(prefix) + 2;
-               name = kmalloc(name_len, GFP_ATOMIC);
+               name = kmalloc(name_len, GFP_KERNEL);
                if (!name)
                        return NULL;
 
@@ -3141,6 +3143,7 @@ int snd_soc_register_platform(struct device *dev,
        platform->driver = platform_drv;
        platform->dapm.dev = dev;
        platform->dapm.platform = platform;
+       platform->dapm.stream_event = platform_drv->stream_event;
 
        mutex_lock(&client_mutex);
        list_add(&platform->list, &platform_list);
@@ -3253,6 +3256,7 @@ int snd_soc_register_codec(struct device *dev,
        codec->dapm.dev = dev;
        codec->dapm.codec = codec;
        codec->dapm.seq_notifier = codec_drv->seq_notifier;
+       codec->dapm.stream_event = codec_drv->stream_event;
        codec->dev = dev;
        codec->driver = codec_drv;
        codec->num_dai = num_dai;
index 7e15914b363362406e868070eb04c347e5fc8c8a..170c4ffa609ff2f9df87da7af186f47d12cee977 100644 (file)
@@ -443,6 +443,11 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
                        if (path->name != (char *)w->kcontrol_news[i].name)
                                continue;
 
+                       if (w->kcontrols[i]) {
+                               path->kcontrol = w->kcontrols[i];
+                               continue;
+                       }
+
                        wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
                                    sizeof(struct snd_soc_dapm_widget *),
                        wlist = kzalloc(wlistsize, GFP_KERNEL);
@@ -1556,7 +1561,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
                /* found, now check type */
                found = 1;
                path->connect = connect;
-               break;
        }
 
        if (found)
@@ -2584,7 +2588,7 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
        {
                if (!w->sname || w->dapm != dapm)
                        continue;
-               dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
+               dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
                        w->name, w->sname, stream, event);
                if (strstr(w->sname, stream)) {
                        switch(event) {
@@ -2604,6 +2608,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
        }
 
        dapm_power_widgets(dapm, event);
+
+       /* do we need to notify any clients that DAPM stream is complete */
+       if (dapm->stream_event)
+               dapm->stream_event(dapm, event);
 }
 
 /**
index cca490c80589db6e5c5f402da6dda77c988bf41e..66fcccd79efe9a2cbc8aa591d491f0f15fbc378f 100644 (file)
 
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
 #include <sound/soc.h>
 
 #include <trace/events/asoc.h>
 
-#ifdef CONFIG_SPI_MASTER
-static int do_spi_write(void *control, const char *data, int len)
-{
-       struct spi_device *spi = control;
-       int ret;
-
-       ret = spi_write(spi, data, len);
-       if (ret < 0)
-               return ret;
-
-       return len;
-}
-#endif
-
-static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
-                      unsigned int value, const void *data, int len)
+#ifdef CONFIG_REGMAP
+static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
+                   unsigned int value)
 {
        int ret;
 
@@ -49,13 +37,7 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
                return 0;
        }
 
-       ret = codec->hw_write(codec->control_data, data, len);
-       if (ret == len)
-               return 0;
-       if (ret < 0)
-               return ret;
-       else
-               return -EIO;
+       return regmap_write(codec->control_data, reg, value);
 }
 
 static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
@@ -69,8 +51,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
                if (codec->cache_only)
                        return -1;
 
-               BUG_ON(!codec->hw_read);
-               return codec->hw_read(codec, reg);
+               ret = regmap_read(codec->control_data, reg, &val);
+               if (ret == 0)
+                       return val;
+               else
+                       return ret;
        }
 
        ret = snd_soc_cache_read(codec, reg, &val);
@@ -79,183 +64,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
        return val;
 }
 
-static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
-                             unsigned int value)
-{
-       u16 data;
-
-       data = cpu_to_be16((reg << 12) | (value & 0xffffff));
-
-       return do_hw_write(codec, reg, value, &data, 2);
-}
-
-static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
-                            unsigned int value)
-{
-       u16 data;
-
-       data = cpu_to_be16((reg << 9) | (value & 0x1ff));
-
-       return do_hw_write(codec, reg, value, &data, 2);
-}
-
-static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
-                            unsigned int value)
-{
-       u8 data[2];
-
-       reg &= 0xff;
-       data[0] = reg;
-       data[1] = value & 0xff;
-
-       return do_hw_write(codec, reg, value, data, 2);
-}
-
-static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
-                             unsigned int value)
-{
-       u8 data[3];
-       u16 val = cpu_to_be16(value);
-
-       data[0] = reg;
-       memcpy(&data[1], &val, sizeof(val));
-
-       return do_hw_write(codec, reg, value, data, 3);
-}
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int do_i2c_read(struct snd_soc_codec *codec,
-                               void *reg, int reglen,
-                               void *data, int datalen)
-{
-       struct i2c_msg xfer[2];
-       int ret;
-       struct i2c_client *client = codec->control_data;
-
-       /* Write register */
-       xfer[0].addr = client->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = reglen;
-       xfer[0].buf = reg;
-
-       /* Read data */
-       xfer[1].addr = client->addr;
-       xfer[1].flags = I2C_M_RD;
-       xfer[1].len = datalen;
-       xfer[1].buf = data;
-
-       ret = i2c_transfer(client->adapter, xfer, 2);
-       if (ret == 2)
-               return 0;
-       else if (ret < 0)
-               return ret;
-       else
-               return -EIO;
-}
-#endif
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
-                                        unsigned int r)
-{
-       u8 reg = r;
-       u8 data;
-       int ret;
-
-       ret = do_i2c_read(codec, &reg, 1, &data, 1);
-       if (ret < 0)
-               return 0;
-       return data;
-}
-#else
-#define snd_soc_8_8_read_i2c NULL
-#endif
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
-                                         unsigned int r)
-{
-       u8 reg = r;
-       u16 data;
-       int ret;
-
-       ret = do_i2c_read(codec, &reg, 1, &data, 2);
-       if (ret < 0)
-               return 0;
-       return (data >> 8) | ((data & 0xff) << 8);
-}
-#else
-#define snd_soc_8_16_read_i2c NULL
-#endif
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
-                                         unsigned int r)
-{
-       u16 reg = r;
-       u8 data;
-       int ret;
-
-       ret = do_i2c_read(codec, &reg, 2, &data, 1);
-       if (ret < 0)
-               return 0;
-       return data;
-}
-#else
-#define snd_soc_16_8_read_i2c NULL
-#endif
-
-static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
-                             unsigned int value)
-{
-       u8 data[3];
-       u16 rval = cpu_to_be16(reg);
-
-       memcpy(data, &rval, sizeof(rval));
-       data[2] = value;
-
-       return do_hw_write(codec, reg, value, data, 3);
-}
-
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
-                                          unsigned int r)
-{
-       u16 reg = cpu_to_be16(r);
-       u16 data;
-       int ret;
-
-       ret = do_i2c_read(codec, &reg, 2, &data, 2);
-       if (ret < 0)
-               return 0;
-       return be16_to_cpu(data);
-}
-#else
-#define snd_soc_16_16_read_i2c NULL
-#endif
-
-static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
-                              unsigned int value)
-{
-       u16 data[2];
-
-       data[0] = cpu_to_be16(reg);
-       data[1] = cpu_to_be16(value);
-
-       return do_hw_write(codec, reg, value, data, sizeof(data));
-}
-
 /* Primitive bulk write support for soc-cache.  The data pointed to by
- * `data' needs to already be in the form the hardware expects
- * including any leading register specific data.  Any data written
- * through this function will not go through the cache as it only
- * handles writing to volatile or out of bounds registers.
+ * `data' needs to already be in the form the hardware expects.  Any
+ * data written through this function will not go through the cache as
+ * it only handles writing to volatile or out of bounds registers.
+ *
+ * This is currently only supported for devices using the regmap API
+ * wrappers.
  */
-static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg,
+static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
+                                    unsigned int reg,
                                     const void *data, size_t len)
 {
-       int ret;
-
        /* To ensure that we don't get out of sync with the cache, check
         * whether the base register is volatile or if we've directly asked
         * to bypass the cache.  Out of bounds registers are considered
@@ -266,66 +86,9 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r
            && reg < codec->driver->reg_cache_size)
                return -EINVAL;
 
-       switch (codec->control_type) {
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-       case SND_SOC_I2C:
-               ret = i2c_master_send(to_i2c_client(codec->dev), data, len);
-               break;
-#endif
-#if defined(CONFIG_SPI_MASTER)
-       case SND_SOC_SPI:
-               ret = spi_write(to_spi_device(codec->dev), data, len);
-               break;
-#endif
-       default:
-               BUG();
-       }
-
-       if (ret == len)
-               return 0;
-       if (ret < 0)
-               return ret;
-       else
-               return -EIO;
+       return regmap_raw_write(codec->control_data, reg, data, len);
 }
 
-static struct {
-       int addr_bits;
-       int data_bits;
-       int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
-       unsigned int (*read)(struct snd_soc_codec *, unsigned int);
-       unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
-} io_types[] = {
-       {
-               .addr_bits = 4, .data_bits = 12,
-               .write = snd_soc_4_12_write,
-       },
-       {
-               .addr_bits = 7, .data_bits = 9,
-               .write = snd_soc_7_9_write,
-       },
-       {
-               .addr_bits = 8, .data_bits = 8,
-               .write = snd_soc_8_8_write,
-               .i2c_read = snd_soc_8_8_read_i2c,
-       },
-       {
-               .addr_bits = 8, .data_bits = 16,
-               .write = snd_soc_8_16_write,
-               .i2c_read = snd_soc_8_16_read_i2c,
-       },
-       {
-               .addr_bits = 16, .data_bits = 8,
-               .write = snd_soc_16_8_write,
-               .i2c_read = snd_soc_16_8_read_i2c,
-       },
-       {
-               .addr_bits = 16, .data_bits = 16,
-               .write = snd_soc_16_16_write,
-               .i2c_read = snd_soc_16_16_read_i2c,
-       },
-};
-
 /**
  * snd_soc_codec_set_cache_io: Set up standard I/O functions.
  *
@@ -349,48 +112,51 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
                               int addr_bits, int data_bits,
                               enum snd_soc_control_type control)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(io_types); i++)
-               if (io_types[i].addr_bits == addr_bits &&
-                   io_types[i].data_bits == data_bits)
-                       break;
-       if (i == ARRAY_SIZE(io_types)) {
-               printk(KERN_ERR
-                      "No I/O functions for %d bit address %d bit data\n",
-                      addr_bits, data_bits);
-               return -EINVAL;
-       }
+       struct regmap_config config;
 
-       codec->write = io_types[i].write;
+       memset(&config, 0, sizeof(config));
+       codec->write = hw_write;
        codec->read = hw_read;
        codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
 
+       config.reg_bits = addr_bits;
+       config.val_bits = data_bits;
+
        switch (control) {
+#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
        case SND_SOC_I2C:
-#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
-               codec->hw_write = (hw_write_t)i2c_master_send;
-#endif
-               if (io_types[i].i2c_read)
-                       codec->hw_read = io_types[i].i2c_read;
-
-               codec->control_data = container_of(codec->dev,
-                                                  struct i2c_client,
-                                                  dev);
+               codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
+                                                     &config);
                break;
+#endif
 
+#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
        case SND_SOC_SPI:
-#ifdef CONFIG_SPI_MASTER
-               codec->hw_write = do_spi_write;
+               codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
+                                                     &config);
+               break;
 #endif
 
-               codec->control_data = container_of(codec->dev,
-                                                  struct spi_device,
-                                                  dev);
+       case SND_SOC_REGMAP:
+               /* Device has made its own regmap arrangements */
                break;
+
+       default:
+               return -EINVAL;
        }
 
+       if (IS_ERR(codec->control_data))
+               return PTR_ERR(codec->control_data);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-
+#else
+int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
+                              int addr_bits, int data_bits,
+                              enum snd_soc_control_type control)
+{
+       return -ENOTSUPP;
+}
+EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
+#endif
index 7c17b98d584609c4a9fd78afe5c019a43728db1f..38b00131b2fe20cf395b70197a650d4e2e35e679 100644 (file)
@@ -327,7 +327,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
                                              IRQF_TRIGGER_FALLING,
                                              gpios[i].name,
                                              &gpios[i]);
-               if (ret)
+               if (ret < 0)
                        goto err;
 
                if (gpios[i].wake) {
index b5759397afa342a89fe494b51d2d97e2a0d3e346..1aee9fcdf650ade07e17f537ea7861e78e3c1cd5 100644 (file)
@@ -27,8 +27,6 @@
 #include <sound/soc.h>
 #include <sound/initval.h>
 
-static DEFINE_MUTEX(pcm_mutex);
-
 static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -290,6 +288,9 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
        codec_dai->active--;
        codec->active--;
 
+       if (!cpu_dai->active && !codec_dai->active)
+               rtd->rate = 0;
+
        /* Muting the DAC suppresses artifacts caused during digital
         * shutdown, for example from stopping clocks.
         */
index 781d9e61adfbe687880dfa34fccd960f5093e8e7..d5754fa5e551eee063e34b2479671a8f02fde94c 100644 (file)
@@ -628,7 +628,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
        if (chip == (void *)-1L)
                return 0;
 
-       if (!(message.event & PM_EVENT_AUTO)) {
+       if (!PMSG_IS_AUTO(message)) {
                snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
                if (!chip->num_suspended_intf++) {
                        list_for_each(p, &chip->pcm_list) {
index cdd19d7fe500b2a6315b3023212f1313032c5999..78a5abda6793dc9069ed9ad4508126de4dd36874 100644 (file)
@@ -881,8 +881,17 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
                uinfo->value.integer.min = 0;
                uinfo->value.integer.max = 1;
        } else {
-               if (! cval->initialized)
-                       get_min_max(cval,  0);
+               if (!cval->initialized) {
+                       get_min_max(cval, 0);
+                       if (cval->initialized && cval->dBmin >= cval->dBmax) {
+                               kcontrol->vd[0].access &= 
+                                       ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+                                         SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
+                               snd_ctl_notify(cval->mixer->chip->card,
+                                              SNDRV_CTL_EVENT_MASK_INFO,
+                                              &kcontrol->id);
+                       }
+               }
                uinfo->value.integer.min = 0;
                uinfo->value.integer.max =
                        (cval->max - cval->min + cval->res - 1) / cval->res;
index fff6450c8c999b6c0ae37597a67abaed900dc023..e8d5c551c69c08d4a17e89a370d0e4caedacb101 100644 (file)
@@ -8,7 +8,10 @@
  * published by the Free Software Foundation.
  */
 
+#include <stdlib.h>
+#ifndef __UCLIBC__
 #include <libio.h>
+#endif
 #include <dwarf-regs.h>
 
 struct pt_regs_dwarfnum {
index 94c2cf0a98b88e771ef4377fef83ea16deb72398..e8a03aceceb11fe88b5552a0952431866213ee42 100644 (file)
@@ -24,7 +24,7 @@
 
 # Set the following to `true' to make a unstripped, unoptimized
 # binary. Leave this set to `false' for production use.
-DEBUG ?=       false
+DEBUG ?=       true
 
 # make the build silent. Set this to something else to make it noisy again.
 V ?=           false
@@ -35,7 +35,7 @@ NLS ?=                true
 
 # Set the following to 'true' to build/install the
 # cpufreq-bench benchmarking tool
-CPUFRQ_BENCH ?= true
+CPUFREQ_BENCH ?= true
 
 # Prefix to the directories we're installing to
 DESTDIR ?=
@@ -137,9 +137,10 @@ CFLAGS +=  -pipe
 ifeq ($(strip $(NLS)),true)
        INSTALL_NLS += install-gmo
        COMPILE_NLS += create-gmo
+       CFLAGS += -DNLS
 endif
 
-ifeq ($(strip $(CPUFRQ_BENCH)),true)
+ifeq ($(strip $(CPUFREQ_BENCH)),true)
        INSTALL_BENCH += install-bench
        COMPILE_BENCH += compile-bench
 endif
index dbf13998462a3c3e02b2784dd10c24314d2c006b..3326217dd31158d24446213d709a3f8cb5b7002c 100644 (file)
@@ -1,10 +1,10 @@
 default: all
 
-centrino-decode: centrino-decode.c
-       $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c
+centrino-decode: ../i386/centrino-decode.c
+       $(CC) $(CFLAGS) -o $@ $<
 
-powernow-k8-decode: powernow-k8-decode.c
-       $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c
+powernow-k8-decode: ../i386/powernow-k8-decode.c
+       $(CC) $(CFLAGS) -o $@ $<
 
 all: centrino-decode powernow-k8-decode
 
diff --git a/tools/power/cpupower/debug/x86_64/centrino-decode.c b/tools/power/cpupower/debug/x86_64/centrino-decode.c
deleted file mode 120000 (symlink)
index 26fb3f1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../i386/centrino-decode.c
\ No newline at end of file
diff --git a/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c b/tools/power/cpupower/debug/x86_64/powernow-k8-decode.c
deleted file mode 120000 (symlink)
index eb30c79..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../i386/powernow-k8-decode.c
\ No newline at end of file
index 3194811d58f55e83c02bc6c3fa7c1aa96fc922a5..bb60a8d1e45abb0e4685792ad02ca187893cac8a 100644 (file)
@@ -1,10 +1,10 @@
-.TH "cpufreq-info" "1" "0.1" "Mattia Dongili" ""
+.TH "cpupower-frequency-info" "1" "0.1" "Mattia Dongili" ""
 .SH "NAME"
 .LP 
-cpufreq\-info \- Utility to retrieve cpufreq kernel information
+cpupower frequency\-info \- Utility to retrieve cpufreq kernel information
 .SH "SYNTAX"
 .LP 
-cpufreq\-info [\fIoptions\fP]
+cpupower [ \-c cpulist ] frequency\-info [\fIoptions\fP]
 .SH "DESCRIPTION"
 .LP 
 A small tool which prints out cpufreq information helpful to developers and interested users.
index 26e3e13eee3b61c7427d579896e9f31f50c01440..685f469093ad200c93e2e9feb3e23dcaec863a5a 100644 (file)
@@ -1,13 +1,13 @@
-.TH "cpufreq-set" "1" "0.1" "Mattia Dongili" ""
+.TH "cpupower-freqency-set" "1" "0.1" "Mattia Dongili" ""
 .SH "NAME"
 .LP 
-cpufreq\-set \- A small tool which allows to modify cpufreq settings.
+cpupower frequency\-set \- A small tool which allows to modify cpufreq settings.
 .SH "SYNTAX"
 .LP 
-cpufreq\-set [\fIoptions\fP]
+cpupower [ \-c cpu ] frequency\-set [\fIoptions\fP]
 .SH "DESCRIPTION"
 .LP 
-cpufreq\-set allows you to modify cpufreq settings without having to type e.g. "/sys/devices/system/cpu/cpu0/cpufreq/scaling_set_speed" all the time.
+cpupower frequency\-set allows you to modify cpufreq settings without having to type e.g. "/sys/devices/system/cpu/cpu0/cpufreq/scaling_set_speed" all the time.
 .SH "OPTIONS"
 .LP 
 .TP 
index 78c20feab85c27447563ee29cd7927aa0cac6363..baf741d06e82543f3529f4f13769bfc1d196cffc 100644 (file)
@@ -3,7 +3,7 @@
 cpupower \- Shows and sets processor power related values
 .SH SYNOPSIS
 .ft B
-.B cpupower [ \-c cpulist ] subcommand [ARGS]
+.B cpupower [ \-c cpulist ] <command> [ARGS]
 
 .B cpupower \-v|\-\-version
 
@@ -13,24 +13,24 @@ cpupower \- Shows and sets processor power related values
 \fBcpupower \fP is a collection of tools to examine and tune power saving
 related features of your processor.
 
-The manpages of the subcommands (cpupower\-<subcommand>(1)) provide detailed
+The manpages of the commands (cpupower\-<command>(1)) provide detailed
 descriptions of supported features. Run \fBcpupower help\fP to get an overview
-of supported subcommands.
+of supported commands.
 
 .SH Options
 .PP
 \-\-help, \-h
 .RS 4
-Shows supported subcommands and general usage.
+Shows supported commands and general usage.
 .RE
 .PP
 \-\-cpu cpulist,  \-c cpulist
 .RS 4
 Only show or set values for specific cores.
-This option is not supported by all subcommands, details can be found in the
-manpages of the subcommands.
+This option is not supported by all commands, details can be found in the
+manpages of the commands.
 
-Some subcommands access all cores (typically the *\-set commands), some only
+Some commands access all cores (typically the *\-set commands), some only
 the first core (typically the *\-info commands) by default.
 
 The syntax for <cpulist> is based on how the kernel exports CPU bitmasks via
index c870ffba5219615c4d55823100c6854c66707f38..c10496fbe3c629c270d6b9ab406f587c8b4736c6 100644 (file)
@@ -8,11 +8,4 @@ extern int cmd_freq_info(int argc, const char **argv);
 extern int cmd_idle_info(int argc, const char **argv);
 extern int cmd_monitor(int argc, const char **argv);
 
-extern void set_help(void);
-extern void info_help(void);
-extern void freq_set_help(void);
-extern void freq_info_help(void);
-extern void idle_info_help(void);
-extern void monitor_help(void);
-
 #endif
index 5a1d25f056b3b60c0f547cc43314d03272fcfac7..28953c9a7bd5980ad600d8830c736119809e51e0 100644 (file)
@@ -510,37 +510,6 @@ static int get_latency(unsigned int cpu, unsigned int human)
        return 0;
 }
 
-void freq_info_help(void)
-{
-       printf(_("Usage: cpupower freqinfo [options]\n"));
-       printf(_("Options:\n"));
-       printf(_("  -e, --debug          Prints out debug information [default]\n"));
-       printf(_("  -f, --freq           Get frequency the CPU currently runs at, according\n"
-              "                       to the cpufreq core *\n"));
-       printf(_("  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
-              "                       it from hardware (only available to root) *\n"));
-       printf(_("  -l, --hwlimits       Determine the minimum and maximum CPU frequency allowed *\n"));
-       printf(_("  -d, --driver         Determines the used cpufreq kernel driver *\n"));
-       printf(_("  -p, --policy         Gets the currently used cpufreq policy *\n"));
-       printf(_("  -g, --governors      Determines available cpufreq governors *\n"));
-       printf(_("  -r, --related-cpus   Determines which CPUs run at the same hardware frequency *\n"));
-       printf(_("  -a, --affected-cpus  Determines which CPUs need to have their frequency\n"
-                       "                       coordinated by software *\n"));
-       printf(_("  -s, --stats          Shows cpufreq statistics if available\n"));
-       printf(_("  -y, --latency        Determines the maximum latency on CPU frequency changes *\n"));
-       printf(_("  -b, --boost          Checks for turbo or boost modes  *\n"));
-       printf(_("  -o, --proc           Prints out information like provided by the /proc/cpufreq\n"
-              "                       interface in 2.4. and early 2.6. kernels\n"));
-       printf(_("  -m, --human          human-readable output for the -f, -w, -s and -y parameters\n"));
-       printf(_("  -h, --help           Prints out this screen\n"));
-
-       printf("\n");
-       printf(_("If no argument is given, full output about\n"
-              "cpufreq is printed which is useful e.g. for reporting bugs.\n\n"));
-       printf(_("By default info of CPU 0 is shown which can be overridden\n"
-                "with the cpupower --cpu main command option.\n"));
-}
-
 static struct option info_opts[] = {
        { .name = "debug",      .has_arg = no_argument,         .flag = NULL,   .val = 'e'},
        { .name = "boost",      .has_arg = no_argument,         .flag = NULL,   .val = 'b'},
@@ -556,7 +525,6 @@ static struct option info_opts[] = {
        { .name = "latency",    .has_arg = no_argument,         .flag = NULL,   .val = 'y'},
        { .name = "proc",       .has_arg = no_argument,         .flag = NULL,   .val = 'o'},
        { .name = "human",      .has_arg = no_argument,         .flag = NULL,   .val = 'm'},
-       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
        { },
 };
 
@@ -570,16 +538,12 @@ int cmd_freq_info(int argc, char **argv)
        int output_param = 0;
 
        do {
-               ret = getopt_long(argc, argv, "hoefwldpgrasmyb", info_opts, NULL);
+               ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL);
                switch (ret) {
                case '?':
                        output_param = '?';
                        cont = 0;
                        break;
-               case 'h':
-                       output_param = 'h';
-                       cont = 0;
-                       break;
                case -1:
                        cont = 0;
                        break;
@@ -642,11 +606,7 @@ int cmd_freq_info(int argc, char **argv)
                return -EINVAL;
        case '?':
                printf(_("invalid or unknown argument\n"));
-               freq_info_help();
                return -EINVAL;
-       case 'h':
-               freq_info_help();
-               return EXIT_SUCCESS;
        case 'o':
                proc_cpufreq_output();
                return EXIT_SUCCESS;
index 5f783622bf31f89e2618ff5b84a50fb37221957b..dd1539eb8c63de3e8d166b24a5f79b65702a4685 100644 (file)
 
 #define NORM_FREQ_LEN 32
 
-void freq_set_help(void)
-{
-       printf(_("Usage: cpupower frequency-set [options]\n"));
-       printf(_("Options:\n"));
-       printf(_("  -d FREQ, --min FREQ      new minimum CPU frequency the governor may select\n"));
-       printf(_("  -u FREQ, --max FREQ      new maximum CPU frequency the governor may select\n"));
-       printf(_("  -g GOV, --governor GOV   new cpufreq governor\n"));
-       printf(_("  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
-              "                           governor to be available and loaded\n"));
-       printf(_("  -r, --related            Switches all hardware-related CPUs\n"));
-       printf(_("  -h, --help               Prints out this screen\n"));
-       printf("\n");
-       printf(_("Notes:\n"
-              "1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n"));
-       printf(_("2. The -f FREQ, --freq FREQ parameter cannot be combined with any other parameter\n"
-              "   except the -c CPU, --cpu CPU parameter\n"
-              "3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n"
-              "   by postfixing the value with the wanted unit name, without any space\n"
-              "   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"));
-
-}
-
 static struct option set_opts[] = {
        { .name = "min",        .has_arg = required_argument,   .flag = NULL,   .val = 'd'},
        { .name = "max",        .has_arg = required_argument,   .flag = NULL,   .val = 'u'},
        { .name = "governor",   .has_arg = required_argument,   .flag = NULL,   .val = 'g'},
        { .name = "freq",       .has_arg = required_argument,   .flag = NULL,   .val = 'f'},
-       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
        { .name = "related",    .has_arg = no_argument,         .flag = NULL,   .val='r'},
        { },
 };
@@ -80,7 +57,6 @@ const struct freq_units def_units[] = {
 static void print_unknown_arg(void)
 {
        printf(_("invalid or unknown argument\n"));
-       freq_set_help();
 }
 
 static unsigned long string_to_frequency(const char *str)
@@ -231,14 +207,11 @@ int cmd_freq_set(int argc, char **argv)
 
        /* parameter parsing */
        do {
-               ret = getopt_long(argc, argv, "d:u:g:f:hr", set_opts, NULL);
+               ret = getopt_long(argc, argv, "d:u:g:f:r", set_opts, NULL);
                switch (ret) {
                case '?':
                        print_unknown_arg();
                        return -EINVAL;
-               case 'h':
-                       freq_set_help();
-                       return 0;
                case -1:
                        cont = 0;
                        break;
index 70da3574f1e99940a33dfa4348a35a046de2c5b8..b028267c1376a6c63c455bbdabeb5c36218aee2a 100644 (file)
@@ -139,30 +139,14 @@ static void proc_cpuidle_cpu_output(unsigned int cpu)
        }
 }
 
-/* --freq / -f */
-
-void idle_info_help(void)
-{
-       printf(_ ("Usage: cpupower idleinfo [options]\n"));
-       printf(_ ("Options:\n"));
-       printf(_ ("  -s, --silent         Only show general C-state information\n"));
-       printf(_ ("  -o, --proc           Prints out information like provided by the /proc/acpi/processor/*/power\n"
-              "                       interface in older kernels\n"));
-       printf(_ ("  -h, --help           Prints out this screen\n"));
-
-       printf("\n");
-}
-
 static struct option info_opts[] = {
        { .name = "silent",     .has_arg = no_argument, .flag = NULL,   .val = 's'},
        { .name = "proc",       .has_arg = no_argument, .flag = NULL,   .val = 'o'},
-       { .name = "help",       .has_arg = no_argument, .flag = NULL,   .val = 'h'},
        { },
 };
 
 static inline void cpuidle_exit(int fail)
 {
-       idle_info_help();
        exit(EXIT_FAILURE);
 }
 
@@ -174,7 +158,7 @@ int cmd_idle_info(int argc, char **argv)
        unsigned int cpu = 0;
 
        do {
-               ret = getopt_long(argc, argv, "hos", info_opts, NULL);
+               ret = getopt_long(argc, argv, "os", info_opts, NULL);
                if (ret == -1)
                        break;
                switch (ret) {
@@ -182,10 +166,6 @@ int cmd_idle_info(int argc, char **argv)
                        output_param = '?';
                        cont = 0;
                        break;
-               case 'h':
-                       output_param = 'h';
-                       cont = 0;
-                       break;
                case 's':
                        verbose = 0;
                        break;
@@ -211,8 +191,6 @@ int cmd_idle_info(int argc, char **argv)
        case '?':
                printf(_("invalid or unknown argument\n"));
                cpuidle_exit(EXIT_FAILURE);
-       case 'h':
-               cpuidle_exit(EXIT_SUCCESS);
        }
 
        /* Default is: show output of CPU 0 only */
index 85253cb7600ef8c7850bcd7332a6639be20b9bf3..3f68632c28c7bccc02f2d0a3266288e4a7bfd74a 100644 (file)
 #include "helpers/helpers.h"
 #include "helpers/sysfs.h"
 
-void info_help(void)
-{
-       printf(_("Usage: cpupower info [ -b ] [ -m ] [ -s ]\n"));
-       printf(_("Options:\n"));
-       printf(_("  -b, --perf-bias    Gets CPU's power vs performance policy on some\n"
-              "                           Intel models [0-15], see manpage for details\n"));
-       printf(_("  -m, --sched-mc     Gets the kernel's multi core scheduler policy.\n"));
-       printf(_("  -s, --sched-smt    Gets the kernel's thread sibling scheduler policy.\n"));
-       printf(_("  -h, --help               Prints out this screen\n"));
-       printf(_("\nPassing no option will show all info, by default only on core 0\n"));
-       printf("\n");
-}
-
 static struct option set_opts[] = {
        { .name = "perf-bias",  .has_arg = optional_argument,   .flag = NULL,   .val = 'b'},
        { .name = "sched-mc",   .has_arg = optional_argument,   .flag = NULL,   .val = 'm'},
        { .name = "sched-smt",  .has_arg = optional_argument,   .flag = NULL,   .val = 's'},
-       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
        { },
 };
 
 static void print_wrong_arg_exit(void)
 {
        printf(_("invalid or unknown argument\n"));
-       info_help();
        exit(EXIT_FAILURE);
 }
 
@@ -64,11 +49,8 @@ int cmd_info(int argc, char **argv)
        textdomain(PACKAGE);
 
        /* parameter parsing */
-       while ((ret = getopt_long(argc, argv, "msbh", set_opts, NULL)) != -1) {
+       while ((ret = getopt_long(argc, argv, "msb", set_opts, NULL)) != -1) {
                switch (ret) {
-               case 'h':
-                       info_help();
-                       return 0;
                case 'b':
                        if (params.perf_bias)
                                print_wrong_arg_exit();
index bc1b391e46f0ba785ed6ae0bc11f18cc7d3678e3..dc4de37621117f7dc6fe8d47669e761063c9eed0 100644 (file)
 #include "helpers/sysfs.h"
 #include "helpers/bitmask.h"
 
-void set_help(void)
-{
-       printf(_("Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n"));
-       printf(_("Options:\n"));
-       printf(_("  -b, --perf-bias [VAL]    Sets CPU's power vs performance policy on some\n"
-              "                           Intel models [0-15], see manpage for details\n"));
-       printf(_("  -m, --sched-mc  [VAL]    Sets the kernel's multi core scheduler policy.\n"));
-       printf(_("  -s, --sched-smt [VAL]    Sets the kernel's thread sibling scheduler policy.\n"));
-       printf(_("  -h, --help               Prints out this screen\n"));
-       printf("\n");
-}
-
 static struct option set_opts[] = {
        { .name = "perf-bias",  .has_arg = optional_argument,   .flag = NULL,   .val = 'b'},
        { .name = "sched-mc",   .has_arg = optional_argument,   .flag = NULL,   .val = 'm'},
        { .name = "sched-smt",  .has_arg = optional_argument,   .flag = NULL,   .val = 's'},
-       { .name = "help",       .has_arg = no_argument,         .flag = NULL,   .val = 'h'},
        { },
 };
 
 static void print_wrong_arg_exit(void)
 {
        printf(_("invalid or unknown argument\n"));
-       set_help();
        exit(EXIT_FAILURE);
 }
 
@@ -66,12 +52,9 @@ int cmd_set(int argc, char **argv)
 
        params.params = 0;
        /* parameter parsing */
-       while ((ret = getopt_long(argc, argv, "m:s:b:h",
+       while ((ret = getopt_long(argc, argv, "m:s:b:",
                                                set_opts, NULL)) != -1) {
                switch (ret) {
-               case 'h':
-                       set_help();
-                       return 0;
                case 'b':
                        if (params.perf_bias)
                                print_wrong_arg_exit();
@@ -110,10 +93,8 @@ int cmd_set(int argc, char **argv)
                }
        };
 
-       if (!params.params) {
-               set_help();
-               return -EINVAL;
-       }
+       if (!params.params)
+               print_wrong_arg_exit();
 
        if (params.sched_mc) {
                ret = sysfs_set_sched("mc", sched_mc);
index 5844ae0f786f2a09ca3b01016e338c03585d3af4..52bee591c1c565f3bf9760505c7a824122d2537c 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include "builtin.h"
 #include "helpers/helpers.h"
 struct cmd_struct {
        const char *cmd;
        int (*main)(int, const char **);
-       void (*usage)(void);
        int needs_root;
 };
 
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
 
-int cmd_help(int argc, const char **argv);
+static int cmd_help(int argc, const char **argv);
 
 /* Global cpu_info object available for all binaries
  * Info only retrieved from CPU 0
@@ -44,55 +44,66 @@ int be_verbose;
 static void print_help(void);
 
 static struct cmd_struct commands[] = {
-       { "frequency-info",     cmd_freq_info,  freq_info_help, 0       },
-       { "frequency-set",      cmd_freq_set,   freq_set_help,  1       },
-       { "idle-info",          cmd_idle_info,  idle_info_help, 0       },
-       { "set",                cmd_set,        set_help,       1       },
-       { "info",               cmd_info,       info_help,      0       },
-       { "monitor",            cmd_monitor,    monitor_help,   0       },
-       { "help",               cmd_help,       print_help,     0       },
-       /*      { "bench",      cmd_bench,      NULL,           1       }, */
+       { "frequency-info",     cmd_freq_info,  0       },
+       { "frequency-set",      cmd_freq_set,   1       },
+       { "idle-info",          cmd_idle_info,  0       },
+       { "set",                cmd_set,        1       },
+       { "info",               cmd_info,       0       },
+       { "monitor",            cmd_monitor,    0       },
+       { "help",               cmd_help,       0       },
+       /*      { "bench",      cmd_bench,      1       }, */
 };
 
-int cmd_help(int argc, const char **argv)
-{
-       unsigned int i;
-
-       if (argc > 1) {
-               for (i = 0; i < ARRAY_SIZE(commands); i++) {
-                       struct cmd_struct *p = commands + i;
-                       if (strcmp(p->cmd, argv[1]))
-                               continue;
-                       if (p->usage) {
-                               p->usage();
-                               return EXIT_SUCCESS;
-                       }
-               }
-       }
-       print_help();
-       if (argc == 1)
-               return EXIT_SUCCESS; /* cpupower help */
-       return EXIT_FAILURE;
-}
-
 static void print_help(void)
 {
        unsigned int i;
 
 #ifdef DEBUG
-       printf(_("cpupower [ -d ][ -c cpulist ] subcommand [ARGS]\n"));
-       printf(_("  -d, --debug      May increase output (stderr) on some subcommands\n"));
+       printf(_("Usage:\tcpupower [-d|--debug] [-c|--cpu cpulist ] <command> [<args>]\n"));
 #else
-       printf(_("cpupower [ -c cpulist ] subcommand [ARGS]\n"));
+       printf(_("Usage:\tcpupower [-c|--cpu cpulist ] <command> [<args>]\n"));
 #endif
-       printf(_("cpupower --version\n"));
-       printf(_("Supported subcommands are:\n"));
+       printf(_("Supported commands are:\n"));
        for (i = 0; i < ARRAY_SIZE(commands); i++)
                printf("\t%s\n", commands[i].cmd);
-       printf(_("\nSome subcommands can make use of the -c cpulist option.\n"));
-       printf(_("Look at the general cpupower manpage how to use it\n"));
-       printf(_("and read up the subcommand's manpage whether it is supported.\n"));
-       printf(_("\nUse cpupower help subcommand for getting help for above subcommands.\n"));
+       printf(_("\nNot all commands can make use of the -c cpulist option.\n"));
+       printf(_("\nUse 'cpupower help <command>' for getting help for above commands.\n"));
+}
+
+static int print_man_page(const char *subpage)
+{
+       int len;
+       char *page;
+
+       len = 10; /* enough for "cpupower-" */
+       if (subpage != NULL)
+               len += strlen(subpage);
+
+       page = malloc(len);
+       if (!page)
+               return -ENOMEM;
+
+       sprintf(page, "cpupower");
+       if ((subpage != NULL) && strcmp(subpage, "help")) {
+               strcat(page, "-");
+               strcat(page, subpage);
+       }
+
+       execlp("man", "man", page, NULL);
+
+       /* should not be reached */
+       return -EINVAL;
+}
+
+static int cmd_help(int argc, const char **argv)
+{
+       if (argc > 1) {
+               print_man_page(argv[1]); /* exits within execlp() */
+               return EXIT_FAILURE;
+       }
+
+       print_help();
+       return EXIT_SUCCESS;
 }
 
 static void print_version(void)
index 592ee362b877c92083d736d7699d7cb6d3e3250a..2747e738efb04d3fa1a53e7686162240cfc7a7ec 100644 (file)
 #include "helpers/bitmask.h"
 
 /* Internationalization ****************************/
+#ifdef NLS
+
 #define _(String) gettext(String)
 #ifndef gettext_noop
 #define gettext_noop(String) String
 #endif
 #define N_(String) gettext_noop(String)
+
+#else /* !NLS */
+
+#define _(String) String
+#define N_(String) String
+
+#endif
 /* Internationalization ****************************/
 
 extern int run_as_root;
@@ -96,6 +105,9 @@ struct cpupower_topology {
                int pkg;
                int core;
                int cpu;
+
+               /* flags */
+               unsigned int is_online:1;
        } *core_info;
 };
 
index 55e2466674c636d767dc3efdb32cf5c145d3fc06..c6343024a61158d094c0a831d369b7d1bd8cdb45 100644 (file)
@@ -56,6 +56,56 @@ static unsigned int sysfs_write_file(const char *path,
        return (unsigned int) numwrite;
 }
 
+/*
+ * Detect whether a CPU is online
+ *
+ * Returns:
+ *     1 -> if CPU is online
+ *     0 -> if CPU is offline
+ *     negative errno values in error case
+ */
+int sysfs_is_cpu_online(unsigned int cpu)
+{
+       char path[SYSFS_PATH_MAX];
+       int fd;
+       ssize_t numread;
+       unsigned long long value;
+       char linebuf[MAX_LINE_LEN];
+       char *endp;
+       struct stat statbuf;
+
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu);
+
+       if (stat(path, &statbuf) != 0)
+               return 0;
+
+       /*
+        * kernel without CONFIG_HOTPLUG_CPU
+        * -> cpuX directory exists, but not cpuX/online file
+        */
+       snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu);
+       if (stat(path, &statbuf) != 0)
+               return 1;
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+               return -errno;
+
+       numread = read(fd, linebuf, MAX_LINE_LEN - 1);
+       if (numread < 1) {
+               close(fd);
+               return -EIO;
+       }
+       linebuf[numread] = '\0';
+       close(fd);
+
+       value = strtoull(linebuf, &endp, 0);
+       if (value > 1 || value < 0)
+               return -EINVAL;
+
+       return value;
+}
+
 /* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
 
 /*
index f9373e0906377d78235972950a00e42a6d0c3744..8cb797bbceb0b565a5f698e68c71b856dbe2b37c 100644 (file)
@@ -7,6 +7,8 @@
 
 extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
 
+extern int sysfs_is_cpu_online(unsigned int cpu);
+
 extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
                                                unsigned int idlestate);
 extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
index 385ee5c7570cc6551c64436cd8cf65a213080188..4eae2c47ba48d20d9e62505e023d0dd0a1c7862f 100644 (file)
@@ -41,6 +41,8 @@ struct cpuid_core_info {
        unsigned int pkg;
        unsigned int thread;
        unsigned int cpu;
+       /* flags */
+       unsigned int is_online:1;
 };
 
 static int __compare(const void *t1, const void *t2)
@@ -78,6 +80,8 @@ int get_cpu_topology(struct cpupower_topology *cpu_top)
                return -ENOMEM;
        cpu_top->pkgs = cpu_top->cores = 0;
        for (cpu = 0; cpu < cpus; cpu++) {
+               cpu_top->core_info[cpu].cpu = cpu;
+               cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu);
                cpu_top->core_info[cpu].pkg =
                        sysfs_topology_read_file(cpu, "physical_package_id");
                if ((int)cpu_top->core_info[cpu].pkg != -1 &&
@@ -85,7 +89,6 @@ int get_cpu_topology(struct cpupower_topology *cpu_top)
                        cpu_top->pkgs = cpu_top->core_info[cpu].pkg;
                cpu_top->core_info[cpu].core =
                        sysfs_topology_read_file(cpu, "core_id");
-               cpu_top->core_info[cpu].cpu = cpu;
        }
        cpu_top->pkgs++;
 
index d048b96a61553d8ab54ca908acd7edeced287354..bcd22a1a397083d1b6e5ed7d311fcbcf8e01dffb 100644 (file)
@@ -134,7 +134,7 @@ static struct cpuidle_monitor *cpuidle_register(void)
        /* Assume idle state count is the same for all CPUs */
        cpuidle_sysfs_monitor.hw_states_num = sysfs_get_idlestate_count(0);
 
-       if (cpuidle_sysfs_monitor.hw_states_num == 0)
+       if (cpuidle_sysfs_monitor.hw_states_num <= 0)
                return NULL;
 
        for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) {
index ba4bf068380d9002bac92fd4d8370f2ebd20040c..0d6571e418db4b7eb73017f23be7041c64bbe56c 100644 (file)
@@ -43,6 +43,12 @@ static struct cpupower_topology cpu_top;
 /* ToDo: Document this in the manpage */
 static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
 
+static void print_wrong_arg_exit(void)
+{
+       printf(_("invalid or unknown argument\n"));
+       exit(EXIT_FAILURE);
+}
+
 long long timespec_diff_us(struct timespec start, struct timespec end)
 {
        struct timespec temp;
@@ -56,21 +62,6 @@ long long timespec_diff_us(struct timespec start, struct timespec end)
        return (temp.tv_sec * 1000000) + (temp.tv_nsec / 1000);
 }
 
-void monitor_help(void)
-{
-       printf(_("cpupower monitor: [-m <mon1>,[<mon2>],.. ] command\n"));
-       printf(_("cpupower monitor: [-m <mon1>,[<mon2>],.. ] [ -i interval_sec ]\n"));
-       printf(_("cpupower monitor: -l\n"));
-       printf(_("\t command: pass an arbitrary command to measure specific workload\n"));
-       printf(_("\t -i: time intervall to measure for in seconds (default 1)\n"));
-       printf(_("\t -l: list available CPU sleep monitors (for use with -m)\n"));
-       printf(_("\t -m: show specific CPU sleep monitors only (in same order)\n"));
-       printf(_("\t -h: print this help\n"));
-       printf("\n");
-       printf(_("only one of: -l, -m are allowed\nIf none of them is passed,"));
-       printf(_(" all supported monitors are shown\n"));
-}
-
 void print_n_spaces(int n)
 {
        int x;
@@ -149,6 +140,10 @@ void print_results(int topology_depth, int cpu)
        unsigned long long result;
        cstate_t s;
 
+       /* Be careful CPUs may got resorted for pkg value do not just use cpu */
+       if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu))
+               return;
+
        if (topology_depth > 2)
                printf("%4d|", cpu_top.core_info[cpu].pkg);
        if (topology_depth > 1)
@@ -190,9 +185,13 @@ void print_results(int topology_depth, int cpu)
                        }
                }
        }
-       /* cpu offline */
-       if (cpu_top.core_info[cpu].pkg == -1 ||
-           cpu_top.core_info[cpu].core == -1) {
+       /*
+        * The monitor could still provide useful data, for example
+        * AMD HW counters partly sit in PCI config space.
+        * It's up to the monitor plug-in to check .is_online, this one
+        * is just for additional info.
+        */
+       if (!cpu_top.core_info[cpu].is_online) {
                printf(_(" *is offline\n"));
                return;
        } else
@@ -238,7 +237,6 @@ static void parse_monitor_param(char *param)
        if (hits == 0) {
                printf(_("No matching monitor found in %s, "
                         "try -l option\n"), param);
-               monitor_help();
                exit(EXIT_FAILURE);
        }
        /* Override detected/registerd monitors array with requested one */
@@ -335,37 +333,27 @@ static void cmdline(int argc, char *argv[])
        int opt;
        progname = basename(argv[0]);
 
-       while ((opt = getopt(argc, argv, "+hli:m:")) != -1) {
+       while ((opt = getopt(argc, argv, "+li:m:")) != -1) {
                switch (opt) {
-               case 'h':
-                       monitor_help();
-                       exit(EXIT_SUCCESS);
                case 'l':
-                       if (mode) {
-                               monitor_help();
-                               exit(EXIT_FAILURE);
-                       }
+                       if (mode)
+                               print_wrong_arg_exit();
                        mode = list;
                        break;
                case 'i':
                        /* only allow -i with -m or no option */
-                       if (mode && mode != show) {
-                               monitor_help();
-                               exit(EXIT_FAILURE);
-                       }
+                       if (mode && mode != show)
+                               print_wrong_arg_exit();
                        interval = atoi(optarg);
                        break;
                case 'm':
-                       if (mode) {
-                               monitor_help();
-                               exit(EXIT_FAILURE);
-                       }
+                       if (mode)
+                               print_wrong_arg_exit();
                        mode = show;
                        show_monitors_param = optarg;
                        break;
                default:
-                       monitor_help();
-                       exit(EXIT_FAILURE);
+                       print_wrong_arg_exit();
                }
        }
        if (!mode)
@@ -385,6 +373,10 @@ int cmd_monitor(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
+       /* Default is: monitor all CPUs */
+       if (bitmask_isallclear(cpus_chosen))
+               bitmask_setall(cpus_chosen);
+
        dprint("System has up to %d CPU cores\n", cpu_count);
 
        for (num = 0; all_monitors[num]; num++) {
index 63ca87a05e5ffba9400e8caf493c24b6fdb3e22d..5650ab5a2c206b05e23296ae035aae52b9a528ca 100644 (file)
 
 #define MSR_TSC        0x10
 
+#define MSR_AMD_HWCR 0xc0010015
+
 enum mperf_id { C0 = 0, Cx, AVG_FREQ, MPERF_CSTATE_COUNT };
 
 static int mperf_get_count_percent(unsigned int self_id, double *percent,
                                   unsigned int cpu);
 static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
                                unsigned int cpu);
+static struct timespec time_start, time_end;
 
 static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
        {
@@ -54,19 +57,33 @@ static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
        },
 };
 
+enum MAX_FREQ_MODE { MAX_FREQ_SYSFS, MAX_FREQ_TSC_REF };
+static int max_freq_mode;
+/*
+ * The max frequency mperf is ticking at (in C0), either retrieved via:
+ *   1) calculated after measurements if we know TSC ticks at mperf/P0 frequency
+ *   2) cpufreq /sys/devices/.../cpu0/cpufreq/cpuinfo_max_freq at init time
+ * 1. Is preferred as it also works without cpufreq subsystem (e.g. on Xen)
+ */
+static unsigned long max_frequency;
+
 static unsigned long long tsc_at_measure_start;
 static unsigned long long tsc_at_measure_end;
-static unsigned long max_frequency;
 static unsigned long long *mperf_previous_count;
 static unsigned long long *aperf_previous_count;
 static unsigned long long *mperf_current_count;
 static unsigned long long *aperf_current_count;
+
 /* valid flag for all CPUs. If a MSR read failed it will be zero */
 static int *is_valid;
 
 static int mperf_get_tsc(unsigned long long *tsc)
 {
-       return read_msr(0, MSR_TSC, tsc);
+       int ret;
+       ret = read_msr(0, MSR_TSC, tsc);
+       if (ret)
+               dprint("Reading TSC MSR failed, returning %llu\n", *tsc);
+       return ret;
 }
 
 static int mperf_init_stats(unsigned int cpu)
@@ -97,36 +114,11 @@ static int mperf_measure_stats(unsigned int cpu)
        return 0;
 }
 
-/*
- * get_average_perf()
- *
- * Returns the average performance (also considers boosted frequencies)
- *
- * Input:
- *   aperf_diff: Difference of the aperf register over a time period
- *   mperf_diff: Difference of the mperf register over the same time period
- *   max_freq:   Maximum frequency (P0)
- *
- * Returns:
- *   Average performance over the time period
- */
-static unsigned long get_average_perf(unsigned long long aperf_diff,
-                                     unsigned long long mperf_diff)
-{
-       unsigned int perf_percent = 0;
-       if (((unsigned long)(-1) / 100) < aperf_diff) {
-               int shift_count = 7;
-               aperf_diff >>= shift_count;
-               mperf_diff >>= shift_count;
-       }
-       perf_percent = (aperf_diff * 100) / mperf_diff;
-       return (max_frequency * perf_percent) / 100;
-}
-
 static int mperf_get_count_percent(unsigned int id, double *percent,
                                   unsigned int cpu)
 {
        unsigned long long aperf_diff, mperf_diff, tsc_diff;
+       unsigned long long timediff;
 
        if (!is_valid[cpu])
                return -1;
@@ -136,11 +128,19 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
 
        mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
        aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
-       tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
 
-       *percent = 100.0 * mperf_diff / tsc_diff;
-       dprint("%s: mperf_diff: %llu, tsc_diff: %llu\n",
-              mperf_cstates[id].name, mperf_diff, tsc_diff);
+       if (max_freq_mode == MAX_FREQ_TSC_REF) {
+               tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
+               *percent = 100.0 * mperf_diff / tsc_diff;
+               dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
+                      mperf_cstates[id].name, mperf_diff, tsc_diff);
+       } else if (max_freq_mode == MAX_FREQ_SYSFS) {
+               timediff = timespec_diff_us(time_start, time_end);
+               *percent = 100.0 * mperf_diff / timediff;
+               dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n",
+                      mperf_cstates[id].name, mperf_diff, timediff);
+       } else
+               return -1;
 
        if (id == Cx)
                *percent = 100.0 - *percent;
@@ -154,7 +154,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
 static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
                                unsigned int cpu)
 {
-       unsigned long long aperf_diff, mperf_diff;
+       unsigned long long aperf_diff, mperf_diff, time_diff, tsc_diff;
 
        if (id != AVG_FREQ)
                return 1;
@@ -165,11 +165,21 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
        mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu];
        aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];
 
-       /* Return MHz for now, might want to return KHz if column width is more
-          generic */
-       *count = get_average_perf(aperf_diff, mperf_diff) / 1000;
-       dprint("%s: %llu\n", mperf_cstates[id].name, *count);
+       if (max_freq_mode == MAX_FREQ_TSC_REF) {
+               /* Calculate max_freq from TSC count */
+               tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
+               time_diff = timespec_diff_us(time_start, time_end);
+               max_frequency = tsc_diff / time_diff;
+       }
 
+       *count = max_frequency * ((double)aperf_diff / mperf_diff);
+       dprint("%s: Average freq based on %s maximum frequency:\n",
+              mperf_cstates[id].name,
+              (max_freq_mode == MAX_FREQ_TSC_REF) ? "TSC calculated" : "sysfs read");
+       dprint("%max_frequency: %lu", max_frequency);
+       dprint("aperf_diff: %llu\n", aperf_diff);
+       dprint("mperf_diff: %llu\n", mperf_diff);
+       dprint("avg freq:   %llu\n", *count);
        return 0;
 }
 
@@ -178,6 +188,7 @@ static int mperf_start(void)
        int cpu;
        unsigned long long dbg;
 
+       clock_gettime(CLOCK_REALTIME, &time_start);
        mperf_get_tsc(&tsc_at_measure_start);
 
        for (cpu = 0; cpu < cpu_count; cpu++)
@@ -193,32 +204,104 @@ static int mperf_stop(void)
        unsigned long long dbg;
        int cpu;
 
-       mperf_get_tsc(&tsc_at_measure_end);
-
        for (cpu = 0; cpu < cpu_count; cpu++)
                mperf_measure_stats(cpu);
 
+       mperf_get_tsc(&tsc_at_measure_end);
+       clock_gettime(CLOCK_REALTIME, &time_end);
+
        mperf_get_tsc(&dbg);
        dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);
 
        return 0;
 }
 
-struct cpuidle_monitor mperf_monitor;
-
-struct cpuidle_monitor *mperf_register(void)
+/*
+ * Mperf register is defined to tick at P0 (maximum) frequency
+ *
+ * Instead of reading out P0 which can be tricky to read out from HW,
+ * we use TSC counter if it reliably ticks at P0/mperf frequency.
+ *
+ * Still try to fall back to:
+ * /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
+ * on older Intel HW without invariant TSC feature.
+ * Or on AMD machines where TSC does not tick at P0 (do not exist yet, but
+ * it's still double checked (MSR_AMD_HWCR)).
+ *
+ * On these machines the user would still get useful mperf
+ * stats when acpi-cpufreq driver is loaded.
+ */
+static int init_maxfreq_mode(void)
 {
+       int ret;
+       unsigned long long hwcr;
        unsigned long min;
 
-       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
-               return NULL;
-
-       /* Assume min/max all the same on all cores */
+       if (!cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC)
+               goto use_sysfs;
+
+       if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) {
+               /* MSR_AMD_HWCR tells us whether TSC runs at P0/mperf
+                * freq.
+                * A test whether hwcr is accessable/available would be:
+                * (cpupower_cpu_info.family > 0x10 ||
+                *   cpupower_cpu_info.family == 0x10 &&
+                *   cpupower_cpu_info.model >= 0x2))
+                * This should be the case for all aperf/mperf
+                * capable AMD machines and is therefore safe to test here.
+                * Compare with Linus kernel git commit: acf01734b1747b1ec4
+                */
+               ret = read_msr(0, MSR_AMD_HWCR, &hwcr);
+               /*
+                * If the MSR read failed, assume a Xen system that did
+                * not explicitly provide access to it and assume TSC works
+               */
+               if (ret != 0) {
+                       dprint("TSC read 0x%x failed - assume TSC working\n",
+                              MSR_AMD_HWCR);
+                       return 0;
+               } else if (1 & (hwcr >> 24)) {
+                       max_freq_mode = MAX_FREQ_TSC_REF;
+                       return 0;
+               } else { /* Use sysfs max frequency if available */ }
+       } else if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) {
+               /*
+                * On Intel we assume mperf (in C0) is ticking at same
+                * rate than TSC
+                */
+               max_freq_mode = MAX_FREQ_TSC_REF;
+               return 0;
+       }
+use_sysfs:
        if (cpufreq_get_hardware_limits(0, &min, &max_frequency)) {
                dprint("Cannot retrieve max freq from cpufreq kernel "
                       "subsystem\n");
-               return NULL;
+               return -1;
        }
+       max_freq_mode = MAX_FREQ_SYSFS;
+       return 0;
+}
+
+/*
+ * This monitor provides:
+ *
+ * 1) Average frequency a CPU resided in
+ *    This always works if the CPU has aperf/mperf capabilities
+ *
+ * 2) C0 and Cx (any sleep state) time a CPU resided in
+ *    Works if mperf timer stops ticking in sleep states which
+ *    seem to be the case on all current HW.
+ * Both is directly retrieved from HW registers and is independent
+ * from kernel statistics.
+ */
+struct cpuidle_monitor mperf_monitor;
+struct cpuidle_monitor *mperf_register(void)
+{
+       if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
+               return NULL;
+
+       if (init_maxfreq_mode())
+               return NULL;
 
        /* Free this at program termination */
        is_valid = calloc(cpu_count, sizeof(int));